156893Sfenner/* 256893Sfenner * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 356893Sfenner * All rights reserved. 4127668Sbms * 556893Sfenner * Redistribution and use in source and binary forms, with or without 656893Sfenner * modification, are permitted provided that the following conditions 756893Sfenner * are met: 856893Sfenner * 1. Redistributions of source code must retain the above copyright 956893Sfenner * notice, this list of conditions and the following disclaimer. 1056893Sfenner * 2. Redistributions in binary form must reproduce the above copyright 1156893Sfenner * notice, this list of conditions and the following disclaimer in the 1256893Sfenner * documentation and/or other materials provided with the distribution. 1356893Sfenner * 3. Neither the name of the project nor the names of its contributors 1456893Sfenner * may be used to endorse or promote products derived from this software 1556893Sfenner * without specific prior written permission. 16127668Sbms * 1756893Sfenner * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 1856893Sfenner * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1956893Sfenner * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2056893Sfenner * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 2156893Sfenner * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2256893Sfenner * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2356893Sfenner * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2456893Sfenner * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2556893Sfenner * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2656893Sfenner * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2756893Sfenner * SUCH DAMAGE. 2856893Sfenner * 2956893Sfenner */ 3056893Sfenner 3156893Sfenner#ifndef lint 32127668Sbmsstatic const char rcsid[] _U_ = 33214478Srpaulo "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.61 2008-02-05 19:34:25 guy Exp $ (LBL)"; 3456893Sfenner#endif 3556893Sfenner 36190207Srpaulo#define NETDISSECT_REWORKED 3756893Sfenner#ifdef HAVE_CONFIG_H 3856893Sfenner#include "config.h" 3956893Sfenner#endif 4056893Sfenner 41127668Sbms#include <tcpdump-stdinc.h> 42127668Sbms 4356893Sfenner#include <string.h> 4456893Sfenner 4556893Sfenner#include <stdio.h> 4656893Sfenner 4756893Sfenner#include "isakmp.h" 4856893Sfenner#include "ipsec_doi.h" 4956893Sfenner#include "oakley.h" 5056893Sfenner#include "interface.h" 5156893Sfenner#include "addrtoname.h" 5256893Sfenner#include "extract.h" /* must come after interface.h */ 5356893Sfenner 5475115Sfenner#include "ip.h" 5575115Sfenner#ifdef INET6 5675115Sfenner#include "ip6.h" 5775115Sfenner#endif 5875115Sfenner 5956893Sfenner#ifndef HAVE_SOCKADDR_STORAGE 6056893Sfenner#define sockaddr_storage sockaddr 6156893Sfenner#endif 6256893Sfenner 63190207Srpaulo#define DECLARE_PRINTER(func) static const u_char *ike##func##_print( \ 64190207Srpaulo netdissect_options *ndo, u_char tpay, \ 65190207Srpaulo const struct isakmp_gen *ext, \ 66190207Srpaulo u_int item_len, \ 67190207Srpaulo const u_char *end_pointer, \ 68190207Srpaulo u_int32_t phase,\ 69190207Srpaulo u_int32_t doi0, \ 70190207Srpaulo u_int32_t proto0, int depth) 71190207Srpaulo 72190207SrpauloDECLARE_PRINTER(v1_sa); 73190207SrpauloDECLARE_PRINTER(v1_p); 74190207SrpauloDECLARE_PRINTER(v1_t); 75190207SrpauloDECLARE_PRINTER(v1_ke); 76190207SrpauloDECLARE_PRINTER(v1_id); 77190207SrpauloDECLARE_PRINTER(v1_cert); 78190207SrpauloDECLARE_PRINTER(v1_cr); 79190207SrpauloDECLARE_PRINTER(v1_sig); 80190207SrpauloDECLARE_PRINTER(v1_hash); 81190207SrpauloDECLARE_PRINTER(v1_nonce); 82190207SrpauloDECLARE_PRINTER(v1_n); 83190207SrpauloDECLARE_PRINTER(v1_d); 84190207SrpauloDECLARE_PRINTER(v1_vid); 85190207Srpaulo 86190207SrpauloDECLARE_PRINTER(v2_sa); 87190207SrpauloDECLARE_PRINTER(v2_ke); 88190207SrpauloDECLARE_PRINTER(v2_ID); 89190207SrpauloDECLARE_PRINTER(v2_cert); 90190207SrpauloDECLARE_PRINTER(v2_cr); 91190207SrpauloDECLARE_PRINTER(v2_auth); 92190207SrpauloDECLARE_PRINTER(v2_nonce); 93190207SrpauloDECLARE_PRINTER(v2_n); 94190207SrpauloDECLARE_PRINTER(v2_d); 95190207SrpauloDECLARE_PRINTER(v2_vid); 96190207SrpauloDECLARE_PRINTER(v2_TS); 97190207SrpauloDECLARE_PRINTER(v2_cp); 98190207SrpauloDECLARE_PRINTER(v2_eap); 99190207Srpaulo 100214478Srpaulostatic const u_char *ikev2_e_print(netdissect_options *ndo, 101214478Srpaulo struct isakmp *base, 102214478Srpaulo u_char tpay, 103214478Srpaulo const struct isakmp_gen *ext, 104214478Srpaulo u_int item_len, 105214478Srpaulo const u_char *end_pointer, 106214478Srpaulo u_int32_t phase, 107214478Srpaulo u_int32_t doi0, 108214478Srpaulo u_int32_t proto0, int depth); 109214478Srpaulo 110214478Srpaulo 111190207Srpaulostatic const u_char *ike_sub0_print(netdissect_options *ndo,u_char, const struct isakmp_gen *, 112127668Sbms const u_char *, u_int32_t, u_int32_t, u_int32_t, int); 113190207Srpaulostatic const u_char *ikev1_sub_print(netdissect_options *ndo,u_char, const struct isakmp_gen *, 114127668Sbms const u_char *, u_int32_t, u_int32_t, u_int32_t, int); 115190207Srpaulo 116190207Srpaulostatic const u_char *ikev2_sub_print(netdissect_options *ndo, 117214478Srpaulo struct isakmp *base, 118190207Srpaulo u_char np, const struct isakmp_gen *ext, 119190207Srpaulo const u_char *ep, u_int32_t phase, 120190207Srpaulo u_int32_t doi, u_int32_t proto, 121190207Srpaulo int depth); 122190207Srpaulo 123190207Srpaulo 12475115Sfennerstatic char *numstr(int); 125127668Sbmsstatic void safememcpy(void *, const void *, size_t); 12656893Sfenner 127190207Srpaulostatic void 128190207Srpauloikev1_print(netdissect_options *ndo, 129190207Srpaulo const u_char *bp, u_int length, 130190207Srpaulo const u_char *bp2, struct isakmp *base); 131190207Srpaulo 13256893Sfenner#define MAXINITIATORS 20 13356893Sfennerint ninitiator = 0; 13456893Sfennerstruct { 13556893Sfenner cookie_t initiator; 13656893Sfenner struct sockaddr_storage iaddr; 13756893Sfenner struct sockaddr_storage raddr; 13856893Sfenner} cookiecache[MAXINITIATORS]; 13956893Sfenner 14056893Sfenner/* protocol id */ 141127668Sbmsstatic const char *protoidstr[] = { 14256893Sfenner NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp", 14356893Sfenner}; 14456893Sfenner 14556893Sfenner/* isakmp->np */ 146127668Sbmsstatic const char *npstr[] = { 147190207Srpaulo "none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash", /* 0 - 8 */ 148190207Srpaulo "sig", "nonce", "n", "d", "vid", /* 9 - 13 */ 149190207Srpaulo "pay14", "pay15", "pay16", "pay17", "pay18", /* 14- 18 */ 150190207Srpaulo "pay19", "pay20", "pay21", "pay22", "pay23", /* 19- 23 */ 151190207Srpaulo "pay24", "pay25", "pay26", "pay27", "pay28", /* 24- 28 */ 152190207Srpaulo "pay29", "pay30", "pay31", "pay32", /* 29- 32 */ 153190207Srpaulo "v2sa", "v2ke", "v2IDi", "v2IDr", "v2cert",/* 33- 37 */ 154190207Srpaulo "v2cr", "v2auth","v2nonce", "v2n", "v2d", /* 38- 42 */ 155190207Srpaulo "v2vid", "v2TSi", "v2TSr", "v2e", "v2cp", /* 43- 47 */ 156190207Srpaulo "v2eap", /* 48 */ 157190207Srpaulo 15856893Sfenner}; 15956893Sfenner 16056893Sfenner/* isakmp->np */ 161190207Srpaulostatic const u_char *(*npfunc[])(netdissect_options *ndo, u_char tpay, 162190207Srpaulo const struct isakmp_gen *ext, 163190207Srpaulo u_int item_len, 164190207Srpaulo const u_char *end_pointer, 165190207Srpaulo u_int32_t phase, 166190207Srpaulo u_int32_t doi0, 167190207Srpaulo u_int32_t proto0, int depth) = { 16856893Sfenner NULL, 169190207Srpaulo ikev1_sa_print, 170190207Srpaulo ikev1_p_print, 171190207Srpaulo ikev1_t_print, 172190207Srpaulo ikev1_ke_print, 173190207Srpaulo ikev1_id_print, 174190207Srpaulo ikev1_cert_print, 175190207Srpaulo ikev1_cr_print, 176190207Srpaulo ikev1_hash_print, 177190207Srpaulo ikev1_sig_print, 178190207Srpaulo ikev1_nonce_print, 179190207Srpaulo ikev1_n_print, 180190207Srpaulo ikev1_d_print, 181190207Srpaulo ikev1_vid_print, /* 13 */ 182190207Srpaulo NULL, NULL, NULL, NULL, NULL, /* 14- 18 */ 183190207Srpaulo NULL, NULL, NULL, NULL, NULL, /* 19- 23 */ 184190207Srpaulo NULL, NULL, NULL, NULL, NULL, /* 24- 28 */ 185190207Srpaulo NULL, NULL, NULL, NULL, /* 29- 32 */ 186190207Srpaulo ikev2_sa_print, /* 33 */ 187190207Srpaulo ikev2_ke_print, /* 34 */ 188190207Srpaulo ikev2_ID_print, /* 35 */ 189190207Srpaulo ikev2_ID_print, /* 36 */ 190190207Srpaulo ikev2_cert_print, /* 37 */ 191190207Srpaulo ikev2_cr_print, /* 38 */ 192190207Srpaulo ikev2_auth_print, /* 39 */ 193190207Srpaulo ikev2_nonce_print, /* 40 */ 194190207Srpaulo ikev2_n_print, /* 41 */ 195190207Srpaulo ikev2_d_print, /* 42 */ 196190207Srpaulo ikev2_vid_print, /* 43 */ 197190207Srpaulo ikev2_TS_print, /* 44 */ 198190207Srpaulo ikev2_TS_print, /* 45 */ 199214478Srpaulo NULL, /* ikev2_e_print,*/ /* 46 - special */ 200190207Srpaulo ikev2_cp_print, /* 47 */ 201190207Srpaulo ikev2_eap_print, /* 48 */ 20256893Sfenner}; 20356893Sfenner 20456893Sfenner/* isakmp->etype */ 205127668Sbmsstatic const char *etypestr[] = { 206190207Srpaulo/* IKEv1 exchange types */ 207190207Srpaulo "none", "base", "ident", "auth", "agg", "inf", NULL, NULL, /* 0-7 */ 208190207Srpaulo NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 8-15 */ 209190207Srpaulo NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 16-23 */ 210190207Srpaulo NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 24-31 */ 211190207Srpaulo "oakley-quick", "oakley-newgroup", /* 32-33 */ 212190207Srpaulo/* IKEv2 exchange types */ 213190207Srpaulo "ikev2_init", "ikev2_auth", "child_sa", "inf2" /* 34-37 */ 21456893Sfenner}; 21556893Sfenner 21656893Sfenner#define STR_OR_ID(x, tab) \ 21756893Sfenner (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x)) 21856893Sfenner#define PROTOIDSTR(x) STR_OR_ID(x, protoidstr) 21956893Sfenner#define NPSTR(x) STR_OR_ID(x, npstr) 22056893Sfenner#define ETYPESTR(x) STR_OR_ID(x, etypestr) 22156893Sfenner 222190207Srpaulo#define CHECKLEN(p, np) \ 223190207Srpaulo if (ep < (u_char *)(p)) { \ 224190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(np))); \ 225190207Srpaulo goto done; \ 226190207Srpaulo } 227190207Srpaulo 228190207Srpaulo 22956893Sfenner#define NPFUNC(x) \ 23056893Sfenner (((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \ 23156893Sfenner ? npfunc[(x)] : NULL) 23256893Sfenner 23356893Sfennerstatic int 23456893Sfenneriszero(u_char *p, size_t l) 23556893Sfenner{ 23656893Sfenner while (l--) { 23756893Sfenner if (*p++) 23856893Sfenner return 0; 23956893Sfenner } 24056893Sfenner return 1; 24156893Sfenner} 24256893Sfenner 24356893Sfenner/* find cookie from initiator cache */ 24456893Sfennerstatic int 24556893Sfennercookie_find(cookie_t *in) 24656893Sfenner{ 24756893Sfenner int i; 24856893Sfenner 24956893Sfenner for (i = 0; i < MAXINITIATORS; i++) { 25056893Sfenner if (memcmp(in, &cookiecache[i].initiator, sizeof(*in)) == 0) 25156893Sfenner return i; 25256893Sfenner } 25356893Sfenner 25456893Sfenner return -1; 25556893Sfenner} 25656893Sfenner 25756893Sfenner/* record initiator */ 25856893Sfennerstatic void 25956893Sfennercookie_record(cookie_t *in, const u_char *bp2) 26056893Sfenner{ 26156893Sfenner int i; 26256893Sfenner struct ip *ip; 26356893Sfenner struct sockaddr_in *sin; 26456893Sfenner#ifdef INET6 26556893Sfenner struct ip6_hdr *ip6; 26656893Sfenner struct sockaddr_in6 *sin6; 26756893Sfenner#endif 26856893Sfenner 26956893Sfenner i = cookie_find(in); 27056893Sfenner if (0 <= i) { 27156893Sfenner ninitiator = (i + 1) % MAXINITIATORS; 27256893Sfenner return; 27356893Sfenner } 27456893Sfenner 27556893Sfenner ip = (struct ip *)bp2; 27675115Sfenner switch (IP_V(ip)) { 27756893Sfenner case 4: 27856893Sfenner memset(&cookiecache[ninitiator].iaddr, 0, 27956893Sfenner sizeof(cookiecache[ninitiator].iaddr)); 28056893Sfenner memset(&cookiecache[ninitiator].raddr, 0, 28156893Sfenner sizeof(cookiecache[ninitiator].raddr)); 28256893Sfenner 28356893Sfenner sin = (struct sockaddr_in *)&cookiecache[ninitiator].iaddr; 28456893Sfenner#ifdef HAVE_SOCKADDR_SA_LEN 28556893Sfenner sin->sin_len = sizeof(struct sockaddr_in); 28656893Sfenner#endif 28756893Sfenner sin->sin_family = AF_INET; 28856893Sfenner memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src)); 28956893Sfenner sin = (struct sockaddr_in *)&cookiecache[ninitiator].raddr; 29056893Sfenner#ifdef HAVE_SOCKADDR_SA_LEN 29156893Sfenner sin->sin_len = sizeof(struct sockaddr_in); 29256893Sfenner#endif 29356893Sfenner sin->sin_family = AF_INET; 29456893Sfenner memcpy(&sin->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst)); 29556893Sfenner break; 29656893Sfenner#ifdef INET6 29756893Sfenner case 6: 29856893Sfenner memset(&cookiecache[ninitiator].iaddr, 0, 29956893Sfenner sizeof(cookiecache[ninitiator].iaddr)); 30056893Sfenner memset(&cookiecache[ninitiator].raddr, 0, 30156893Sfenner sizeof(cookiecache[ninitiator].raddr)); 30256893Sfenner 30356893Sfenner ip6 = (struct ip6_hdr *)bp2; 30456893Sfenner sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].iaddr; 30556893Sfenner#ifdef HAVE_SOCKADDR_SA_LEN 30656893Sfenner sin6->sin6_len = sizeof(struct sockaddr_in6); 30756893Sfenner#endif 30856893Sfenner sin6->sin6_family = AF_INET6; 30956893Sfenner memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src)); 31056893Sfenner sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].raddr; 31156893Sfenner#ifdef HAVE_SOCKADDR_SA_LEN 31256893Sfenner sin6->sin6_len = sizeof(struct sockaddr_in6); 31356893Sfenner#endif 31456893Sfenner sin6->sin6_family = AF_INET6; 31556893Sfenner memcpy(&sin6->sin6_addr, &ip6->ip6_dst, sizeof(ip6->ip6_dst)); 31656893Sfenner break; 31756893Sfenner#endif 31856893Sfenner default: 31956893Sfenner return; 32056893Sfenner } 32156893Sfenner memcpy(&cookiecache[ninitiator].initiator, in, sizeof(*in)); 32256893Sfenner ninitiator = (ninitiator + 1) % MAXINITIATORS; 32356893Sfenner} 32456893Sfenner 32556893Sfenner#define cookie_isinitiator(x, y) cookie_sidecheck((x), (y), 1) 32656893Sfenner#define cookie_isresponder(x, y) cookie_sidecheck((x), (y), 0) 32756893Sfennerstatic int 32856893Sfennercookie_sidecheck(int i, const u_char *bp2, int initiator) 32956893Sfenner{ 33056893Sfenner struct sockaddr_storage ss; 33156893Sfenner struct sockaddr *sa; 33256893Sfenner struct ip *ip; 33356893Sfenner struct sockaddr_in *sin; 33456893Sfenner#ifdef INET6 33556893Sfenner struct ip6_hdr *ip6; 33656893Sfenner struct sockaddr_in6 *sin6; 33756893Sfenner#endif 33856893Sfenner int salen; 33956893Sfenner 34056893Sfenner memset(&ss, 0, sizeof(ss)); 34156893Sfenner ip = (struct ip *)bp2; 34275115Sfenner switch (IP_V(ip)) { 34356893Sfenner case 4: 34456893Sfenner sin = (struct sockaddr_in *)&ss; 34556893Sfenner#ifdef HAVE_SOCKADDR_SA_LEN 34656893Sfenner sin->sin_len = sizeof(struct sockaddr_in); 34756893Sfenner#endif 34856893Sfenner sin->sin_family = AF_INET; 34956893Sfenner memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src)); 35056893Sfenner break; 35156893Sfenner#ifdef INET6 35256893Sfenner case 6: 35356893Sfenner ip6 = (struct ip6_hdr *)bp2; 35456893Sfenner sin6 = (struct sockaddr_in6 *)&ss; 35556893Sfenner#ifdef HAVE_SOCKADDR_SA_LEN 35656893Sfenner sin6->sin6_len = sizeof(struct sockaddr_in6); 35756893Sfenner#endif 35856893Sfenner sin6->sin6_family = AF_INET6; 35956893Sfenner memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src)); 36056893Sfenner break; 36156893Sfenner#endif 36256893Sfenner default: 36356893Sfenner return 0; 36456893Sfenner } 36556893Sfenner 36656893Sfenner sa = (struct sockaddr *)&ss; 36756893Sfenner if (initiator) { 36856893Sfenner if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].iaddr)->sa_family) 36956893Sfenner return 0; 37056893Sfenner#ifdef HAVE_SOCKADDR_SA_LEN 37156893Sfenner salen = sa->sa_len; 37256893Sfenner#else 37356893Sfenner#ifdef INET6 37456893Sfenner if (sa->sa_family == AF_INET6) 37556893Sfenner salen = sizeof(struct sockaddr_in6); 37656893Sfenner else 37756893Sfenner salen = sizeof(struct sockaddr); 37856893Sfenner#else 37956893Sfenner salen = sizeof(struct sockaddr); 38056893Sfenner#endif 38156893Sfenner#endif 38256893Sfenner if (memcmp(&ss, &cookiecache[i].iaddr, salen) == 0) 38356893Sfenner return 1; 38456893Sfenner } else { 38556893Sfenner if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].raddr)->sa_family) 38656893Sfenner return 0; 38756893Sfenner#ifdef HAVE_SOCKADDR_SA_LEN 38856893Sfenner salen = sa->sa_len; 38956893Sfenner#else 39056893Sfenner#ifdef INET6 39156893Sfenner if (sa->sa_family == AF_INET6) 39256893Sfenner salen = sizeof(struct sockaddr_in6); 39356893Sfenner else 39456893Sfenner salen = sizeof(struct sockaddr); 39556893Sfenner#else 39656893Sfenner salen = sizeof(struct sockaddr); 39756893Sfenner#endif 39856893Sfenner#endif 39956893Sfenner if (memcmp(&ss, &cookiecache[i].raddr, salen) == 0) 40056893Sfenner return 1; 40156893Sfenner } 40256893Sfenner return 0; 40356893Sfenner} 40456893Sfenner 405214478Srpaulostatic void 406214478Srpaulohexprint(netdissect_options *ndo, caddr_t loc, size_t len) 40756893Sfenner{ 408214478Srpaulo u_char *p; 409127668Sbms size_t i; 41056893Sfenner 41156893Sfenner p = (u_char *)loc; 41256893Sfenner for (i = 0; i < len; i++) 413190207Srpaulo ND_PRINT((ndo,"%02x", p[i] & 0xff)); 414214478Srpaulo} 415214478Srpaulo 416214478Srpaulostatic int 417214478Srpaulorawprint(netdissect_options *ndo, caddr_t loc, size_t len) 418214478Srpaulo{ 419214478Srpaulo ND_TCHECK2(*loc, len); 420214478Srpaulo 421214478Srpaulo hexprint(ndo, loc, len); 422127668Sbms return 1; 423124488Sfennertrunc: 424127668Sbms return 0; 42556893Sfenner} 42656893Sfenner 427214478Srpaulo 428190207Srpaulo/* 429190207Srpaulo * returns false if we run out of data buffer 430190207Srpaulo */ 431190207Srpaulostatic int ike_show_somedata(struct netdissect_options *ndo, 432190207Srpaulo const u_char *cp, const u_char *ep) 433190207Srpaulo{ 434190207Srpaulo /* there is too much data, just show some of it */ 435190207Srpaulo const u_char *end = ep - 20; 436190207Srpaulo int elen = 20; 437190207Srpaulo int len = ep - cp; 438190207Srpaulo if(len > 10) { 439190207Srpaulo len = 10; 440190207Srpaulo } 441190207Srpaulo 442190207Srpaulo /* really shouldn't happen because of above */ 443190207Srpaulo if(end < cp + len) { 444190207Srpaulo end = cp+len; 445190207Srpaulo elen = ep - end; 446190207Srpaulo } 447190207Srpaulo 448190207Srpaulo ND_PRINT((ndo," data=(")); 449190207Srpaulo if(!rawprint(ndo, (caddr_t)(cp), len)) goto trunc; 450190207Srpaulo ND_PRINT((ndo, "...")); 451190207Srpaulo if(elen) { 452190207Srpaulo if(!rawprint(ndo, (caddr_t)(end), elen)) goto trunc; 453190207Srpaulo } 454190207Srpaulo ND_PRINT((ndo,")")); 455190207Srpaulo return 1; 456190207Srpaulo 457190207Srpaulotrunc: 458190207Srpaulo return 0; 459190207Srpaulo} 460190207Srpaulo 46156893Sfennerstruct attrmap { 462127668Sbms const char *type; 463127668Sbms u_int nvalue; 464127668Sbms const char *value[30]; /*XXX*/ 46556893Sfenner}; 46656893Sfenner 467127668Sbmsstatic const u_char * 468190207Srpauloikev1_attrmap_print(netdissect_options *ndo, 469190207Srpaulo const u_char *p, const u_char *ep, 470190207Srpaulo const struct attrmap *map, size_t nmap) 47156893Sfenner{ 47275115Sfenner u_int16_t *q; 47356893Sfenner int totlen; 47456893Sfenner u_int32_t t, v; 47556893Sfenner 47675115Sfenner q = (u_int16_t *)p; 47756893Sfenner if (p[0] & 0x80) 47856893Sfenner totlen = 4; 47956893Sfenner else 480127668Sbms totlen = 4 + EXTRACT_16BITS(&q[1]); 48156893Sfenner if (ep < p + totlen) { 482190207Srpaulo ND_PRINT((ndo,"[|attr]")); 48356893Sfenner return ep + 1; 48456893Sfenner } 48556893Sfenner 486190207Srpaulo ND_PRINT((ndo,"(")); 487127668Sbms t = EXTRACT_16BITS(&q[0]) & 0x7fff; 48856893Sfenner if (map && t < nmap && map[t].type) 489190207Srpaulo ND_PRINT((ndo,"type=%s ", map[t].type)); 49056893Sfenner else 491190207Srpaulo ND_PRINT((ndo,"type=#%d ", t)); 49256893Sfenner if (p[0] & 0x80) { 493190207Srpaulo ND_PRINT((ndo,"value=")); 494127668Sbms v = EXTRACT_16BITS(&q[1]); 49556893Sfenner if (map && t < nmap && v < map[t].nvalue && map[t].value[v]) 496190207Srpaulo ND_PRINT((ndo,"%s", map[t].value[v])); 49756893Sfenner else 498190207Srpaulo rawprint(ndo, (caddr_t)&q[1], 2); 49956893Sfenner } else { 500190207Srpaulo ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&q[1]))); 501190207Srpaulo rawprint(ndo, (caddr_t)&p[4], EXTRACT_16BITS(&q[1])); 50256893Sfenner } 503190207Srpaulo ND_PRINT((ndo,")")); 50456893Sfenner return p + totlen; 50556893Sfenner} 50656893Sfenner 507127668Sbmsstatic const u_char * 508190207Srpauloikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep) 50956893Sfenner{ 51075115Sfenner u_int16_t *q; 51156893Sfenner int totlen; 51256893Sfenner u_int32_t t; 51356893Sfenner 51475115Sfenner q = (u_int16_t *)p; 51556893Sfenner if (p[0] & 0x80) 51656893Sfenner totlen = 4; 51756893Sfenner else 518127668Sbms totlen = 4 + EXTRACT_16BITS(&q[1]); 51956893Sfenner if (ep < p + totlen) { 520190207Srpaulo ND_PRINT((ndo,"[|attr]")); 52156893Sfenner return ep + 1; 52256893Sfenner } 52356893Sfenner 524190207Srpaulo ND_PRINT((ndo,"(")); 525127668Sbms t = EXTRACT_16BITS(&q[0]) & 0x7fff; 526190207Srpaulo ND_PRINT((ndo,"type=#%d ", t)); 52756893Sfenner if (p[0] & 0x80) { 528190207Srpaulo ND_PRINT((ndo,"value=")); 52956893Sfenner t = q[1]; 530190207Srpaulo rawprint(ndo, (caddr_t)&q[1], 2); 53156893Sfenner } else { 532190207Srpaulo ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&q[1]))); 533190207Srpaulo rawprint(ndo, (caddr_t)&p[2], EXTRACT_16BITS(&q[1])); 53456893Sfenner } 535190207Srpaulo ND_PRINT((ndo,")")); 53656893Sfenner return p + totlen; 53756893Sfenner} 53856893Sfenner 539127668Sbmsstatic const u_char * 540190207Srpauloikev1_sa_print(netdissect_options *ndo, u_char tpay _U_, 541190207Srpaulo const struct isakmp_gen *ext, 542146773Ssam u_int item_len _U_, 543146773Ssam const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_, 544146773Ssam u_int32_t proto0, int depth) 54556893Sfenner{ 546190207Srpaulo const struct ikev1_pl_sa *p; 547190207Srpaulo struct ikev1_pl_sa sa; 548127668Sbms const u_int32_t *q; 54975115Sfenner u_int32_t doi, sit, ident; 550127668Sbms const u_char *cp, *np; 55156893Sfenner int t; 55256893Sfenner 553190207Srpaulo ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SA))); 55456893Sfenner 555190207Srpaulo p = (struct ikev1_pl_sa *)ext; 556190207Srpaulo ND_TCHECK(*p); 55775115Sfenner safememcpy(&sa, ext, sizeof(sa)); 55875115Sfenner doi = ntohl(sa.doi); 55975115Sfenner sit = ntohl(sa.sit); 56056893Sfenner if (doi != 1) { 561190207Srpaulo ND_PRINT((ndo," doi=%d", doi)); 562190207Srpaulo ND_PRINT((ndo," situation=%u", (u_int32_t)ntohl(sa.sit))); 56356893Sfenner return (u_char *)(p + 1); 56456893Sfenner } 56556893Sfenner 566190207Srpaulo ND_PRINT((ndo," doi=ipsec")); 56775115Sfenner q = (u_int32_t *)&sa.sit; 568190207Srpaulo ND_PRINT((ndo," situation=")); 56956893Sfenner t = 0; 57075115Sfenner if (sit & 0x01) { 571190207Srpaulo ND_PRINT((ndo,"identity")); 57256893Sfenner t++; 57356893Sfenner } 57475115Sfenner if (sit & 0x02) { 575190207Srpaulo ND_PRINT((ndo,"%ssecrecy", t ? "+" : "")); 57656893Sfenner t++; 57756893Sfenner } 57875115Sfenner if (sit & 0x04) 579190207Srpaulo ND_PRINT((ndo,"%sintegrity", t ? "+" : "")); 58056893Sfenner 58175115Sfenner np = (u_char *)ext + sizeof(sa); 58275115Sfenner if (sit != 0x01) { 583190207Srpaulo ND_TCHECK2(*(ext + 1), sizeof(ident)); 58475115Sfenner safememcpy(&ident, ext + 1, sizeof(ident)); 585190207Srpaulo ND_PRINT((ndo," ident=%u", (u_int32_t)ntohl(ident))); 58675115Sfenner np += sizeof(ident); 58775115Sfenner } 58856893Sfenner 58975115Sfenner ext = (struct isakmp_gen *)np; 590190207Srpaulo ND_TCHECK(*ext); 59156893Sfenner 592190207Srpaulo cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0, 593127668Sbms depth); 59456893Sfenner 59556893Sfenner return cp; 596127668Sbmstrunc: 597190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SA))); 598127668Sbms return NULL; 59956893Sfenner} 60056893Sfenner 601127668Sbmsstatic const u_char * 602190207Srpauloikev1_p_print(netdissect_options *ndo, u_char tpay _U_, 603190207Srpaulo const struct isakmp_gen *ext, u_int item_len _U_, 604146773Ssam const u_char *ep, u_int32_t phase, u_int32_t doi0, 605146773Ssam u_int32_t proto0 _U_, int depth) 60656893Sfenner{ 607190207Srpaulo const struct ikev1_pl_p *p; 608190207Srpaulo struct ikev1_pl_p prop; 609127668Sbms const u_char *cp; 61056893Sfenner 611190207Srpaulo ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_P))); 61256893Sfenner 613190207Srpaulo p = (struct ikev1_pl_p *)ext; 614190207Srpaulo ND_TCHECK(*p); 61575115Sfenner safememcpy(&prop, ext, sizeof(prop)); 616190207Srpaulo ND_PRINT((ndo," #%d protoid=%s transform=%d", 617190207Srpaulo prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t)); 61875115Sfenner if (prop.spi_size) { 619190207Srpaulo ND_PRINT((ndo," spi=")); 620190207Srpaulo if (!rawprint(ndo, (caddr_t)(p + 1), prop.spi_size)) 621127668Sbms goto trunc; 62256893Sfenner } 62356893Sfenner 62475115Sfenner ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size); 625190207Srpaulo ND_TCHECK(*ext); 626190207Srpaulo 627190207Srpaulo cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_T, ext, ep, phase, doi0, 628190207Srpaulo prop.prot_id, depth); 629190207Srpaulo 63056893Sfenner return cp; 631127668Sbmstrunc: 632190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P))); 633127668Sbms return NULL; 63456893Sfenner} 63556893Sfenner 636190207Srpaulostatic const char *ikev1_p_map[] = { 63756893Sfenner NULL, "ike", 63856893Sfenner}; 63956893Sfenner 640190207Srpaulostatic const char *ikev2_t_type_map[]={ 641190207Srpaulo NULL, "encr", "prf", "integ", "dh", "esn" 642190207Srpaulo}; 643190207Srpaulo 644127668Sbmsstatic const char *ah_p_map[] = { 64575115Sfenner NULL, "(reserved)", "md5", "sha", "1des", 64675115Sfenner "sha2-256", "sha2-384", "sha2-512", 64756893Sfenner}; 64856893Sfenner 649190207Srpaulostatic const char *prf_p_map[] = { 650190207Srpaulo NULL, "hmac-md5", "hmac-sha", "hmac-tiger", 651190207Srpaulo "aes128_xcbc" 652190207Srpaulo}; 653190207Srpaulo 654190207Srpaulostatic const char *integ_p_map[] = { 655190207Srpaulo NULL, "hmac-md5", "hmac-sha", "dec-mac", 656190207Srpaulo "kpdk-md5", "aes-xcbc" 657190207Srpaulo}; 658190207Srpaulo 659190207Srpaulostatic const char *esn_p_map[] = { 660190207Srpaulo "no-esn", "esn" 661190207Srpaulo}; 662190207Srpaulo 663190207Srpaulostatic const char *dh_p_map[] = { 664190207Srpaulo NULL, "modp768", 665190207Srpaulo "modp1024", /* group 2 */ 666190207Srpaulo "EC2N 2^155", /* group 3 */ 667190207Srpaulo "EC2N 2^185", /* group 4 */ 668190207Srpaulo "modp1536", /* group 5 */ 669190207Srpaulo "iana-grp06", "iana-grp07", /* reserved */ 670190207Srpaulo "iana-grp08", "iana-grp09", 671190207Srpaulo "iana-grp10", "iana-grp11", 672190207Srpaulo "iana-grp12", "iana-grp13", 673190207Srpaulo "modp2048", /* group 14 */ 674190207Srpaulo "modp3072", /* group 15 */ 675190207Srpaulo "modp4096", /* group 16 */ 676190207Srpaulo "modp6144", /* group 17 */ 677190207Srpaulo "modp8192", /* group 18 */ 678190207Srpaulo}; 679190207Srpaulo 680127668Sbmsstatic const char *esp_p_map[] = { 68156893Sfenner NULL, "1des-iv64", "1des", "3des", "rc5", "idea", "cast", 68275115Sfenner "blowfish", "3idea", "1des-iv32", "rc4", "null", "aes" 68356893Sfenner}; 68456893Sfenner 685127668Sbmsstatic const char *ipcomp_p_map[] = { 68656893Sfenner NULL, "oui", "deflate", "lzs", 68756893Sfenner}; 68856893Sfenner 689127668Sbmsconst struct attrmap ipsec_t_map[] = { 690127668Sbms { NULL, 0, { NULL } }, 69156893Sfenner { "lifetype", 3, { NULL, "sec", "kb", }, }, 692127668Sbms { "life", 0, { NULL } }, 693190207Srpaulo { "group desc", 18, { NULL, "modp768", 694190207Srpaulo "modp1024", /* group 2 */ 695190207Srpaulo "EC2N 2^155", /* group 3 */ 696190207Srpaulo "EC2N 2^185", /* group 4 */ 697190207Srpaulo "modp1536", /* group 5 */ 698190207Srpaulo "iana-grp06", "iana-grp07", /* reserved */ 699190207Srpaulo "iana-grp08", "iana-grp09", 700190207Srpaulo "iana-grp10", "iana-grp11", 701190207Srpaulo "iana-grp12", "iana-grp13", 702190207Srpaulo "modp2048", /* group 14 */ 703190207Srpaulo "modp3072", /* group 15 */ 704190207Srpaulo "modp4096", /* group 16 */ 705190207Srpaulo "modp6144", /* group 17 */ 706190207Srpaulo "modp8192", /* group 18 */ 707190207Srpaulo }, }, 70856893Sfenner { "enc mode", 3, { NULL, "tunnel", "transport", }, }, 70956893Sfenner { "auth", 5, { NULL, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, }, 710127668Sbms { "keylen", 0, { NULL } }, 711127668Sbms { "rounds", 0, { NULL } }, 712127668Sbms { "dictsize", 0, { NULL } }, 713127668Sbms { "privalg", 0, { NULL } }, 71456893Sfenner}; 71556893Sfenner 716190207Srpauloconst struct attrmap encr_t_map[] = { 717190207Srpaulo { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 0, 1 */ 718190207Srpaulo { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 2, 3 */ 719190207Srpaulo { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 4, 5 */ 720190207Srpaulo { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 6, 7 */ 721190207Srpaulo { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 8, 9 */ 722190207Srpaulo { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 10,11*/ 723190207Srpaulo { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 12,13*/ 724190207Srpaulo { "keylen", 14, { NULL }}, 725190207Srpaulo}; 726190207Srpaulo 727127668Sbmsconst struct attrmap oakley_t_map[] = { 728127668Sbms { NULL, 0, { NULL } }, 72975115Sfenner { "enc", 8, { NULL, "1des", "idea", "blowfish", "rc5", 73075115Sfenner "3des", "cast", "aes", }, }, 73175115Sfenner { "hash", 7, { NULL, "md5", "sha1", "tiger", 73275115Sfenner "sha2-256", "sha2-384", "sha2-512", }, }, 73356893Sfenner { "auth", 6, { NULL, "preshared", "dss", "rsa sig", "rsa enc", 73456893Sfenner "rsa enc revised", }, }, 735190207Srpaulo { "group desc", 18, { NULL, "modp768", 736190207Srpaulo "modp1024", /* group 2 */ 737190207Srpaulo "EC2N 2^155", /* group 3 */ 738190207Srpaulo "EC2N 2^185", /* group 4 */ 739190207Srpaulo "modp1536", /* group 5 */ 740190207Srpaulo "iana-grp06", "iana-grp07", /* reserved */ 741190207Srpaulo "iana-grp08", "iana-grp09", 742190207Srpaulo "iana-grp10", "iana-grp11", 743190207Srpaulo "iana-grp12", "iana-grp13", 744190207Srpaulo "modp2048", /* group 14 */ 745190207Srpaulo "modp3072", /* group 15 */ 746190207Srpaulo "modp4096", /* group 16 */ 747190207Srpaulo "modp6144", /* group 17 */ 748190207Srpaulo "modp8192", /* group 18 */ 749190207Srpaulo }, }, 75056893Sfenner { "group type", 4, { NULL, "MODP", "ECP", "EC2N", }, }, 751127668Sbms { "group prime", 0, { NULL } }, 752127668Sbms { "group gen1", 0, { NULL } }, 753127668Sbms { "group gen2", 0, { NULL } }, 754127668Sbms { "group curve A", 0, { NULL } }, 755127668Sbms { "group curve B", 0, { NULL } }, 75656893Sfenner { "lifetype", 3, { NULL, "sec", "kb", }, }, 757127668Sbms { "lifeduration", 0, { NULL } }, 758127668Sbms { "prf", 0, { NULL } }, 759127668Sbms { "keylen", 0, { NULL } }, 760127668Sbms { "field", 0, { NULL } }, 761127668Sbms { "order", 0, { NULL } }, 76256893Sfenner}; 76356893Sfenner 764127668Sbmsstatic const u_char * 765190207Srpauloikev1_t_print(netdissect_options *ndo, u_char tpay _U_, 766190207Srpaulo const struct isakmp_gen *ext, u_int item_len, 767190207Srpaulo const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_, 768190207Srpaulo u_int32_t proto, int depth _U_) 76956893Sfenner{ 770190207Srpaulo const struct ikev1_pl_t *p; 771190207Srpaulo struct ikev1_pl_t t; 772127668Sbms const u_char *cp; 773127668Sbms const char *idstr; 774127668Sbms const struct attrmap *map; 77556893Sfenner size_t nmap; 776127668Sbms const u_char *ep2; 77756893Sfenner 778190207Srpaulo ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_T))); 77956893Sfenner 780190207Srpaulo p = (struct ikev1_pl_t *)ext; 781190207Srpaulo ND_TCHECK(*p); 78275115Sfenner safememcpy(&t, ext, sizeof(t)); 78356893Sfenner 78456893Sfenner switch (proto) { 78556893Sfenner case 1: 786190207Srpaulo idstr = STR_OR_ID(t.t_id, ikev1_p_map); 78756893Sfenner map = oakley_t_map; 78856893Sfenner nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]); 78956893Sfenner break; 79056893Sfenner case 2: 79175115Sfenner idstr = STR_OR_ID(t.t_id, ah_p_map); 79256893Sfenner map = ipsec_t_map; 79356893Sfenner nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); 79456893Sfenner break; 79556893Sfenner case 3: 79675115Sfenner idstr = STR_OR_ID(t.t_id, esp_p_map); 79756893Sfenner map = ipsec_t_map; 79856893Sfenner nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); 79956893Sfenner break; 80056893Sfenner case 4: 80175115Sfenner idstr = STR_OR_ID(t.t_id, ipcomp_p_map); 80256893Sfenner map = ipsec_t_map; 80356893Sfenner nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); 80456893Sfenner break; 80556893Sfenner default: 80656893Sfenner idstr = NULL; 80756893Sfenner map = NULL; 80856893Sfenner nmap = 0; 80956893Sfenner break; 81056893Sfenner } 81156893Sfenner 81256893Sfenner if (idstr) 813190207Srpaulo ND_PRINT((ndo," #%d id=%s ", t.t_no, idstr)); 81456893Sfenner else 815190207Srpaulo ND_PRINT((ndo," #%d id=%d ", t.t_no, t.t_id)); 81656893Sfenner cp = (u_char *)(p + 1); 817127668Sbms ep2 = (u_char *)p + item_len; 81856893Sfenner while (cp < ep && cp < ep2) { 81956893Sfenner if (map && nmap) { 820190207Srpaulo cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2, 82156893Sfenner map, nmap); 82256893Sfenner } else 823190207Srpaulo cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2); 82456893Sfenner } 82556893Sfenner if (ep < ep2) 826190207Srpaulo ND_PRINT((ndo,"...")); 82756893Sfenner return cp; 828127668Sbmstrunc: 829190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_T))); 830127668Sbms return NULL; 83156893Sfenner} 83256893Sfenner 833127668Sbmsstatic const u_char * 834190207Srpauloikev1_ke_print(netdissect_options *ndo, u_char tpay _U_, 835190207Srpaulo const struct isakmp_gen *ext, u_int item_len _U_, 836190207Srpaulo const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_, 837190207Srpaulo u_int32_t proto _U_, int depth _U_) 83856893Sfenner{ 83975115Sfenner struct isakmp_gen e; 84075115Sfenner 841190207Srpaulo ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_KE))); 84256893Sfenner 843190207Srpaulo ND_TCHECK(*ext); 84475115Sfenner safememcpy(&e, ext, sizeof(e)); 845190207Srpaulo ND_PRINT((ndo," key len=%d", ntohs(e.len) - 4)); 846190207Srpaulo if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { 847190207Srpaulo ND_PRINT((ndo," ")); 848190207Srpaulo if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) 849127668Sbms goto trunc; 85056893Sfenner } 85175115Sfenner return (u_char *)ext + ntohs(e.len); 852127668Sbmstrunc: 853190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_KE))); 854127668Sbms return NULL; 85556893Sfenner} 85656893Sfenner 857127668Sbmsstatic const u_char * 858190207Srpauloikev1_id_print(netdissect_options *ndo, u_char tpay _U_, 859190207Srpaulo const struct isakmp_gen *ext, u_int item_len _U_, 860190207Srpaulo const u_char *ep _U_, u_int32_t phase, u_int32_t doi _U_, 861190207Srpaulo u_int32_t proto _U_, int depth _U_) 86256893Sfenner{ 86356893Sfenner#define USE_IPSECDOI_IN_PHASE1 1 864190207Srpaulo const struct ikev1_pl_id *p; 865190207Srpaulo struct ikev1_pl_id id; 866127668Sbms static const char *idtypestr[] = { 86756893Sfenner "IPv4", "IPv4net", "IPv6", "IPv6net", 86856893Sfenner }; 869127668Sbms static const char *ipsecidtypestr[] = { 87056893Sfenner NULL, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6", 87156893Sfenner "IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN", 87256893Sfenner "keyid", 87356893Sfenner }; 87456893Sfenner int len; 875127668Sbms const u_char *data; 87656893Sfenner 877190207Srpaulo ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_ID))); 87856893Sfenner 879190207Srpaulo p = (struct ikev1_pl_id *)ext; 880190207Srpaulo ND_TCHECK(*p); 88175115Sfenner safememcpy(&id, ext, sizeof(id)); 882127668Sbms if (sizeof(*p) < item_len) { 88356893Sfenner data = (u_char *)(p + 1); 884127668Sbms len = item_len - sizeof(*p); 885127668Sbms } else { 88656893Sfenner data = NULL; 887127668Sbms len = 0; 888127668Sbms } 88956893Sfenner 89056893Sfenner#if 0 /*debug*/ 891190207Srpaulo ND_PRINT((ndo," [phase=%d doi=%d proto=%d]", phase, doi, proto)); 89256893Sfenner#endif 89356893Sfenner switch (phase) { 89456893Sfenner#ifndef USE_IPSECDOI_IN_PHASE1 89556893Sfenner case 1: 89656893Sfenner#endif 89756893Sfenner default: 898190207Srpaulo ND_PRINT((ndo," idtype=%s", STR_OR_ID(id.d.id_type, idtypestr))); 899190207Srpaulo ND_PRINT((ndo," doi_data=%u", 900190207Srpaulo (u_int32_t)(ntohl(id.d.doi_data) & 0xffffff))); 90156893Sfenner break; 90256893Sfenner 90356893Sfenner#ifdef USE_IPSECDOI_IN_PHASE1 90456893Sfenner case 1: 90556893Sfenner#endif 90656893Sfenner case 2: 90756893Sfenner { 908127668Sbms const struct ipsecdoi_id *p; 909127668Sbms struct ipsecdoi_id id; 91056893Sfenner struct protoent *pe; 91156893Sfenner 91256893Sfenner p = (struct ipsecdoi_id *)ext; 913190207Srpaulo ND_TCHECK(*p); 91475115Sfenner safememcpy(&id, ext, sizeof(id)); 915190207Srpaulo ND_PRINT((ndo," idtype=%s", STR_OR_ID(id.type, ipsecidtypestr))); 91675115Sfenner if (id.proto_id) { 917127668Sbms#ifndef WIN32 91875115Sfenner setprotoent(1); 919127668Sbms#endif /* WIN32 */ 92075115Sfenner pe = getprotobynumber(id.proto_id); 92175115Sfenner if (pe) 922190207Srpaulo ND_PRINT((ndo," protoid=%s", pe->p_name)); 923127668Sbms#ifndef WIN32 92475115Sfenner endprotoent(); 925127668Sbms#endif /* WIN32 */ 92675115Sfenner } else { 92775115Sfenner /* it DOES NOT mean IPPROTO_IP! */ 928190207Srpaulo ND_PRINT((ndo," protoid=%s", "0")); 92975115Sfenner } 930190207Srpaulo ND_PRINT((ndo," port=%d", ntohs(id.port))); 93156893Sfenner if (!len) 93256893Sfenner break; 933127668Sbms if (data == NULL) 934127668Sbms goto trunc; 935190207Srpaulo ND_TCHECK2(*data, len); 93675115Sfenner switch (id.type) { 93756893Sfenner case IPSECDOI_ID_IPV4_ADDR: 938127668Sbms if (len < 4) 939190207Srpaulo ND_PRINT((ndo," len=%d [bad: < 4]", len)); 940127668Sbms else 941190207Srpaulo ND_PRINT((ndo," len=%d %s", len, ipaddr_string(data))); 94256893Sfenner len = 0; 94356893Sfenner break; 94456893Sfenner case IPSECDOI_ID_FQDN: 94556893Sfenner case IPSECDOI_ID_USER_FQDN: 94656893Sfenner { 94756893Sfenner int i; 948190207Srpaulo ND_PRINT((ndo," len=%d ", len)); 94998524Sfenner for (i = 0; i < len; i++) 95098524Sfenner safeputchar(data[i]); 95156893Sfenner len = 0; 95256893Sfenner break; 95356893Sfenner } 95456893Sfenner case IPSECDOI_ID_IPV4_ADDR_SUBNET: 95556893Sfenner { 956127668Sbms const u_char *mask; 957127668Sbms if (len < 8) 958190207Srpaulo ND_PRINT((ndo," len=%d [bad: < 8]", len)); 959127668Sbms else { 960127668Sbms mask = data + sizeof(struct in_addr); 961190207Srpaulo ND_PRINT((ndo," len=%d %s/%u.%u.%u.%u", len, 962190207Srpaulo ipaddr_string(data), 963190207Srpaulo mask[0], mask[1], mask[2], mask[3])); 964127668Sbms } 96556893Sfenner len = 0; 96656893Sfenner break; 96756893Sfenner } 96856893Sfenner#ifdef INET6 96956893Sfenner case IPSECDOI_ID_IPV6_ADDR: 970127668Sbms if (len < 16) 971190207Srpaulo ND_PRINT((ndo," len=%d [bad: < 16]", len)); 972127668Sbms else 973190207Srpaulo ND_PRINT((ndo," len=%d %s", len, ip6addr_string(data))); 97456893Sfenner len = 0; 97556893Sfenner break; 97656893Sfenner case IPSECDOI_ID_IPV6_ADDR_SUBNET: 97756893Sfenner { 978127668Sbms const u_int32_t *mask; 979127668Sbms if (len < 20) 980190207Srpaulo ND_PRINT((ndo," len=%d [bad: < 20]", len)); 981127668Sbms else { 982127668Sbms mask = (u_int32_t *)(data + sizeof(struct in6_addr)); 983127668Sbms /*XXX*/ 984190207Srpaulo ND_PRINT((ndo," len=%d %s/0x%08x%08x%08x%08x", len, 985190207Srpaulo ip6addr_string(data), 986190207Srpaulo mask[0], mask[1], mask[2], mask[3])); 987127668Sbms } 98856893Sfenner len = 0; 98956893Sfenner break; 99056893Sfenner } 99156893Sfenner#endif /*INET6*/ 99256893Sfenner case IPSECDOI_ID_IPV4_ADDR_RANGE: 993127668Sbms if (len < 8) 994190207Srpaulo ND_PRINT((ndo," len=%d [bad: < 8]", len)); 995127668Sbms else { 996190207Srpaulo ND_PRINT((ndo," len=%d %s-%s", len, 997190207Srpaulo ipaddr_string(data), 998190207Srpaulo ipaddr_string(data + sizeof(struct in_addr)))); 999127668Sbms } 100056893Sfenner len = 0; 100156893Sfenner break; 100256893Sfenner#ifdef INET6 100356893Sfenner case IPSECDOI_ID_IPV6_ADDR_RANGE: 1004127668Sbms if (len < 32) 1005190207Srpaulo ND_PRINT((ndo," len=%d [bad: < 32]", len)); 1006127668Sbms else { 1007190207Srpaulo ND_PRINT((ndo," len=%d %s-%s", len, 1008190207Srpaulo ip6addr_string(data), 1009190207Srpaulo ip6addr_string(data + sizeof(struct in6_addr)))); 1010127668Sbms } 101156893Sfenner len = 0; 101256893Sfenner break; 101356893Sfenner#endif /*INET6*/ 101456893Sfenner case IPSECDOI_ID_DER_ASN1_DN: 101556893Sfenner case IPSECDOI_ID_DER_ASN1_GN: 101656893Sfenner case IPSECDOI_ID_KEY_ID: 101756893Sfenner break; 101856893Sfenner } 101956893Sfenner break; 102056893Sfenner } 102156893Sfenner } 102256893Sfenner if (data && len) { 1023190207Srpaulo ND_PRINT((ndo," len=%d", len)); 1024190207Srpaulo if (2 < ndo->ndo_vflag) { 1025190207Srpaulo ND_PRINT((ndo," ")); 1026190207Srpaulo if (!rawprint(ndo, (caddr_t)data, len)) 1027127668Sbms goto trunc; 102856893Sfenner } 102956893Sfenner } 1030127668Sbms return (u_char *)ext + item_len; 1031127668Sbmstrunc: 1032190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_ID))); 1033127668Sbms return NULL; 103456893Sfenner} 103556893Sfenner 1036127668Sbmsstatic const u_char * 1037190207Srpauloikev1_cert_print(netdissect_options *ndo, u_char tpay _U_, 1038190207Srpaulo const struct isakmp_gen *ext, u_int item_len _U_, 1039190207Srpaulo const u_char *ep _U_, u_int32_t phase _U_, 1040190207Srpaulo u_int32_t doi0 _U_, 1041190207Srpaulo u_int32_t proto0 _U_, int depth _U_) 104275115Sfenner{ 1043190207Srpaulo const struct ikev1_pl_cert *p; 1044190207Srpaulo struct ikev1_pl_cert cert; 1045127668Sbms static const char *certstr[] = { 104675115Sfenner "none", "pkcs7", "pgp", "dns", 104775115Sfenner "x509sign", "x509ke", "kerberos", "crl", 104875115Sfenner "arl", "spki", "x509attr", 104975115Sfenner }; 105075115Sfenner 1051190207Srpaulo ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CERT))); 105275115Sfenner 1053190207Srpaulo p = (struct ikev1_pl_cert *)ext; 1054190207Srpaulo ND_TCHECK(*p); 105575115Sfenner safememcpy(&cert, ext, sizeof(cert)); 1056190207Srpaulo ND_PRINT((ndo," len=%d", item_len - 4)); 1057190207Srpaulo ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr))); 1058190207Srpaulo if (2 < ndo->ndo_vflag && 4 < item_len) { 1059190207Srpaulo ND_PRINT((ndo," ")); 1060190207Srpaulo if (!rawprint(ndo, (caddr_t)(ext + 1), item_len - 4)) 1061127668Sbms goto trunc; 106275115Sfenner } 1063127668Sbms return (u_char *)ext + item_len; 1064127668Sbmstrunc: 1065190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CERT))); 1066127668Sbms return NULL; 106775115Sfenner} 106875115Sfenner 1069127668Sbmsstatic const u_char * 1070190207Srpauloikev1_cr_print(netdissect_options *ndo, u_char tpay _U_, 1071190207Srpaulo const struct isakmp_gen *ext, u_int item_len _U_, 1072190207Srpaulo const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi0 _U_, 1073190207Srpaulo u_int32_t proto0 _U_, int depth _U_) 107475115Sfenner{ 1075190207Srpaulo const struct ikev1_pl_cert *p; 1076190207Srpaulo struct ikev1_pl_cert cert; 1077127668Sbms static const char *certstr[] = { 107875115Sfenner "none", "pkcs7", "pgp", "dns", 107975115Sfenner "x509sign", "x509ke", "kerberos", "crl", 108075115Sfenner "arl", "spki", "x509attr", 108175115Sfenner }; 108275115Sfenner 1083190207Srpaulo ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CR))); 108475115Sfenner 1085190207Srpaulo p = (struct ikev1_pl_cert *)ext; 1086190207Srpaulo ND_TCHECK(*p); 108775115Sfenner safememcpy(&cert, ext, sizeof(cert)); 1088190207Srpaulo ND_PRINT((ndo," len=%d", item_len - 4)); 1089190207Srpaulo ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr))); 1090190207Srpaulo if (2 < ndo->ndo_vflag && 4 < item_len) { 1091190207Srpaulo ND_PRINT((ndo," ")); 1092190207Srpaulo if (!rawprint(ndo, (caddr_t)(ext + 1), item_len - 4)) 1093127668Sbms goto trunc; 109475115Sfenner } 1095127668Sbms return (u_char *)ext + item_len; 1096127668Sbmstrunc: 1097190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CR))); 1098127668Sbms return NULL; 109975115Sfenner} 110075115Sfenner 1101127668Sbmsstatic const u_char * 1102190207Srpauloikev1_hash_print(netdissect_options *ndo, u_char tpay _U_, 1103190207Srpaulo const struct isakmp_gen *ext, u_int item_len _U_, 1104190207Srpaulo const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_, 1105190207Srpaulo u_int32_t proto _U_, int depth _U_) 110656893Sfenner{ 110775115Sfenner struct isakmp_gen e; 110875115Sfenner 1109190207Srpaulo ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_HASH))); 111056893Sfenner 1111190207Srpaulo ND_TCHECK(*ext); 111275115Sfenner safememcpy(&e, ext, sizeof(e)); 1113190207Srpaulo ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); 1114190207Srpaulo if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { 1115190207Srpaulo ND_PRINT((ndo," ")); 1116190207Srpaulo if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) 1117127668Sbms goto trunc; 111856893Sfenner } 111975115Sfenner return (u_char *)ext + ntohs(e.len); 1120127668Sbmstrunc: 1121190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_HASH))); 1122127668Sbms return NULL; 112356893Sfenner} 112456893Sfenner 1125127668Sbmsstatic const u_char * 1126190207Srpauloikev1_sig_print(netdissect_options *ndo, u_char tpay _U_, 1127190207Srpaulo const struct isakmp_gen *ext, u_int item_len _U_, 1128190207Srpaulo const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_, 1129190207Srpaulo u_int32_t proto _U_, int depth _U_) 113075115Sfenner{ 113175115Sfenner struct isakmp_gen e; 113275115Sfenner 1133190207Srpaulo ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SIG))); 113475115Sfenner 1135190207Srpaulo ND_TCHECK(*ext); 113675115Sfenner safememcpy(&e, ext, sizeof(e)); 1137190207Srpaulo ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); 1138190207Srpaulo if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { 1139190207Srpaulo ND_PRINT((ndo," ")); 1140190207Srpaulo if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) 1141127668Sbms goto trunc; 114275115Sfenner } 114375115Sfenner return (u_char *)ext + ntohs(e.len); 1144127668Sbmstrunc: 1145190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SIG))); 1146127668Sbms return NULL; 114775115Sfenner} 114875115Sfenner 1149127668Sbmsstatic const u_char * 1150190207Srpauloikev1_nonce_print(netdissect_options *ndo, u_char tpay _U_, 1151190207Srpaulo const struct isakmp_gen *ext, 1152190207Srpaulo u_int item_len _U_, 1153190207Srpaulo const u_char *ep _U_, 1154190207Srpaulo u_int32_t phase _U_, u_int32_t doi _U_, 1155190207Srpaulo u_int32_t proto _U_, int depth _U_) 115656893Sfenner{ 115775115Sfenner struct isakmp_gen e; 115875115Sfenner 1159190207Srpaulo ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_NONCE))); 116056893Sfenner 1161190207Srpaulo ND_TCHECK(*ext); 116275115Sfenner safememcpy(&e, ext, sizeof(e)); 1163190207Srpaulo ND_PRINT((ndo," n len=%d", ntohs(e.len) - 4)); 1164190207Srpaulo if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { 1165190207Srpaulo ND_PRINT((ndo," ")); 1166190207Srpaulo if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) 1167127668Sbms goto trunc; 1168190207Srpaulo } else if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) { 1169190207Srpaulo ND_PRINT((ndo," ")); 1170190207Srpaulo if (!ike_show_somedata(ndo, (u_char *)(caddr_t)(ext + 1), ep)) 1171190207Srpaulo goto trunc; 117256893Sfenner } 117375115Sfenner return (u_char *)ext + ntohs(e.len); 1174127668Sbmstrunc: 1175190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_NONCE))); 1176127668Sbms return NULL; 117756893Sfenner} 117856893Sfenner 1179127668Sbmsstatic const u_char * 1180190207Srpauloikev1_n_print(netdissect_options *ndo, u_char tpay _U_, 1181190207Srpaulo const struct isakmp_gen *ext, u_int item_len, 1182190207Srpaulo const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_, 1183190207Srpaulo u_int32_t proto0 _U_, int depth) 118456893Sfenner{ 1185190207Srpaulo struct ikev1_pl_n *p, n; 1186127668Sbms const u_char *cp; 118756893Sfenner u_char *ep2; 118856893Sfenner u_int32_t doi; 118956893Sfenner u_int32_t proto; 1190127668Sbms static const char *notify_error_str[] = { 119156893Sfenner NULL, "INVALID-PAYLOAD-TYPE", 119256893Sfenner "DOI-NOT-SUPPORTED", "SITUATION-NOT-SUPPORTED", 119356893Sfenner "INVALID-COOKIE", "INVALID-MAJOR-VERSION", 119456893Sfenner "INVALID-MINOR-VERSION", "INVALID-EXCHANGE-TYPE", 119556893Sfenner "INVALID-FLAGS", "INVALID-MESSAGE-ID", 119656893Sfenner "INVALID-PROTOCOL-ID", "INVALID-SPI", 119756893Sfenner "INVALID-TRANSFORM-ID", "ATTRIBUTES-NOT-SUPPORTED", 119856893Sfenner "NO-PROPOSAL-CHOSEN", "BAD-PROPOSAL-SYNTAX", 119956893Sfenner "PAYLOAD-MALFORMED", "INVALID-KEY-INFORMATION", 120056893Sfenner "INVALID-ID-INFORMATION", "INVALID-CERT-ENCODING", 120156893Sfenner "INVALID-CERTIFICATE", "CERT-TYPE-UNSUPPORTED", 120256893Sfenner "INVALID-CERT-AUTHORITY", "INVALID-HASH-INFORMATION", 120356893Sfenner "AUTHENTICATION-FAILED", "INVALID-SIGNATURE", 120456893Sfenner "ADDRESS-NOTIFICATION", "NOTIFY-SA-LIFETIME", 120556893Sfenner "CERTIFICATE-UNAVAILABLE", "UNSUPPORTED-EXCHANGE-TYPE", 120656893Sfenner "UNEQUAL-PAYLOAD-LENGTHS", 120756893Sfenner }; 1208127668Sbms static const char *ipsec_notify_error_str[] = { 1209127668Sbms "RESERVED", 1210127668Sbms }; 1211127668Sbms static const char *notify_status_str[] = { 1212127668Sbms "CONNECTED", 1213127668Sbms }; 1214127668Sbms static const char *ipsec_notify_status_str[] = { 121556893Sfenner "RESPONDER-LIFETIME", "REPLAY-STATUS", 121656893Sfenner "INITIAL-CONTACT", 121756893Sfenner }; 121856893Sfenner/* NOTE: these macro must be called with x in proper range */ 121956893Sfenner 1220127668Sbms/* 0 - 8191 */ 1221127668Sbms#define NOTIFY_ERROR_STR(x) \ 1222127668Sbms STR_OR_ID((x), notify_error_str) 1223127668Sbms 1224127668Sbms/* 8192 - 16383 */ 1225127668Sbms#define IPSEC_NOTIFY_ERROR_STR(x) \ 1226127668Sbms STR_OR_ID((u_int)((x) - 8192), ipsec_notify_error_str) 1227127668Sbms 1228127668Sbms/* 16384 - 24575 */ 1229127668Sbms#define NOTIFY_STATUS_STR(x) \ 1230127668Sbms STR_OR_ID((u_int)((x) - 16384), notify_status_str) 1231127668Sbms 1232127668Sbms/* 24576 - 32767 */ 1233127668Sbms#define IPSEC_NOTIFY_STATUS_STR(x) \ 1234127668Sbms STR_OR_ID((u_int)((x) - 24576), ipsec_notify_status_str) 1235127668Sbms 1236190207Srpaulo ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_N))); 123756893Sfenner 1238190207Srpaulo p = (struct ikev1_pl_n *)ext; 1239190207Srpaulo ND_TCHECK(*p); 124075115Sfenner safememcpy(&n, ext, sizeof(n)); 124175115Sfenner doi = ntohl(n.doi); 124275115Sfenner proto = n.prot_id; 124356893Sfenner if (doi != 1) { 1244190207Srpaulo ND_PRINT((ndo," doi=%d", doi)); 1245190207Srpaulo ND_PRINT((ndo," proto=%d", proto)); 1246127668Sbms if (ntohs(n.type) < 8192) 1247190207Srpaulo ND_PRINT((ndo," type=%s", NOTIFY_ERROR_STR(ntohs(n.type)))); 1248127668Sbms else if (ntohs(n.type) < 16384) 1249190207Srpaulo ND_PRINT((ndo," type=%s", numstr(ntohs(n.type)))); 1250127668Sbms else if (ntohs(n.type) < 24576) 1251190207Srpaulo ND_PRINT((ndo," type=%s", NOTIFY_STATUS_STR(ntohs(n.type)))); 1252127668Sbms else 1253190207Srpaulo ND_PRINT((ndo," type=%s", numstr(ntohs(n.type)))); 125475115Sfenner if (n.spi_size) { 1255190207Srpaulo ND_PRINT((ndo," spi=")); 1256190207Srpaulo if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size)) 1257127668Sbms goto trunc; 125856893Sfenner } 125975115Sfenner return (u_char *)(p + 1) + n.spi_size; 126056893Sfenner } 126156893Sfenner 1262190207Srpaulo ND_PRINT((ndo," doi=ipsec")); 1263190207Srpaulo ND_PRINT((ndo," proto=%s", PROTOIDSTR(proto))); 126475115Sfenner if (ntohs(n.type) < 8192) 1265190207Srpaulo ND_PRINT((ndo," type=%s", NOTIFY_ERROR_STR(ntohs(n.type)))); 126675115Sfenner else if (ntohs(n.type) < 16384) 1267190207Srpaulo ND_PRINT((ndo," type=%s", IPSEC_NOTIFY_ERROR_STR(ntohs(n.type)))); 126875115Sfenner else if (ntohs(n.type) < 24576) 1269190207Srpaulo ND_PRINT((ndo," type=%s", NOTIFY_STATUS_STR(ntohs(n.type)))); 1270127668Sbms else if (ntohs(n.type) < 32768) 1271190207Srpaulo ND_PRINT((ndo," type=%s", IPSEC_NOTIFY_STATUS_STR(ntohs(n.type)))); 127256893Sfenner else 1273190207Srpaulo ND_PRINT((ndo," type=%s", numstr(ntohs(n.type)))); 127475115Sfenner if (n.spi_size) { 1275190207Srpaulo ND_PRINT((ndo," spi=")); 1276190207Srpaulo if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size)) 1277127668Sbms goto trunc; 127856893Sfenner } 127956893Sfenner 128075115Sfenner cp = (u_char *)(p + 1) + n.spi_size; 1281127668Sbms ep2 = (u_char *)p + item_len; 128256893Sfenner 128356893Sfenner if (cp < ep) { 1284190207Srpaulo ND_PRINT((ndo," orig=(")); 128575115Sfenner switch (ntohs(n.type)) { 128656893Sfenner case IPSECDOI_NTYPE_RESPONDER_LIFETIME: 128756893Sfenner { 1288127668Sbms const struct attrmap *map = oakley_t_map; 128956893Sfenner size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]); 129056893Sfenner while (cp < ep && cp < ep2) { 1291190207Srpaulo cp = ikev1_attrmap_print(ndo, cp, 129256893Sfenner (ep < ep2) ? ep : ep2, map, nmap); 129356893Sfenner } 129456893Sfenner break; 129556893Sfenner } 129656893Sfenner case IPSECDOI_NTYPE_REPLAY_STATUS: 1297190207Srpaulo ND_PRINT((ndo,"replay detection %sabled", 1298190207Srpaulo (*(u_int32_t *)cp) ? "en" : "dis")); 129956893Sfenner break; 130056893Sfenner case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN: 1301190207Srpaulo if (ikev1_sub_print(ndo, ISAKMP_NPTYPE_SA, 1302190207Srpaulo (struct isakmp_gen *)cp, ep, phase, doi, proto, 1303190207Srpaulo depth) == NULL) 1304127668Sbms return NULL; 130556893Sfenner break; 130656893Sfenner default: 130756893Sfenner /* NULL is dummy */ 1308190207Srpaulo isakmp_print(ndo, cp, 1309146773Ssam item_len - sizeof(*p) - n.spi_size, 1310146773Ssam NULL); 131156893Sfenner } 1312190207Srpaulo ND_PRINT((ndo,")")); 131356893Sfenner } 1314127668Sbms return (u_char *)ext + item_len; 1315127668Sbmstrunc: 1316190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N))); 1317127668Sbms return NULL; 131856893Sfenner} 131956893Sfenner 1320127668Sbmsstatic const u_char * 1321190207Srpauloikev1_d_print(netdissect_options *ndo, u_char tpay _U_, 1322190207Srpaulo const struct isakmp_gen *ext, u_int item_len _U_, 1323190207Srpaulo const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi0 _U_, 1324190207Srpaulo u_int32_t proto0 _U_, int depth _U_) 132556893Sfenner{ 1326190207Srpaulo const struct ikev1_pl_d *p; 1327190207Srpaulo struct ikev1_pl_d d; 1328127668Sbms const u_int8_t *q; 132956893Sfenner u_int32_t doi; 133056893Sfenner u_int32_t proto; 133156893Sfenner int i; 133256893Sfenner 1333190207Srpaulo ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_D))); 133456893Sfenner 1335190207Srpaulo p = (struct ikev1_pl_d *)ext; 1336190207Srpaulo ND_TCHECK(*p); 133775115Sfenner safememcpy(&d, ext, sizeof(d)); 133875115Sfenner doi = ntohl(d.doi); 133975115Sfenner proto = d.prot_id; 134056893Sfenner if (doi != 1) { 1341190207Srpaulo ND_PRINT((ndo," doi=%u", doi)); 1342190207Srpaulo ND_PRINT((ndo," proto=%u", proto)); 134356893Sfenner } else { 1344190207Srpaulo ND_PRINT((ndo," doi=ipsec")); 1345190207Srpaulo ND_PRINT((ndo," proto=%s", PROTOIDSTR(proto))); 134656893Sfenner } 1347190207Srpaulo ND_PRINT((ndo," spilen=%u", d.spi_size)); 1348190207Srpaulo ND_PRINT((ndo," nspi=%u", ntohs(d.num_spi))); 1349190207Srpaulo ND_PRINT((ndo," spi=")); 135056893Sfenner q = (u_int8_t *)(p + 1); 135175115Sfenner for (i = 0; i < ntohs(d.num_spi); i++) { 135256893Sfenner if (i != 0) 1353190207Srpaulo ND_PRINT((ndo,",")); 1354190207Srpaulo if (!rawprint(ndo, (caddr_t)q, d.spi_size)) 1355127668Sbms goto trunc; 135675115Sfenner q += d.spi_size; 135756893Sfenner } 135856893Sfenner return q; 1359127668Sbmstrunc: 1360190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_D))); 1361127668Sbms return NULL; 136256893Sfenner} 136356893Sfenner 1364127668Sbmsstatic const u_char * 1365190207Srpauloikev1_vid_print(netdissect_options *ndo, u_char tpay _U_, 1366190207Srpaulo const struct isakmp_gen *ext, 1367190207Srpaulo u_int item_len _U_, const u_char *ep _U_, 1368190207Srpaulo u_int32_t phase _U_, u_int32_t doi _U_, 1369190207Srpaulo u_int32_t proto _U_, int depth _U_) 137056893Sfenner{ 137175115Sfenner struct isakmp_gen e; 137275115Sfenner 1373190207Srpaulo ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_VID))); 137456893Sfenner 1375190207Srpaulo ND_TCHECK(*ext); 137675115Sfenner safememcpy(&e, ext, sizeof(e)); 1377190207Srpaulo ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); 1378190207Srpaulo if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { 1379190207Srpaulo ND_PRINT((ndo," ")); 1380190207Srpaulo if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) 1381127668Sbms goto trunc; 138256893Sfenner } 138375115Sfenner return (u_char *)ext + ntohs(e.len); 1384127668Sbmstrunc: 1385190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_VID))); 1386127668Sbms return NULL; 138756893Sfenner} 138856893Sfenner 1389190207Srpaulo/************************************************************/ 1390190207Srpaulo/* */ 1391190207Srpaulo/* IKE v2 - rfc4306 - dissector */ 1392190207Srpaulo/* */ 1393190207Srpaulo/************************************************************/ 1394190207Srpaulo 1395190207Srpaulostatic void 1396190207Srpauloikev2_pay_print(netdissect_options *ndo, const char *payname, int critical) 1397190207Srpaulo{ 1398190207Srpaulo ND_PRINT((ndo,"%s%s:", payname, critical&0x80 ? "[C]" : "")); 1399190207Srpaulo} 1400190207Srpaulo 1401127668Sbmsstatic const u_char * 1402190207Srpauloikev2_gen_print(netdissect_options *ndo, u_char tpay, 1403190207Srpaulo const struct isakmp_gen *ext) 140456893Sfenner{ 1405190207Srpaulo struct isakmp_gen e; 1406190207Srpaulo 1407190207Srpaulo ND_TCHECK(*ext); 1408190207Srpaulo safememcpy(&e, ext, sizeof(e)); 1409190207Srpaulo ikev2_pay_print(ndo, NPSTR(tpay), e.critical); 1410190207Srpaulo 1411190207Srpaulo ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); 1412190207Srpaulo if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) { 1413190207Srpaulo ND_PRINT((ndo," ")); 1414190207Srpaulo if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) 1415190207Srpaulo goto trunc; 1416190207Srpaulo } 1417190207Srpaulo return (u_char *)ext + ntohs(e.len); 1418190207Srpaulotrunc: 1419190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(tpay))); 1420190207Srpaulo return NULL; 1421190207Srpaulo} 1422190207Srpaulo 1423190207Srpaulostatic const u_char * 1424190207Srpauloikev2_t_print(netdissect_options *ndo, u_char tpay _U_, int pcount, 1425190207Srpaulo const struct isakmp_gen *ext, u_int item_len, 1426190207Srpaulo const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_, 1427190207Srpaulo u_int32_t proto _U_, int depth _U_) 1428190207Srpaulo{ 1429190207Srpaulo const struct ikev2_t *p; 1430190207Srpaulo struct ikev2_t t; 1431190207Srpaulo u_int16_t t_id; 1432127668Sbms const u_char *cp; 1433190207Srpaulo const char *idstr; 1434190207Srpaulo const struct attrmap *map; 1435190207Srpaulo size_t nmap; 1436190207Srpaulo const u_char *ep2; 1437190207Srpaulo 1438190207Srpaulo p = (struct ikev2_t *)ext; 1439190207Srpaulo ND_TCHECK(*p); 1440190207Srpaulo safememcpy(&t, ext, sizeof(t)); 1441190207Srpaulo ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_T), t.h.critical); 1442190207Srpaulo 1443190207Srpaulo t_id = ntohs(t.t_id); 1444190207Srpaulo 1445190207Srpaulo map = NULL; 1446190207Srpaulo nmap = 0; 1447190207Srpaulo 1448190207Srpaulo switch (t.t_type) { 1449190207Srpaulo case IV2_T_ENCR: 1450190207Srpaulo idstr = STR_OR_ID(t_id, esp_p_map); 1451190207Srpaulo map = encr_t_map; 1452190207Srpaulo nmap = sizeof(encr_t_map)/sizeof(encr_t_map[0]); 1453190207Srpaulo break; 1454190207Srpaulo 1455190207Srpaulo case IV2_T_PRF: 1456190207Srpaulo idstr = STR_OR_ID(t_id, prf_p_map); 1457190207Srpaulo break; 1458190207Srpaulo 1459190207Srpaulo case IV2_T_INTEG: 1460190207Srpaulo idstr = STR_OR_ID(t_id, integ_p_map); 1461190207Srpaulo break; 1462190207Srpaulo 1463190207Srpaulo case IV2_T_DH: 1464190207Srpaulo idstr = STR_OR_ID(t_id, dh_p_map); 1465190207Srpaulo break; 1466190207Srpaulo 1467190207Srpaulo case IV2_T_ESN: 1468190207Srpaulo idstr = STR_OR_ID(t_id, esn_p_map); 1469190207Srpaulo break; 1470190207Srpaulo 1471190207Srpaulo default: 1472190207Srpaulo idstr = NULL; 1473190207Srpaulo break; 1474190207Srpaulo } 1475190207Srpaulo 1476190207Srpaulo if (idstr) 1477190207Srpaulo ND_PRINT((ndo," #%u type=%s id=%s ", pcount, 1478190207Srpaulo STR_OR_ID(t.t_type, ikev2_t_type_map), 1479190207Srpaulo idstr)); 1480190207Srpaulo else 1481190207Srpaulo ND_PRINT((ndo," #%u type=%s id=%u ", pcount, 1482190207Srpaulo STR_OR_ID(t.t_type, ikev2_t_type_map), 1483190207Srpaulo t.t_id)); 1484190207Srpaulo cp = (u_char *)(p + 1); 1485190207Srpaulo ep2 = (u_char *)p + item_len; 1486190207Srpaulo while (cp < ep && cp < ep2) { 1487190207Srpaulo if (map && nmap) { 1488190207Srpaulo cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2, 1489190207Srpaulo map, nmap); 1490190207Srpaulo } else 1491190207Srpaulo cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2); 1492190207Srpaulo } 1493190207Srpaulo if (ep < ep2) 1494190207Srpaulo ND_PRINT((ndo,"...")); 1495190207Srpaulo return cp; 1496190207Srpaulotrunc: 1497190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_T))); 1498190207Srpaulo return NULL; 1499190207Srpaulo} 1500190207Srpaulo 1501190207Srpaulostatic const u_char * 1502190207Srpauloikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_, 1503190207Srpaulo const struct isakmp_gen *ext, u_int item_len _U_, 1504190207Srpaulo const u_char *ep, u_int32_t phase, u_int32_t doi0, 1505190207Srpaulo u_int32_t proto0 _U_, int depth) 1506190207Srpaulo{ 1507190207Srpaulo const struct ikev2_p *p; 1508190207Srpaulo struct ikev2_p prop; 1509190207Srpaulo const u_char *cp; 1510190207Srpaulo 1511190207Srpaulo p = (struct ikev2_p *)ext; 1512190207Srpaulo ND_TCHECK(*p); 1513190207Srpaulo safememcpy(&prop, ext, sizeof(prop)); 1514190207Srpaulo ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_P), prop.h.critical); 1515190207Srpaulo 1516214478Srpaulo ND_PRINT((ndo," #%u protoid=%s transform=%d len=%u", 1517214478Srpaulo prop.p_no, PROTOIDSTR(prop.prot_id), 1518214478Srpaulo prop.num_t, ntohs(prop.h.len))); 1519190207Srpaulo if (prop.spi_size) { 1520190207Srpaulo ND_PRINT((ndo," spi=")); 1521190207Srpaulo if (!rawprint(ndo, (caddr_t)(p + 1), prop.spi_size)) 1522190207Srpaulo goto trunc; 1523190207Srpaulo } 1524190207Srpaulo 1525190207Srpaulo ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size); 1526190207Srpaulo ND_TCHECK(*ext); 1527214478Srpaulo 1528214478Srpaulo cp = ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_T, ext, ep, phase, doi0, 1529190207Srpaulo prop.prot_id, depth); 1530190207Srpaulo 1531190207Srpaulo return cp; 1532190207Srpaulotrunc: 1533190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P))); 1534190207Srpaulo return NULL; 1535190207Srpaulo} 1536190207Srpaulo 1537190207Srpaulostatic const u_char * 1538190207Srpauloikev2_sa_print(netdissect_options *ndo, u_char tpay, 1539190207Srpaulo const struct isakmp_gen *ext1, 1540190207Srpaulo u_int item_len _U_, const u_char *ep _U_, 1541190207Srpaulo u_int32_t phase _U_, u_int32_t doi _U_, 1542190207Srpaulo u_int32_t proto _U_, int depth _U_) 1543190207Srpaulo{ 154475115Sfenner struct isakmp_gen e; 1545214478Srpaulo int osa_length, sa_length; 1546190207Srpaulo 1547190207Srpaulo ND_TCHECK(*ext1); 1548190207Srpaulo safememcpy(&e, ext1, sizeof(e)); 1549190207Srpaulo ikev2_pay_print(ndo, "sa", e.critical); 1550190207Srpaulo 1551214478Srpaulo osa_length= ntohs(e.len); 1552214478Srpaulo sa_length = osa_length - 4; 1553214478Srpaulo ND_PRINT((ndo," len=%d", sa_length)); 1554190207Srpaulo 1555214478Srpaulo ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_P, 1556190207Srpaulo ext1+1, ep, 1557190207Srpaulo 0, 0, 0, depth); 1558190207Srpaulo 1559214478Srpaulo return (u_char *)ext1 + osa_length; 1560190207Srpaulotrunc: 1561190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(tpay))); 1562190207Srpaulo return NULL; 1563190207Srpaulo} 1564190207Srpaulo 1565190207Srpaulostatic const u_char * 1566190207Srpauloikev2_ke_print(netdissect_options *ndo, u_char tpay, 1567190207Srpaulo const struct isakmp_gen *ext, 1568190207Srpaulo u_int item_len _U_, const u_char *ep _U_, 1569190207Srpaulo u_int32_t phase _U_, u_int32_t doi _U_, 1570190207Srpaulo u_int32_t proto _U_, int depth _U_) 1571190207Srpaulo{ 1572190207Srpaulo struct ikev2_ke ke; 1573190207Srpaulo struct ikev2_ke *k; 1574190207Srpaulo 1575190207Srpaulo k = (struct ikev2_ke *)ext; 1576190207Srpaulo ND_TCHECK(*ext); 1577190207Srpaulo safememcpy(&ke, ext, sizeof(ke)); 1578190207Srpaulo ikev2_pay_print(ndo, NPSTR(tpay), ke.h.critical); 1579190207Srpaulo 1580190207Srpaulo ND_PRINT((ndo," len=%u group=%s", ntohs(ke.h.len) - 8, 1581190207Srpaulo STR_OR_ID(ntohs(ke.ke_group), dh_p_map))); 1582190207Srpaulo 1583190207Srpaulo if (2 < ndo->ndo_vflag && 8 < ntohs(ke.h.len)) { 1584190207Srpaulo ND_PRINT((ndo," ")); 1585190207Srpaulo if (!rawprint(ndo, (caddr_t)(k + 1), ntohs(ke.h.len) - 8)) 1586190207Srpaulo goto trunc; 1587190207Srpaulo } 1588190207Srpaulo return (u_char *)ext + ntohs(ke.h.len); 1589190207Srpaulotrunc: 1590190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(tpay))); 1591190207Srpaulo return NULL; 1592190207Srpaulo} 1593190207Srpaulo 1594190207Srpaulostatic const u_char * 1595190207Srpauloikev2_ID_print(netdissect_options *ndo, u_char tpay, 1596190207Srpaulo const struct isakmp_gen *ext, 1597190207Srpaulo u_int item_len _U_, const u_char *ep _U_, 1598190207Srpaulo u_int32_t phase _U_, u_int32_t doi _U_, 1599190207Srpaulo u_int32_t proto _U_, int depth _U_) 1600190207Srpaulo{ 1601214478Srpaulo struct ikev2_id id; 1602214478Srpaulo int id_len, idtype_len, i; 1603214478Srpaulo unsigned int dumpascii, dumphex; 1604214478Srpaulo unsigned char *typedata; 1605214478Srpaulo 1606214478Srpaulo ND_TCHECK(*ext); 1607214478Srpaulo safememcpy(&id, ext, sizeof(id)); 1608214478Srpaulo ikev2_pay_print(ndo, NPSTR(tpay), id.h.critical); 1609214478Srpaulo 1610214478Srpaulo id_len = ntohs(id.h.len); 1611214478Srpaulo 1612214478Srpaulo ND_PRINT((ndo," len=%d", id_len - 4)); 1613214478Srpaulo if (2 < ndo->ndo_vflag && 4 < id_len) { 1614214478Srpaulo ND_PRINT((ndo," ")); 1615214478Srpaulo if (!rawprint(ndo, (caddr_t)(ext + 1), id_len - 4)) 1616214478Srpaulo goto trunc; 1617214478Srpaulo } 1618214478Srpaulo 1619214478Srpaulo idtype_len =id_len - sizeof(struct ikev2_id); 1620214478Srpaulo dumpascii = 0; 1621214478Srpaulo dumphex = 0; 1622214478Srpaulo typedata = (unsigned char *)(ext)+sizeof(struct ikev2_id); 1623214478Srpaulo 1624214478Srpaulo switch(id.type) { 1625214478Srpaulo case ID_IPV4_ADDR: 1626214478Srpaulo ND_PRINT((ndo, " ipv4:")); 1627214478Srpaulo dumphex=1; 1628214478Srpaulo break; 1629214478Srpaulo case ID_FQDN: 1630214478Srpaulo ND_PRINT((ndo, " fqdn:")); 1631214478Srpaulo dumpascii=1; 1632214478Srpaulo break; 1633214478Srpaulo case ID_RFC822_ADDR: 1634214478Srpaulo ND_PRINT((ndo, " rfc822:")); 1635214478Srpaulo dumpascii=1; 1636214478Srpaulo break; 1637214478Srpaulo case ID_IPV6_ADDR: 1638214478Srpaulo ND_PRINT((ndo, " ipv6:")); 1639214478Srpaulo dumphex=1; 1640214478Srpaulo break; 1641214478Srpaulo case ID_DER_ASN1_DN: 1642214478Srpaulo ND_PRINT((ndo, " dn:")); 1643214478Srpaulo dumphex=1; 1644214478Srpaulo break; 1645214478Srpaulo case ID_DER_ASN1_GN: 1646214478Srpaulo ND_PRINT((ndo, " gn:")); 1647214478Srpaulo dumphex=1; 1648214478Srpaulo break; 1649214478Srpaulo case ID_KEY_ID: 1650214478Srpaulo ND_PRINT((ndo, " keyid:")); 1651214478Srpaulo dumphex=1; 1652214478Srpaulo break; 1653214478Srpaulo } 1654214478Srpaulo 1655214478Srpaulo if(dumpascii) { 1656214478Srpaulo ND_TCHECK2(*typedata, idtype_len); 1657214478Srpaulo for(i=0; i<idtype_len; i++) { 1658214478Srpaulo if(isprint(typedata[i])) { 1659214478Srpaulo ND_PRINT((ndo, "%c", typedata[i])); 1660214478Srpaulo } else { 1661214478Srpaulo ND_PRINT((ndo, ".")); 1662214478Srpaulo } 1663214478Srpaulo } 1664214478Srpaulo } 1665214478Srpaulo if(dumphex) { 1666214478Srpaulo if (!rawprint(ndo, (caddr_t)typedata, idtype_len)) 1667214478Srpaulo goto trunc; 1668214478Srpaulo } 1669214478Srpaulo 1670214478Srpaulo return (u_char *)ext + id_len; 1671214478Srpaulotrunc: 1672214478Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(tpay))); 1673214478Srpaulo return NULL; 1674190207Srpaulo} 1675190207Srpaulo 1676190207Srpaulostatic const u_char * 1677190207Srpauloikev2_cert_print(netdissect_options *ndo, u_char tpay, 1678190207Srpaulo const struct isakmp_gen *ext, 1679190207Srpaulo u_int item_len _U_, const u_char *ep _U_, 1680190207Srpaulo u_int32_t phase _U_, u_int32_t doi _U_, 1681190207Srpaulo u_int32_t proto _U_, int depth _U_) 1682190207Srpaulo{ 1683190207Srpaulo return ikev2_gen_print(ndo, tpay, ext); 1684190207Srpaulo} 1685190207Srpaulo 1686190207Srpaulostatic const u_char * 1687190207Srpauloikev2_cr_print(netdissect_options *ndo, u_char tpay, 1688190207Srpaulo const struct isakmp_gen *ext, 1689190207Srpaulo u_int item_len _U_, const u_char *ep _U_, 1690190207Srpaulo u_int32_t phase _U_, u_int32_t doi _U_, 1691190207Srpaulo u_int32_t proto _U_, int depth _U_) 1692190207Srpaulo{ 1693190207Srpaulo return ikev2_gen_print(ndo, tpay, ext); 1694190207Srpaulo} 1695190207Srpaulo 1696190207Srpaulostatic const u_char * 1697190207Srpauloikev2_auth_print(netdissect_options *ndo, u_char tpay, 1698190207Srpaulo const struct isakmp_gen *ext, 1699190207Srpaulo u_int item_len _U_, const u_char *ep _U_, 1700190207Srpaulo u_int32_t phase _U_, u_int32_t doi _U_, 1701190207Srpaulo u_int32_t proto _U_, int depth _U_) 1702190207Srpaulo{ 1703214478Srpaulo struct ikev2_auth a; 1704190207Srpaulo const char *v2_auth[]={ "invalid", "rsasig", 1705190207Srpaulo "shared-secret", "dsssig" }; 1706214478Srpaulo u_char *authdata = (u_char*)ext + sizeof(a); 1707214478Srpaulo unsigned int len; 1708190207Srpaulo 1709190207Srpaulo ND_TCHECK(*ext); 1710214478Srpaulo safememcpy(&a, ext, sizeof(a)); 1711214478Srpaulo ikev2_pay_print(ndo, NPSTR(tpay), a.h.critical); 1712214478Srpaulo len = ntohs(a.h.len); 1713190207Srpaulo 1714214478Srpaulo ND_PRINT((ndo," len=%d method=%s", len-4, 1715214478Srpaulo STR_OR_ID(a.auth_method, v2_auth))); 1716190207Srpaulo 1717214478Srpaulo if (1 < ndo->ndo_vflag && 4 < len) { 1718190207Srpaulo ND_PRINT((ndo," authdata=(")); 1719214478Srpaulo if (!rawprint(ndo, (caddr_t)authdata, len - sizeof(a))) 1720190207Srpaulo goto trunc; 1721190207Srpaulo ND_PRINT((ndo,") ")); 1722214478Srpaulo } else if(ndo->ndo_vflag && 4 < len) { 1723214478Srpaulo if(!ike_show_somedata(ndo, authdata, ep)) goto trunc; 1724190207Srpaulo } 1725190207Srpaulo 1726214478Srpaulo return (u_char *)ext + len; 1727190207Srpaulotrunc: 1728190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(tpay))); 1729190207Srpaulo return NULL; 1730190207Srpaulo} 1731190207Srpaulo 1732190207Srpaulostatic const u_char * 1733190207Srpauloikev2_nonce_print(netdissect_options *ndo, u_char tpay, 1734190207Srpaulo const struct isakmp_gen *ext, 1735190207Srpaulo u_int item_len _U_, const u_char *ep _U_, 1736190207Srpaulo u_int32_t phase _U_, u_int32_t doi _U_, 1737190207Srpaulo u_int32_t proto _U_, int depth _U_) 1738190207Srpaulo{ 1739190207Srpaulo struct isakmp_gen e; 1740190207Srpaulo 1741190207Srpaulo ND_TCHECK(*ext); 1742190207Srpaulo safememcpy(&e, ext, sizeof(e)); 1743190207Srpaulo ikev2_pay_print(ndo, "nonce", e.critical); 1744190207Srpaulo 1745190207Srpaulo ND_PRINT((ndo," len=%d", ntohs(e.len) - 4)); 1746190207Srpaulo if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) { 1747190207Srpaulo ND_PRINT((ndo," nonce=(")); 1748190207Srpaulo if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) 1749190207Srpaulo goto trunc; 1750190207Srpaulo ND_PRINT((ndo,") ")); 1751190207Srpaulo } else if(ndo->ndo_vflag && 4 < ntohs(e.len)) { 1752190207Srpaulo if(!ike_show_somedata(ndo, (const u_char *)(ext+1), ep)) goto trunc; 1753190207Srpaulo } 1754190207Srpaulo 1755190207Srpaulo return (u_char *)ext + ntohs(e.len); 1756190207Srpaulotrunc: 1757190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(tpay))); 1758190207Srpaulo return NULL; 1759190207Srpaulo} 1760190207Srpaulo 1761190207Srpaulo/* notify payloads */ 1762190207Srpaulostatic const u_char * 1763190207Srpauloikev2_n_print(netdissect_options *ndo, u_char tpay _U_, 1764190207Srpaulo const struct isakmp_gen *ext, 1765190207Srpaulo u_int item_len _U_, const u_char *ep _U_, 1766190207Srpaulo u_int32_t phase _U_, u_int32_t doi _U_, 1767190207Srpaulo u_int32_t proto _U_, int depth _U_) 1768190207Srpaulo{ 1769190207Srpaulo struct ikev2_n *p, n; 1770190207Srpaulo const u_char *cp; 1771190207Srpaulo u_char *ep2; 1772190207Srpaulo u_char showspi, showdata, showsomedata; 1773190207Srpaulo const char *notify_name; 1774190207Srpaulo u_int32_t type; 1775190207Srpaulo 1776190207Srpaulo p = (struct ikev2_n *)ext; 1777190207Srpaulo ND_TCHECK(*p); 1778190207Srpaulo safememcpy(&n, ext, sizeof(n)); 1779190207Srpaulo ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_N), n.h.critical); 1780190207Srpaulo 1781190207Srpaulo showspi = 1; 1782190207Srpaulo showdata = 0; 1783190207Srpaulo showsomedata=0; 1784190207Srpaulo notify_name=NULL; 1785190207Srpaulo 1786190207Srpaulo ND_PRINT((ndo," prot_id=%s", PROTOIDSTR(n.prot_id))); 1787190207Srpaulo 1788190207Srpaulo type = ntohs(n.type); 1789190207Srpaulo 1790190207Srpaulo /* notify space is annoying sparse */ 1791190207Srpaulo switch(type) { 1792190207Srpaulo case IV2_NOTIFY_UNSUPPORTED_CRITICAL_PAYLOAD: 1793190207Srpaulo notify_name = "unsupported_critical_payload"; 1794190207Srpaulo showspi = 0; 1795190207Srpaulo break; 1796190207Srpaulo 1797190207Srpaulo case IV2_NOTIFY_INVALID_IKE_SPI: 1798190207Srpaulo notify_name = "invalid_ike_spi"; 1799190207Srpaulo showspi = 1; 1800190207Srpaulo break; 1801190207Srpaulo 1802190207Srpaulo case IV2_NOTIFY_INVALID_MAJOR_VERSION: 1803190207Srpaulo notify_name = "invalid_major_version"; 1804190207Srpaulo showspi = 0; 1805190207Srpaulo break; 1806190207Srpaulo 1807190207Srpaulo case IV2_NOTIFY_INVALID_SYNTAX: 1808190207Srpaulo notify_name = "invalid_syntax"; 1809190207Srpaulo showspi = 1; 1810190207Srpaulo break; 1811190207Srpaulo 1812190207Srpaulo case IV2_NOTIFY_INVALID_MESSAGE_ID: 1813190207Srpaulo notify_name = "invalid_message_id"; 1814190207Srpaulo showspi = 1; 1815190207Srpaulo break; 1816190207Srpaulo 1817190207Srpaulo case IV2_NOTIFY_INVALID_SPI: 1818190207Srpaulo notify_name = "invalid_spi"; 1819190207Srpaulo showspi = 1; 1820190207Srpaulo break; 1821190207Srpaulo 1822190207Srpaulo case IV2_NOTIFY_NO_PROPOSAL_CHOSEN: 1823190207Srpaulo notify_name = "no_protocol_chosen"; 1824190207Srpaulo showspi = 1; 1825190207Srpaulo break; 1826190207Srpaulo 1827190207Srpaulo case IV2_NOTIFY_INVALID_KE_PAYLOAD: 1828190207Srpaulo notify_name = "invalid_ke_payload"; 1829190207Srpaulo showspi = 1; 1830190207Srpaulo break; 1831190207Srpaulo 1832190207Srpaulo case IV2_NOTIFY_AUTHENTICATION_FAILED: 1833190207Srpaulo notify_name = "authentication_failed"; 1834190207Srpaulo showspi = 1; 1835190207Srpaulo break; 1836190207Srpaulo 1837190207Srpaulo case IV2_NOTIFY_SINGLE_PAIR_REQUIRED: 1838190207Srpaulo notify_name = "single_pair_required"; 1839190207Srpaulo showspi = 1; 1840190207Srpaulo break; 1841190207Srpaulo 1842190207Srpaulo case IV2_NOTIFY_NO_ADDITIONAL_SAS: 1843190207Srpaulo notify_name = "no_additional_sas"; 1844190207Srpaulo showspi = 0; 1845190207Srpaulo break; 1846190207Srpaulo 1847190207Srpaulo case IV2_NOTIFY_INTERNAL_ADDRESS_FAILURE: 1848190207Srpaulo notify_name = "internal_address_failure"; 1849190207Srpaulo showspi = 0; 1850190207Srpaulo break; 1851190207Srpaulo 1852190207Srpaulo case IV2_NOTIFY_FAILED_CP_REQUIRED: 1853190207Srpaulo notify_name = "failed:cp_required"; 1854190207Srpaulo showspi = 0; 1855190207Srpaulo break; 1856190207Srpaulo 1857190207Srpaulo case IV2_NOTIFY_INVALID_SELECTORS: 1858190207Srpaulo notify_name = "invalid_selectors"; 1859190207Srpaulo showspi = 0; 1860190207Srpaulo break; 1861190207Srpaulo 1862190207Srpaulo case IV2_NOTIFY_INITIAL_CONTACT: 1863190207Srpaulo notify_name = "initial_contact"; 1864190207Srpaulo showspi = 0; 1865190207Srpaulo break; 1866190207Srpaulo 1867190207Srpaulo case IV2_NOTIFY_SET_WINDOW_SIZE: 1868190207Srpaulo notify_name = "set_window_size"; 1869190207Srpaulo showspi = 0; 1870190207Srpaulo break; 1871190207Srpaulo 1872190207Srpaulo case IV2_NOTIFY_ADDITIONAL_TS_POSSIBLE: 1873190207Srpaulo notify_name = "additional_ts_possible"; 1874190207Srpaulo showspi = 0; 1875190207Srpaulo break; 1876190207Srpaulo 1877190207Srpaulo case IV2_NOTIFY_IPCOMP_SUPPORTED: 1878190207Srpaulo notify_name = "ipcomp_supported"; 1879190207Srpaulo showspi = 0; 1880190207Srpaulo break; 1881190207Srpaulo 1882190207Srpaulo case IV2_NOTIFY_NAT_DETECTION_SOURCE_IP: 1883190207Srpaulo notify_name = "nat_detection_source_ip"; 1884190207Srpaulo showspi = 1; 1885190207Srpaulo break; 1886190207Srpaulo 1887190207Srpaulo case IV2_NOTIFY_NAT_DETECTION_DESTINATION_IP: 1888190207Srpaulo notify_name = "nat_detection_destination_ip"; 1889190207Srpaulo showspi = 1; 1890190207Srpaulo break; 1891190207Srpaulo 1892190207Srpaulo case IV2_NOTIFY_COOKIE: 1893190207Srpaulo notify_name = "cookie"; 1894190207Srpaulo showspi = 1; 1895190207Srpaulo showsomedata= 1; 1896190207Srpaulo showdata= 0; 1897190207Srpaulo break; 1898190207Srpaulo 1899190207Srpaulo case IV2_NOTIFY_USE_TRANSPORT_MODE: 1900190207Srpaulo notify_name = "use_transport_mode"; 1901190207Srpaulo showspi = 0; 1902190207Srpaulo break; 1903190207Srpaulo 1904190207Srpaulo case IV2_NOTIFY_HTTP_CERT_LOOKUP_SUPPORTED: 1905190207Srpaulo notify_name = "http_cert_lookup_supported"; 1906190207Srpaulo showspi = 0; 1907190207Srpaulo break; 1908190207Srpaulo 1909190207Srpaulo case IV2_NOTIFY_REKEY_SA: 1910190207Srpaulo notify_name = "rekey_sa"; 1911190207Srpaulo showspi = 1; 1912190207Srpaulo break; 1913190207Srpaulo 1914190207Srpaulo case IV2_NOTIFY_ESP_TFC_PADDING_NOT_SUPPORTED: 1915190207Srpaulo notify_name = "tfc_padding_not_supported"; 1916190207Srpaulo showspi = 0; 1917190207Srpaulo break; 1918190207Srpaulo 1919190207Srpaulo case IV2_NOTIFY_NON_FIRST_FRAGMENTS_ALSO: 1920190207Srpaulo notify_name = "non_first_fragment_also"; 1921190207Srpaulo showspi = 0; 1922190207Srpaulo break; 1923190207Srpaulo 1924190207Srpaulo default: 1925190207Srpaulo if (type < 8192) { 1926190207Srpaulo notify_name="error"; 1927190207Srpaulo } else if(type < 16384) { 1928190207Srpaulo notify_name="private-error"; 1929190207Srpaulo } else if(type < 40960) { 1930190207Srpaulo notify_name="status"; 1931190207Srpaulo } else { 1932190207Srpaulo notify_name="private-status"; 1933190207Srpaulo } 1934190207Srpaulo } 1935190207Srpaulo 1936190207Srpaulo if(notify_name) { 1937190207Srpaulo ND_PRINT((ndo," type=%u(%s)", type, notify_name)); 1938190207Srpaulo } 1939190207Srpaulo 1940190207Srpaulo 1941190207Srpaulo if (showspi && n.spi_size) { 1942190207Srpaulo ND_PRINT((ndo," spi=")); 1943190207Srpaulo if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size)) 1944190207Srpaulo goto trunc; 1945190207Srpaulo } 1946190207Srpaulo 1947190207Srpaulo cp = (u_char *)(p + 1) + n.spi_size; 1948190207Srpaulo ep2 = (u_char *)p + item_len; 1949190207Srpaulo 1950190207Srpaulo if(3 < ndo->ndo_vflag) { 1951190207Srpaulo showdata = 1; 1952190207Srpaulo } 1953190207Srpaulo 1954190207Srpaulo if ((showdata || (showsomedata && ep-cp < 30)) && cp < ep) { 1955190207Srpaulo ND_PRINT((ndo," data=(")); 1956190207Srpaulo if (!rawprint(ndo, (caddr_t)(cp), ep - cp)) 1957190207Srpaulo goto trunc; 1958190207Srpaulo 1959190207Srpaulo ND_PRINT((ndo,")")); 1960190207Srpaulo 1961190207Srpaulo } else if(showsomedata && cp < ep) { 1962190207Srpaulo if(!ike_show_somedata(ndo, cp, ep)) goto trunc; 1963190207Srpaulo } 1964190207Srpaulo 1965190207Srpaulo return (u_char *)ext + item_len; 1966190207Srpaulotrunc: 1967190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N))); 1968190207Srpaulo return NULL; 1969190207Srpaulo} 1970190207Srpaulo 1971190207Srpaulostatic const u_char * 1972190207Srpauloikev2_d_print(netdissect_options *ndo, u_char tpay, 1973190207Srpaulo const struct isakmp_gen *ext, 1974190207Srpaulo u_int item_len _U_, const u_char *ep _U_, 1975190207Srpaulo u_int32_t phase _U_, u_int32_t doi _U_, 1976190207Srpaulo u_int32_t proto _U_, int depth _U_) 1977190207Srpaulo{ 1978190207Srpaulo return ikev2_gen_print(ndo, tpay, ext); 1979190207Srpaulo} 1980190207Srpaulo 1981190207Srpaulostatic const u_char * 1982190207Srpauloikev2_vid_print(netdissect_options *ndo, u_char tpay, 1983190207Srpaulo const struct isakmp_gen *ext, 1984190207Srpaulo u_int item_len _U_, const u_char *ep _U_, 1985190207Srpaulo u_int32_t phase _U_, u_int32_t doi _U_, 1986190207Srpaulo u_int32_t proto _U_, int depth _U_) 1987190207Srpaulo{ 1988190207Srpaulo struct isakmp_gen e; 1989190207Srpaulo const u_char *vid; 1990190207Srpaulo int i, len; 1991190207Srpaulo 1992190207Srpaulo ND_TCHECK(*ext); 1993190207Srpaulo safememcpy(&e, ext, sizeof(e)); 1994190207Srpaulo ikev2_pay_print(ndo, NPSTR(tpay), e.critical); 1995190207Srpaulo ND_PRINT((ndo," len=%d vid=", ntohs(e.len) - 4)); 1996190207Srpaulo 1997190207Srpaulo vid = (const u_char *)(ext+1); 1998190207Srpaulo len = ntohs(e.len) - 4; 1999190207Srpaulo ND_TCHECK2(*vid, len); 2000190207Srpaulo for(i=0; i<len; i++) { 2001190207Srpaulo if(isprint(vid[i])) ND_PRINT((ndo, "%c", vid[i])); 2002214478Srpaulo else ND_PRINT((ndo, ".")); 2003190207Srpaulo } 2004190207Srpaulo if (2 < ndo->ndo_vflag && 4 < len) { 2005190207Srpaulo ND_PRINT((ndo," ")); 2006190207Srpaulo if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4)) 2007190207Srpaulo goto trunc; 2008190207Srpaulo } 2009190207Srpaulo return (u_char *)ext + ntohs(e.len); 2010190207Srpaulotrunc: 2011190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(tpay))); 2012190207Srpaulo return NULL; 2013190207Srpaulo} 2014190207Srpaulo 2015190207Srpaulostatic const u_char * 2016190207Srpauloikev2_TS_print(netdissect_options *ndo, u_char tpay, 2017190207Srpaulo const struct isakmp_gen *ext, 2018190207Srpaulo u_int item_len _U_, const u_char *ep _U_, 2019190207Srpaulo u_int32_t phase _U_, u_int32_t doi _U_, 2020190207Srpaulo u_int32_t proto _U_, int depth _U_) 2021190207Srpaulo{ 2022190207Srpaulo return ikev2_gen_print(ndo, tpay, ext); 2023190207Srpaulo} 2024190207Srpaulo 2025190207Srpaulostatic const u_char * 2026214478Srpauloikev2_e_print(netdissect_options *ndo, 2027214478Srpaulo#ifndef HAVE_LIBCRYPTO 2028214478Srpaulo _U_ 2029214478Srpaulo#endif 2030214478Srpaulo struct isakmp *base, 2031214478Srpaulo u_char tpay, 2032214478Srpaulo const struct isakmp_gen *ext, 2033214478Srpaulo u_int item_len _U_, const u_char *ep _U_, 2034214478Srpaulo#ifndef HAVE_LIBCRYPTO 2035214478Srpaulo _U_ 2036214478Srpaulo#endif 2037214478Srpaulo u_int32_t phase, 2038214478Srpaulo#ifndef HAVE_LIBCRYPTO 2039214478Srpaulo _U_ 2040214478Srpaulo#endif 2041214478Srpaulo u_int32_t doi, 2042214478Srpaulo#ifndef HAVE_LIBCRYPTO 2043214478Srpaulo _U_ 2044214478Srpaulo#endif 2045214478Srpaulo u_int32_t proto, 2046214478Srpaulo#ifndef HAVE_LIBCRYPTO 2047214478Srpaulo _U_ 2048214478Srpaulo#endif 2049214478Srpaulo int depth) 2050190207Srpaulo{ 2051214478Srpaulo struct isakmp_gen e; 2052214478Srpaulo u_char *dat; 2053214478Srpaulo volatile int dlen; 2054214478Srpaulo 2055214478Srpaulo ND_TCHECK(*ext); 2056214478Srpaulo safememcpy(&e, ext, sizeof(e)); 2057214478Srpaulo ikev2_pay_print(ndo, NPSTR(tpay), e.critical); 2058214478Srpaulo 2059214478Srpaulo dlen = ntohs(e.len)-4; 2060214478Srpaulo 2061214478Srpaulo ND_PRINT((ndo," len=%d", dlen)); 2062214478Srpaulo if (2 < ndo->ndo_vflag && 4 < dlen) { 2063214478Srpaulo ND_PRINT((ndo," ")); 2064214478Srpaulo if (!rawprint(ndo, (caddr_t)(ext + 1), dlen)) 2065214478Srpaulo goto trunc; 2066214478Srpaulo } 2067214478Srpaulo 2068214478Srpaulo dat = (u_char *)(ext+1); 2069214478Srpaulo ND_TCHECK2(*dat, dlen); 2070214478Srpaulo 2071214478Srpaulo#ifdef HAVE_LIBCRYPTO 2072214478Srpaulo /* try to decypt it! */ 2073214478Srpaulo if(esp_print_decrypt_buffer_by_ikev2(ndo, 2074214478Srpaulo base->flags & ISAKMP_FLAG_I, 2075214478Srpaulo base->i_ck, base->r_ck, 2076214478Srpaulo dat, dat+dlen)) { 2077214478Srpaulo 2078214478Srpaulo ext = (const struct isakmp_gen *)ndo->ndo_packetp; 2079214478Srpaulo 2080214478Srpaulo /* got it decrypted, print stuff inside. */ 2081214478Srpaulo ikev2_sub_print(ndo, base, e.np, ext, ndo->ndo_snapend, 2082214478Srpaulo phase, doi, proto, depth+1); 2083214478Srpaulo } 2084214478Srpaulo#endif 2085214478Srpaulo 2086214478Srpaulo 2087214478Srpaulo /* always return NULL, because E must be at end, and NP refers 2088214478Srpaulo * to what was inside. 2089214478Srpaulo */ 2090214478Srpaulo return NULL; 2091214478Srpaulotrunc: 2092214478Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(tpay))); 2093214478Srpaulo return NULL; 2094190207Srpaulo} 2095190207Srpaulo 2096190207Srpaulostatic const u_char * 2097190207Srpauloikev2_cp_print(netdissect_options *ndo, u_char tpay, 2098190207Srpaulo const struct isakmp_gen *ext, 2099190207Srpaulo u_int item_len _U_, const u_char *ep _U_, 2100190207Srpaulo u_int32_t phase _U_, u_int32_t doi _U_, 2101190207Srpaulo u_int32_t proto _U_, int depth _U_) 2102190207Srpaulo{ 2103190207Srpaulo return ikev2_gen_print(ndo, tpay, ext); 2104190207Srpaulo} 2105190207Srpaulo 2106190207Srpaulostatic const u_char * 2107190207Srpauloikev2_eap_print(netdissect_options *ndo, u_char tpay, 2108190207Srpaulo const struct isakmp_gen *ext, 2109190207Srpaulo u_int item_len _U_, const u_char *ep _U_, 2110190207Srpaulo u_int32_t phase _U_, u_int32_t doi _U_, 2111190207Srpaulo u_int32_t proto _U_, int depth _U_) 2112190207Srpaulo{ 2113190207Srpaulo return ikev2_gen_print(ndo, tpay, ext); 2114190207Srpaulo} 2115190207Srpaulo 2116190207Srpaulostatic const u_char * 2117190207Srpauloike_sub0_print(netdissect_options *ndo, 2118190207Srpaulo u_char np, const struct isakmp_gen *ext, const u_char *ep, 2119214478Srpaulo 2120214478Srpaulo u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) 2121190207Srpaulo{ 2122190207Srpaulo const u_char *cp; 2123190207Srpaulo struct isakmp_gen e; 2124111726Sfenner u_int item_len; 212556893Sfenner 212656893Sfenner cp = (u_char *)ext; 2127190207Srpaulo ND_TCHECK(*ext); 212875115Sfenner safememcpy(&e, ext, sizeof(e)); 212956893Sfenner 2130127668Sbms /* 2131127668Sbms * Since we can't have a payload length of less than 4 bytes, 2132127668Sbms * we need to bail out here if the generic header is nonsensical 2133127668Sbms * or truncated, otherwise we could loop forever processing 2134127668Sbms * zero-length items or otherwise misdissect the packet. 2135127668Sbms */ 2136127668Sbms item_len = ntohs(e.len); 2137127668Sbms if (item_len <= 4) 2138127668Sbms return NULL; 2139127668Sbms 2140127668Sbms if (NPFUNC(np)) { 2141127668Sbms /* 2142127668Sbms * XXX - what if item_len is too short, or too long, 2143127668Sbms * for this payload type? 2144127668Sbms */ 2145190207Srpaulo cp = (*npfunc[np])(ndo, np, ext, item_len, ep, phase, doi, proto, depth); 2146127668Sbms } else { 2147190207Srpaulo ND_PRINT((ndo,"%s", NPSTR(np))); 2148127668Sbms cp += item_len; 214956893Sfenner } 2150127668Sbms 215156893Sfenner return cp; 2152127668Sbmstrunc: 2153190207Srpaulo ND_PRINT((ndo," [|isakmp]")); 2154127668Sbms return NULL; 215556893Sfenner} 215656893Sfenner 2157127668Sbmsstatic const u_char * 2158190207Srpauloikev1_sub_print(netdissect_options *ndo, 2159190207Srpaulo u_char np, const struct isakmp_gen *ext, const u_char *ep, 2160190207Srpaulo u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) 216156893Sfenner{ 2162127668Sbms const u_char *cp; 216356893Sfenner int i; 216475115Sfenner struct isakmp_gen e; 216556893Sfenner 2166127668Sbms cp = (const u_char *)ext; 216756893Sfenner 216856893Sfenner while (np) { 2169190207Srpaulo ND_TCHECK(*ext); 2170124488Sfenner 217175115Sfenner safememcpy(&e, ext, sizeof(e)); 217275115Sfenner 2173190207Srpaulo ND_TCHECK2(*ext, ntohs(e.len)); 2174127668Sbms 217556893Sfenner depth++; 2176190207Srpaulo ND_PRINT((ndo,"\n")); 217756893Sfenner for (i = 0; i < depth; i++) 2178190207Srpaulo ND_PRINT((ndo," ")); 2179190207Srpaulo ND_PRINT((ndo,"(")); 2180190207Srpaulo cp = ike_sub0_print(ndo, np, ext, ep, phase, doi, proto, depth); 2181190207Srpaulo ND_PRINT((ndo,")")); 218256893Sfenner depth--; 218356893Sfenner 2184111726Sfenner if (cp == NULL) { 2185111726Sfenner /* Zero-length subitem */ 2186111726Sfenner return NULL; 2187111726Sfenner } 2188111726Sfenner 218975115Sfenner np = e.np; 219056893Sfenner ext = (struct isakmp_gen *)cp; 219156893Sfenner } 219256893Sfenner return cp; 2193124488Sfennertrunc: 2194190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(np))); 2195124488Sfenner return NULL; 219656893Sfenner} 219756893Sfenner 219856893Sfennerstatic char * 219956893Sfennernumstr(int x) 220056893Sfenner{ 220156893Sfenner static char buf[20]; 220275115Sfenner snprintf(buf, sizeof(buf), "#%d", x); 220356893Sfenner return buf; 220456893Sfenner} 220556893Sfenner 220675115Sfenner/* 220775115Sfenner * some compiler tries to optimize memcpy(), using the alignment constraint 220875115Sfenner * on the argument pointer type. by using this function, we try to avoid the 220975115Sfenner * optimization. 221075115Sfenner */ 221175115Sfennerstatic void 2212127668Sbmssafememcpy(void *p, const void *q, size_t l) 221375115Sfenner{ 221475115Sfenner memcpy(p, q, l); 221575115Sfenner} 221675115Sfenner 2217214478Srpaulostatic void 2218190207Srpauloikev1_print(netdissect_options *ndo, 2219190207Srpaulo const u_char *bp, u_int length, 2220190207Srpaulo const u_char *bp2, struct isakmp *base) 222156893Sfenner{ 2222127668Sbms const struct isakmp *p; 2223127668Sbms const u_char *ep; 222456893Sfenner u_char np; 222556893Sfenner int i; 222656893Sfenner int phase; 2227190207Srpaulo 2228127668Sbms p = (const struct isakmp *)bp; 2229146773Ssam ep = ndo->ndo_snapend; 2230190207Srpaulo 2231190207Srpaulo phase = (*(u_int32_t *)base->msgid == 0) ? 1 : 2; 223256893Sfenner if (phase == 1) 2233190207Srpaulo ND_PRINT((ndo," phase %d", phase)); 223456893Sfenner else 2235190207Srpaulo ND_PRINT((ndo," phase %d/others", phase)); 2236190207Srpaulo 2237190207Srpaulo i = cookie_find(&base->i_ck); 223856893Sfenner if (i < 0) { 2239190207Srpaulo if (iszero((u_char *)&base->r_ck, sizeof(base->r_ck))) { 224056893Sfenner /* the first packet */ 2241190207Srpaulo ND_PRINT((ndo," I")); 224256893Sfenner if (bp2) 2243190207Srpaulo cookie_record(&base->i_ck, bp2); 224456893Sfenner } else 2245190207Srpaulo ND_PRINT((ndo," ?")); 224656893Sfenner } else { 224756893Sfenner if (bp2 && cookie_isinitiator(i, bp2)) 2248190207Srpaulo ND_PRINT((ndo," I")); 224956893Sfenner else if (bp2 && cookie_isresponder(i, bp2)) 2250190207Srpaulo ND_PRINT((ndo," R")); 225156893Sfenner else 2252190207Srpaulo ND_PRINT((ndo," ?")); 225356893Sfenner } 2254190207Srpaulo 2255190207Srpaulo ND_PRINT((ndo," %s", ETYPESTR(base->etype))); 2256190207Srpaulo if (base->flags) { 2257190207Srpaulo ND_PRINT((ndo,"[%s%s]", base->flags & ISAKMP_FLAG_E ? "E" : "", 2258190207Srpaulo base->flags & ISAKMP_FLAG_C ? "C" : "")); 2259190207Srpaulo } 2260190207Srpaulo 2261190207Srpaulo if (ndo->ndo_vflag) { 2262190207Srpaulo const struct isakmp_gen *ext; 2263190207Srpaulo int nparen; 2264190207Srpaulo 2265190207Srpaulo ND_PRINT((ndo,":")); 2266190207Srpaulo 2267190207Srpaulo /* regardless of phase... */ 2268190207Srpaulo if (base->flags & ISAKMP_FLAG_E) { 2269190207Srpaulo /* 2270190207Srpaulo * encrypted, nothing we can do right now. 2271190207Srpaulo * we hope to decrypt the packet in the future... 2272190207Srpaulo */ 2273190207Srpaulo ND_PRINT((ndo," [encrypted %s]", NPSTR(base->np))); 2274190207Srpaulo goto done; 2275190207Srpaulo } 2276190207Srpaulo 2277190207Srpaulo nparen = 0; 2278190207Srpaulo CHECKLEN(p + 1, base->np); 2279190207Srpaulo np = base->np; 2280190207Srpaulo ext = (struct isakmp_gen *)(p + 1); 2281190207Srpaulo ikev1_sub_print(ndo, np, ext, ep, phase, 0, 0, 0); 2282190207Srpaulo } 2283190207Srpaulo 2284190207Srpaulodone: 2285190207Srpaulo if (ndo->ndo_vflag) { 2286190207Srpaulo if (ntohl(base->len) != length) { 2287190207Srpaulo ND_PRINT((ndo," (len mismatch: isakmp %u/ip %u)", 2288190207Srpaulo (u_int32_t)ntohl(base->len), length)); 2289190207Srpaulo } 2290190207Srpaulo } 2291190207Srpaulo} 229256893Sfenner 2293190207Srpaulostatic const u_char * 2294214478Srpauloikev2_sub0_print(netdissect_options *ndo, struct isakmp *base, 2295214478Srpaulo u_char np, int pcount, 2296190207Srpaulo const struct isakmp_gen *ext, const u_char *ep, 2297190207Srpaulo u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) 2298190207Srpaulo{ 2299190207Srpaulo const u_char *cp; 2300190207Srpaulo struct isakmp_gen e; 2301190207Srpaulo u_int item_len; 2302190207Srpaulo 2303190207Srpaulo cp = (u_char *)ext; 2304190207Srpaulo ND_TCHECK(*ext); 2305190207Srpaulo safememcpy(&e, ext, sizeof(e)); 2306190207Srpaulo 2307190207Srpaulo /* 2308190207Srpaulo * Since we can't have a payload length of less than 4 bytes, 2309190207Srpaulo * we need to bail out here if the generic header is nonsensical 2310190207Srpaulo * or truncated, otherwise we could loop forever processing 2311190207Srpaulo * zero-length items or otherwise misdissect the packet. 2312190207Srpaulo */ 2313190207Srpaulo item_len = ntohs(e.len); 2314190207Srpaulo if (item_len <= 4) 2315190207Srpaulo return NULL; 2316190207Srpaulo 2317190207Srpaulo if(np == ISAKMP_NPTYPE_P) { 2318190207Srpaulo cp = ikev2_p_print(ndo, np, pcount, ext, item_len, 2319190207Srpaulo ep, phase, doi, proto, depth); 2320190207Srpaulo } else if(np == ISAKMP_NPTYPE_T) { 2321190207Srpaulo cp = ikev2_t_print(ndo, np, pcount, ext, item_len, 2322190207Srpaulo ep, phase, doi, proto, depth); 2323214478Srpaulo } else if(np == ISAKMP_NPTYPE_v2E) { 2324214478Srpaulo cp = ikev2_e_print(ndo, base, np, ext, item_len, 2325214478Srpaulo ep, phase, doi, proto, depth); 2326190207Srpaulo } else if (NPFUNC(np)) { 2327190207Srpaulo /* 2328190207Srpaulo * XXX - what if item_len is too short, or too long, 2329190207Srpaulo * for this payload type? 2330190207Srpaulo */ 2331190207Srpaulo cp = (*npfunc[np])(ndo, np, /*pcount,*/ ext, item_len, 2332190207Srpaulo ep, phase, doi, proto, depth); 2333190207Srpaulo } else { 2334190207Srpaulo ND_PRINT((ndo,"%s", NPSTR(np))); 2335190207Srpaulo cp += item_len; 233656893Sfenner } 233756893Sfenner 2338190207Srpaulo return cp; 2339190207Srpaulotrunc: 2340190207Srpaulo ND_PRINT((ndo," [|isakmp]")); 2341190207Srpaulo return NULL; 2342190207Srpaulo} 2343190207Srpaulo 2344190207Srpaulostatic const u_char * 2345190207Srpauloikev2_sub_print(netdissect_options *ndo, 2346214478Srpaulo struct isakmp *base, 2347190207Srpaulo u_char np, const struct isakmp_gen *ext, const u_char *ep, 2348190207Srpaulo u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth) 2349190207Srpaulo{ 2350190207Srpaulo const u_char *cp; 2351190207Srpaulo int i; 2352190207Srpaulo int pcount; 2353190207Srpaulo struct isakmp_gen e; 2354190207Srpaulo 2355190207Srpaulo cp = (const u_char *)ext; 2356190207Srpaulo pcount = 0; 2357190207Srpaulo while (np) { 2358190207Srpaulo pcount++; 2359190207Srpaulo ND_TCHECK(*ext); 2360190207Srpaulo 2361190207Srpaulo safememcpy(&e, ext, sizeof(e)); 2362190207Srpaulo 2363190207Srpaulo ND_TCHECK2(*ext, ntohs(e.len)); 2364190207Srpaulo 2365190207Srpaulo depth++; 2366190207Srpaulo ND_PRINT((ndo,"\n")); 2367190207Srpaulo for (i = 0; i < depth; i++) 2368190207Srpaulo ND_PRINT((ndo," ")); 2369190207Srpaulo ND_PRINT((ndo,"(")); 2370214478Srpaulo cp = ikev2_sub0_print(ndo, base, np, pcount, 2371190207Srpaulo ext, ep, phase, doi, proto, depth); 2372190207Srpaulo ND_PRINT((ndo,")")); 2373190207Srpaulo depth--; 2374190207Srpaulo 2375190207Srpaulo if (cp == NULL) { 2376190207Srpaulo /* Zero-length subitem */ 2377190207Srpaulo return NULL; 2378190207Srpaulo } 2379190207Srpaulo 2380190207Srpaulo np = e.np; 2381190207Srpaulo ext = (struct isakmp_gen *)cp; 2382190207Srpaulo } 2383190207Srpaulo return cp; 2384190207Srpaulotrunc: 2385190207Srpaulo ND_PRINT((ndo," [|%s]", NPSTR(np))); 2386190207Srpaulo return NULL; 2387190207Srpaulo} 2388190207Srpaulo 2389190207Srpaulostatic void 2390190207Srpauloikev2_print(netdissect_options *ndo, 2391190207Srpaulo const u_char *bp, u_int length, 2392190207Srpaulo const u_char *bp2 _U_, struct isakmp *base) 2393190207Srpaulo{ 2394190207Srpaulo const struct isakmp *p; 2395190207Srpaulo const u_char *ep; 2396190207Srpaulo u_char np; 2397190207Srpaulo int phase; 2398190207Srpaulo 2399190207Srpaulo p = (const struct isakmp *)bp; 2400190207Srpaulo ep = ndo->ndo_snapend; 2401190207Srpaulo 2402190207Srpaulo phase = (*(u_int32_t *)base->msgid == 0) ? 1 : 2; 2403190207Srpaulo if (phase == 1) 2404190207Srpaulo ND_PRINT((ndo, " parent_sa")); 2405190207Srpaulo else 2406190207Srpaulo ND_PRINT((ndo, " child_sa ")); 2407190207Srpaulo 2408190207Srpaulo ND_PRINT((ndo, " %s", ETYPESTR(base->etype))); 2409190207Srpaulo if (base->flags) { 2410214478Srpaulo ND_PRINT((ndo, "[%s%s%s]", 2411190207Srpaulo base->flags & ISAKMP_FLAG_I ? "I" : "", 2412190207Srpaulo base->flags & ISAKMP_FLAG_V ? "V" : "", 2413190207Srpaulo base->flags & ISAKMP_FLAG_R ? "R" : "")); 2414190207Srpaulo } 2415190207Srpaulo 2416190207Srpaulo if (ndo->ndo_vflag) { 2417127668Sbms const struct isakmp_gen *ext; 2418127668Sbms int nparen; 241956893Sfenner 2420190207Srpaulo ND_PRINT((ndo, ":")); 242156893Sfenner 2422127668Sbms /* regardless of phase... */ 2423190207Srpaulo if (base->flags & ISAKMP_FLAG_E) { 2424127668Sbms /* 2425127668Sbms * encrypted, nothing we can do right now. 2426127668Sbms * we hope to decrypt the packet in the future... 2427127668Sbms */ 2428190207Srpaulo ND_PRINT((ndo, " [encrypted %s]", NPSTR(base->np))); 2429127668Sbms goto done; 2430127668Sbms } 243156893Sfenner 2432127668Sbms nparen = 0; 2433190207Srpaulo CHECKLEN(p + 1, base->np) 243456893Sfenner 2435190207Srpaulo np = base->np; 2436127668Sbms ext = (struct isakmp_gen *)(p + 1); 2437214478Srpaulo ikev2_sub_print(ndo, base, np, ext, ep, phase, 0, 0, 0); 2438127668Sbms } 2439127668Sbms 244056893Sfennerdone: 2441190207Srpaulo if (ndo->ndo_vflag) { 2442190207Srpaulo if (ntohl(base->len) != length) { 2443190207Srpaulo ND_PRINT((ndo, " (len mismatch: isakmp %u/ip %u)", 2444190207Srpaulo (u_int32_t)ntohl(base->len), length)); 244556893Sfenner } 244656893Sfenner } 244756893Sfenner} 2448146773Ssam 2449146773Ssamvoid 2450190207Srpauloisakmp_print(netdissect_options *ndo, 2451190207Srpaulo const u_char *bp, u_int length, 2452190207Srpaulo const u_char *bp2) 2453190207Srpaulo{ 2454190207Srpaulo const struct isakmp *p; 2455190207Srpaulo struct isakmp base; 2456190207Srpaulo const u_char *ep; 2457190207Srpaulo int major, minor; 2458190207Srpaulo 2459214478Srpaulo#ifdef HAVE_LIBCRYPTO 2460214478Srpaulo /* initialize SAs */ 2461214478Srpaulo if (ndo->ndo_sa_list_head == NULL) { 2462214478Srpaulo if (ndo->ndo_espsecret) 2463214478Srpaulo esp_print_decodesecret(ndo); 2464214478Srpaulo } 2465214478Srpaulo#endif 2466214478Srpaulo 2467190207Srpaulo p = (const struct isakmp *)bp; 2468190207Srpaulo ep = ndo->ndo_snapend; 2469190207Srpaulo 2470190207Srpaulo if ((struct isakmp *)ep < p + 1) { 2471190207Srpaulo ND_PRINT((ndo,"[|isakmp]")); 2472190207Srpaulo return; 2473190207Srpaulo } 2474190207Srpaulo 2475190207Srpaulo safememcpy(&base, p, sizeof(base)); 2476190207Srpaulo 2477190207Srpaulo ND_PRINT((ndo,"isakmp")); 2478190207Srpaulo major = (base.vers & ISAKMP_VERS_MAJOR) 2479190207Srpaulo >> ISAKMP_VERS_MAJOR_SHIFT; 2480190207Srpaulo minor = (base.vers & ISAKMP_VERS_MINOR) 2481190207Srpaulo >> ISAKMP_VERS_MINOR_SHIFT; 2482190207Srpaulo 2483190207Srpaulo if (ndo->ndo_vflag) { 2484190207Srpaulo ND_PRINT((ndo," %d.%d", major, minor)); 2485190207Srpaulo } 2486190207Srpaulo 2487190207Srpaulo if (ndo->ndo_vflag) { 2488190207Srpaulo ND_PRINT((ndo," msgid ")); 2489214478Srpaulo hexprint(ndo, (caddr_t)&base.msgid, sizeof(base.msgid)); 2490190207Srpaulo } 2491190207Srpaulo 2492190207Srpaulo if (1 < ndo->ndo_vflag) { 2493190207Srpaulo ND_PRINT((ndo," cookie ")); 2494214478Srpaulo hexprint(ndo, (caddr_t)&base.i_ck, sizeof(base.i_ck)); 2495190207Srpaulo ND_PRINT((ndo,"->")); 2496214478Srpaulo hexprint(ndo, (caddr_t)&base.r_ck, sizeof(base.r_ck)); 2497190207Srpaulo } 2498190207Srpaulo ND_PRINT((ndo,":")); 2499190207Srpaulo 2500190207Srpaulo switch(major) { 2501190207Srpaulo case IKEv1_MAJOR_VERSION: 2502190207Srpaulo ikev1_print(ndo, bp, length, bp2, &base); 2503190207Srpaulo break; 2504190207Srpaulo 2505190207Srpaulo case IKEv2_MAJOR_VERSION: 2506190207Srpaulo ikev2_print(ndo, bp, length, bp2, &base); 2507190207Srpaulo break; 2508190207Srpaulo } 2509190207Srpaulo} 2510190207Srpaulo 2511190207Srpaulovoid 2512146773Ssamisakmp_rfc3948_print(netdissect_options *ndo, 2513146773Ssam const u_char *bp, u_int length, 2514146773Ssam const u_char *bp2) 2515146773Ssam{ 2516146773Ssam const u_char *ep; 2517146773Ssam ep = ndo->ndo_snapend; 2518146773Ssam 2519146773Ssam if(length == 1 && bp[0]==0xff) { 2520146773Ssam ND_PRINT((ndo, "isakmp-nat-keep-alive")); 2521146773Ssam return; 2522146773Ssam } 2523146773Ssam 2524146773Ssam if(length < 4) { 2525146773Ssam goto trunc; 2526146773Ssam } 2527190207Srpaulo 2528146773Ssam /* 2529146773Ssam * see if this is an IKE packet 2530146773Ssam */ 2531146773Ssam if(bp[0]==0 && bp[1]==0 && bp[2]==0 && bp[3]==0) { 2532146773Ssam ND_PRINT((ndo, "NONESP-encap: ")); 2533146773Ssam isakmp_print(ndo, bp+4, length-4, bp2); 2534146773Ssam return; 2535146773Ssam } 2536146773Ssam 2537146773Ssam /* must be an ESP packet */ 2538146773Ssam { 2539146773Ssam int nh, enh, padlen; 2540146773Ssam int advance; 2541146773Ssam 2542146773Ssam ND_PRINT((ndo, "UDP-encap: ")); 2543146773Ssam 2544146773Ssam advance = esp_print(ndo, bp, length, bp2, &enh, &padlen); 2545146773Ssam if(advance <= 0) 2546146773Ssam return; 2547146773Ssam 2548146773Ssam bp += advance; 2549146773Ssam length -= advance + padlen; 2550146773Ssam nh = enh & 0xff; 2551146773Ssam 2552146773Ssam ip_print_inner(ndo, bp, length, nh, bp2); 2553146773Ssam return; 2554146773Ssam } 2555146773Ssam 2556146773Ssamtrunc: 2557190207Srpaulo ND_PRINT((ndo,"[|isakmp]")); 2558146773Ssam return; 2559146773Ssam} 2560146773Ssam 2561146773Ssam/* 2562146773Ssam * Local Variables: 2563146773Ssam * c-style: whitesmith 2564146773Ssam * c-basic-offset: 8 2565146773Ssam * End: 2566146773Ssam */ 2567146773Ssam 2568146773Ssam 2569146773Ssam 2570146773Ssam 2571