1 /****************************************************************************
2 **
3 ** File: isakmp.c
4 **
5 ** Extensions and additions by: Stuart Stock (stuart@ins.com)
6 ** Original Author: Mike Borella
7 **
8 ** Comments: Dump ISAKMP headers under IPSec DOI
9 **
10 ** See RFC 2408 "Internet Security Association and Key Management Protocol"
11 ** and RFC 2407 "The Internet IP Security Domain Interpretation for ISAKMP"
12 **
13 ** and when you can't find the value anywhere else, look in:
14 ** draft-ietf-ipsec-ike-01 "The Internet Key Exchange (IKE)"
15 **
16 ** $Id: isakmp.c,v 1.11 2007/06/25 13:03:00 farooq-i-azam Exp $
17 **
18 ** This program is free software; you can redistribute it and/or modify
19 ** it under the terms of the GNU General Public License as published by
20 ** the Free Software Foundation; either version 2 of the License, or
21 ** (at your option) any later version.
22 **
23 ** This program is distributed in the hope that it will be useful,
24 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
25 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 ** GNU Library General Public License for more details.
27 **
28 ** You should have received a copy of the GNU General Public License
29 ** along with this program; if not, write to the Free Software
30 ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 **
32 *****************************************************************************/
33
34 #include "isakmp.h"
35 #include "payload.h"
36
37 extern strmap_t ipproto_map[];
38 extern struct arg_t * my_args;
39
40 #define ISAKMP_DOI_IPSEC 1
41
42 /*
43 * Static part of ISAKMP header
44 */
45
46 typedef struct isakmp
47 {
48 char i_cookie[8];
49 char r_cookie[8];
50 #if defined(WORDS_BIGENDIAN)
51 u_int16_t maj_version:4,
52 min_version:4,
53 next_payload:8;
54 #else
55 u_int16_t next_payload:8,
56 min_version:4,
57 maj_version:4;
58 #endif
59 u_int8_t exchange_type;
60 u_int8_t flags;
61 u_int32_t msg_id;
62 u_int32_t length;
63 } isakmp_t;
64
65
66 /*
67 * ISAKMP Generic Payload Header
68 */
69
70 typedef struct isakmpgeneric
71 {
72 u_int8_t next_payload;
73 u_int8_t reserved;
74 u_int16_t length;
75 } isakmpgeneric_t;
76
77 /*
78 * ISAKMP proposal payload (partial)
79 */
80
81 typedef struct isakmpproposal
82 {
83 u_int8_t number;
84 u_int8_t protocol_id;
85 u_int8_t spi_size;
86 u_int8_t num_transforms;
87 } isakmpproposal_t;
88
89
90 /*
91 * ISAKMP transform payload (partial)
92 */
93
94 typedef struct isakmptransform
95 {
96 u_int8_t number;
97 u_int8_t id;
98 u_int16_t reserved;
99 } isakmptransform_t;
100
101 /*
102 * ISAKMP flags
103 */
104
105 #define ISAKMP_FLAG_ENCRYPTION 0x01
106 #define ISAKMP_FLAG_COMMIT 0x02
107 #define ISAKMP_FLAG_AUTHONLY 0x04
108
109 /*
110 * ISAKMP payload types
111 */
112
113 #define ISAKMP_PAYLOAD_NONE 0
114 #define ISAKMP_PAYLOAD_SA 1
115 #define ISAKMP_PAYLOAD_PROPOSAL 2
116 #define ISAKMP_PAYLOAD_TRANSFORM 3
117 #define ISAKMP_PAYLOAD_KEYEXCHANGE 4
118 #define ISAKMP_PAYLOAD_IDENTIFICATION 5
119 #define ISAKMP_PAYLOAD_CERTIFICATE 6
120 #define ISAKMP_PAYLOAD_CERTIFICATEREQ 7
121 #define ISAKMP_PAYLOAD_HASH 8
122 #define ISAKMP_PAYLOAD_SIGNATURE 9
123 #define ISAKMP_PAYLOAD_NONCE 10
124 #define ISAKMP_PAYLOAD_NOTIFICATION 11
125 #define ISAKMP_PAYLOAD_DELETE 12
126 #define ISAKMP_PAYLOAD_VENDORID 13
127
128 /*
129 * ISAKMP payload map
130 */
131
132 strmap_t isakmp_payload_map[] =
133 {
134 { ISAKMP_PAYLOAD_NONE, "none" },
135 { ISAKMP_PAYLOAD_SA, "security association" },
136 { ISAKMP_PAYLOAD_PROPOSAL, "proposal" },
137 { ISAKMP_PAYLOAD_TRANSFORM, "transform" },
138 { ISAKMP_PAYLOAD_KEYEXCHANGE, "key exchange" },
139 { ISAKMP_PAYLOAD_IDENTIFICATION, "identification" },
140 { ISAKMP_PAYLOAD_CERTIFICATE, "certificate" },
141 { ISAKMP_PAYLOAD_CERTIFICATEREQ, "certificate request" },
142 { ISAKMP_PAYLOAD_HASH, "hash" },
143 { ISAKMP_PAYLOAD_SIGNATURE, "signature" },
144 { ISAKMP_PAYLOAD_NONCE, "nonce" },
145 { ISAKMP_PAYLOAD_NOTIFICATION, "notification" },
146 { ISAKMP_PAYLOAD_DELETE, "delete" },
147 { ISAKMP_PAYLOAD_VENDORID, "vendor id" },
148 { 0, "" }
149 };
150
151
152 /*
153 * ISAKMP exchange types
154 */
155
156 #define ISAKMP_EXCHANGE_NONE 0
157 #define ISAKMP_EXCHANGE_BASE 1
158 #define ISAKMP_EXCHANGE_IDPROTECT 2
159 #define ISAKMP_EXCHANGE_AUTHONLY 3
160 #define ISAKMP_EXCHANGE_AGGRESSIVE 4
161 #define ISAKMP_EXCHANGE_INFORMATIONAL 5
162
163 /*
164 * ISAKMP exchange map
165 */
166
167 strmap_t isakmp_exchange_map[] =
168 {
169 { ISAKMP_EXCHANGE_NONE, "none" },
170 { ISAKMP_EXCHANGE_BASE, "base" },
171 { ISAKMP_EXCHANGE_IDPROTECT, "identity protection" },
172 { ISAKMP_EXCHANGE_AUTHONLY, "authentication only" },
173 { ISAKMP_EXCHANGE_AGGRESSIVE, "aggressive" },
174 { ISAKMP_EXCHANGE_INFORMATIONAL, "informational" },
175 { 0, "" }
176 };
177
178
179 /*
180 * Situation definitions for IPSEC DOI
181 */
182
183 #define ISAKMP_SIT_IDENTITYONLY 0x01
184 #define ISAKMP_SIT_SECRECY 0x02
185 #define ISAKMP_SIT_INTEGRITY 0x04
186
187 /*
188 * IPSEC DOI situation map
189 */
190
191 strmap_t isakmp_doisituation_map[] =
192 {
193 { ISAKMP_SIT_IDENTITYONLY, "identity only" },
194 { ISAKMP_SIT_SECRECY, "secrecy" },
195 { ISAKMP_SIT_INTEGRITY, "integrity" },
196 { 0, "" }
197 };
198
199 /*
200 * Protocol ID definitions
201 */
202
203 #define ISAKMP_PROTOCOLID_RESERVED 0
204 #define ISAKMP_PROTOCOLID_ISAKMP 1
205 #define ISAKMP_PROTOCOLID_IPSECAH 2
206 #define ISAKMP_PROTOCOLID_IPSECESP 3
207 #define ISAKMP_PROTOCOLID_IPCOMP 4
208
209 /*
210 * Protocol ID map
211 */
212
213 strmap_t isakmp_protocolid_map[] =
214 {
215 { ISAKMP_PROTOCOLID_RESERVED, "reserved" },
216 { ISAKMP_PROTOCOLID_ISAKMP, "ISAKMP" },
217 { ISAKMP_PROTOCOLID_IPSECAH, "IPSEC AH" },
218 { ISAKMP_PROTOCOLID_IPSECESP, "IPSEC ESP" },
219 { ISAKMP_PROTOCOLID_IPCOMP, "IPCOMP" },
220 { 0, "" }
221 };
222
223 /*
224 * Transform definitions
225 */
226
227 #define ISAKMP_TRANSFORM_RESERVED 0
228 #define ISAKMP_TRANSFORM_KEYIKE 1
229
230 /*
231 * Transform map
232 */
233
234 strmap_t isakmp_transform_map[] =
235 {
236 { ISAKMP_TRANSFORM_RESERVED, "reserved" },
237 { ISAKMP_TRANSFORM_KEYIKE, "KEY_IKE" },
238 { 0, "" }
239 };
240
241 /*
242 * Attribute types
243 */
244
245 #define ISAKMP_ATTR_ENCRALG 1
246 #define ISAKMP_ATTR_HASHALG 2
247 #define ISAKMP_ATTR_AUTHMETHOD 3
248 #define ISAKMP_ATTR_GROUPDESC 4
249 #define ISAKMP_ATTR_GROUPTYPE 5
250 #define ISAKMP_ATTR_GROUPPRIME 6
251 #define ISAKMP_ATTR_GROUPGEN1 7
252 #define ISAKMP_ATTR_GROUPGEN2 8
253 #define ISAKMP_ATTR_GROUPCURVEA 9
254 #define ISAKMP_ATTR_GROUPCURVEB 10
255 #define ISAKMP_ATTR_LIFETYPE 11
256 #define ISAKMP_ATTR_LIFEDURATION 12
257 #define ISAKMP_ATTR_PRF 13
258 #define ISAKMP_ATTR_KEYLENGTH 14
259 #define ISAKMP_ATTR_FIELDSIZE 15
260 #define ISAKMP_ATTR_GROUPORDER 16
261
262 /*
263 * Attribute type map
264 */
265
266 strmap_t isakmp_attr_map[] =
267 {
268 { ISAKMP_ATTR_ENCRALG, "encryption algorithm" },
269 { ISAKMP_ATTR_HASHALG, "hash algorithm" },
270 { ISAKMP_ATTR_AUTHMETHOD, "authentication method" },
271 { ISAKMP_ATTR_GROUPDESC, "group description" },
272 { ISAKMP_ATTR_GROUPTYPE, "group type" },
273 { ISAKMP_ATTR_GROUPPRIME, "group prime" },
274 { ISAKMP_ATTR_GROUPGEN1, "group generator 1" },
275 { ISAKMP_ATTR_GROUPGEN2, "group generator 2" },
276 { ISAKMP_ATTR_GROUPCURVEA, "group curve A" },
277 { ISAKMP_ATTR_GROUPCURVEB, "group curve B" },
278 { ISAKMP_ATTR_LIFETYPE, "life type" },
279 { ISAKMP_ATTR_LIFEDURATION, "life duration" },
280 { ISAKMP_ATTR_PRF, "PRF" },
281 { ISAKMP_ATTR_KEYLENGTH, "key length" },
282 { ISAKMP_ATTR_FIELDSIZE, "field size" },
283 { ISAKMP_ATTR_GROUPORDER, "group order" },
284 { 0, "" }
285 };
286
287 /*
288 * Encryption algorithm attribute types
289 */
290
291 #define ISAKMP_ATTR_ENCRALG_DESCBC 1
292 #define ISAKMP_ATTR_ENCRALG_IDEACBC 2
293 #define ISAKMP_ATTR_ENCRALG_BLOWFISHCBC 3
294 #define ISAKMP_ATTR_ENCRALG_RC5R16B64CBC 4
295 #define ISAKMP_ATTR_ENCRALG_3DESCBC 5
296 #define ISAKMP_ATTR_ENCRALG_CASTCBC 6
297
298 /*
299 * Encryption algorithm attribute map
300 */
301
302 strmap_t isakmp_attr_encralg_map[] =
303 {
304 { ISAKMP_ATTR_ENCRALG_DESCBC, "DES-CBC" },
305 { ISAKMP_ATTR_ENCRALG_IDEACBC, "IDEA-CBC" },
306 { ISAKMP_ATTR_ENCRALG_BLOWFISHCBC, "blowfish-CBC" },
307 { ISAKMP_ATTR_ENCRALG_RC5R16B64CBC, "RC5-R16-B64-CBC" },
308 { ISAKMP_ATTR_ENCRALG_3DESCBC, "3DES-CBC" },
309 { ISAKMP_ATTR_ENCRALG_CASTCBC, "CAST-CBC" },
310 { 0, "" }
311 };
312
313 /*
314 * Hash algorithm attribute types
315 */
316
317 #define ISAKMP_ATTR_HASHALG_MD5 1
318 #define ISAKMP_ATTR_HASHALG_SHA 2
319 #define ISAKMP_ATTR_HASHALG_TIGER 3
320
321 /*
322 * Hash algorithm attribute map
323 */
324
325 strmap_t isakmp_attr_hashalg_map[] =
326 {
327 { ISAKMP_ATTR_HASHALG_MD5, "MD5" },
328 { ISAKMP_ATTR_HASHALG_SHA, "SHA" },
329 { ISAKMP_ATTR_HASHALG_TIGER, "Tiger" },
330 { 0, "" }
331 };
332
333 /*
334 * Authentication method attribute types
335 */
336
337 #define ISAKMP_ATTR_AUTHMETHOD_PRESHAREDKEY 1
338 #define ISAKMP_ATTR_AUTHMETHOD_DSSSIG 2
339 #define ISAKMP_ATTR_AUTHMETHOD_RSASIG 3
340 #define ISAKMP_ATTR_AUTHMETHOD_ENCRRSA 4
341 #define ISAKMP_ATTR_AUTHMETHOD_REVENCRRSA 5
342
343 /*
344 * Authentication method attribute map
345 */
346
347 strmap_t isakmp_attr_authmethod_map[] =
348 {
349 { ISAKMP_ATTR_AUTHMETHOD_PRESHAREDKEY, "pre-shared key" },
350 { ISAKMP_ATTR_AUTHMETHOD_DSSSIG, "DSS signatures" },
351 { ISAKMP_ATTR_AUTHMETHOD_RSASIG, "RSA signatures" },
352 { ISAKMP_ATTR_AUTHMETHOD_ENCRRSA, "encryption with RSA" },
353 { ISAKMP_ATTR_AUTHMETHOD_REVENCRRSA, "revised encryption with RSA" },
354 { 0, "" }
355 };
356
357
358 /*
359 * Group description attribute types
360 */
361
362 #define ISAKMP_ATTR_GROUPDESC_MODP768 1
363 #define ISAKMP_ATTR_GROUPDESC_MODP1024 2
364 #define ISAKMP_ATTR_GROUPDESC_EC2N155 3
365 #define ISAKMP_ATTR_GROUPDESC_EC2N185 4
366
367 /*
368 * Group description attribute map
369 */
370
371 strmap_t isakmp_attr_groupdesc_map[] =
372 {
373 { ISAKMP_ATTR_GROUPDESC_MODP768, "768-bit MODP group" },
374 { ISAKMP_ATTR_GROUPDESC_MODP1024, "1024-bit MODP group" },
375 { ISAKMP_ATTR_GROUPDESC_EC2N155, "EC2N group on GP[2^155]" },
376 { ISAKMP_ATTR_GROUPDESC_EC2N185, "EC2N group on GP[2^185]" },
377 { 0, "" }
378 };
379
380 /*
381 * Group type attribute types
382 */
383
384 #define ISAKMP_ATTR_GROUPTYPE_MODP 1
385 #define ISAKMP_ATTR_GROUPTYPE_ECP 2
386 #define ISAKMP_ATTR_GROUPTYPE_EC2N 3
387
388 /*
389 * Group type attribute map
390 */
391
392 strmap_t isakmp_attr_grouptype_map[] =
393 {
394 { ISAKMP_ATTR_GROUPTYPE_MODP, "modular exponentiation" },
395 { ISAKMP_ATTR_GROUPTYPE_ECP, "elliptical curve over GF[P]" },
396 { ISAKMP_ATTR_GROUPTYPE_EC2N, "elliptical curve over GF[2^N]" },
397 { 0, "" }
398 };
399
400 /*
401 * Life type attribute types
402 */
403
404 #define ISAKMP_ATTR_LIFETYPE_SECONDS 1
405 #define ISAKMP_ATTR_LIFETYPE_KILOBYTES 2
406
407 /*
408 * Life type attribute map
409 */
410
411 strmap_t isakmp_attr_lifetype_map[] =
412 {
413 { ISAKMP_ATTR_LIFETYPE_SECONDS, "seconds" },
414 { ISAKMP_ATTR_LIFETYPE_KILOBYTES, "kilobytes" },
415 { 0, "" }
416 };
417
418 void isakmp_next_payload(packet_t *, u_int8_t);
419
420 /*----------------------------------------------------------------------------
421 **
422 ** dump_isakmp_attributes()
423 **
424 ** Parse an ISAKMP attribute set and interpret it. This is for IKE with
425 ** the IPSEC DOI only!
426 **
427 **----------------------------------------------------------------------------
428 */
429
dump_isakmp_attributes(u_int8_t * attr,int len)430 void dump_isakmp_attributes(u_int8_t *attr, int len)
431 {
432 u_int8_t * p;
433 u_int16_t type;
434 u_int16_t length;
435 u_int8_t * value;
436
437 p = attr;
438
439 while (1)
440 {
441 /* get the type */
442 if (p+2 > attr+len)
443 return;
444 memcpy((void *) &type, (void * ) p, 2);
445 type = ntohs(type);
446 p = p + 2;
447 if (type >= 0x8000)
448 {
449 u_int16_t temp;
450
451 temp = type - 0x8000;
452 display_strmap("Attribute", temp, isakmp_attr_map);
453 }
454 else
455 display_strmap("Attribute", type, isakmp_attr_map);
456
457
458 /* determine whether we have a length field or not */
459 if (type < 0x8000)
460 {
461 /* get length field */
462 if (p+2 > attr+len)
463 return;
464 memcpy((void *) &length, (void *) p, 2);
465 length = ntohs(length);
466 p = p + 2;
467 display(" Length", (u_int8_t *) &length, 2, DISP_DEC);
468 }
469 else
470 length = 2;
471
472 /*
473 * Get the value. Values without a length field should be 2 bytes.
474 * It must say that in some RFC but I just can't find it...
475 */
476
477 if (p+length > attr+len)
478 return;
479 value = my_malloc(length);
480 memcpy((void *) value, (void *) p, length);
481 reverse_byte_order(value, length);
482 p = p + length;
483
484 /* display the value, based on its type */
485 switch(type & 0x7fff)
486 {
487 case ISAKMP_ATTR_ENCRALG:
488 display_strmap(" Value", (u_int16_t) *value,
489 isakmp_attr_encralg_map);
490 break;
491
492 case ISAKMP_ATTR_HASHALG:
493 display_strmap(" Value", (u_int16_t) *value,
494 isakmp_attr_hashalg_map);
495 break;
496
497 case ISAKMP_ATTR_AUTHMETHOD:
498 display_strmap(" Value", (u_int16_t) *value,
499 isakmp_attr_authmethod_map);
500 break;
501
502 case ISAKMP_ATTR_GROUPDESC:
503 display_strmap(" Value", (u_int16_t) *value,
504 isakmp_attr_groupdesc_map);
505 break;
506
507 case ISAKMP_ATTR_GROUPTYPE:
508 display_strmap(" Value", (u_int16_t) *value,
509 isakmp_attr_grouptype_map);
510 break;
511
512 case ISAKMP_ATTR_LIFETYPE:
513 display_strmap(" Value", (u_int16_t) *value,
514 isakmp_attr_lifetype_map);
515 break;
516
517 default:
518 display(" Value", (u_int8_t *) value, length, DISP_DEC);
519 break;
520 }
521
522 my_free(value);
523 }
524 }
525
526 /*----------------------------------------------------------------------------
527 **
528 ** dump_isakmp_transform()
529 **
530 ** Parse ISAKMP transform payload
531 **
532 **----------------------------------------------------------------------------
533 */
534
dump_isakmp_transform(packet_t * pkt)535 void dump_isakmp_transform(packet_t * pkt)
536 {
537 isakmpgeneric_t hdr;
538 isakmptransform_t transform;
539 u_int8_t * sa_attributes = NULL;
540 int sa_attributes_len;
541
542 /* get the generic header */
543 if (get_packet_bytes((u_int8_t *) &hdr, pkt, sizeof(hdr)) == 0)
544 return;
545
546 /* conversions */
547 hdr.length = ntohs(hdr.length);
548
549 if (my_args->m)
550 {
551 /* nothing to do here... */
552 }
553 else
554 {
555 display_header_banner("ISAKMP/IKE transform");
556 display_strmap("Next payload", hdr.next_payload, isakmp_payload_map);
557 display("Reserved", (u_int8_t *) &hdr.reserved, 1, DISP_DEC);
558 display("Payload length", (u_int8_t *) &hdr.length, 2, DISP_DEC);
559 }
560
561 /* Get the fixed transform payload, then the SA attributes field */
562 if (get_packet_bytes((u_int8_t *) &transform, pkt,
563 sizeof(isakmptransform_t)) == 0)
564 return;
565 sa_attributes_len = hdr.length - 8;
566 if (sa_attributes_len > 0)
567 {
568 sa_attributes = (u_int8_t *) my_malloc(sa_attributes_len);
569 if (get_packet_bytes(sa_attributes, pkt, sa_attributes_len) == 0)
570 {
571 my_free(sa_attributes);
572 return;
573 }
574 }
575
576 /* conversion */
577 transform.reserved = ntohs(transform.reserved);
578
579 if (my_args->m)
580 {
581 /* nothing to do here... */
582 }
583 else
584 {
585 display("Transform #", (u_int8_t *) &transform.number, 1, DISP_DEC);
586 display_strmap("Transform ID", transform.id, isakmp_transform_map);
587 display("Reserved", (u_int8_t *) &transform.reserved, 2, DISP_DEC);
588 if (sa_attributes_len > 0)
589 dump_isakmp_attributes(sa_attributes, sa_attributes_len);
590 }
591
592 /* Dump the hex buffer */
593 hexbuffer_flush();
594
595 /* free the sa_attrinutes memory */
596 if (sa_attributes_len > 0)
597 my_free(sa_attributes);
598 }
599
600 /*----------------------------------------------------------------------------
601 **
602 ** dump_isakmp_proposal()
603 **
604 ** Parse ISAKMP proposal payload
605 **
606 **----------------------------------------------------------------------------
607 */
608
dump_isakmp_proposal(packet_t * pkt)609 void dump_isakmp_proposal(packet_t * pkt)
610 {
611 isakmpgeneric_t hdr;
612 isakmpproposal_t proposal;
613 u_int8_t * spi = NULL;
614 int i;
615
616 /* get the generic header */
617 if (get_packet_bytes((u_int8_t *) &hdr, pkt, sizeof(hdr)) == 0)
618 return;
619
620 /* conversions */
621 hdr.length = ntohs(hdr.length);
622
623 if (my_args->m)
624 {
625 /* nothing to do here... */
626 }
627 else
628 {
629 display_header_banner("ISAKMP/IKE proposal");
630 display_strmap("Next payload", hdr.next_payload, isakmp_payload_map);
631 display("Reserved", (u_int8_t *) &hdr.reserved, 1, DISP_DEC);
632 display("Payload length", (u_int8_t *) &hdr.length, 2, DISP_DEC);
633 }
634
635 /* get the proposal, then the SPI */
636 if (get_packet_bytes((u_int8_t *) &proposal, pkt, sizeof(proposal)) == 0)
637 return;
638 if (proposal.spi_size > 0)
639 {
640 spi = my_malloc(proposal.spi_size);
641 if (get_packet_bytes((u_int8_t *) &spi, pkt, proposal.spi_size) == 0)
642 {
643 my_free(spi);
644 return;
645 }
646 }
647
648 if (my_args->m)
649 {
650 /* nothing to do here... */
651 }
652 else
653 {
654 display("Proposal #", (u_int8_t *) &proposal.number, 1, DISP_DEC);
655 display_strmap("Protocol ID", proposal.protocol_id,
656 isakmp_protocolid_map);
657 display("SPI size", (u_int8_t *) &proposal.spi_size, 1, DISP_DEC);
658 display("Number of transforms", (u_int8_t *) &proposal.num_transforms,
659 1, DISP_DEC);
660 if (proposal.spi_size > 0)
661 display("SPI", (u_int8_t *) &spi, proposal.spi_size, DISP_HEX);
662 }
663
664 /* Dump the hex buffer */
665 hexbuffer_flush();
666
667 /* free the spi memory */
668 if (proposal.spi_size > 0)
669 my_free(spi);
670
671 /* Do each of the transform headers */
672 i = 0;
673 while (i < proposal.num_transforms)
674 {
675 dump_isakmp_transform(pkt);
676 i++;
677 }
678
679 }
680
681 /*----------------------------------------------------------------------------
682 **
683 ** dump_isakmp_sa()
684 **
685 ** Parse ISAKMP SA payload
686 **
687 **----------------------------------------------------------------------------
688 */
689
dump_isakmp_sa(packet_t * pkt)690 void dump_isakmp_sa(packet_t * pkt)
691 {
692 isakmpgeneric_t hdr;
693 u_int32_t doi;
694 u_int32_t situation;
695
696 /* get the generic header */
697 if (get_packet_bytes((u_int8_t *) &hdr, pkt, sizeof(hdr)) == 0)
698 return;
699
700 /* conversions */
701 hdr.length = ntohs(hdr.length);
702
703 if (my_args->m)
704 {
705 /* nothing to do here... */
706 }
707 else
708 {
709 display_header_banner("ISAKMP/IKE SA");
710 display_strmap("Next payload", hdr.next_payload, isakmp_payload_map);
711 display("Reserved", (u_int8_t *) &hdr.reserved, 1, DISP_DEC);
712 display("Payload length", (u_int8_t *) &hdr.length, 2, DISP_DEC);
713 }
714
715 /*
716 * The next 4 bytes is the DOI. We need to get it now in order to figure
717 * out what the situation is...
718 */
719
720 if (get_packet_bytes((u_int8_t *) &doi, pkt, 4) == 0)
721 return;
722
723 /* conversion */
724 doi = ntohl(doi);
725
726 if (!my_args->m)
727 display("DOI", (u_int8_t *) &doi, 4, DISP_DEC);
728
729 /* get the situation based on the DOI. The IPSEC DOI situation is 4 bytes */
730 if (doi != ISAKMP_DOI_IPSEC)
731 return;
732 if (get_packet_bytes((u_int8_t *) &situation, pkt, 4) == 0)
733 return;
734
735 /* conversion */
736 situation = ntohl(situation);
737
738 if (!my_args->m)
739 display_strmap("Situation", situation, isakmp_doisituation_map);
740
741
742 /* Dump the hex buffer */
743 hexbuffer_flush();
744
745 /*
746 * Since an SA payload is always followed by a number of
747 * proposal / transform payload sets, we parse then next, automatically,
748 * then we do the given "next payload". How annoying...
749 */
750
751 dump_isakmp_proposal(pkt);
752
753 /* determine the next payload and parse it */
754 isakmp_next_payload(pkt, hdr.next_payload);
755 }
756
757 /*----------------------------------------------------------------------------
758 **
759 ** dump_isakmp_vendorid()
760 **
761 ** Parse ISAKMP vendorid payload
762 **
763 **----------------------------------------------------------------------------
764 */
765
dump_isakmp_vendorid(packet_t * pkt)766 void dump_isakmp_vendorid(packet_t * pkt)
767 {
768 isakmpgeneric_t hdr;
769 u_int8_t * vendorid;
770 int len;
771
772 /* get the generic header */
773 if (get_packet_bytes((u_int8_t *) &hdr, pkt, sizeof(hdr)) == 0)
774 return;
775
776 /* conversions */
777 hdr.length = ntohs(hdr.length);
778
779 if (my_args->m)
780 {
781 /* nothing to do here... */
782 }
783 else
784 {
785 display_header_banner("ISAKMP/IKE vendor ID");
786 display_strmap("Next payload", hdr.next_payload, isakmp_payload_map);
787 display("Reserved", (u_int8_t *) &hdr.reserved, 1, DISP_DEC);
788 display("Payload length", (u_int8_t *) &hdr.length, 2, DISP_DEC);
789 }
790
791 /*
792 * This payload contains a vendor ID hash that is hdr.length - 4 bytes
793 * First allocate memory and grab it
794 */
795
796 len = hdr.length - sizeof(isakmpgeneric_t);
797 vendorid = (u_int8_t *) my_malloc(len);
798 if (get_packet_bytes(vendorid, pkt, len) == 0)
799 {
800 my_free(vendorid);
801 return;
802 }
803
804 display("Vendor ID (hash)", vendorid, len, DISP_HEX_MULTILINE);
805
806 /* free memory */
807 my_free(vendorid);
808
809 /* determine the next payload and parse it */
810 isakmp_next_payload(pkt, hdr.next_payload);
811 }
812
813 /*----------------------------------------------------------------------------
814 **
815 ** dump_isakmp_delete()
816 **
817 ** Parse ISAKMP delete payload
818 **
819 **----------------------------------------------------------------------------
820 */
821
dump_isakmp_delete(packet_t * pkt)822 void dump_isakmp_delete(packet_t * pkt)
823 {
824 isakmpgeneric_t hdr;
825
826 /* get the generic header */
827 if (get_packet_bytes((u_int8_t *) &hdr, pkt, sizeof(hdr)) == 0)
828 return;
829
830 /* conversions */
831 hdr.length = ntohs(hdr.length);
832
833 if (my_args->m)
834 {
835 /* nothing to do here... */
836 }
837 else
838 {
839 display_header_banner("ISAKMP/IKE delete");
840 display_strmap("Next payload", hdr.next_payload, isakmp_payload_map);
841 display("Reserved", (u_int8_t *) &hdr.reserved, 1, DISP_DEC);
842 display("Payload length", (u_int8_t *) &hdr.length, 2, DISP_DEC);
843 }
844
845 }
846
847 /*----------------------------------------------------------------------------
848 **
849 ** isakmp_next_payload()
850 **
851 ** Call the proper payload parser based on the given next payload field
852 **
853 **----------------------------------------------------------------------------
854 */
855
isakmp_next_payload(packet_t * pkt,u_int8_t next)856 void isakmp_next_payload(packet_t * pkt, u_int8_t next)
857 {
858 switch (next)
859 {
860 case ISAKMP_PAYLOAD_DELETE:
861 dump_isakmp_delete(pkt);
862 break;
863
864 case ISAKMP_PAYLOAD_SA:
865 dump_isakmp_sa(pkt);
866 break;
867
868 case ISAKMP_PAYLOAD_VENDORID:
869 dump_isakmp_vendorid(pkt);
870 break;
871
872 default:
873 /* unrecognized payload, so we'll fall through and stop */
874 break;
875 }
876 }
877
878 /*----------------------------------------------------------------------------
879 **
880 ** dump_isakmp()
881 **
882 ** Parse ISAKMP packet and dump fields.
883 **
884 **----------------------------------------------------------------------------
885 */
886
dump_isakmp(packet_t * pkt)887 void dump_isakmp(packet_t * pkt)
888 {
889 isakmp_t isakmp;
890 u_int8_t major;
891 u_int8_t minor;
892 u_int8_t next;
893 u_int8_t e_flag, c_flag, a_flag;
894
895 /* Set the layer */
896 set_layer(LAYER_APPLICATION);
897
898 /*
899 * Get the main ISAKMP header
900 */
901
902 if (get_packet_bytes((u_int8_t *) &isakmp, pkt, sizeof(isakmp_t)) == 0)
903 return;
904
905 /*
906 * Conversions
907 */
908
909 isakmp.msg_id = ntohl(isakmp.msg_id);
910 isakmp.length = ntohl(isakmp.length);
911 next = isakmp.next_payload;
912 major = isakmp.maj_version;
913 minor = isakmp.min_version;
914 e_flag = isakmp.flags & ISAKMP_FLAG_ENCRYPTION;
915 c_flag = isakmp.flags & ISAKMP_FLAG_COMMIT >> 1;
916 a_flag = isakmp.flags & ISAKMP_FLAG_AUTHONLY >> 2;
917
918 /*
919 * Dump header
920 */
921
922 if (my_args->m)
923 {
924 /* do something here */
925 }
926 else
927 {
928 display_header_banner("ISAKMP/IKE Header");
929
930 display("Initiatior cookie", (u_int8_t *) &isakmp.i_cookie, 8, DISP_HEX);
931 display("Responder cookie", (u_int8_t *) &isakmp.r_cookie, 8, DISP_HEX);
932 display_strmap("Next payload", next, isakmp_payload_map);
933 display("Major version", (u_int8_t *) &major, 1, DISP_DEC);
934 display("Minor version", (u_int8_t *) &minor, 1, DISP_DEC);
935 display_strmap("Exchange type", isakmp.exchange_type,
936 isakmp_exchange_map);
937 display("Encryption flag", (u_int8_t *) &e_flag, 1, DISP_DEC);
938 display("Commit flag", (u_int8_t *) &c_flag, 1, DISP_DEC);
939 display("Auth only flag", (u_int8_t *) &a_flag, 1, DISP_DEC);
940 display("Message ID", (u_int8_t *) &isakmp.msg_id, 4, DISP_DEC);
941 display("Length", (u_int8_t *) &isakmp.length, 4, DISP_DEC);
942 }
943
944 /*
945 * Dump the hex buffer
946 */
947
948 hexbuffer_flush();
949
950 /*
951 * Short circuit processing if this is the only header or encryption
952 * bit is set
953 */
954
955 if (next == ISAKMP_PAYLOAD_NONE || e_flag)
956 {
957 return;
958 }
959
960 /* determine the next payload and parse it */
961 isakmp_next_payload(pkt, next);
962
963 }
964