print-isakmp.c

来自「TCPDUMP的C语言源代码,是在数据链路层的应用」· C语言 代码 · 共 2,402 行 · 第 1/4 页

C
2,402
字号
/* * 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. * */#ifndef lintstatic const char rcsid[] _U_ =    "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.56 2007-08-29 12:31:00 mcr Exp $ (LBL)";#endif#define NETDISSECT_REWORKED#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <tcpdump-stdinc.h>#include <string.h>#include <stdio.h>#include "isakmp.h"#include "ipsec_doi.h"#include "oakley.h"#include "interface.h"#include "addrtoname.h"#include "extract.h"                    /* must come after interface.h */#include "ip.h"#ifdef INET6#include "ip6.h"#endif#ifndef HAVE_SOCKADDR_STORAGE#define sockaddr_storage sockaddr#endif#define DECLARE_PRINTER(func) static const u_char *ike##func##_print( \		netdissect_options *ndo, u_char tpay,	              \		const struct isakmp_gen *ext,			      \		u_int item_len, \		const u_char *end_pointer, \		u_int32_t phase,\		u_int32_t doi0, \		u_int32_t proto0, int depth)DECLARE_PRINTER(v1_sa);DECLARE_PRINTER(v1_p);DECLARE_PRINTER(v1_t);DECLARE_PRINTER(v1_ke);DECLARE_PRINTER(v1_id);DECLARE_PRINTER(v1_cert);DECLARE_PRINTER(v1_cr);DECLARE_PRINTER(v1_sig);DECLARE_PRINTER(v1_hash);DECLARE_PRINTER(v1_nonce);DECLARE_PRINTER(v1_n);DECLARE_PRINTER(v1_d);DECLARE_PRINTER(v1_vid);DECLARE_PRINTER(v2_sa);DECLARE_PRINTER(v2_ke);DECLARE_PRINTER(v2_ID);DECLARE_PRINTER(v2_cert);DECLARE_PRINTER(v2_cr);DECLARE_PRINTER(v2_auth);DECLARE_PRINTER(v2_nonce);DECLARE_PRINTER(v2_n);DECLARE_PRINTER(v2_d);DECLARE_PRINTER(v2_vid);DECLARE_PRINTER(v2_TS);DECLARE_PRINTER(v2_e);DECLARE_PRINTER(v2_cp);DECLARE_PRINTER(v2_eap);static const u_char *ike_sub0_print(netdissect_options *ndo,u_char, const struct isakmp_gen *,	const u_char *,	u_int32_t, u_int32_t, u_int32_t, int);static const u_char *ikev1_sub_print(netdissect_options *ndo,u_char, const struct isakmp_gen *,	const u_char *, u_int32_t, u_int32_t, u_int32_t, int);static const u_char *ikev2_sub_print(netdissect_options *ndo,				     u_char np, const struct isakmp_gen *ext,				     const u_char *ep, u_int32_t phase,				     u_int32_t doi, u_int32_t proto,				     int depth);static char *numstr(int);static void safememcpy(void *, const void *, size_t);static voidikev1_print(netdissect_options *ndo,	    const u_char *bp,  u_int length,	    const u_char *bp2, struct isakmp *base);#define MAXINITIATORS	20int ninitiator = 0;struct {	cookie_t initiator;	struct sockaddr_storage iaddr;	struct sockaddr_storage raddr;} cookiecache[MAXINITIATORS];/* protocol id */static const char *protoidstr[] = {	NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp",};/* isakmp->np */static const char *npstr[] = {	"none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash", /* 0 - 8 */	"sig", "nonce", "n", "d", "vid",      /* 9 - 13 */	"pay14", "pay15", "pay16", "pay17", "pay18", /* 14- 18 */	"pay19", "pay20", "pay21", "pay22", "pay23", /* 19- 23 */	"pay24", "pay25", "pay26", "pay27", "pay28", /* 24- 28 */	"pay29", "pay30", "pay31", "pay32",          /* 29- 32 */	"v2sa",  "v2ke",  "v2IDi", "v2IDr", "v2cert",/* 33- 37 */	"v2cr",  "v2auth","v2nonce", "v2n",   "v2d",   /* 38- 42 */	"v2vid", "v2TSi", "v2TSr", "v2e",   "v2cp",  /* 43- 47 */	"v2eap",                                     /* 48 */	};/* isakmp->np */static const u_char *(*npfunc[])(netdissect_options *ndo, u_char tpay, 				 const struct isakmp_gen *ext,				 u_int item_len,				 const u_char *end_pointer,				 u_int32_t phase,				 u_int32_t doi0,				 u_int32_t proto0, int depth) = {	NULL,	ikev1_sa_print,	ikev1_p_print,	ikev1_t_print,	ikev1_ke_print,	ikev1_id_print,	ikev1_cert_print,	ikev1_cr_print,	ikev1_hash_print,	ikev1_sig_print,	ikev1_nonce_print,	ikev1_n_print,	ikev1_d_print,	ikev1_vid_print,                  /* 13 */	NULL, NULL, NULL, NULL, NULL,     /* 14- 18 */	NULL, NULL, NULL, NULL, NULL,     /* 19- 23 */	NULL, NULL, NULL, NULL, NULL,     /* 24- 28 */	NULL, NULL, NULL, NULL,           /* 29- 32 */	ikev2_sa_print,                 /* 33 */	ikev2_ke_print,                 /* 34 */	ikev2_ID_print,                 /* 35 */	ikev2_ID_print,                 /* 36 */	ikev2_cert_print,               /* 37 */	ikev2_cr_print,                 /* 38 */	ikev2_auth_print,               /* 39 */	ikev2_nonce_print,              /* 40 */	ikev2_n_print,                  /* 41 */	ikev2_d_print,                  /* 42 */	ikev2_vid_print,                /* 43 */	ikev2_TS_print,                 /* 44 */	ikev2_TS_print,                 /* 45 */	ikev2_e_print,                  /* 46 */	ikev2_cp_print,                 /* 47 */	ikev2_eap_print,                /* 48 */};/* isakmp->etype */static const char *etypestr[] = {/* IKEv1 exchange types */	"none", "base", "ident", "auth", "agg", "inf", NULL, NULL,  /* 0-7 */	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,  /*  8-15 */	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,  /* 16-23 */	NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,  /* 24-31 */	"oakley-quick", "oakley-newgroup",               /* 32-33 *//* IKEv2 exchange types */	"ikev2_init", "ikev2_auth", "child_sa", "inf2"   /* 34-37 */};#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 CHECKLEN(p, np)							\		if (ep < (u_char *)(p)) {				\			ND_PRINT((ndo," [|%s]", NPSTR(np)));		\			goto done;					\		}		#define NPFUNC(x) \	(((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \		? npfunc[(x)] : NULL)static intiszero(u_char *p, size_t l){	while (l--) {		if (*p++)			return 0;	}	return 1;}/* find cookie from initiator cache */static intcookie_find(cookie_t *in){	int i;	for (i = 0; i < MAXINITIATORS; i++) {		if (memcmp(in, &cookiecache[i].initiator, sizeof(*in)) == 0)			return i;	}	return -1;}/* record initiator */static voidcookie_record(cookie_t *in, const u_char *bp2){	int i;	struct ip *ip;	struct sockaddr_in *sin;#ifdef INET6	struct ip6_hdr *ip6;	struct sockaddr_in6 *sin6;#endif	i = cookie_find(in);	if (0 <= i) {		ninitiator = (i + 1) % MAXINITIATORS;		return;	}	ip = (struct ip *)bp2;	switch (IP_V(ip)) {	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;#ifdef HAVE_SOCKADDR_SA_LEN		sin->sin_len = sizeof(struct sockaddr_in);#endif		sin->sin_family = AF_INET;		memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));		sin = (struct sockaddr_in *)&cookiecache[ninitiator].raddr;#ifdef HAVE_SOCKADDR_SA_LEN		sin->sin_len = sizeof(struct sockaddr_in);#endif		sin->sin_family = AF_INET;		memcpy(&sin->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst));		break;#ifdef INET6	case 6:		memset(&cookiecache[ninitiator].iaddr, 0,			sizeof(cookiecache[ninitiator].iaddr));		memset(&cookiecache[ninitiator].raddr, 0,			sizeof(cookiecache[ninitiator].raddr));		ip6 = (struct ip6_hdr *)bp2;		sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].iaddr;#ifdef HAVE_SOCKADDR_SA_LEN		sin6->sin6_len = sizeof(struct sockaddr_in6);#endif		sin6->sin6_family = AF_INET6;		memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src));		sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].raddr;#ifdef HAVE_SOCKADDR_SA_LEN		sin6->sin6_len = sizeof(struct sockaddr_in6);#endif		sin6->sin6_family = AF_INET6;		memcpy(&sin6->sin6_addr, &ip6->ip6_dst, sizeof(ip6->ip6_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 intcookie_sidecheck(int i, const u_char *bp2, int initiator){	struct sockaddr_storage ss;	struct sockaddr *sa;	struct ip *ip;	struct sockaddr_in *sin;#ifdef INET6	struct ip6_hdr *ip6;	struct sockaddr_in6 *sin6;#endif	int salen;	memset(&ss, 0, sizeof(ss));	ip = (struct ip *)bp2;	switch (IP_V(ip)) {	case 4:		sin = (struct sockaddr_in *)&ss;#ifdef HAVE_SOCKADDR_SA_LEN		sin->sin_len = sizeof(struct sockaddr_in);#endif		sin->sin_family = AF_INET;		memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));		break;#ifdef INET6	case 6:		ip6 = (struct ip6_hdr *)bp2;		sin6 = (struct sockaddr_in6 *)&ss;#ifdef HAVE_SOCKADDR_SA_LEN		sin6->sin6_len = sizeof(struct sockaddr_in6);#endif		sin6->sin6_family = AF_INET6;		memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_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 HAVE_SOCKADDR_SA_LEN		salen = sa->sa_len;#else#ifdef INET6		if (sa->sa_family == AF_INET6)			salen = sizeof(struct sockaddr_in6);		else			salen = sizeof(struct sockaddr);#else		salen = sizeof(struct sockaddr);#endif#endif		if (memcmp(&ss, &cookiecache[i].iaddr, salen) == 0)			return 1;	} else {		if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].raddr)->sa_family)			return 0;#ifdef HAVE_SOCKADDR_SA_LEN		salen = sa->sa_len;#else#ifdef INET6		if (sa->sa_family == AF_INET6)			salen = sizeof(struct sockaddr_in6);		else			salen = sizeof(struct sockaddr);#else		salen = sizeof(struct sockaddr);#endif#endif		if (memcmp(&ss, &cookiecache[i].raddr, salen) == 0)			return 1;	}	return 0;}static intrawprint(netdissect_options *ndo, caddr_t loc, size_t len){	static u_char *p;	size_t i;	ND_TCHECK2(*loc, len);		p = (u_char *)loc;	for (i = 0; i < len; i++)		ND_PRINT((ndo,"%02x", p[i] & 0xff));	return 1;trunc:	return 0;}/* * returns false if we run out of data buffer */static int ike_show_somedata(struct netdissect_options *ndo,			     const u_char *cp, const u_char *ep){	/* there is too much data, just show some of it */	const u_char *end = ep - 20;	int  elen = 20;	int   len = ep - cp;	if(len > 10) {		len = 10;	}		/* really shouldn't happen because of above */	if(end < cp + len) {		end = cp+len;		elen = ep - end;	}		ND_PRINT((ndo," data=("));	if(!rawprint(ndo, (caddr_t)(cp), len)) goto trunc;	ND_PRINT((ndo, "..."));	if(elen) {		if(!rawprint(ndo, (caddr_t)(end), elen)) goto trunc;	}	ND_PRINT((ndo,")"));	return 1;trunc:	return 0;}struct attrmap {	const char *type;	u_int nvalue;	const char *value[30];	/*XXX*/};static const u_char *ikev1_attrmap_print(netdissect_options *ndo,		    const u_char *p, const u_char *ep,		    const struct attrmap *map, size_t nmap){	u_int16_t *q;	int totlen;	u_int32_t t, v;	q = (u_int16_t *)p;	if (p[0] & 0x80)		totlen = 4;	else		totlen = 4 + EXTRACT_16BITS(&q[1]);	if (ep < p + totlen) {		ND_PRINT((ndo,"[|attr]"));		return ep + 1;	}	ND_PRINT((ndo,"("));	t = EXTRACT_16BITS(&q[0]) & 0x7fff;	if (map && t < nmap && map[t].type)		ND_PRINT((ndo,"type=%s ", map[t].type));	else		ND_PRINT((ndo,"type=#%d ", t));	if (p[0] & 0x80) {		ND_PRINT((ndo,"value="));		v = EXTRACT_16BITS(&q[1]);		if (map && t < nmap && v < map[t].nvalue && map[t].value[v])			ND_PRINT((ndo,"%s", map[t].value[v]));		else			rawprint(ndo, (caddr_t)&q[1], 2);	} else {		ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&q[1])));		rawprint(ndo, (caddr_t)&p[4], EXTRACT_16BITS(&q[1]));	}	ND_PRINT((ndo,")"));	return p + totlen;}static const u_char *ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep){	u_int16_t *q;	int totlen;	u_int32_t t;	q = (u_int16_t *)p;	if (p[0] & 0x80)		totlen = 4;	else		totlen = 4 + EXTRACT_16BITS(&q[1]);	if (ep < p + totlen) {		ND_PRINT((ndo,"[|attr]"));		return ep + 1;	}	ND_PRINT((ndo,"("));	t = EXTRACT_16BITS(&q[0]) & 0x7fff;	ND_PRINT((ndo,"type=#%d ", t));	if (p[0] & 0x80) {		ND_PRINT((ndo,"value="));		t = q[1];		rawprint(ndo, (caddr_t)&q[1], 2);	} else {		ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&q[1])));		rawprint(ndo, (caddr_t)&p[2], EXTRACT_16BITS(&q[1]));	}	ND_PRINT((ndo,")"));	return p + totlen;}static const u_char *ikev1_sa_print(netdissect_options *ndo, u_char tpay _U_,	       const struct isakmp_gen *ext,		u_int item_len _U_,		const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_,		u_int32_t proto0, int depth){	const struct ikev1_pl_sa *p;	struct ikev1_pl_sa sa;	const u_int32_t *q;	u_int32_t doi, sit, ident;	const u_char *cp, *np;	int t;	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SA)));	p = (struct ikev1_pl_sa *)ext;	ND_TCHECK(*p);	safememcpy(&sa, ext, sizeof(sa));	doi = ntohl(sa.doi);	sit = ntohl(sa.sit);	if (doi != 1) {		ND_PRINT((ndo," doi=%d", doi));		ND_PRINT((ndo," situation=%u", (u_int32_t)ntohl(sa.sit)));		return (u_char *)(p + 1);	}	ND_PRINT((ndo," doi=ipsec"));	q = (u_int32_t *)&sa.sit;	ND_PRINT((ndo," situation="));	t = 0;	if (sit & 0x01) {		ND_PRINT((ndo,"identity"));		t++;	}	if (sit & 0x02) {		ND_PRINT((ndo,"%ssecrecy", t ? "+" : ""));		t++;	}	if (sit & 0x04)		ND_PRINT((ndo,"%sintegrity", t ? "+" : ""));	np = (u_char *)ext + sizeof(sa);	if (sit != 0x01) {		ND_TCHECK2(*(ext + 1), sizeof(ident));		safememcpy(&ident, ext + 1, sizeof(ident));		ND_PRINT((ndo," ident=%u", (u_int32_t)ntohl(ident)));		np += sizeof(ident);	}	ext = (struct isakmp_gen *)np;	ND_TCHECK(*ext);	cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0,		depth);	return cp;trunc:	ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SA)));	return NULL;}static const u_char *ikev1_p_print(netdissect_options *ndo, u_char tpay _U_,	      const struct isakmp_gen *ext, u_int item_len _U_,	       const u_char *ep, u_int32_t phase, u_int32_t doi0,	       u_int32_t proto0 _U_, int depth){	const struct ikev1_pl_p *p;	struct ikev1_pl_p prop;	const u_char *cp;	ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_P)));	p = (struct ikev1_pl_p *)ext;	ND_TCHECK(*p);	safememcpy(&prop, ext, sizeof(prop));	ND_PRINT((ndo," #%d protoid=%s transform=%d",		  prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t));	if (prop.spi_size) {		ND_PRINT((ndo," spi="));

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?