2 * Routines for the Internet Security Association and Key Management Protocol (ISAKMP)
3 * Brad Robel-Forrest <brad.robel-forrest@watchguard.com>
5 * $Id: packet-isakmp.c,v 1.12 2000/01/07 22:05:31 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@zing.org>
9 * Copyright 1998 Gerald Combs
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 #ifdef HAVE_SYS_TYPES_H
32 # include <sys/types.h>
37 #ifdef HAVE_NETINET_IN_H
38 #include <netinet/in.h>
44 #ifdef NEED_SNPRINTF_H
50 # include "snprintf.h"
53 static int proto_isakmp = -1;
55 static gint ett_isakmp = -1;
56 static gint ett_isakmp_flags = -1;
57 static gint ett_isakmp_payload = -1;
59 #define NUM_PROTO_TYPES 5
60 #define proto2str(t) \
61 ((t < NUM_PROTO_TYPES) ? prototypestr[t] : "UNKNOWN-PROTO-TYPE")
63 static const char *prototypestr[NUM_PROTO_TYPES] = {
71 #define NUM_P1_ATT_TYPES 17
72 #define p1_atttype2str(t) \
73 ((t < NUM_P1_ATT_TYPES) ? p1_atttypestr[t] : "UNKNOWN-ATTRIBUTE-TYPE")
75 static const char *p1_atttypestr[NUM_P1_ATT_TYPES] = {
76 "UNKNOWN-ATTRIBUTE-TYPE",
77 "Encryption-Algorithm",
79 "Authentication-Method",
83 "Group-Generator-One",
84 "Group-Generator-Two",
95 #define NUM_ATT_TYPES 10
96 #define atttype2str(t) \
97 ((t < NUM_ATT_TYPES) ? atttypestr[t] : "UNKNOWN-ATTRIBUTE-TYPE")
99 static const char *atttypestr[NUM_ATT_TYPES] = {
100 "UNKNOWN-ATTRIBUTE-TYPE",
104 "Encapsulation-Mode",
105 "Authentication-Algorithm",
108 "Compress-Dictinary-Size",
109 "Compress-Private-Algorithm"
112 #define NUM_TRANS_TYPES 2
113 #define trans2str(t) \
114 ((t < NUM_TRANS_TYPES) ? transtypestr[t] : "UNKNOWN-TRANS-TYPE")
116 static const char *transtypestr[NUM_TRANS_TYPES] = {
121 #define NUM_AH_TRANS_TYPES 5
122 #define ah_trans2str(t) \
123 ((t < NUM_AH_TRANS_TYPES) ? ah_transtypestr[t] : "UNKNOWN-AH-TRANS-TYPE")
125 static const char *ah_transtypestr[NUM_AH_TRANS_TYPES] = {
133 #define NUM_ESP_TRANS_TYPES 12
134 #define esp_trans2str(t) \
135 ((t < NUM_ESP_TRANS_TYPES) ? esp_transtypestr[t] : "UNKNOWN-ESP-TRANS-TYPE")
137 static const char *esp_transtypestr[NUM_ESP_TRANS_TYPES] = {
152 #define NUM_ID_TYPES 12
154 ((t < NUM_ID_TYPES) ? idtypestr[t] : "UNKNOWN-ID-TYPE")
156 static const char *idtypestr[NUM_ID_TYPES] = {
193 struct proposal_hdr {
200 guint8 num_transforms;
207 guint8 transform_num;
212 #define TRANS_LEN(p) (pntohs(&((struct trans_hdr *)(p))->length))
287 static void dissect_none(const u_char *, int, frame_data *, proto_tree *);
288 static void dissect_sa(const u_char *, int, frame_data *, proto_tree *);
289 static void dissect_proposal(const u_char *, int, frame_data *, proto_tree *);
290 static void dissect_transform(const u_char *, int, frame_data *, proto_tree *,
292 static void dissect_key_exch(const u_char *, int, frame_data *, proto_tree *);
293 static void dissect_id(const u_char *, int, frame_data *, proto_tree *);
294 static void dissect_cert(const u_char *, int, frame_data *, proto_tree *);
295 static void dissect_certreq(const u_char *, int, frame_data *, proto_tree *);
296 static void dissect_hash(const u_char *, int, frame_data *, proto_tree *);
297 static void dissect_sig(const u_char *, int, frame_data *, proto_tree *);
298 static void dissect_nonce(const u_char *, int, frame_data *, proto_tree *);
299 static void dissect_notif(const u_char *, int, frame_data *, proto_tree *);
300 static void dissect_delete(const u_char *, int, frame_data *, proto_tree *);
301 static void dissect_vid(const u_char *, int, frame_data *, proto_tree *);
303 static const char *payloadtype2str(guint8);
304 static const char *exchtype2str(guint8);
305 static const char *doitype2str(guint32);
306 static const char *msgtype2str(guint16);
307 static const char *situation2str(guint32);
308 static const char *value2str(int, guint16, guint16);
309 static const char *num2str(const guint8 *, guint16);
311 #define NUM_LOAD_TYPES 14
312 #define loadtype2str(t) \
313 ((t < NUM_LOAD_TYPES) ? strfuncs[t].str : "Unknown payload type")
314 #define LOAD_TYPE_TRANSFORM 3
316 static struct strfunc {
318 void (*func)(const u_char *, int, frame_data *, proto_tree *);
319 } strfuncs[NUM_LOAD_TYPES] = {
320 {"NONE", dissect_none },
321 {"Security Association", dissect_sa },
322 {"Proposal", dissect_proposal },
323 {"Transform", NULL },
324 {"Key Exchange", dissect_key_exch },
325 {"Identification", dissect_id },
326 {"Certificate", dissect_cert },
327 {"Certificate Request", dissect_certreq },
328 {"Hash", dissect_hash },
329 {"Signature", dissect_sig },
330 {"Nonce", dissect_nonce },
331 {"Notification", dissect_notif },
332 {"Delete", dissect_delete },
333 {"Vendor ID", dissect_vid }
336 void dissect_isakmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
338 struct isakmp_hdr * hdr = (struct isakmp_hdr *)(pd + offset);
341 if (check_col(fd, COL_PROTOCOL))
342 col_add_str(fd, COL_PROTOCOL, "ISAKMP");
344 len = pntohl(&hdr->length);
346 if (check_col(fd, COL_INFO))
347 col_add_fstr(fd, COL_INFO, "%s", exchtype2str(hdr->exch_type));
349 if (IS_DATA_IN_FRAME(offset) && tree) {
351 proto_tree * isakmp_tree;
353 ti = proto_tree_add_item(tree, proto_isakmp, offset, len, NULL);
354 isakmp_tree = proto_item_add_subtree(ti, ett_isakmp);
356 proto_tree_add_text(isakmp_tree, offset, sizeof(hdr->icookie),
358 offset += sizeof(hdr->icookie);
360 proto_tree_add_text(isakmp_tree, offset, sizeof(hdr->rcookie),
362 offset += sizeof(hdr->rcookie);
364 proto_tree_add_text(isakmp_tree, offset, sizeof(hdr->next_payload),
365 "Next payload: %s (%u)",
366 payloadtype2str(hdr->next_payload), hdr->next_payload);
367 offset += sizeof(hdr->next_payload);
369 proto_tree_add_text(isakmp_tree, offset, sizeof(hdr->version),
371 hi_nibble(hdr->version), lo_nibble(hdr->version));
372 offset += sizeof(hdr->version);
374 proto_tree_add_text(isakmp_tree, offset, sizeof(hdr->exch_type),
375 "Exchange type: %s (%u)",
376 exchtype2str(hdr->exch_type), hdr->exch_type);
377 offset += sizeof(hdr->exch_type);
383 fti = proto_tree_add_text(isakmp_tree, offset, sizeof(hdr->flags), "Flags");
384 ftree = proto_item_add_subtree(fti, ett_isakmp_flags);
386 proto_tree_add_text(ftree, offset, 1, "%s",
387 decode_boolean_bitfield(hdr->flags, E_FLAG, sizeof(hdr->flags)*8,
388 "Encryption", "No encryption"));
389 proto_tree_add_text(ftree, offset, 1, "%s",
390 decode_boolean_bitfield(hdr->flags, C_FLAG, sizeof(hdr->flags)*8,
391 "Commit", "No commit"));
392 proto_tree_add_text(ftree, offset, 1, "%s",
393 decode_boolean_bitfield(hdr->flags, A_FLAG, sizeof(hdr->flags)*8,
394 "Authentication", "No authentication"));
395 offset += sizeof(hdr->flags);
398 proto_tree_add_text(isakmp_tree, offset, sizeof(hdr->message_id), "Message ID");
399 offset += sizeof(hdr->message_id);
401 proto_tree_add_text(isakmp_tree, offset, sizeof(hdr->length),
403 offset += sizeof(hdr->length);
405 if (hdr->next_payload < NUM_LOAD_TYPES) {
406 if (hdr->next_payload == LOAD_TYPE_TRANSFORM)
407 dissect_transform(pd, offset, fd, isakmp_tree, 0); /* XXX - protocol ID? */
409 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, isakmp_tree);
412 dissect_data(pd, offset, fd, isakmp_tree);
417 dissect_none(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
421 dissect_sa(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
423 struct sa_hdr * hdr = (struct sa_hdr *)(pd + offset);
424 guint16 length = pntohs(&hdr->length);
425 guint32 doi = pntohl(&hdr->doi);
426 guint32 situation = pntohl(&hdr->situation);
427 proto_item * ti = proto_tree_add_text(tree, offset, length, "Security Association payload");
430 ntree = proto_item_add_subtree(ti, ett_isakmp_payload);
432 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
433 "Next payload: %s (%u)",
434 payloadtype2str(hdr->next_payload), hdr->next_payload);
435 offset += sizeof(hdr->next_payload) * 2;
437 proto_tree_add_text(ntree, offset, sizeof(length),
438 "Length: %u", length);
439 offset += sizeof(length);
441 proto_tree_add_text(ntree, offset, sizeof(doi),
442 "Domain of interpretation: %s (%u)",
443 doitype2str(doi), doi);
444 offset += sizeof(doi);
446 proto_tree_add_text(ntree, offset, sizeof(situation),
447 "Situation: %s (%u)",
448 situation2str(situation), situation);
449 offset += sizeof(situation);
451 dissect_proposal(pd, offset, fd, ntree);
452 offset += (length - sizeof(*hdr));
454 if (hdr->next_payload < NUM_LOAD_TYPES) {
455 if (hdr->next_payload == LOAD_TYPE_TRANSFORM)
456 dissect_transform(pd, offset, fd, tree, 0); /* XXX - protocol ID? */
458 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
461 dissect_data(pd, offset, fd, tree);
465 dissect_proposal(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
467 struct proposal_hdr * hdr = (struct proposal_hdr *)(pd + offset);
468 guint16 length = pntohs(&hdr->length);
469 proto_item * ti = proto_tree_add_text(tree, offset, length, "Proposal payload");
472 int next_hdr_offset = offset + length;
474 ntree = proto_item_add_subtree(ti, ett_isakmp_payload);
476 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
477 "Next payload: %s (%u)",
478 payloadtype2str(hdr->next_payload), hdr->next_payload);
479 offset += sizeof(hdr->next_payload) * 2;
481 proto_tree_add_text(ntree, offset, sizeof(length),
482 "Length: %u", length);
483 offset += sizeof(length);
485 proto_tree_add_text(ntree, offset, sizeof(hdr->proposal_num),
486 "Proposal number: %u", hdr->proposal_num);
487 offset += sizeof(hdr->proposal_num);
489 proto_tree_add_text(ntree, offset, sizeof(hdr->protocol_id),
490 "Protocol ID: %s (%u)",
491 proto2str(hdr->protocol_id), hdr->protocol_id);
492 offset += sizeof(hdr->protocol_id);
494 proto_tree_add_text(ntree, offset, sizeof(hdr->spi_size),
495 "SPI size: %u", hdr->spi_size);
496 offset += sizeof(hdr->spi_size);
498 proto_tree_add_text(ntree, offset, sizeof(hdr->num_transforms),
499 "Number of transforms: %u", hdr->num_transforms);
500 offset += sizeof(hdr->num_transforms);
503 proto_tree_add_text(ntree, offset, hdr->spi_size, "SPI");
504 offset += hdr->spi_size;
507 if (hdr->num_transforms > 0)
508 dissect_transform(pd, offset, fd, ntree, hdr->protocol_id);
510 if (hdr->next_payload < NUM_LOAD_TYPES) {
511 if (hdr->next_payload == LOAD_TYPE_TRANSFORM)
512 dissect_transform(pd, next_hdr_offset, fd, tree, 0); /* XXX - protocol ID? */
514 (*strfuncs[hdr->next_payload].func)(pd, next_hdr_offset, fd, tree);
517 dissect_data(pd, next_hdr_offset, fd, tree);
521 dissect_transform(const u_char *pd, int offset, frame_data *fd,
522 proto_tree *tree, guint8 protocol_id)
525 struct trans_hdr * hdr = (struct trans_hdr *)(pd + offset);
526 guint16 length = pntohs(&hdr->length);
527 proto_item * ti = proto_tree_add_text(tree, offset, length, "Transform payload");
530 ntree = proto_item_add_subtree(ti, ett_isakmp_payload);
532 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
533 "Next payload: %s (%u)",
534 payloadtype2str(hdr->next_payload), hdr->next_payload);
535 offset += sizeof(hdr->next_payload) * 2;
537 proto_tree_add_text(ntree, offset, sizeof(length),
538 "Length: %u", length);
539 offset += sizeof(length);
541 proto_tree_add_text(ntree, offset, sizeof(hdr->transform_num),
542 "Transform number: %u", hdr->transform_num);
543 offset += sizeof(hdr->transform_num);
545 switch (protocol_id) {
548 proto_tree_add_text(ntree, offset, sizeof(hdr->transform_id),
549 "Transform ID: %s (%u)",
550 trans2str(hdr->transform_id), hdr->transform_id);
553 proto_tree_add_text(ntree, offset, sizeof(hdr->transform_id),
554 "Transform ID: %s (%u)",
555 ah_trans2str(hdr->transform_id), hdr->transform_id);
558 proto_tree_add_text(ntree, offset, sizeof(hdr->transform_id),
559 "Transform ID: %s (%u)",
560 esp_trans2str(hdr->transform_id), hdr->transform_id);
563 offset += sizeof(hdr->transform_id) + sizeof(hdr->reserved2);
565 length -= sizeof(*hdr);
567 const char *str = NULL;
569 guint16 type = pntohs(pd + offset) & 0x7fff;
570 guint16 val_len = pntohs(pd + offset + 2);
572 if (protocol_id == 1 && hdr->transform_id == 1) {
574 str = p1_atttype2str(type);
577 str = atttype2str(type);
580 if (pd[offset] & 0xf0) {
581 proto_tree_add_text(ntree, offset, 4,
584 value2str(ike_phase1, type, val_len), val_len);
589 guint16 pack_len = 4 + val_len;
591 proto_tree_add_text(ntree, offset, pack_len,
594 num2str(pd + offset + 4, val_len));
600 if (hdr->next_payload < NUM_LOAD_TYPES) {
601 if (hdr->next_payload == LOAD_TYPE_TRANSFORM)
602 dissect_transform(pd, offset, fd, tree, protocol_id);
604 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
607 dissect_data(pd, offset, fd, tree);
611 dissect_key_exch(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
613 struct ke_hdr * hdr = (struct ke_hdr *)(pd + offset);
614 guint16 length = pntohs(&hdr->length);
615 proto_item * ti = proto_tree_add_text(tree, offset, length, "Key Exchange payload");
618 ntree = proto_item_add_subtree(ti, ett_isakmp_payload);
620 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
621 "Next payload: %s (%u)",
622 payloadtype2str(hdr->next_payload), hdr->next_payload);
623 offset += sizeof(hdr->next_payload) * 2;
625 proto_tree_add_text(ntree, offset, sizeof(length),
626 "Length: %u", length);
627 offset += sizeof(length);
629 proto_tree_add_text(ntree, offset, length - sizeof(*hdr), "Key Exchange Data");
630 offset += (length - sizeof(*hdr));
632 if (hdr->next_payload < NUM_LOAD_TYPES) {
633 if (hdr->next_payload == LOAD_TYPE_TRANSFORM)
634 dissect_transform(pd, offset, fd, tree, 0); /* XXX - protocol ID? */
636 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
639 dissect_data(pd, offset, fd, tree);
643 dissect_id(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
645 struct id_hdr * hdr = (struct id_hdr *)(pd + offset);
646 guint16 length = pntohs(&hdr->length);
647 proto_item * ti = proto_tree_add_text(tree, offset, length, "Identification payload");
650 ntree = proto_item_add_subtree(ti, ett_isakmp_payload);
652 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
653 "Next payload: %s (%u)",
654 payloadtype2str(hdr->next_payload), hdr->next_payload);
655 offset += sizeof(hdr->next_payload) * 2;
657 proto_tree_add_text(ntree, offset, sizeof(length),
658 "Length: %u", length);
659 offset += sizeof(length);
661 proto_tree_add_text(ntree, offset, sizeof(hdr->id_type),
662 "ID type: %s (%u)", id2str(hdr->id_type), hdr->id_type);
663 offset += sizeof(hdr->id_type);
665 proto_tree_add_text(ntree, offset, sizeof(hdr->protocol_id),
666 "Protocol ID: %u", hdr->protocol_id);
667 offset += sizeof(hdr->protocol_id);
669 proto_tree_add_text(ntree, offset, sizeof(hdr->port),
670 "Port: %u", pntohs(&hdr->port));
671 offset += sizeof(hdr->port);
673 switch (hdr->id_type) {
676 proto_tree_add_text(ntree, offset, length-sizeof(*hdr),
677 "Identification data: %s", ip_to_str(pd+offset));
681 proto_tree_add_text(ntree, offset, length-sizeof(*hdr),
682 "Identification data: %s", (char *)(pd+offset));
685 proto_tree_add_text(ntree, offset, length - sizeof(*hdr), "Identification Data");
687 offset += (length - sizeof(*hdr));
689 if (hdr->next_payload < NUM_LOAD_TYPES) {
690 if (hdr->next_payload == LOAD_TYPE_TRANSFORM)
691 dissect_transform(pd, offset, fd, tree, 0); /* XXX - protocol ID? */
693 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
696 dissect_data(pd, offset, fd, tree);
700 dissect_cert(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
702 struct cert_hdr * hdr = (struct cert_hdr *)(pd + offset);
703 guint16 length = pntohs(&hdr->length);
704 proto_item * ti = proto_tree_add_text(tree, offset, length, "Certificate payload");
707 ntree = proto_item_add_subtree(ti, ett_isakmp_payload);
709 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
710 "Next payload: %s (%u)",
711 payloadtype2str(hdr->next_payload), hdr->next_payload);
712 offset += sizeof(hdr->next_payload) * 2;
714 proto_tree_add_text(ntree, offset, sizeof(length),
715 "Length: %u", length);
716 offset += sizeof(length);
718 proto_tree_add_text(ntree, offset, sizeof(hdr->cert_enc),
719 "Certificate encoding: %u", hdr->cert_enc);
720 offset += sizeof(hdr->cert_enc);
722 proto_tree_add_text(ntree, offset, length - sizeof(*hdr), "Certificate Data");
723 offset += (length - sizeof(*hdr));
725 if (hdr->next_payload < NUM_LOAD_TYPES) {
726 if (hdr->next_payload == LOAD_TYPE_TRANSFORM)
727 dissect_transform(pd, offset, fd, tree, 0); /* XXX - protocol ID? */
729 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
732 dissect_data(pd, offset, fd, tree);
736 dissect_certreq(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
738 struct certreq_hdr * hdr = (struct certreq_hdr *)(pd + offset);
739 guint16 length = pntohs(&hdr->length);
740 proto_item * ti = proto_tree_add_text(tree, offset, length, "Certificate Request payload");
743 ntree = proto_item_add_subtree(ti, ett_isakmp_payload);
745 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
746 "Next payload: %s (%u)",
747 payloadtype2str(hdr->next_payload), hdr->next_payload);
748 offset += sizeof(hdr->next_payload) * 2;
750 proto_tree_add_text(ntree, offset, sizeof(length),
751 "Length: %u", length);
752 offset += sizeof(length);
754 proto_tree_add_text(ntree, offset, sizeof(hdr->cert_type),
755 "Certificate type: %u", hdr->cert_type);
756 offset += sizeof(hdr->cert_type);
758 proto_tree_add_text(ntree, offset, length - sizeof(*hdr), "Certificate Authority");
759 offset += (length - sizeof(*hdr));
761 if (hdr->next_payload < NUM_LOAD_TYPES) {
762 if (hdr->next_payload == LOAD_TYPE_TRANSFORM)
763 dissect_transform(pd, offset, fd, tree, 0); /* XXX - protocol ID? */
765 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
768 dissect_data(pd, offset, fd, tree);
772 dissect_hash(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
774 struct hash_hdr * hdr = (struct hash_hdr *)(pd + offset);
775 guint16 length = pntohs(&hdr->length);
776 proto_item * ti = proto_tree_add_text(tree, offset, length, "Hash payload");
779 ntree = proto_item_add_subtree(ti, ett_isakmp_payload);
781 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
782 "Next payload: %s (%u)",
783 payloadtype2str(hdr->next_payload), hdr->next_payload);
784 offset += sizeof(hdr->next_payload) * 2;
786 proto_tree_add_text(ntree, offset, sizeof(length),
787 "Length: %u", length);
788 offset += sizeof(length);
790 proto_tree_add_text(ntree, offset, length - sizeof(*hdr), "Hash Data");
791 offset += (length - sizeof(*hdr));
793 if (hdr->next_payload < NUM_LOAD_TYPES) {
794 if (hdr->next_payload == LOAD_TYPE_TRANSFORM)
795 dissect_transform(pd, offset, fd, tree, 0); /* XXX - protocol ID? */
797 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
800 dissect_data(pd, offset, fd, tree);
804 dissect_sig(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
806 struct sig_hdr * hdr = (struct sig_hdr *)(pd + offset);
807 guint16 length = pntohs(&hdr->length);
808 proto_item * ti = proto_tree_add_text(tree, offset, length, "Signature payload");
811 ntree = proto_item_add_subtree(ti, ett_isakmp_payload);
813 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
814 "Next payload: %s (%u)",
815 payloadtype2str(hdr->next_payload), hdr->next_payload);
816 offset += sizeof(hdr->next_payload) * 2;
818 proto_tree_add_text(ntree, offset, sizeof(length),
819 "Length: %u", length);
820 offset += sizeof(length);
822 proto_tree_add_text(ntree, offset, length - sizeof(*hdr), "Signature Data");
823 offset += (length - sizeof(*hdr));
825 if (hdr->next_payload < NUM_LOAD_TYPES) {
826 if (hdr->next_payload == LOAD_TYPE_TRANSFORM)
827 dissect_transform(pd, offset, fd, tree, 0); /* XXX - protocol ID? */
829 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
832 dissect_data(pd, offset, fd, tree);
836 dissect_nonce(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
838 struct nonce_hdr * hdr = (struct nonce_hdr *)(pd + offset);
839 guint16 length = pntohs(&hdr->length);
840 proto_item * ti = proto_tree_add_text(tree, offset, length, "Nonce payload");
843 ntree = proto_item_add_subtree(ti, ett_isakmp_payload);
845 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
846 "Next payload: %s (%u)",
847 payloadtype2str(hdr->next_payload), hdr->next_payload);
848 offset += sizeof(hdr->next_payload) * 2;
850 proto_tree_add_text(ntree, offset, sizeof(length),
851 "Length: %u", length);
852 offset += sizeof(length);
854 proto_tree_add_text(ntree, offset, length - sizeof(*hdr), "Nonce Data");
855 offset += (length - sizeof(*hdr));
857 if (hdr->next_payload < NUM_LOAD_TYPES) {
858 if (hdr->next_payload == LOAD_TYPE_TRANSFORM)
859 dissect_transform(pd, offset, fd, tree, 0); /* XXX - protocol ID? */
861 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
864 dissect_data(pd, offset, fd, tree);
868 dissect_notif(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
870 struct notif_hdr * hdr = (struct notif_hdr *)(pd + offset);
871 guint16 length = pntohs(&hdr->length);
872 guint32 doi = pntohl(&hdr->doi);
873 guint16 msgtype = pntohs(&hdr->msgtype);
874 proto_item * ti = proto_tree_add_text(tree, offset, length, "Notification payload");
877 ntree = proto_item_add_subtree(ti, ett_isakmp_payload);
879 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
880 "Next payload: %s (%u)",
881 payloadtype2str(hdr->next_payload), hdr->next_payload);
882 offset += sizeof(hdr->next_payload) * 2;
884 proto_tree_add_text(ntree, offset, sizeof(length),
885 "Length: %u", length);
886 offset += sizeof(length);
888 proto_tree_add_text(ntree, offset, sizeof(doi),
889 "Domain of Interpretation: %s (%u)", doitype2str(doi), doi);
890 offset += sizeof(doi);
892 proto_tree_add_text(ntree, offset, sizeof(hdr->protocol_id),
893 "Protocol ID: %s (%u)",
894 proto2str(hdr->protocol_id), hdr->protocol_id);
895 offset += sizeof(hdr->protocol_id);
897 proto_tree_add_text(ntree, offset, sizeof(hdr->spi_size),
898 "SPI size: %u", hdr->spi_size);
899 offset += sizeof(hdr->spi_size);
901 proto_tree_add_text(ntree, offset, sizeof(msgtype),
902 "Message type: %s (%u)", msgtype2str(msgtype), msgtype);
903 offset += sizeof(msgtype);
906 proto_tree_add_text(ntree, offset, hdr->spi_size, "Security Parameter Index");
907 offset += hdr->spi_size;
910 if (length - sizeof(*hdr)) {
911 proto_tree_add_text(ntree, offset, length - sizeof(*hdr) - hdr->spi_size,
912 "Notification Data");
913 offset += (length - sizeof(*hdr) - hdr->spi_size);
916 if (hdr->next_payload < NUM_LOAD_TYPES) {
917 if (hdr->next_payload == LOAD_TYPE_TRANSFORM)
918 dissect_transform(pd, offset, fd, tree, 0); /* XXX - protocol ID? */
920 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
923 dissect_data(pd, offset, fd, tree);
927 dissect_delete(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
929 struct delete_hdr * hdr = (struct delete_hdr *)(pd + offset);
930 guint16 length = pntohs(&hdr->length);
931 guint32 doi = pntohl(&hdr->doi);
932 guint16 num_spis = pntohs(&hdr->num_spis);
933 proto_item * ti = proto_tree_add_text(tree, offset, length, "Delete payload");
937 ntree = proto_item_add_subtree(ti, ett_isakmp_payload);
939 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
940 "Next payload: %s (%u)",
941 payloadtype2str(hdr->next_payload), hdr->next_payload);
942 offset += sizeof(hdr->next_payload) * 2;
944 proto_tree_add_text(ntree, offset, sizeof(length),
945 "Length: %u", length);
946 offset += sizeof(length);
948 proto_tree_add_text(ntree, offset, sizeof(doi),
949 "Domain of Interpretation: %s (%u)", doitype2str(doi), doi);
950 offset += sizeof(doi);
952 proto_tree_add_text(ntree, offset, sizeof(hdr->protocol_id),
953 "Protocol ID: %s (%u)",
954 proto2str(hdr->protocol_id), hdr->protocol_id);
955 offset += sizeof(hdr->protocol_id);
957 proto_tree_add_text(ntree, offset, sizeof(hdr->spi_size),
958 "SPI size: %u", hdr->spi_size);
959 offset += sizeof(hdr->spi_size);
961 proto_tree_add_text(ntree, offset, num_spis,
962 "Number of SPIs: %u", num_spis);
963 offset += sizeof(hdr->num_spis);
965 for (i = 0; i < num_spis; ++i) {
966 proto_tree_add_text(ntree, offset, hdr->spi_size,
968 offset += hdr->spi_size;
971 if (hdr->next_payload < NUM_LOAD_TYPES) {
972 if (hdr->next_payload == LOAD_TYPE_TRANSFORM)
973 dissect_transform(pd, offset, fd, tree, 0); /* XXX - protocol ID? */
975 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
978 dissect_data(pd, offset, fd, tree);
982 dissect_vid(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
984 struct vid_hdr * hdr = (struct vid_hdr *)(pd + offset);
985 guint16 length = pntohs(&hdr->length);
986 proto_item * ti = proto_tree_add_text(tree, offset, length, "Vendor ID payload");
989 ntree = proto_item_add_subtree(ti, ett_isakmp_payload);
991 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
992 "Next payload: %s (%u)",
993 payloadtype2str(hdr->next_payload), hdr->next_payload);
994 offset += sizeof(hdr->next_payload) * 2;
996 proto_tree_add_text(ntree, offset, sizeof(length),
997 "Length: %u", length);
998 offset += sizeof(length);
1000 proto_tree_add_text(ntree, offset, length - sizeof(*hdr), "Vendor ID");
1001 offset += (length - sizeof(*hdr));
1003 if (hdr->next_payload < NUM_LOAD_TYPES) {
1004 if (hdr->next_payload == LOAD_TYPE_TRANSFORM)
1005 dissect_transform(pd, offset, fd, tree, 0); /* XXX - protocol ID? */
1007 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
1010 dissect_data(pd, offset, fd, tree);
1014 payloadtype2str(guint8 type) {
1016 if (type < NUM_LOAD_TYPES) return strfuncs[type].str;
1017 if (type < 128) return "RESERVED";
1018 if (type < 256) return "Private USE";
1020 return "Huh? You should never see this! Shame on you!";
1024 exchtype2str(guint8 type) {
1026 #define NUM_EXCHSTRS 6
1027 static const char * exchstrs[NUM_EXCHSTRS] = {
1030 "Identity Protection (Main Mode)",
1031 "Authentication Only",
1036 if (type < NUM_EXCHSTRS) return exchstrs[type];
1037 if (type < 32) return "ISAKMP Future Use";
1040 return "Quick Mode";
1042 return "New Group Mode";
1044 if (type < 240) return "DOI Specific Use";
1045 if (type < 256) return "Private Use";
1047 return "Huh? You should never see this! Shame on you!";
1051 doitype2str(guint32 type) {
1052 if (type == 1) return "IPSEC";
1053 return "Unknown DOI Type";
1057 msgtype2str(guint16 type) {
1059 #define NUM_PREDEFINED 31
1060 static const char *msgs[NUM_PREDEFINED] = {
1062 "INVALID-PAYLOAD-TYPE",
1063 "DOI-NOT-SUPPORTED",
1064 "SITUATION-NOT-SUPPORTED",
1066 "INVALID-MAJOR-VERSION",
1067 "INVALID-MINOR-VERSION",
1068 "INVALID-EXCHANGE-TYPE",
1070 "INVALID-MESSAGE-ID",
1071 "INVALID-PROTOCOL-ID",
1073 "INVALID-TRANSFORM-ID",
1074 "ATTRIBUTES-NOT-SUPPORTED",
1075 "NO-PROPOSAL-CHOSEN",
1076 "BAD-PROPOSAL-SYNTAX",
1077 "PAYLOAD-MALFORMED",
1078 "INVALID-KEY-INFORMATION",
1079 "INVALID-ID-INFORMATION",
1080 "INVALID-CERT-ENCODING",
1081 "INVALID-CERTIFICATE",
1082 "CERT-TYPE-UNSUPPORTED",
1083 "INVALID-CERT-AUTHORITY",
1084 "INVALID-HASH-INFORMATION",
1085 "AUTHENTICATION-FAILED",
1086 "INVALID-SIGNATURE",
1087 "ADDRESS-NOTIFICATION",
1088 "NOTIFY-SA-LIFETIME",
1089 "CERTIFICATE-UNAVAILABLE",
1090 "UNSUPPORTED-EXCHANGE-TYPE",
1091 "UNEQUAL-PAYLOAD-LENGTHS"
1094 if (type < NUM_PREDEFINED) return msgs[type];
1095 if (type < 8192) return "RESERVED (Future Use)";
1096 if (type < 16384) return "Private Use";
1097 if (type < 16385) return "CONNECTED";
1098 if (type < 24576) return "RESERVED (Future Use) - status";
1099 if (type < 24577) return "RESPONDER-LIFETIME";
1100 if (type < 24578) return "REPLAY-STATUS";
1101 if (type < 24579) return "INITIAL-CONTACT";
1102 if (type < 32768) return "DOI-specific codes";
1103 if (type < 40960) return "Private Use - status";
1104 if (type < 65535) return "RESERVED (Future Use) - status (2)";
1106 return "Huh? You should never see this! Shame on you!";
1110 situation2str(guint32 type) {
1112 #define SIT_MSG_NUM 1024
1113 #define SIT_IDENTITY 0x01
1114 #define SIT_SECRECY 0x02
1115 #define SIT_INTEGRITY 0x04
1117 static char msg[SIT_MSG_NUM];
1121 if (type & SIT_IDENTITY) {
1122 n += snprintf(msg, SIT_MSG_NUM-n, "%sIDENTITY", sep);
1125 if (type & SIT_SECRECY) {
1126 n += snprintf(msg, SIT_MSG_NUM-n, "%sSECRECY", sep);
1129 if (type & SIT_INTEGRITY) {
1130 n += snprintf(msg, SIT_MSG_NUM-n, "%sINTEGRITY", sep);
1138 value2str(int ike_p1, guint16 att_type, guint16 value) {
1140 if (value == 0) return "RESERVED";
1146 case 1: return "Seconds";
1147 case 2: return "Kilobytes";
1148 default: return "UNKNOWN-SA-VALUE";
1151 return "Duration-Value";
1153 return "Group-Value";
1156 case 1: return "Tunnel";
1157 case 2: return "Transport";
1158 default: return "UNKNOWN-ENCAPSULATION-VALUE";
1162 case 1: return "HMAC-MD5";
1163 case 2: return "HMAC-SHA";
1164 case 3: return "DES-MAC";
1165 case 4: return "KPDK";
1166 default: return "UNKNOWN-AUTHENTICATION-VALUE";
1169 return "Key-Length";
1171 return "Key-Rounds";
1174 default: return "UNKNOWN-ATTRIBUTE-TYPE";
1181 case 1: return "DES-CBC";
1182 case 2: return "IDEA-CBC";
1183 case 3: return "BLOWFISH-CBC";
1184 case 4: return "RC5-R16-B64-CBC";
1185 case 5: return "3DES-CBC";
1186 case 6: return "CAST-CBC";
1187 default: return "UNKNOWN-ENCRYPTION-ALG";
1191 case 1: return "MD5";
1192 case 2: return "SHA";
1193 case 3: return "TIGER";
1194 default: return "UNKNOWN-HASH-ALG";
1198 case 1: return "PSK";
1199 case 2: return "DSS-SIG";
1200 case 3: return "RSA-SIG";
1201 case 4: return "RSA-ENC";
1202 case 5: return "RSA-Revised-ENC";
1203 default: return "UNKNOWN-AUTH-METHOD";
1212 return "Group-Value";
1215 case 1: return "MODP";
1216 case 2: return "ECP";
1217 case 3: return "EC2N";
1218 default: return "UNKNOWN-GROUPT-TYPE";
1222 case 1: return "Seconds";
1223 case 2: return "Kilobytes";
1224 default: return "UNKNOWN-SA-VALUE";
1227 return "Duration-Value";
1231 return "Key-Length";
1233 return "Field-Size";
1234 default: return "UNKNOWN-ATTRIBUTE-TYPE";
1240 num2str(const guint8 *pd, guint16 len) {
1242 #define NUMSTR_LEN 1024
1243 static char numstr[NUMSTR_LEN];
1247 snprintf(numstr, NUMSTR_LEN, "%u", *pd);
1250 snprintf(numstr, NUMSTR_LEN, "%u", pntohs(pd));
1253 snprintf(numstr, NUMSTR_LEN, "%u", pntohl(pd) & 0x0fff);
1256 snprintf(numstr, NUMSTR_LEN, "%u", pntohl(pd));
1259 snprintf(numstr, NUMSTR_LEN, "<too big>");
1266 proto_register_isakmp(void)
1268 /* static hf_register_info hf[] = {
1270 { "Name", "isakmp.abbreviation", TYPE, VALS_POINTER }},
1272 static gint *ett[] = {
1275 &ett_isakmp_payload,
1278 proto_isakmp = proto_register_protocol("Internet Security Association and Key Management Protocol", "isakmp");
1279 /* proto_register_field_array(proto_isakmp, hf, array_length(hf));*/
1280 proto_register_subtree_array(ett, array_length(ett));