blob: 2b352e5ff7f0ac242d2fec0d143a88bc7de4e591 [file] [log] [blame]
The Android Open Source Project2949f582009-03-03 19:30:46 -08001/*
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[] _U_ =
JP Abgrall53f17a92014-02-12 14:02:41 -080033 "@(#) $Header: /tcpdump/master/tcpdump/print-isakmp.c,v 1.61 2008-02-05 19:34:25 guy Exp $ (LBL)";
The Android Open Source Project2949f582009-03-03 19:30:46 -080034#endif
35
JP Abgrall53f17a92014-02-12 14:02:41 -080036#define NETDISSECT_REWORKED
The Android Open Source Project2949f582009-03-03 19:30:46 -080037#ifdef HAVE_CONFIG_H
38#include "config.h"
39#endif
40
JP Abgrall53f17a92014-02-12 14:02:41 -080041/* The functions from print-esp.c used in this file are only defined when both
42 * OpenSSL and evp.h are detected. Employ the same preprocessor device here.
43 */
44#ifndef HAVE_OPENSSL_EVP_H
45#undef HAVE_LIBCRYPTO
46#endif
47
The Android Open Source Project2949f582009-03-03 19:30:46 -080048#include <tcpdump-stdinc.h>
49
50#include <string.h>
51
52#include <stdio.h>
53
54#include "isakmp.h"
55#include "ipsec_doi.h"
56#include "oakley.h"
57#include "interface.h"
58#include "addrtoname.h"
59#include "extract.h" /* must come after interface.h */
60
61#include "ip.h"
62#ifdef INET6
63#include "ip6.h"
64#endif
65
66#ifndef HAVE_SOCKADDR_STORAGE
67#define sockaddr_storage sockaddr
68#endif
69
JP Abgrall53f17a92014-02-12 14:02:41 -080070#define DECLARE_PRINTER(func) static const u_char *ike##func##_print( \
71 netdissect_options *ndo, u_char tpay, \
72 const struct isakmp_gen *ext, \
73 u_int item_len, \
74 const u_char *end_pointer, \
75 u_int32_t phase,\
76 u_int32_t doi0, \
77 u_int32_t proto0, int depth)
78
79DECLARE_PRINTER(v1_sa);
80DECLARE_PRINTER(v1_p);
81DECLARE_PRINTER(v1_t);
82DECLARE_PRINTER(v1_ke);
83DECLARE_PRINTER(v1_id);
84DECLARE_PRINTER(v1_cert);
85DECLARE_PRINTER(v1_cr);
86DECLARE_PRINTER(v1_sig);
87DECLARE_PRINTER(v1_hash);
88DECLARE_PRINTER(v1_nonce);
89DECLARE_PRINTER(v1_n);
90DECLARE_PRINTER(v1_d);
91DECLARE_PRINTER(v1_vid);
92
93DECLARE_PRINTER(v2_sa);
94DECLARE_PRINTER(v2_ke);
95DECLARE_PRINTER(v2_ID);
96DECLARE_PRINTER(v2_cert);
97DECLARE_PRINTER(v2_cr);
98DECLARE_PRINTER(v2_auth);
99DECLARE_PRINTER(v2_nonce);
100DECLARE_PRINTER(v2_n);
101DECLARE_PRINTER(v2_d);
102DECLARE_PRINTER(v2_vid);
103DECLARE_PRINTER(v2_TS);
104DECLARE_PRINTER(v2_cp);
105DECLARE_PRINTER(v2_eap);
106
107static const u_char *ikev2_e_print(netdissect_options *ndo,
108 struct isakmp *base,
109 u_char tpay,
110 const struct isakmp_gen *ext,
111 u_int item_len,
112 const u_char *end_pointer,
113 u_int32_t phase,
114 u_int32_t doi0,
115 u_int32_t proto0, int depth);
116
117
118static const u_char *ike_sub0_print(netdissect_options *ndo,u_char, const struct isakmp_gen *,
The Android Open Source Project2949f582009-03-03 19:30:46 -0800119 const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
JP Abgrall53f17a92014-02-12 14:02:41 -0800120static const u_char *ikev1_sub_print(netdissect_options *ndo,u_char, const struct isakmp_gen *,
The Android Open Source Project2949f582009-03-03 19:30:46 -0800121 const u_char *, u_int32_t, u_int32_t, u_int32_t, int);
JP Abgrall53f17a92014-02-12 14:02:41 -0800122
123static const u_char *ikev2_sub_print(netdissect_options *ndo,
124 struct isakmp *base,
125 u_char np, const struct isakmp_gen *ext,
126 const u_char *ep, u_int32_t phase,
127 u_int32_t doi, u_int32_t proto,
128 int depth);
129
130
The Android Open Source Project2949f582009-03-03 19:30:46 -0800131static char *numstr(int);
JP Abgrall53f17a92014-02-12 14:02:41 -0800132
133static void
134ikev1_print(netdissect_options *ndo,
135 const u_char *bp, u_int length,
136 const u_char *bp2, struct isakmp *base);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800137
138#define MAXINITIATORS 20
139int ninitiator = 0;
140struct {
141 cookie_t initiator;
142 struct sockaddr_storage iaddr;
143 struct sockaddr_storage raddr;
144} cookiecache[MAXINITIATORS];
145
146/* protocol id */
147static const char *protoidstr[] = {
148 NULL, "isakmp", "ipsec-ah", "ipsec-esp", "ipcomp",
149};
150
151/* isakmp->np */
152static const char *npstr[] = {
JP Abgrall53f17a92014-02-12 14:02:41 -0800153 "none", "sa", "p", "t", "ke", "id", "cert", "cr", "hash", /* 0 - 8 */
154 "sig", "nonce", "n", "d", "vid", /* 9 - 13 */
155 "pay14", "pay15", "pay16", "pay17", "pay18", /* 14- 18 */
156 "pay19", "pay20", "pay21", "pay22", "pay23", /* 19- 23 */
157 "pay24", "pay25", "pay26", "pay27", "pay28", /* 24- 28 */
158 "pay29", "pay30", "pay31", "pay32", /* 29- 32 */
159 "v2sa", "v2ke", "v2IDi", "v2IDr", "v2cert",/* 33- 37 */
160 "v2cr", "v2auth","v2nonce", "v2n", "v2d", /* 38- 42 */
161 "v2vid", "v2TSi", "v2TSr", "v2e", "v2cp", /* 43- 47 */
162 "v2eap", /* 48 */
163
The Android Open Source Project2949f582009-03-03 19:30:46 -0800164};
165
166/* isakmp->np */
JP Abgrall53f17a92014-02-12 14:02:41 -0800167static const u_char *(*npfunc[])(netdissect_options *ndo, u_char tpay,
168 const struct isakmp_gen *ext,
169 u_int item_len,
170 const u_char *end_pointer,
171 u_int32_t phase,
172 u_int32_t doi0,
173 u_int32_t proto0, int depth) = {
The Android Open Source Project2949f582009-03-03 19:30:46 -0800174 NULL,
JP Abgrall53f17a92014-02-12 14:02:41 -0800175 ikev1_sa_print,
176 ikev1_p_print,
177 ikev1_t_print,
178 ikev1_ke_print,
179 ikev1_id_print,
180 ikev1_cert_print,
181 ikev1_cr_print,
182 ikev1_hash_print,
183 ikev1_sig_print,
184 ikev1_nonce_print,
185 ikev1_n_print,
186 ikev1_d_print,
187 ikev1_vid_print, /* 13 */
188 NULL, NULL, NULL, NULL, NULL, /* 14- 18 */
189 NULL, NULL, NULL, NULL, NULL, /* 19- 23 */
190 NULL, NULL, NULL, NULL, NULL, /* 24- 28 */
191 NULL, NULL, NULL, NULL, /* 29- 32 */
192 ikev2_sa_print, /* 33 */
193 ikev2_ke_print, /* 34 */
194 ikev2_ID_print, /* 35 */
195 ikev2_ID_print, /* 36 */
196 ikev2_cert_print, /* 37 */
197 ikev2_cr_print, /* 38 */
198 ikev2_auth_print, /* 39 */
199 ikev2_nonce_print, /* 40 */
200 ikev2_n_print, /* 41 */
201 ikev2_d_print, /* 42 */
202 ikev2_vid_print, /* 43 */
203 ikev2_TS_print, /* 44 */
204 ikev2_TS_print, /* 45 */
205 NULL, /* ikev2_e_print,*/ /* 46 - special */
206 ikev2_cp_print, /* 47 */
207 ikev2_eap_print, /* 48 */
The Android Open Source Project2949f582009-03-03 19:30:46 -0800208};
209
210/* isakmp->etype */
211static const char *etypestr[] = {
JP Abgrall53f17a92014-02-12 14:02:41 -0800212/* IKEv1 exchange types */
213 "none", "base", "ident", "auth", "agg", "inf", NULL, NULL, /* 0-7 */
214 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 8-15 */
215 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 16-23 */
216 NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, /* 24-31 */
217 "oakley-quick", "oakley-newgroup", /* 32-33 */
218/* IKEv2 exchange types */
219 "ikev2_init", "ikev2_auth", "child_sa", "inf2" /* 34-37 */
The Android Open Source Project2949f582009-03-03 19:30:46 -0800220};
221
222#define STR_OR_ID(x, tab) \
223 (((x) < sizeof(tab)/sizeof(tab[0]) && tab[(x)]) ? tab[(x)] : numstr(x))
224#define PROTOIDSTR(x) STR_OR_ID(x, protoidstr)
225#define NPSTR(x) STR_OR_ID(x, npstr)
226#define ETYPESTR(x) STR_OR_ID(x, etypestr)
227
JP Abgrall53f17a92014-02-12 14:02:41 -0800228#define CHECKLEN(p, np) \
229 if (ep < (u_char *)(p)) { \
230 ND_PRINT((ndo," [|%s]", NPSTR(np))); \
231 goto done; \
232 }
233
234
The Android Open Source Project2949f582009-03-03 19:30:46 -0800235#define NPFUNC(x) \
236 (((x) < sizeof(npfunc)/sizeof(npfunc[0]) && npfunc[(x)]) \
237 ? npfunc[(x)] : NULL)
238
239static int
240iszero(u_char *p, size_t l)
241{
242 while (l--) {
243 if (*p++)
244 return 0;
245 }
246 return 1;
247}
248
249/* find cookie from initiator cache */
250static int
251cookie_find(cookie_t *in)
252{
253 int i;
254
255 for (i = 0; i < MAXINITIATORS; i++) {
256 if (memcmp(in, &cookiecache[i].initiator, sizeof(*in)) == 0)
257 return i;
258 }
259
260 return -1;
261}
262
263/* record initiator */
264static void
265cookie_record(cookie_t *in, const u_char *bp2)
266{
267 int i;
268 struct ip *ip;
269 struct sockaddr_in *sin;
270#ifdef INET6
271 struct ip6_hdr *ip6;
272 struct sockaddr_in6 *sin6;
273#endif
274
275 i = cookie_find(in);
276 if (0 <= i) {
277 ninitiator = (i + 1) % MAXINITIATORS;
278 return;
279 }
280
281 ip = (struct ip *)bp2;
282 switch (IP_V(ip)) {
283 case 4:
284 memset(&cookiecache[ninitiator].iaddr, 0,
285 sizeof(cookiecache[ninitiator].iaddr));
286 memset(&cookiecache[ninitiator].raddr, 0,
287 sizeof(cookiecache[ninitiator].raddr));
288
289 sin = (struct sockaddr_in *)&cookiecache[ninitiator].iaddr;
290#ifdef HAVE_SOCKADDR_SA_LEN
291 sin->sin_len = sizeof(struct sockaddr_in);
292#endif
293 sin->sin_family = AF_INET;
JP Abgrall53f17a92014-02-12 14:02:41 -0800294 UNALIGNED_MEMCPY(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800295 sin = (struct sockaddr_in *)&cookiecache[ninitiator].raddr;
296#ifdef HAVE_SOCKADDR_SA_LEN
297 sin->sin_len = sizeof(struct sockaddr_in);
298#endif
299 sin->sin_family = AF_INET;
JP Abgrall53f17a92014-02-12 14:02:41 -0800300 UNALIGNED_MEMCPY(&sin->sin_addr, &ip->ip_dst, sizeof(ip->ip_dst));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800301 break;
302#ifdef INET6
303 case 6:
304 memset(&cookiecache[ninitiator].iaddr, 0,
305 sizeof(cookiecache[ninitiator].iaddr));
306 memset(&cookiecache[ninitiator].raddr, 0,
307 sizeof(cookiecache[ninitiator].raddr));
308
309 ip6 = (struct ip6_hdr *)bp2;
310 sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].iaddr;
311#ifdef HAVE_SOCKADDR_SA_LEN
312 sin6->sin6_len = sizeof(struct sockaddr_in6);
313#endif
314 sin6->sin6_family = AF_INET6;
JP Abgrall53f17a92014-02-12 14:02:41 -0800315 UNALIGNED_MEMCPY(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800316 sin6 = (struct sockaddr_in6 *)&cookiecache[ninitiator].raddr;
317#ifdef HAVE_SOCKADDR_SA_LEN
318 sin6->sin6_len = sizeof(struct sockaddr_in6);
319#endif
320 sin6->sin6_family = AF_INET6;
JP Abgrall53f17a92014-02-12 14:02:41 -0800321 UNALIGNED_MEMCPY(&sin6->sin6_addr, &ip6->ip6_dst, sizeof(ip6->ip6_dst));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800322 break;
323#endif
324 default:
325 return;
326 }
JP Abgrall53f17a92014-02-12 14:02:41 -0800327 UNALIGNED_MEMCPY(&cookiecache[ninitiator].initiator, in, sizeof(*in));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800328 ninitiator = (ninitiator + 1) % MAXINITIATORS;
329}
330
331#define cookie_isinitiator(x, y) cookie_sidecheck((x), (y), 1)
332#define cookie_isresponder(x, y) cookie_sidecheck((x), (y), 0)
333static int
334cookie_sidecheck(int i, const u_char *bp2, int initiator)
335{
336 struct sockaddr_storage ss;
337 struct sockaddr *sa;
338 struct ip *ip;
339 struct sockaddr_in *sin;
340#ifdef INET6
341 struct ip6_hdr *ip6;
342 struct sockaddr_in6 *sin6;
343#endif
344 int salen;
345
346 memset(&ss, 0, sizeof(ss));
347 ip = (struct ip *)bp2;
348 switch (IP_V(ip)) {
349 case 4:
350 sin = (struct sockaddr_in *)&ss;
351#ifdef HAVE_SOCKADDR_SA_LEN
352 sin->sin_len = sizeof(struct sockaddr_in);
353#endif
354 sin->sin_family = AF_INET;
JP Abgrall53f17a92014-02-12 14:02:41 -0800355 UNALIGNED_MEMCPY(&sin->sin_addr, &ip->ip_src, sizeof(ip->ip_src));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800356 break;
357#ifdef INET6
358 case 6:
359 ip6 = (struct ip6_hdr *)bp2;
360 sin6 = (struct sockaddr_in6 *)&ss;
361#ifdef HAVE_SOCKADDR_SA_LEN
362 sin6->sin6_len = sizeof(struct sockaddr_in6);
363#endif
364 sin6->sin6_family = AF_INET6;
JP Abgrall53f17a92014-02-12 14:02:41 -0800365 UNALIGNED_MEMCPY(&sin6->sin6_addr, &ip6->ip6_src, sizeof(ip6->ip6_src));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800366 break;
367#endif
368 default:
369 return 0;
370 }
371
372 sa = (struct sockaddr *)&ss;
373 if (initiator) {
374 if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].iaddr)->sa_family)
375 return 0;
376#ifdef HAVE_SOCKADDR_SA_LEN
377 salen = sa->sa_len;
378#else
379#ifdef INET6
380 if (sa->sa_family == AF_INET6)
381 salen = sizeof(struct sockaddr_in6);
382 else
383 salen = sizeof(struct sockaddr);
384#else
385 salen = sizeof(struct sockaddr);
386#endif
387#endif
388 if (memcmp(&ss, &cookiecache[i].iaddr, salen) == 0)
389 return 1;
390 } else {
391 if (sa->sa_family != ((struct sockaddr *)&cookiecache[i].raddr)->sa_family)
392 return 0;
393#ifdef HAVE_SOCKADDR_SA_LEN
394 salen = sa->sa_len;
395#else
396#ifdef INET6
397 if (sa->sa_family == AF_INET6)
398 salen = sizeof(struct sockaddr_in6);
399 else
400 salen = sizeof(struct sockaddr);
401#else
402 salen = sizeof(struct sockaddr);
403#endif
404#endif
405 if (memcmp(&ss, &cookiecache[i].raddr, salen) == 0)
406 return 1;
407 }
408 return 0;
409}
410
JP Abgrall53f17a92014-02-12 14:02:41 -0800411static void
412hexprint(netdissect_options *ndo, caddr_t loc, size_t len)
The Android Open Source Project2949f582009-03-03 19:30:46 -0800413{
JP Abgrall53f17a92014-02-12 14:02:41 -0800414 u_char *p;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800415 size_t i;
416
The Android Open Source Project2949f582009-03-03 19:30:46 -0800417 p = (u_char *)loc;
418 for (i = 0; i < len; i++)
JP Abgrall53f17a92014-02-12 14:02:41 -0800419 ND_PRINT((ndo,"%02x", p[i] & 0xff));
420}
421
422static int
423rawprint(netdissect_options *ndo, caddr_t loc, size_t len)
424{
425 ND_TCHECK2(*loc, len);
426
427 hexprint(ndo, loc, len);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800428 return 1;
429trunc:
430 return 0;
431}
432
JP Abgrall53f17a92014-02-12 14:02:41 -0800433
434/*
435 * returns false if we run out of data buffer
436 */
437static int ike_show_somedata(struct netdissect_options *ndo,
438 const u_char *cp, const u_char *ep)
439{
440 /* there is too much data, just show some of it */
441 const u_char *end = ep - 20;
442 int elen = 20;
443 int len = ep - cp;
444 if(len > 10) {
445 len = 10;
446 }
447
448 /* really shouldn't happen because of above */
449 if(end < cp + len) {
450 end = cp+len;
451 elen = ep - end;
452 }
453
454 ND_PRINT((ndo," data=("));
455 if(!rawprint(ndo, (caddr_t)(cp), len)) goto trunc;
456 ND_PRINT((ndo, "..."));
457 if(elen) {
458 if(!rawprint(ndo, (caddr_t)(end), elen)) goto trunc;
459 }
460 ND_PRINT((ndo,")"));
461 return 1;
462
463trunc:
464 return 0;
465}
466
The Android Open Source Project2949f582009-03-03 19:30:46 -0800467struct attrmap {
468 const char *type;
469 u_int nvalue;
470 const char *value[30]; /*XXX*/
471};
472
473static const u_char *
JP Abgrall53f17a92014-02-12 14:02:41 -0800474ikev1_attrmap_print(netdissect_options *ndo,
475 const u_char *p, const u_char *ep,
476 const struct attrmap *map, size_t nmap)
The Android Open Source Project2949f582009-03-03 19:30:46 -0800477{
The Android Open Source Project2949f582009-03-03 19:30:46 -0800478 int totlen;
479 u_int32_t t, v;
480
The Android Open Source Project2949f582009-03-03 19:30:46 -0800481 if (p[0] & 0x80)
482 totlen = 4;
483 else
JP Abgrall53f17a92014-02-12 14:02:41 -0800484 totlen = 4 + EXTRACT_16BITS(&p[2]);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800485 if (ep < p + totlen) {
JP Abgrall53f17a92014-02-12 14:02:41 -0800486 ND_PRINT((ndo,"[|attr]"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800487 return ep + 1;
488 }
489
JP Abgrall53f17a92014-02-12 14:02:41 -0800490 ND_PRINT((ndo,"("));
491 t = EXTRACT_16BITS(&p[0]) & 0x7fff;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800492 if (map && t < nmap && map[t].type)
JP Abgrall53f17a92014-02-12 14:02:41 -0800493 ND_PRINT((ndo,"type=%s ", map[t].type));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800494 else
JP Abgrall53f17a92014-02-12 14:02:41 -0800495 ND_PRINT((ndo,"type=#%d ", t));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800496 if (p[0] & 0x80) {
JP Abgrall53f17a92014-02-12 14:02:41 -0800497 ND_PRINT((ndo,"value="));
498 v = EXTRACT_16BITS(&p[2]);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800499 if (map && t < nmap && v < map[t].nvalue && map[t].value[v])
JP Abgrall53f17a92014-02-12 14:02:41 -0800500 ND_PRINT((ndo,"%s", map[t].value[v]));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800501 else
JP Abgrall53f17a92014-02-12 14:02:41 -0800502 rawprint(ndo, (caddr_t)&p[2], 2);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800503 } else {
JP Abgrall53f17a92014-02-12 14:02:41 -0800504 ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&p[2])));
505 rawprint(ndo, (caddr_t)&p[4], EXTRACT_16BITS(&p[2]));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800506 }
JP Abgrall53f17a92014-02-12 14:02:41 -0800507 ND_PRINT((ndo,")"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800508 return p + totlen;
509}
510
511static const u_char *
JP Abgrall53f17a92014-02-12 14:02:41 -0800512ikev1_attr_print(netdissect_options *ndo, const u_char *p, const u_char *ep)
The Android Open Source Project2949f582009-03-03 19:30:46 -0800513{
The Android Open Source Project2949f582009-03-03 19:30:46 -0800514 int totlen;
515 u_int32_t t;
516
The Android Open Source Project2949f582009-03-03 19:30:46 -0800517 if (p[0] & 0x80)
518 totlen = 4;
519 else
JP Abgrall53f17a92014-02-12 14:02:41 -0800520 totlen = 4 + EXTRACT_16BITS(&p[2]);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800521 if (ep < p + totlen) {
JP Abgrall53f17a92014-02-12 14:02:41 -0800522 ND_PRINT((ndo,"[|attr]"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800523 return ep + 1;
524 }
525
JP Abgrall53f17a92014-02-12 14:02:41 -0800526 ND_PRINT((ndo,"("));
527 t = EXTRACT_16BITS(&p[0]) & 0x7fff;
528 ND_PRINT((ndo,"type=#%d ", t));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800529 if (p[0] & 0x80) {
JP Abgrall53f17a92014-02-12 14:02:41 -0800530 ND_PRINT((ndo,"value="));
531 t = p[2];
532 rawprint(ndo, (caddr_t)&p[2], 2);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800533 } else {
JP Abgrall53f17a92014-02-12 14:02:41 -0800534 ND_PRINT((ndo,"len=%d value=", EXTRACT_16BITS(&p[2])));
535 rawprint(ndo, (caddr_t)&p[4], EXTRACT_16BITS(&p[2]));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800536 }
JP Abgrall53f17a92014-02-12 14:02:41 -0800537 ND_PRINT((ndo,")"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800538 return p + totlen;
539}
540
541static const u_char *
JP Abgrall53f17a92014-02-12 14:02:41 -0800542ikev1_sa_print(netdissect_options *ndo, u_char tpay _U_,
543 const struct isakmp_gen *ext,
The Android Open Source Project2949f582009-03-03 19:30:46 -0800544 u_int item_len _U_,
545 const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_,
546 u_int32_t proto0, int depth)
547{
JP Abgrall53f17a92014-02-12 14:02:41 -0800548 const struct ikev1_pl_sa *p;
549 struct ikev1_pl_sa sa;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800550 u_int32_t doi, sit, ident;
551 const u_char *cp, *np;
552 int t;
553
JP Abgrall53f17a92014-02-12 14:02:41 -0800554 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SA)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800555
JP Abgrall53f17a92014-02-12 14:02:41 -0800556 p = (struct ikev1_pl_sa *)ext;
557 ND_TCHECK(*p);
558 UNALIGNED_MEMCPY(&sa, ext, sizeof(sa));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800559 doi = ntohl(sa.doi);
560 sit = ntohl(sa.sit);
561 if (doi != 1) {
JP Abgrall53f17a92014-02-12 14:02:41 -0800562 ND_PRINT((ndo," doi=%d", doi));
563 ND_PRINT((ndo," situation=%u", (u_int32_t)ntohl(sa.sit)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800564 return (u_char *)(p + 1);
565 }
566
JP Abgrall53f17a92014-02-12 14:02:41 -0800567 ND_PRINT((ndo," doi=ipsec"));
568 ND_PRINT((ndo," situation="));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800569 t = 0;
570 if (sit & 0x01) {
JP Abgrall53f17a92014-02-12 14:02:41 -0800571 ND_PRINT((ndo,"identity"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800572 t++;
573 }
574 if (sit & 0x02) {
JP Abgrall53f17a92014-02-12 14:02:41 -0800575 ND_PRINT((ndo,"%ssecrecy", t ? "+" : ""));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800576 t++;
577 }
578 if (sit & 0x04)
JP Abgrall53f17a92014-02-12 14:02:41 -0800579 ND_PRINT((ndo,"%sintegrity", t ? "+" : ""));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800580
581 np = (u_char *)ext + sizeof(sa);
582 if (sit != 0x01) {
JP Abgrall53f17a92014-02-12 14:02:41 -0800583 ND_TCHECK2(*(ext + 1), sizeof(ident));
584 UNALIGNED_MEMCPY(&ident, ext + 1, sizeof(ident));
585 ND_PRINT((ndo," ident=%u", (u_int32_t)ntohl(ident)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800586 np += sizeof(ident);
587 }
588
589 ext = (struct isakmp_gen *)np;
JP Abgrall53f17a92014-02-12 14:02:41 -0800590 ND_TCHECK(*ext);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800591
JP Abgrall53f17a92014-02-12 14:02:41 -0800592 cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_P, ext, ep, phase, doi, proto0,
The Android Open Source Project2949f582009-03-03 19:30:46 -0800593 depth);
594
595 return cp;
596trunc:
JP Abgrall53f17a92014-02-12 14:02:41 -0800597 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SA)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800598 return NULL;
599}
600
601static const u_char *
JP Abgrall53f17a92014-02-12 14:02:41 -0800602ikev1_p_print(netdissect_options *ndo, u_char tpay _U_,
603 const struct isakmp_gen *ext, u_int item_len _U_,
The Android Open Source Project2949f582009-03-03 19:30:46 -0800604 const u_char *ep, u_int32_t phase, u_int32_t doi0,
605 u_int32_t proto0 _U_, int depth)
606{
JP Abgrall53f17a92014-02-12 14:02:41 -0800607 const struct ikev1_pl_p *p;
608 struct ikev1_pl_p prop;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800609 const u_char *cp;
610
JP Abgrall53f17a92014-02-12 14:02:41 -0800611 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_P)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800612
JP Abgrall53f17a92014-02-12 14:02:41 -0800613 p = (struct ikev1_pl_p *)ext;
614 ND_TCHECK(*p);
615 UNALIGNED_MEMCPY(&prop, ext, sizeof(prop));
616 ND_PRINT((ndo," #%d protoid=%s transform=%d",
617 prop.p_no, PROTOIDSTR(prop.prot_id), prop.num_t));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800618 if (prop.spi_size) {
JP Abgrall53f17a92014-02-12 14:02:41 -0800619 ND_PRINT((ndo," spi="));
620 if (!rawprint(ndo, (caddr_t)(p + 1), prop.spi_size))
The Android Open Source Project2949f582009-03-03 19:30:46 -0800621 goto trunc;
622 }
623
624 ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size);
JP Abgrall53f17a92014-02-12 14:02:41 -0800625 ND_TCHECK(*ext);
626
627 cp = ikev1_sub_print(ndo, ISAKMP_NPTYPE_T, ext, ep, phase, doi0,
628 prop.prot_id, depth);
629
The Android Open Source Project2949f582009-03-03 19:30:46 -0800630 return cp;
631trunc:
JP Abgrall53f17a92014-02-12 14:02:41 -0800632 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800633 return NULL;
634}
635
JP Abgrall53f17a92014-02-12 14:02:41 -0800636static const char *ikev1_p_map[] = {
The Android Open Source Project2949f582009-03-03 19:30:46 -0800637 NULL, "ike",
638};
639
JP Abgrall53f17a92014-02-12 14:02:41 -0800640static const char *ikev2_t_type_map[]={
641 NULL, "encr", "prf", "integ", "dh", "esn"
642};
643
The Android Open Source Project2949f582009-03-03 19:30:46 -0800644static const char *ah_p_map[] = {
645 NULL, "(reserved)", "md5", "sha", "1des",
646 "sha2-256", "sha2-384", "sha2-512",
647};
648
JP Abgrall53f17a92014-02-12 14:02:41 -0800649static const char *prf_p_map[] = {
650 NULL, "hmac-md5", "hmac-sha", "hmac-tiger",
651 "aes128_xcbc"
652};
653
654static const char *integ_p_map[] = {
655 NULL, "hmac-md5", "hmac-sha", "dec-mac",
656 "kpdk-md5", "aes-xcbc"
657};
658
659static const char *esn_p_map[] = {
660 "no-esn", "esn"
661};
662
663static const char *dh_p_map[] = {
664 NULL, "modp768",
665 "modp1024", /* group 2 */
666 "EC2N 2^155", /* group 3 */
667 "EC2N 2^185", /* group 4 */
668 "modp1536", /* group 5 */
669 "iana-grp06", "iana-grp07", /* reserved */
670 "iana-grp08", "iana-grp09",
671 "iana-grp10", "iana-grp11",
672 "iana-grp12", "iana-grp13",
673 "modp2048", /* group 14 */
674 "modp3072", /* group 15 */
675 "modp4096", /* group 16 */
676 "modp6144", /* group 17 */
677 "modp8192", /* group 18 */
678};
679
The Android Open Source Project2949f582009-03-03 19:30:46 -0800680static const char *esp_p_map[] = {
681 NULL, "1des-iv64", "1des", "3des", "rc5", "idea", "cast",
682 "blowfish", "3idea", "1des-iv32", "rc4", "null", "aes"
683};
684
685static const char *ipcomp_p_map[] = {
686 NULL, "oui", "deflate", "lzs",
687};
688
689const struct attrmap ipsec_t_map[] = {
690 { NULL, 0, { NULL } },
691 { "lifetype", 3, { NULL, "sec", "kb", }, },
692 { "life", 0, { NULL } },
JP Abgrall53f17a92014-02-12 14:02:41 -0800693 { "group desc", 18, { NULL, "modp768",
694 "modp1024", /* group 2 */
695 "EC2N 2^155", /* group 3 */
696 "EC2N 2^185", /* group 4 */
697 "modp1536", /* group 5 */
698 "iana-grp06", "iana-grp07", /* reserved */
699 "iana-grp08", "iana-grp09",
700 "iana-grp10", "iana-grp11",
701 "iana-grp12", "iana-grp13",
702 "modp2048", /* group 14 */
703 "modp3072", /* group 15 */
704 "modp4096", /* group 16 */
705 "modp6144", /* group 17 */
706 "modp8192", /* group 18 */
707 }, },
The Android Open Source Project2949f582009-03-03 19:30:46 -0800708 { "enc mode", 3, { NULL, "tunnel", "transport", }, },
709 { "auth", 5, { NULL, "hmac-md5", "hmac-sha1", "1des-mac", "keyed", }, },
710 { "keylen", 0, { NULL } },
711 { "rounds", 0, { NULL } },
712 { "dictsize", 0, { NULL } },
713 { "privalg", 0, { NULL } },
714};
715
JP Abgrall53f17a92014-02-12 14:02:41 -0800716const struct attrmap encr_t_map[] = {
717 { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 0, 1 */
718 { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 2, 3 */
719 { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 4, 5 */
720 { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 6, 7 */
721 { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 8, 9 */
722 { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 10,11*/
723 { NULL, 0, { NULL } }, { NULL, 0, { NULL } }, /* 12,13*/
724 { "keylen", 14, { NULL }},
725};
726
The Android Open Source Project2949f582009-03-03 19:30:46 -0800727const struct attrmap oakley_t_map[] = {
728 { NULL, 0, { NULL } },
729 { "enc", 8, { NULL, "1des", "idea", "blowfish", "rc5",
730 "3des", "cast", "aes", }, },
731 { "hash", 7, { NULL, "md5", "sha1", "tiger",
732 "sha2-256", "sha2-384", "sha2-512", }, },
733 { "auth", 6, { NULL, "preshared", "dss", "rsa sig", "rsa enc",
734 "rsa enc revised", }, },
JP Abgrall53f17a92014-02-12 14:02:41 -0800735 { "group desc", 18, { NULL, "modp768",
736 "modp1024", /* group 2 */
737 "EC2N 2^155", /* group 3 */
738 "EC2N 2^185", /* group 4 */
739 "modp1536", /* group 5 */
740 "iana-grp06", "iana-grp07", /* reserved */
741 "iana-grp08", "iana-grp09",
742 "iana-grp10", "iana-grp11",
743 "iana-grp12", "iana-grp13",
744 "modp2048", /* group 14 */
745 "modp3072", /* group 15 */
746 "modp4096", /* group 16 */
747 "modp6144", /* group 17 */
748 "modp8192", /* group 18 */
749 }, },
The Android Open Source Project2949f582009-03-03 19:30:46 -0800750 { "group type", 4, { NULL, "MODP", "ECP", "EC2N", }, },
751 { "group prime", 0, { NULL } },
752 { "group gen1", 0, { NULL } },
753 { "group gen2", 0, { NULL } },
754 { "group curve A", 0, { NULL } },
755 { "group curve B", 0, { NULL } },
756 { "lifetype", 3, { NULL, "sec", "kb", }, },
757 { "lifeduration", 0, { NULL } },
758 { "prf", 0, { NULL } },
759 { "keylen", 0, { NULL } },
760 { "field", 0, { NULL } },
761 { "order", 0, { NULL } },
762};
763
764static const u_char *
JP Abgrall53f17a92014-02-12 14:02:41 -0800765ikev1_t_print(netdissect_options *ndo, u_char tpay _U_,
766 const struct isakmp_gen *ext, u_int item_len,
767 const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_,
768 u_int32_t proto, int depth _U_)
The Android Open Source Project2949f582009-03-03 19:30:46 -0800769{
JP Abgrall53f17a92014-02-12 14:02:41 -0800770 const struct ikev1_pl_t *p;
771 struct ikev1_pl_t t;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800772 const u_char *cp;
773 const char *idstr;
774 const struct attrmap *map;
775 size_t nmap;
776 const u_char *ep2;
777
JP Abgrall53f17a92014-02-12 14:02:41 -0800778 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_T)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800779
JP Abgrall53f17a92014-02-12 14:02:41 -0800780 p = (struct ikev1_pl_t *)ext;
781 ND_TCHECK(*p);
782 UNALIGNED_MEMCPY(&t, ext, sizeof(t));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800783
784 switch (proto) {
785 case 1:
JP Abgrall53f17a92014-02-12 14:02:41 -0800786 idstr = STR_OR_ID(t.t_id, ikev1_p_map);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800787 map = oakley_t_map;
788 nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
789 break;
790 case 2:
791 idstr = STR_OR_ID(t.t_id, ah_p_map);
792 map = ipsec_t_map;
793 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
794 break;
795 case 3:
796 idstr = STR_OR_ID(t.t_id, esp_p_map);
797 map = ipsec_t_map;
798 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
799 break;
800 case 4:
801 idstr = STR_OR_ID(t.t_id, ipcomp_p_map);
802 map = ipsec_t_map;
803 nmap = sizeof(ipsec_t_map)/sizeof(ipsec_t_map[0]);
804 break;
805 default:
806 idstr = NULL;
807 map = NULL;
808 nmap = 0;
809 break;
810 }
811
812 if (idstr)
JP Abgrall53f17a92014-02-12 14:02:41 -0800813 ND_PRINT((ndo," #%d id=%s ", t.t_no, idstr));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800814 else
JP Abgrall53f17a92014-02-12 14:02:41 -0800815 ND_PRINT((ndo," #%d id=%d ", t.t_no, t.t_id));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800816 cp = (u_char *)(p + 1);
817 ep2 = (u_char *)p + item_len;
818 while (cp < ep && cp < ep2) {
819 if (map && nmap) {
JP Abgrall53f17a92014-02-12 14:02:41 -0800820 cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2,
The Android Open Source Project2949f582009-03-03 19:30:46 -0800821 map, nmap);
822 } else
JP Abgrall53f17a92014-02-12 14:02:41 -0800823 cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800824 }
825 if (ep < ep2)
JP Abgrall53f17a92014-02-12 14:02:41 -0800826 ND_PRINT((ndo,"..."));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800827 return cp;
828trunc:
JP Abgrall53f17a92014-02-12 14:02:41 -0800829 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_T)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800830 return NULL;
831}
832
833static const u_char *
JP Abgrall53f17a92014-02-12 14:02:41 -0800834ikev1_ke_print(netdissect_options *ndo, u_char tpay _U_,
835 const struct isakmp_gen *ext, u_int item_len _U_,
836 const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_,
837 u_int32_t proto _U_, int depth _U_)
The Android Open Source Project2949f582009-03-03 19:30:46 -0800838{
839 struct isakmp_gen e;
840
JP Abgrall53f17a92014-02-12 14:02:41 -0800841 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_KE)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800842
JP Abgrall53f17a92014-02-12 14:02:41 -0800843 ND_TCHECK(*ext);
844 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
845 ND_PRINT((ndo," key len=%d", ntohs(e.len) - 4));
846 if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
847 ND_PRINT((ndo," "));
848 if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
The Android Open Source Project2949f582009-03-03 19:30:46 -0800849 goto trunc;
850 }
851 return (u_char *)ext + ntohs(e.len);
852trunc:
JP Abgrall53f17a92014-02-12 14:02:41 -0800853 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_KE)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800854 return NULL;
855}
856
857static const u_char *
JP Abgrall53f17a92014-02-12 14:02:41 -0800858ikev1_id_print(netdissect_options *ndo, u_char tpay _U_,
859 const struct isakmp_gen *ext, u_int item_len _U_,
860 const u_char *ep _U_, u_int32_t phase, u_int32_t doi _U_,
861 u_int32_t proto _U_, int depth _U_)
The Android Open Source Project2949f582009-03-03 19:30:46 -0800862{
863#define USE_IPSECDOI_IN_PHASE1 1
JP Abgrall53f17a92014-02-12 14:02:41 -0800864 const struct ikev1_pl_id *p;
865 struct ikev1_pl_id id;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800866 static const char *idtypestr[] = {
867 "IPv4", "IPv4net", "IPv6", "IPv6net",
868 };
869 static const char *ipsecidtypestr[] = {
870 NULL, "IPv4", "FQDN", "user FQDN", "IPv4net", "IPv6",
871 "IPv6net", "IPv4range", "IPv6range", "ASN1 DN", "ASN1 GN",
872 "keyid",
873 };
874 int len;
875 const u_char *data;
876
JP Abgrall53f17a92014-02-12 14:02:41 -0800877 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_ID)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800878
JP Abgrall53f17a92014-02-12 14:02:41 -0800879 p = (struct ikev1_pl_id *)ext;
880 ND_TCHECK(*p);
881 UNALIGNED_MEMCPY(&id, ext, sizeof(id));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800882 if (sizeof(*p) < item_len) {
883 data = (u_char *)(p + 1);
884 len = item_len - sizeof(*p);
885 } else {
886 data = NULL;
887 len = 0;
888 }
889
890#if 0 /*debug*/
JP Abgrall53f17a92014-02-12 14:02:41 -0800891 ND_PRINT((ndo," [phase=%d doi=%d proto=%d]", phase, doi, proto));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800892#endif
893 switch (phase) {
894#ifndef USE_IPSECDOI_IN_PHASE1
895 case 1:
896#endif
897 default:
JP Abgrall53f17a92014-02-12 14:02:41 -0800898 ND_PRINT((ndo," idtype=%s", STR_OR_ID(id.d.id_type, idtypestr)));
899 ND_PRINT((ndo," doi_data=%u",
900 (u_int32_t)(ntohl(id.d.doi_data) & 0xffffff)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800901 break;
902
903#ifdef USE_IPSECDOI_IN_PHASE1
904 case 1:
905#endif
906 case 2:
907 {
908 const struct ipsecdoi_id *p;
909 struct ipsecdoi_id id;
910 struct protoent *pe;
911
912 p = (struct ipsecdoi_id *)ext;
JP Abgrall53f17a92014-02-12 14:02:41 -0800913 ND_TCHECK(*p);
914 UNALIGNED_MEMCPY(&id, ext, sizeof(id));
915 ND_PRINT((ndo," idtype=%s", STR_OR_ID(id.type, ipsecidtypestr)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800916 if (id.proto_id) {
917#ifndef WIN32
JP Abgrall53f17a92014-02-12 14:02:41 -0800918 setprotoent(1);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800919#endif /* WIN32 */
920 pe = getprotobynumber(id.proto_id);
921 if (pe)
JP Abgrall53f17a92014-02-12 14:02:41 -0800922 ND_PRINT((ndo," protoid=%s", pe->p_name));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800923#ifndef WIN32
JP Abgrall53f17a92014-02-12 14:02:41 -0800924 endprotoent();
The Android Open Source Project2949f582009-03-03 19:30:46 -0800925#endif /* WIN32 */
926 } else {
927 /* it DOES NOT mean IPPROTO_IP! */
JP Abgrall53f17a92014-02-12 14:02:41 -0800928 ND_PRINT((ndo," protoid=%s", "0"));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800929 }
JP Abgrall53f17a92014-02-12 14:02:41 -0800930 ND_PRINT((ndo," port=%d", ntohs(id.port)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800931 if (!len)
932 break;
933 if (data == NULL)
934 goto trunc;
JP Abgrall53f17a92014-02-12 14:02:41 -0800935 ND_TCHECK2(*data, len);
The Android Open Source Project2949f582009-03-03 19:30:46 -0800936 switch (id.type) {
937 case IPSECDOI_ID_IPV4_ADDR:
938 if (len < 4)
JP Abgrall53f17a92014-02-12 14:02:41 -0800939 ND_PRINT((ndo," len=%d [bad: < 4]", len));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800940 else
JP Abgrall53f17a92014-02-12 14:02:41 -0800941 ND_PRINT((ndo," len=%d %s", len, ipaddr_string(data)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800942 len = 0;
943 break;
944 case IPSECDOI_ID_FQDN:
945 case IPSECDOI_ID_USER_FQDN:
946 {
947 int i;
JP Abgrall53f17a92014-02-12 14:02:41 -0800948 ND_PRINT((ndo," len=%d ", len));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800949 for (i = 0; i < len; i++)
950 safeputchar(data[i]);
951 len = 0;
952 break;
953 }
954 case IPSECDOI_ID_IPV4_ADDR_SUBNET:
955 {
956 const u_char *mask;
957 if (len < 8)
JP Abgrall53f17a92014-02-12 14:02:41 -0800958 ND_PRINT((ndo," len=%d [bad: < 8]", len));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800959 else {
960 mask = data + sizeof(struct in_addr);
JP Abgrall53f17a92014-02-12 14:02:41 -0800961 ND_PRINT((ndo," len=%d %s/%u.%u.%u.%u", len,
962 ipaddr_string(data),
963 mask[0], mask[1], mask[2], mask[3]));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800964 }
965 len = 0;
966 break;
967 }
968#ifdef INET6
969 case IPSECDOI_ID_IPV6_ADDR:
970 if (len < 16)
JP Abgrall53f17a92014-02-12 14:02:41 -0800971 ND_PRINT((ndo," len=%d [bad: < 16]", len));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800972 else
JP Abgrall53f17a92014-02-12 14:02:41 -0800973 ND_PRINT((ndo," len=%d %s", len, ip6addr_string(data)));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800974 len = 0;
975 break;
976 case IPSECDOI_ID_IPV6_ADDR_SUBNET:
977 {
JP Abgrall53f17a92014-02-12 14:02:41 -0800978 const u_char *mask;
The Android Open Source Project2949f582009-03-03 19:30:46 -0800979 if (len < 20)
JP Abgrall53f17a92014-02-12 14:02:41 -0800980 ND_PRINT((ndo," len=%d [bad: < 20]", len));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800981 else {
JP Abgrall53f17a92014-02-12 14:02:41 -0800982 mask = (u_char *)(data + sizeof(struct in6_addr));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800983 /*XXX*/
JP Abgrall53f17a92014-02-12 14:02:41 -0800984 ND_PRINT((ndo," len=%d %s/0x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", len,
985 ip6addr_string(data),
986 mask[0], mask[1], mask[2], mask[3],
987 mask[4], mask[5], mask[6], mask[7],
988 mask[8], mask[9], mask[10], mask[11],
989 mask[12], mask[13], mask[14], mask[15]));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800990 }
991 len = 0;
992 break;
993 }
994#endif /*INET6*/
995 case IPSECDOI_ID_IPV4_ADDR_RANGE:
996 if (len < 8)
JP Abgrall53f17a92014-02-12 14:02:41 -0800997 ND_PRINT((ndo," len=%d [bad: < 8]", len));
The Android Open Source Project2949f582009-03-03 19:30:46 -0800998 else {
JP Abgrall53f17a92014-02-12 14:02:41 -0800999 ND_PRINT((ndo," len=%d %s-%s", len,
1000 ipaddr_string(data),
1001 ipaddr_string(data + sizeof(struct in_addr))));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001002 }
1003 len = 0;
1004 break;
1005#ifdef INET6
1006 case IPSECDOI_ID_IPV6_ADDR_RANGE:
1007 if (len < 32)
JP Abgrall53f17a92014-02-12 14:02:41 -08001008 ND_PRINT((ndo," len=%d [bad: < 32]", len));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001009 else {
JP Abgrall53f17a92014-02-12 14:02:41 -08001010 ND_PRINT((ndo," len=%d %s-%s", len,
1011 ip6addr_string(data),
1012 ip6addr_string(data + sizeof(struct in6_addr))));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001013 }
1014 len = 0;
1015 break;
1016#endif /*INET6*/
1017 case IPSECDOI_ID_DER_ASN1_DN:
1018 case IPSECDOI_ID_DER_ASN1_GN:
1019 case IPSECDOI_ID_KEY_ID:
1020 break;
1021 }
1022 break;
1023 }
1024 }
1025 if (data && len) {
JP Abgrall53f17a92014-02-12 14:02:41 -08001026 ND_PRINT((ndo," len=%d", len));
1027 if (2 < ndo->ndo_vflag) {
1028 ND_PRINT((ndo," "));
1029 if (!rawprint(ndo, (caddr_t)data, len))
The Android Open Source Project2949f582009-03-03 19:30:46 -08001030 goto trunc;
1031 }
1032 }
1033 return (u_char *)ext + item_len;
1034trunc:
JP Abgrall53f17a92014-02-12 14:02:41 -08001035 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_ID)));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001036 return NULL;
1037}
1038
1039static const u_char *
JP Abgrall53f17a92014-02-12 14:02:41 -08001040ikev1_cert_print(netdissect_options *ndo, u_char tpay _U_,
1041 const struct isakmp_gen *ext, u_int item_len _U_,
1042 const u_char *ep _U_, u_int32_t phase _U_,
1043 u_int32_t doi0 _U_,
1044 u_int32_t proto0 _U_, int depth _U_)
The Android Open Source Project2949f582009-03-03 19:30:46 -08001045{
JP Abgrall53f17a92014-02-12 14:02:41 -08001046 const struct ikev1_pl_cert *p;
1047 struct ikev1_pl_cert cert;
The Android Open Source Project2949f582009-03-03 19:30:46 -08001048 static const char *certstr[] = {
1049 "none", "pkcs7", "pgp", "dns",
1050 "x509sign", "x509ke", "kerberos", "crl",
1051 "arl", "spki", "x509attr",
1052 };
1053
JP Abgrall53f17a92014-02-12 14:02:41 -08001054 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CERT)));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001055
JP Abgrall53f17a92014-02-12 14:02:41 -08001056 p = (struct ikev1_pl_cert *)ext;
1057 ND_TCHECK(*p);
1058 UNALIGNED_MEMCPY(&cert, ext, sizeof(cert));
1059 ND_PRINT((ndo," len=%d", item_len - 4));
1060 ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
1061 if (2 < ndo->ndo_vflag && 4 < item_len) {
1062 ND_PRINT((ndo," "));
1063 if (!rawprint(ndo, (caddr_t)(ext + 1), item_len - 4))
The Android Open Source Project2949f582009-03-03 19:30:46 -08001064 goto trunc;
1065 }
1066 return (u_char *)ext + item_len;
1067trunc:
JP Abgrall53f17a92014-02-12 14:02:41 -08001068 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CERT)));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001069 return NULL;
1070}
1071
1072static const u_char *
JP Abgrall53f17a92014-02-12 14:02:41 -08001073ikev1_cr_print(netdissect_options *ndo, u_char tpay _U_,
1074 const struct isakmp_gen *ext, u_int item_len _U_,
1075 const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi0 _U_,
1076 u_int32_t proto0 _U_, int depth _U_)
The Android Open Source Project2949f582009-03-03 19:30:46 -08001077{
JP Abgrall53f17a92014-02-12 14:02:41 -08001078 const struct ikev1_pl_cert *p;
1079 struct ikev1_pl_cert cert;
The Android Open Source Project2949f582009-03-03 19:30:46 -08001080 static const char *certstr[] = {
1081 "none", "pkcs7", "pgp", "dns",
1082 "x509sign", "x509ke", "kerberos", "crl",
1083 "arl", "spki", "x509attr",
1084 };
1085
JP Abgrall53f17a92014-02-12 14:02:41 -08001086 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_CR)));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001087
JP Abgrall53f17a92014-02-12 14:02:41 -08001088 p = (struct ikev1_pl_cert *)ext;
1089 ND_TCHECK(*p);
1090 UNALIGNED_MEMCPY(&cert, ext, sizeof(cert));
1091 ND_PRINT((ndo," len=%d", item_len - 4));
1092 ND_PRINT((ndo," type=%s", STR_OR_ID((cert.encode), certstr)));
1093 if (2 < ndo->ndo_vflag && 4 < item_len) {
1094 ND_PRINT((ndo," "));
1095 if (!rawprint(ndo, (caddr_t)(ext + 1), item_len - 4))
The Android Open Source Project2949f582009-03-03 19:30:46 -08001096 goto trunc;
1097 }
1098 return (u_char *)ext + item_len;
1099trunc:
JP Abgrall53f17a92014-02-12 14:02:41 -08001100 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_CR)));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001101 return NULL;
1102}
1103
1104static const u_char *
JP Abgrall53f17a92014-02-12 14:02:41 -08001105ikev1_hash_print(netdissect_options *ndo, u_char tpay _U_,
1106 const struct isakmp_gen *ext, u_int item_len _U_,
The Android Open Source Project2949f582009-03-03 19:30:46 -08001107 const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_,
1108 u_int32_t proto _U_, int depth _U_)
1109{
1110 struct isakmp_gen e;
1111
JP Abgrall53f17a92014-02-12 14:02:41 -08001112 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_HASH)));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001113
JP Abgrall53f17a92014-02-12 14:02:41 -08001114 ND_TCHECK(*ext);
1115 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
1116 ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
1117 if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1118 ND_PRINT((ndo," "));
1119 if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
The Android Open Source Project2949f582009-03-03 19:30:46 -08001120 goto trunc;
1121 }
1122 return (u_char *)ext + ntohs(e.len);
1123trunc:
JP Abgrall53f17a92014-02-12 14:02:41 -08001124 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_HASH)));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001125 return NULL;
1126}
1127
1128static const u_char *
JP Abgrall53f17a92014-02-12 14:02:41 -08001129ikev1_sig_print(netdissect_options *ndo, u_char tpay _U_,
1130 const struct isakmp_gen *ext, u_int item_len _U_,
1131 const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi _U_,
1132 u_int32_t proto _U_, int depth _U_)
The Android Open Source Project2949f582009-03-03 19:30:46 -08001133{
1134 struct isakmp_gen e;
1135
JP Abgrall53f17a92014-02-12 14:02:41 -08001136 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_SIG)));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001137
JP Abgrall53f17a92014-02-12 14:02:41 -08001138 ND_TCHECK(*ext);
1139 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
1140 ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
1141 if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1142 ND_PRINT((ndo," "));
1143 if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
The Android Open Source Project2949f582009-03-03 19:30:46 -08001144 goto trunc;
1145 }
1146 return (u_char *)ext + ntohs(e.len);
1147trunc:
JP Abgrall53f17a92014-02-12 14:02:41 -08001148 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_SIG)));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001149 return NULL;
1150}
1151
1152static const u_char *
JP Abgrall53f17a92014-02-12 14:02:41 -08001153ikev1_nonce_print(netdissect_options *ndo, u_char tpay _U_,
1154 const struct isakmp_gen *ext,
1155 u_int item_len _U_,
1156 const u_char *ep _U_,
1157 u_int32_t phase _U_, u_int32_t doi _U_,
1158 u_int32_t proto _U_, int depth _U_)
The Android Open Source Project2949f582009-03-03 19:30:46 -08001159{
JP Abgrall53f17a92014-02-12 14:02:41 -08001160 struct isakmp_gen e;
1161
1162 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_NONCE)));
1163
1164 ND_TCHECK(*ext);
1165 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
1166 ND_PRINT((ndo," n len=%d", ntohs(e.len) - 4));
1167 if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1168 ND_PRINT((ndo," "));
1169 if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
1170 goto trunc;
1171 } else if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1172 ND_PRINT((ndo," "));
1173 if (!ike_show_somedata(ndo, (u_char *)(caddr_t)(ext + 1), ep))
1174 goto trunc;
1175 }
1176 return (u_char *)ext + ntohs(e.len);
1177trunc:
1178 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_NONCE)));
1179 return NULL;
1180}
1181
1182static const u_char *
1183ikev1_n_print(netdissect_options *ndo, u_char tpay _U_,
1184 const struct isakmp_gen *ext, u_int item_len,
1185 const u_char *ep, u_int32_t phase, u_int32_t doi0 _U_,
1186 u_int32_t proto0 _U_, int depth)
1187{
1188 struct ikev1_pl_n *p, n;
The Android Open Source Project2949f582009-03-03 19:30:46 -08001189 const u_char *cp;
1190 u_char *ep2;
1191 u_int32_t doi;
1192 u_int32_t proto;
1193 static const char *notify_error_str[] = {
1194 NULL, "INVALID-PAYLOAD-TYPE",
1195 "DOI-NOT-SUPPORTED", "SITUATION-NOT-SUPPORTED",
1196 "INVALID-COOKIE", "INVALID-MAJOR-VERSION",
1197 "INVALID-MINOR-VERSION", "INVALID-EXCHANGE-TYPE",
1198 "INVALID-FLAGS", "INVALID-MESSAGE-ID",
1199 "INVALID-PROTOCOL-ID", "INVALID-SPI",
1200 "INVALID-TRANSFORM-ID", "ATTRIBUTES-NOT-SUPPORTED",
1201 "NO-PROPOSAL-CHOSEN", "BAD-PROPOSAL-SYNTAX",
1202 "PAYLOAD-MALFORMED", "INVALID-KEY-INFORMATION",
1203 "INVALID-ID-INFORMATION", "INVALID-CERT-ENCODING",
1204 "INVALID-CERTIFICATE", "CERT-TYPE-UNSUPPORTED",
1205 "INVALID-CERT-AUTHORITY", "INVALID-HASH-INFORMATION",
1206 "AUTHENTICATION-FAILED", "INVALID-SIGNATURE",
1207 "ADDRESS-NOTIFICATION", "NOTIFY-SA-LIFETIME",
1208 "CERTIFICATE-UNAVAILABLE", "UNSUPPORTED-EXCHANGE-TYPE",
1209 "UNEQUAL-PAYLOAD-LENGTHS",
1210 };
1211 static const char *ipsec_notify_error_str[] = {
1212 "RESERVED",
1213 };
1214 static const char *notify_status_str[] = {
1215 "CONNECTED",
1216 };
1217 static const char *ipsec_notify_status_str[] = {
1218 "RESPONDER-LIFETIME", "REPLAY-STATUS",
1219 "INITIAL-CONTACT",
1220 };
1221/* NOTE: these macro must be called with x in proper range */
1222
1223/* 0 - 8191 */
1224#define NOTIFY_ERROR_STR(x) \
1225 STR_OR_ID((x), notify_error_str)
1226
1227/* 8192 - 16383 */
1228#define IPSEC_NOTIFY_ERROR_STR(x) \
1229 STR_OR_ID((u_int)((x) - 8192), ipsec_notify_error_str)
1230
1231/* 16384 - 24575 */
1232#define NOTIFY_STATUS_STR(x) \
1233 STR_OR_ID((u_int)((x) - 16384), notify_status_str)
1234
1235/* 24576 - 32767 */
1236#define IPSEC_NOTIFY_STATUS_STR(x) \
1237 STR_OR_ID((u_int)((x) - 24576), ipsec_notify_status_str)
1238
JP Abgrall53f17a92014-02-12 14:02:41 -08001239 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_N)));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001240
JP Abgrall53f17a92014-02-12 14:02:41 -08001241 p = (struct ikev1_pl_n *)ext;
1242 ND_TCHECK(*p);
1243 UNALIGNED_MEMCPY(&n, ext, sizeof(n));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001244 doi = ntohl(n.doi);
1245 proto = n.prot_id;
1246 if (doi != 1) {
JP Abgrall53f17a92014-02-12 14:02:41 -08001247 ND_PRINT((ndo," doi=%d", doi));
1248 ND_PRINT((ndo," proto=%d", proto));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001249 if (ntohs(n.type) < 8192)
JP Abgrall53f17a92014-02-12 14:02:41 -08001250 ND_PRINT((ndo," type=%s", NOTIFY_ERROR_STR(ntohs(n.type))));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001251 else if (ntohs(n.type) < 16384)
JP Abgrall53f17a92014-02-12 14:02:41 -08001252 ND_PRINT((ndo," type=%s", numstr(ntohs(n.type))));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001253 else if (ntohs(n.type) < 24576)
JP Abgrall53f17a92014-02-12 14:02:41 -08001254 ND_PRINT((ndo," type=%s", NOTIFY_STATUS_STR(ntohs(n.type))));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001255 else
JP Abgrall53f17a92014-02-12 14:02:41 -08001256 ND_PRINT((ndo," type=%s", numstr(ntohs(n.type))));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001257 if (n.spi_size) {
JP Abgrall53f17a92014-02-12 14:02:41 -08001258 ND_PRINT((ndo," spi="));
1259 if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size))
The Android Open Source Project2949f582009-03-03 19:30:46 -08001260 goto trunc;
1261 }
1262 return (u_char *)(p + 1) + n.spi_size;
1263 }
1264
JP Abgrall53f17a92014-02-12 14:02:41 -08001265 ND_PRINT((ndo," doi=ipsec"));
1266 ND_PRINT((ndo," proto=%s", PROTOIDSTR(proto)));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001267 if (ntohs(n.type) < 8192)
JP Abgrall53f17a92014-02-12 14:02:41 -08001268 ND_PRINT((ndo," type=%s", NOTIFY_ERROR_STR(ntohs(n.type))));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001269 else if (ntohs(n.type) < 16384)
JP Abgrall53f17a92014-02-12 14:02:41 -08001270 ND_PRINT((ndo," type=%s", IPSEC_NOTIFY_ERROR_STR(ntohs(n.type))));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001271 else if (ntohs(n.type) < 24576)
JP Abgrall53f17a92014-02-12 14:02:41 -08001272 ND_PRINT((ndo," type=%s", NOTIFY_STATUS_STR(ntohs(n.type))));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001273 else if (ntohs(n.type) < 32768)
JP Abgrall53f17a92014-02-12 14:02:41 -08001274 ND_PRINT((ndo," type=%s", IPSEC_NOTIFY_STATUS_STR(ntohs(n.type))));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001275 else
JP Abgrall53f17a92014-02-12 14:02:41 -08001276 ND_PRINT((ndo," type=%s", numstr(ntohs(n.type))));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001277 if (n.spi_size) {
JP Abgrall53f17a92014-02-12 14:02:41 -08001278 ND_PRINT((ndo," spi="));
1279 if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size))
The Android Open Source Project2949f582009-03-03 19:30:46 -08001280 goto trunc;
1281 }
1282
1283 cp = (u_char *)(p + 1) + n.spi_size;
1284 ep2 = (u_char *)p + item_len;
1285
1286 if (cp < ep) {
JP Abgrall53f17a92014-02-12 14:02:41 -08001287 ND_PRINT((ndo," orig=("));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001288 switch (ntohs(n.type)) {
1289 case IPSECDOI_NTYPE_RESPONDER_LIFETIME:
1290 {
1291 const struct attrmap *map = oakley_t_map;
1292 size_t nmap = sizeof(oakley_t_map)/sizeof(oakley_t_map[0]);
1293 while (cp < ep && cp < ep2) {
JP Abgrall53f17a92014-02-12 14:02:41 -08001294 cp = ikev1_attrmap_print(ndo, cp,
The Android Open Source Project2949f582009-03-03 19:30:46 -08001295 (ep < ep2) ? ep : ep2, map, nmap);
1296 }
1297 break;
1298 }
1299 case IPSECDOI_NTYPE_REPLAY_STATUS:
JP Abgrall53f17a92014-02-12 14:02:41 -08001300 ND_PRINT((ndo,"replay detection %sabled",
1301 EXTRACT_32BITS(cp) ? "en" : "dis"));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001302 break;
1303 case ISAKMP_NTYPE_NO_PROPOSAL_CHOSEN:
JP Abgrall53f17a92014-02-12 14:02:41 -08001304 if (ikev1_sub_print(ndo, ISAKMP_NPTYPE_SA,
1305 (struct isakmp_gen *)cp, ep, phase, doi, proto,
1306 depth) == NULL)
The Android Open Source Project2949f582009-03-03 19:30:46 -08001307 return NULL;
1308 break;
1309 default:
1310 /* NULL is dummy */
JP Abgrall53f17a92014-02-12 14:02:41 -08001311 isakmp_print(ndo, cp,
The Android Open Source Project2949f582009-03-03 19:30:46 -08001312 item_len - sizeof(*p) - n.spi_size,
1313 NULL);
1314 }
JP Abgrall53f17a92014-02-12 14:02:41 -08001315 ND_PRINT((ndo,")"));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001316 }
1317 return (u_char *)ext + item_len;
1318trunc:
JP Abgrall53f17a92014-02-12 14:02:41 -08001319 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N)));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001320 return NULL;
1321}
1322
1323static const u_char *
JP Abgrall53f17a92014-02-12 14:02:41 -08001324ikev1_d_print(netdissect_options *ndo, u_char tpay _U_,
1325 const struct isakmp_gen *ext, u_int item_len _U_,
1326 const u_char *ep _U_, u_int32_t phase _U_, u_int32_t doi0 _U_,
1327 u_int32_t proto0 _U_, int depth _U_)
The Android Open Source Project2949f582009-03-03 19:30:46 -08001328{
JP Abgrall53f17a92014-02-12 14:02:41 -08001329 const struct ikev1_pl_d *p;
1330 struct ikev1_pl_d d;
The Android Open Source Project2949f582009-03-03 19:30:46 -08001331 const u_int8_t *q;
1332 u_int32_t doi;
1333 u_int32_t proto;
1334 int i;
1335
JP Abgrall53f17a92014-02-12 14:02:41 -08001336 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_D)));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001337
JP Abgrall53f17a92014-02-12 14:02:41 -08001338 p = (struct ikev1_pl_d *)ext;
1339 ND_TCHECK(*p);
1340 UNALIGNED_MEMCPY(&d, ext, sizeof(d));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001341 doi = ntohl(d.doi);
1342 proto = d.prot_id;
1343 if (doi != 1) {
JP Abgrall53f17a92014-02-12 14:02:41 -08001344 ND_PRINT((ndo," doi=%u", doi));
1345 ND_PRINT((ndo," proto=%u", proto));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001346 } else {
JP Abgrall53f17a92014-02-12 14:02:41 -08001347 ND_PRINT((ndo," doi=ipsec"));
1348 ND_PRINT((ndo," proto=%s", PROTOIDSTR(proto)));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001349 }
JP Abgrall53f17a92014-02-12 14:02:41 -08001350 ND_PRINT((ndo," spilen=%u", d.spi_size));
1351 ND_PRINT((ndo," nspi=%u", ntohs(d.num_spi)));
1352 ND_PRINT((ndo," spi="));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001353 q = (u_int8_t *)(p + 1);
1354 for (i = 0; i < ntohs(d.num_spi); i++) {
1355 if (i != 0)
JP Abgrall53f17a92014-02-12 14:02:41 -08001356 ND_PRINT((ndo,","));
1357 if (!rawprint(ndo, (caddr_t)q, d.spi_size))
The Android Open Source Project2949f582009-03-03 19:30:46 -08001358 goto trunc;
1359 q += d.spi_size;
1360 }
1361 return q;
1362trunc:
JP Abgrall53f17a92014-02-12 14:02:41 -08001363 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_D)));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001364 return NULL;
1365}
1366
1367static const u_char *
JP Abgrall53f17a92014-02-12 14:02:41 -08001368ikev1_vid_print(netdissect_options *ndo, u_char tpay _U_,
1369 const struct isakmp_gen *ext,
1370 u_int item_len _U_, const u_char *ep _U_,
1371 u_int32_t phase _U_, u_int32_t doi _U_,
1372 u_int32_t proto _U_, int depth _U_)
The Android Open Source Project2949f582009-03-03 19:30:46 -08001373{
1374 struct isakmp_gen e;
1375
JP Abgrall53f17a92014-02-12 14:02:41 -08001376 ND_PRINT((ndo,"%s:", NPSTR(ISAKMP_NPTYPE_VID)));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001377
JP Abgrall53f17a92014-02-12 14:02:41 -08001378 ND_TCHECK(*ext);
1379 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
1380 ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
1381 if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1382 ND_PRINT((ndo," "));
1383 if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
The Android Open Source Project2949f582009-03-03 19:30:46 -08001384 goto trunc;
1385 }
1386 return (u_char *)ext + ntohs(e.len);
1387trunc:
JP Abgrall53f17a92014-02-12 14:02:41 -08001388 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_VID)));
1389 return NULL;
1390}
1391
1392/************************************************************/
1393/* */
1394/* IKE v2 - rfc4306 - dissector */
1395/* */
1396/************************************************************/
1397
1398static void
1399ikev2_pay_print(netdissect_options *ndo, const char *payname, int critical)
1400{
1401 ND_PRINT((ndo,"%s%s:", payname, critical&0x80 ? "[C]" : ""));
1402}
1403
1404static const u_char *
1405ikev2_gen_print(netdissect_options *ndo, u_char tpay,
1406 const struct isakmp_gen *ext)
1407{
1408 struct isakmp_gen e;
1409
1410 ND_TCHECK(*ext);
1411 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
1412 ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
1413
1414 ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
1415 if (2 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1416 ND_PRINT((ndo," "));
1417 if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
1418 goto trunc;
1419 }
1420 return (u_char *)ext + ntohs(e.len);
1421trunc:
1422 ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
The Android Open Source Project2949f582009-03-03 19:30:46 -08001423 return NULL;
1424}
1425
1426static const u_char *
JP Abgrall53f17a92014-02-12 14:02:41 -08001427ikev2_t_print(netdissect_options *ndo, u_char tpay _U_, int pcount,
1428 const struct isakmp_gen *ext, u_int item_len,
1429 const u_char *ep, u_int32_t phase _U_, u_int32_t doi _U_,
1430 u_int32_t proto _U_, int depth _U_)
1431{
1432 const struct ikev2_t *p;
1433 struct ikev2_t t;
1434 u_int16_t t_id;
1435 const u_char *cp;
1436 const char *idstr;
1437 const struct attrmap *map;
1438 size_t nmap;
1439 const u_char *ep2;
1440
1441 p = (struct ikev2_t *)ext;
1442 ND_TCHECK(*p);
1443 UNALIGNED_MEMCPY(&t, ext, sizeof(t));
1444 ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_T), t.h.critical);
1445
1446 t_id = ntohs(t.t_id);
1447
1448 map = NULL;
1449 nmap = 0;
1450
1451 switch (t.t_type) {
1452 case IV2_T_ENCR:
1453 idstr = STR_OR_ID(t_id, esp_p_map);
1454 map = encr_t_map;
1455 nmap = sizeof(encr_t_map)/sizeof(encr_t_map[0]);
1456 break;
1457
1458 case IV2_T_PRF:
1459 idstr = STR_OR_ID(t_id, prf_p_map);
1460 break;
1461
1462 case IV2_T_INTEG:
1463 idstr = STR_OR_ID(t_id, integ_p_map);
1464 break;
1465
1466 case IV2_T_DH:
1467 idstr = STR_OR_ID(t_id, dh_p_map);
1468 break;
1469
1470 case IV2_T_ESN:
1471 idstr = STR_OR_ID(t_id, esn_p_map);
1472 break;
1473
1474 default:
1475 idstr = NULL;
1476 break;
1477 }
1478
1479 if (idstr)
1480 ND_PRINT((ndo," #%u type=%s id=%s ", pcount,
1481 STR_OR_ID(t.t_type, ikev2_t_type_map),
1482 idstr));
1483 else
1484 ND_PRINT((ndo," #%u type=%s id=%u ", pcount,
1485 STR_OR_ID(t.t_type, ikev2_t_type_map),
1486 t.t_id));
1487 cp = (u_char *)(p + 1);
1488 ep2 = (u_char *)p + item_len;
1489 while (cp < ep && cp < ep2) {
1490 if (map && nmap) {
1491 cp = ikev1_attrmap_print(ndo, cp, (ep < ep2) ? ep : ep2,
1492 map, nmap);
1493 } else
1494 cp = ikev1_attr_print(ndo, cp, (ep < ep2) ? ep : ep2);
1495 }
1496 if (ep < ep2)
1497 ND_PRINT((ndo,"..."));
1498 return cp;
1499trunc:
1500 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_T)));
1501 return NULL;
1502}
1503
1504static const u_char *
1505ikev2_p_print(netdissect_options *ndo, u_char tpay _U_, int pcount _U_,
1506 const struct isakmp_gen *ext, u_int item_len _U_,
1507 const u_char *ep, u_int32_t phase, u_int32_t doi0,
1508 u_int32_t proto0 _U_, int depth)
1509{
1510 const struct ikev2_p *p;
1511 struct ikev2_p prop;
1512 const u_char *cp;
1513
1514 p = (struct ikev2_p *)ext;
1515 ND_TCHECK(*p);
1516 UNALIGNED_MEMCPY(&prop, ext, sizeof(prop));
1517 ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_P), prop.h.critical);
1518
1519 ND_PRINT((ndo," #%u protoid=%s transform=%d len=%u",
1520 prop.p_no, PROTOIDSTR(prop.prot_id),
1521 prop.num_t, ntohs(prop.h.len)));
1522 if (prop.spi_size) {
1523 ND_PRINT((ndo," spi="));
1524 if (!rawprint(ndo, (caddr_t)(p + 1), prop.spi_size))
1525 goto trunc;
1526 }
1527
1528 ext = (struct isakmp_gen *)((u_char *)(p + 1) + prop.spi_size);
1529 ND_TCHECK(*ext);
1530
1531 cp = ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_T, ext, ep, phase, doi0,
1532 prop.prot_id, depth);
1533
1534 return cp;
1535trunc:
1536 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_P)));
1537 return NULL;
1538}
1539
1540static const u_char *
1541ikev2_sa_print(netdissect_options *ndo, u_char tpay,
1542 const struct isakmp_gen *ext1,
1543 u_int item_len _U_, const u_char *ep _U_,
1544 u_int32_t phase _U_, u_int32_t doi _U_,
1545 u_int32_t proto _U_, int depth _U_)
1546{
1547 struct isakmp_gen e;
1548 int osa_length, sa_length;
1549
1550 ND_TCHECK(*ext1);
1551 UNALIGNED_MEMCPY(&e, ext1, sizeof(e));
1552 ikev2_pay_print(ndo, "sa", e.critical);
1553
1554 osa_length= ntohs(e.len);
1555 sa_length = osa_length - 4;
1556 ND_PRINT((ndo," len=%d", sa_length));
1557
1558 ikev2_sub_print(ndo, NULL, ISAKMP_NPTYPE_P,
1559 ext1+1, ep,
1560 0, 0, 0, depth);
1561
1562 return (u_char *)ext1 + osa_length;
1563trunc:
1564 ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
1565 return NULL;
1566}
1567
1568static const u_char *
1569ikev2_ke_print(netdissect_options *ndo, u_char tpay,
1570 const struct isakmp_gen *ext,
1571 u_int item_len _U_, const u_char *ep _U_,
1572 u_int32_t phase _U_, u_int32_t doi _U_,
1573 u_int32_t proto _U_, int depth _U_)
1574{
1575 struct ikev2_ke ke;
1576 struct ikev2_ke *k;
1577
1578 k = (struct ikev2_ke *)ext;
1579 ND_TCHECK(*ext);
1580 UNALIGNED_MEMCPY(&ke, ext, sizeof(ke));
1581 ikev2_pay_print(ndo, NPSTR(tpay), ke.h.critical);
1582
1583 ND_PRINT((ndo," len=%u group=%s", ntohs(ke.h.len) - 8,
1584 STR_OR_ID(ntohs(ke.ke_group), dh_p_map)));
1585
1586 if (2 < ndo->ndo_vflag && 8 < ntohs(ke.h.len)) {
1587 ND_PRINT((ndo," "));
1588 if (!rawprint(ndo, (caddr_t)(k + 1), ntohs(ke.h.len) - 8))
1589 goto trunc;
1590 }
1591 return (u_char *)ext + ntohs(ke.h.len);
1592trunc:
1593 ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
1594 return NULL;
1595}
1596
1597static const u_char *
1598ikev2_ID_print(netdissect_options *ndo, u_char tpay,
1599 const struct isakmp_gen *ext,
1600 u_int item_len _U_, const u_char *ep _U_,
1601 u_int32_t phase _U_, u_int32_t doi _U_,
1602 u_int32_t proto _U_, int depth _U_)
1603{
1604 struct ikev2_id id;
1605 int id_len, idtype_len, i;
1606 unsigned int dumpascii, dumphex;
1607 unsigned char *typedata;
1608
1609 ND_TCHECK(*ext);
1610 UNALIGNED_MEMCPY(&id, ext, sizeof(id));
1611 ikev2_pay_print(ndo, NPSTR(tpay), id.h.critical);
1612
1613 id_len = ntohs(id.h.len);
1614
1615 ND_PRINT((ndo," len=%d", id_len - 4));
1616 if (2 < ndo->ndo_vflag && 4 < id_len) {
1617 ND_PRINT((ndo," "));
1618 if (!rawprint(ndo, (caddr_t)(ext + 1), id_len - 4))
1619 goto trunc;
1620 }
1621
1622 idtype_len =id_len - sizeof(struct ikev2_id);
1623 dumpascii = 0;
1624 dumphex = 0;
1625 typedata = (unsigned char *)(ext)+sizeof(struct ikev2_id);
1626
1627 switch(id.type) {
1628 case ID_IPV4_ADDR:
1629 ND_PRINT((ndo, " ipv4:"));
1630 dumphex=1;
1631 break;
1632 case ID_FQDN:
1633 ND_PRINT((ndo, " fqdn:"));
1634 dumpascii=1;
1635 break;
1636 case ID_RFC822_ADDR:
1637 ND_PRINT((ndo, " rfc822:"));
1638 dumpascii=1;
1639 break;
1640 case ID_IPV6_ADDR:
1641 ND_PRINT((ndo, " ipv6:"));
1642 dumphex=1;
1643 break;
1644 case ID_DER_ASN1_DN:
1645 ND_PRINT((ndo, " dn:"));
1646 dumphex=1;
1647 break;
1648 case ID_DER_ASN1_GN:
1649 ND_PRINT((ndo, " gn:"));
1650 dumphex=1;
1651 break;
1652 case ID_KEY_ID:
1653 ND_PRINT((ndo, " keyid:"));
1654 dumphex=1;
1655 break;
1656 }
1657
1658 if(dumpascii) {
1659 ND_TCHECK2(*typedata, idtype_len);
1660 for(i=0; i<idtype_len; i++) {
1661 if(ND_ISPRINT(typedata[i])) {
1662 ND_PRINT((ndo, "%c", typedata[i]));
1663 } else {
1664 ND_PRINT((ndo, "."));
1665 }
1666 }
1667 }
1668 if(dumphex) {
1669 if (!rawprint(ndo, (caddr_t)typedata, idtype_len))
1670 goto trunc;
1671 }
1672
1673 return (u_char *)ext + id_len;
1674trunc:
1675 ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
1676 return NULL;
1677}
1678
1679static const u_char *
1680ikev2_cert_print(netdissect_options *ndo, u_char tpay,
1681 const struct isakmp_gen *ext,
1682 u_int item_len _U_, const u_char *ep _U_,
1683 u_int32_t phase _U_, u_int32_t doi _U_,
1684 u_int32_t proto _U_, int depth _U_)
1685{
1686 return ikev2_gen_print(ndo, tpay, ext);
1687}
1688
1689static const u_char *
1690ikev2_cr_print(netdissect_options *ndo, u_char tpay,
1691 const struct isakmp_gen *ext,
1692 u_int item_len _U_, const u_char *ep _U_,
1693 u_int32_t phase _U_, u_int32_t doi _U_,
1694 u_int32_t proto _U_, int depth _U_)
1695{
1696 return ikev2_gen_print(ndo, tpay, ext);
1697}
1698
1699static const u_char *
1700ikev2_auth_print(netdissect_options *ndo, u_char tpay,
1701 const struct isakmp_gen *ext,
1702 u_int item_len _U_, const u_char *ep _U_,
1703 u_int32_t phase _U_, u_int32_t doi _U_,
1704 u_int32_t proto _U_, int depth _U_)
1705{
1706 struct ikev2_auth a;
1707 const char *v2_auth[]={ "invalid", "rsasig",
1708 "shared-secret", "dsssig" };
1709 u_char *authdata = (u_char*)ext + sizeof(a);
1710 unsigned int len;
1711
1712 ND_TCHECK(*ext);
1713 UNALIGNED_MEMCPY(&a, ext, sizeof(a));
1714 ikev2_pay_print(ndo, NPSTR(tpay), a.h.critical);
1715 len = ntohs(a.h.len);
1716
1717 ND_PRINT((ndo," len=%d method=%s", len-4,
1718 STR_OR_ID(a.auth_method, v2_auth)));
1719
1720 if (1 < ndo->ndo_vflag && 4 < len) {
1721 ND_PRINT((ndo," authdata=("));
1722 if (!rawprint(ndo, (caddr_t)authdata, len - sizeof(a)))
1723 goto trunc;
1724 ND_PRINT((ndo,") "));
1725 } else if(ndo->ndo_vflag && 4 < len) {
1726 if(!ike_show_somedata(ndo, authdata, ep)) goto trunc;
1727 }
1728
1729 return (u_char *)ext + len;
1730trunc:
1731 ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
1732 return NULL;
1733}
1734
1735static const u_char *
1736ikev2_nonce_print(netdissect_options *ndo, u_char tpay,
1737 const struct isakmp_gen *ext,
1738 u_int item_len _U_, const u_char *ep _U_,
1739 u_int32_t phase _U_, u_int32_t doi _U_,
1740 u_int32_t proto _U_, int depth _U_)
1741{
1742 struct isakmp_gen e;
1743
1744 ND_TCHECK(*ext);
1745 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
1746 ikev2_pay_print(ndo, "nonce", e.critical);
1747
1748 ND_PRINT((ndo," len=%d", ntohs(e.len) - 4));
1749 if (1 < ndo->ndo_vflag && 4 < ntohs(e.len)) {
1750 ND_PRINT((ndo," nonce=("));
1751 if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
1752 goto trunc;
1753 ND_PRINT((ndo,") "));
1754 } else if(ndo->ndo_vflag && 4 < ntohs(e.len)) {
1755 if(!ike_show_somedata(ndo, (const u_char *)(ext+1), ep)) goto trunc;
1756 }
1757
1758 return (u_char *)ext + ntohs(e.len);
1759trunc:
1760 ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
1761 return NULL;
1762}
1763
1764/* notify payloads */
1765static const u_char *
1766ikev2_n_print(netdissect_options *ndo, u_char tpay _U_,
1767 const struct isakmp_gen *ext,
1768 u_int item_len _U_, const u_char *ep _U_,
1769 u_int32_t phase _U_, u_int32_t doi _U_,
1770 u_int32_t proto _U_, int depth _U_)
1771{
1772 struct ikev2_n *p, n;
1773 const u_char *cp;
1774 u_char showspi, showdata, showsomedata;
1775 const char *notify_name;
1776 u_int32_t type;
1777
1778 p = (struct ikev2_n *)ext;
1779 ND_TCHECK(*p);
1780 UNALIGNED_MEMCPY(&n, ext, sizeof(n));
1781 ikev2_pay_print(ndo, NPSTR(ISAKMP_NPTYPE_N), n.h.critical);
1782
1783 showspi = 1;
1784 showdata = 0;
1785 showsomedata=0;
1786 notify_name=NULL;
1787
1788 ND_PRINT((ndo," prot_id=%s", PROTOIDSTR(n.prot_id)));
1789
1790 type = ntohs(n.type);
1791
1792 /* notify space is annoying sparse */
1793 switch(type) {
1794 case IV2_NOTIFY_UNSUPPORTED_CRITICAL_PAYLOAD:
1795 notify_name = "unsupported_critical_payload";
1796 showspi = 0;
1797 break;
1798
1799 case IV2_NOTIFY_INVALID_IKE_SPI:
1800 notify_name = "invalid_ike_spi";
1801 showspi = 1;
1802 break;
1803
1804 case IV2_NOTIFY_INVALID_MAJOR_VERSION:
1805 notify_name = "invalid_major_version";
1806 showspi = 0;
1807 break;
1808
1809 case IV2_NOTIFY_INVALID_SYNTAX:
1810 notify_name = "invalid_syntax";
1811 showspi = 1;
1812 break;
1813
1814 case IV2_NOTIFY_INVALID_MESSAGE_ID:
1815 notify_name = "invalid_message_id";
1816 showspi = 1;
1817 break;
1818
1819 case IV2_NOTIFY_INVALID_SPI:
1820 notify_name = "invalid_spi";
1821 showspi = 1;
1822 break;
1823
1824 case IV2_NOTIFY_NO_PROPOSAL_CHOSEN:
1825 notify_name = "no_protocol_chosen";
1826 showspi = 1;
1827 break;
1828
1829 case IV2_NOTIFY_INVALID_KE_PAYLOAD:
1830 notify_name = "invalid_ke_payload";
1831 showspi = 1;
1832 break;
1833
1834 case IV2_NOTIFY_AUTHENTICATION_FAILED:
1835 notify_name = "authentication_failed";
1836 showspi = 1;
1837 break;
1838
1839 case IV2_NOTIFY_SINGLE_PAIR_REQUIRED:
1840 notify_name = "single_pair_required";
1841 showspi = 1;
1842 break;
1843
1844 case IV2_NOTIFY_NO_ADDITIONAL_SAS:
1845 notify_name = "no_additional_sas";
1846 showspi = 0;
1847 break;
1848
1849 case IV2_NOTIFY_INTERNAL_ADDRESS_FAILURE:
1850 notify_name = "internal_address_failure";
1851 showspi = 0;
1852 break;
1853
1854 case IV2_NOTIFY_FAILED_CP_REQUIRED:
1855 notify_name = "failed:cp_required";
1856 showspi = 0;
1857 break;
1858
1859 case IV2_NOTIFY_INVALID_SELECTORS:
1860 notify_name = "invalid_selectors";
1861 showspi = 0;
1862 break;
1863
1864 case IV2_NOTIFY_INITIAL_CONTACT:
1865 notify_name = "initial_contact";
1866 showspi = 0;
1867 break;
1868
1869 case IV2_NOTIFY_SET_WINDOW_SIZE:
1870 notify_name = "set_window_size";
1871 showspi = 0;
1872 break;
1873
1874 case IV2_NOTIFY_ADDITIONAL_TS_POSSIBLE:
1875 notify_name = "additional_ts_possible";
1876 showspi = 0;
1877 break;
1878
1879 case IV2_NOTIFY_IPCOMP_SUPPORTED:
1880 notify_name = "ipcomp_supported";
1881 showspi = 0;
1882 break;
1883
1884 case IV2_NOTIFY_NAT_DETECTION_SOURCE_IP:
1885 notify_name = "nat_detection_source_ip";
1886 showspi = 1;
1887 break;
1888
1889 case IV2_NOTIFY_NAT_DETECTION_DESTINATION_IP:
1890 notify_name = "nat_detection_destination_ip";
1891 showspi = 1;
1892 break;
1893
1894 case IV2_NOTIFY_COOKIE:
1895 notify_name = "cookie";
1896 showspi = 1;
1897 showsomedata= 1;
1898 showdata= 0;
1899 break;
1900
1901 case IV2_NOTIFY_USE_TRANSPORT_MODE:
1902 notify_name = "use_transport_mode";
1903 showspi = 0;
1904 break;
1905
1906 case IV2_NOTIFY_HTTP_CERT_LOOKUP_SUPPORTED:
1907 notify_name = "http_cert_lookup_supported";
1908 showspi = 0;
1909 break;
1910
1911 case IV2_NOTIFY_REKEY_SA:
1912 notify_name = "rekey_sa";
1913 showspi = 1;
1914 break;
1915
1916 case IV2_NOTIFY_ESP_TFC_PADDING_NOT_SUPPORTED:
1917 notify_name = "tfc_padding_not_supported";
1918 showspi = 0;
1919 break;
1920
1921 case IV2_NOTIFY_NON_FIRST_FRAGMENTS_ALSO:
1922 notify_name = "non_first_fragment_also";
1923 showspi = 0;
1924 break;
1925
1926 default:
1927 if (type < 8192) {
1928 notify_name="error";
1929 } else if(type < 16384) {
1930 notify_name="private-error";
1931 } else if(type < 40960) {
1932 notify_name="status";
1933 } else {
1934 notify_name="private-status";
1935 }
1936 }
1937
1938 if(notify_name) {
1939 ND_PRINT((ndo," type=%u(%s)", type, notify_name));
1940 }
1941
1942
1943 if (showspi && n.spi_size) {
1944 ND_PRINT((ndo," spi="));
1945 if (!rawprint(ndo, (caddr_t)(p + 1), n.spi_size))
1946 goto trunc;
1947 }
1948
1949 cp = (u_char *)(p + 1) + n.spi_size;
1950
1951 if(3 < ndo->ndo_vflag) {
1952 showdata = 1;
1953 }
1954
1955 if ((showdata || (showsomedata && ep-cp < 30)) && cp < ep) {
1956 ND_PRINT((ndo," data=("));
1957 if (!rawprint(ndo, (caddr_t)(cp), ep - cp))
1958 goto trunc;
1959
1960 ND_PRINT((ndo,")"));
1961
1962 } else if(showsomedata && cp < ep) {
1963 if(!ike_show_somedata(ndo, cp, ep)) goto trunc;
1964 }
1965
1966 return (u_char *)ext + item_len;
1967trunc:
1968 ND_PRINT((ndo," [|%s]", NPSTR(ISAKMP_NPTYPE_N)));
1969 return NULL;
1970}
1971
1972static const u_char *
1973ikev2_d_print(netdissect_options *ndo, u_char tpay,
1974 const struct isakmp_gen *ext,
1975 u_int item_len _U_, const u_char *ep _U_,
1976 u_int32_t phase _U_, u_int32_t doi _U_,
1977 u_int32_t proto _U_, int depth _U_)
1978{
1979 return ikev2_gen_print(ndo, tpay, ext);
1980}
1981
1982static const u_char *
1983ikev2_vid_print(netdissect_options *ndo, u_char tpay,
1984 const struct isakmp_gen *ext,
1985 u_int item_len _U_, const u_char *ep _U_,
1986 u_int32_t phase _U_, u_int32_t doi _U_,
1987 u_int32_t proto _U_, int depth _U_)
1988{
1989 struct isakmp_gen e;
1990 const u_char *vid;
1991 int i, len;
1992
1993 ND_TCHECK(*ext);
1994 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
1995 ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
1996 ND_PRINT((ndo," len=%d vid=", ntohs(e.len) - 4));
1997
1998 vid = (const u_char *)(ext+1);
1999 len = ntohs(e.len) - 4;
2000 ND_TCHECK2(*vid, len);
2001 for(i=0; i<len; i++) {
2002 if(ND_ISPRINT(vid[i])) ND_PRINT((ndo, "%c", vid[i]));
2003 else ND_PRINT((ndo, "."));
2004 }
2005 if (2 < ndo->ndo_vflag && 4 < len) {
2006 ND_PRINT((ndo," "));
2007 if (!rawprint(ndo, (caddr_t)(ext + 1), ntohs(e.len) - 4))
2008 goto trunc;
2009 }
2010 return (u_char *)ext + ntohs(e.len);
2011trunc:
2012 ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
2013 return NULL;
2014}
2015
2016static const u_char *
2017ikev2_TS_print(netdissect_options *ndo, u_char tpay,
2018 const struct isakmp_gen *ext,
2019 u_int item_len _U_, const u_char *ep _U_,
2020 u_int32_t phase _U_, u_int32_t doi _U_,
2021 u_int32_t proto _U_, int depth _U_)
2022{
2023 return ikev2_gen_print(ndo, tpay, ext);
2024}
2025
2026static const u_char *
2027ikev2_e_print(netdissect_options *ndo,
2028#ifndef HAVE_LIBCRYPTO
2029 _U_
2030#endif
2031 struct isakmp *base,
2032 u_char tpay,
2033 const struct isakmp_gen *ext,
2034 u_int item_len _U_, const u_char *ep _U_,
2035#ifndef HAVE_LIBCRYPTO
2036 _U_
2037#endif
2038 u_int32_t phase,
2039#ifndef HAVE_LIBCRYPTO
2040 _U_
2041#endif
2042 u_int32_t doi,
2043#ifndef HAVE_LIBCRYPTO
2044 _U_
2045#endif
2046 u_int32_t proto,
2047#ifndef HAVE_LIBCRYPTO
2048 _U_
2049#endif
2050 int depth)
2051{
2052 struct isakmp_gen e;
2053 u_char *dat;
2054 volatile int dlen;
2055
2056 ND_TCHECK(*ext);
2057 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
2058 ikev2_pay_print(ndo, NPSTR(tpay), e.critical);
2059
2060 dlen = ntohs(e.len)-4;
2061
2062 ND_PRINT((ndo," len=%d", dlen));
2063 if (2 < ndo->ndo_vflag && 4 < dlen) {
2064 ND_PRINT((ndo," "));
2065 if (!rawprint(ndo, (caddr_t)(ext + 1), dlen))
2066 goto trunc;
2067 }
2068
2069 dat = (u_char *)(ext+1);
2070 ND_TCHECK2(*dat, dlen);
2071
2072#ifdef HAVE_LIBCRYPTO
2073 /* try to decypt it! */
2074 if(esp_print_decrypt_buffer_by_ikev2(ndo,
2075 base->flags & ISAKMP_FLAG_I,
2076 base->i_ck, base->r_ck,
2077 dat, dat+dlen)) {
2078
2079 ext = (const struct isakmp_gen *)ndo->ndo_packetp;
2080
2081 /* got it decrypted, print stuff inside. */
2082 ikev2_sub_print(ndo, base, e.np, ext, ndo->ndo_snapend,
2083 phase, doi, proto, depth+1);
2084 }
2085#endif
2086
2087
2088 /* always return NULL, because E must be at end, and NP refers
2089 * to what was inside.
2090 */
2091 return NULL;
2092trunc:
2093 ND_PRINT((ndo," [|%s]", NPSTR(tpay)));
2094 return NULL;
2095}
2096
2097static const u_char *
2098ikev2_cp_print(netdissect_options *ndo, u_char tpay,
2099 const struct isakmp_gen *ext,
2100 u_int item_len _U_, const u_char *ep _U_,
2101 u_int32_t phase _U_, u_int32_t doi _U_,
2102 u_int32_t proto _U_, int depth _U_)
2103{
2104 return ikev2_gen_print(ndo, tpay, ext);
2105}
2106
2107static const u_char *
2108ikev2_eap_print(netdissect_options *ndo, u_char tpay,
2109 const struct isakmp_gen *ext,
2110 u_int item_len _U_, const u_char *ep _U_,
2111 u_int32_t phase _U_, u_int32_t doi _U_,
2112 u_int32_t proto _U_, int depth _U_)
2113{
2114 return ikev2_gen_print(ndo, tpay, ext);
2115}
2116
2117static const u_char *
2118ike_sub0_print(netdissect_options *ndo,
2119 u_char np, const struct isakmp_gen *ext, const u_char *ep,
2120
2121 u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
The Android Open Source Project2949f582009-03-03 19:30:46 -08002122{
2123 const u_char *cp;
2124 struct isakmp_gen e;
2125 u_int item_len;
2126
2127 cp = (u_char *)ext;
JP Abgrall53f17a92014-02-12 14:02:41 -08002128 ND_TCHECK(*ext);
2129 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
The Android Open Source Project2949f582009-03-03 19:30:46 -08002130
2131 /*
2132 * Since we can't have a payload length of less than 4 bytes,
2133 * we need to bail out here if the generic header is nonsensical
2134 * or truncated, otherwise we could loop forever processing
2135 * zero-length items or otherwise misdissect the packet.
2136 */
2137 item_len = ntohs(e.len);
2138 if (item_len <= 4)
2139 return NULL;
2140
2141 if (NPFUNC(np)) {
2142 /*
2143 * XXX - what if item_len is too short, or too long,
2144 * for this payload type?
2145 */
JP Abgrall53f17a92014-02-12 14:02:41 -08002146 cp = (*npfunc[np])(ndo, np, ext, item_len, ep, phase, doi, proto, depth);
The Android Open Source Project2949f582009-03-03 19:30:46 -08002147 } else {
JP Abgrall53f17a92014-02-12 14:02:41 -08002148 ND_PRINT((ndo,"%s", NPSTR(np)));
The Android Open Source Project2949f582009-03-03 19:30:46 -08002149 cp += item_len;
2150 }
2151
2152 return cp;
2153trunc:
JP Abgrall53f17a92014-02-12 14:02:41 -08002154 ND_PRINT((ndo," [|isakmp]"));
The Android Open Source Project2949f582009-03-03 19:30:46 -08002155 return NULL;
2156}
2157
2158static const u_char *
JP Abgrall53f17a92014-02-12 14:02:41 -08002159ikev1_sub_print(netdissect_options *ndo,
2160 u_char np, const struct isakmp_gen *ext, const u_char *ep,
2161 u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
The Android Open Source Project2949f582009-03-03 19:30:46 -08002162{
2163 const u_char *cp;
2164 int i;
2165 struct isakmp_gen e;
2166
2167 cp = (const u_char *)ext;
2168
2169 while (np) {
JP Abgrall53f17a92014-02-12 14:02:41 -08002170 ND_TCHECK(*ext);
The Android Open Source Project2949f582009-03-03 19:30:46 -08002171
JP Abgrall53f17a92014-02-12 14:02:41 -08002172 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
2173
2174 ND_TCHECK2(*ext, ntohs(e.len));
The Android Open Source Project2949f582009-03-03 19:30:46 -08002175
2176 depth++;
JP Abgrall53f17a92014-02-12 14:02:41 -08002177 ND_PRINT((ndo,"\n"));
The Android Open Source Project2949f582009-03-03 19:30:46 -08002178 for (i = 0; i < depth; i++)
JP Abgrall53f17a92014-02-12 14:02:41 -08002179 ND_PRINT((ndo," "));
2180 ND_PRINT((ndo,"("));
2181 cp = ike_sub0_print(ndo, np, ext, ep, phase, doi, proto, depth);
2182 ND_PRINT((ndo,")"));
The Android Open Source Project2949f582009-03-03 19:30:46 -08002183 depth--;
2184
2185 if (cp == NULL) {
2186 /* Zero-length subitem */
2187 return NULL;
2188 }
2189
2190 np = e.np;
2191 ext = (struct isakmp_gen *)cp;
2192 }
2193 return cp;
2194trunc:
JP Abgrall53f17a92014-02-12 14:02:41 -08002195 ND_PRINT((ndo," [|%s]", NPSTR(np)));
The Android Open Source Project2949f582009-03-03 19:30:46 -08002196 return NULL;
2197}
2198
2199static char *
2200numstr(int x)
2201{
2202 static char buf[20];
2203 snprintf(buf, sizeof(buf), "#%d", x);
2204 return buf;
2205}
2206
The Android Open Source Project2949f582009-03-03 19:30:46 -08002207static void
JP Abgrall53f17a92014-02-12 14:02:41 -08002208ikev1_print(netdissect_options *ndo,
2209 const u_char *bp, u_int length,
2210 const u_char *bp2, struct isakmp *base)
The Android Open Source Project2949f582009-03-03 19:30:46 -08002211{
JP Abgrall53f17a92014-02-12 14:02:41 -08002212 const struct isakmp *p;
2213 const u_char *ep;
2214 u_char np;
2215 int i;
2216 int phase;
2217
2218 p = (const struct isakmp *)bp;
2219 ep = ndo->ndo_snapend;
2220
2221 phase = (EXTRACT_32BITS(base->msgid) == 0) ? 1 : 2;
2222 if (phase == 1)
2223 ND_PRINT((ndo," phase %d", phase));
2224 else
2225 ND_PRINT((ndo," phase %d/others", phase));
2226
2227 i = cookie_find(&base->i_ck);
2228 if (i < 0) {
2229 if (iszero((u_char *)&base->r_ck, sizeof(base->r_ck))) {
2230 /* the first packet */
2231 ND_PRINT((ndo," I"));
2232 if (bp2)
2233 cookie_record(&base->i_ck, bp2);
2234 } else
2235 ND_PRINT((ndo," ?"));
2236 } else {
2237 if (bp2 && cookie_isinitiator(i, bp2))
2238 ND_PRINT((ndo," I"));
2239 else if (bp2 && cookie_isresponder(i, bp2))
2240 ND_PRINT((ndo," R"));
2241 else
2242 ND_PRINT((ndo," ?"));
2243 }
2244
2245 ND_PRINT((ndo," %s", ETYPESTR(base->etype)));
2246 if (base->flags) {
2247 ND_PRINT((ndo,"[%s%s]", base->flags & ISAKMP_FLAG_E ? "E" : "",
2248 base->flags & ISAKMP_FLAG_C ? "C" : ""));
2249 }
2250
2251 if (ndo->ndo_vflag) {
2252 const struct isakmp_gen *ext;
2253
2254 ND_PRINT((ndo,":"));
2255
2256 /* regardless of phase... */
2257 if (base->flags & ISAKMP_FLAG_E) {
2258 /*
2259 * encrypted, nothing we can do right now.
2260 * we hope to decrypt the packet in the future...
2261 */
2262 ND_PRINT((ndo," [encrypted %s]", NPSTR(base->np)));
2263 goto done;
2264 }
2265
2266 CHECKLEN(p + 1, base->np);
2267 np = base->np;
2268 ext = (struct isakmp_gen *)(p + 1);
2269 ikev1_sub_print(ndo, np, ext, ep, phase, 0, 0, 0);
2270 }
2271
2272done:
2273 if (ndo->ndo_vflag) {
2274 if (ntohl(base->len) != length) {
2275 ND_PRINT((ndo," (len mismatch: isakmp %u/ip %u)",
2276 (u_int32_t)ntohl(base->len), length));
2277 }
2278 }
2279}
2280
2281static const u_char *
2282ikev2_sub0_print(netdissect_options *ndo, struct isakmp *base,
2283 u_char np, int pcount,
2284 const struct isakmp_gen *ext, const u_char *ep,
2285 u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
2286{
2287 const u_char *cp;
2288 struct isakmp_gen e;
2289 u_int item_len;
2290
2291 cp = (u_char *)ext;
2292 ND_TCHECK(*ext);
2293 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
2294
2295 /*
2296 * Since we can't have a payload length of less than 4 bytes,
2297 * we need to bail out here if the generic header is nonsensical
2298 * or truncated, otherwise we could loop forever processing
2299 * zero-length items or otherwise misdissect the packet.
2300 */
2301 item_len = ntohs(e.len);
2302 if (item_len <= 4)
2303 return NULL;
2304
2305 if(np == ISAKMP_NPTYPE_P) {
2306 cp = ikev2_p_print(ndo, np, pcount, ext, item_len,
2307 ep, phase, doi, proto, depth);
2308 } else if(np == ISAKMP_NPTYPE_T) {
2309 cp = ikev2_t_print(ndo, np, pcount, ext, item_len,
2310 ep, phase, doi, proto, depth);
2311 } else if(np == ISAKMP_NPTYPE_v2E) {
2312 cp = ikev2_e_print(ndo, base, np, ext, item_len,
2313 ep, phase, doi, proto, depth);
2314 } else if (NPFUNC(np)) {
2315 /*
2316 * XXX - what if item_len is too short, or too long,
2317 * for this payload type?
2318 */
2319 cp = (*npfunc[np])(ndo, np, /*pcount,*/ ext, item_len,
2320 ep, phase, doi, proto, depth);
2321 } else {
2322 ND_PRINT((ndo,"%s", NPSTR(np)));
2323 cp += item_len;
2324 }
2325
2326 return cp;
2327trunc:
2328 ND_PRINT((ndo," [|isakmp]"));
2329 return NULL;
2330}
2331
2332static const u_char *
2333ikev2_sub_print(netdissect_options *ndo,
2334 struct isakmp *base,
2335 u_char np, const struct isakmp_gen *ext, const u_char *ep,
2336 u_int32_t phase, u_int32_t doi, u_int32_t proto, int depth)
2337{
2338 const u_char *cp;
2339 int i;
2340 int pcount;
2341 struct isakmp_gen e;
2342
2343 cp = (const u_char *)ext;
2344 pcount = 0;
2345 while (np) {
2346 pcount++;
2347 ND_TCHECK(*ext);
2348
2349 UNALIGNED_MEMCPY(&e, ext, sizeof(e));
2350
2351 ND_TCHECK2(*ext, ntohs(e.len));
2352
2353 depth++;
2354 ND_PRINT((ndo,"\n"));
2355 for (i = 0; i < depth; i++)
2356 ND_PRINT((ndo," "));
2357 ND_PRINT((ndo,"("));
2358 cp = ikev2_sub0_print(ndo, base, np, pcount,
2359 ext, ep, phase, doi, proto, depth);
2360 ND_PRINT((ndo,")"));
2361 depth--;
2362
2363 if (cp == NULL) {
2364 /* Zero-length subitem */
2365 return NULL;
2366 }
2367
2368 np = e.np;
2369 ext = (struct isakmp_gen *)cp;
2370 }
2371 return cp;
2372trunc:
2373 ND_PRINT((ndo," [|%s]", NPSTR(np)));
2374 return NULL;
2375}
2376
2377static void
2378ikev2_print(netdissect_options *ndo,
2379 const u_char *bp, u_int length,
2380 const u_char *bp2 _U_, struct isakmp *base)
2381{
2382 const struct isakmp *p;
2383 const u_char *ep;
2384 u_char np;
2385 int phase;
2386
2387 p = (const struct isakmp *)bp;
2388 ep = ndo->ndo_snapend;
2389
2390 phase = (EXTRACT_32BITS(base->msgid) == 0) ? 1 : 2;
2391 if (phase == 1)
2392 ND_PRINT((ndo, " parent_sa"));
2393 else
2394 ND_PRINT((ndo, " child_sa "));
2395
2396 ND_PRINT((ndo, " %s", ETYPESTR(base->etype)));
2397 if (base->flags) {
2398 ND_PRINT((ndo, "[%s%s%s]",
2399 base->flags & ISAKMP_FLAG_I ? "I" : "",
2400 base->flags & ISAKMP_FLAG_V ? "V" : "",
2401 base->flags & ISAKMP_FLAG_R ? "R" : ""));
2402 }
2403
2404 if (ndo->ndo_vflag) {
2405 const struct isakmp_gen *ext;
2406
2407 ND_PRINT((ndo, ":"));
2408
2409 /* regardless of phase... */
2410 if (base->flags & ISAKMP_FLAG_E) {
2411 /*
2412 * encrypted, nothing we can do right now.
2413 * we hope to decrypt the packet in the future...
2414 */
2415 ND_PRINT((ndo, " [encrypted %s]", NPSTR(base->np)));
2416 goto done;
2417 }
2418
2419 CHECKLEN(p + 1, base->np)
2420
2421 np = base->np;
2422 ext = (struct isakmp_gen *)(p + 1);
2423 ikev2_sub_print(ndo, base, np, ext, ep, phase, 0, 0, 0);
2424 }
2425
2426done:
2427 if (ndo->ndo_vflag) {
2428 if (ntohl(base->len) != length) {
2429 ND_PRINT((ndo, " (len mismatch: isakmp %u/ip %u)",
2430 (u_int32_t)ntohl(base->len), length));
2431 }
2432 }
The Android Open Source Project2949f582009-03-03 19:30:46 -08002433}
2434
2435void
2436isakmp_print(netdissect_options *ndo,
2437 const u_char *bp, u_int length,
2438 const u_char *bp2)
2439{
2440 const struct isakmp *p;
2441 struct isakmp base;
2442 const u_char *ep;
The Android Open Source Project2949f582009-03-03 19:30:46 -08002443 int major, minor;
2444
JP Abgrall53f17a92014-02-12 14:02:41 -08002445#ifdef HAVE_LIBCRYPTO
2446 /* initialize SAs */
2447 if (ndo->ndo_sa_list_head == NULL) {
2448 if (ndo->ndo_espsecret)
2449 esp_print_decodesecret(ndo);
2450 }
2451#endif
2452
The Android Open Source Project2949f582009-03-03 19:30:46 -08002453 p = (const struct isakmp *)bp;
2454 ep = ndo->ndo_snapend;
2455
2456 if ((struct isakmp *)ep < p + 1) {
JP Abgrall53f17a92014-02-12 14:02:41 -08002457 ND_PRINT((ndo,"[|isakmp]"));
The Android Open Source Project2949f582009-03-03 19:30:46 -08002458 return;
2459 }
2460
JP Abgrall53f17a92014-02-12 14:02:41 -08002461 UNALIGNED_MEMCPY(&base, p, sizeof(base));
The Android Open Source Project2949f582009-03-03 19:30:46 -08002462
JP Abgrall53f17a92014-02-12 14:02:41 -08002463 ND_PRINT((ndo,"isakmp"));
2464 major = (base.vers & ISAKMP_VERS_MAJOR)
2465 >> ISAKMP_VERS_MAJOR_SHIFT;
2466 minor = (base.vers & ISAKMP_VERS_MINOR)
2467 >> ISAKMP_VERS_MINOR_SHIFT;
2468
2469 if (ndo->ndo_vflag) {
2470 ND_PRINT((ndo," %d.%d", major, minor));
The Android Open Source Project2949f582009-03-03 19:30:46 -08002471 }
2472
JP Abgrall53f17a92014-02-12 14:02:41 -08002473 if (ndo->ndo_vflag) {
2474 ND_PRINT((ndo," msgid "));
2475 hexprint(ndo, (caddr_t)&base.msgid, sizeof(base.msgid));
The Android Open Source Project2949f582009-03-03 19:30:46 -08002476 }
2477
JP Abgrall53f17a92014-02-12 14:02:41 -08002478 if (1 < ndo->ndo_vflag) {
2479 ND_PRINT((ndo," cookie "));
2480 hexprint(ndo, (caddr_t)&base.i_ck, sizeof(base.i_ck));
2481 ND_PRINT((ndo,"->"));
2482 hexprint(ndo, (caddr_t)&base.r_ck, sizeof(base.r_ck));
The Android Open Source Project2949f582009-03-03 19:30:46 -08002483 }
JP Abgrall53f17a92014-02-12 14:02:41 -08002484 ND_PRINT((ndo,":"));
The Android Open Source Project2949f582009-03-03 19:30:46 -08002485
JP Abgrall53f17a92014-02-12 14:02:41 -08002486 switch(major) {
2487 case IKEv1_MAJOR_VERSION:
2488 ikev1_print(ndo, bp, length, bp2, &base);
2489 break;
The Android Open Source Project2949f582009-03-03 19:30:46 -08002490
JP Abgrall53f17a92014-02-12 14:02:41 -08002491 case IKEv2_MAJOR_VERSION:
2492 ikev2_print(ndo, bp, length, bp2, &base);
2493 break;
The Android Open Source Project2949f582009-03-03 19:30:46 -08002494 }
2495}
2496
2497void
2498isakmp_rfc3948_print(netdissect_options *ndo,
2499 const u_char *bp, u_int length,
2500 const u_char *bp2)
2501{
The Android Open Source Project2949f582009-03-03 19:30:46 -08002502
2503 if(length == 1 && bp[0]==0xff) {
2504 ND_PRINT((ndo, "isakmp-nat-keep-alive"));
2505 return;
2506 }
2507
2508 if(length < 4) {
2509 goto trunc;
2510 }
JP Abgrall53f17a92014-02-12 14:02:41 -08002511
The Android Open Source Project2949f582009-03-03 19:30:46 -08002512 /*
2513 * see if this is an IKE packet
2514 */
2515 if(bp[0]==0 && bp[1]==0 && bp[2]==0 && bp[3]==0) {
2516 ND_PRINT((ndo, "NONESP-encap: "));
2517 isakmp_print(ndo, bp+4, length-4, bp2);
2518 return;
2519 }
2520
2521 /* must be an ESP packet */
2522 {
2523 int nh, enh, padlen;
2524 int advance;
2525
2526 ND_PRINT((ndo, "UDP-encap: "));
2527
2528 advance = esp_print(ndo, bp, length, bp2, &enh, &padlen);
2529 if(advance <= 0)
2530 return;
2531
2532 bp += advance;
2533 length -= advance + padlen;
2534 nh = enh & 0xff;
2535
2536 ip_print_inner(ndo, bp, length, nh, bp2);
2537 return;
2538 }
2539
2540trunc:
JP Abgrall53f17a92014-02-12 14:02:41 -08002541 ND_PRINT((ndo,"[|isakmp]"));
The Android Open Source Project2949f582009-03-03 19:30:46 -08002542 return;
2543}
2544
2545/*
2546 * Local Variables:
2547 * c-style: whitesmith
2548 * c-basic-offset: 8
2549 * End:
2550 */
JP Abgrall53f17a92014-02-12 14:02:41 -08002551
2552
2553
2554