📄 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[] = "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.26 2000/12/12 09:20:26 itojun Exp $ (LBL)";#endif#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <string.h>#ifndef WIN32
#include <ctype.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/socket.h>
#else
#include <winsock2.h>
#include "bittypes.h"
#include "IP6_misc.h"
typedef char * caddr_t;
#endif /* WIN32 */
struct mbuf;struct rtentry;#ifndef WIN32
#include <netinet/in.h>#endif /* WIN32 */
#include <stdio.h>#include <netdb.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#ifndef WIN32
#include "ip6.h"#endif /* WIN32 */
#endif#ifndef HAVE_SOCKADDR_STORAGE#define sockaddr_storage sockaddr#endifstatic 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_cert_print(struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);static u_char *isakmp_cr_print(struct isakmp_gen *, u_char *, u_int32_t, u_int32_t, u_int32_t);static u_char *isakmp_sig_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);static void safememcpy(void *, void *, size_t);#define MAXINITIATORS 20int ninitiator = 0;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, isakmp_cert_print, isakmp_cr_print, isakmp_hash_print, isakmp_sig_print, 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 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 voidrawprint(caddr_t loc, size_t len){ static u_char *p; int i; p = (u_char *)loc; for (i = 0; i < len; i++) printf("%02x", p[i] & 0xff);}struct attrmap { char *type; int nvalue; char *value[30]; /*XXX*/};static u_char *isakmp_attrmap_print(u_char *p, u_char *ep, 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 + ntohs(q[1]); if (ep < p + totlen) { printf("[|attr]"); return ep + 1; } printf("("); 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) { printf("value="); v = ntohs(q[1]); if (map && t < nmap && v < map[t].nvalue && map[t].value[v]) printf("%s", 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])); } printf(")"); return p + totlen;}static u_char *isakmp_attr_print(u_char *p, 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 + ntohs(q[1]); if (ep < p + totlen) { printf("[|attr]"); return ep + 1; } printf("("); t = ntohs(q[0]) & 0x7fff; printf("type=#%d ", t); if (p[0] & 0x80) { printf("value="); t = q[1]; rawprint((caddr_t)&q[1], 2); } else { printf("len=%d value=", ntohs(q[1])); rawprint((caddr_t)&p[2], ntohs(q[1])); } printf(")"); return p + totlen;}static u_char *isakmp_sa_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, u_int32_t doi0, u_int32_t proto0){ struct isakmp_pl_sa *p, sa; u_int32_t *q; u_int32_t doi, sit, ident; u_char *cp, *np; int t; printf("%s:", NPSTR(ISAKMP_NPTYPE_SA)); p = (struct isakmp_pl_sa *)ext; safememcpy(&sa, ext, sizeof(sa)); doi = ntohl(sa.doi); sit = ntohl(sa.sit); if (doi != 1) { printf(" doi=%d", doi); printf(" situation=%u", (u_int32_t)ntohl(sa.sit)); return (u_char *)(p + 1); } printf(" doi=ipsec"); q = (u_int32_t *)&sa.sit; printf(" situation="); t = 0; if (sit & 0x01) { printf("identity"); t++; } if (sit & 0x02) { printf("%ssecrecy", t ? "+" : ""); t++; } if (sit & 0x04) printf("%sintegrity", t ? "+" : ""); np = (u_char *)ext + sizeof(sa); if (sit != 0x01) { safememcpy(&ident, ext + 1, sizeof(ident)); printf(" ident=%u", (u_int32_t)ntohl(ident)); np += sizeof(ident); } ext = (struct isakmp_gen *)np; cp = isakmp_sub_print(ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0); return cp;}static u_char *isakmp_p_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, u_int32_t doi0, u_int32_t proto0){ struct isakmp_pl_p *p, prop; u_char *cp; printf("%s:", NPSTR(ISAKMP_NPTYPE_P)); p = (struct isakmp_pl_p *)ext; safememcpy(&prop, ext, sizeof(prop)); printf(" #%d protoid=%s transform=%d", prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t); if (prop.spi_size) { printf(" spi="); rawprint((caddr_t)(p + 1), prop.spi_size); } ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size); cp = isakmp_sub_print(ISAKMP_NPTYPE_T, ext, ep, phase, doi0, prop.prot_id); return cp;}static char *isakmp_p_map[] = { NULL, "ike",};static char *ah_p_map[] = { NULL, "(reserved)", "md5", "sha", "1des", "sha2-256", "sha2-384", "sha2-512",};static char *esp_p_map[] = { NULL, "1des-iv64", "1des", "3des", "rc5", "idea", "cast", "blowfish", "3idea", "1des-iv32", "rc4", "null", "aes"};static char *ipcomp_p_map[] = { NULL, "oui", "deflate", "lzs",};struct attrmap ipsec_t_map[] = { { NULL, 0, }, { "lifetype", 3, { NULL, "sec", "kb", }, }, { "life", 0, }, { "group desc", 5, { NULL, "modp768", "modp1024", "EC2N 2^155", "EC2N 2^185", }, }, { "enc mode", 3, { NULL, "tunnel", "transport", }, }, { "auth", 5, { NULL, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, }, { "keylen", 0, }, { "rounds", 0, }, { "dictsize", 0, }, { "privalg", 0, },};struct attrmap oakley_t_map[] = { { NULL, 0 }, { "enc", 8, { NULL, "1des", "idea", "blowfish", "rc5", "3des", "cast", "aes", }, }, { "hash", 7, { NULL, "md5", "sha1", "tiger", "sha2-256", "sha2-384", "sha2-512", }, }, { "auth", 6, { NULL, "preshared", "dss", "rsa sig", "rsa enc", "rsa enc revised", }, }, { "group desc", 5, { NULL, "modp768", "modp1024", "EC2N 2^155", "EC2N 2^185", }, }, { "group type", 4, { NULL, "MODP", "ECP", "EC2N", }, }, { "group prime", 0, }, { "group gen1", 0, }, { "group gen2", 0, }, { "group curve A", 0, }, { "group curve B", 0, }, { "lifetype", 3, { NULL, "sec", "kb", }, }, { "lifeduration", 0, }, { "prf", 0, }, { "keylen", 0, }, { "field", 0, }, { "order", 0, },};static u_char *isakmp_t_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, u_int32_t doi, u_int32_t proto){ struct isakmp_pl_t *p, t; u_char *cp; char *idstr; struct attrmap *map; size_t nmap; u_char *ep2; printf("%s:", NPSTR(ISAKMP_NPTYPE_T)); p = (struct isakmp_pl_t *)ext; safememcpy(&t, ext, sizeof(t)); switch (proto) { case 1: idstr = STR_OR_ID(t.t_id, isakmp_p_map); map = oakley_t_map; nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]); break; case 2: idstr = STR_OR_ID(t.t_id, ah_p_map); map = ipsec_t_map; nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); break; case 3: idstr = STR_OR_ID(t.t_id, esp_p_map); map = ipsec_t_map; nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); break; case 4: idstr = STR_OR_ID(t.t_id, ipcomp_p_map); map = ipsec_t_map; nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); break; default: idstr = NULL; map = NULL; nmap = 0; break; } if (idstr) printf(" #%d id=%s ", t.t_no, idstr); else printf(" #%d id=%d ", t.t_no, t.t_id); cp = (u_char *)(p + 1); ep2 = (u_char *)p + ntohs(t.h.len); while (cp < ep && cp < ep2) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -