1 |
|
|
/* $OpenBSD: print-ike.c,v 1.37 2015/01/16 06:40:21 deraadt Exp $ */ |
2 |
|
|
|
3 |
|
|
/* |
4 |
|
|
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999 |
5 |
|
|
* The Regents of the University of California. All rights reserved. |
6 |
|
|
* Copyright (c) 2001 Håkan Olsson. All rights reserved. |
7 |
|
|
* |
8 |
|
|
* Redistribution and use in source and binary forms, with or without |
9 |
|
|
* modification, are permitted provided that: (1) source code distributions |
10 |
|
|
* retain the above copyright notice and this paragraph in its entirety, (2) |
11 |
|
|
* distributions including binary code include the above copyright notice and |
12 |
|
|
* this paragraph in its entirety in the documentation or other materials |
13 |
|
|
* provided with the distribution, and (3) all advertising materials mentioning |
14 |
|
|
* features or use of this software display the following acknowledgement: |
15 |
|
|
* ``This product includes software developed by the University of California, |
16 |
|
|
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of |
17 |
|
|
* the University nor the names of its contributors may be used to endorse |
18 |
|
|
* or promote products derived from this software without specific prior |
19 |
|
|
* written permission. |
20 |
|
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED |
21 |
|
|
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF |
22 |
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. |
23 |
|
|
* |
24 |
|
|
* Format and print ike (isakmp) packets. |
25 |
|
|
* By Tero Kivinen <kivinen@ssh.fi>, Tero Mononen <tmo@ssh.fi>, |
26 |
|
|
* Tatu Ylonen <ylo@ssh.fi> and Timo J. Rinne <tri@ssh.fi> |
27 |
|
|
* in co-operation with SSH Communications Security, Espoo, Finland |
28 |
|
|
*/ |
29 |
|
|
|
30 |
|
|
#include <sys/time.h> |
31 |
|
|
#include <sys/socket.h> |
32 |
|
|
|
33 |
|
|
struct mbuf; |
34 |
|
|
struct rtentry; |
35 |
|
|
#include <net/if.h> |
36 |
|
|
#include <netinet/in.h> |
37 |
|
|
#include <arpa/inet.h> |
38 |
|
|
|
39 |
|
|
#include <ctype.h> |
40 |
|
|
#include <stdio.h> |
41 |
|
|
#include <string.h> |
42 |
|
|
|
43 |
|
|
#include "interface.h" |
44 |
|
|
#include "addrtoname.h" |
45 |
|
|
#include "ike.h" |
46 |
|
|
|
47 |
|
|
struct isakmp_header { |
48 |
|
|
u_int8_t init_cookie[8]; |
49 |
|
|
u_int8_t resp_cookie[8]; |
50 |
|
|
u_int8_t next_payload; |
51 |
|
|
u_int8_t version; |
52 |
|
|
u_int8_t exgtype; |
53 |
|
|
u_int8_t flags; |
54 |
|
|
u_int8_t msgid[4]; |
55 |
|
|
u_int32_t length; |
56 |
|
|
u_int8_t payloads[0]; |
57 |
|
|
}; |
58 |
|
|
|
59 |
|
|
struct sa_payload { |
60 |
|
|
u_int8_t next_payload; |
61 |
|
|
u_int8_t reserved; |
62 |
|
|
u_int16_t payload_length; |
63 |
|
|
u_int32_t doi; |
64 |
|
|
u_int8_t situation[0]; |
65 |
|
|
}; |
66 |
|
|
|
67 |
|
|
struct proposal_payload { |
68 |
|
|
u_int8_t next_payload; |
69 |
|
|
u_int8_t reserved; |
70 |
|
|
u_int16_t payload_length; |
71 |
|
|
u_int8_t nprop; |
72 |
|
|
u_int8_t proto; |
73 |
|
|
u_int8_t spi_size; |
74 |
|
|
u_int8_t nspis; |
75 |
|
|
u_int8_t spi[0]; |
76 |
|
|
}; |
77 |
|
|
|
78 |
|
|
struct transform_payload { |
79 |
|
|
u_int8_t next_payload; |
80 |
|
|
u_int8_t reserved; |
81 |
|
|
u_int16_t payload_length; |
82 |
|
|
u_int8_t ntrans; |
83 |
|
|
u_int8_t transform; |
84 |
|
|
u_int16_t reserved2; |
85 |
|
|
u_int8_t attribute[0]; |
86 |
|
|
}; |
87 |
|
|
|
88 |
|
|
struct ke_payload { |
89 |
|
|
u_int8_t next_payload; |
90 |
|
|
u_int8_t reserved; |
91 |
|
|
u_int16_t payload_length; |
92 |
|
|
u_int8_t data[0]; |
93 |
|
|
}; |
94 |
|
|
|
95 |
|
|
struct id_payload { |
96 |
|
|
u_int8_t next_payload; |
97 |
|
|
u_int8_t reserved; |
98 |
|
|
u_int16_t payload_length; |
99 |
|
|
u_int8_t type; |
100 |
|
|
u_int8_t id_data[3]; |
101 |
|
|
u_int8_t data[0]; |
102 |
|
|
}; |
103 |
|
|
|
104 |
|
|
struct notification_payload { |
105 |
|
|
u_int8_t next_payload; |
106 |
|
|
u_int8_t reserved; |
107 |
|
|
u_int16_t payload_length; |
108 |
|
|
u_int32_t doi; |
109 |
|
|
u_int8_t protocol_id; |
110 |
|
|
u_int8_t spi_size; |
111 |
|
|
u_int16_t type; |
112 |
|
|
u_int8_t data[0]; |
113 |
|
|
}; |
114 |
|
|
|
115 |
|
|
struct delete_payload { |
116 |
|
|
u_int8_t next_payload; |
117 |
|
|
u_int8_t reserved; |
118 |
|
|
u_int16_t payload_length; |
119 |
|
|
u_int32_t doi; |
120 |
|
|
u_int8_t proto; |
121 |
|
|
u_int8_t spi_size; |
122 |
|
|
u_int16_t nspis; |
123 |
|
|
u_int8_t spi[0]; |
124 |
|
|
}; |
125 |
|
|
|
126 |
|
|
struct vendor_payload { |
127 |
|
|
u_int8_t next_payload; |
128 |
|
|
u_int8_t reserved; |
129 |
|
|
u_int16_t payload_length; |
130 |
|
|
u_int8_t vid[0]; |
131 |
|
|
}; |
132 |
|
|
|
133 |
|
|
struct attribute_payload { |
134 |
|
|
u_int8_t next_payload; |
135 |
|
|
u_int8_t reserved; |
136 |
|
|
u_int16_t payload_length; |
137 |
|
|
u_int8_t type; |
138 |
|
|
u_int8_t reserved2; |
139 |
|
|
u_int16_t id; |
140 |
|
|
}; |
141 |
|
|
|
142 |
|
|
static void ike_pl_print(u_int8_t, u_int8_t *, u_int8_t); |
143 |
|
|
|
144 |
|
|
int ike_tab_level = 0; |
145 |
|
|
u_int8_t xform_proto; |
146 |
|
|
|
147 |
|
|
static const char *ike[] = IKE_PROTO_INITIALIZER; |
148 |
|
|
|
149 |
|
|
#define SMALL_TABS 4 |
150 |
|
|
#define SPACES " " |
151 |
|
|
const char * |
152 |
|
|
ike_tab_offset(void) |
153 |
|
|
{ |
154 |
|
|
const char *p, *endline; |
155 |
|
|
static const char line[] = SPACES; |
156 |
|
|
|
157 |
|
|
endline = line + sizeof line - 1; |
158 |
|
|
p = endline - SMALL_TABS * (ike_tab_level); |
159 |
|
|
|
160 |
|
|
return (p > line ? p : line); |
161 |
|
|
} |
162 |
|
|
|
163 |
|
|
static char * |
164 |
|
|
ike_get_cookie (u_int8_t *ic, u_int8_t *rc) |
165 |
|
|
{ |
166 |
|
|
static char cookie_jar[35]; |
167 |
|
|
int i; |
168 |
|
|
|
169 |
|
|
for (i = 0; i < 8; i++) |
170 |
|
|
snprintf(cookie_jar + i*2, sizeof(cookie_jar) - i*2, |
171 |
|
|
"%02x", *(ic + i)); |
172 |
|
|
strlcat(cookie_jar, "->", sizeof(cookie_jar)); |
173 |
|
|
for (i = 0; i < 8; i++) |
174 |
|
|
snprintf(cookie_jar + 18 + i*2, sizeof(cookie_jar) - 18 - i*2, |
175 |
|
|
"%02x", *(rc + i)); |
176 |
|
|
return cookie_jar; |
177 |
|
|
} |
178 |
|
|
|
179 |
|
|
/* |
180 |
|
|
* Print isakmp requests |
181 |
|
|
*/ |
182 |
|
|
void |
183 |
|
|
ike_print (const u_int8_t *cp, u_int length) |
184 |
|
|
{ |
185 |
|
|
struct isakmp_header *ih; |
186 |
|
|
const u_int8_t *ep; |
187 |
|
|
u_int8_t *payload, next_payload; |
188 |
|
|
int encrypted; |
189 |
|
|
static const char *exgtypes[] = IKE_EXCHANGE_TYPES_INITIALIZER; |
190 |
|
|
|
191 |
|
|
encrypted = 0; |
192 |
|
|
|
193 |
|
|
#ifdef TCHECK |
194 |
|
|
#undef TCHECK |
195 |
|
|
#endif |
196 |
|
|
#define TCHECK(var, l) if ((u_int8_t *)&(var) > ep - l) goto trunc |
197 |
|
|
|
198 |
|
|
ih = (struct isakmp_header *)cp; |
199 |
|
|
|
200 |
|
|
if (length < sizeof (struct isakmp_header)) |
201 |
|
|
goto trunc; |
202 |
|
|
|
203 |
|
|
/* 'ep' points to the end of avaible data. */ |
204 |
|
|
ep = snapend; |
205 |
|
|
|
206 |
|
|
printf(" isakmp"); |
207 |
|
|
|
208 |
|
|
printf(" v%d.%d", ih->version >> 4, ih->version & 0xf); |
209 |
|
|
|
210 |
|
|
printf(" exchange "); |
211 |
|
|
if (ih->exgtype < (sizeof exgtypes/sizeof exgtypes[0])) |
212 |
|
|
printf("%s", exgtypes[ih->exgtype]); |
213 |
|
|
else |
214 |
|
|
printf("%d (unknown)", ih->exgtype); |
215 |
|
|
|
216 |
|
|
if (ih->flags & FLAGS_ENCRYPTION) { |
217 |
|
|
printf(" encrypted"); |
218 |
|
|
encrypted = 1; |
219 |
|
|
} |
220 |
|
|
|
221 |
|
|
if (ih->flags & FLAGS_COMMIT) { |
222 |
|
|
printf(" commit"); |
223 |
|
|
} |
224 |
|
|
|
225 |
|
|
printf("\n\tcookie: %s", ike_get_cookie (ih->init_cookie, |
226 |
|
|
ih->resp_cookie)); |
227 |
|
|
|
228 |
|
|
TCHECK(ih->msgid, sizeof(ih->msgid)); |
229 |
|
|
printf(" msgid: %02x%02x%02x%02x", ih->msgid[0], ih->msgid[1], |
230 |
|
|
ih->msgid[2], ih->msgid[3]); |
231 |
|
|
|
232 |
|
|
TCHECK(ih->length, sizeof(ih->length)); |
233 |
|
|
printf(" len: %d", ntohl(ih->length)); |
234 |
|
|
|
235 |
|
|
if (ih->version > IKE_VERSION_2) { |
236 |
|
|
printf(" new version"); |
237 |
|
|
return; |
238 |
|
|
} |
239 |
|
|
|
240 |
|
|
payload = ih->payloads; |
241 |
|
|
next_payload = ih->next_payload; |
242 |
|
|
|
243 |
|
|
/* if encrypted, then open special file for encryption keys */ |
244 |
|
|
if (encrypted) { |
245 |
|
|
/* decrypt XXX */ |
246 |
|
|
return; |
247 |
|
|
} |
248 |
|
|
|
249 |
|
|
/* if verbose, print payload data */ |
250 |
|
|
if (vflag) |
251 |
|
|
ike_pl_print(next_payload, payload, ISAKMP_DOI); |
252 |
|
|
|
253 |
|
|
return; |
254 |
|
|
|
255 |
|
|
trunc: |
256 |
|
|
fputs(" [|isakmp]", stdout); |
257 |
|
|
} |
258 |
|
|
|
259 |
|
|
void |
260 |
|
|
ike_pl_sa_print (u_int8_t *buf, int len) |
261 |
|
|
{ |
262 |
|
|
struct sa_payload *sp = (struct sa_payload *)buf; |
263 |
|
|
u_int32_t sit_ipsec, doi; |
264 |
|
|
|
265 |
|
|
if (len < sizeof(struct sa_payload)) { |
266 |
|
|
printf(" [|payload]"); |
267 |
|
|
return; |
268 |
|
|
} |
269 |
|
|
|
270 |
|
|
doi = ntohl(sp->doi); |
271 |
|
|
printf(" DOI: %d", doi); |
272 |
|
|
|
273 |
|
|
if (doi == IPSEC_DOI) { |
274 |
|
|
if ((sp->situation + sizeof(u_int32_t)) > (buf + len)) { |
275 |
|
|
printf(" [|payload]"); |
276 |
|
|
return; |
277 |
|
|
} |
278 |
|
|
printf("(IPSEC) situation: "); |
279 |
|
|
sit_ipsec = ntohl(*(u_int32_t *)sp->situation); |
280 |
|
|
if (sit_ipsec & IKE_SITUATION_IDENTITY_ONLY) |
281 |
|
|
printf("IDENTITY_ONLY "); |
282 |
|
|
if (sit_ipsec & IKE_SITUATION_SECRECY) |
283 |
|
|
printf("SECRECY "); |
284 |
|
|
if (sit_ipsec & IKE_SITUATION_INTEGRITY) |
285 |
|
|
printf("INTEGRITY "); |
286 |
|
|
if ((sit_ipsec & IKE_SITUATION_MASK) == 0) |
287 |
|
|
printf("0x%x (unknown)", sit_ipsec); |
288 |
|
|
ike_pl_print (PAYLOAD_PROPOSAL, buf + |
289 |
|
|
sizeof(struct sa_payload) + sizeof(u_int32_t), IPSEC_DOI); |
290 |
|
|
} else |
291 |
|
|
printf(" situation: (unknown)"); |
292 |
|
|
} |
293 |
|
|
|
294 |
|
|
int |
295 |
|
|
ike_attribute_print (u_int8_t *buf, u_int8_t doi, int maxlen) |
296 |
|
|
{ |
297 |
|
|
static char *attrs[] = IKE_ATTR_INITIALIZER; |
298 |
|
|
static char *attr_enc[] = IKE_ATTR_ENCRYPT_INITIALIZER; |
299 |
|
|
static char *attr_hash[] = IKE_ATTR_HASH_INITIALIZER; |
300 |
|
|
static char *attr_auth[] = IKE_ATTR_AUTH_INITIALIZER; |
301 |
|
|
static char *attr_gdesc[] = IKE_ATTR_GROUP_DESC_INITIALIZER; |
302 |
|
|
static char *attr_gtype[] = IKE_ATTR_GROUP_INITIALIZER; |
303 |
|
|
static char *attr_ltype[] = IKE_ATTR_SA_DURATION_INITIALIZER; |
304 |
|
|
static char *ipsec_attrs[] = IPSEC_ATTR_INITIALIZER; |
305 |
|
|
static char *ipsec_attr_auth[] = IPSEC_ATTR_AUTH_INITIALIZER; |
306 |
|
|
static char *ipsec_attr_ltype[] = IPSEC_ATTR_DURATION_INITIALIZER; |
307 |
|
|
|
308 |
|
|
u_int8_t af = buf[0] >> 7; |
309 |
|
|
u_int16_t type = (buf[0] & 0x7f) << 8 | buf[1]; |
310 |
|
|
u_int16_t len = buf[2] << 8 | buf[3], val; |
311 |
|
|
|
312 |
|
|
if (doi == ISAKMP_DOI) |
313 |
|
|
printf("\n\t%sattribute %s = ", ike_tab_offset(), |
314 |
|
|
(type < sizeof attrs / sizeof attrs[0] ? |
315 |
|
|
attrs[type] : "<unknown>")); |
316 |
|
|
else |
317 |
|
|
printf("\n\t%sattribute %s = ", ike_tab_offset(), |
318 |
|
|
(type < (sizeof ipsec_attrs / sizeof ipsec_attrs[0]) ? |
319 |
|
|
ipsec_attrs[type] : "<unknown>")); |
320 |
|
|
|
321 |
|
|
if ((af == 1 && maxlen < 4) || (af == 0 && maxlen < (len + 4))) { |
322 |
|
|
printf("\n\t%s[|attr]", ike_tab_offset()); |
323 |
|
|
return maxlen; |
324 |
|
|
} |
325 |
|
|
|
326 |
|
|
if (af == 0) { |
327 |
|
|
/* AF=0; print the variable length attribute value */ |
328 |
|
|
for (val = 0; val < len; val++) |
329 |
|
|
printf("%02x", *(buf + 4 + val)); |
330 |
|
|
return len + 4; |
331 |
|
|
} |
332 |
|
|
|
333 |
|
|
val = len; /* For AF=1, this field is the "VALUE" */ |
334 |
|
|
len = 4; /* and with AF=1, length is always 4 */ |
335 |
|
|
|
336 |
|
|
#define CASE_PRINT(TYPE, var) \ |
337 |
|
|
case TYPE : \ |
338 |
|
|
if (val < sizeof var / sizeof var [0]) \ |
339 |
|
|
printf("%s", var [val]); \ |
340 |
|
|
else \ |
341 |
|
|
printf("%d (unknown)", val); \ |
342 |
|
|
break; |
343 |
|
|
|
344 |
|
|
if (doi == ISAKMP_DOI) |
345 |
|
|
switch(type) { |
346 |
|
|
CASE_PRINT(IKE_ATTR_ENCRYPTION_ALGORITHM, attr_enc); |
347 |
|
|
CASE_PRINT(IKE_ATTR_HASH_ALGORITHM, attr_hash); |
348 |
|
|
CASE_PRINT(IKE_ATTR_AUTHENTICATION_METHOD, attr_auth); |
349 |
|
|
CASE_PRINT(IKE_ATTR_GROUP_DESC, attr_gdesc); |
350 |
|
|
CASE_PRINT(IKE_ATTR_GROUP_TYPE, attr_gtype); |
351 |
|
|
CASE_PRINT(IKE_ATTR_LIFE_TYPE, attr_ltype); |
352 |
|
|
default: |
353 |
|
|
printf("%d", val); |
354 |
|
|
} |
355 |
|
|
else |
356 |
|
|
switch(type) { |
357 |
|
|
CASE_PRINT(IPSEC_ATTR_SA_LIFE_TYPE, ipsec_attr_ltype); |
358 |
|
|
CASE_PRINT(IPSEC_ATTR_AUTHENTICATION_ALGORITHM, |
359 |
|
|
ipsec_attr_auth); |
360 |
|
|
case IPSEC_ATTR_ENCAPSULATION_MODE: |
361 |
|
|
printf("%s", tok2str(ipsec_attr_encap, |
362 |
|
|
"%d", val)); |
363 |
|
|
break; |
364 |
|
|
default: |
365 |
|
|
printf("%d", val); |
366 |
|
|
} |
367 |
|
|
|
368 |
|
|
#undef CASE_PRINT |
369 |
|
|
return len; |
370 |
|
|
} |
371 |
|
|
|
372 |
|
|
void |
373 |
|
|
ike_pl_transform_print (u_int8_t *buf, int len, u_int8_t doi) |
374 |
|
|
{ |
375 |
|
|
struct transform_payload *tp = (struct transform_payload *)buf; |
376 |
|
|
const char *ah[] = IPSEC_AH_INITIALIZER; |
377 |
|
|
const char *esp[] = IPSEC_ESP_INITIALIZER; |
378 |
|
|
const char *ipcomp[] = IPCOMP_INITIALIZER; |
379 |
|
|
u_int8_t *attr = tp->attribute; |
380 |
|
|
|
381 |
|
|
if (len < sizeof(struct transform_payload)) { |
382 |
|
|
printf(" [|payload]"); |
383 |
|
|
return; |
384 |
|
|
} |
385 |
|
|
|
386 |
|
|
printf("\n\t%stransform: %u ID: ", ike_tab_offset(), tp->ntrans); |
387 |
|
|
|
388 |
|
|
switch (doi) { |
389 |
|
|
case ISAKMP_DOI: |
390 |
|
|
if (tp->transform < (sizeof ike / sizeof ike[0])) |
391 |
|
|
printf("%s", ike[tp->transform]); |
392 |
|
|
else |
393 |
|
|
printf("%d(unknown)", tp->transform); |
394 |
|
|
break; |
395 |
|
|
|
396 |
|
|
default: /* IPSEC_DOI */ |
397 |
|
|
switch (xform_proto) { /* from ike_proposal_print */ |
398 |
|
|
case PROTO_IPSEC_AH: |
399 |
|
|
if (tp->transform < (sizeof ah / sizeof ah[0])) |
400 |
|
|
printf("%s", ah[tp->transform]); |
401 |
|
|
else |
402 |
|
|
printf("%d(unknown)", tp->transform); |
403 |
|
|
break; |
404 |
|
|
case PROTO_IPSEC_ESP: |
405 |
|
|
if (tp->transform < (sizeof esp / sizeof esp[0])) |
406 |
|
|
printf("%s", esp[tp->transform]); |
407 |
|
|
else |
408 |
|
|
printf("%d(unknown)", tp->transform); |
409 |
|
|
break; |
410 |
|
|
case PROTO_IPCOMP: |
411 |
|
|
if (tp->transform < (sizeof ipcomp / sizeof ipcomp[0])) |
412 |
|
|
printf("%s", ipcomp[tp->transform]); |
413 |
|
|
else |
414 |
|
|
printf("%d(unknown)", tp->transform); |
415 |
|
|
break; |
416 |
|
|
default: |
417 |
|
|
printf("%d(unknown)", tp->transform); |
418 |
|
|
} |
419 |
|
|
break; |
420 |
|
|
} |
421 |
|
|
|
422 |
|
|
ike_tab_level++; |
423 |
|
|
while ((int)(attr - buf) < len) /* Skip last 'NONE' attr */ |
424 |
|
|
attr += ike_attribute_print(attr, doi, len - (attr - buf)); |
425 |
|
|
ike_tab_level--; |
426 |
|
|
} |
427 |
|
|
|
428 |
|
|
void |
429 |
|
|
ike_pl_proposal_print (u_int8_t *buf, int len, u_int8_t doi) |
430 |
|
|
{ |
431 |
|
|
struct proposal_payload *pp = (struct proposal_payload *)buf; |
432 |
|
|
int i; |
433 |
|
|
|
434 |
|
|
if (len < sizeof(struct proposal_payload)) { |
435 |
|
|
printf(" [|payload]"); |
436 |
|
|
return; |
437 |
|
|
} |
438 |
|
|
|
439 |
|
|
printf(" proposal: %d proto: %s spisz: %d xforms: %d", |
440 |
|
|
pp->nprop, (pp->proto < (sizeof ike / sizeof ike[0]) ? |
441 |
|
|
ike[pp->proto] : "(unknown)"), pp->spi_size, pp->nspis); |
442 |
|
|
|
443 |
|
|
xform_proto = pp->proto; |
444 |
|
|
|
445 |
|
|
if (pp->spi_size) { |
446 |
|
|
if ((pp->spi + pp->spi_size) > (buf + len)) { |
447 |
|
|
printf(" [|payload]"); |
448 |
|
|
return; |
449 |
|
|
} |
450 |
|
|
if (pp->proto == PROTO_IPCOMP) |
451 |
|
|
printf(" CPI: 0x"); |
452 |
|
|
else |
453 |
|
|
printf(" SPI: 0x"); |
454 |
|
|
for (i = 0; i < pp->spi_size; i++) |
455 |
|
|
printf("%02x", pp->spi[i]); |
456 |
|
|
} |
457 |
|
|
|
458 |
|
|
/* Reset to sane value. */ |
459 |
|
|
if (pp->proto == PROTO_ISAKMP) |
460 |
|
|
doi = ISAKMP_DOI; |
461 |
|
|
else |
462 |
|
|
doi = IPSEC_DOI; |
463 |
|
|
|
464 |
|
|
if (pp->nspis > 0) |
465 |
|
|
ike_pl_print(PAYLOAD_TRANSFORM, pp->spi + pp->spi_size, doi); |
466 |
|
|
} |
467 |
|
|
|
468 |
|
|
void |
469 |
|
|
ike_pl_ke_print (u_int8_t *buf, int len, u_int8_t doi) |
470 |
|
|
{ |
471 |
|
|
if (len < sizeof(struct ke_payload)) { |
472 |
|
|
printf(" [|payload]"); |
473 |
|
|
return; |
474 |
|
|
} |
475 |
|
|
|
476 |
|
|
if (doi != IPSEC_DOI) |
477 |
|
|
return; |
478 |
|
|
|
479 |
|
|
/* XXX ... */ |
480 |
|
|
} |
481 |
|
|
|
482 |
|
|
void |
483 |
|
|
ipsec_id_print (u_int8_t *buf, int len, u_int8_t doi) |
484 |
|
|
{ |
485 |
|
|
struct id_payload *ip = (struct id_payload *)buf; |
486 |
|
|
static const char *idtypes[] = IPSEC_ID_TYPE_INITIALIZER; |
487 |
|
|
char ntop_buf[INET6_ADDRSTRLEN]; |
488 |
|
|
struct in_addr in; |
489 |
|
|
u_int8_t *p; |
490 |
|
|
|
491 |
|
|
if (len < sizeof (struct id_payload)) { |
492 |
|
|
printf(" [|payload]"); |
493 |
|
|
return; |
494 |
|
|
} |
495 |
|
|
|
496 |
|
|
if (doi != ISAKMP_DOI) |
497 |
|
|
return; |
498 |
|
|
|
499 |
|
|
/* Don't print proto+port unless actually used */ |
500 |
|
|
if (ip->id_data[0] | ip->id_data[1] | ip->id_data[2]) |
501 |
|
|
printf(" proto: %d port: %d", ip->id_data[0], |
502 |
|
|
(ip->id_data[1] << 8) + ip->id_data[2]); |
503 |
|
|
|
504 |
|
|
printf(" type: %s = ", ip->type < (sizeof idtypes/sizeof idtypes[0]) ? |
505 |
|
|
idtypes[ip->type] : "<unknown>"); |
506 |
|
|
|
507 |
|
|
switch (ip->type) { |
508 |
|
|
case IPSEC_ID_IPV4_ADDR: |
509 |
|
|
if ((ip->data + sizeof in) > (buf + len)) { |
510 |
|
|
printf(" [|payload]"); |
511 |
|
|
return; |
512 |
|
|
} |
513 |
|
|
memcpy (&in.s_addr, ip->data, sizeof in); |
514 |
|
|
printf("%s", inet_ntoa (in)); |
515 |
|
|
break; |
516 |
|
|
|
517 |
|
|
case IPSEC_ID_IPV4_ADDR_SUBNET: |
518 |
|
|
case IPSEC_ID_IPV4_ADDR_RANGE: |
519 |
|
|
if ((ip->data + 2 * (sizeof in)) > (buf + len)) { |
520 |
|
|
printf(" [|payload]"); |
521 |
|
|
return; |
522 |
|
|
} |
523 |
|
|
memcpy (&in.s_addr, ip->data, sizeof in); |
524 |
|
|
printf("%s%s", inet_ntoa (in), |
525 |
|
|
ip->type == IPSEC_ID_IPV4_ADDR_SUBNET ? "/" : "-"); |
526 |
|
|
memcpy (&in.s_addr, ip->data + sizeof in, sizeof in); |
527 |
|
|
printf("%s", inet_ntoa (in)); |
528 |
|
|
break; |
529 |
|
|
|
530 |
|
|
case IPSEC_ID_IPV6_ADDR: |
531 |
|
|
if ((ip->data + sizeof ntop_buf) > (buf + len)) { |
532 |
|
|
printf(" [|payload]"); |
533 |
|
|
return; |
534 |
|
|
} |
535 |
|
|
printf("%s", inet_ntop (AF_INET6, ip->data, ntop_buf, |
536 |
|
|
sizeof ntop_buf)); |
537 |
|
|
break; |
538 |
|
|
|
539 |
|
|
case IPSEC_ID_IPV6_ADDR_SUBNET: |
540 |
|
|
case IPSEC_ID_IPV6_ADDR_RANGE: |
541 |
|
|
if ((ip->data + 2 * sizeof ntop_buf) > (buf + len)) { |
542 |
|
|
printf(" [|payload]"); |
543 |
|
|
return; |
544 |
|
|
} |
545 |
|
|
printf("%s%s", inet_ntop (AF_INET6, ip->data, ntop_buf, |
546 |
|
|
sizeof ntop_buf), |
547 |
|
|
ip->type == IPSEC_ID_IPV6_ADDR_SUBNET ? "/" : "-"); |
548 |
|
|
printf("%s", inet_ntop (AF_INET6, ip->data + sizeof ntop_buf, |
549 |
|
|
ntop_buf, sizeof ntop_buf)); |
550 |
|
|
break; |
551 |
|
|
|
552 |
|
|
case IPSEC_ID_FQDN: |
553 |
|
|
case IPSEC_ID_USER_FQDN: |
554 |
|
|
printf("\""); |
555 |
|
|
for (p = ip->data; (int)(p - buf) < len; p++) |
556 |
|
|
printf("%c",(isprint(*p) ? *p : '.')); |
557 |
|
|
printf("\""); |
558 |
|
|
break; |
559 |
|
|
|
560 |
|
|
case IPSEC_ID_DER_ASN1_DN: |
561 |
|
|
case IPSEC_ID_DER_ASN1_GN: |
562 |
|
|
case IPSEC_ID_KEY_ID: |
563 |
|
|
default: |
564 |
|
|
printf("\"(not shown)\""); |
565 |
|
|
break; |
566 |
|
|
} |
567 |
|
|
} |
568 |
|
|
|
569 |
|
|
void |
570 |
|
|
ike_pl_delete_print (u_int8_t *buf, int len) |
571 |
|
|
{ |
572 |
|
|
struct delete_payload *dp = (struct delete_payload *)buf; |
573 |
|
|
u_int32_t doi; |
574 |
|
|
u_int16_t s, nspis; |
575 |
|
|
u_int8_t *data; |
576 |
|
|
|
577 |
|
|
if (len < sizeof (struct delete_payload)) { |
578 |
|
|
printf(" [|payload]"); |
579 |
|
|
return; |
580 |
|
|
} |
581 |
|
|
|
582 |
|
|
doi = ntohl(dp->doi); |
583 |
|
|
nspis = ntohs(dp->nspis); |
584 |
|
|
|
585 |
|
|
if (doi != ISAKMP_DOI && doi != IPSEC_DOI) { |
586 |
|
|
printf(" (unknown DOI)"); |
587 |
|
|
return; |
588 |
|
|
} |
589 |
|
|
|
590 |
|
|
printf(" DOI: %u(%s) proto: %s nspis: %u", doi, |
591 |
|
|
doi == ISAKMP_DOI ? "ISAKMP" : "IPSEC", |
592 |
|
|
dp->proto < (sizeof ike / sizeof ike[0]) ? ike[dp->proto] : |
593 |
|
|
"(unknown)", nspis); |
594 |
|
|
|
595 |
|
|
if ((dp->spi + nspis * dp->spi_size) > (buf + len)) { |
596 |
|
|
printf(" [|payload]"); |
597 |
|
|
return; |
598 |
|
|
} |
599 |
|
|
|
600 |
|
|
for (s = 0; s < nspis; s++) { |
601 |
|
|
data = dp->spi + s * dp->spi_size; |
602 |
|
|
if (dp->spi_size == 16) |
603 |
|
|
printf("\n\t%scookie: %s", ike_tab_offset(), |
604 |
|
|
ike_get_cookie(&data[0], &data[8])); |
605 |
|
|
else |
606 |
|
|
printf("\n\t%sSPI: 0x%08x", ike_tab_offset(), |
607 |
|
|
data[0]<<24 | data[1]<<16 | data[2]<<8 | data[3]); |
608 |
|
|
} |
609 |
|
|
} |
610 |
|
|
|
611 |
|
|
void |
612 |
|
|
ike_pl_notification_print (u_int8_t *buf, int len) |
613 |
|
|
{ |
614 |
|
|
static const char *nftypes[] = IKE_NOTIFY_TYPES_INITIALIZER; |
615 |
|
|
struct notification_payload *np = (struct notification_payload *)buf; |
616 |
|
|
u_int32_t *replay, *seq; |
617 |
|
|
u_int32_t doi; |
618 |
|
|
u_int16_t type; |
619 |
|
|
u_int8_t *attr; |
620 |
|
|
|
621 |
|
|
if (len < sizeof (struct notification_payload)) { |
622 |
|
|
printf(" [|payload]"); |
623 |
|
|
return; |
624 |
|
|
} |
625 |
|
|
|
626 |
|
|
doi = ntohl (np->doi); |
627 |
|
|
type = ntohs (np->type); |
628 |
|
|
|
629 |
|
|
if (doi != ISAKMP_DOI && doi != IPSEC_DOI) { |
630 |
|
|
printf(" (unknown DOI)"); |
631 |
|
|
return; |
632 |
|
|
} |
633 |
|
|
|
634 |
|
|
printf("\n\t%snotification: ", ike_tab_offset()); |
635 |
|
|
|
636 |
|
|
if (type > 0 && type < (sizeof nftypes / sizeof nftypes[0])) { |
637 |
|
|
printf("%s", nftypes[type]); |
638 |
|
|
return; |
639 |
|
|
} |
640 |
|
|
switch (type) { |
641 |
|
|
|
642 |
|
|
case NOTIFY_IPSEC_RESPONDER_LIFETIME: |
643 |
|
|
printf("RESPONDER LIFETIME "); |
644 |
|
|
if (np->spi_size == 16) |
645 |
|
|
printf("(%s)", ike_get_cookie (&np->data[0], |
646 |
|
|
&np->data[8])); |
647 |
|
|
else |
648 |
|
|
printf("SPI: 0x%08x", np->data[0]<<24 | |
649 |
|
|
np->data[1]<<16 | np->data[2]<<8 | np->data[3]); |
650 |
|
|
attr = &np->data[np->spi_size]; |
651 |
|
|
ike_tab_level++; |
652 |
|
|
while ((int)(attr - buf) < len - 4) /* Skip last 'NONE' attr */ |
653 |
|
|
attr += ike_attribute_print(attr, IPSEC_DOI, |
654 |
|
|
len - (attr-buf)); |
655 |
|
|
ike_tab_level--; |
656 |
|
|
break; |
657 |
|
|
|
658 |
|
|
case NOTIFY_IPSEC_REPLAY_STATUS: |
659 |
|
|
replay = (u_int32_t *)&np->data[np->spi_size]; |
660 |
|
|
printf("REPLAY STATUS [%sabled] ", *replay ? "en" : "dis"); |
661 |
|
|
if (np->spi_size == 16) |
662 |
|
|
printf("(%s)", ike_get_cookie (&np->data[0], |
663 |
|
|
&np->data[8])); |
664 |
|
|
else |
665 |
|
|
printf("SPI: 0x%08x", np->data[0]<<24 | |
666 |
|
|
np->data[1]<<16 | np->data[2]<<8 | np->data[3]); |
667 |
|
|
break; |
668 |
|
|
|
669 |
|
|
case NOTIFY_IPSEC_INITIAL_CONTACT: |
670 |
|
|
printf("INITIAL CONTACT (%s)", ike_get_cookie (&np->data[0], |
671 |
|
|
&np->data[8])); |
672 |
|
|
break; |
673 |
|
|
|
674 |
|
|
case NOTIFY_STATUS_DPD_R_U_THERE: |
675 |
|
|
case NOTIFY_STATUS_DPD_R_U_THERE_ACK: |
676 |
|
|
printf("STATUS_DPD_R_U_THERE%s ", |
677 |
|
|
type == NOTIFY_STATUS_DPD_R_U_THERE ? "" : "_ACK"); |
678 |
|
|
if (np->spi_size != 16 || |
679 |
|
|
len < sizeof(struct notification_payload) + |
680 |
|
|
sizeof(u_int32_t)) |
681 |
|
|
printf("[bad notify]"); |
682 |
|
|
else { |
683 |
|
|
seq = (u_int32_t *)&np->data[np->spi_size]; |
684 |
|
|
printf("seq %u", ntohl(*seq)); |
685 |
|
|
} |
686 |
|
|
break; |
687 |
|
|
|
688 |
|
|
|
689 |
|
|
default: |
690 |
|
|
printf("%d (unknown)", type); |
691 |
|
|
break; |
692 |
|
|
} |
693 |
|
|
} |
694 |
|
|
|
695 |
|
|
void |
696 |
|
|
ike_pl_vendor_print (u_int8_t *buf, int len, u_int8_t doi) |
697 |
|
|
{ |
698 |
|
|
struct vendor_payload *vp = (struct vendor_payload *)buf; |
699 |
|
|
u_int8_t *p; |
700 |
|
|
int i; |
701 |
|
|
|
702 |
|
|
if (len < sizeof(struct vendor_payload)) { |
703 |
|
|
printf(" [|payload]"); |
704 |
|
|
return; |
705 |
|
|
} |
706 |
|
|
|
707 |
|
|
for (i = 0; i < sizeof vendor_ids / sizeof vendor_ids[0]; i ++) |
708 |
|
|
if (memcmp(vp->vid, vendor_ids[i].vid, |
709 |
|
|
vendor_ids[i].len) == 0) { |
710 |
|
|
printf (" (supports %s)", vendor_ids[i].name); |
711 |
|
|
return; |
712 |
|
|
} |
713 |
|
|
|
714 |
|
|
if (doi != IPSEC_DOI) |
715 |
|
|
return; |
716 |
|
|
|
717 |
|
|
printf(" \""); |
718 |
|
|
for (p = vp->vid; (int)(p - buf) < len; p++) |
719 |
|
|
printf("%c", (isprint(*p) ? *p : '.')); |
720 |
|
|
printf("\""); |
721 |
|
|
} |
722 |
|
|
|
723 |
|
|
/* IKE mode-config. */ |
724 |
|
|
int |
725 |
|
|
ike_cfg_attribute_print (u_int8_t *buf, int attr_type, int maxlen) |
726 |
|
|
{ |
727 |
|
|
static char *attrs[] = IKE_CFG_ATTRIBUTE_INITIALIZER; |
728 |
|
|
char ntop_buf[INET6_ADDRSTRLEN]; |
729 |
|
|
struct in_addr in; |
730 |
|
|
|
731 |
|
|
u_int8_t af = buf[0] >> 7; |
732 |
|
|
u_int16_t type = (buf[0] & 0x7f) << 8 | buf[1]; |
733 |
|
|
u_int16_t len = af ? 2 : buf[2] << 8 | buf[3], p; |
734 |
|
|
u_int8_t *val = af ? buf + 2 : buf + 4; |
735 |
|
|
|
736 |
|
|
printf("\n\t%sattribute %s = ", ike_tab_offset(), |
737 |
|
|
type < (sizeof attrs / sizeof attrs[0]) ? attrs[type] : |
738 |
|
|
"<unknown>"); |
739 |
|
|
|
740 |
|
|
if ((af == 1 && maxlen < 4) || |
741 |
|
|
(af == 0 && maxlen < (len + 4))) { |
742 |
|
|
printf("\n\t%s[|attr]", ike_tab_offset()); |
743 |
|
|
return maxlen; |
744 |
|
|
} |
745 |
|
|
|
746 |
|
|
/* XXX The 2nd term is for bug compatibility with PGPnet. */ |
747 |
|
|
if (len == 0 || (af && !val[0] && !val[1])) { |
748 |
|
|
printf("<none>"); |
749 |
|
|
return 4; |
750 |
|
|
} |
751 |
|
|
|
752 |
|
|
/* XXX Generally lengths are not checked well below. */ |
753 |
|
|
switch (type) { |
754 |
|
|
case IKE_CFG_ATTR_INTERNAL_IP4_ADDRESS: |
755 |
|
|
case IKE_CFG_ATTR_INTERNAL_IP4_NETMASK: |
756 |
|
|
case IKE_CFG_ATTR_INTERNAL_IP4_DNS: |
757 |
|
|
case IKE_CFG_ATTR_INTERNAL_IP4_NBNS: |
758 |
|
|
case IKE_CFG_ATTR_INTERNAL_IP4_DHCP: |
759 |
|
|
memcpy (&in.s_addr, val, sizeof in); |
760 |
|
|
printf("%s", inet_ntoa (in)); |
761 |
|
|
break; |
762 |
|
|
|
763 |
|
|
case IKE_CFG_ATTR_INTERNAL_IP6_ADDRESS: |
764 |
|
|
case IKE_CFG_ATTR_INTERNAL_IP6_NETMASK: |
765 |
|
|
case IKE_CFG_ATTR_INTERNAL_IP6_DNS: |
766 |
|
|
case IKE_CFG_ATTR_INTERNAL_IP6_NBNS: |
767 |
|
|
case IKE_CFG_ATTR_INTERNAL_IP6_DHCP: |
768 |
|
|
printf("%s", inet_ntop (AF_INET6, val, ntop_buf, |
769 |
|
|
sizeof ntop_buf)); |
770 |
|
|
break; |
771 |
|
|
|
772 |
|
|
case IKE_CFG_ATTR_INTERNAL_IP4_SUBNET: |
773 |
|
|
memcpy(&in.s_addr, val, sizeof in); |
774 |
|
|
printf("%s/", inet_ntoa (in)); |
775 |
|
|
memcpy(&in.s_addr, val + sizeof in, sizeof in); |
776 |
|
|
printf("%s", inet_ntoa (in)); |
777 |
|
|
break; |
778 |
|
|
|
779 |
|
|
case IKE_CFG_ATTR_INTERNAL_IP6_SUBNET: |
780 |
|
|
printf("%s/%u", inet_ntop (AF_INET6, val, ntop_buf, |
781 |
|
|
sizeof ntop_buf), val[16]); |
782 |
|
|
break; |
783 |
|
|
|
784 |
|
|
case IKE_CFG_ATTR_INTERNAL_ADDRESS_EXPIRY: |
785 |
|
|
printf("%u seconds", |
786 |
|
|
val[0] << 24 | val[1] << 16 | val[2] << 8 | val[3]); |
787 |
|
|
break; |
788 |
|
|
|
789 |
|
|
case IKE_CFG_ATTR_APPLICATION_VERSION: |
790 |
|
|
for (p = 0; p < len; p++) |
791 |
|
|
printf("%c", isprint(val[p]) ? val[p] : '.'); |
792 |
|
|
break; |
793 |
|
|
|
794 |
|
|
case IKE_CFG_ATTR_SUPPORTED_ATTRIBUTES: |
795 |
|
|
printf("<%d attributes>", len / 2); |
796 |
|
|
ike_tab_level++; |
797 |
|
|
for (p = 0; p < len; p += 2) { |
798 |
|
|
type = (val[p] << 8 | val[p + 1]) & 0x7fff; |
799 |
|
|
printf("\n\t%s%s", ike_tab_offset(), |
800 |
|
|
type < (sizeof attrs/sizeof attrs[0]) ? |
801 |
|
|
attrs[type] : "<unknown>"); |
802 |
|
|
} |
803 |
|
|
ike_tab_level--; |
804 |
|
|
break; |
805 |
|
|
|
806 |
|
|
default: |
807 |
|
|
break; |
808 |
|
|
} |
809 |
|
|
return af ? 4 : len + 4; |
810 |
|
|
} |
811 |
|
|
|
812 |
|
|
void |
813 |
|
|
ike_pl_attribute_print (u_int8_t *buf, int len) |
814 |
|
|
{ |
815 |
|
|
struct attribute_payload *ap = (struct attribute_payload *)buf; |
816 |
|
|
static const char *pl_attr[] = IKE_CFG_ATTRIBUTE_TYPE_INITIALIZER; |
817 |
|
|
u_int8_t *attr = buf + sizeof(struct attribute_payload); |
818 |
|
|
|
819 |
|
|
if (len < sizeof(struct attribute_payload)) { |
820 |
|
|
printf(" [|payload]"); |
821 |
|
|
return; |
822 |
|
|
} |
823 |
|
|
|
824 |
|
|
printf(" type: %s Id: %d", |
825 |
|
|
ap->type < (sizeof pl_attr/sizeof pl_attr[0]) ? pl_attr[ap->type] : |
826 |
|
|
"<unknown>", ap->id); |
827 |
|
|
|
828 |
|
|
while ((int)(attr - buf) < len) |
829 |
|
|
attr += ike_cfg_attribute_print(attr, ap->type, |
830 |
|
|
len - (attr - buf)); |
831 |
|
|
} |
832 |
|
|
|
833 |
|
|
void |
834 |
|
|
ike_pl_print (u_int8_t type, u_int8_t *buf, u_int8_t doi) |
835 |
|
|
{ |
836 |
|
|
static const char *pltypes[] = IKE_PAYLOAD_TYPES_INITIALIZER; |
837 |
|
|
static const char *plprivtypes[] = |
838 |
|
|
IKE_PRIVATE_PAYLOAD_TYPES_INITIALIZER; |
839 |
|
|
static const char *plv2types[] = IKEV2_PAYLOAD_TYPES_INITIALIZER; |
840 |
|
|
u_int8_t next_type; |
841 |
|
|
u_int16_t this_len; |
842 |
|
|
|
843 |
|
|
if (&buf[4] > snapend) { |
844 |
|
|
goto pltrunc; |
845 |
|
|
} |
846 |
|
|
|
847 |
|
|
next_type = buf[0]; |
848 |
|
|
this_len = buf[2]<<8 | buf[3]; |
849 |
|
|
|
850 |
|
|
if (type < PAYLOAD_PRIVATE_MIN && type >= PAYLOAD_IKEV2_SA) |
851 |
|
|
printf("\n\t%spayload: %s len: %hu", ike_tab_offset(), |
852 |
|
|
plv2types[type - PAYLOAD_IKEV2_SA], this_len); |
853 |
|
|
else if (type < PAYLOAD_PRIVATE_MIN || type >= PAYLOAD_PRIVATE_MAX) |
854 |
|
|
printf("\n\t%spayload: %s len: %hu", ike_tab_offset(), |
855 |
|
|
(type < (sizeof pltypes/sizeof pltypes[0]) ? |
856 |
|
|
pltypes[type] : "<unknown>"), this_len); |
857 |
|
|
else |
858 |
|
|
printf("\n\t%spayload: %s len: %hu", ike_tab_offset(), |
859 |
|
|
plprivtypes[type - PAYLOAD_PRIVATE_MIN], this_len); |
860 |
|
|
|
861 |
|
|
if ((type < PAYLOAD_RESERVED_MIN && |
862 |
|
|
(type < sizeof(min_payload_lengths)/sizeof(min_payload_lengths[0]) && |
863 |
|
|
this_len < min_payload_lengths[type])) || |
864 |
|
|
this_len == 0) |
865 |
|
|
goto pltrunc; |
866 |
|
|
|
867 |
|
|
if ((type > PAYLOAD_PRIVATE_MIN && type < PAYLOAD_PRIVATE_MAX && |
868 |
|
|
this_len < min_priv_payload_lengths[type - PAYLOAD_PRIVATE_MIN]) || |
869 |
|
|
this_len == 0) |
870 |
|
|
goto pltrunc; |
871 |
|
|
|
872 |
|
|
if (buf + this_len > snapend) |
873 |
|
|
goto pltrunc; |
874 |
|
|
|
875 |
|
|
ike_tab_level++; |
876 |
|
|
switch (type) { |
877 |
|
|
case PAYLOAD_NONE: |
878 |
|
|
return; |
879 |
|
|
|
880 |
|
|
case PAYLOAD_SA: |
881 |
|
|
ike_pl_sa_print(buf, this_len); |
882 |
|
|
break; |
883 |
|
|
|
884 |
|
|
case PAYLOAD_PROPOSAL: |
885 |
|
|
ike_pl_proposal_print(buf, this_len, doi); |
886 |
|
|
break; |
887 |
|
|
|
888 |
|
|
case PAYLOAD_TRANSFORM: |
889 |
|
|
ike_pl_transform_print(buf, this_len, doi); |
890 |
|
|
break; |
891 |
|
|
|
892 |
|
|
case PAYLOAD_KE: |
893 |
|
|
ike_pl_ke_print(buf, this_len, doi); |
894 |
|
|
break; |
895 |
|
|
|
896 |
|
|
case PAYLOAD_ID: |
897 |
|
|
/* Should only happen with IPsec DOI */ |
898 |
|
|
ipsec_id_print(buf, this_len, doi); |
899 |
|
|
break; |
900 |
|
|
|
901 |
|
|
case PAYLOAD_CERT: |
902 |
|
|
case PAYLOAD_CERTREQUEST: |
903 |
|
|
case PAYLOAD_HASH: |
904 |
|
|
case PAYLOAD_SIG: |
905 |
|
|
case PAYLOAD_NONCE: |
906 |
|
|
break; |
907 |
|
|
|
908 |
|
|
case PAYLOAD_DELETE: |
909 |
|
|
ike_pl_delete_print(buf, this_len); |
910 |
|
|
break; |
911 |
|
|
|
912 |
|
|
case PAYLOAD_NOTIFICATION: |
913 |
|
|
ike_pl_notification_print(buf, this_len); |
914 |
|
|
break; |
915 |
|
|
|
916 |
|
|
case PAYLOAD_VENDOR: |
917 |
|
|
ike_pl_vendor_print(buf, this_len, doi); |
918 |
|
|
break; |
919 |
|
|
|
920 |
|
|
case PAYLOAD_ATTRIBUTE: |
921 |
|
|
ike_pl_attribute_print(buf, this_len); |
922 |
|
|
break; |
923 |
|
|
|
924 |
|
|
case PAYLOAD_SAK: |
925 |
|
|
case PAYLOAD_SAT: |
926 |
|
|
case PAYLOAD_KD: |
927 |
|
|
case PAYLOAD_SEQ: |
928 |
|
|
case PAYLOAD_POP: |
929 |
|
|
case PAYLOAD_NAT_D: |
930 |
|
|
break; |
931 |
|
|
|
932 |
|
|
case PAYLOAD_NAT_OA: |
933 |
|
|
/* RFC3947 NAT-OA uses a subset of the ID payload */ |
934 |
|
|
ipsec_id_print(buf, this_len, doi); |
935 |
|
|
break; |
936 |
|
|
|
937 |
|
|
case PAYLOAD_NAT_D_DRAFT: |
938 |
|
|
break; |
939 |
|
|
|
940 |
|
|
case PAYLOAD_NAT_OA_DRAFT: |
941 |
|
|
ipsec_id_print(buf, this_len, doi); |
942 |
|
|
break; |
943 |
|
|
|
944 |
|
|
default: |
945 |
|
|
break; |
946 |
|
|
} |
947 |
|
|
ike_tab_level--; |
948 |
|
|
|
949 |
|
|
if (next_type) /* Recurse over next payload */ |
950 |
|
|
ike_pl_print(next_type, buf + this_len, doi); |
951 |
|
|
|
952 |
|
|
return; |
953 |
|
|
|
954 |
|
|
pltrunc: |
955 |
|
|
if (doi == ISAKMP_DOI) |
956 |
|
|
fputs(" [|isakmp]", stdout); |
957 |
|
|
else |
958 |
|
|
fputs(" [|ipsec]", stdout); |
959 |
|
|
} |