📄 _isakmp.c
字号:
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the project nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#if 0
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.8.2.1 2000/01/14 19:19:56 mcr Exp $ (LBL)";
#endif
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <netinet/if_ether.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/ip_var.h>
#include <netinet/udp.h>
#include <netinet/udp_var.h>
#include <netinet/tcp.h>
#include <netinet/ipv6.h>
#include <netdb.h>
#include "isakmp.h"
#include "ipsec_do.h"
#include "oakley.h"
#include "interfac.h"
#include "a2name.h"
#include "extract.h" /* must come after interface.h */
#ifndef HAVE_SOCKADDR_STORAGE
#define sockaddr_storage sockaddr
#endif
static u_char *isakmp_sa_print (struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_p_print (struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_t_print (struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_ke_print (struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_id_print (struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_hash_print (struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_nonce_print (struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_n_print (struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_d_print (struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_vid_print (struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_sub0_print (u_char, struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static u_char *isakmp_sub_print (u_char, struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);
static char *numstr (int);
#define MAXINITIATORS 20
int ninitiator = 0;
static struct {
cookie_t initiator;
struct sockaddr_storage iaddr;
struct sockaddr_storage raddr;
} cookiecache [MAXINITIATORS];
/* protocol id
*/
static char *protoidstr[] = {
NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp",
};
/* isakmp->np
*/
static char *npstr[] = {
"none", "sa", "p", "t", "ke", "id", "cert", "cr",
"hash", "sig", "nonce", "n", "d", "vid"
};
/* isakmp->np
*/
static u_char *(*npfunc[]) (struct isakmp_gen*, u_char*,
u_int32_t, u_int32_t, u_int32_t) = {
NULL,
isakmp_sa_print,
isakmp_p_print,
isakmp_t_print,
isakmp_ke_print,
isakmp_id_print,
NULL,
NULL,
isakmp_hash_print,
NULL,
isakmp_nonce_print,
isakmp_n_print,
isakmp_d_print,
isakmp_vid_print
};
/* isakmp->etype
*/
static char *etypestr[] = {
"none", "base", "ident", "auth", "agg", "inf", NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
"oakley-quick", "oakley-newgroup",
};
#define STR_OR_ID(x, tab) (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? \
tab[(x)] : numstr(x))
#define PROTOIDSTR(x) STR_OR_ID(x, protoidstr)
#define NPSTR(x) STR_OR_ID(x, npstr)
#define ETYPESTR(x) STR_OR_ID(x, etypestr)
#define NPFUNC(x) (((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) ? \
npfunc[(x)] : NULL)
static int iszero (u_char * p, size_t l)
{
while (l--)
{
if (*p++)
return 0;
}
return 1;
}
/*
* find cookie from initiator cache
*/
static int cookie_find (cookie_t * in)
{
int i;
for (i = 0; i < MAXINITIATORS; i++)
{
if (!memcmp (in, &cookiecache[i].initiator, sizeof(*in)))
return i;
}
return -1;
}
/*
* record initiator
*/
static void cookie_record (cookie_t * in, const u_char * bp2)
{
struct ip *ip;
struct sockaddr_in *sin;
int i;
#ifdef USE_INET6
struct ipv6hdr *ip6;
struct sockaddr_in6 *sin6;
#endif
i = cookie_find (in);
if (0 <= i)
{
ninitiator = (i + 1) % MAXINITIATORS;
return;
}
ip = (struct ip *) bp2;
switch (ip->ip_v)
{
case 4:
memset (&cookiecache[ninitiator].iaddr, 0, sizeof(cookiecache[ninitiator].iaddr));
memset (&cookiecache[ninitiator].raddr, 0, sizeof(cookiecache[ninitiator].raddr));
sin = (struct sockaddr_in *) &cookiecache[ninitiator].iaddr;
sin->sin_family = AF_INET;
memcpy (&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
sin = (struct sockaddr_in *) &cookiecache[ninitiator].raddr;
sin->sin_family = AF_INET;
memcpy (&sin->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst));
break;
#ifdef USE_INET6
case 6:
memset (&cookiecache[ninitiator].iaddr, 0, sizeof(cookiecache[ninitiator].iaddr));
memset (&cookiecache[ninitiator].raddr, 0, sizeof(cookiecache[ninitiator].raddr));
ip6 = (struct ipv6hdr *) bp2;
sin6 = (struct sockaddr_in6 *) &cookiecache[ninitiator].iaddr;
sin6->sin6_family = AF_INET6;
memcpy (&sin6->sin6_addr, &ip6->ipv6_src, sizeof(ip6->ipv6_src));
sin6 = (struct sockaddr_in6 *) &cookiecache[ninitiator].raddr;
sin6->sin6_family = AF_INET6;
memcpy (&sin6->sin6_addr, &ip6->ipv6_dst, sizeof(ip6->ipv6_dst));
break;
#endif
default:
return;
}
memcpy (&cookiecache[ninitiator].initiator, in, sizeof(*in));
ninitiator = (ninitiator + 1) % MAXINITIATORS;
}
#define cookie_isinitiator(x, y) cookie_sidecheck((x), (y), 1)
#define cookie_isresponder(x, y) cookie_sidecheck((x), (y), 0)
static int cookie_sidecheck (int i, const u_char *bp2, int initiator)
{
struct sockaddr_storage ss;
struct sockaddr *sa;
struct ip *ip;
struct sockaddr_in *sin;
#ifdef USE_INET6
struct ipv6hdr *ip6;
struct sockaddr_in6 *sin6;
#endif
int salen;
memset (&ss, 0, sizeof(ss));
ip = (struct ip *) bp2;
switch (ip->ip_v)
{
case 4:
sin = (struct sockaddr_in *) &ss;
sin->sin_family = AF_INET;
memcpy (&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
break;
#ifdef USE_INET6
case 6:
ip6 = (struct ipv6hdr*) bp2;
sin6 = (struct sockaddr_in6*) &ss;
sin6->sin6_family = AF_INET6;
memcpy (&sin6->sin6_addr, &ip6->ipv6_src, sizeof(ip6->ipv6_src));
break;
#endif
default:
return 0;
}
sa = (struct sockaddr *) &ss;
if (initiator)
{
if (sa->sa_family != ((struct sockaddr*)&cookiecache[i].iaddr)->sa_family)
return 0;
#ifdef USE_INET6
if (sa->sa_family == AF_INET6)
salen = sizeof(struct sockaddr_in6);
else salen = sizeof(struct sockaddr);
#else
salen = sizeof(struct sockaddr);
#endif
if (!memcmp (&ss, &cookiecache[i].iaddr, salen))
return 1;
}
else
{
if (sa->sa_family != ((struct sockaddr *) &cookiecache[i].raddr)->sa_family)
return 0;
#ifdef USE_INET6
if (sa->sa_family == AF_INET6)
salen = sizeof(struct sockaddr_in6);
else salen = sizeof(struct sockaddr);
#else
salen = sizeof(struct sockaddr);
#endif
if (!memcmp (&ss, &cookiecache[i].raddr, salen))
return 1;
}
return 0;
}
static void rawprint (caddr_t loc, size_t len)
{
u_char *p = (u_char*) loc;
int i;
for (i = 0; i < len; i++)
PRINTF ("%02x", p[i] & 0xff);
}
struct attrmap {
char *type;
int nvalue;
char *value[30];
};
static u_char *isakmp_attrmap_print (u_char *p, u_char *ep,
struct attrmap *map, size_t nmap)
{
u_short *q;
int totlen;
u_int32_t t, v;
q = (u_short *) p;
if (p[0] & 0x80)
totlen = 4;
else totlen = 4 + ntohs (q[1]);
if (ep < p + totlen)
{
PUTS ("[|attr]");
return ep + 1;
}
PUTCHAR ('(');
t = ntohs (q[0]) & 0x7fff;
if (map && t < nmap && map[t].type)
PRINTF ("type=%s ", map[t].type);
else PRINTF ("type=#%d ", t);
if (p[0] & 0x80)
{
PUTS ("value=");
v = ntohs (q[1]);
if (map && t < nmap && v < map[t].nvalue && map[t].value[v])
PUTS (map[t].value[v]);
else rawprint ((caddr_t) & q[1], 2);
}
else
{
PRINTF ("len=%d value=", ntohs (q[1]));
rawprint ((caddr_t) & p[4], ntohs (q[1]));
}
PUTCHAR (')');
return p + totlen;
}
static u_char *isakmp_attr_print (u_char * p, u_char * ep)
{
u_short *q;
int totlen;
u_int32_t t;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -