tcpdump mailing list archives

Re: [Patch] Host Identity Protocol


From: Varjonen Samu <samu.varjonen () hiit fi>
Date: Tue, 28 Jul 2009 14:07:07 +0200

Hi,

Sorry, it took so long from me to get this work forward. First an answer for the question below. Should this be compiled in without INET6. The answer is no. Patch is fixed accordingly. I was also presented another question/comment on hex printing 64 bit values. Patch included is now using up to date code for printing.

Now I ask you "tcpdump-workers" to review the code and give comments.

How about including this code to tcpdump? I am happy to improve it based on comments.

BR,
Samu

Samu Varjonen wrote:
Hi,

Sorry for delayd answer. I will look into your suggestions/commnents and revise the patch accordingly as soon as possible and I'll resend the patch to the list.

Guy Harris kirjoitti:

On Jul 10, 2009, at 2:16 AM, Varjonen Samu wrote:

diff -N -r -u --strip-trailing-cr tcpdump-orig/configure.in tcpdump/configure.in
--- tcpdump-orig/configure.in    2009-05-20 11:29:46.000000000 +0300
+++ tcpdump/configure.in    2009-05-17 13:13:13.000000000 +0300
@@ -158,7 +158,7 @@
  --disable-ipv6          disable ipv6 support],
[ case "$enableval" in
yes)   AC_MSG_RESULT(yes)
- LOCALSRC="print-ip6.c print-ip6opts.c print-mobility.c print-ripng.c print-icmp6.c print-frag6.c print-rt6.c print-ospf6.c print-dhcp6.c $LOCALSRC" + LOCALSRC="print-ip6.c print-ip6opts.c print-mobility.c print-ripng.c print-icmp6.c print-frag6.c print-rt6.c print-ospf6.c print-dhcp6.c print-hip.c $LOCALSRC"
       AC_DEFINE(INET6)
       ipv6=yes
       ;;
diff -N -r -u --strip-trailing-cr tcpdump-orig/interface.h tcpdump/interface.h
--- tcpdump-orig/interface.h    2009-05-20 11:29:46.000000000 +0300
+++ tcpdump/interface.h    2009-05-17 13:15:00.000000000 +0300
@@ -336,6 +336,7 @@
extern int rt6_print(const u_char *, const u_char *);
extern void ospf6_print(const u_char *, u_int);
extern void dhcp6_print(const u_char *, u_int);
+extern void hip_print(const u_char *, u_int);
#endif /*INET6*/
extern u_short in_cksum(const u_short *, register u_int, int);
extern u_int16_t in_cksum_shouldbe(u_int16_t, u_int16_t);

Those seem to imply this is IPv6-only, but:

diff -N -r -u --strip-trailing-cr tcpdump-orig/print-ip.c tcpdump/print-ip.c
--- tcpdump-orig/print-ip.c    2009-05-20 11:29:46.000000000 +0300
+++ tcpdump/print-ip.c    2009-05-18 20:09:48.000000000 +0300
@@ -519,6 +519,10 @@
        pgm_print(ipds->cp, ipds->len, (const u_char *)ipds->ip);
        break;

+        case IPPROTO_HIP:
+        hip_print(ipds->cp, ipds->len);
+        break;
+
    default:
        if ((proto = getprotobynumber(ipds->nh)) != NULL)
            ND_PRINT((ndo, " %s", proto->p_name));

that doesn't. Should this be compiled in if INET6 isn't defined (i.e., if this is a version of tcpdump that doesn't support IPv6)?
-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.



diff -N -r -u --strip-trailing-cr tcpdump-orig/configure.in tcpdump/configure.in
--- tcpdump-orig/configure.in   2009-05-20 10:29:46.000000000 +0200
+++ tcpdump/configure.in        2009-05-17 12:13:13.000000000 +0200
@@ -158,7 +158,7 @@
   --disable-ipv6          disable ipv6 support],
 [ case "$enableval" in
 yes)   AC_MSG_RESULT(yes)
-       LOCALSRC="print-ip6.c print-ip6opts.c print-mobility.c print-ripng.c print-icmp6.c print-frag6.c print-rt6.c 
print-ospf6.c print-dhcp6.c $LOCALSRC"
+       LOCALSRC="print-ip6.c print-ip6opts.c print-mobility.c print-ripng.c print-icmp6.c print-frag6.c print-rt6.c 
print-ospf6.c print-dhcp6.c print-hip.c $LOCALSRC"
        AC_DEFINE(INET6)
        ipv6=yes
        ;;
diff -N -r -u --strip-trailing-cr tcpdump-orig/interface.h tcpdump/interface.h
--- tcpdump-orig/interface.h    2009-05-20 10:29:46.000000000 +0200
+++ tcpdump/interface.h 2009-05-17 12:15:00.000000000 +0200
@@ -336,6 +336,7 @@
 extern int rt6_print(const u_char *, const u_char *);
 extern void ospf6_print(const u_char *, u_int);
 extern void dhcp6_print(const u_char *, u_int);
+extern void hip_print(const u_char *, u_int);
 #endif /*INET6*/
 extern u_short in_cksum(const u_short *, register u_int, int);
 extern u_int16_t in_cksum_shouldbe(u_int16_t, u_int16_t);
diff -N -r -u --strip-trailing-cr tcpdump-orig/ipproto.c tcpdump/ipproto.c
--- tcpdump-orig/ipproto.c      2009-05-20 10:29:46.000000000 +0200
+++ tcpdump/ipproto.c   2009-05-18 18:56:10.000000000 +0200
@@ -55,6 +55,7 @@
     { IPPROTO_PGM, "PGM" },
     { IPPROTO_SCTP, "SCTP" },
     { IPPROTO_MOBILITY, "Mobility" },
+    { IPPROTO_HIP, "HIP" },
     { 0, NULL }
 };
 
diff -N -r -u --strip-trailing-cr tcpdump-orig/ipproto.h tcpdump/ipproto.h
--- tcpdump-orig/ipproto.h      2009-05-20 10:29:46.000000000 +0200
+++ tcpdump/ipproto.h   2009-05-17 12:33:07.000000000 +0200
@@ -142,3 +142,6 @@
 #ifndef IPPROTO_MOBILITY
 #define IPPROTO_MOBILITY       135
 #endif
+#ifndef IPPROTO_HIP
+#define IPPROTO_HIP            139
+#endif
diff -N -r -u --strip-trailing-cr tcpdump-orig/Makefile.in tcpdump/Makefile.in
--- tcpdump-orig/Makefile.in    2009-05-20 10:29:46.000000000 +0200
+++ tcpdump/Makefile.in 2009-05-17 12:20:28.000000000 +0200
@@ -76,7 +76,7 @@
        print-domain.c print-dtp.c print-dvmrp.c print-enc.c print-egp.c \
        print-eap.c print-eigrp.c\
        print-esp.c print-ether.c print-fddi.c print-fr.c \
-       print-gre.c print-hsrp.c print-icmp.c print-igmp.c \
+       print-gre.c print-hip.c print-hsrp.c print-icmp.c print-igmp.c \
        print-igrp.c print-ip.c print-ipcomp.c print-ipfc.c \
        print-ipx.c print-isoclns.c print-juniper.c print-krb.c \
        print-l2tp.c print-lane.c print-ldp.c print-lldp.c print-llc.c \
