tcpdump mailing list archives
[Patch] Host Identity Protocol
From: Varjonen Samu <samu.varjonen () hiit fi>
Date: Fri, 10 Jul 2009 12:16:28 +0300
Hi, Here is a patch providing the dissection of HIP control packets for Tcpdump.Host Identity Protocol (HIP) allows consenting hosts to securely establish and maintain shared IP-layer state, allowing separation of the identifier and locator roles of IP addresses, thereby enabling continuity of communications across IP address changes. HIP is based on a Sigma-compliant Diffie-Hellman key exchange, using public key identifiers from a new Host Identity namespace for mutual peer authentication. The protocol is designed to be resistant to denial-of-service (DoS) and man-in-the-middle (MitM) attacks. When used together with another suitable security protocol, such as the Encapsulated Security Payload (ESP), it provides integrity protection and optional encryption for upper-layer protocols, such as TCP and UDP.
Defined in RFCs 4423, 5201 through 5206 draft-ietf-hip-cert-00 and draft-ietf-hip-nat-traversal-06. Currently three different implementations: http://www.infrahip.net/, HIP for Linux (HIPL), supported Linux http://www.openhip.org/, OpenHIP, supported Windows, OS X, Linux http://www.hip4inter.net/, HIP for Internet, supported *BSD/Linux BR, Samu Varjonen
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);
diff -N -r -u --strip-trailing-cr tcpdump-orig/ipproto.c tcpdump/ipproto.c
--- tcpdump-orig/ipproto.c 2009-05-20 11:29:46.000000000 +0300
+++ tcpdump/ipproto.c 2009-05-18 19:56:10.000000000 +0300
@@ -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 11:29:46.000000000 +0300
+++ tcpdump/ipproto.h 2009-05-17 13:33:07.000000000 +0300
@@ -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 11:29:46.000000000 +0300
+++ tcpdump/Makefile.in 2009-05-17 13:20:28.000000000 +0300
@@ -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 02:00:00.000000000 +0200
+++ tcpdump/print-hip.c 2009-07-06 15:29:43.000000000 +0300
@@ -0,0 +1,1396 @@
+/*
+ * 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 "interface.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_int32_t *dp, int hostorder)
+{
+#ifdef INT64_FORMAT
+ u_int64_t res;
+
+ if (hostorder)
+ res = ((u_int64_t)ntohl(dp[0]) << 32) | (u_int64_t)ntohl(dp[1]);
+ else
+ res = ((u_int64_t)dp[0] << 32) | (u_int64_t)dp[1];
+ printf(HEX_INT64_FORMAT, res);
+#else
+ if (hostorder)
+ printf("0x%08x%08x", (u_int32_t)ntohl(dp[0]), (u_int32_t)ntohl(dp[1]));
+ else
+ printf("0x%08x%08x", (u_int32_t)dp[0], (u_int32_t)dp[1]);
+#endif
+}
+
+/*******************************************************************************
+* 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_int32_t *)&p->generation, 0);
+ printf("/host order=");
+ hip_print_int64_hex((u_int32_t *)&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_int32_t *)&p->I, 0);
+ printf("/host order=");
+ hip_print_int64_hex((u_int32_t *)&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_int32_t *)&p->I, 0);
+ printf("/host order=");
+ hip_print_int64_hex((u_int32_t *)&p->I, 1);
+ printf(", J net order=");
+ hip_print_int64_hex((u_int32_t *)&p->J, 0);
+ printf("/host order=");
+ hip_print_int64_hex((u_int32_t *)&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 11:29:46.000000000 +0300
+++ tcpdump/print-ip6.c 2009-05-17 23:12:07.000000000 +0300
@@ -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 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));
diff -N -r -u --strip-trailing-cr tcpdump-orig/print-udp.c tcpdump/print-udp.c
--- tcpdump-orig/print-udp.c 2009-05-20 11:29:46.000000000 +0300
+++ tcpdump/print-udp.c 2009-07-03 14:38:21.000000000 +0300
@@ -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 11:29:46.000000000 +0300
+++ tcpdump/udp.h 2009-05-19 23:49:15.000000000 +0300
@@ -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:
- [Patch] Host Identity Protocol Varjonen Samu (Jul 10)
- Re: [Patch] Host Identity Protocol Guy Harris (Jul 10)
- Re: [Patch] Host Identity Protocol Guy Harris (Jul 10)
- Re: [Patch] Host Identity Protocol Samu Varjonen (Jul 16)
- Re: [Patch] Host Identity Protocol Varjonen Samu (Jul 28)
- Re: [Patch] Host Identity Protocol Samu Varjonen (Jul 16)
