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.9 1999/09/17 05:56:54 guy Exp $
7 * Ethereal - Network traffic analyzer
8 * By Gerald Combs <gerald@unicom.net>
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 #define NUM_PROTO_TYPES 5
56 #define proto2str(t) \
57 ((t < NUM_PROTO_TYPES) ? prototypestr[t] : "UNKNOWN-PROTO-TYPE")
59 static const char *prototypestr[NUM_PROTO_TYPES] = {
67 #define NUM_ATT_TYPES 13
68 #define atttype2str(t) \
69 ((t < NUM_ATT_TYPES) ? atttypestr[t] : "UNKNOWN-ATTRIBUTE-TYPE")
71 static const char *atttypestr[NUM_ATT_TYPES] = {
72 "UNKNOWN-ATTRIBUTE-TYPE",
77 "Authentication-Algorithm",
80 "Compress-Dictinary-Size",
81 "Compress-Private-Algorithm"
82 "UNKNOWN-ATTRIBUTE-TYPE",
85 "Oakley-Life-Duration"
88 #define NUM_TRANS_TYPES 2
89 #define trans2str(t) \
90 ((t < NUM_TRANS_TYPES) ? transtypestr[t] : "UNKNOWN-TRANS-TYPE")
92 static const char *transtypestr[NUM_TRANS_TYPES] = {
97 #define NUM_ID_TYPES 12
99 ((t < NUM_ID_TYPES) ? idtypestr[t] : "UNKNOWN-ID-TYPE")
101 static const char *idtypestr[NUM_ID_TYPES] = {
138 struct proposal_hdr {
145 guint8 num_transforms;
152 guint8 transform_num;
157 #define TRANS_LEN(p) (pntohs(&((struct trans_hdr *)(p))->length))
232 static void dissect_none(const u_char *, int, frame_data *, proto_tree *);
233 static void dissect_sa(const u_char *, int, frame_data *, proto_tree *);
234 static void dissect_proposal(const u_char *, int, frame_data *, proto_tree *);
235 static void dissect_transform(const u_char *, int, frame_data *, proto_tree *);
236 static void dissect_key_exch(const u_char *, int, frame_data *, proto_tree *);
237 static void dissect_id(const u_char *, int, frame_data *, proto_tree *);
238 static void dissect_cert(const u_char *, int, frame_data *, proto_tree *);
239 static void dissect_certreq(const u_char *, int, frame_data *, proto_tree *);
240 static void dissect_hash(const u_char *, int, frame_data *, proto_tree *);
241 static void dissect_sig(const u_char *, int, frame_data *, proto_tree *);
242 static void dissect_nonce(const u_char *, int, frame_data *, proto_tree *);
243 static void dissect_notif(const u_char *, int, frame_data *, proto_tree *);
244 static void dissect_delete(const u_char *, int, frame_data *, proto_tree *);
245 static void dissect_vid(const u_char *, int, frame_data *, proto_tree *);
247 static const char *payloadtype2str(guint8);
248 static const char *exchtype2str(guint8);
249 static const char *doitype2str(guint32);
250 static const char *msgtype2str(guint16);
251 static const char *situation2str(guint32);
252 static const char *value2str(guint16, guint16);
253 static const char *num2str(const guint8 *, guint16);
255 #define NUM_LOAD_TYPES 14
256 #define loadtype2str(t) \
257 ((t < NUM_LOAD_TYPES) ? strfuncs[t].str : "Unknown payload type")
259 static struct strfunc {
261 void (*func)(const u_char *, int, frame_data *, proto_tree *);
262 } strfuncs[NUM_LOAD_TYPES] = {
263 {"NONE", dissect_none },
264 {"Security Association", dissect_sa },
265 {"Proposal", dissect_proposal },
266 {"Transform", dissect_transform },
267 {"Key Exchange", dissect_key_exch },
268 {"Identification", dissect_id },
269 {"Certificate", dissect_cert },
270 {"Certificate Request", dissect_certreq },
271 {"Hash", dissect_hash },
272 {"Signature", dissect_sig },
273 {"Nonce", dissect_nonce },
274 {"Notification", dissect_notif },
275 {"Delete", dissect_delete },
276 {"Vendor ID", dissect_vid }
279 void dissect_isakmp(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
281 struct isakmp_hdr * hdr = (struct isakmp_hdr *)(pd + offset);
284 if (check_col(fd, COL_PROTOCOL))
285 col_add_str(fd, COL_PROTOCOL, "ISAKMP");
287 len = pntohl(&hdr->length);
289 if (check_col(fd, COL_INFO))
290 col_add_fstr(fd, COL_INFO, "%s", exchtype2str(hdr->exch_type));
292 if (IS_DATA_IN_FRAME(offset) && tree) {
294 proto_tree * isakmp_tree;
296 ti = proto_tree_add_item(tree, proto_isakmp, offset, len, NULL);
297 isakmp_tree = proto_item_add_subtree(ti, ETT_ISAKMP);
299 proto_tree_add_text(isakmp_tree, offset, sizeof(hdr->icookie),
301 offset += sizeof(hdr->icookie);
303 proto_tree_add_text(isakmp_tree, offset, sizeof(hdr->rcookie),
305 offset += sizeof(hdr->rcookie);
307 proto_tree_add_text(isakmp_tree, offset, sizeof(hdr->next_payload),
308 "Next payload: %s (%u)",
309 payloadtype2str(hdr->next_payload), hdr->next_payload);
310 offset += sizeof(hdr->next_payload);
312 proto_tree_add_text(isakmp_tree, offset, sizeof(hdr->version),
314 hi_nibble(hdr->version), lo_nibble(hdr->version));
315 offset += sizeof(hdr->version);
317 proto_tree_add_text(isakmp_tree, offset, sizeof(hdr->exch_type),
318 "Exchange type: %s (%u)",
319 exchtype2str(hdr->exch_type), hdr->exch_type);
320 offset += sizeof(hdr->exch_type);
326 fti = proto_tree_add_text(isakmp_tree, offset, sizeof(hdr->flags), "Flags");
327 ftree = proto_item_add_subtree(fti, ETT_ISAKMP_FLAGS);
329 proto_tree_add_text(ftree, offset, 1, "%s",
330 decode_boolean_bitfield(hdr->flags, E_FLAG, sizeof(hdr->flags)*8,
331 "Encryption", "No encryption"));
332 proto_tree_add_text(ftree, offset, 1, "%s",
333 decode_boolean_bitfield(hdr->flags, C_FLAG, sizeof(hdr->flags)*8,
334 "Commit", "No commit"));
335 proto_tree_add_text(ftree, offset, 1, "%s",
336 decode_boolean_bitfield(hdr->flags, A_FLAG, sizeof(hdr->flags)*8,
337 "Authentication", "No authentication"));
338 offset += sizeof(hdr->flags);
341 proto_tree_add_text(isakmp_tree, offset, sizeof(hdr->message_id), "Message ID");
342 offset += sizeof(hdr->message_id);
344 proto_tree_add_text(isakmp_tree, offset, sizeof(hdr->length),
346 offset += sizeof(hdr->length);
348 if (hdr->next_payload < NUM_LOAD_TYPES)
349 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, isakmp_tree);
351 dissect_data(pd, offset, fd, isakmp_tree);
356 dissect_none(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
360 dissect_sa(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
362 struct sa_hdr * hdr = (struct sa_hdr *)(pd + offset);
363 guint16 length = pntohs(&hdr->length);
364 guint32 doi = pntohl(&hdr->doi);
365 guint32 situation = pntohl(&hdr->situation);
366 proto_item * ti = proto_tree_add_text(tree, offset, length, "Security Association payload");
369 ntree = proto_item_add_subtree(ti, ETT_ISAKMP_PAYLOAD);
371 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
372 "Next payload: %s (%u)",
373 payloadtype2str(hdr->next_payload), hdr->next_payload);
374 offset += sizeof(hdr->next_payload) * 2;
376 proto_tree_add_text(ntree, offset, sizeof(length),
377 "Length: %u", length);
378 offset += sizeof(length);
380 proto_tree_add_text(ntree, offset, sizeof(doi),
381 "Domain of interpretation: %s (%u)",
382 doitype2str(doi), doi);
383 offset += sizeof(doi);
385 proto_tree_add_text(ntree, offset, sizeof(situation),
386 "Situation: %s (%u)",
387 situation2str(situation), situation);
388 offset += sizeof(situation);
390 dissect_proposal(pd, offset, fd, ntree);
391 offset += (length - sizeof(*hdr));
393 if (hdr->next_payload < NUM_LOAD_TYPES)
394 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
396 dissect_data(pd, offset, fd, tree);
400 dissect_proposal(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
402 struct proposal_hdr * hdr = (struct proposal_hdr *)(pd + offset);
403 guint16 length = pntohs(&hdr->length);
404 proto_item * ti = proto_tree_add_text(tree, offset, length, "Proposal payload");
408 ntree = proto_item_add_subtree(ti, ETT_ISAKMP_PAYLOAD);
410 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
411 "Next payload: %s (%u)",
412 payloadtype2str(hdr->next_payload), hdr->next_payload);
413 offset += sizeof(hdr->next_payload) * 2;
415 proto_tree_add_text(ntree, offset, sizeof(length),
416 "Length: %u", length);
417 offset += sizeof(length);
419 proto_tree_add_text(ntree, offset, sizeof(hdr->proposal_num),
420 "Proposal number: %u", hdr->proposal_num);
421 offset += sizeof(hdr->proposal_num);
423 proto_tree_add_text(ntree, offset, sizeof(hdr->protocol_id),
424 "Protocol ID: %s (%u)",
425 proto2str(hdr->protocol_id), hdr->protocol_id);
426 offset += sizeof(hdr->protocol_id);
428 proto_tree_add_text(ntree, offset, sizeof(hdr->spi_size),
429 "SPI size: %u", hdr->spi_size);
430 offset += sizeof(hdr->spi_size);
433 proto_tree_add_text(ntree, offset, hdr->spi_size, "SPI");
434 offset += hdr->spi_size;
437 proto_tree_add_text(ntree, offset, sizeof(hdr->num_transforms),
438 "Number of transforms: %u", hdr->num_transforms);
439 offset += sizeof(hdr->num_transforms);
441 for (i = 0; i < hdr->num_transforms; ++i) {
442 dissect_transform(pd, offset, fd, ntree);
443 offset += TRANS_LEN(pd+offset);
446 if (hdr->next_payload < NUM_LOAD_TYPES)
447 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
449 dissect_data(pd, offset, fd, tree);
453 dissect_transform(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
455 struct trans_hdr * hdr = (struct trans_hdr *)(pd + offset);
456 guint16 length = pntohs(&hdr->length);
457 proto_item * ti = proto_tree_add_text(tree, offset, length, "Transform payload");
460 ntree = proto_item_add_subtree(ti, ETT_ISAKMP_PAYLOAD);
462 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
463 "Next payload: %s (%u)",
464 payloadtype2str(hdr->next_payload), hdr->next_payload);
465 offset += sizeof(hdr->next_payload) * 2;
467 proto_tree_add_text(ntree, offset, sizeof(length),
468 "Length: %u", length);
469 offset += sizeof(length);
471 proto_tree_add_text(ntree, offset, sizeof(hdr->transform_num),
472 "Transform number: %u", hdr->transform_num);
473 offset += sizeof(hdr->transform_num);
475 proto_tree_add_text(ntree, offset, sizeof(hdr->transform_id),
476 "Transform ID: %s (%u)",
477 trans2str(hdr->transform_id), hdr->transform_id);
478 offset += sizeof(hdr->transform_id) + sizeof(hdr->reserved2);
480 length -= sizeof(*hdr);
482 guint16 type = pntohs(pd + offset) & 0x7fff;
483 guint16 val_len = pntohs(pd + offset + 2);
485 if (pd[offset] & 0xf0) {
486 proto_tree_add_text(ntree, offset, 4,
488 atttype2str(type), type,
489 value2str(type, val_len), val_len);
494 guint16 pack_len = 4 + val_len;
496 proto_tree_add_text(ntree, offset, pack_len,
498 atttype2str(type), type,
499 num2str(pd + offset + 4, val_len));
505 if (hdr->next_payload < NUM_LOAD_TYPES)
506 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
508 dissect_data(pd, offset, fd, tree);
512 dissect_key_exch(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
514 struct ke_hdr * hdr = (struct ke_hdr *)(pd + offset);
515 guint16 length = pntohs(&hdr->length);
516 proto_item * ti = proto_tree_add_text(tree, offset, length, "Key Exchange payload");
519 ntree = proto_item_add_subtree(ti, ETT_ISAKMP_PAYLOAD);
521 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
522 "Next payload: %s (%u)",
523 payloadtype2str(hdr->next_payload), hdr->next_payload);
524 offset += sizeof(hdr->next_payload) * 2;
526 proto_tree_add_text(ntree, offset, sizeof(length),
527 "Length: %u", length);
528 offset += sizeof(length);
530 proto_tree_add_text(ntree, offset, length - sizeof(*hdr), "Key Exchange Data");
531 offset += (length - sizeof(*hdr));
533 if (hdr->next_payload < NUM_LOAD_TYPES)
534 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
536 dissect_data(pd, offset, fd, tree);
540 dissect_id(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
542 struct id_hdr * hdr = (struct id_hdr *)(pd + offset);
543 guint16 length = pntohs(&hdr->length);
544 proto_item * ti = proto_tree_add_text(tree, offset, length, "Identification payload");
547 ntree = proto_item_add_subtree(ti, ETT_ISAKMP_PAYLOAD);
549 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
550 "Next payload: %s (%u)",
551 payloadtype2str(hdr->next_payload), hdr->next_payload);
552 offset += sizeof(hdr->next_payload) * 2;
554 proto_tree_add_text(ntree, offset, sizeof(length),
555 "Length: %u", length);
556 offset += sizeof(length);
558 proto_tree_add_text(ntree, offset, sizeof(hdr->id_type),
559 "ID type: %s (%u)", id2str(hdr->id_type), hdr->id_type);
560 offset += sizeof(hdr->id_type);
562 proto_tree_add_text(ntree, offset, sizeof(hdr->protocol_id),
563 "Protocol ID: %u", hdr->protocol_id);
564 offset += sizeof(hdr->protocol_id);
566 proto_tree_add_text(ntree, offset, sizeof(hdr->port),
567 "Port: %u", pntohs(&hdr->port));
568 offset += sizeof(hdr->port);
570 switch (hdr->id_type) {
573 proto_tree_add_text(ntree, offset, length-sizeof(*hdr),
574 "Identification data: %s", ip_to_str(pd+offset));
578 proto_tree_add_text(ntree, offset, length-sizeof(*hdr),
579 "Identification data: %s", (char *)(pd+offset));
582 proto_tree_add_text(ntree, offset, length - sizeof(*hdr), "Identification Data");
584 offset += (length - sizeof(*hdr));
586 if (hdr->next_payload < NUM_LOAD_TYPES)
587 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
589 dissect_data(pd, offset, fd, tree);
593 dissect_cert(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
595 struct cert_hdr * hdr = (struct cert_hdr *)(pd + offset);
596 guint16 length = pntohs(&hdr->length);
597 proto_item * ti = proto_tree_add_text(tree, offset, length, "Certificate payload");
600 ntree = proto_item_add_subtree(ti, ETT_ISAKMP_PAYLOAD);
602 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
603 "Next payload: %s (%u)",
604 payloadtype2str(hdr->next_payload), hdr->next_payload);
605 offset += sizeof(hdr->next_payload) * 2;
607 proto_tree_add_text(ntree, offset, sizeof(length),
608 "Length: %u", length);
609 offset += sizeof(length);
611 proto_tree_add_text(ntree, offset, sizeof(hdr->cert_enc),
612 "Certificate encoding: %u", hdr->cert_enc);
613 offset += sizeof(hdr->cert_enc);
615 proto_tree_add_text(ntree, offset, length - sizeof(*hdr), "Certificate Data");
616 offset += (length - sizeof(*hdr));
618 if (hdr->next_payload < NUM_LOAD_TYPES)
619 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
621 dissect_data(pd, offset, fd, tree);
625 dissect_certreq(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
627 struct certreq_hdr * hdr = (struct certreq_hdr *)(pd + offset);
628 guint16 length = pntohs(&hdr->length);
629 proto_item * ti = proto_tree_add_text(tree, offset, length, "Certificate Request payload");
632 ntree = proto_item_add_subtree(ti, ETT_ISAKMP_PAYLOAD);
634 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
635 "Next payload: %s (%u)",
636 payloadtype2str(hdr->next_payload), hdr->next_payload);
637 offset += sizeof(hdr->next_payload) * 2;
639 proto_tree_add_text(ntree, offset, sizeof(length),
640 "Length: %u", length);
641 offset += sizeof(length);
643 proto_tree_add_text(ntree, offset, sizeof(hdr->cert_type),
644 "Certificate type: %u", hdr->cert_type);
645 offset += sizeof(hdr->cert_type);
647 proto_tree_add_text(ntree, offset, length - sizeof(*hdr), "Certificate Authority");
648 offset += (length - sizeof(*hdr));
650 if (hdr->next_payload < NUM_LOAD_TYPES)
651 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
653 dissect_data(pd, offset, fd, tree);
657 dissect_hash(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
659 struct hash_hdr * hdr = (struct hash_hdr *)(pd + offset);
660 guint16 length = pntohs(&hdr->length);
661 proto_item * ti = proto_tree_add_text(tree, offset, length, "Hash payload");
664 ntree = proto_item_add_subtree(ti, ETT_ISAKMP_PAYLOAD);
666 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
667 "Next payload: %s (%u)",
668 payloadtype2str(hdr->next_payload), hdr->next_payload);
669 offset += sizeof(hdr->next_payload) * 2;
671 proto_tree_add_text(ntree, offset, sizeof(length),
672 "Length: %u", length);
673 offset += sizeof(length);
675 proto_tree_add_text(ntree, offset, length - sizeof(*hdr), "Hash Data");
676 offset += (length - sizeof(*hdr));
678 if (hdr->next_payload < NUM_LOAD_TYPES)
679 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
681 dissect_data(pd, offset, fd, tree);
685 dissect_sig(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
687 struct sig_hdr * hdr = (struct sig_hdr *)(pd + offset);
688 guint16 length = pntohs(&hdr->length);
689 proto_item * ti = proto_tree_add_text(tree, offset, length, "Signature payload");
692 ntree = proto_item_add_subtree(ti, ETT_ISAKMP_PAYLOAD);
694 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
695 "Next payload: %s (%u)",
696 payloadtype2str(hdr->next_payload), hdr->next_payload);
697 offset += sizeof(hdr->next_payload) * 2;
699 proto_tree_add_text(ntree, offset, sizeof(length),
700 "Length: %u", length);
701 offset += sizeof(length);
703 proto_tree_add_text(ntree, offset, length - sizeof(*hdr), "Signature Data");
704 offset += (length - sizeof(*hdr));
706 if (hdr->next_payload < NUM_LOAD_TYPES)
707 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
709 dissect_data(pd, offset, fd, tree);
713 dissect_nonce(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
715 struct nonce_hdr * hdr = (struct nonce_hdr *)(pd + offset);
716 guint16 length = pntohs(&hdr->length);
717 proto_item * ti = proto_tree_add_text(tree, offset, length, "Nonce payload");
720 ntree = proto_item_add_subtree(ti, ETT_ISAKMP_PAYLOAD);
722 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
723 "Next payload: %s (%u)",
724 payloadtype2str(hdr->next_payload), hdr->next_payload);
725 offset += sizeof(hdr->next_payload) * 2;
727 proto_tree_add_text(ntree, offset, sizeof(length),
728 "Length: %u", length);
729 offset += sizeof(length);
731 proto_tree_add_text(ntree, offset, length - sizeof(*hdr), "Nonce Data");
732 offset += (length - sizeof(*hdr));
734 if (hdr->next_payload < NUM_LOAD_TYPES)
735 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
737 dissect_data(pd, offset, fd, tree);
741 dissect_notif(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
743 struct notif_hdr * hdr = (struct notif_hdr *)(pd + offset);
744 guint16 length = pntohs(&hdr->length);
745 guint32 doi = pntohl(&hdr->doi);
746 guint16 msgtype = pntohs(&hdr->msgtype);
747 proto_item * ti = proto_tree_add_text(tree, offset, length, "Notification payload");
750 ntree = proto_item_add_subtree(ti, ETT_ISAKMP_PAYLOAD);
752 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
753 "Next payload: %s (%u)",
754 payloadtype2str(hdr->next_payload), hdr->next_payload);
755 offset += sizeof(hdr->next_payload) * 2;
757 proto_tree_add_text(ntree, offset, sizeof(length),
758 "Length: %u", length);
759 offset += sizeof(length);
761 proto_tree_add_text(ntree, offset, sizeof(doi),
762 "Domain of Interpretation: %s (%u)", doitype2str(doi), doi);
763 offset += sizeof(doi);
765 proto_tree_add_text(ntree, offset, sizeof(hdr->protocol_id),
766 "Protocol ID: %s (%u)",
767 proto2str(hdr->protocol_id), hdr->protocol_id);
768 offset += sizeof(hdr->protocol_id);
770 proto_tree_add_text(ntree, offset, sizeof(hdr->spi_size),
771 "SPI size: %u", hdr->spi_size);
772 offset += sizeof(hdr->spi_size);
774 proto_tree_add_text(ntree, offset, sizeof(msgtype),
775 "Message type: %s (%u)", msgtype2str(msgtype), msgtype);
776 offset += sizeof(msgtype);
779 proto_tree_add_text(ntree, offset, hdr->spi_size, "Security Parameter Index");
780 offset += hdr->spi_size;
783 if (length - sizeof(*hdr)) {
784 proto_tree_add_text(ntree, offset, length - sizeof(*hdr) - hdr->spi_size,
785 "Notification Data");
786 offset += (length - sizeof(*hdr) - hdr->spi_size);
789 if (hdr->next_payload < NUM_LOAD_TYPES)
790 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
792 dissect_data(pd, offset, fd, tree);
796 dissect_delete(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
798 struct delete_hdr * hdr = (struct delete_hdr *)(pd + offset);
799 guint16 length = pntohs(&hdr->length);
800 guint32 doi = pntohl(&hdr->doi);
801 guint16 num_spis = pntohs(&hdr->num_spis);
802 proto_item * ti = proto_tree_add_text(tree, offset, length, "Delete payload");
806 ntree = proto_item_add_subtree(ti, ETT_ISAKMP_PAYLOAD);
808 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
809 "Next payload: %s (%u)",
810 payloadtype2str(hdr->next_payload), hdr->next_payload);
811 offset += sizeof(hdr->next_payload) * 2;
813 proto_tree_add_text(ntree, offset, sizeof(length),
814 "Length: %u", length);
815 offset += sizeof(length);
817 proto_tree_add_text(ntree, offset, sizeof(doi),
818 "Domain of Interpretation: %s (%u)", doitype2str(doi), doi);
819 offset += sizeof(doi);
821 proto_tree_add_text(ntree, offset, sizeof(hdr->protocol_id),
822 "Protocol ID: %s (%u)",
823 proto2str(hdr->protocol_id), hdr->protocol_id);
824 offset += sizeof(hdr->protocol_id);
826 proto_tree_add_text(ntree, offset, sizeof(hdr->spi_size),
827 "SPI size: %u", hdr->spi_size);
828 offset += sizeof(hdr->spi_size);
830 proto_tree_add_text(ntree, offset, num_spis,
831 "Number of SPIs: %u", num_spis);
832 offset += sizeof(hdr->num_spis);
834 for (i = 0; i < num_spis; ++i) {
835 proto_tree_add_text(ntree, offset, hdr->spi_size,
837 offset += hdr->spi_size;
840 if (hdr->next_payload < NUM_LOAD_TYPES)
841 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
843 dissect_data(pd, offset, fd, tree);
847 dissect_vid(const u_char *pd, int offset, frame_data *fd, proto_tree *tree) {
849 struct vid_hdr * hdr = (struct vid_hdr *)(pd + offset);
850 guint16 length = pntohs(&hdr->length);
851 proto_item * ti = proto_tree_add_text(tree, offset, length, "Vendor ID payload");
854 ntree = proto_item_add_subtree(ti, ETT_ISAKMP_PAYLOAD);
856 proto_tree_add_text(ntree, offset, sizeof(hdr->next_payload),
857 "Next payload: %s (%u)",
858 payloadtype2str(hdr->next_payload), hdr->next_payload);
859 offset += sizeof(hdr->next_payload) * 2;
861 proto_tree_add_text(ntree, offset, sizeof(length),
862 "Length: %u", length);
863 offset += sizeof(length);
865 proto_tree_add_text(ntree, offset, length - sizeof(*hdr), "Vendor ID");
866 offset += (length - sizeof(*hdr));
868 if (hdr->next_payload < NUM_LOAD_TYPES)
869 (*strfuncs[hdr->next_payload].func)(pd, offset, fd, tree);
871 dissect_data(pd, offset, fd, tree);
875 payloadtype2str(guint8 type) {
877 if (type < NUM_LOAD_TYPES) return strfuncs[type].str;
878 if (type < 128) return "RESERVED";
879 if (type < 256) return "Private USE";
881 return "Huh? You should never see this! Shame on you!";
885 exchtype2str(guint8 type) {
887 #define NUM_EXCHSTRS 6
888 static const char * exchstrs[NUM_EXCHSTRS] = {
891 "Identity Protection",
892 "Authentication Only",
897 if (type < NUM_EXCHSTRS) return exchstrs[type];
898 if (type < 32) return "ISAKMP Future Use";
899 if (type < 240) return "DOI Specific Use";
900 if (type < 256) return "Private Use";
902 return "Huh? You should never see this! Shame on you!";
906 doitype2str(guint32 type) {
907 if (type == 1) return "IPSEC";
908 return "Unknown DOI Type";
912 msgtype2str(guint16 type) {
914 #define NUM_PREDEFINED 31
915 static const char *msgs[NUM_PREDEFINED] = {
917 "INVALID-PAYLOAD-TYPE",
919 "SITUATION-NOT-SUPPORTED",
921 "INVALID-MAJOR-VERSION",
922 "INVALID-MINOR-VERSION",
923 "INVALID-EXCHANGE-TYPE",
925 "INVALID-MESSAGE-ID",
926 "INVALID-PROTOCOL-ID",
928 "INVALID-TRANSFORM-ID",
929 "ATTRIBUTES-NOT-SUPPORTED",
930 "NO-PROPOSAL-CHOSEN",
931 "BAD-PROPOSAL-SYNTAX",
933 "INVALID-KEY-INFORMATION",
934 "INVALID-ID-INFORMATION",
935 "INVALID-CERT-ENCODING",
936 "INVALID-CERTIFICATE",
937 "CERT-TYPE-UNSUPPORTED",
938 "INVALID-CERT-AUTHORITY",
939 "INVALID-HASH-INFORMATION",
940 "AUTHENTICATION-FAILED",
942 "ADDRESS-NOTIFICATION",
943 "NOTIFY-SA-LIFETIME",
944 "CERTIFICATE-UNAVAILABLE",
945 "UNSUPPORTED-EXCHANGE-TYPE",
946 "UNEQUAL-PAYLOAD-LENGTHS"
949 if (type < NUM_PREDEFINED) return msgs[type];
950 if (type < 8192) return "RESERVED (Future Use)";
951 if (type < 16384) return "Private Use";
952 if (type < 16385) return "CONNECTED";
953 if (type < 24576) return "RESERVED (Future Use) - status";
954 if (type < 24577) return "RESPONDER-LIFETIME";
955 if (type < 24578) return "REPLAY-STATUS";
956 if (type < 24579) return "INITIAL-CONTACT";
957 if (type < 32768) return "DOI-specific codes";
958 if (type < 40960) return "Private Use - status";
959 if (type < 65535) return "RESERVED (Future Use) - status (2)";
961 return "Huh? You should never see this! Shame on you!";
965 situation2str(guint32 type) {
967 #define SIT_MSG_NUM 1024
968 #define SIT_IDENTITY 0x01
969 #define SIT_SECRECY 0x02
970 #define SIT_INTEGRITY 0x04
972 static char msg[SIT_MSG_NUM];
976 if (type & SIT_IDENTITY) {
977 n += snprintf(msg, SIT_MSG_NUM-n, "%sIDENTITY", sep);
980 if (type & SIT_SECRECY) {
981 n += snprintf(msg, SIT_MSG_NUM-n, "%sSECRECY", sep);
984 if (type & SIT_INTEGRITY) {
985 n += snprintf(msg, SIT_MSG_NUM-n, "%sINTEGRITY", sep);
993 value2str(guint16 att_type, guint16 value) {
995 if (value == 0) return "RESERVED";
1001 case 1: return "Seconds";
1002 case 2: return "Kilobytes";
1003 default: return "UNKNOWN-SA-VALUE";
1006 return "Group-Value";
1009 case 1: return "Tunnel";
1010 case 2: return "Transport";
1011 default: return "UNKNOWN-ENCAPSULATION-VALUE";
1015 case 1: return "HMAC-MD5";
1016 case 2: return "HMAC-SHA";
1017 case 3: return "DES-MAC";
1018 case 4: return "KPDK";
1019 default: return "UNKNOWN-AUTHENTICATION-VALUE";
1023 default: return "UNKNOWN-ATTRIBUTE-TYPE";
1028 num2str(const guint8 *pd, guint16 len) {
1030 #define NUMSTR_LEN 1024
1031 static char numstr[NUMSTR_LEN];
1035 snprintf(numstr, NUMSTR_LEN, "%u", *pd);
1038 snprintf(numstr, NUMSTR_LEN, "%u", pntohs(pd));
1041 snprintf(numstr, NUMSTR_LEN, "%u", pntohl(pd) & 0x0fff);
1044 snprintf(numstr, NUMSTR_LEN, "%u", pntohl(pd));
1047 snprintf(numstr, NUMSTR_LEN, "<too big>");
1054 proto_register_isakmp(void)
1056 /* static hf_register_info hf[] = {
1058 { "Name", "isakmp.abbreviation", TYPE, VALS_POINTER }},
1061 proto_isakmp = proto_register_protocol("Internet Security Association and Key Management Protocol", "isakmp");
1062 /* proto_register_field_array(proto_isakmp, hf, array_length(hf));*/