diff -N -r -u --strip-trailing-cr tcpdump-orig/print-hip.c tcpdump/print-hip.c
--- tcpdump-orig/print-hip.c    1970-01-01 01:00:00.000000000 +0100
+++ tcpdump/print-hip.c 2009-07-28 00:47:40.000000000 +0200
@@ -0,0 +1,1389 @@
+/*
+ * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994
+ *     The Regents of the University of California.  All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that: (1) source code distributions
+ * retain the above copyright notice and this paragraph in its entirety, (2)
+ * distributions including binary code include the above copyright notice and
+ * this paragraph in its entirety in the documentation or other materials
+ * provided with the distribution, and (3) all advertising materials mentioning
+ * features or use of this software display the following acknowledgement:
+ * ``This product includes software developed by the University of California,
+ * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
+ * the University nor the names of its contributors may be used to endorse
+ * or promote products derived from this software without specific prior
+ * written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Support for dissecting Host Identity Protocol (HIP)
+ * RFCs 5201 - 5206, draft-ietf-hip-cert-00, draft-ietf-hip-nat-traversal-06
+ * 
+ * Author: Samu Varjonen <samu.varjonen () hiit fi>
+ * based on patch created by
+ *   Mika Kousa <mika.kousa () iki fi>
+ *   Kristian Slavov <kslavov () piuha net>  
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <sys/param.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <netinet/in.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+#include <tcpdump-stdinc.h>
+
+#include "interface.h"
+#include "extract.h"
+#include "addrtoname.h"
+
+#define HIP_HI_DSA                                 3
+#define HIP_HI_RSA                                 5
+
+/* RFC 5201 */
+#define        HIP_I1                              1
+#define        HIP_R1                              2
+#define        HIP_I2                              3
+#define        HIP_R2                              4
+#define        HIP_UPDATE                          16
+#define        HIP_NOTIFY                          17 
+#define        HIP_CLOSE                           18 
+#define        HIP_CLOSE_ACK                       19 
+
+/* RFC 5202 */
+#define       HIP_ESP_RESERVED                     0
+#define       HIP_ESP_AES_SHA1                     1
+#define       HIP_ESP_3DES_SHA1                    2
+#define       HIP_ESP_3DES_MD5                     3
+#define       HIP_ESP_BLOWFISH_SHA1                4
+#define       HIP_ESP_NULL_SHA1                    5
+#define       HIP_ESP_NULL_MD5                     6
+
+/* RFC 5201 */
+#define       HIP_DH_RESERVED                      0 
+#define       HIP_DH_384                           1
+#define       HIP_DH_OAKLEY_1                      2
+#define       HIP_DH_OAKLEY_5                      3
+#define       HIP_DH_OAKLEY_15                     4
+#define       HIP_DH_OAKLEY_17                     5
+#define       HIP_DH_OAKLEY_18                     6
+
+/**/
+#define       HIP_NAT_TRAVERSAL_MODE_RESERVED      0
+#define       HIP_NAT_TRAVERSAL_MODE_UDP           1
+#define       HIP_NAT_TRAVERSAL_MODE_ICE_STUN_UDP  2
+
+/* HIP TLV parameters listed in order of RFCs */
+
+/* RFC 5201 */
+#define HIP_PARAM_R1_COUNTER                       128
+#define HIP_PARAM_PUZZLE                           257
+#define HIP_PARAM_SOLUTION                         321
+#define HIP_PARAM_SEQ                              385
+#define HIP_PARAM_ACK                              449
+#define HIP_PARAM_DIFFIE_HELLMAN                   513
+#define HIP_PARAM_HIP_TRANSFORM                    577
+#define HIP_PARAM_ENCRYPTED                        641
+#define HIP_PARAM_HOST_ID                          705
+/* Type number defined in RFC 5201 contents 
+   in draft-ietf-hip-cert-00 */
+#define HIP_PARAM_CERT                             768
+#define HIP_PARAM_NOTIFICATION                     832
+#define HIP_PARAM_ECHO_REQUEST_SIGNED              897
+#define HIP_PARAM_ECHO_RESPONSE_SIGNED             961
+#define HIP_PARAM_HMAC                             61505
+#define HIP_PARAM_HMAC_2                           61569
+#define HIP_PARAM_HIP_SIGNATURE_2                  61633
+#define HIP_PARAM_HIP_SIGNATURE                    61697
+#define HIP_PARAM_ECHO_REQUEST_UNSIGNED            63661
+#define HIP_PARAM_ECHO_RESPONSE_UNSIGNED           63425
+/* RFC 5202 */
+#define HIP_PARAM_ESP_INFO                         65
+#define HIP_PARAM_ESP_TRANSFORM                    4095
+/* RFC 5203 */
+#define HIP_PARAM_REG_INFO                         930
+#define HIP_PARAM_REG_REQUEST                      932
+#define HIP_PARAM_REG_RESPONSE                     934
+#define HIP_PARAM_REG_FAILED                       936
+/* RFC 5204 */
+#define HIP_PARAM_FROM                             65498
+#define HIP_PARAM_RVS_HMAC                         65500
+#define HIP_PARAM_VIA_RVS                          65502
+/* RFC 5206 */
+#define HIP_PARAM_LOCATOR                          193
+/* draft-ietf-hip-nat-raversal-06.txt */
+#define HIP_PARAM_NAT_TRAVERSAL_MODE               608
+#define HIP_PARAM_TRANSACTION_PACING               610
+#define HIP_PARAM_REG_FROM                         950
+#define HIP_PARAM_RELAY_FROM                       63998
+#define HIP_PARAM_RELAY_TO                         64002
+
+/* Bit masks */
+#define HIP_PARAM_CRITICAL_BIT                    0x0001
+/* See RFC 5201 section 5.1 */
+#define HIP_PACKET_TYPE_MASK                      0x7F
+/* draft-ietf-shim6-proto-12 see section 5.3 */
+#define HIP_SHIM6_FIXED_BIT_P_MASK                0x80
+#define HIP_SHIM6_FIXED_BIT_S_MASK                0x01
+/* 00001110 Excluding the shim6 compatibility bit */
+#define HIP_RESERVED_MASK                         0x0E 
+#define HIP_VERSION_MASK                          0xF0
+#define HIP_CONTROL_A_MASK                        0x0001
+#define HIP_CONTROL_C_MASK                        0x0002
+
+#define HI_HDR_FLAGS_MASK                         0xFFFF0000
+#define HI_HDR_PROTO_MASK                         0x0000FF00
+#define HI_HDR_ALG_MASK                           0x000000FF
+
+#define HIP_LOCATOR_RESERVED_MASK                 0xFE
+#define HIP_LOCATOR_PREFERRED_MASK                0x01
+
+#define HIP_TRANSFORM_HIP_MAX                     6
+#define HIP_TRANSFORM_ESP_MAX                     6
+#define HIP_NAT_TRAVERSAL_MODE_MAX                6
+#define HIP_MAX_PACKET                            2048
+#define HIP_PUZZLE_OPAQUE_LEN                     2
+
+#define HIP_AH_SHA_LEN                            20
+
+typedef uint16_t hip_tlv_type_t;
+typedef uint16_t hip_tlv_len_t;
+
+/* Returns length of TLV option (contents) with padding. */
+#define HIP_LEN_PAD(len) \
+    ((((len) & 0x07) == 0) ? (len) : ((((len) >> 3) << 3) + 8))
+
+/* Structs */
+struct hip_common {
+        uint8_t payload_proto;
+        uint8_t payload_len;
+        uint8_t type_hdr;
+        uint8_t ver_res;
+
+        uint16_t checksum;
+        uint16_t control;
+
+        struct in6_addr hits;  /* Sender HIT   */
+        struct in6_addr hitr;  /* Receiver HIT */
+} __attribute__ ((packed));
+
+struct hip_tlv_common {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+} __attribute__ ((packed));
+
+struct hip_r1_counter {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+
+        uint32_t reserved;
+        uint64_t generation;
+} __attribute__ ((packed));
+
+struct hip_puzzle {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+
+        uint8_t K;
+        uint8_t lifetime;
+        uint8_t opaque[HIP_PUZZLE_OPAQUE_LEN];
+        uint64_t I;
+} __attribute__ ((packed));
+
+struct hip_solution {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+
+        uint8_t K;
+        uint8_t reserved;
+        uint8_t opaque[HIP_PUZZLE_OPAQUE_LEN];
+        uint64_t I;
+        uint64_t J;
+} __attribute__ ((packed));
+
+struct hip_seq {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+
+        uint32_t update_id;
+} __attribute__ ((packed));
+
+struct hip_ack {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+
+        uint32_t peer_update_id; /* n items */
+} __attribute__ ((packed));
+
+struct hip_diffie_hellman {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+
+        uint8_t group_id;  
+        /* fixed part ends */
+        uint8_t public_value[0];
+} __attribute__ ((packed));
+
+typedef uint16_t hip_transform_suite_t;
+
+struct hip_hip_transform {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+
+        hip_transform_suite_t suite_id[HIP_TRANSFORM_HIP_MAX];
+} __attribute__ ((packed));
+
+struct hip_encrypted_aes_sha1 {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+
+        uint32_t reserved;
+        uint8_t iv[16];
+        /* fixed part ends */
+} __attribute__ ((packed));
+
+struct hip_encrypted_3des_sha1 {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+
+        uint32_t reserved;
+        uint8_t iv[8];
+        /* fixed part ends */
+} __attribute__ ((packed));
+
+struct hip_encrypted_null_sha1 {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+
+        uint32_t reserved;
+        /* fixed part ends */
+} __attribute__ ((packed));
+
+struct hip_host_id_key_rdata {
+        uint16_t flags;
+        uint8_t protocol;
+        uint8_t algorithm;
+
+        /* fixed part ends */
+} __attribute__ ((packed));
+
+struct hip_host_id {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+
+        uint16_t hi_length;
+        uint16_t di_type_length;
+
+        struct hip_host_id_key_rdata rdata;
+        /* fixed part ends */
+} __attribute__ ((packed));
+
+struct hip_cert {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+
+       uint8_t  cert_group;
+        uint8_t  cert_count;
+        uint8_t  cert_id;
+        uint8_t  cert_type;
+        /* end of fixed part */
+} __attribute__ ((packed));
+
+struct hip_notification {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+
+        uint16_t reserved;
+        uint16_t msgtype;
+        /* end of fixed part */
+} __attribute__ ((packed));
+
+struct hip_echo_request { 
+        hip_tlv_type_t type;
+        hip_tlv_len_t  length;
+        /* opaque */
+} __attribute__ ((packed));
+
+struct hip_echo_response {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+        /* opaque */
+} __attribute__ ((packed));
+
+struct hip_hmac {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+
+        uint8_t hmac_data[HIP_AH_SHA_LEN];
+} __attribute__ ((packed));
+
+/* HMAC2 is the same as above */
+
+/* HIP SIGNATURE2 is the same as below */
+
+struct hip_signature {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+
+        uint8_t algorithm;
+        uint8_t signature[0]; /* variable length */
+        /* fixed part end */
+} __attribute__ ((packed));
+
+/* HIP_ECHO_REQUEST_UNSIGNED same as signed version above */
+
+/* HIP_ECHO_RESPONSE_UNSIGNED same as signed version above */
+
+struct hip_esp_info {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+
+        uint16_t reserved;
+        uint16_t keymat_index;
+        uint32_t old_spi;
+        uint32_t new_spi;
+} __attribute__ ((packed));
+
+struct hip_esp_transform {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+
+        uint16_t reserved;
+
+        hip_transform_suite_t suite_id[HIP_TRANSFORM_ESP_MAX];
+} __attribute__ ((packed));
+
+struct hip_reg_info {
+        hip_tlv_type_t type;
+        hip_tlv_len_t  length;
+
+       uint8_t min_lifetime;
+       uint8_t max_lifetime;
+
+       uint8_t reg_type[0]; /* Variable */
+} __attribute__ ((packed));
+
+struct hip_reg_request_response {
+        hip_tlv_type_t type;
+        hip_tlv_len_t  length;
+
+       uint8_t lifetime;
+       uint8_t reg_type[0]; /* Variable */        
+} __attribute__ ((packed));
+
+/* REG_REQUEST is exactly like RESPONSE see above */
+
+struct hip_reg_failed {
+        hip_tlv_type_t type;
+        hip_tlv_len_t  length;
+
+       uint8_t failure_type;
+       uint8_t reg_type[0]; /* Variable */
+} __attribute__ ((packed));
+
+struct hip_from {
+        hip_tlv_type_t type;
+        hip_tlv_len_t  length;
+        uint8_t address[16];
+} __attribute__ ((packed));
+
+struct hip_rvs_hmac {
+        hip_tlv_type_t type;
+        hip_tlv_len_t  length;
+        uint8_t hmac_data[HIP_AH_SHA_LEN];
+} __attribute__ ((packed));
+
+struct hip_via_rvs {
+        hip_tlv_type_t type;
+        hip_tlv_len_t  length;
+        uint8_t address[16];
+        /* the rest of the addresses */
+} __attribute__ ((packed));
+
+/* Type 0 and 1 */
+struct hip_locator_info_addr_item {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+        uint8_t traffic_type;
+        uint8_t locator_type;
+        uint8_t locator_length;
+        uint8_t reserved;
+        uint32_t lifetime;
+        /* end of fixed part - locator of arbitrary length follows but 
+           currently support only IPv6 */
+        uint8_t locator[16];
+}  __attribute__ ((packed));
+
+/* Type 2 */
+struct hip_locator_info_addr_item2 {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+        uint8_t traffic_type;
+        uint8_t locator_type;
+        uint8_t locator_length;
+        uint8_t reserved;
+        uint32_t lifetime;
+       uint16_t transport_port;
+       uint8_t transport_protocol;
+       uint8_t kind;
+       uint32_t priority;
+       uint32_t spi;
+        /* end of fixed part - locator of arbitrary length follows but 
+           currently support only IPv6 */
+        uint8_t locator[16];
+}  __attribute__ ((packed));
+
+struct hip_nat_traversal_mode {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+
+        uint16_t reserved;
+
+        hip_transform_suite_t suite_id[HIP_NAT_TRAVERSAL_MODE_MAX];
+} __attribute__ ((packed));
+
+struct hip_transaction_pacing {
+        hip_tlv_type_t type;
+        hip_tlv_len_t length;
+
+       uint32_t min_ta;
+} __attribute__ ((packed));
+
+struct hip_reg_from {
+        hip_tlv_type_t type;
+        hip_tlv_len_t  length;
+
+       uint16_t port;
+       uint8_t protocol;
+       uint8_t reserved;
+        uint8_t address[16];
+} __attribute__ ((packed));
+
+struct hip_relay_from {
+        hip_tlv_type_t type;
+        hip_tlv_len_t  length;
+
+       uint16_t port;
+       uint8_t protocol;
+       uint8_t reserved;
+        uint8_t address[16];
+} __attribute__ ((packed));
+
+struct hip_relay_to {
+        hip_tlv_type_t type;
+        hip_tlv_len_t  length;
+
+       uint16_t port;
+       uint8_t protocol;
+       uint8_t reserved;
+        uint8_t address[16];
+} __attribute__ ((packed));
+
+/*******************************************************************************
+* Token arrays                                                                 *
+*******************************************************************************/
+
+static struct tok hip_types[] = {
+       { HIP_I1,                                "I1"                     },
+       { HIP_R1,                                "R1"                     },
+       { HIP_I2,                                "I2"                     },
+       { HIP_R2,                                "R2"                     },
+       { HIP_UPDATE,                            "UPDATE"                 },
+       { HIP_NOTIFY,                            "NOTIFY"                 },
+       { HIP_CLOSE,                             "CLOSE"                  },
+        { HIP_CLOSE_ACK,                         "CLOSE_ACK"              },
+       { 0,                                     NULL                     }
+};
+
+static struct tok hip_param_types[] = {
+       { HIP_PARAM_R1_COUNTER,                  "R1 COUNTER"             },
+       { HIP_PARAM_PUZZLE,                      "PUZZLE"                 },
+       { HIP_PARAM_SOLUTION,                    "SOLUTION"               },
+       { HIP_PARAM_SEQ,                         "SEQ"                    },
+       { HIP_PARAM_ACK,                         "ACK"                    },
+       { HIP_PARAM_DIFFIE_HELLMAN,              "DIFFIE_HELLMAN"         },
+       { HIP_PARAM_HIP_TRANSFORM,               "HIP_TRANSFORM"          },
+       { HIP_PARAM_ENCRYPTED,                   "ENCRYPTED"              },
+       { HIP_PARAM_HOST_ID,                     "HOST_ID"                },
+       { HIP_PARAM_CERT,                        "CERT"                   },
+       { HIP_PARAM_NOTIFICATION,                "NOTIFICATION"           },
+       { HIP_PARAM_ECHO_REQUEST_SIGNED,         "ECHO_REQUEST_SIGNED"    },
+       { HIP_PARAM_ECHO_RESPONSE_SIGNED,        "ECHO_RESPONSE_SIGNED"   },
+       { HIP_PARAM_HMAC,                        "HMAC"                   },
+       { HIP_PARAM_HMAC_2,                      "HMAC_2"                 },
+       { HIP_PARAM_HIP_SIGNATURE_2,              "HIP_SIGNATURE_2"       },
+       { HIP_PARAM_HIP_SIGNATURE,               "HIP_SIGNATURE"          },
+       { HIP_PARAM_ECHO_REQUEST_UNSIGNED,       "ECHO_REQUEST_UNSIGNED"  },
+       { HIP_PARAM_ECHO_RESPONSE_UNSIGNED,      "ECHO_RESPONSE_UNSIGNED" },
+       { HIP_PARAM_ESP_INFO,                    "ESP_INFO"               },
+       { HIP_PARAM_ESP_TRANSFORM,               "ESP_TRANSFORM"          },
+       { HIP_PARAM_REG_INFO,                    "REG_INFO"               },
+        { HIP_PARAM_REG_REQUEST,                 "REG_REQUEST"            },
+       { HIP_PARAM_REG_RESPONSE,                "REG_RESPONSE"           },
+        { HIP_PARAM_REG_FAILED,                  "REG_FAILED"             },
+       { HIP_PARAM_FROM,                        "FROM"                   },
+       { HIP_PARAM_RVS_HMAC,                    "RVS_HMAC"               },
+        { HIP_PARAM_VIA_RVS,                     "VIA_RVS"                },
+        { HIP_PARAM_LOCATOR,                     "LOCATOR"                },
+       { HIP_PARAM_NAT_TRAVERSAL_MODE,          "NAT_TRAVERSAL_MODE"     },
+       { HIP_PARAM_TRANSACTION_PACING,          "TRANSACTION_PACING"     },
+       { HIP_PARAM_REG_FROM,                    "REG_FROM"               },
+       { HIP_PARAM_RELAY_FROM,                  "RELAY_FROM"             }, 
+       { HIP_PARAM_RELAY_TO,                    "RELAY_TO"               },
+       { 0,                                     NULL                     }
+};
+
+static struct tok hip_esp_transform_types[] = {
+       { HIP_ESP_RESERVED,                      "Reserved"               },
+       { HIP_ESP_AES_SHA1,                      "AES-SHA1"               },
+       { HIP_ESP_3DES_SHA1,                     "3DES-SHA1"              },
+       { HIP_ESP_3DES_MD5,                      "3DES-MD5"               },
+       { HIP_ESP_BLOWFISH_SHA1,                 "BLOWFISH-SHA1"          },
+       { HIP_ESP_NULL_SHA1,                     "NULL-SHA1"              },
+       { HIP_ESP_NULL_MD5,                      "NULL-MD5"               },
+       { 0,                                     NULL                     }
+};
+
+#define hip_hip_transform_types hip_esp_transform_types
+
+static struct tok hip_rdata_algorithms[] = {
+       { HIP_HI_DSA,                            "DSA"                    },
+       { HIP_HI_RSA,                            "RSA"                    },
+       { 0,                                     NULL                     }
+};
+
+static struct tok hip_dh_group_id_types[] = {
+       { HIP_DH_RESERVED,                       "Reserved"               },
+       { HIP_DH_384,                            "384-bit group"          },
+       { HIP_DH_OAKLEY_1,                       "768-bit (OAKLEY 1)"     },
+       { HIP_DH_OAKLEY_5,                       "1536-bit (OAKLEY 5)"    },
+       { HIP_DH_OAKLEY_15,                      "3072-bit (OAKLEY 15)"   },
+       { HIP_DH_OAKLEY_17,                      "6144-bit (OAKLEY 17)"   },
+       { HIP_DH_OAKLEY_18,                      "8192-bit (OAKLEY 18)"   },
+       { 0,                                     NULL                     }
+};
+
+static struct tok hip_nat_traversal_modes[] = {
+       { HIP_NAT_TRAVERSAL_MODE_RESERVED,       "Reserved"               },
+       { HIP_NAT_TRAVERSAL_MODE_UDP,            "UDP-encapsulation"      },
+       { HIP_NAT_TRAVERSAL_MODE_ICE_STUN_UDP,   "ICE-STUN-UDP"           },
+       { 0,                                     NULL                     }
+};
+
+/*******************************************************************************
+* Tool functions                                                               *
+*******************************************************************************/
+
+void 
+hip_hexdump(u_char *data, int len) 
+{
+       int i;
+       for (i = 0; i < len; i++)
+               printf("%02x", data[i]);
+}
+
+/* supports only hex print, modified from print_int64 in print-nfs.c */
+static void 
+hip_print_int64_hex (const u_char *dp, int hostorder)
+{
+       if (hostorder)
+               printf("0x%" PRIx64, EXTRACT_LE_64BITS(dp));
+       else
+               printf("0x%" PRIx64, EXTRACT_64BITS(dp));
+}
+
+/*******************************************************************************
+*  Dissectors for HIP params                                                  *
+*******************************************************************************/
+
+void 
+hip_print_param_r1_counter (const struct hip_tlv_common * tlv)
+{
+       struct hip_r1_counter *p = (struct hip_r1_counter *) tlv;
+        
+       printf(" Reserved=%u", p->reserved);
+       printf(", Generation net order=");
+       hip_print_int64_hex((u_char *)&p->generation, 0);
+       printf("/host order=");
+       hip_print_int64_hex((u_char *)&p->generation, 1);
+
+}
+
+void 
+hip_print_param_puzzle (const struct hip_tlv_common * tlv) 
+{
+       struct hip_puzzle *p = (struct hip_puzzle *) tlv;
+
+       printf("(K=%u, lifetime=%u, opaque=0x", p->K, p->lifetime);
+       hip_hexdump((u_char *) &p->opaque, HIP_PUZZLE_OPAQUE_LEN);
+       printf(", I net order=");
+       hip_print_int64_hex((u_char *)&p->I, 0);
+       printf("/host order=");
+       hip_print_int64_hex((u_char *)&p->I, 1);
+       printf(")");
+}
+
+void 
+hip_print_param_solution (const struct hip_tlv_common * tlv) 
+{
+       struct hip_solution * p = (struct hip_solution *) tlv;
+
+       printf("(K=%u, reserved=0x%x, opaque=0x", p->K, p->reserved);
+       hip_hexdump((u_char *) &p->opaque, HIP_PUZZLE_OPAQUE_LEN);
+       printf(", I net order=");
+       hip_print_int64_hex((u_char *)&p->I, 0);
+       printf("/host order=");
+       hip_print_int64_hex((u_char *)&p->I, 1);
+       printf(", J net order=");
+       hip_print_int64_hex((u_char *)&p->J, 0);
+       printf("/host order=");
+       hip_print_int64_hex((u_char *)&p->J, 1);
+       printf(")");
+}
+
+void 
+hip_print_param_seq (const struct hip_tlv_common * tlv) 
+{
+       struct hip_seq * p = (struct hip_seq *) tlv;
+
+       printf("(Update ID=%u)", ntohl(p->update_id));
+}
+
+void 
+hip_print_param_ack (const struct hip_tlv_common * tlv) 
+{
+       struct hip_ack * p = (struct hip_ack *) tlv;
+       size_t n, i;
+       uint32_t * peer_update_id;
+
+       if (ntohs(p->length) % sizeof(uint32_t))
+               return;
+
+       n = ntohs(p->length) / sizeof(uint32_t);
+       peer_update_id = (uint32_t *) ((void *)p + sizeof(struct hip_tlv_common));
+       printf("(");
+       for (i = 0; i < n; i++, peer_update_id++) {
+               if (i) printf(",");
+               printf("peer Update ID=%u", ntohl(* peer_update_id));
+       }
+       printf(")");
+}
+
+void 
+hip_print_param_diffie_hellman (const struct hip_tlv_common * tlv) 
+{
+       struct hip_diffie_hellman * p = (struct hip_diffie_hellman *) tlv;
+
+       printf("(group_id=%s(%u), public value=0x",
+              tok2str(hip_dh_group_id_types, NULL, p->group_id), p->group_id);
+       hip_hexdump((u_char *)p + sizeof(struct hip_tlv_common)+sizeof(uint8_t),
+                   ntohs(p->length) - sizeof(uint8_t));
+       printf(")");
+
+}
+
+void 
+hip_print_param_hip_transform (const struct hip_tlv_common * tlv) 
+{
+       struct hip_hip_transform * p = (struct hip_hip_transform *) tlv;
+       u_int16_t *id;
+       int i, n;
+
+       printf("(");
+       if (ntohs(p->length) == 0) {
+               printf("no transforms)");
+               return;
+       }
+
+       n = ntohs(p->length) / sizeof(u_int16_t);
+       if (n > HIP_TRANSFORM_HIP_MAX) {
+         printf("too many Transform IDs (%d))", n);
+         return;
+       }
+
+       id = (u_int16_t *) ((u_char *)p + sizeof(struct hip_tlv_common));
+       for (i = 1; i <= n; i++, id++) {
+         if (i > 1)
+           printf(",");
+         printf("Transform ID #%d=%s(%d)", i,
+                tok2str(hip_hip_transform_types, NULL, ntohs(* id)), ntohs(* id));
+       }
+
+       printf(")");
+}
+
+void 
+hip_print_param_encrypted (const struct hip_tlv_common * tlv) 
+{
+       int i;
+       u_char *cp;
+
+       cp = (u_char *)tlv + sizeof(struct hip_tlv_common) + sizeof(u_int32_t);
+       printf("(IV=0x");
+       for (i = 0; i < 8; i++)
+               printf("%02x", *cp++);
+       printf(", encrypted=0x");
+       hip_hexdump(cp, ntohs(tlv->length) - sizeof(u_int32_t) - 8);
+       printf(")");
+}
+
+void 
+hip_print_param_host_id (const struct hip_tlv_common * tlv) 
+{
+       struct hip_host_id * p = (struct hip_host_id *) tlv;
+       u_int8_t t;
+       u_char * cp;
+       struct hip_host_id_key_rdata * rdata;
+       int di_type, di_length;
+
+       //      di_type = ntohs(p->di_type_length) & 0xf000;
+       di_type = ntohs(p->di_type_length) >> 12;
+       di_length = ntohs(p->di_type_length) & 0x0fff;
+       printf("(HI Length=%d, DI Type-Length=%d (DI-type=%d, DI Length=%d), ",
+              ntohs(p->hi_length), ntohs(p->di_type_length), di_type, di_length);
+
+       /* HOST ID is in RFC2535 KEY RDATA format */
+       rdata = (struct hip_host_id_key_rdata *)((u_char *)p + 
+                                                sizeof(struct hip_tlv_common) + 
+                                                2 * sizeof(uint16_t));
+       cp = (u_char *) rdata;
+       printf("HI: flags=0x%x, protocol=%d, algorithm=%d",
+              rdata->flags, rdata->protocol, rdata->algorithm);
+
+       /* check if algorithm is listed in HIP drafts */
+       /* 3=DSA, 5=RSA */
+       if (! (rdata->algorithm == HIP_HI_DSA || rdata->algorithm == HIP_HI_RSA) ) {
+               printf(" unknown algorithm");
+               cp += ntohs(p->hi_length);
+               goto print_di;
+       }
+
+       if (rdata->algorithm != HIP_HI_DSA) {
+               printf(" RSA parsing not supported yet");
+               cp += ntohs(p->hi_length);
+               goto print_di;
+       }
+
+       printf("(%s)", tok2str(hip_rdata_algorithms, "unknown", rdata->algorithm));
+       cp = (u_char *)p + sizeof(struct hip_host_id);
+       t = (u_int8_t) *cp;
+       printf(" T=%d", t);
+       if (ntohs(p->length) < (4 + 1 + 20 + 3 * (64 + t * 8))) {
+               printf(", truncated RDATA)");
+               goto print_di;
+       }
+       cp++;
+       printf(",Q=0x"); hip_hexdump(cp, 20);
+       cp += 20;
+       printf(",P=0x"); hip_hexdump(cp, 64 + t * 8);
+       cp += 64 + t * 8;
+       printf(",G=0x"); hip_hexdump(cp, 64 + t * 8);
+       cp += 64 + t * 8;
+       printf(",Y=0x"); hip_hexdump(cp, 64 + t * 8);
+
+ print_di:
+       printf(" DI=0x");
+       hip_hexdump(cp, di_length);
+       printf(")");
+}
+
+void
+hip_print_param_cert (const struct hip_tlv_common * tlv)
+{
+       struct hip_cert *p = (struct hip_cert *)tlv;
+       unsigned char *cert;
+       int cert_len;
+       
+       printf(" Cert Group=%u", p->cert_group);
+       printf(", Cert Count=%u", p->cert_count);
+       printf(", Cert ID=%u", p->cert_id);
+       printf(", Cert Type=%u", p->cert_type);
+       
+        /* Calculate the length of the certificate and dump it */
+       printf(", Certificate=0x");
+       cert_len = ntohs(tlv->length) - 4;
+       cert = (((unsigned char *)p) + 4);
+       hip_hexdump(cert, cert_len);
+}
+
+void 
+hip_print_param_notification (const struct hip_tlv_common * tlv) 
+{
+       struct hip_notification * p = (struct hip_notification *) tlv;
+       printf("(Reserved=%x,Message Type=%u,Notification data=0x",
+              ntohs(p->reserved), ntohs(p->msgtype)); 
+       hip_hexdump((u_char *)p + sizeof(struct hip_tlv_common) + 
+                   2*sizeof(u_int16_t), ntohs(p->length)-2*sizeof(u_int16_t));
+       printf(")");
+}
+
+void
+hip_print_param_echo_request_signed (const struct hip_tlv_common * tlv)
+{
+       printf(" Opaque=0x");
+       hip_hexdump((u_char*)tlv, ntohs(tlv->length));
+}
+
+void
+hip_print_param_echo_response_signed (const struct hip_tlv_common * tlv)
+{
+       printf(" Opaque=0x");
+       hip_hexdump((u_char*)tlv, ntohs(tlv->length));
+}
+
+void 
+hip_print_param_hmac (const struct hip_tlv_common * tlv) 
+{
+       struct hip_hmac * p = (struct hip_hmac *) tlv;
+
+       printf("(hmac data=0x");
+       hip_hexdump((u_char *)&p->hmac_data,
+                   HIP_LEN_PAD(ntohs(tlv->length)) - sizeof(struct hip_tlv_common));
+       printf(")");
+}
+ 
+void 
+hip_print_param_hmac_2 (const struct hip_tlv_common * tlv) 
+{
+       struct hip_hmac * p = (struct hip_hmac *) tlv;
+
+       printf("(hmac_2 data=0x");
+       hip_hexdump((u_char *)&p->hmac_data,
+                   HIP_LEN_PAD(ntohs(tlv->length)) - sizeof(struct hip_tlv_common));
+       printf(")");
+}
+
+void 
+hip_print_param_hip_signature_2 (const struct hip_tlv_common * tlv) 
+{
+       struct hip_signature * p = (struct hip_signature *) tlv;
+       /* draft: same algorithm as in ESP_TRANSFORM */
+       printf("(algorithm=%s(%u),signature=0x",
+              tok2str(hip_rdata_algorithms, NULL, p->algorithm), p->algorithm);
+       hip_hexdump((u_char *)p + sizeof(struct hip_tlv_common) + 
+                   sizeof(u_int8_t), ntohs(p->length)-sizeof(u_int8_t));
+       printf(")");
+}
+
+void 
+hip_print_param_hip_signature (const struct hip_tlv_common * tlv) 
+{
+       struct hip_signature * p = (struct hip_signature *) tlv;
+       /* draft: same algorithm as in ESP_TRANSFORM */
+       printf("(algorithm=%s(%u),signature=0x",
+              tok2str(hip_rdata_algorithms, NULL, p->algorithm), p->algorithm);
+       hip_hexdump((u_char *)p + sizeof(struct hip_tlv_common) + 
+                   sizeof(u_int8_t), ntohs(p->length)-sizeof(u_int8_t));
+       printf(")");
+}
+
+void
+hip_print_param_echo_request_unsigned (const struct hip_tlv_common * tlv)
+{
+       printf(" Opaque=0x");
+       hip_hexdump((u_char *)tlv, ntohs(tlv->length));
+}
+
+void
+hip_print_param_echo_response_unsigned (const struct hip_tlv_common * tlv)
+{
+       printf(" Opaque=0x");
+       hip_hexdump((u_char*)tlv, ntohs(tlv->length));
+}
+
+void
+hip_print_param_esp_info (const struct hip_tlv_common * tlv)
+{
+       struct hip_esp_info *p = (struct hip_esp_info *)tlv;
+       
+       printf(" Reserved=%u", p->reserved);
+       printf(", KEYMAT Index=0x%x", ntohs(p->keymat_index));
+       printf(", Old SPI=0x%x", htonl(p->old_spi));
+       printf(", New SPI=0x%x", htonl(p->new_spi));
+}
+
+void 
+hip_print_param_esp_transform (const struct hip_tlv_common * tlv) 
+{
+       struct hip_esp_transform * p = (struct hip_esp_transform *) tlv;
+       int i, n;
+       u_int16_t *id;
+
+       printf("(");
+       printf("reserved=0x%x,", ntohs(p->reserved));
+
+       if (ntohs(p->length) == 0) {
+               printf("no transforms)");
+               return;
+       }
+
+       n = (ntohs(p->length)-sizeof(uint16_t)) / sizeof(u_int16_t);
+       if (n > HIP_TRANSFORM_ESP_MAX) {
+         printf("too many Suite IDs (%d))", n);
+         return;
+       }
+
+       id = (u_int16_t *) ((u_char *)p + sizeof(uint16_t) + sizeof(struct hip_tlv_common));
+       for (i = 1; i <= n; i++, id++) {
+         if (i > 1)
+           printf(",");
+         printf("Suite-ID #%d=%s(%d)", i,
+                tok2str(hip_esp_transform_types, NULL, ntohs(*id)), ntohs(*id));
+       }
+
+       printf(")");
+}
+
+void
+hip_print_param_reg_info (const struct hip_tlv_common * tlv)
+{
+       struct hip_reg_info *p = (struct hip_reg_info *)tlv;
+       int reg_type_count, i;
+       unsigned char * rt;
+
+       printf(" Min lifetime=%u", p->min_lifetime);
+       printf(", Max lifetime=%u", p->max_lifetime);
+       reg_type_count = ntohs(tlv->length) - 2;
+       rt = p->reg_type;
+       for (i = 0; i < reg_type_count; i++) { 
+               printf(", Reg type=0x%x", *rt);
+               rt++;
+       }
+}
+
+void
+hip_print_param_reg_request (const struct hip_tlv_common * tlv)
+{
+       struct hip_reg_request_response *p = (struct hip_reg_request_response *)tlv;
+       int reg_type_count, i;
+       unsigned char  * rt;
+
+       printf(" Lifetime=%u", p->lifetime);
+       reg_type_count = ntohs(tlv->length) - 1;
+       rt = p->reg_type;
+       for (i = 0; i < reg_type_count; i++) { 
+               printf(", Reg type=0x%x", *rt);
+               rt++;
+       }
+}
+
+void
+hip_print_param_reg_response (const struct hip_tlv_common * tlv)
+{
+       struct hip_reg_request_response *p = (struct hip_reg_request_response *)tlv;
+       int reg_type_count, i;
+       unsigned char * rt;
+
+       printf(" Lifetime=%u", p->lifetime);
+       reg_type_count = ntohs(tlv->length) - 1;
+       rt = p->reg_type;
+       for (i = 0; i < reg_type_count; i++) { 
+               printf(", Reg type=0x%x", *rt);
+               rt++;
+       }
+}
+
+void
+hip_print_param_reg_failed (const struct hip_tlv_common * tlv)
+{
+       struct hip_reg_failed *p = (struct hip_reg_failed *)tlv;
+       int reg_type_count, i;
+       unsigned char * rt;
+
+       printf(" Failure type=%u", p->failure_type);
+       reg_type_count = ntohs(tlv->length) - 1;
+       rt = p->reg_type;
+       for (i = 0; i < reg_type_count; i++) { 
+               printf(", Reg type=0x%x", *rt);
+               rt++;
+       }
+}
+
+void
+hip_print_param_from (const struct hip_tlv_common * tlv)
+{
+       struct hip_from *p = (struct hip_from *)tlv;
+
+       (void)printf(" Address=%s ", ip6addr_string(&p->address));
+}
+
+void
+hip_print_param_rvs_hmac (const struct hip_tlv_common * tlv)
+{
+       struct hip_rvs_hmac *p = (struct hip_rvs_hmac *)tlv;
+
+       printf("(hmac data=0x");
+       hip_hexdump((u_char *)&p->hmac_data,
+                   HIP_LEN_PAD(ntohs(tlv->length)) - sizeof(struct hip_tlv_common));
+       printf(")");
+}
+
+void
+hip_print_param_via_rvs (const struct hip_tlv_common * tlv)
+{
+       struct hip_via_rvs *p = (struct hip_via_rvs *)tlv;
+
+       (void)printf(" Address=%s ", ip6addr_string(&p->address));
+}
+
+void
+hip_print_param_locator (const struct hip_tlv_common * tlv)
+{
+       uint8_t type;
+       uint8_t reserved;
+        uint8_t preferred;
+       int offset = 0;
+       char * cp = NULL;
+       struct hip_locator_info_addr_item *p = NULL;
+       struct hip_locator_info_addr_item2 *p2 = NULL;
+
+        p = (struct hip_locator_info_addr_item *)tlv;
+
+       while (offset < htons(tlv->length)) {
+               printf("\n  Traffic type=%u", p->traffic_type);
+               printf(", type=%u", p->locator_type);
+               printf(", length=%u", p->locator_length);
+               reserved = (p->reserved & HIP_LOCATOR_RESERVED_MASK) >> 1;
+               printf(", Reserved=%u", reserved);
+               preferred = p->reserved & HIP_LOCATOR_PREFERRED_MASK;
+               printf(", Preferred=%u", preferred);
+               printf(", Lifetime=0x%x", htonl(p->lifetime));
+
+               type = p->locator_type;
+               if (type == 0 || type == 1) {
+                       (void)printf(" Locator=%s ", ip6addr_string(&p->locator));
+                       offset += 24;
+                       cp = (char *)p;
+                       cp += 24;
+                       p = (struct hip_locator_info_addr_item *)cp;    
+               } else if (type == 2) { 
+                       p2 = (struct hip_locator_info_addr_item2 *)p;
+                       printf(", Transport port=%u", p2->transport_port);
+                       printf(", Transport protocol=%u", p2->transport_protocol);
+                       printf(", Kind=%u", p2->kind);
+                       printf(", Priority=0x%x", htonl(p2->priority));
+                       printf(", SPI=0x%x", htonl(p2->spi));
+                       (void)printf(" Locator=%s ", ip6addr_string(&p2->locator));
+                       offset += 36;
+                       cp = (char *)p;
+                       cp += 36;
+                       p = (struct hip_locator_info_addr_item *)cp;
+               } 
+       }
+}
+
+void
+hip_print_param_nat_traversal_mode (const struct hip_tlv_common * tlv)
+{
+       struct hip_nat_traversal_mode *p = (struct hip_nat_traversal_mode *)tlv;
+       int i, n;
+       u_int16_t *id;
+
+       printf("(");
+       printf("reserved=0x%x,", ntohs(p->reserved));
+
+       if (ntohs(p->length) == 0) {
+               printf("no transforms)");
+               return;
+       }
+
+       n = (ntohs(p->length)-sizeof(uint16_t)) / sizeof(u_int16_t);
+       if (n > HIP_NAT_TRAVERSAL_MODE_MAX) {
+         printf("too many Mode IDs (%d))", n);
+         return;
+       }
+
+       id = (u_int16_t *) ((u_char *)p + sizeof(uint16_t) + sizeof(struct hip_tlv_common));
+       for (i = 1; i <= n; i++, id++) {
+         if (i > 1)
+           printf(",");
+         printf("Mode-ID #%d=%s(%d)", i,
+                tok2str(hip_nat_traversal_modes, NULL, ntohs(*id)), ntohs(*id));
+       }
+
+       printf(")");
+
+}
+
+void
+hip_print_param_nat_transaction_pacing (const struct hip_tlv_common * tlv)
+{
+       struct hip_transaction_pacing *p = (struct hip_transaction_pacing *)tlv;
+
+       printf(" Min Ta=0x%x", htonl(p->min_ta));
+}
+
+void
+hip_print_param_reg_from (const struct hip_tlv_common * tlv)
+{
+       struct hip_reg_from *p = (struct hip_reg_from *)tlv;
+       
+       printf(" Port=%u", ntohs(p->port));
+       printf(", Protocol=%u", p->protocol);
+       printf(", Reserved=%u", p->reserved);
+       (void)printf(" Address=%s ", ip6addr_string(&p->address));      
+}
+
+void
+hip_print_param_relay_from (const struct hip_tlv_common * tlv)
+{
+       struct hip_relay_from *p = (struct hip_relay_from *)tlv;
+
+       printf(" Port=%u", ntohs(p->port));
+       printf(", Protocol=%u", p->protocol);
+       printf(", Reserved=%u", p->reserved);
+       (void)printf(" Address=%s ", ip6addr_string(&p->address));      
+}
+
+void
+hip_print_param_relay_to (const struct hip_tlv_common * tlv)
+{
+       struct hip_relay_to *p = (struct hip_relay_to *)tlv;
+
+       printf(" Port=%u", ntohs(p->port));
+       printf(", Protocol=%u", p->protocol);
+       printf(", Reserved=%u", p->reserved);
+       (void)printf(" Address=%s ", ip6addr_string(&p->address));      
+}
+
+void 
+hip_print_param_unknown (const struct hip_tlv_common *tlv, u_int tlv_len) 
+{
+       printf("(0x");
+       hip_hexdump((u_char *)tlv + sizeof(struct hip_tlv_common), 
+                   ntohs(tlv->length) - 0 * sizeof(struct hip_tlv_common));
+       printf(")");
+}
+
+/*******************************************************************************
+* Print a HIP datagram                                                         *
+*******************************************************************************/
+
+void
+hip_print (register const u_char *bp, register u_int length)
+{
+       register const struct hip_common *hip;
+       register u_int len;
+       register const u_char *cp;
+       int type;
+       struct tok *token;
+       
+       hip = (const struct hip_common *) bp;
+       
+#ifdef LBL_ALIGN
+       /* CHECK IF HIP HAS THE SAME CASE:
+        * The IP6 header is not 16-byte aligned, so copy into a buf. */
+       if ((u_long)hip & 15) {
+               static u_char *abuf;
+               
+               if (abuf == NULL) {
+                       abuf = malloc(snaplen);
+                       if (abuf == NULL)
+                               error("hip_print: malloc");
+               }
+               memcpy(abuf, hip, min(length, snaplen));
+               snapend += abuf - (u_char *)hip;
+               packetp = abuf;
+               hip = (struct hip_common *)abuf;
+               bp = abuf;
+       }
+#endif
+       TCHECK(*hip);
+       if (length < sizeof(struct hip_common)) {
+               (void)printf("Truncated - HIP (length=%d)", length);
+               return;
+       }
+       if (length > HIP_MAX_PACKET) {
+               (void)printf("Oversized HIP (length=%d)", length);
+               return;
+
+       }
+       
+       len = (hip->payload_len+1) << 3;
+       if (length < len)
+               (void)printf("Truncated HIP (%d bytes missing!)",
+                            len - length);
+       
+       /* print common header */
+       (void)printf("HIP %s > %s: ", ip6addr_string(&hip->hits),
+                    ip6addr_string(&hip->hitr));
+       
+       /* XXTODO print out the fixed shim6 bits */
+
+       if (vflag) {
+               (void)printf("len=%d (%d bytes),type=%d,ver_res=0x%x,control=0x%x,"
+                            "checksum=0x%x (checksum_host=0x%x) ",
+                            hip->payload_len, 
+                            8 * hip->payload_len, 
+                            hip->type_hdr,
+                            hip->ver_res,
+                            ntohs(hip->control), 
+                            hip->checksum,
+                            ntohs(hip->checksum));
+       }
+       
+       type = hip->type_hdr;
+       
+       /* check that we support the packet type */
+       token = hip_types;
+       while (token->s) {
+               if (token->v == type)
+                       break;
+               token++;
+       }
+       if (!token->s) {
+               printf("Unknown packet (type=%d)", type);
+               return;         
+       }
+       printf("%s", tok2str(hip_types, NULL, type));
+       if (vflag > 1) {
+               /* print payloads */
+               cp = (const u_char *)(hip+1);
+               while (cp < snapend) {
+                       struct hip_tlv_common *tlv;
+                       u_int tlv_len, tlv_type;
+                       
+                       tlv = (struct hip_tlv_common *) cp;
+                       tlv_len = HIP_LEN_PAD(sizeof(struct hip_tlv_common) +
+                                             ntohs(((const struct hip_tlv_common *) tlv)->length));
+                       tlv_type = ntohs(tlv->type);
+                       
+                       printf("\n");
+                       
+                       if (cp + tlv_len > snapend) {
+                               printf("  TLV type=%d exceeds packet\n", tlv_type);
+                               goto trunc;
+                       }
+                       
+                       printf("  TLV type=%d,len=%d: %s", tlv_type, tlv_len,
+                              tok2str(hip_param_types, "  Unknown parameter (type=%d)", tlv_type));
+                       if (vflag > 2) {
+                               switch (tlv_type) {
+                               case HIP_PARAM_ESP_INFO:
+                                       hip_print_param_esp_info(tlv);
+                                       break;
+                               case HIP_PARAM_R1_COUNTER:
+                                       hip_print_param_r1_counter(tlv);
+                                       break;
+                               case HIP_PARAM_LOCATOR:
+                                       hip_print_param_locator(tlv);
+                                       break;
+                               case HIP_PARAM_PUZZLE:
+                                       hip_print_param_puzzle(tlv);
+                                       break;
+                               case HIP_PARAM_SOLUTION:
+                                       hip_print_param_solution(tlv);
+                                       break;
+                               case HIP_PARAM_SEQ:
+                                       hip_print_param_seq(tlv);
+                                       break;
+                               case HIP_PARAM_ACK:
+                                       hip_print_param_ack(tlv);
+                                       break;
+                               case HIP_PARAM_DIFFIE_HELLMAN:
+                                       hip_print_param_diffie_hellman(tlv);
+                                       break;
+                               case HIP_PARAM_HIP_TRANSFORM:
+                                       hip_print_param_hip_transform(tlv);
+                                       break;
+                               case HIP_PARAM_NAT_TRAVERSAL_MODE:
+                                       hip_print_param_nat_traversal_mode(tlv);
+                                       break;
+                               case HIP_PARAM_TRANSACTION_PACING:
+                                       hip_print_param_nat_transaction_pacing(tlv);
+                                       break;
+                               case HIP_PARAM_ENCRYPTED:
+                                       hip_print_param_encrypted(tlv);
+                                       break;
+                               case HIP_PARAM_HOST_ID:
+                                       hip_print_param_host_id(tlv);
+                                       break;
+                               case HIP_PARAM_CERT:
+                                       hip_print_param_host_id(tlv);
+                                       break;
+                               case HIP_PARAM_NOTIFICATION:
+                                       hip_print_param_notification(tlv);
+                                       break;
+                               case HIP_PARAM_ECHO_REQUEST_SIGNED:
+                                       hip_print_param_echo_request_signed(tlv);
+                                       break;
+                               case HIP_PARAM_REG_INFO:
+                                       hip_print_param_reg_info(tlv);
+                                       break;
+                               case HIP_PARAM_REG_REQUEST:
+                                       hip_print_param_reg_request(tlv);
+                                       break;
+                               case HIP_PARAM_REG_RESPONSE:
+                                       hip_print_param_reg_response(tlv);
+                               break;
+                               case HIP_PARAM_REG_FAILED:
+                                       hip_print_param_reg_failed(tlv);
+                                       break;
+                               case HIP_PARAM_REG_FROM:
+                                       hip_print_param_reg_from(tlv);
+                                       break;
+                               case HIP_PARAM_ECHO_RESPONSE_SIGNED:
+                                       hip_print_param_echo_response_signed(tlv);
+                                       break;
+                               case HIP_PARAM_ESP_TRANSFORM:
+                                       hip_print_param_esp_transform(tlv);
+                                       break;
+                               case HIP_PARAM_HMAC:
+                                       hip_print_param_hmac(tlv);
+                                       break;
+                               case HIP_PARAM_HMAC_2:
+                                       hip_print_param_hmac_2(tlv);
+                                       break;
+                               case HIP_PARAM_HIP_SIGNATURE_2:
+                                       hip_print_param_hip_signature_2(tlv);
+                                       break;
+                               case HIP_PARAM_HIP_SIGNATURE:
+                                       hip_print_param_hip_signature(tlv);
+                                       break;
+                               case HIP_PARAM_ECHO_REQUEST_UNSIGNED:
+                                       hip_print_param_echo_request_unsigned(tlv);
+                                       break;
+                               case HIP_PARAM_ECHO_RESPONSE_UNSIGNED:
+                                       hip_print_param_echo_response_unsigned(tlv);
+                                       break;
+                               case HIP_PARAM_RELAY_FROM:
+                                       hip_print_param_relay_from(tlv);
+                                       break;
+                               case HIP_PARAM_RELAY_TO:
+                                       hip_print_param_relay_to(tlv);
+                                       break;
+                               case HIP_PARAM_FROM:
+                                       hip_print_param_from(tlv);
+                                       break;
+                               case HIP_PARAM_RVS_HMAC:
+                                       hip_print_param_rvs_hmac(tlv);
+                                       break;
+                               case HIP_PARAM_VIA_RVS:
+                                       hip_print_param_via_rvs(tlv);
+                                       break;
+                               default:
+                                       hip_print_param_unknown(tlv, tlv_len);
+                                       break;
+                               }
+                       }
+                       cp += tlv_len;
+               }
+       }
+       printf("\n");
+       return;
+trunc:
+       (void)printf("[|hip]");
+}
diff -N -r -u --strip-trailing-cr tcpdump-orig/print-ip6.c tcpdump/print-ip6.c
--- tcpdump-orig/print-ip6.c    2009-05-20 10:29:46.000000000 +0200
+++ tcpdump/print-ip6.c 2009-05-17 22:12:07.000000000 +0200
@@ -220,6 +220,10 @@
                        rsvp_print(cp, len);
                        return;
 
+               case IPPROTO_HIP:
+                        hip_print(cp, len);
+                        return;
+
                case IPPROTO_NONE:
                        (void)printf("no next header");
                        return;
diff -N -r -u --strip-trailing-cr tcpdump-orig/print-ip.c tcpdump/print-ip.c
--- tcpdump-orig/print-ip.c     2009-05-20 10:29:46.000000000 +0200
+++ tcpdump/print-ip.c  2009-07-28 01:28:46.000000000 +0200
@@ -1,3 +1,4 @@
+
 /*
  * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
  *     The Regents of the University of California.  All rights reserved.
@@ -519,6 +520,13 @@
                pgm_print(ipds->cp, ipds->len, (const u_char *)ipds->ip);
                break;
 
+#ifdef INET6
+        case IPPROTO_HIP:
+               /* hip on top of ip */
+               hip_print(ipds->cp, ipds->len);
+               break;
+#endif /*INET6*/
+
        default:
                if ((proto = getprotobynumber(ipds->nh)) != NULL)
                        ND_PRINT((ndo, " %s", proto->p_name));
diff -N -r -u --strip-trailing-cr tcpdump-orig/print-udp.c tcpdump/print-udp.c
--- tcpdump-orig/print-udp.c    2009-05-20 10:29:46.000000000 +0200
+++ tcpdump/print-udp.c 2009-07-03 13:38:21.000000000 +0200
@@ -423,6 +423,7 @@
        register const struct ip *ip;
        register const u_char *cp;
        register const u_char *ep = bp + length;
