diff -urN wireshark-0.99.7.orig/epan/dissectors/Makefile.common wireshark-0.99.7/epan/dissectors/Makefile.common --- wireshark-0.99.7.orig/epan/dissectors/Makefile.common 2007-12-20 21:19:06.000000000 +0100 +++ wireshark-0.99.7/epan/dissectors/Makefile.common 2007-12-20 21:20:59.000000000 +0100 @@ -341,6 +341,7 @@ packet-dis-fields.c \ packet-dis-pdus.c \ packet-diffserv-mpls-common.c \ + packet-hip.c \ packet-distcc.c \ packet-dlsw.c \ packet-dmp.c \ diff -urN wireshark-0.99.7.orig/epan/dissectors/packet-hip.c wireshark-0.99.7/epan/dissectors/packet-hip.c --- wireshark-0.99.7.orig/epan/dissectors/packet-hip.c 1970-01-01 01:00:00.000000000 +0100 +++ wireshark-0.99.7/epan/dissectors/packet-hip.c 2007-12-20 21:37:45.000000000 +0100 @@ -0,0 +1,1235 @@ +/* packet-hip.c + * Routines for HIP packet disassembly + * + * 03/2006 draft-ietf-hip-base-05, -esp-02, -mm-03, -registration-01, -rvs-04 + * 07/2005 draft-ietf-hip-base-03, -esp-00, and -mm-02 + * 03/2005 draft-ietf-hip-base-01 + * 11/2004 RSA and draft-ietf-hip-mm-00 + * 09/2004 draft-nikander-hip-mm-02 + * 07/2004 draft-ietf-hip-base-00 + * 02/2004 + * 03/2003 + * + * Jeff Ahrenholz + * Thomas Henderson + * + * Packet dissector for Host Identity Protocol (HIP) packets. + * This tool displays the TLV structure, verifies checksums, + * and shows NULL encrypted parameters, but will not verify + * signatures or decode encrypted parameters. + * + * $Id$ + * + * Ethereal - Network traffic analyzer + * By Gerald Combs + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include + +#include +#include +#include +#include "ipproto.h" +#include "in_cksum.h" +#include "prefs.h" + + +#include "packet-ip.h" +#include + +static int proto_hip = -1; +static int hf_hip_proto = -1; +static int hf_hip_hdr_len = -1; +static int hf_hip_packet_type = -1; +static int hf_hip_version = -1; +static int hf_hip_res = -1; +static int hf_hip_controls = -1; +static int hf_hip_controls_cert = -1; +static int hf_hip_controls_anon = -1; +static int hf_hip_checksum = -1; +static int hf_hip_hit_sndr = -1; +static int hf_hip_hit_rcvr = -1; + +static int hf_hip_type = -1; +static int hf_hip_tlv_ei_res = -1; +static int hf_hip_tlv_ei_keyidx = -1; +static int hf_hip_tlv_ei_oldspi = -1; +static int hf_hip_tlv_ei_newspi = -1; +static int hf_hip_tlv_r1_res = -1; +static int hf_hip_tlv_r1count = -1; +static int hf_hip_tlv_puzzle_k = -1; +static int hf_hip_tlv_puzzle_life = -1; +static int hf_hip_tlv_puzzle_o = -1; +static int hf_hip_tlv_puzzle_i = -1; +static int hf_hip_tlv_puzzle_j = -1; +static int hf_hip_tlv_seq_updid = -1; +static int hf_hip_tlv_ack_updid = -1; +static int hf_hip_tlv_dh_group_id = -1; +static int hf_hip_tlv_dh_pub = -1; +static int hf_hip_tlv_trans_id = -1; +static int hf_hip_tlv_esp_reserved = -1; +static int hf_hip_tlv_host_id_len = -1; +static int hf_hip_tlv_host_di_type = -1; +static int hf_hip_tlv_host_di_len = -1; +static int hf_hip_tlv_host_id_hdr = -1; +static int hf_hip_tlv_host_id_hdr_flags = -1; +static int hf_hip_tlv_host_id_hdr_proto = -1; +static int hf_hip_tlv_host_id_hdr_alg = -1; +static int hf_hip_tlv_host_id_t = -1; +static int hf_hip_tlv_host_id_q = -1; +static int hf_hip_tlv_host_id_p = -1; +static int hf_hip_tlv_host_id_g = -1; +static int hf_hip_tlv_host_id_y = -1; +static int hf_hip_tlv_host_id_e_len = -1; +static int hf_hip_tlv_host_id_e = -1; +static int hf_hip_tlv_host_id_n = -1; +static int hf_hip_tlv_cert_count = -1; +static int hf_hip_tlv_cert_id = -1; +static int hf_hip_tlv_cert_type = -1; +static int hf_hip_tlv_certificate = -1; +static int hf_hip_tlv_notify_res = -1; +static int hf_hip_tlv_notify_type = -1; +static int hf_hip_tlv_notify_data = -1; +static int hf_hip_tlv_opaque_data = -1; +static int hf_hip_tlv_reg_ltmin = -1; +static int hf_hip_tlv_reg_ltmax = -1; +static int hf_hip_tlv_reg_lt = -1; +static int hf_hip_tlv_reg_type = -1; +static int hf_hip_tlv_reg_failtype = -1; +static int hf_hip_tlv_hmac = -1; +static int hf_hip_tlv_sig_alg = -1; +static int hf_hip_tlv_sig = -1; +static int hf_hip_tlv_id = -1; +static int hf_hip_tlv_enc_reserved = -1; +static int hf_hip_tlv_enc_iv = -1; +static int hf_hip_tlv_locator_traffic_type = -1; +static int hf_hip_tlv_locator_type = -1; +static int hf_hip_tlv_locator_len = -1; +static int hf_hip_tlv_locator_reserved = -1; +static int hf_hip_tlv_locator_lifetime = -1; +static int hip_transform = 0; + +static gint ett_hip = -1; +static gint ett_hip_controls = -1; +static gint ett_hip_tlv = -1; +static gint ett_hip_tlv_data = -1; +static gint ett_hip_tlv_host_id_hdr = -1; + +/* Place HIP summary in protocol tree */ +static gboolean hip_summary_in_tree = TRUE; + +/* This minimal structure used to get at the Type field*/ +struct newhip { + guint16 nextpluslen; /* Next header, plus length */ + guint8 hiptype; /* Type (what we are after) */ + guint8 hipreserved; /* Reserved (what we are after) */ + /*variable size*/ /* (IV and) Payload data */ +}; + +/* 128-bit Host Identity Tag */ +#define HIT_BITSIZE 128 +typedef unsigned char hip_hit [HIT_BITSIZE/8]; + +#define HI_ALG_DSA 3 +#define HI_ALG_RSA 5 + +/* HIP packet types */ +typedef enum { + HIP_I1=1, + HIP_R1, + HIP_I2, + HIP_R2, + CER, /* 5 - removed from draft-ietf-hip-base-03 */ + BOS=11, /* 11 - removed from draft-ietf-hip-base-01 */ + UPDATE=16, /* 16 */ + NOTIFY=17, /* 17 */ + CLOSE=18, /* 18 */ + CLOSE_ACK=19, /* 19 */ +} HIP_PACKETS; + +/* HIP TLV parameters */ +/* 03/2006 draft-ietf-hip-base-05, -esp-02, -mm-03, -registration-01, -rvs-04 */ +#define PARAM_ESP_INFO 65 +#define PARAM_R1_COUNTER 128 +#define PARAM_LOCATOR 193 +#define PARAM_PUZZLE 257 +#define PARAM_SOLUTION 321 +#define PARAM_SEQ 385 +#define PARAM_ACK 449 +#define PARAM_DIFFIE_HELLMAN 513 +#define PARAM_HIP_TRANSFORM 577 +#define PARAM_ENCRYPTED 641 +#define PARAM_HOST_ID 705 +#define PARAM_CERT 768 +#define PARAM_NOTIFY 832 +#define PARAM_ECHO_REQUEST 897 +#define PARAM_REG_INFO 930 +#define PARAM_REG_REQUEST 932 +#define PARAM_REG_RESPONSE 934 +#define PARAM_REG_FAILED 936 +#define PARAM_ECHO_RESPONSE 961 +#define PARAM_ESP_TRANSFORM 4095 +#define PARAM_TRANSFORM_LOW 2048 /* defines range for transforms */ +#define PARAM_TRANSFORM_HIGH 4095 +#define PARAM_HMAC 61505 +#define PARAM_HMAC_2 61569 +#define PARAM_HIP_SIGNATURE_2 61633 +#define PARAM_HIP_SIGNATURE 61697 +#define PARAM_ECHO_REQUEST_NOSIG 63661 +#define PARAM_ECHO_RESPONSE_NOSIG 63425 +#define PARAM_FROM 65498 +#define PARAM_RVS_HMAC 65500 +#define PARAM_VIA_RVS 65502 +#define PARAM_CRITICAL_BIT 0x0001 + +#define HIP_CONTROL_C_MASK 0x0002 +#define HIP_CONTROL_A_MASK 0x0001 + +#define HI_HDR_FLAGS_MASK 0xFFFF0000 +#define HI_HDR_PROTO_MASK 0x0000FF00 +#define HI_HDR_ALG_MASK 0x000000FF + +const value_string hi_hdr_flags_vals[] = { + { 0x0200, "key is associated with a user" }, + { 0x0201, "zone key" }, + { 0x0202, "key is associated with non-zone entity" }, + { 0x0, "Other" }, +}; + +const value_string hi_hdr_proto_vals[] = { + { 0x01, "key is used for TLS" }, + { 0x02, "key is used for email" }, + { 0x03, "key is used for DNS security" }, + { 0x04, "key is used for Oakley/IPSEC" }, + { 0xFF, "key is valid for any protocol" }, + { 0x0, NULL }, +}; + +const value_string hi_hdr_alg_vals[] = { + { 0x00, "reserved" }, + { 0x01, "RSA/MD5" }, + { 0x02, "Diffie-Hellman" }, + { 0x03, "DSA" }, + { 0x04, "elliptic curve crypto" }, + { 0x05, "RSA" }, + { 0xFF, "reserved" }, +}; + +const value_string notify_vals[] = { + { 1, "Unsupported critical parameter type" }, + { 7, "Invalid syntax" }, + { 14, "No Diffie-Hellman proposal chosen" }, + { 15, "Invalid Diffie-Hellman chosen" }, + { 16, "No HIP proposal chosen" }, + { 17, "Invalid HIP transform chosen" }, + { 18, "No ESP proposal chosen" }, + { 19, "Invalid ESP transform chosen" }, + { 24, "Authentication failed" }, + { 26, "Checksum failed" }, + { 28, "HMAC failed" }, + { 32, "Encryption failed" }, + { 40, "Invalid HIT" }, + { 42, "Blocked by policy" }, + { 44, "Server busy please retry" }, + { 46, "I2 acknowledgement" }, + { 0x0, NULL }, +}; + +typedef struct _hiphdr { + guint8 proto; /* payload protocol */ + guint8 hdr_len; /* header length */ + guint8 packet_type; /* packet type */ + guint8 res:4,version:4; /* version, reserved */ + guint16 checksum; /* checksum */ + guint16 control; /* control */ + hip_hit hit_sndr; /* Sender's Host Identity Tag */ + hip_hit hit_rcvr; /* Receiver's Host Identity Tag*/ + /* HIP parameters ... */ +} hiphdr; + +typedef struct _tlv_head +{ + guint16 type; + guint16 length; +} tlv_head; + + +/* functions */ +char * hip_param(int n); +char *dh_group_id_label(int groupid); +char *transform_id_label(int transform); +char *sig_alg_label(int alg); +int dissect_hip_tlv(tvbuff_t *tvb, int offset, proto_item *ti, int type, int tlv_len); + +static dissector_handle_t data_handle; + +/**** end defs from hip.h ****/ + +/* + * Dissect the HIP packet + */ +static void +dissect_hip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) +{ + proto_tree *hip_tree, *hip_tlv_tree=NULL; + proto_item *ti, *ti_tlv; + hiphdr hiph; + tlv_head tlv; + int length, offset = 0; + guint16 control_h, checksum_h, computed_checksum; + guint16 tlv_type_h, tlv_length_h; /* For storing in host order */ + vec_t cksum_vec[4]; + guint32 phdr[2]; + + /* + * load the top pane info. This should be overwritten by + * the next protocol in the stack + */ + if (check_col(pinfo->cinfo, COL_PROTOCOL)) + col_set_str(pinfo->cinfo, COL_PROTOCOL, "HIP"); + if (check_col(pinfo->cinfo, COL_INFO)) + col_clear(pinfo->cinfo, COL_INFO); + + /* Convert control and checksum to host order */ + + tvb_memcpy(tvb, (guint8 *)&hiph, 0, sizeof(hiphdr)); + control_h = g_ntohs(hiph.control); + checksum_h = g_ntohs(hiph.checksum); + + if (check_col(pinfo->cinfo, COL_INFO)) { + switch (hiph.packet_type) { + case HIP_I1: + col_add_fstr(pinfo->cinfo, COL_INFO, + "HIP I1 (HIP Initiator Packet)"); + break; + case HIP_R1: + col_add_fstr(pinfo->cinfo, COL_INFO, + "HIP R1 (HIP Responder Packet)"); + break; + case HIP_I2: + col_add_fstr(pinfo->cinfo, COL_INFO, + "HIP I2 (Second HIP Initiator Packet)"); + break; + case HIP_R2: + col_add_fstr(pinfo->cinfo, COL_INFO, + "HIP R2 (Second HIP Responder Packet)"); + break; + case UPDATE: + col_add_fstr(pinfo->cinfo, COL_INFO, + "HIP UPDATE (HIP Update Packet)"); + break; + case CER: + col_add_fstr(pinfo->cinfo, COL_INFO, + "HIP CER (HIP Certificate Packet)"); + break; + case BOS: + col_add_fstr(pinfo->cinfo, COL_INFO, + "HIP BOS (HIP Bootstrap Packet)"); + break; + case NOTIFY: + col_add_fstr(pinfo->cinfo, COL_INFO, + "HIP NOTIFY (HIP Notification Packet)"); + break; + case CLOSE: + col_add_fstr(pinfo->cinfo, COL_INFO, + "HIP CLOSE (HIP Close Packet)"); + break; + case CLOSE_ACK: + col_add_fstr(pinfo->cinfo, COL_INFO, + "HIP CLOSE_ACK (HIP Close Acknowledgement Packet)"); + break; + default: + col_add_fstr(pinfo->cinfo, COL_INFO, "HIP Unknown type"); + break; + } + } + + /* + * populate a tree in the second pane with the status of the link layer + * (ie none) + */ + if(tree) { + if (hip_summary_in_tree) { + ti = proto_tree_add_protocol_format(tree, proto_hip, tvb, 0, -1, "Host Identity Protocol"); + } else { + ti = proto_tree_add_item(tree, proto_hip, tvb, 0, -1, FALSE); + } + + hip_tree = proto_item_add_subtree(ti, ett_hip); + proto_tree_add_uint(hip_tree, hf_hip_proto, tvb, offset, 1, hiph.proto); + proto_tree_add_uint(hip_tree, hf_hip_hdr_len, tvb, offset+1, 1, hiph.hdr_len); + proto_tree_add_uint(hip_tree, hf_hip_packet_type, tvb, offset+2, 1, hiph.packet_type); + proto_tree_add_uint_format(hip_tree, hf_hip_version, tvb, offset+3, 1, hiph.version, + "Version: %u, Reserved: %u", hiph.version, hiph.res); + ti = proto_tree_add_uint(hip_tree, hf_hip_controls, tvb, offset+4, 2, control_h); + if (ti) { /* HIP Controls subtree*/ + ti = proto_item_add_subtree(ti, ett_hip_controls); + proto_tree_add_boolean(ti, hf_hip_controls_cert, tvb, offset+5,1, control_h); + proto_tree_add_boolean(ti, hf_hip_controls_anon, tvb, offset+5,1, control_h); + } + + + /* Checksum - this is the same algorithm from UDP, ICMPv6 */ + if (!pinfo->fragmented) { + /* IPv4 or IPv6 addresses */ + cksum_vec[0].ptr = pinfo->src.data; + cksum_vec[0].len = pinfo->src.len; + cksum_vec[1].ptr = pinfo->dst.data; + cksum_vec[1].len = pinfo->dst.len; + /* the rest of the pseudo-header */ + if (pinfo->src.type == AT_IPv6) { + cksum_vec[2].ptr = (const guint8 *)&phdr; + phdr[0] = g_htonl(tvb_reported_length(tvb)); + phdr[1] = g_htonl(IP_PROTO_HIP); + cksum_vec[2].len = 8; + } else { + cksum_vec[2].ptr = (const guint8 *)&phdr; + phdr[0] = g_htonl((IP_PROTO_HIP<<16)+tvb_reported_length(tvb)); + cksum_vec[2].len = 4; + } + /* pointer to the HIP header (packet data) */ + cksum_vec[3].len = tvb_reported_length(tvb); + cksum_vec[3].ptr = tvb_get_ptr(tvb, 0, cksum_vec[3].len); + computed_checksum = in_cksum(cksum_vec, 4); + if (computed_checksum == 0) { + proto_tree_add_uint_format(hip_tree, hf_hip_checksum, tvb, + offset+6, 2, checksum_h, "Checksum: 0x%04x (correct)", + checksum_h); + } else { + proto_tree_add_uint_format(hip_tree, hf_hip_checksum, tvb, + offset+6, 2, checksum_h, + "Checksum: 0x%04x (incorrect, should be 0x%04x)", + checksum_h, + in_cksum_shouldbe(checksum_h, computed_checksum)); + } + } else { + proto_tree_add_uint_format(hip_tree, hf_hip_checksum, tvb, + offset+6, 2, checksum_h,"Checksum: 0x%04x (unverified)", + checksum_h); + } + offset += 8; + proto_tree_add_bytes(hip_tree, hf_hip_hit_sndr, tvb, offset, sizeof(hip_hit), hiph.hit_sndr); + offset += sizeof(hip_hit); + proto_tree_add_bytes(hip_tree, hf_hip_hit_rcvr, tvb, offset, sizeof(hip_hit), hiph.hit_rcvr); + offset += sizeof(hip_hit); + + length = (hiph.hdr_len+1)*8; + /* Begin TLV parsing */ + if (offset < length) { + ti_tlv = proto_tree_add_text(hip_tree, tvb, offset, tvb_length(tvb), "HIP Parameters"); + hip_tlv_tree = proto_item_add_subtree(ti_tlv, ett_hip_tlv); + } + /* Parse type and length in TLV */ + while (offset < length) + { + tvb_memcpy(tvb, (guint8 *)&tlv, offset, sizeof(tlv_head)); + tlv_type_h = g_ntohs(tlv.type); + tlv_length_h = g_ntohs(tlv.length); + ti_tlv = proto_tree_add_uint_format(hip_tlv_tree, hf_hip_type, tvb, + offset, 4+tlv_length_h, tlv.type, "%s (type=%u, length=%u)", + hip_param(tlv_type_h), tlv_type_h, tlv_length_h); + + /* Parse value */ + dissect_hip_tlv(tvb, offset, ti_tlv, tlv_type_h, tlv_length_h); + + offset += 11 + tlv_length_h - (tlv_length_h + 3) % 8; + } + + } +} + +void +proto_register_hip(void) +{ +/* Most of this stuff is unused */ + module_t *hip_module; + static hf_register_info hf[] = { + { &hf_hip_proto, + { "Payload Protocol", "hip.proto", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_hdr_len, + { "Header Length", "hip.hdr_len", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_packet_type, + { "Packet Type", "hip.packet_type", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_version, + { "Version", "hip.version", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_res, + { "Reserved", "hip.res", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_controls, + { "HIP Controls", "hip.controls", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_controls_cert, + { "Certificate (One or more CER packets follows)", "hip.controls.c", FT_BOOLEAN, 16, NULL, HIP_CONTROL_C_MASK, "", HFILL }}, + + { &hf_hip_controls_anon, + { "Anonymous (Sender's HI is anonymous)", "hip.controls.a", FT_BOOLEAN, 16, NULL, HIP_CONTROL_A_MASK, "", HFILL }}, + + { &hf_hip_checksum, + { "Checksum", "hip.checksum", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_hit_sndr, + { "Sender's HIT", "hip.hit_sndr", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_hit_rcvr, + { "Receiver's HIT", "hip.hit_rcvr", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_type, + { "Type", "hip.type", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_r1_res, + { "Reserved", "hip.tlv.r1_res", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_r1count, + { "R1 Counter", "hip.tlv.r1count", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_puzzle_k, + { "Puzzle Difficulty K","hip.tlv_puzzle_k", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_puzzle_life, + { "Puzzle Lifetime","hip.tlv_puzzle_life", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_puzzle_o, + { "Opaque Data","hip.tlv_puzzle_o", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_puzzle_i, + { "Puzzle Random I", "hip.tlv.puzzle_i", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_puzzle_j, + { "Puzzle Solution J", "hip.tlv_puzzle_j", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_ei_res, + { "Reserved", "hip.tlv_ei_res", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_ei_keyidx, + { "Keymat Index", "hip.tlv_ei_keyidx", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_ei_oldspi, + { "Old SPI", "hip.tlv_ei_oldspi", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_ei_newspi, + { "New SPI", "hip.tlv_ei_newspi", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_seq_updid, + { "Update ID", "hip.tlv_seq_updid", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_ack_updid, + { "ACKed Peer Update ID", "hip.tlv_ack_updid", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_dh_group_id, + { "Group ID", "hip.tlv.dh_group_id", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_dh_pub, + { "Public Value", "hip.tlv.dh_pub", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_trans_id, + { "Transform ID", "hip.tlv.trans_id", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_esp_reserved, + { "Reserved", "hip.tlv.esp_reserved", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_host_id_len, + { "Host Identity Length","hip.tlv.host_id_len", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_host_di_type, + { "Domain Identifier Type","hip.tlv.host_di_type", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_host_di_len, + { "Domain Identifier Length","hip.tlv.host_di_len", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_host_id_hdr, + { "Host Identity flags","hip.tlv.host_id_hdr", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_host_id_hdr_flags, + { "Flags","hip.tlv.host_id_hdr_flags", FT_UINT32, BASE_HEX, VALS(hi_hdr_flags_vals), HI_HDR_FLAGS_MASK, "", HFILL }}, + + { &hf_hip_tlv_host_id_hdr_proto, + { "Protocol","hip.tlv.host_id_hdr_flags", FT_UINT32, BASE_HEX, VALS(hi_hdr_proto_vals), HI_HDR_PROTO_MASK, "", HFILL }}, + + { &hf_hip_tlv_host_id_hdr_alg, + { "Algorithm","hip.tlv.host_id_hdr_alg", FT_UINT32, BASE_HEX, VALS(hi_hdr_alg_vals), HI_HDR_ALG_MASK, "", HFILL }}, + + { &hf_hip_tlv_host_id_t, + { "Host Identity T","hip.tlv.host_id_t", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_host_id_q, + { "Host Identity Q","hip.tlv.host_id_q", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_host_id_p, + { "Host Identity P","hip.tlv.host_id_p", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_host_id_g, + { "Host Identity G","hip.tlv.host_id_g", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_host_id_y, + { "Host Identity Y (public value)", "hip.tlv.host_id_y", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_host_id_e_len, + { "RSA Host Identity e_len (exponent length)", + "hip.tlv.host_id_e_len", FT_UINT16, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_host_id_e, + { "RSA Host Identity e (exponent)", "hip.tlv.host_id_e", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_host_id_n, + { "RSA Host Identity n (public modulus)", "hip.tlv.host_id_n", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_cert_count, + { "Cert count","hip.tlv.cert_count", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_cert_id, + { "Cert ID","hip.tlv.cert_id", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_cert_type, + { "Cert type","hip.tlv.cert_type", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_certificate, + { "Certificate","hip.tlv.certificate", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_notify_res, + { "Reserved","hip.tlv.notify_res", FT_UINT16, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_notify_type, + { "Notify Message Type","hip.tlv.notify_type", FT_UINT16, BASE_DEC, VALS(notify_vals), 0xFFFF, "", HFILL }}, + + { &hf_hip_tlv_notify_data, + { "Notification Data","hip.tlv.notify_data", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_opaque_data, + { "Opaque Data","hip.tlv.opaque_data", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_reg_ltmin, + { "Minimum Registration Lifetime","hip.tlv.reg_ltmin", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_reg_ltmax, + { "Maximum Registration Lifetime","hip.tlv.reg_ltmax", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_reg_lt, + { "Registration Lifetime","hip.tlv.reg_lt", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_reg_type, + { "Registration Type","hip.tlv.reg_type", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_reg_failtype, + { "Registration Failure Type","hip.tlv.reg_failtype", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_hmac, + { "HMAC","hip.tlv.hmac", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_sig_alg, + { "Signature Algorithm","hip.tlv.sig_alg", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_sig, + { "Signature", "hip.tlv.sig", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_id, + { "ID", "hip.tlv.id", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_enc_reserved, + { "Reserved", "hip.tlv.enc_reserved", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_enc_iv, + { "IV", "hip.tlv.enc_iv", FT_BYTES, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_locator_traffic_type, + { "Traffic Type", "hip.tlv.locator_traffic_type", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_locator_type, + { "Locator Type", "hip.tlv.locator_type", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_locator_len, + { "Locator Length", "hip.tlv.locator_len", FT_UINT8, BASE_DEC, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_locator_reserved, + { "Reserved | P bit", "hip.tlv.locator_reserved", FT_UINT8, BASE_HEX, NULL, 0x0, "", HFILL }}, + + { &hf_hip_tlv_locator_lifetime, + { "Locator Lifetime", "hip.tlv.locator_lifetime", FT_UINT32, BASE_HEX, NULL, 0x0, "", HFILL }}, + + }; + static gint *ett[] = { + &ett_hip, + &ett_hip_controls, + &ett_hip_tlv, + &ett_hip_tlv_data, + &ett_hip_tlv_host_id_hdr, + }; + + proto_hip = proto_register_protocol("Host Identity Protocol", + "HIP", "hip"); + + proto_register_field_array(proto_hip, hf, array_length(hf)); + proto_register_subtree_array(ett, array_length(ett)); + + /* Register configuration preferences */ + hip_module = prefs_register_protocol(proto_hip, NULL); + prefs_register_bool_preference(hip_module, "summary_in_tree", + "Show HIP summary in protocol tree", + "Whether the HIP summary line should be shown in the protocol tree", + &hip_summary_in_tree); +} + +void +proto_reg_handoff_hip(void) +{ + dissector_handle_t hip_handle; + + hip_handle = create_dissector_handle(dissect_hip, proto_hip); + dissector_add("ip.proto", IP_PROTO_HIP, hip_handle); + data_handle = find_dissector("data"); +} + +char * hip_param(int n) +{ + static char s[24]; + + switch (n) + { + //case 0: /* sometimes extra padding */ + // return NULL; + // break; + case PARAM_ESP_INFO: + sprintf(s, "ESP INFO"); + break; + case PARAM_R1_COUNTER: + sprintf(s, "R1 COUNTER"); + break; + case PARAM_LOCATOR: + sprintf(s, "LOCATOR"); + break; + case PARAM_PUZZLE: + sprintf(s, "PUZZLE"); + break; + case PARAM_SOLUTION: + sprintf(s, "SOLUTION"); + break; + case PARAM_SEQ: + sprintf(s, "SEQ"); + break; + case PARAM_ACK: + sprintf(s, "ACK"); + break; + case PARAM_DIFFIE_HELLMAN: + sprintf(s, "DIFFIE_HELLMAN"); + break; + case PARAM_HIP_TRANSFORM: + sprintf(s, "HIP_TRANSFORM"); + break; + case PARAM_ENCRYPTED: + sprintf(s, "ENCRYPTED"); + break; + case PARAM_HOST_ID: + sprintf(s, "HOST_ID"); + break; + case PARAM_CERT: + sprintf(s, "CERT"); + break; + case PARAM_NOTIFY: + sprintf(s, "NOTIFY"); + break; + case PARAM_ECHO_REQUEST: + sprintf(s, "ECHO_REQUEST"); + break; + case PARAM_ECHO_RESPONSE: + sprintf(s, "ECHO_RESPONSE"); + break; + case PARAM_ESP_TRANSFORM: + sprintf(s, "ESP_TRANSFORM"); + break; + case PARAM_HMAC: + sprintf(s, "HMAC"); + break; + case PARAM_HMAC_2: + sprintf(s, "HMAC_2"); + break; + case PARAM_HIP_SIGNATURE_2: + sprintf(s, "HIP_SIGNATURE_2"); + break; + case PARAM_HIP_SIGNATURE: + sprintf(s, "HIP_SIGNATURE"); + break; + case PARAM_ECHO_REQUEST_NOSIG: + sprintf(s, "ECHO_REQUEST (No sig.)"); + break; + case PARAM_ECHO_RESPONSE_NOSIG: + sprintf(s, "ECHO_RESPONSE (No sig.)"); + break; + default: + sprintf(s, "?UNKNOWN?"); + break; + } + + return s; +} + +char *dh_group_id_label(int groupid) +{ + static char s[26]; + switch(groupid) + { + case 0: + sprintf(s, "Reserved"); + break; + case 1: + sprintf(s, "384-bit group"); + break; + case 2: + sprintf(s, "OAKLEY well-known group 1"); + break; + case 3: + sprintf(s, "1536-bit MODP group"); + break; + case 4: + sprintf(s, "3072-bit MODP group"); + break; + case 5: + sprintf(s, "6144-bit MODP group"); + break; + case 6: + sprintf(s, "8192-bit MODP group"); + break; + default: + sprintf(s, "UNKNOWN?"); + break; + } + return s; + +} + +char *transform_id_label(int transform) +{ + static char s[32]; + switch (transform) + { + case 0: + sprintf(s, "Reserved"); + break; + case 1: + sprintf(s, "AES-CBC with HMAC-SHA1"); + break; + case 2: + sprintf(s, "3DES-CBC with HMAC-SHA1"); + break; + case 3: + sprintf(s, "3DES-CBC with HMAC-MD5"); + break; + case 4: + sprintf(s, "BLOWFISH-CBC with HMAC-SHA1"); + break; + case 5: + sprintf(s, "NULL with HMAC-SHA1"); + break; + case 6: + sprintf(s, "NULL with HMAC-MD5"); + break; + default: + sprintf(s, "UNKNOWN?"); + break; + + } + return s; +} + +char *sig_alg_label(int alg) +{ + static char s[10]; + switch (alg) + { + case 0: + sprintf(s, "Reserved"); + break; + case HI_ALG_DSA: + sprintf(s, "DSA"); + break; + case HI_ALG_RSA: + sprintf(s, "RSA"); + break; + default: + sprintf(s, "UNKNOWN?"); + break; + + } + return s; +} + + +int dissect_hip_tlv(tvbuff_t *tvb, int offset, proto_item *ti, int type, int tlv_len) +{ + proto_tree *t=NULL; + proto_item *ti_tlv; + guint8 data[512]; + guint8 n, algorithm, reg_type; + guint16 trans, hi_len, di_len, di_type, e_len; + guint32 reserved, hi_hdr; + int newoffset, newlen, hi_t; + + switch (type) + { + case PARAM_ESP_INFO: + t = proto_item_add_subtree(ti, ett_hip_tlv_data); + proto_tree_add_uint(t, hf_hip_tlv_ei_res, tvb, offset+4, 2, + tvb_get_ntohs(tvb, offset+4)); + proto_tree_add_uint(t, hf_hip_tlv_ei_keyidx, tvb, offset+6, 2, + tvb_get_ntohs(tvb, offset+6)); + proto_tree_add_uint(t, hf_hip_tlv_ei_oldspi, tvb, offset+8, 4, + tvb_get_ntohl(tvb, offset+8)); + proto_tree_add_uint(t, hf_hip_tlv_ei_newspi, tvb, offset+12, 4, + tvb_get_ntohl(tvb, offset+12)); + break; + case PARAM_R1_COUNTER: + t = proto_item_add_subtree(ti, ett_hip_tlv_data); + proto_tree_add_uint(t, hf_hip_tlv_r1_res, tvb, offset+4, 4, + tvb_get_ntohl(tvb, offset+4)); + tvb_memcpy(tvb, (guint8*)data, offset+8, 8); + proto_tree_add_bytes(t, hf_hip_tlv_r1count, tvb, offset+8, 8, data); + break; + case PARAM_LOCATOR: + t = proto_item_add_subtree(ti, ett_hip_tlv_data); + tlv_len -= 4; + newoffset = offset + 4; + while (tlv_len > 0) { + proto_tree_add_uint(t, hf_hip_tlv_locator_traffic_type, tvb, + newoffset, 1, tvb_get_guint8(tvb, newoffset)); + newoffset++; + proto_tree_add_uint(t, hf_hip_tlv_locator_type, tvb, + newoffset, 1, tvb_get_guint8(tvb, newoffset)); + newoffset++; + proto_tree_add_uint(t, hf_hip_tlv_locator_len, tvb, + newoffset, 1, tvb_get_guint8(tvb, newoffset)); + newoffset++; + reserved = tvb_get_guint8(tvb, newoffset); + proto_tree_add_uint_format(t, hf_hip_tlv_locator_reserved, tvb, + newoffset, 1, reserved, "Reserved: 0x%x %s", reserved, + (reserved >> 31) ? "(Preferred)" : ""); + newoffset++; + proto_tree_add_uint(t, hf_hip_tlv_locator_lifetime, tvb, + newoffset, 4, tvb_get_ntohl(tvb, newoffset)); + newoffset += 4; + proto_tree_add_text(t, tvb, newoffset, 16, "Address: %s", + ip6_to_str((const struct e_in6_addr*) + tvb_get_ptr(tvb, newoffset, 16))); + newoffset += 16; + tlv_len -= 32; + } + break; + case PARAM_PUZZLE: + case PARAM_SOLUTION: + t = proto_item_add_subtree(ti, ett_hip_tlv_data); + proto_tree_add_uint(t, hf_hip_tlv_puzzle_k, tvb, offset+4, 1, + tvb_get_guint8(tvb, offset+4)); + proto_tree_add_uint(t, hf_hip_tlv_puzzle_life, tvb, offset+5, 1, + tvb_get_guint8(tvb, offset+5)); + proto_tree_add_uint(t, hf_hip_tlv_puzzle_o, tvb,offset+6, 2, + tvb_get_ntohs(tvb, offset+6)); + tvb_memcpy(tvb, (guint8*)data, offset+8, 8); + proto_tree_add_bytes(t, hf_hip_tlv_puzzle_i, tvb,offset+8, 8, data); + if (type == PARAM_SOLUTION) { /* solution also contains J */ + tvb_memcpy(tvb, (guint8*)data, offset+16, 8); + proto_tree_add_bytes(t, hf_hip_tlv_puzzle_j, tvb, offset+16, 8, + data); + } + break; + case PARAM_SEQ: /* SEQ */ + t = proto_item_add_subtree(ti, ett_hip_tlv_data); + proto_tree_add_uint(t, hf_hip_tlv_seq_updid, tvb, offset+4, 4, + tvb_get_ntohl(tvb, offset+4)); + break; + case PARAM_ACK: /* ACK */ + t = proto_item_add_subtree(ti, ett_hip_tlv_data); + newoffset = offset + 4; + while (tlv_len > 0) { + proto_tree_add_uint(t, hf_hip_tlv_ack_updid, tvb, newoffset, 4, tvb_get_ntohl(tvb, newoffset)); + newoffset += 4; + tlv_len -= 4; + } + break; + case PARAM_DIFFIE_HELLMAN: /* DIFFIE_HELLMAN */ + t = proto_item_add_subtree(ti, ett_hip_tlv_data); + n = tvb_get_guint8(tvb, offset+4); + proto_tree_add_uint_format(t, hf_hip_tlv_dh_group_id, tvb, offset+4, + 1, n, "%u (%s)", n, dh_group_id_label(n)); + tvb_memcpy(tvb, (guint8*)data, offset+5, tlv_len-1); + proto_tree_add_bytes(t, hf_hip_tlv_dh_pub, tvb, offset+5, tlv_len-1, + data); + break; + case PARAM_ESP_TRANSFORM: /* ESP_TRANSFORM */ + case PARAM_HIP_TRANSFORM: /* HIP_TRANSFORM */ + t = proto_item_add_subtree(ti, ett_hip_tlv_data); + /* ESP transform may have E bit*/ + if (type == PARAM_ESP_TRANSFORM) { + proto_tree_add_uint(t, hf_hip_tlv_esp_reserved, tvb, + offset+4, 2, tvb_get_ntohs(tvb, offset+4)); + newoffset = offset + 6; + tlv_len -= 2; + } else { + newoffset = offset + 4; + /* check for NULL as only HIP transform */ + if (tlv_len == 2) + hip_transform = tvb_get_ntohs(tvb, newoffset); + else + hip_transform = 0; + } + while (tlv_len > 0) { + trans = tvb_get_ntohs(tvb, newoffset); + proto_tree_add_uint_format(t, hf_hip_tlv_trans_id, tvb, + newoffset, 2, trans, "%u (%s)", trans, + transform_id_label(trans)); + tlv_len -= 2; /* two bytes per transform id */ + newoffset += 2; + } + break; + case PARAM_ENCRYPTED: /* ENCRYPTED */ + t = proto_item_add_subtree(ti, ett_hip_tlv_data); + proto_tree_add_uint(t, hf_hip_tlv_enc_reserved, tvb, offset+4, 4, + tvb_get_ntohl(tvb, offset+4)); + if (hip_transform == 5) { /* null encryption, no IV */ + offset += 8; + t = proto_item_add_subtree(t, ett_hip_tlv_data); + } else { /* encrypted data */ + tvb_memcpy(tvb, (guint8*)data, offset+8, 8); + proto_tree_add_bytes(t, hf_hip_tlv_enc_iv,tvb,offset+8,8,data); + proto_tree_add_text(t, tvb, offset+16, tlv_len-12, + "Encrypted Data (%u bytes)", tlv_len-12); + break; + } + case PARAM_HOST_ID: /* HOST_ID */ + if (type != PARAM_ENCRYPTED) + t = proto_item_add_subtree(ti, ett_hip_tlv_data); + /* hi_length, fqdn_length */ + hi_len = tvb_get_ntohs(tvb, offset+4); + di_len = tvb_get_ntohs(tvb, offset+6); + di_type = (di_len >> 12) & 0x000F; /* get 4 bits for DI type */ + di_len = di_len & 0x0FFF; /* 12 bits for DI length */ + proto_tree_add_uint(t, hf_hip_tlv_host_id_len, tvb, offset+4, 2, + hi_len); + proto_tree_add_uint(t, hf_hip_tlv_host_di_type, tvb, offset+6, 1, + di_type); + proto_tree_add_uint(t, hf_hip_tlv_host_di_len, tvb, offset+6, 2, + di_len); + /* hi_hdr - first 4 bytes are 0200ff03 (RFC 2535) + * flags 2 octets + * protocol 1 octet + * algorithm 1 octet (DSA or RSA) + */ + hi_hdr = tvb_get_ntohl(tvb, offset+8); + ti_tlv = proto_tree_add_uint(t, hf_hip_tlv_host_id_hdr, tvb, offset+8, 4, hi_hdr); + if (ti_tlv) { + ti_tlv = proto_item_add_subtree(ti_tlv,ett_hip_tlv_host_id_hdr); + proto_tree_add_uint(ti_tlv, hf_hip_tlv_host_id_hdr_flags, tvb, offset+8,2, hi_hdr); + proto_tree_add_uint(ti_tlv, hf_hip_tlv_host_id_hdr_proto, tvb, offset+10,1, hi_hdr); + proto_tree_add_uint(ti_tlv, hf_hip_tlv_host_id_hdr_alg, tvb, offset+11,1, hi_hdr); + } + algorithm = tvb_get_guint8(tvb, offset+11); + switch (algorithm) { + case HI_ALG_DSA: + /* DSA + * T 1 octet + * Q 20 octets + * P 64 + T*8 octets + * G 64 + T*8 octets + * Y 64 + T*8 octets + */ + /* hi_t */ + proto_tree_add_uint(t, hf_hip_tlv_host_id_t, tvb, offset+12, 1, + tvb_get_guint8(tvb, offset+12)); + hi_t = tvb_get_guint8(tvb, offset+12); + tvb_memcpy(tvb, (guint8*)data, offset+13, 20); + proto_tree_add_bytes(t, hf_hip_tlv_host_id_q, tvb, offset+13, + 20, data); + newoffset = offset + 33; + if (hi_t > 56) /* max 4096 bits */ + break; + newlen = 64 + (hi_t * 8); + tvb_memcpy(tvb, (guint8*)data, newoffset, newlen); + proto_tree_add_bytes(t, hf_hip_tlv_host_id_p, tvb, newoffset, + newlen, data); + newoffset += newlen; + tvb_memcpy(tvb, (guint8*)data, newoffset, newlen); + proto_tree_add_bytes(t, hf_hip_tlv_host_id_g, tvb, newoffset, + newlen, data); + newoffset += newlen; + tvb_memcpy(tvb, (guint8*)data, newoffset, newlen); + proto_tree_add_bytes(t, hf_hip_tlv_host_id_y, tvb, newoffset, + newlen, data); + break; + case HI_ALG_RSA: + /* RSA + * e_len 1 or 3 octets + * e specified by e_len + * n variable length public modulus + */ + e_len = tvb_get_guint8(tvb, offset+12); + newoffset = offset+13; + hi_len -= 5; /* subtract RDATA + e_len */ + if (e_len == 0) { /* e_len is 0 followed by 16-bit value */ + e_len = tvb_get_ntohs(tvb, offset+13); + newoffset += 2; + hi_len -= 2; + } + if (e_len > 512) { /* per, RFC 3110 < 4096 bits */ + proto_tree_add_text(t, tvb, offset+13, 2, + "<< e_len too large >>"); + break; + } + proto_tree_add_uint(t, hf_hip_tlv_host_id_e_len, tvb, offset+12, + (e_len > 255) ? 3:1, e_len); + proto_tree_add_bytes(t, hf_hip_tlv_host_id_e, tvb, newoffset, + e_len, tvb_get_ptr(tvb, newoffset, e_len)); + newoffset += e_len; + hi_len -= e_len; + if ((hi_len > 512) || (hi_len < 0)) { + proto_tree_add_text(t, tvb, newoffset, 1, + "<< Invalid HI length >>"); + break; + } + /* RSA public modulus n */ + proto_tree_add_bytes(t, hf_hip_tlv_host_id_n, tvb, newoffset, + hi_len, tvb_get_ptr(tvb,newoffset,hi_len)); + break; + default: + proto_tree_add_text(t, tvb, offset+11, 1, + "Unknown algorithm type (%d).\n", algorithm); + + break; + } + /* FQDN */ + if (di_type == 0) + break; + if (di_len > sizeof(data)) + di_len = sizeof(data) - 1; + memset(data,0,sizeof(data)); /* this null-terminates the string */ + tvb_memcpy(tvb, (guint8*)data, offset+16+hi_len, di_len); + if (di_type == 1) { + proto_tree_add_text(t, tvb, offset+16+hi_len, di_len, + "FQDN: %s", data); + } else if (di_type == 2) { + proto_tree_add_text(t, tvb, offset+16+hi_len, di_len, + "NAI: %s", data); + } + break; + case PARAM_CERT: /* CERT */ + t = proto_item_add_subtree(ti, ett_hip_tlv_data); + proto_tree_add_uint(t, hf_hip_tlv_cert_count, tvb, offset+4, 1, + tvb_get_guint8(tvb, offset+4)); + proto_tree_add_uint(t, hf_hip_tlv_cert_id, tvb, offset+5, 1, + tvb_get_guint8(tvb, offset+5)); + proto_tree_add_uint(t, hf_hip_tlv_cert_type, tvb, offset+6, 1, + tvb_get_guint8(tvb, offset+6)); + tvb_memcpy(tvb, (guint8*)data, offset+7, tlv_len-3); + proto_tree_add_bytes(t, hf_hip_tlv_certificate, tvb, offset+7, + tlv_len-3, data); + break; + case PARAM_NOTIFY: /* NOTIFY */ + t = proto_item_add_subtree(ti, ett_hip_tlv_data); + proto_tree_add_uint(t, hf_hip_tlv_notify_res, tvb, offset+4, 2, + tvb_get_ntohs(tvb, offset+4)); + proto_tree_add_uint(t, hf_hip_tlv_notify_type, tvb, offset+6, 2, + tvb_get_ntohs(tvb, offset+6)); + tvb_memcpy(tvb, (guint8*)data, offset+8, tlv_len-4); + proto_tree_add_bytes(t, hf_hip_tlv_notify_data, tvb, offset+8, + tlv_len-4, data); + + break; + case PARAM_ECHO_REQUEST: /* ECHO REQUEST */ + case PARAM_ECHO_RESPONSE: /* ECHO RESPONSE */ + case PARAM_ECHO_REQUEST_NOSIG: /* ECHO REQUEST */ + case PARAM_ECHO_RESPONSE_NOSIG: /* ECHO RESPONSE */ + t = proto_item_add_subtree(ti, ett_hip_tlv_data); + tvb_memcpy(tvb, (guint8*)data, offset+4, tlv_len); + proto_tree_add_bytes(t, hf_hip_tlv_opaque_data, tvb, offset+4, + tlv_len, data); + break; + case PARAM_REG_INFO: + case PARAM_REG_REQUEST: + case PARAM_REG_RESPONSE: + case PARAM_REG_FAILED: + /* min lt, max lt | lifetime | failuretype */ + if (type == PARAM_REG_INFO) { /* min lt, max lt */ + proto_tree_add_uint(t, hf_hip_tlv_reg_ltmin, tvb, offset+4, + 1, tvb_get_guint8(tvb, offset+4)); + proto_tree_add_uint(t, hf_hip_tlv_reg_ltmax, tvb, offset+5, + 1, tvb_get_guint8(tvb, offset+5)); + newoffset = 6; + } else if (type == PARAM_REG_FAILED) { /* failure type */ + proto_tree_add_uint(t, hf_hip_tlv_reg_failtype, tvb, offset+4, + 1, tvb_get_guint8(tvb, offset+4)); + newoffset = 5; + } else { /* lifetime */ + proto_tree_add_uint(t, hf_hip_tlv_reg_lt, tvb, offset+4, + 1, tvb_get_guint8(tvb, offset+4)); + newoffset = 5; + } + /* reg type 1 ... n, padding */ + while (tlv_len > 0) { + reg_type = tvb_get_guint8(tvb, newoffset); + proto_tree_add_uint(t, hf_hip_tlv_reg_type, tvb, newoffset, 1, + reg_type); + tlv_len--; /* one byte per registration type */ + newoffset++; + } + break; + case PARAM_RVS_HMAC: /* RVS HMAC */ + case PARAM_HMAC: /* HMAC */ + case PARAM_HMAC_2: /* HMAC */ + t = proto_item_add_subtree(ti, ett_hip_tlv_data); + tvb_memcpy(tvb, (guint8*)data, offset+4, tlv_len); + proto_tree_add_bytes(t, hf_hip_tlv_hmac, tvb, offset+4, + tlv_len,data); + break; + case PARAM_HIP_SIGNATURE_2: /* HIP_SIGNATURE_2 */ + case PARAM_HIP_SIGNATURE: /* HIP_SIGNATURE */ + t = proto_item_add_subtree(ti, ett_hip_tlv_data); + n = tvb_get_guint8(tvb, offset+4); + proto_tree_add_uint_format(t, hf_hip_tlv_sig_alg, tvb, offset+4, 1, + n, "%u (%s)", n, sig_alg_label(n)); + tvb_memcpy(tvb, (guint8*)data, offset+5, tlv_len-1); + proto_tree_add_bytes(t, hf_hip_tlv_sig, tvb, offset+5, tlv_len-1, + data); + break; + case PARAM_FROM: + t = proto_item_add_subtree(ti, ett_hip_tlv_data); + proto_tree_add_text(t, tvb, offset+4, 16, "Address: %s", + ip6_to_str((const struct e_in6_addr*) + tvb_get_ptr(tvb, offset+4, 16))); + break; + case PARAM_VIA_RVS: + t = proto_item_add_subtree(ti, ett_hip_tlv_data); + newoffset = offset + 4; + while (tlv_len > 0) { + proto_tree_add_text(t, tvb, newoffset, 16, "RVS Address: %s", + ip6_to_str((const struct e_in6_addr*) + tvb_get_ptr(tvb, newoffset, 16))); + tlv_len -= 16; + newoffset += 16; + } + break; + default: + break; + } + return (0); +} + diff -urN wireshark-0.99.7.orig/epan/dissectors/register.c wireshark-0.99.7/epan/dissectors/register.c --- wireshark-0.99.7.orig/epan/dissectors/register.c 2007-12-20 21:19:06.000000000 +0100 +++ wireshark-0.99.7/epan/dissectors/register.c 2007-12-20 21:15:05.000000000 +0100 @@ -251,6 +251,7 @@ {extern void proto_register_fp (void); if(cb) (*cb)(RA_REGISTER, "proto_register_fp", client_data); proto_register_fp ();} {extern void proto_register_fr (void); if(cb) (*cb)(RA_REGISTER, "proto_register_fr", client_data); proto_register_fr ();} {extern void proto_register_fractalgeneratorprotocol (void); if(cb) (*cb)(RA_REGISTER, "proto_register_fractalgeneratorprotocol", client_data); proto_register_fractalgeneratorprotocol ();} + {extern void proto_register_hip (void); proto_register_hip ();} {extern void proto_register_frame (void); if(cb) (*cb)(RA_REGISTER, "proto_register_frame", client_data); proto_register_frame ();} {extern void proto_register_ftam (void); if(cb) (*cb)(RA_REGISTER, "proto_register_ftam", client_data); proto_register_ftam ();} {extern void proto_register_ftp (void); if(cb) (*cb)(RA_REGISTER, "proto_register_ftp", client_data); proto_register_ftp ();} @@ -893,6 +894,7 @@ {extern void proto_reg_handoff_dcerpc_frsapi (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_dcerpc_frsapi", client_data); proto_reg_handoff_dcerpc_frsapi ();} {extern void proto_reg_handoff_dcerpc_frsrpc (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_dcerpc_frsrpc", client_data); proto_reg_handoff_dcerpc_frsrpc ();} {extern void proto_reg_handoff_dcerpc_initshutdown (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_dcerpc_initshutdown", client_data); proto_reg_handoff_dcerpc_initshutdown ();} + {extern void proto_reg_handoff_hip (void); proto_reg_handoff_hip ();} {extern void proto_reg_handoff_dcerpc_lsarpc (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_dcerpc_lsarpc", client_data); proto_reg_handoff_dcerpc_lsarpc ();} {extern void proto_reg_handoff_dcerpc_mapi (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_dcerpc_mapi", client_data); proto_reg_handoff_dcerpc_mapi ();} {extern void proto_reg_handoff_dcerpc_messenger (void); if(cb) (*cb)(RA_HANDOFF, "proto_reg_handoff_dcerpc_messenger", client_data); proto_reg_handoff_dcerpc_messenger ();} diff -urN wireshark-0.99.7.orig/epan/ipproto.h wireshark-0.99.7/epan/ipproto.h --- wireshark-0.99.7.orig/epan/ipproto.h 2007-12-20 21:19:06.000000000 +0100 +++ wireshark-0.99.7/epan/ipproto.h 2007-12-20 21:41:08.000000000 +0100 @@ -187,6 +187,7 @@ #define IP_PROTO_MPLS_IN_IP 137 /* MPLS in IP - RFC4023 */ #define IP_PROTO_AX4000 173 /* AX/4000 Testblock - non IANA */ #define IP_PROTO_NCS_HEARTBEAT 224 /* Novell NCS Heartbeat - http://support.novell.com/cgi-bin/search/searchtid.cgi?/10071158.htm */ +#define IP_PROTO_HIP 253 /* Host Identity Protocol */ extern const char *ipprotostr(int proto); diff -urN wireshark-0.99.7.orig/epan/prefs.c wireshark-0.99.7/epan/prefs.c --- wireshark-0.99.7.orig/epan/prefs.c 2007-12-20 21:19:06.000000000 +0100 +++ wireshark-0.99.7/epan/prefs.c 2007-12-20 21:42:40.000000000 +0100 @@ -2172,6 +2172,10 @@ /* Handle old names for UDP preferences. */ if (strcmp(dotp, "udp_summary_in_tree") == 0) pref = prefs_find_preference(module, "summary_in_tree"); + } else if (strcmp(module->name, "hip") == 0) { + /* Handle old names for HIP preferences. */ + if (strcmp(dotp, "hip_summary_in_tree") == 0) + pref = prefs_find_preference(module, "summary_in_tree"); } else if (strcmp(module->name, "ndps") == 0) { /* Handle old names for NDPS preferences. */ if (strcmp(dotp, "desegment_ndps") == 0)