?? print-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. * */#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 + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -