1/* 2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the project nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 */ 30 31#ifndef lint 32static const char rcsid[] = 33 "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.29.2.2 2003/02/26 05:58:39 fenner Exp $ (LBL)"; 34#endif 35 36#ifdef HAVE_CONFIG_H 37#include "config.h" 38#endif 39 40#include <string.h> 41#include <ctype.h> 42#include <sys/param.h> 43#include <sys/time.h> 44#include <sys/socket.h> 45 46#include <netinet/in.h> 47 48#include <stdio.h> 49#include <netdb.h> 50 51#include "isakmp.h" 52#include "ipsec_doi.h" 53#include "oakley.h" 54#include "interface.h" 55#include "addrtoname.h" 56#include "extract.h" /* must come after interface.h */ 57 58#include "ip.h" 59#ifdef INET6 60#include "ip6.h" 61#endif 62 63#ifndef HAVE_SOCKADDR_STORAGE 64#define sockaddr_storage sockaddr 65#endif 66 67static u_char *isakmp_sa_print(struct isakmp_gen *, u_char *, u_int32_t, 68 u_int32_t, u_int32_t); 69static u_char *isakmp_p_print(struct isakmp_gen *, u_char *, u_int32_t, 70 u_int32_t, u_int32_t); 71static u_char *isakmp_t_print(struct isakmp_gen *, u_char *, u_int32_t, 72 u_int32_t, u_int32_t); 73static u_char *isakmp_ke_print(struct isakmp_gen *, u_char *, u_int32_t, 74 u_int32_t, u_int32_t); 75static u_char *isakmp_id_print(struct isakmp_gen *, u_char *, u_int32_t, 76 u_int32_t, u_int32_t); 77static u_char *isakmp_cert_print(struct isakmp_gen *, u_char *, u_int32_t, 78 u_int32_t, u_int32_t); 79static u_char *isakmp_cr_print(struct isakmp_gen *, u_char *, u_int32_t, 80 u_int32_t, u_int32_t); 81static u_char *isakmp_sig_print(struct isakmp_gen *, u_char *, u_int32_t, 82 u_int32_t, u_int32_t); 83static u_char *isakmp_hash_print(struct isakmp_gen *, u_char *, 84 u_int32_t, u_int32_t, u_int32_t); 85static u_char *isakmp_nonce_print(struct isakmp_gen *, u_char *, 86 u_int32_t, u_int32_t, u_int32_t); 87static u_char *isakmp_n_print(struct isakmp_gen *, u_char *, u_int32_t, 88 u_int32_t, u_int32_t); 89static u_char *isakmp_d_print(struct isakmp_gen *, u_char *, u_int32_t, 90 u_int32_t, u_int32_t); 91static u_char *isakmp_vid_print(struct isakmp_gen *, u_char *, u_int32_t, 92 u_int32_t, u_int32_t); 93static u_char *isakmp_sub0_print(u_char, struct isakmp_gen *, u_char *, 94 u_int32_t, u_int32_t, u_int32_t); 95static u_char *isakmp_sub_print(u_char, struct isakmp_gen *, u_char *, 96 u_int32_t, u_int32_t, u_int32_t); 97static char *numstr(int); 98static void safememcpy(void *, void *, size_t); 99 100#define MAXINITIATORS 20 101int ninitiator = 0; 102struct { 103 cookie_t initiator; 104 struct sockaddr_storage iaddr; 105 struct sockaddr_storage raddr; 106} cookiecache[MAXINITIATORS]; 107 108/* protocol id */ 109static char *protoidstr[] = { 110 NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp", 111}; 112 113/* isakmp->np */ 114static char *npstr[] = { 115 "none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash", 116 "sig", "nonce", "n", "d", "vid" 117}; 118 119/* isakmp->np */ 120static u_char *(*npfunc[])(struct isakmp_gen *, u_char *, u_int32_t, 121 u_int32_t, u_int32_t) = { 122 NULL, 123 isakmp_sa_print, 124 isakmp_p_print, 125 isakmp_t_print, 126 isakmp_ke_print, 127 isakmp_id_print, 128 isakmp_cert_print, 129 isakmp_cr_print, 130 isakmp_hash_print, 131 isakmp_sig_print, 132 isakmp_nonce_print, 133 isakmp_n_print, 134 isakmp_d_print, 135 isakmp_vid_print, 136}; 137 138/* isakmp->etype */ 139static char *etypestr[] = { 140 "none", "base", "ident", "auth", "agg", "inf", NULL, NULL, 141 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 142 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 143 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 144 "oakley-quick", "oakley-newgroup", 145}; 146 147#define STR_OR_ID(x, tab) \ 148 (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x)) 149#define PROTOIDSTR(x) STR_OR_ID(x, protoidstr) 150#define NPSTR(x) STR_OR_ID(x, npstr) 151#define ETYPESTR(x) STR_OR_ID(x, etypestr) 152 153#define NPFUNC(x) \ 154 (((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \ 155 ? npfunc[(x)] : NULL) 156 157static int 158iszero(u_char *p, size_t l) 159{ 160 while (l--) { 161 if (*p++) 162 return 0; 163 } 164 return 1; 165} 166 167/* find cookie from initiator cache */ 168static int 169cookie_find(cookie_t *in) 170{ 171 int i; 172 173 for (i = 0; i < MAXINITIATORS; i++) { 174 if (memcmp(in, &cookiecache[i].initiator, sizeof(*in)) == 0) 175 return i; 176 } 177 178 return -1; 179} 180 181/* record initiator */ 182static void 183cookie_record(cookie_t *in, const u_char *bp2) 184{ 185 int i; 186 struct ip *ip; 187 struct sockaddr_in *sin; 188#ifdef INET6 189 struct ip6_hdr *ip6; 190 struct sockaddr_in6 *sin6; 191#endif 192 193 i = cookie_find(in); 194 if (0 <= i) { 195 ninitiator = (i + 1) % MAXINITIATORS; 196 return; 197 } 198 199 ip = (struct ip *)bp2; 200 switch (IP_V(ip)) { 201 case 4: 202 memset(&cookiecache[ninitiator].iaddr, 0, 203 sizeof(cookiecache[ninitiator].iaddr)); 204 memset(&cookiecache[ninitiator].raddr, 0, 205 sizeof(cookiecache[ninitiator].raddr)); 206 207 sin = (struct sockaddr_in *)&cookiecache[ninitiator].iaddr; 208#ifdef HAVE_SOCKADDR_SA_LEN 209 sin->sin_len = sizeof(struct sockaddr_in); 210#endif 211 sin->sin_family = AF_INET; 212 memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src)); 213 sin = (struct sockaddr_in *)&cookiecache[ninitiator].raddr; 214#ifdef HAVE_SOCKADDR_SA_LEN 215 sin->sin_len = sizeof(struct sockaddr_in); 216#endif 217 sin->sin_family = AF_INET; 218 memcpy(&sin->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst)); 219 break; 220#ifdef INET6 221 case 6: 222 memset(&cookiecache[ninitiator].iaddr, 0, 223 sizeof(cookiecache[ninitiator].iaddr)); 224 memset(&cookiecache[ninitiator].raddr, 0, 225 sizeof(cookiecache[ninitiator].raddr)); 226 227 ip6 = (struct ip6_hdr *)bp2; 228 sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].iaddr; 229#ifdef HAVE_SOCKADDR_SA_LEN 230 sin6->sin6_len = sizeof(struct sockaddr_in6); 231#endif 232 sin6->sin6_family = AF_INET6; 233 memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src)); 234 sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].raddr; 235#ifdef HAVE_SOCKADDR_SA_LEN 236 sin6->sin6_len = sizeof(struct sockaddr_in6); 237#endif 238 sin6->sin6_family = AF_INET6; 239 memcpy(&sin6->sin6_addr, &ip6->ip6_dst, sizeof(ip6->ip6_dst)); 240 break; 241#endif 242 default: 243 return; 244 } 245 memcpy(&cookiecache[ninitiator].initiator, in, sizeof(*in)); 246 ninitiator = (ninitiator + 1) % MAXINITIATORS; 247} 248 249#define cookie_isinitiator(x, y) cookie_sidecheck((x), (y), 1) 250#define cookie_isresponder(x, y) cookie_sidecheck((x), (y), 0) 251static int 252cookie_sidecheck(int i, const u_char *bp2, int initiator) 253{ 254 struct sockaddr_storage ss; 255 struct sockaddr *sa; 256 struct ip *ip; 257 struct sockaddr_in *sin; 258#ifdef INET6 259 struct ip6_hdr *ip6; 260 struct sockaddr_in6 *sin6; 261#endif 262 int salen; 263 264 memset(&ss, 0, sizeof(ss)); 265 ip = (struct ip *)bp2; 266 switch (IP_V(ip)) { 267 case 4: 268 sin = (struct sockaddr_in *)&ss; 269#ifdef HAVE_SOCKADDR_SA_LEN 270 sin->sin_len = sizeof(struct sockaddr_in); 271#endif 272 sin->sin_family = AF_INET; 273 memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src)); 274 break; 275#ifdef INET6 276 case 6: 277 ip6 = (struct ip6_hdr *)bp2; 278 sin6 = (struct sockaddr_in6 *)&ss; 279#ifdef HAVE_SOCKADDR_SA_LEN 280 sin6->sin6_len = sizeof(struct sockaddr_in6); 281#endif 282 sin6->sin6_family = AF_INET6; 283 memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src)); 284 break; 285#endif 286 default: 287 return 0; 288 } 289 290 sa = (struct sockaddr *)&ss; 291 if (initiator) { 292 if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].iaddr)->sa_family) 293 return 0; 294#ifdef HAVE_SOCKADDR_SA_LEN 295 salen = sa->sa_len; 296#else 297#ifdef INET6 298 if (sa->sa_family == AF_INET6) 299 salen = sizeof(struct sockaddr_in6); 300 else 301 salen = sizeof(struct sockaddr); 302#else 303 salen = sizeof(struct sockaddr); 304#endif 305#endif 306 if (memcmp(&ss, &cookiecache[i].iaddr, salen) == 0) 307 return 1; 308 } else { 309 if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].raddr)->sa_family) 310 return 0; 311#ifdef HAVE_SOCKADDR_SA_LEN 312 salen = sa->sa_len; 313#else 314#ifdef INET6 315 if (sa->sa_family == AF_INET6) 316 salen = sizeof(struct sockaddr_in6); 317 else 318 salen = sizeof(struct sockaddr); 319#else 320 salen = sizeof(struct sockaddr); 321#endif 322#endif 323 if (memcmp(&ss, &cookiecache[i].raddr, salen) == 0) 324 return 1; 325 } 326 return 0; 327} 328 329static void 330rawprint(caddr_t loc, size_t len) 331{ 332 static u_char *p; 333 int i; 334
| 1/* 2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 3. Neither the name of the project nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 */ 30 31#ifndef lint 32static const char rcsid[] = 33 "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.29.2.2 2003/02/26 05:58:39 fenner Exp $ (LBL)"; 34#endif 35 36#ifdef HAVE_CONFIG_H 37#include "config.h" 38#endif 39 40#include <string.h> 41#include <ctype.h> 42#include <sys/param.h> 43#include <sys/time.h> 44#include <sys/socket.h> 45 46#include <netinet/in.h> 47 48#include <stdio.h> 49#include <netdb.h> 50 51#include "isakmp.h" 52#include "ipsec_doi.h" 53#include "oakley.h" 54#include "interface.h" 55#include "addrtoname.h" 56#include "extract.h" /* must come after interface.h */ 57 58#include "ip.h" 59#ifdef INET6 60#include "ip6.h" 61#endif 62 63#ifndef HAVE_SOCKADDR_STORAGE 64#define sockaddr_storage sockaddr 65#endif 66 67static u_char *isakmp_sa_print(struct isakmp_gen *, u_char *, u_int32_t, 68 u_int32_t, u_int32_t); 69static u_char *isakmp_p_print(struct isakmp_gen *, u_char *, u_int32_t, 70 u_int32_t, u_int32_t); 71static u_char *isakmp_t_print(struct isakmp_gen *, u_char *, u_int32_t, 72 u_int32_t, u_int32_t); 73static u_char *isakmp_ke_print(struct isakmp_gen *, u_char *, u_int32_t, 74 u_int32_t, u_int32_t); 75static u_char *isakmp_id_print(struct isakmp_gen *, u_char *, u_int32_t, 76 u_int32_t, u_int32_t); 77static u_char *isakmp_cert_print(struct isakmp_gen *, u_char *, u_int32_t, 78 u_int32_t, u_int32_t); 79static u_char *isakmp_cr_print(struct isakmp_gen *, u_char *, u_int32_t, 80 u_int32_t, u_int32_t); 81static u_char *isakmp_sig_print(struct isakmp_gen *, u_char *, u_int32_t, 82 u_int32_t, u_int32_t); 83static u_char *isakmp_hash_print(struct isakmp_gen *, u_char *, 84 u_int32_t, u_int32_t, u_int32_t); 85static u_char *isakmp_nonce_print(struct isakmp_gen *, u_char *, 86 u_int32_t, u_int32_t, u_int32_t); 87static u_char *isakmp_n_print(struct isakmp_gen *, u_char *, u_int32_t, 88 u_int32_t, u_int32_t); 89static u_char *isakmp_d_print(struct isakmp_gen *, u_char *, u_int32_t, 90 u_int32_t, u_int32_t); 91static u_char *isakmp_vid_print(struct isakmp_gen *, u_char *, u_int32_t, 92 u_int32_t, u_int32_t); 93static u_char *isakmp_sub0_print(u_char, struct isakmp_gen *, u_char *, 94 u_int32_t, u_int32_t, u_int32_t); 95static u_char *isakmp_sub_print(u_char, struct isakmp_gen *, u_char *, 96 u_int32_t, u_int32_t, u_int32_t); 97static char *numstr(int); 98static void safememcpy(void *, void *, size_t); 99 100#define MAXINITIATORS 20 101int ninitiator = 0; 102struct { 103 cookie_t initiator; 104 struct sockaddr_storage iaddr; 105 struct sockaddr_storage raddr; 106} cookiecache[MAXINITIATORS]; 107 108/* protocol id */ 109static char *protoidstr[] = { 110 NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp", 111}; 112 113/* isakmp->np */ 114static char *npstr[] = { 115 "none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash", 116 "sig", "nonce", "n", "d", "vid" 117}; 118 119/* isakmp->np */ 120static u_char *(*npfunc[])(struct isakmp_gen *, u_char *, u_int32_t, 121 u_int32_t, u_int32_t) = { 122 NULL, 123 isakmp_sa_print, 124 isakmp_p_print, 125 isakmp_t_print, 126 isakmp_ke_print, 127 isakmp_id_print, 128 isakmp_cert_print, 129 isakmp_cr_print, 130 isakmp_hash_print, 131 isakmp_sig_print, 132 isakmp_nonce_print, 133 isakmp_n_print, 134 isakmp_d_print, 135 isakmp_vid_print, 136}; 137 138/* isakmp->etype */ 139static char *etypestr[] = { 140 "none", "base", "ident", "auth", "agg", "inf", NULL, NULL, 141 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 142 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 143 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 144 "oakley-quick", "oakley-newgroup", 145}; 146 147#define STR_OR_ID(x, tab) \ 148 (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x)) 149#define PROTOIDSTR(x) STR_OR_ID(x, protoidstr) 150#define NPSTR(x) STR_OR_ID(x, npstr) 151#define ETYPESTR(x) STR_OR_ID(x, etypestr) 152 153#define NPFUNC(x) \ 154 (((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \ 155 ? npfunc[(x)] : NULL) 156 157static int 158iszero(u_char *p, size_t l) 159{ 160 while (l--) { 161 if (*p++) 162 return 0; 163 } 164 return 1; 165} 166 167/* find cookie from initiator cache */ 168static int 169cookie_find(cookie_t *in) 170{ 171 int i; 172 173 for (i = 0; i < MAXINITIATORS; i++) { 174 if (memcmp(in, &cookiecache[i].initiator, sizeof(*in)) == 0) 175 return i; 176 } 177 178 return -1; 179} 180 181/* record initiator */ 182static void 183cookie_record(cookie_t *in, const u_char *bp2) 184{ 185 int i; 186 struct ip *ip; 187 struct sockaddr_in *sin; 188#ifdef INET6 189 struct ip6_hdr *ip6; 190 struct sockaddr_in6 *sin6; 191#endif 192 193 i = cookie_find(in); 194 if (0 <= i) { 195 ninitiator = (i + 1) % MAXINITIATORS; 196 return; 197 } 198 199 ip = (struct ip *)bp2; 200 switch (IP_V(ip)) { 201 case 4: 202 memset(&cookiecache[ninitiator].iaddr, 0, 203 sizeof(cookiecache[ninitiator].iaddr)); 204 memset(&cookiecache[ninitiator].raddr, 0, 205 sizeof(cookiecache[ninitiator].raddr)); 206 207 sin = (struct sockaddr_in *)&cookiecache[ninitiator].iaddr; 208#ifdef HAVE_SOCKADDR_SA_LEN 209 sin->sin_len = sizeof(struct sockaddr_in); 210#endif 211 sin->sin_family = AF_INET; 212 memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src)); 213 sin = (struct sockaddr_in *)&cookiecache[ninitiator].raddr; 214#ifdef HAVE_SOCKADDR_SA_LEN 215 sin->sin_len = sizeof(struct sockaddr_in); 216#endif 217 sin->sin_family = AF_INET; 218 memcpy(&sin->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst)); 219 break; 220#ifdef INET6 221 case 6: 222 memset(&cookiecache[ninitiator].iaddr, 0, 223 sizeof(cookiecache[ninitiator].iaddr)); 224 memset(&cookiecache[ninitiator].raddr, 0, 225 sizeof(cookiecache[ninitiator].raddr)); 226 227 ip6 = (struct ip6_hdr *)bp2; 228 sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].iaddr; 229#ifdef HAVE_SOCKADDR_SA_LEN 230 sin6->sin6_len = sizeof(struct sockaddr_in6); 231#endif 232 sin6->sin6_family = AF_INET6; 233 memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src)); 234 sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].raddr; 235#ifdef HAVE_SOCKADDR_SA_LEN 236 sin6->sin6_len = sizeof(struct sockaddr_in6); 237#endif 238 sin6->sin6_family = AF_INET6; 239 memcpy(&sin6->sin6_addr, &ip6->ip6_dst, sizeof(ip6->ip6_dst)); 240 break; 241#endif 242 default: 243 return; 244 } 245 memcpy(&cookiecache[ninitiator].initiator, in, sizeof(*in)); 246 ninitiator = (ninitiator + 1) % MAXINITIATORS; 247} 248 249#define cookie_isinitiator(x, y) cookie_sidecheck((x), (y), 1) 250#define cookie_isresponder(x, y) cookie_sidecheck((x), (y), 0) 251static int 252cookie_sidecheck(int i, const u_char *bp2, int initiator) 253{ 254 struct sockaddr_storage ss; 255 struct sockaddr *sa; 256 struct ip *ip; 257 struct sockaddr_in *sin; 258#ifdef INET6 259 struct ip6_hdr *ip6; 260 struct sockaddr_in6 *sin6; 261#endif 262 int salen; 263 264 memset(&ss, 0, sizeof(ss)); 265 ip = (struct ip *)bp2; 266 switch (IP_V(ip)) { 267 case 4: 268 sin = (struct sockaddr_in *)&ss; 269#ifdef HAVE_SOCKADDR_SA_LEN 270 sin->sin_len = sizeof(struct sockaddr_in); 271#endif 272 sin->sin_family = AF_INET; 273 memcpy(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src)); 274 break; 275#ifdef INET6 276 case 6: 277 ip6 = (struct ip6_hdr *)bp2; 278 sin6 = (struct sockaddr_in6 *)&ss; 279#ifdef HAVE_SOCKADDR_SA_LEN 280 sin6->sin6_len = sizeof(struct sockaddr_in6); 281#endif 282 sin6->sin6_family = AF_INET6; 283 memcpy(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src)); 284 break; 285#endif 286 default: 287 return 0; 288 } 289 290 sa = (struct sockaddr *)&ss; 291 if (initiator) { 292 if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].iaddr)->sa_family) 293 return 0; 294#ifdef HAVE_SOCKADDR_SA_LEN 295 salen = sa->sa_len; 296#else 297#ifdef INET6 298 if (sa->sa_family == AF_INET6) 299 salen = sizeof(struct sockaddr_in6); 300 else 301 salen = sizeof(struct sockaddr); 302#else 303 salen = sizeof(struct sockaddr); 304#endif 305#endif 306 if (memcmp(&ss, &cookiecache[i].iaddr, salen) == 0) 307 return 1; 308 } else { 309 if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].raddr)->sa_family) 310 return 0; 311#ifdef HAVE_SOCKADDR_SA_LEN 312 salen = sa->sa_len; 313#else 314#ifdef INET6 315 if (sa->sa_family == AF_INET6) 316 salen = sizeof(struct sockaddr_in6); 317 else 318 salen = sizeof(struct sockaddr); 319#else 320 salen = sizeof(struct sockaddr); 321#endif 322#endif 323 if (memcmp(&ss, &cookiecache[i].raddr, salen) == 0) 324 return 1; 325 } 326 return 0; 327} 328 329static void 330rawprint(caddr_t loc, size_t len) 331{ 332 static u_char *p; 333 int i; 334
|
338} 339 340struct attrmap { 341 char *type; 342 int nvalue; 343 char *value[30]; /*XXX*/ 344}; 345 346static u_char * 347isakmp_attrmap_print(u_char *p, u_char *ep, struct attrmap *map, size_t nmap) 348{ 349 u_int16_t *q; 350 int totlen; 351 u_int32_t t, v; 352 353 q = (u_int16_t *)p; 354 if (p[0] & 0x80) 355 totlen = 4; 356 else 357 totlen = 4 + ntohs(q[1]); 358 if (ep < p + totlen) { 359 printf("[|attr]"); 360 return ep + 1; 361 } 362 363 printf("("); 364 t = ntohs(q[0]) & 0x7fff; 365 if (map && t < nmap && map[t].type) 366 printf("type=%s ", map[t].type); 367 else 368 printf("type=#%d ", t); 369 if (p[0] & 0x80) { 370 printf("value="); 371 v = ntohs(q[1]); 372 if (map && t < nmap && v < map[t].nvalue && map[t].value[v]) 373 printf("%s", map[t].value[v]); 374 else 375 rawprint((caddr_t)&q[1], 2); 376 } else { 377 printf("len=%d value=", ntohs(q[1])); 378 rawprint((caddr_t)&p[4], ntohs(q[1])); 379 } 380 printf(")"); 381 return p + totlen; 382} 383 384static u_char * 385isakmp_attr_print(u_char *p, u_char *ep) 386{ 387 u_int16_t *q; 388 int totlen; 389 u_int32_t t; 390 391 q = (u_int16_t *)p; 392 if (p[0] & 0x80) 393 totlen = 4; 394 else 395 totlen = 4 + ntohs(q[1]); 396 if (ep < p + totlen) { 397 printf("[|attr]"); 398 return ep + 1; 399 } 400 401 printf("("); 402 t = ntohs(q[0]) & 0x7fff; 403 printf("type=#%d ", t); 404 if (p[0] & 0x80) { 405 printf("value="); 406 t = q[1]; 407 rawprint((caddr_t)&q[1], 2); 408 } else { 409 printf("len=%d value=", ntohs(q[1])); 410 rawprint((caddr_t)&p[2], ntohs(q[1])); 411 } 412 printf(")"); 413 return p + totlen; 414} 415 416static u_char * 417isakmp_sa_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 418 u_int32_t doi0, u_int32_t proto0) 419{ 420 struct isakmp_pl_sa *p, sa; 421 u_int32_t *q; 422 u_int32_t doi, sit, ident; 423 u_char *cp, *np; 424 int t; 425 426 printf("%s:", NPSTR(ISAKMP_NPTYPE_SA)); 427 428 p = (struct isakmp_pl_sa *)ext; 429 safememcpy(&sa, ext, sizeof(sa)); 430 doi = ntohl(sa.doi); 431 sit = ntohl(sa.sit); 432 if (doi != 1) { 433 printf(" doi=%d", doi); 434 printf(" situation=%u", (u_int32_t)ntohl(sa.sit)); 435 return (u_char *)(p + 1); 436 } 437 438 printf(" doi=ipsec"); 439 q = (u_int32_t *)&sa.sit; 440 printf(" situation="); 441 t = 0; 442 if (sit & 0x01) { 443 printf("identity"); 444 t++; 445 } 446 if (sit & 0x02) { 447 printf("%ssecrecy", t ? "+" : ""); 448 t++; 449 } 450 if (sit & 0x04) 451 printf("%sintegrity", t ? "+" : ""); 452 453 np = (u_char *)ext + sizeof(sa); 454 if (sit != 0x01) { 455 safememcpy(&ident, ext + 1, sizeof(ident)); 456 printf(" ident=%u", (u_int32_t)ntohl(ident)); 457 np += sizeof(ident); 458 } 459 460 ext = (struct isakmp_gen *)np; 461 462 cp = isakmp_sub_print(ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0); 463 464 return cp; 465} 466 467static u_char * 468isakmp_p_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 469 u_int32_t doi0, u_int32_t proto0) 470{ 471 struct isakmp_pl_p *p, prop; 472 u_char *cp; 473 474 printf("%s:", NPSTR(ISAKMP_NPTYPE_P)); 475 476 p = (struct isakmp_pl_p *)ext; 477 safememcpy(&prop, ext, sizeof(prop)); 478 printf(" #%d protoid=%s transform=%d", 479 prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t); 480 if (prop.spi_size) { 481 printf(" spi="); 482 rawprint((caddr_t)(p + 1), prop.spi_size); 483 } 484 485 ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size); 486 487 cp = isakmp_sub_print(ISAKMP_NPTYPE_T, ext, ep, phase, doi0, 488 prop.prot_id); 489 490 return cp; 491} 492 493static char *isakmp_p_map[] = { 494 NULL, "ike", 495}; 496 497static char *ah_p_map[] = { 498 NULL, "(reserved)", "md5", "sha", "1des", 499 "sha2-256", "sha2-384", "sha2-512", 500}; 501 502static char *esp_p_map[] = { 503 NULL, "1des-iv64", "1des", "3des", "rc5", "idea", "cast", 504 "blowfish", "3idea", "1des-iv32", "rc4", "null", "aes" 505}; 506 507static char *ipcomp_p_map[] = { 508 NULL, "oui", "deflate", "lzs", 509}; 510 511struct attrmap ipsec_t_map[] = { 512 { NULL, 0, }, 513 { "lifetype", 3, { NULL, "sec", "kb", }, }, 514 { "life", 0, }, 515 { "group desc", 5, { NULL, "modp768", "modp1024", "EC2N 2^155", 516 "EC2N 2^185", }, }, 517 { "enc mode", 3, { NULL, "tunnel", "transport", }, }, 518 { "auth", 5, { NULL, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, }, 519 { "keylen", 0, }, 520 { "rounds", 0, }, 521 { "dictsize", 0, }, 522 { "privalg", 0, }, 523}; 524 525struct attrmap oakley_t_map[] = { 526 { NULL, 0 }, 527 { "enc", 8, { NULL, "1des", "idea", "blowfish", "rc5", 528 "3des", "cast", "aes", }, }, 529 { "hash", 7, { NULL, "md5", "sha1", "tiger", 530 "sha2-256", "sha2-384", "sha2-512", }, }, 531 { "auth", 6, { NULL, "preshared", "dss", "rsa sig", "rsa enc", 532 "rsa enc revised", }, }, 533 { "group desc", 5, { NULL, "modp768", "modp1024", "EC2N 2^155", 534 "EC2N 2^185", }, }, 535 { "group type", 4, { NULL, "MODP", "ECP", "EC2N", }, }, 536 { "group prime", 0, }, 537 { "group gen1", 0, }, 538 { "group gen2", 0, }, 539 { "group curve A", 0, }, 540 { "group curve B", 0, }, 541 { "lifetype", 3, { NULL, "sec", "kb", }, }, 542 { "lifeduration", 0, }, 543 { "prf", 0, }, 544 { "keylen", 0, }, 545 { "field", 0, }, 546 { "order", 0, }, 547}; 548 549static u_char * 550isakmp_t_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 551 u_int32_t doi, u_int32_t proto) 552{ 553 struct isakmp_pl_t *p, t; 554 u_char *cp; 555 char *idstr; 556 struct attrmap *map; 557 size_t nmap; 558 u_char *ep2; 559 560 printf("%s:", NPSTR(ISAKMP_NPTYPE_T)); 561 562 p = (struct isakmp_pl_t *)ext; 563 safememcpy(&t, ext, sizeof(t)); 564 565 switch (proto) { 566 case 1: 567 idstr = STR_OR_ID(t.t_id, isakmp_p_map); 568 map = oakley_t_map; 569 nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]); 570 break; 571 case 2: 572 idstr = STR_OR_ID(t.t_id, ah_p_map); 573 map = ipsec_t_map; 574 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); 575 break; 576 case 3: 577 idstr = STR_OR_ID(t.t_id, esp_p_map); 578 map = ipsec_t_map; 579 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); 580 break; 581 case 4: 582 idstr = STR_OR_ID(t.t_id, ipcomp_p_map); 583 map = ipsec_t_map; 584 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); 585 break; 586 default: 587 idstr = NULL; 588 map = NULL; 589 nmap = 0; 590 break; 591 } 592 593 if (idstr) 594 printf(" #%d id=%s ", t.t_no, idstr); 595 else 596 printf(" #%d id=%d ", t.t_no, t.t_id); 597 cp = (u_char *)(p + 1); 598 ep2 = (u_char *)p + ntohs(t.h.len); 599 while (cp < ep && cp < ep2) { 600 if (map && nmap) { 601 cp = isakmp_attrmap_print(cp, (ep < ep2) ? ep : ep2, 602 map, nmap); 603 } else 604 cp = isakmp_attr_print(cp, (ep < ep2) ? ep : ep2); 605 } 606 if (ep < ep2) 607 printf("..."); 608 return cp; 609} 610 611static u_char * 612isakmp_ke_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 613 u_int32_t doi, u_int32_t proto) 614{ 615 struct isakmp_gen e; 616 617 printf("%s:", NPSTR(ISAKMP_NPTYPE_KE)); 618 619 safememcpy(&e, ext, sizeof(e)); 620 printf(" key len=%d", ntohs(e.len) - 4); 621 if (2 < vflag && 4 < ntohs(e.len)) { 622 printf(" "); 623 rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); 624 } 625 return (u_char *)ext + ntohs(e.len); 626} 627 628static u_char * 629isakmp_id_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 630 u_int32_t doi, u_int32_t proto) 631{ 632#define USE_IPSECDOI_IN_PHASE1 1 633 struct isakmp_pl_id *p, id; 634 static char *idtypestr[] = { 635 "IPv4", "IPv4net", "IPv6", "IPv6net", 636 }; 637 static char *ipsecidtypestr[] = { 638 NULL, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6", 639 "IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN", 640 "keyid", 641 }; 642 int len; 643 u_char *data; 644 645 printf("%s:", NPSTR(ISAKMP_NPTYPE_ID)); 646 647 p = (struct isakmp_pl_id *)ext; 648 safememcpy(&id, ext, sizeof(id)); 649 if (sizeof(*p) < id.h.len) 650 data = (u_char *)(p + 1); 651 else 652 data = NULL; 653 len = ntohs(id.h.len) - sizeof(*p); 654 655#if 0 /*debug*/ 656 printf(" [phase=%d doi=%d proto=%d]", phase, doi, proto); 657#endif 658 switch (phase) { 659#ifndef USE_IPSECDOI_IN_PHASE1 660 case 1: 661#endif 662 default: 663 printf(" idtype=%s", STR_OR_ID(id.d.id_type, idtypestr)); 664 printf(" doi_data=%u", 665 (u_int32_t)(ntohl(id.d.doi_data) & 0xffffff)); 666 break; 667 668#ifdef USE_IPSECDOI_IN_PHASE1 669 case 1: 670#endif 671 case 2: 672 { 673 struct ipsecdoi_id *p, id; 674 struct protoent *pe; 675 676 p = (struct ipsecdoi_id *)ext; 677 safememcpy(&id, ext, sizeof(id)); 678 printf(" idtype=%s", STR_OR_ID(id.type, ipsecidtypestr)); 679 if (id.proto_id) { 680 setprotoent(1); 681 pe = getprotobynumber(id.proto_id); 682 if (pe) 683 printf(" protoid=%s", pe->p_name); 684 endprotoent(); 685 } else { 686 /* it DOES NOT mean IPPROTO_IP! */ 687 printf(" protoid=%s", "0"); 688 } 689 printf(" port=%d", ntohs(id.port)); 690 if (!len) 691 break; 692 switch (id.type) { 693 case IPSECDOI_ID_IPV4_ADDR: 694 printf(" len=%d %s", len, ipaddr_string(data)); 695 len = 0; 696 break; 697 case IPSECDOI_ID_FQDN: 698 case IPSECDOI_ID_USER_FQDN: 699 { 700 int i; 701 printf(" len=%d ", len); 702 for (i = 0; i < len; i++) 703 safeputchar(data[i]); 704 len = 0; 705 break; 706 } 707 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 708 { 709 u_char *mask; 710 mask = data + sizeof(struct in_addr); 711 printf(" len=%d %s/%u.%u.%u.%u", len, 712 ipaddr_string(data), 713 mask[0], mask[1], mask[2], mask[3]); 714 len = 0; 715 break; 716 } 717#ifdef INET6 718 case IPSECDOI_ID_IPV6_ADDR: 719 printf(" len=%d %s", len, ip6addr_string(data)); 720 len = 0; 721 break; 722 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 723 { 724 u_int32_t *mask; 725 mask = (u_int32_t *)(data + sizeof(struct in6_addr)); 726 /*XXX*/ 727 printf(" len=%d %s/0x%08x%08x%08x%08x", len, 728 ip6addr_string(data), 729 mask[0], mask[1], mask[2], mask[3]); 730 len = 0; 731 break; 732 } 733#endif /*INET6*/ 734 case IPSECDOI_ID_IPV4_ADDR_RANGE: 735 printf(" len=%d %s-%s", len, ipaddr_string(data), 736 ipaddr_string(data + sizeof(struct in_addr))); 737 len = 0; 738 break; 739#ifdef INET6 740 case IPSECDOI_ID_IPV6_ADDR_RANGE: 741 printf(" len=%d %s-%s", len, ip6addr_string(data), 742 ip6addr_string(data + sizeof(struct in6_addr))); 743 len = 0; 744 break; 745#endif /*INET6*/ 746 case IPSECDOI_ID_DER_ASN1_DN: 747 case IPSECDOI_ID_DER_ASN1_GN: 748 case IPSECDOI_ID_KEY_ID: 749 break; 750 } 751 break; 752 } 753 } 754 if (data && len) { 755 printf(" len=%d", len); 756 if (2 < vflag) { 757 printf(" "); 758 rawprint((caddr_t)data, len); 759 } 760 } 761 return (u_char *)ext + ntohs(id.h.len); 762} 763 764static u_char * 765isakmp_cert_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 766 u_int32_t doi0, u_int32_t proto0) 767{ 768 struct isakmp_pl_cert *p, cert; 769 static char *certstr[] = { 770 "none", "pkcs7", "pgp", "dns", 771 "x509sign", "x509ke", "kerberos", "crl", 772 "arl", "spki", "x509attr", 773 }; 774 775 printf("%s:", NPSTR(ISAKMP_NPTYPE_CERT)); 776 777 p = (struct isakmp_pl_cert *)ext; 778 safememcpy(&cert, ext, sizeof(cert)); 779 printf(" len=%d", ntohs(cert.h.len) - 4); 780 printf(" type=%s", STR_OR_ID((cert.encode), certstr)); 781 if (2 < vflag && 4 < ntohs(cert.h.len)) { 782 printf(" "); 783 rawprint((caddr_t)(ext + 1), ntohs(cert.h.len) - 4); 784 } 785 return (u_char *)ext + ntohs(cert.h.len); 786} 787 788static u_char * 789isakmp_cr_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 790 u_int32_t doi0, u_int32_t proto0) 791{ 792 struct isakmp_pl_cert *p, cert; 793 static char *certstr[] = { 794 "none", "pkcs7", "pgp", "dns", 795 "x509sign", "x509ke", "kerberos", "crl", 796 "arl", "spki", "x509attr", 797 }; 798 799 printf("%s:", NPSTR(ISAKMP_NPTYPE_CR)); 800 801 p = (struct isakmp_pl_cert *)ext; 802 safememcpy(&cert, ext, sizeof(cert)); 803 printf(" len=%d", ntohs(cert.h.len) - 4); 804 printf(" type=%s", STR_OR_ID((cert.encode), certstr)); 805 if (2 < vflag && 4 < ntohs(cert.h.len)) { 806 printf(" "); 807 rawprint((caddr_t)(ext + 1), ntohs(cert.h.len) - 4); 808 } 809 return (u_char *)ext + ntohs(cert.h.len); 810} 811 812static u_char * 813isakmp_hash_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 814 u_int32_t doi, u_int32_t proto) 815{ 816 struct isakmp_gen e; 817 818 printf("%s:", NPSTR(ISAKMP_NPTYPE_HASH)); 819 820 safememcpy(&e, ext, sizeof(e)); 821 printf(" len=%d", ntohs(e.len) - 4); 822 if (2 < vflag && 4 < ntohs(e.len)) { 823 printf(" "); 824 rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); 825 } 826 return (u_char *)ext + ntohs(e.len); 827} 828 829static u_char * 830isakmp_sig_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 831 u_int32_t doi, u_int32_t proto) 832{ 833 struct isakmp_gen e; 834 835 printf("%s:", NPSTR(ISAKMP_NPTYPE_SIG)); 836 837 safememcpy(&e, ext, sizeof(e)); 838 printf(" len=%d", ntohs(e.len) - 4); 839 if (2 < vflag && 4 < ntohs(e.len)) { 840 printf(" "); 841 rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); 842 } 843 return (u_char *)ext + ntohs(e.len); 844} 845 846static u_char * 847isakmp_nonce_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 848 u_int32_t doi, u_int32_t proto) 849{ 850 struct isakmp_gen e; 851 852 printf("%s:", NPSTR(ISAKMP_NPTYPE_NONCE)); 853 854 safememcpy(&e, ext, sizeof(e)); 855 printf(" n len=%d", ntohs(e.len) - 4); 856 if (2 < vflag && 4 < ntohs(e.len)) { 857 printf(" "); 858 rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); 859 } 860 return (u_char *)ext + ntohs(e.len); 861} 862 863static u_char * 864isakmp_n_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 865 u_int32_t doi0, u_int32_t proto0) 866{ 867 struct isakmp_pl_n *p, n; 868 u_char *cp; 869 u_char *ep2; 870 u_int32_t doi; 871 u_int32_t proto; 872 static char *notifystr[] = { 873 NULL, "INVALID-PAYLOAD-TYPE", 874 "DOI-NOT-SUPPORTED", "SITUATION-NOT-SUPPORTED", 875 "INVALID-COOKIE", "INVALID-MAJOR-VERSION", 876 "INVALID-MINOR-VERSION", "INVALID-EXCHANGE-TYPE", 877 "INVALID-FLAGS", "INVALID-MESSAGE-ID", 878 "INVALID-PROTOCOL-ID", "INVALID-SPI", 879 "INVALID-TRANSFORM-ID", "ATTRIBUTES-NOT-SUPPORTED", 880 "NO-PROPOSAL-CHOSEN", "BAD-PROPOSAL-SYNTAX", 881 "PAYLOAD-MALFORMED", "INVALID-KEY-INFORMATION", 882 "INVALID-ID-INFORMATION", "INVALID-CERT-ENCODING", 883 "INVALID-CERTIFICATE", "CERT-TYPE-UNSUPPORTED", 884 "INVALID-CERT-AUTHORITY", "INVALID-HASH-INFORMATION", 885 "AUTHENTICATION-FAILED", "INVALID-SIGNATURE", 886 "ADDRESS-NOTIFICATION", "NOTIFY-SA-LIFETIME", 887 "CERTIFICATE-UNAVAILABLE", "UNSUPPORTED-EXCHANGE-TYPE", 888 "UNEQUAL-PAYLOAD-LENGTHS", 889 }; 890 static char *ipsecnotifystr[] = { 891 "RESPONDER-LIFETIME", "REPLAY-STATUS", 892 "INITIAL-CONTACT", 893 }; 894/* NOTE: these macro must be called with x in proper range */ 895#define NOTIFYSTR(x) \ 896 (((x) == 16384) ? "CONNECTED" : STR_OR_ID((x), notifystr)) 897#define IPSECNOTIFYSTR(x) \ 898 (((x) == 8192) ? "RESERVED" : STR_OR_ID(((x) - 24576), ipsecnotifystr)) 899 900 printf("%s:", NPSTR(ISAKMP_NPTYPE_N)); 901 902 p = (struct isakmp_pl_n *)ext; 903 safememcpy(&n, ext, sizeof(n)); 904 doi = ntohl(n.doi); 905 proto = n.prot_id; 906 if (doi != 1) { 907 printf(" doi=%d", doi); 908 printf(" proto=%d", proto); 909 printf(" type=%s", NOTIFYSTR(ntohs(n.type))); 910 if (n.spi_size) { 911 printf(" spi="); 912 rawprint((caddr_t)(p + 1), n.spi_size); 913 } 914 return (u_char *)(p + 1) + n.spi_size; 915 } 916 917 printf(" doi=ipsec"); 918 printf(" proto=%s", PROTOIDSTR(proto)); 919 if (ntohs(n.type) < 8192) 920 printf(" type=%s", NOTIFYSTR(ntohs(n.type))); 921 else if (ntohs(n.type) < 16384) 922 printf(" type=%s", IPSECNOTIFYSTR(ntohs(n.type))); 923 else if (ntohs(n.type) < 24576) 924 printf(" type=%s", NOTIFYSTR(ntohs(n.type))); 925 else if (ntohs(n.type) < 40960) 926 printf(" type=%s", IPSECNOTIFYSTR(ntohs(n.type))); 927 else 928 printf(" type=%s", NOTIFYSTR(ntohs(n.type))); 929 if (n.spi_size) { 930 printf(" spi="); 931 rawprint((caddr_t)(p + 1), n.spi_size); 932 } 933 934 cp = (u_char *)(p + 1) + n.spi_size; 935 ep2 = (u_char *)p + ntohs(n.h.len); 936 937 if (cp < ep) { 938 printf(" orig=("); 939 switch (ntohs(n.type)) { 940 case IPSECDOI_NTYPE_RESPONDER_LIFETIME: 941 { 942 struct attrmap *map = oakley_t_map; 943 size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]); 944 while (cp < ep && cp < ep2) { 945 cp = isakmp_attrmap_print(cp, 946 (ep < ep2) ? ep : ep2, map, nmap); 947 } 948 break; 949 } 950 case IPSECDOI_NTYPE_REPLAY_STATUS: 951 printf("replay detection %sabled", 952 (*(u_int32_t *)cp) ? "en" : "dis"); 953 break; 954 case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN: 955 isakmp_sub_print(ISAKMP_NPTYPE_SA, 956 (struct isakmp_gen *)cp, ep, phase, doi, proto); 957 break; 958 default: 959 /* NULL is dummy */ 960 isakmp_print(cp, 961 ntohs(n.h.len) - sizeof(*p) - n.spi_size, 962 NULL); 963 } 964 printf(")"); 965 } 966 return (u_char *)ext + ntohs(n.h.len); 967} 968 969static u_char * 970isakmp_d_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 971 u_int32_t doi0, u_int32_t proto0) 972{ 973 struct isakmp_pl_d *p, d; 974 u_int8_t *q; 975 u_int32_t doi; 976 u_int32_t proto; 977 int i; 978 979 printf("%s:", NPSTR(ISAKMP_NPTYPE_D)); 980 981 p = (struct isakmp_pl_d *)ext; 982 safememcpy(&d, ext, sizeof(d)); 983 doi = ntohl(d.doi); 984 proto = d.prot_id; 985 if (doi != 1) { 986 printf(" doi=%u", doi); 987 printf(" proto=%u", proto); 988 } else { 989 printf(" doi=ipsec"); 990 printf(" proto=%s", PROTOIDSTR(proto)); 991 } 992 printf(" spilen=%u", d.spi_size); 993 printf(" nspi=%u", ntohs(d.num_spi)); 994 printf(" spi="); 995 q = (u_int8_t *)(p + 1); 996 for (i = 0; i < ntohs(d.num_spi); i++) { 997 if (i != 0) 998 printf(","); 999 rawprint((caddr_t)q, d.spi_size); 1000 q += d.spi_size; 1001 } 1002 return q; 1003} 1004 1005static u_char * 1006isakmp_vid_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 1007 u_int32_t doi, u_int32_t proto) 1008{ 1009 struct isakmp_gen e; 1010 1011 printf("%s:", NPSTR(ISAKMP_NPTYPE_VID)); 1012 1013 safememcpy(&e, ext, sizeof(e)); 1014 printf(" len=%d", ntohs(e.len) - 4); 1015 if (2 < vflag && 4 < ntohs(e.len)) { 1016 printf(" "); 1017 rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); 1018 } 1019 return (u_char *)ext + ntohs(e.len); 1020} 1021 1022static u_char * 1023isakmp_sub0_print(u_char np, struct isakmp_gen *ext, u_char *ep, 1024 u_int32_t phase, u_int32_t doi, u_int32_t proto) 1025{ 1026 u_char *cp; 1027 struct isakmp_gen e; 1028 u_int item_len; 1029 1030 cp = (u_char *)ext; 1031 safememcpy(&e, ext, sizeof(e)); 1032 1033 if (NPFUNC(np)) 1034 cp = (*NPFUNC(np))(ext, ep, phase, doi, proto); 1035 else { 1036 printf("%s", NPSTR(np)); 1037 item_len = ntohs(e.len); 1038 if (item_len == 0) { 1039 /* 1040 * We don't want to loop forever processing this 1041 * bogus (zero-length) item; return NULL so that 1042 * we stop dissecting. 1043 */ 1044 cp = NULL; 1045 } else 1046 cp += item_len; 1047 } 1048 return cp; 1049} 1050 1051static u_char * 1052isakmp_sub_print(u_char np, struct isakmp_gen *ext, u_char *ep, 1053 u_int32_t phase, u_int32_t doi, u_int32_t proto) 1054{ 1055 u_char *cp; 1056 static int depth = 0; 1057 int i; 1058 struct isakmp_gen e; 1059 1060 cp = (u_char *)ext; 1061 1062 while (np) {
| 342} 343 344struct attrmap { 345 char *type; 346 int nvalue; 347 char *value[30]; /*XXX*/ 348}; 349 350static u_char * 351isakmp_attrmap_print(u_char *p, u_char *ep, struct attrmap *map, size_t nmap) 352{ 353 u_int16_t *q; 354 int totlen; 355 u_int32_t t, v; 356 357 q = (u_int16_t *)p; 358 if (p[0] & 0x80) 359 totlen = 4; 360 else 361 totlen = 4 + ntohs(q[1]); 362 if (ep < p + totlen) { 363 printf("[|attr]"); 364 return ep + 1; 365 } 366 367 printf("("); 368 t = ntohs(q[0]) & 0x7fff; 369 if (map && t < nmap && map[t].type) 370 printf("type=%s ", map[t].type); 371 else 372 printf("type=#%d ", t); 373 if (p[0] & 0x80) { 374 printf("value="); 375 v = ntohs(q[1]); 376 if (map && t < nmap && v < map[t].nvalue && map[t].value[v]) 377 printf("%s", map[t].value[v]); 378 else 379 rawprint((caddr_t)&q[1], 2); 380 } else { 381 printf("len=%d value=", ntohs(q[1])); 382 rawprint((caddr_t)&p[4], ntohs(q[1])); 383 } 384 printf(")"); 385 return p + totlen; 386} 387 388static u_char * 389isakmp_attr_print(u_char *p, u_char *ep) 390{ 391 u_int16_t *q; 392 int totlen; 393 u_int32_t t; 394 395 q = (u_int16_t *)p; 396 if (p[0] & 0x80) 397 totlen = 4; 398 else 399 totlen = 4 + ntohs(q[1]); 400 if (ep < p + totlen) { 401 printf("[|attr]"); 402 return ep + 1; 403 } 404 405 printf("("); 406 t = ntohs(q[0]) & 0x7fff; 407 printf("type=#%d ", t); 408 if (p[0] & 0x80) { 409 printf("value="); 410 t = q[1]; 411 rawprint((caddr_t)&q[1], 2); 412 } else { 413 printf("len=%d value=", ntohs(q[1])); 414 rawprint((caddr_t)&p[2], ntohs(q[1])); 415 } 416 printf(")"); 417 return p + totlen; 418} 419 420static u_char * 421isakmp_sa_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 422 u_int32_t doi0, u_int32_t proto0) 423{ 424 struct isakmp_pl_sa *p, sa; 425 u_int32_t *q; 426 u_int32_t doi, sit, ident; 427 u_char *cp, *np; 428 int t; 429 430 printf("%s:", NPSTR(ISAKMP_NPTYPE_SA)); 431 432 p = (struct isakmp_pl_sa *)ext; 433 safememcpy(&sa, ext, sizeof(sa)); 434 doi = ntohl(sa.doi); 435 sit = ntohl(sa.sit); 436 if (doi != 1) { 437 printf(" doi=%d", doi); 438 printf(" situation=%u", (u_int32_t)ntohl(sa.sit)); 439 return (u_char *)(p + 1); 440 } 441 442 printf(" doi=ipsec"); 443 q = (u_int32_t *)&sa.sit; 444 printf(" situation="); 445 t = 0; 446 if (sit & 0x01) { 447 printf("identity"); 448 t++; 449 } 450 if (sit & 0x02) { 451 printf("%ssecrecy", t ? "+" : ""); 452 t++; 453 } 454 if (sit & 0x04) 455 printf("%sintegrity", t ? "+" : ""); 456 457 np = (u_char *)ext + sizeof(sa); 458 if (sit != 0x01) { 459 safememcpy(&ident, ext + 1, sizeof(ident)); 460 printf(" ident=%u", (u_int32_t)ntohl(ident)); 461 np += sizeof(ident); 462 } 463 464 ext = (struct isakmp_gen *)np; 465 466 cp = isakmp_sub_print(ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0); 467 468 return cp; 469} 470 471static u_char * 472isakmp_p_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 473 u_int32_t doi0, u_int32_t proto0) 474{ 475 struct isakmp_pl_p *p, prop; 476 u_char *cp; 477 478 printf("%s:", NPSTR(ISAKMP_NPTYPE_P)); 479 480 p = (struct isakmp_pl_p *)ext; 481 safememcpy(&prop, ext, sizeof(prop)); 482 printf(" #%d protoid=%s transform=%d", 483 prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t); 484 if (prop.spi_size) { 485 printf(" spi="); 486 rawprint((caddr_t)(p + 1), prop.spi_size); 487 } 488 489 ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size); 490 491 cp = isakmp_sub_print(ISAKMP_NPTYPE_T, ext, ep, phase, doi0, 492 prop.prot_id); 493 494 return cp; 495} 496 497static char *isakmp_p_map[] = { 498 NULL, "ike", 499}; 500 501static char *ah_p_map[] = { 502 NULL, "(reserved)", "md5", "sha", "1des", 503 "sha2-256", "sha2-384", "sha2-512", 504}; 505 506static char *esp_p_map[] = { 507 NULL, "1des-iv64", "1des", "3des", "rc5", "idea", "cast", 508 "blowfish", "3idea", "1des-iv32", "rc4", "null", "aes" 509}; 510 511static char *ipcomp_p_map[] = { 512 NULL, "oui", "deflate", "lzs", 513}; 514 515struct attrmap ipsec_t_map[] = { 516 { NULL, 0, }, 517 { "lifetype", 3, { NULL, "sec", "kb", }, }, 518 { "life", 0, }, 519 { "group desc", 5, { NULL, "modp768", "modp1024", "EC2N 2^155", 520 "EC2N 2^185", }, }, 521 { "enc mode", 3, { NULL, "tunnel", "transport", }, }, 522 { "auth", 5, { NULL, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, }, 523 { "keylen", 0, }, 524 { "rounds", 0, }, 525 { "dictsize", 0, }, 526 { "privalg", 0, }, 527}; 528 529struct attrmap oakley_t_map[] = { 530 { NULL, 0 }, 531 { "enc", 8, { NULL, "1des", "idea", "blowfish", "rc5", 532 "3des", "cast", "aes", }, }, 533 { "hash", 7, { NULL, "md5", "sha1", "tiger", 534 "sha2-256", "sha2-384", "sha2-512", }, }, 535 { "auth", 6, { NULL, "preshared", "dss", "rsa sig", "rsa enc", 536 "rsa enc revised", }, }, 537 { "group desc", 5, { NULL, "modp768", "modp1024", "EC2N 2^155", 538 "EC2N 2^185", }, }, 539 { "group type", 4, { NULL, "MODP", "ECP", "EC2N", }, }, 540 { "group prime", 0, }, 541 { "group gen1", 0, }, 542 { "group gen2", 0, }, 543 { "group curve A", 0, }, 544 { "group curve B", 0, }, 545 { "lifetype", 3, { NULL, "sec", "kb", }, }, 546 { "lifeduration", 0, }, 547 { "prf", 0, }, 548 { "keylen", 0, }, 549 { "field", 0, }, 550 { "order", 0, }, 551}; 552 553static u_char * 554isakmp_t_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 555 u_int32_t doi, u_int32_t proto) 556{ 557 struct isakmp_pl_t *p, t; 558 u_char *cp; 559 char *idstr; 560 struct attrmap *map; 561 size_t nmap; 562 u_char *ep2; 563 564 printf("%s:", NPSTR(ISAKMP_NPTYPE_T)); 565 566 p = (struct isakmp_pl_t *)ext; 567 safememcpy(&t, ext, sizeof(t)); 568 569 switch (proto) { 570 case 1: 571 idstr = STR_OR_ID(t.t_id, isakmp_p_map); 572 map = oakley_t_map; 573 nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]); 574 break; 575 case 2: 576 idstr = STR_OR_ID(t.t_id, ah_p_map); 577 map = ipsec_t_map; 578 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); 579 break; 580 case 3: 581 idstr = STR_OR_ID(t.t_id, esp_p_map); 582 map = ipsec_t_map; 583 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); 584 break; 585 case 4: 586 idstr = STR_OR_ID(t.t_id, ipcomp_p_map); 587 map = ipsec_t_map; 588 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]); 589 break; 590 default: 591 idstr = NULL; 592 map = NULL; 593 nmap = 0; 594 break; 595 } 596 597 if (idstr) 598 printf(" #%d id=%s ", t.t_no, idstr); 599 else 600 printf(" #%d id=%d ", t.t_no, t.t_id); 601 cp = (u_char *)(p + 1); 602 ep2 = (u_char *)p + ntohs(t.h.len); 603 while (cp < ep && cp < ep2) { 604 if (map && nmap) { 605 cp = isakmp_attrmap_print(cp, (ep < ep2) ? ep : ep2, 606 map, nmap); 607 } else 608 cp = isakmp_attr_print(cp, (ep < ep2) ? ep : ep2); 609 } 610 if (ep < ep2) 611 printf("..."); 612 return cp; 613} 614 615static u_char * 616isakmp_ke_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 617 u_int32_t doi, u_int32_t proto) 618{ 619 struct isakmp_gen e; 620 621 printf("%s:", NPSTR(ISAKMP_NPTYPE_KE)); 622 623 safememcpy(&e, ext, sizeof(e)); 624 printf(" key len=%d", ntohs(e.len) - 4); 625 if (2 < vflag && 4 < ntohs(e.len)) { 626 printf(" "); 627 rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); 628 } 629 return (u_char *)ext + ntohs(e.len); 630} 631 632static u_char * 633isakmp_id_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 634 u_int32_t doi, u_int32_t proto) 635{ 636#define USE_IPSECDOI_IN_PHASE1 1 637 struct isakmp_pl_id *p, id; 638 static char *idtypestr[] = { 639 "IPv4", "IPv4net", "IPv6", "IPv6net", 640 }; 641 static char *ipsecidtypestr[] = { 642 NULL, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6", 643 "IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN", 644 "keyid", 645 }; 646 int len; 647 u_char *data; 648 649 printf("%s:", NPSTR(ISAKMP_NPTYPE_ID)); 650 651 p = (struct isakmp_pl_id *)ext; 652 safememcpy(&id, ext, sizeof(id)); 653 if (sizeof(*p) < id.h.len) 654 data = (u_char *)(p + 1); 655 else 656 data = NULL; 657 len = ntohs(id.h.len) - sizeof(*p); 658 659#if 0 /*debug*/ 660 printf(" [phase=%d doi=%d proto=%d]", phase, doi, proto); 661#endif 662 switch (phase) { 663#ifndef USE_IPSECDOI_IN_PHASE1 664 case 1: 665#endif 666 default: 667 printf(" idtype=%s", STR_OR_ID(id.d.id_type, idtypestr)); 668 printf(" doi_data=%u", 669 (u_int32_t)(ntohl(id.d.doi_data) & 0xffffff)); 670 break; 671 672#ifdef USE_IPSECDOI_IN_PHASE1 673 case 1: 674#endif 675 case 2: 676 { 677 struct ipsecdoi_id *p, id; 678 struct protoent *pe; 679 680 p = (struct ipsecdoi_id *)ext; 681 safememcpy(&id, ext, sizeof(id)); 682 printf(" idtype=%s", STR_OR_ID(id.type, ipsecidtypestr)); 683 if (id.proto_id) { 684 setprotoent(1); 685 pe = getprotobynumber(id.proto_id); 686 if (pe) 687 printf(" protoid=%s", pe->p_name); 688 endprotoent(); 689 } else { 690 /* it DOES NOT mean IPPROTO_IP! */ 691 printf(" protoid=%s", "0"); 692 } 693 printf(" port=%d", ntohs(id.port)); 694 if (!len) 695 break; 696 switch (id.type) { 697 case IPSECDOI_ID_IPV4_ADDR: 698 printf(" len=%d %s", len, ipaddr_string(data)); 699 len = 0; 700 break; 701 case IPSECDOI_ID_FQDN: 702 case IPSECDOI_ID_USER_FQDN: 703 { 704 int i; 705 printf(" len=%d ", len); 706 for (i = 0; i < len; i++) 707 safeputchar(data[i]); 708 len = 0; 709 break; 710 } 711 case IPSECDOI_ID_IPV4_ADDR_SUBNET: 712 { 713 u_char *mask; 714 mask = data + sizeof(struct in_addr); 715 printf(" len=%d %s/%u.%u.%u.%u", len, 716 ipaddr_string(data), 717 mask[0], mask[1], mask[2], mask[3]); 718 len = 0; 719 break; 720 } 721#ifdef INET6 722 case IPSECDOI_ID_IPV6_ADDR: 723 printf(" len=%d %s", len, ip6addr_string(data)); 724 len = 0; 725 break; 726 case IPSECDOI_ID_IPV6_ADDR_SUBNET: 727 { 728 u_int32_t *mask; 729 mask = (u_int32_t *)(data + sizeof(struct in6_addr)); 730 /*XXX*/ 731 printf(" len=%d %s/0x%08x%08x%08x%08x", len, 732 ip6addr_string(data), 733 mask[0], mask[1], mask[2], mask[3]); 734 len = 0; 735 break; 736 } 737#endif /*INET6*/ 738 case IPSECDOI_ID_IPV4_ADDR_RANGE: 739 printf(" len=%d %s-%s", len, ipaddr_string(data), 740 ipaddr_string(data + sizeof(struct in_addr))); 741 len = 0; 742 break; 743#ifdef INET6 744 case IPSECDOI_ID_IPV6_ADDR_RANGE: 745 printf(" len=%d %s-%s", len, ip6addr_string(data), 746 ip6addr_string(data + sizeof(struct in6_addr))); 747 len = 0; 748 break; 749#endif /*INET6*/ 750 case IPSECDOI_ID_DER_ASN1_DN: 751 case IPSECDOI_ID_DER_ASN1_GN: 752 case IPSECDOI_ID_KEY_ID: 753 break; 754 } 755 break; 756 } 757 } 758 if (data && len) { 759 printf(" len=%d", len); 760 if (2 < vflag) { 761 printf(" "); 762 rawprint((caddr_t)data, len); 763 } 764 } 765 return (u_char *)ext + ntohs(id.h.len); 766} 767 768static u_char * 769isakmp_cert_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 770 u_int32_t doi0, u_int32_t proto0) 771{ 772 struct isakmp_pl_cert *p, cert; 773 static char *certstr[] = { 774 "none", "pkcs7", "pgp", "dns", 775 "x509sign", "x509ke", "kerberos", "crl", 776 "arl", "spki", "x509attr", 777 }; 778 779 printf("%s:", NPSTR(ISAKMP_NPTYPE_CERT)); 780 781 p = (struct isakmp_pl_cert *)ext; 782 safememcpy(&cert, ext, sizeof(cert)); 783 printf(" len=%d", ntohs(cert.h.len) - 4); 784 printf(" type=%s", STR_OR_ID((cert.encode), certstr)); 785 if (2 < vflag && 4 < ntohs(cert.h.len)) { 786 printf(" "); 787 rawprint((caddr_t)(ext + 1), ntohs(cert.h.len) - 4); 788 } 789 return (u_char *)ext + ntohs(cert.h.len); 790} 791 792static u_char * 793isakmp_cr_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 794 u_int32_t doi0, u_int32_t proto0) 795{ 796 struct isakmp_pl_cert *p, cert; 797 static char *certstr[] = { 798 "none", "pkcs7", "pgp", "dns", 799 "x509sign", "x509ke", "kerberos", "crl", 800 "arl", "spki", "x509attr", 801 }; 802 803 printf("%s:", NPSTR(ISAKMP_NPTYPE_CR)); 804 805 p = (struct isakmp_pl_cert *)ext; 806 safememcpy(&cert, ext, sizeof(cert)); 807 printf(" len=%d", ntohs(cert.h.len) - 4); 808 printf(" type=%s", STR_OR_ID((cert.encode), certstr)); 809 if (2 < vflag && 4 < ntohs(cert.h.len)) { 810 printf(" "); 811 rawprint((caddr_t)(ext + 1), ntohs(cert.h.len) - 4); 812 } 813 return (u_char *)ext + ntohs(cert.h.len); 814} 815 816static u_char * 817isakmp_hash_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 818 u_int32_t doi, u_int32_t proto) 819{ 820 struct isakmp_gen e; 821 822 printf("%s:", NPSTR(ISAKMP_NPTYPE_HASH)); 823 824 safememcpy(&e, ext, sizeof(e)); 825 printf(" len=%d", ntohs(e.len) - 4); 826 if (2 < vflag && 4 < ntohs(e.len)) { 827 printf(" "); 828 rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); 829 } 830 return (u_char *)ext + ntohs(e.len); 831} 832 833static u_char * 834isakmp_sig_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 835 u_int32_t doi, u_int32_t proto) 836{ 837 struct isakmp_gen e; 838 839 printf("%s:", NPSTR(ISAKMP_NPTYPE_SIG)); 840 841 safememcpy(&e, ext, sizeof(e)); 842 printf(" len=%d", ntohs(e.len) - 4); 843 if (2 < vflag && 4 < ntohs(e.len)) { 844 printf(" "); 845 rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); 846 } 847 return (u_char *)ext + ntohs(e.len); 848} 849 850static u_char * 851isakmp_nonce_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 852 u_int32_t doi, u_int32_t proto) 853{ 854 struct isakmp_gen e; 855 856 printf("%s:", NPSTR(ISAKMP_NPTYPE_NONCE)); 857 858 safememcpy(&e, ext, sizeof(e)); 859 printf(" n len=%d", ntohs(e.len) - 4); 860 if (2 < vflag && 4 < ntohs(e.len)) { 861 printf(" "); 862 rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); 863 } 864 return (u_char *)ext + ntohs(e.len); 865} 866 867static u_char * 868isakmp_n_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 869 u_int32_t doi0, u_int32_t proto0) 870{ 871 struct isakmp_pl_n *p, n; 872 u_char *cp; 873 u_char *ep2; 874 u_int32_t doi; 875 u_int32_t proto; 876 static char *notifystr[] = { 877 NULL, "INVALID-PAYLOAD-TYPE", 878 "DOI-NOT-SUPPORTED", "SITUATION-NOT-SUPPORTED", 879 "INVALID-COOKIE", "INVALID-MAJOR-VERSION", 880 "INVALID-MINOR-VERSION", "INVALID-EXCHANGE-TYPE", 881 "INVALID-FLAGS", "INVALID-MESSAGE-ID", 882 "INVALID-PROTOCOL-ID", "INVALID-SPI", 883 "INVALID-TRANSFORM-ID", "ATTRIBUTES-NOT-SUPPORTED", 884 "NO-PROPOSAL-CHOSEN", "BAD-PROPOSAL-SYNTAX", 885 "PAYLOAD-MALFORMED", "INVALID-KEY-INFORMATION", 886 "INVALID-ID-INFORMATION", "INVALID-CERT-ENCODING", 887 "INVALID-CERTIFICATE", "CERT-TYPE-UNSUPPORTED", 888 "INVALID-CERT-AUTHORITY", "INVALID-HASH-INFORMATION", 889 "AUTHENTICATION-FAILED", "INVALID-SIGNATURE", 890 "ADDRESS-NOTIFICATION", "NOTIFY-SA-LIFETIME", 891 "CERTIFICATE-UNAVAILABLE", "UNSUPPORTED-EXCHANGE-TYPE", 892 "UNEQUAL-PAYLOAD-LENGTHS", 893 }; 894 static char *ipsecnotifystr[] = { 895 "RESPONDER-LIFETIME", "REPLAY-STATUS", 896 "INITIAL-CONTACT", 897 }; 898/* NOTE: these macro must be called with x in proper range */ 899#define NOTIFYSTR(x) \ 900 (((x) == 16384) ? "CONNECTED" : STR_OR_ID((x), notifystr)) 901#define IPSECNOTIFYSTR(x) \ 902 (((x) == 8192) ? "RESERVED" : STR_OR_ID(((x) - 24576), ipsecnotifystr)) 903 904 printf("%s:", NPSTR(ISAKMP_NPTYPE_N)); 905 906 p = (struct isakmp_pl_n *)ext; 907 safememcpy(&n, ext, sizeof(n)); 908 doi = ntohl(n.doi); 909 proto = n.prot_id; 910 if (doi != 1) { 911 printf(" doi=%d", doi); 912 printf(" proto=%d", proto); 913 printf(" type=%s", NOTIFYSTR(ntohs(n.type))); 914 if (n.spi_size) { 915 printf(" spi="); 916 rawprint((caddr_t)(p + 1), n.spi_size); 917 } 918 return (u_char *)(p + 1) + n.spi_size; 919 } 920 921 printf(" doi=ipsec"); 922 printf(" proto=%s", PROTOIDSTR(proto)); 923 if (ntohs(n.type) < 8192) 924 printf(" type=%s", NOTIFYSTR(ntohs(n.type))); 925 else if (ntohs(n.type) < 16384) 926 printf(" type=%s", IPSECNOTIFYSTR(ntohs(n.type))); 927 else if (ntohs(n.type) < 24576) 928 printf(" type=%s", NOTIFYSTR(ntohs(n.type))); 929 else if (ntohs(n.type) < 40960) 930 printf(" type=%s", IPSECNOTIFYSTR(ntohs(n.type))); 931 else 932 printf(" type=%s", NOTIFYSTR(ntohs(n.type))); 933 if (n.spi_size) { 934 printf(" spi="); 935 rawprint((caddr_t)(p + 1), n.spi_size); 936 } 937 938 cp = (u_char *)(p + 1) + n.spi_size; 939 ep2 = (u_char *)p + ntohs(n.h.len); 940 941 if (cp < ep) { 942 printf(" orig=("); 943 switch (ntohs(n.type)) { 944 case IPSECDOI_NTYPE_RESPONDER_LIFETIME: 945 { 946 struct attrmap *map = oakley_t_map; 947 size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]); 948 while (cp < ep && cp < ep2) { 949 cp = isakmp_attrmap_print(cp, 950 (ep < ep2) ? ep : ep2, map, nmap); 951 } 952 break; 953 } 954 case IPSECDOI_NTYPE_REPLAY_STATUS: 955 printf("replay detection %sabled", 956 (*(u_int32_t *)cp) ? "en" : "dis"); 957 break; 958 case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN: 959 isakmp_sub_print(ISAKMP_NPTYPE_SA, 960 (struct isakmp_gen *)cp, ep, phase, doi, proto); 961 break; 962 default: 963 /* NULL is dummy */ 964 isakmp_print(cp, 965 ntohs(n.h.len) - sizeof(*p) - n.spi_size, 966 NULL); 967 } 968 printf(")"); 969 } 970 return (u_char *)ext + ntohs(n.h.len); 971} 972 973static u_char * 974isakmp_d_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 975 u_int32_t doi0, u_int32_t proto0) 976{ 977 struct isakmp_pl_d *p, d; 978 u_int8_t *q; 979 u_int32_t doi; 980 u_int32_t proto; 981 int i; 982 983 printf("%s:", NPSTR(ISAKMP_NPTYPE_D)); 984 985 p = (struct isakmp_pl_d *)ext; 986 safememcpy(&d, ext, sizeof(d)); 987 doi = ntohl(d.doi); 988 proto = d.prot_id; 989 if (doi != 1) { 990 printf(" doi=%u", doi); 991 printf(" proto=%u", proto); 992 } else { 993 printf(" doi=ipsec"); 994 printf(" proto=%s", PROTOIDSTR(proto)); 995 } 996 printf(" spilen=%u", d.spi_size); 997 printf(" nspi=%u", ntohs(d.num_spi)); 998 printf(" spi="); 999 q = (u_int8_t *)(p + 1); 1000 for (i = 0; i < ntohs(d.num_spi); i++) { 1001 if (i != 0) 1002 printf(","); 1003 rawprint((caddr_t)q, d.spi_size); 1004 q += d.spi_size; 1005 } 1006 return q; 1007} 1008 1009static u_char * 1010isakmp_vid_print(struct isakmp_gen *ext, u_char *ep, u_int32_t phase, 1011 u_int32_t doi, u_int32_t proto) 1012{ 1013 struct isakmp_gen e; 1014 1015 printf("%s:", NPSTR(ISAKMP_NPTYPE_VID)); 1016 1017 safememcpy(&e, ext, sizeof(e)); 1018 printf(" len=%d", ntohs(e.len) - 4); 1019 if (2 < vflag && 4 < ntohs(e.len)) { 1020 printf(" "); 1021 rawprint((caddr_t)(ext + 1), ntohs(e.len) - 4); 1022 } 1023 return (u_char *)ext + ntohs(e.len); 1024} 1025 1026static u_char * 1027isakmp_sub0_print(u_char np, struct isakmp_gen *ext, u_char *ep, 1028 u_int32_t phase, u_int32_t doi, u_int32_t proto) 1029{ 1030 u_char *cp; 1031 struct isakmp_gen e; 1032 u_int item_len; 1033 1034 cp = (u_char *)ext; 1035 safememcpy(&e, ext, sizeof(e)); 1036 1037 if (NPFUNC(np)) 1038 cp = (*NPFUNC(np))(ext, ep, phase, doi, proto); 1039 else { 1040 printf("%s", NPSTR(np)); 1041 item_len = ntohs(e.len); 1042 if (item_len == 0) { 1043 /* 1044 * We don't want to loop forever processing this 1045 * bogus (zero-length) item; return NULL so that 1046 * we stop dissecting. 1047 */ 1048 cp = NULL; 1049 } else 1050 cp += item_len; 1051 } 1052 return cp; 1053} 1054 1055static u_char * 1056isakmp_sub_print(u_char np, struct isakmp_gen *ext, u_char *ep, 1057 u_int32_t phase, u_int32_t doi, u_int32_t proto) 1058{ 1059 u_char *cp; 1060 static int depth = 0; 1061 int i; 1062 struct isakmp_gen e; 1063 1064 cp = (u_char *)ext; 1065 1066 while (np) {
|