+       register const u_char *phip, *phipmagic;
        u_int16_t sport, dport, ulen;
 #ifdef INET6
        register const struct ip6_hdr *ip6;
@@ -697,7 +698,23 @@
                        sip_print((const u_char *)(up + 1), length);
                 else if (ISPORT(SYSLOG_PORT))
                        syslog_print((const u_char *)(up + 1), length);
-               else
+                else if (ISPORT(HIP_UDP_PORT)) 
+               {
+                       /* see draft-ietf-hip-nat-traversal-06 for details */
+                       phip = (const u_char *)(up+1);                  
+                       phipmagic = (const u_char *)(phip+4);
+                        /* Check the required NULL bytes and jump over them */
+                       if (htonl(*(phip+3)) == 0) 
+                               hip_print(phip+4, length);
+                       /* It was not HIP check if it is STUN used by HIP */
+                       else if (htonl(*(phipmagic+3) == 0x2112A442))
+                               printf("UDP encapsulated HIP STUN packet\n");
+                       /* It must be UDP encapsulated ESP */
+                       else
+                               printf("UDP encapsulated ESP (HIP) packet\n");
+               }
+
+               else
                        (void)printf("UDP, length %u",
                            (u_int32_t)(ulen - sizeof(*up)));
 #undef ISPORT
diff -N -r -u --strip-trailing-cr tcpdump-orig/udp.h tcpdump/udp.h
--- tcpdump-orig/udp.h  2009-05-20 10:29:46.000000000 +0200
+++ tcpdump/udp.h       2009-05-19 22:49:15.000000000 +0200
@@ -85,6 +85,7 @@
 #define SFLOW_PORT              6343 /* http://www.sflow.org/developers/specifications.php */
 #define LWAPP_DATA_PORT         12222 /* draft-ohara-capwap-lwapp-04.txt */
 #define LWAPP_CONTROL_PORT      12223 /* draft-ohara-capwap-lwapp-04.txt */
+#define HIP_UDP_PORT            50500
 
 #ifdef INET6
 #define RIPNG_PORT 521         /*XXX*/
-
This is the tcpdump-workers list.
Visit https://cod.sandelman.ca/ to unsubscribe.

Current thread: