wireshark/epan/dissectors/packet-hip.c
Michael Mann 2eb7b05b8c Convert most UDP dissectors to use "auto" preferences.
Similar to the "tcp.port" changes in I99604f95d426ad345f4b494598d94178b886eb67,
convert dissectors that use "udp.port".

More cleanup done on dissectors that use both TCP and UDP dissector
tables, so that less preference callbacks exist.

Change-Id: If07be9b9e850c244336a7069599cd554ce312dd3
Reviewed-on: https://code.wireshark.org/review/18120
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
2016-10-13 02:51:18 +00:00

1626 lines
71 KiB
C

/* packet-hip.c
* Definitions and routines for HIP control packet disassembly
* Samu Varjonen <samu.varjonen@hiit.fi>
*
* Based on dissector originally created by
* Jeff Ahrenholz <jeffrey.m.ahrenholz@boeing.com>
* Thomas Henderson <thomas.r.henderson@boeing.com>
* Samu Varjonen <samu.varjonen@hiit.fi>
* Thomas Jansen <mithi@mithi.net>
*
* 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.
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <epan/packet.h>
#include <epan/expert.h>
#include <epan/ipproto.h>
#include <epan/in_cksum.h>
void proto_register_hip(void);
void proto_reg_handoff_hip(void);
#define HIP_UDP_PORT 10500
#define HI_ALG_DSA 3
#define HI_ALG_RSA 5
/* HIP packet types */
typedef enum {
HIP_I1=1,
HIP_R1,
HIP_I2,
HIP_R2,
HIP_UPDATE=16,
HIP_NOTIFY=17,
HIP_CLOSE=18,
HIP_CLOSE_ACK=19
} HIP_PACKETS;
/* HIP TLV parameters listed in order of RFCs */
/* RFC 5201 */
#define PARAM_R1_COUNTER 128
#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
/* Type number defined in RFC 5201 contents
in draft-ietf-hip-cert-00 */
#define PARAM_CERT 768
#define PARAM_NOTIFICATION 832
#define PARAM_ECHO_REQUEST_SIGNED 897
#define PARAM_ECHO_RESPONSE_SIGNED 961
#define PARAM_HMAC 61505
#define PARAM_HMAC_2 61569
#define PARAM_HIP_SIGNATURE_2 61633
#define PARAM_HIP_SIGNATURE 61697
#define PARAM_ECHO_REQUEST_UNSIGNED 63661
#define PARAM_ECHO_RESPONSE_UNSIGNED 63425
/* RFC 5202 */
#define PARAM_ESP_INFO 65
#define PARAM_ESP_TRANSFORM 4095
/* RFC 5203 */
#define PARAM_REG_INFO 930
#define PARAM_REG_REQUEST 932
#define PARAM_REG_RESPONSE 934
#define PARAM_REG_FAILED 936
/* RFC 5204 */
#define PARAM_FROM 65498
#define PARAM_RVS_HMAC 65500
#define PARAM_VIA_RVS 65502
/* RFC 5206 */
#define PARAM_LOCATOR 193
/* RFC 5770 */
#define PARAM_NAT_TRAVERSAL_MODE 608
#define PARAM_TRANSACTION_PACING 610
#define PARAM_REG_FROM 950
#define PARAM_RELAY_FROM 63998
#define PARAM_RELAY_TO 64002
#define PARAM_RELAY_HMAC 65520
/* HIPv2 draft-ietf-hip-rfc5201-bis-08 see section 5.2 */
#define PARAM_HIP_CIPHER 579
#define PARAM_HIT_SUITE_LIST 715
/* Bit masks */
#define 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
static const value_string pinfo_vals[] = {
{ HIP_I1, "HIP I1 (HIP Initiator Packet)" },
{ HIP_R1, "HIP R1 (HIP Responder Packet)" },
{ HIP_I2, "HIP I2 (Second HIP Initiator Packet)" },
{ HIP_R2, "HIP R2 (Second HIP Responder Packet)" },
{ HIP_UPDATE, "HIP UPDATE (HIP Update Packet)" },
{ HIP_NOTIFY, "HIP NOTIFY (HIP Notify Packet)" },
{ HIP_CLOSE, "HIP CLOSE (HIP Close Packet)" },
{ HIP_CLOSE_ACK, "HIP CLOSE_ACK (HIP Close Acknowledgment Packet)" },
{ 0, NULL }
};
static const value_string hip_param_vals[] = {
{ PARAM_ESP_INFO, "ESP_INFO" },
{ PARAM_R1_COUNTER, "R1_COUNTER" },
{ PARAM_LOCATOR, "LOCATOR" },
{ PARAM_PUZZLE, "PUZZLE" },
{ PARAM_SOLUTION, "SOLUTION" },
{ PARAM_SEQ, "SEQ" },
{ PARAM_ACK, "ACK" },
{ PARAM_DIFFIE_HELLMAN, "DIFFIE_HELLMAN" },
{ PARAM_HIP_TRANSFORM, "HIP_TRANSFORM" },
{ PARAM_ENCRYPTED, "ENCRYPTED" },
{ PARAM_HOST_ID, "HOST_ID" },
{ PARAM_CERT, "CERT" },
{ PARAM_NOTIFICATION, "NOTIFICATION" },
{ PARAM_ECHO_REQUEST_SIGNED, "ECHO_REQUEST_SIGNED" },
{ PARAM_ECHO_RESPONSE_SIGNED, "ECHO_RESPONSE_SIGNED" },
{ PARAM_ESP_TRANSFORM, "ESP_TRANSFORM" },
{ PARAM_HMAC, "HMAC" },
{ PARAM_HMAC_2, "HMAC_2" },
{ PARAM_HIP_SIGNATURE, "HIP_SIGNATURE" },
{ PARAM_HIP_SIGNATURE_2, "HIP_SIGNATURE_2" },
{ PARAM_ECHO_REQUEST_UNSIGNED, "ECHO_REQUEST_UNSIGNED" },
{ PARAM_ECHO_RESPONSE_UNSIGNED, "ECHO_RESPONSE_UNSIGNED" },
{ PARAM_NAT_TRAVERSAL_MODE, "NAT_TRAVERSAL_MODE" },
{ PARAM_TRANSACTION_PACING, "TRANSACTION_PACING" },
{ PARAM_RELAY_FROM, "RELAY_FROM" },
{ PARAM_RELAY_TO, "RELAY_TO" },
{ PARAM_RELAY_HMAC, "RELAY_HMAC" },
{ PARAM_REG_INFO, "REG_INFO" },
{ PARAM_REG_REQUEST, "REG_REQUEST" },
{ PARAM_REG_RESPONSE, "REG_RESPONSE" },
{ PARAM_REG_FROM, "REG_FROM" },
{ PARAM_HIP_CIPHER, "HIP_CIPHER"},
{ PARAM_HIT_SUITE_LIST, "HIT_SUITE_LIST"},
{ 0, NULL }
};
/* RFC 5201 section 5.2.6. */
static const value_string dh_group_id_vals[] = {
{ 0x0, "Reserved" },
{ 0x01, "384-bit group" },
{ 0x02, "OAKLEY well-known group 1" },
{ 0x03, "1536-bit MODP group" },
{ 0x04, "3072-bit MODP group" },
{ 0x05, "6144-bit MODP group" },
{ 0x06, "8192-bit MODP group" },
{ 0, NULL }
};
/* RFC 5202 section 5.1.2. */
static const value_string transform_id_vals[] = {
{ 0x0, "Reserved" },
{ 0x01, "AES-CBC with HMAC-SHA1" },
{ 0x02, "3DES-CBC with HMAC-SHA1" },
{ 0x03, "3DES-CBC with HMAC-MD5" },
{ 0x04, "BLOWFISH-CBC with HMAC-SHA1" },
{ 0x05, "NULL with HMAC-SHA1" },
{ 0x06, "NULL with HMAC-MD5" },
{ 0, NULL }
};
static const value_string reg_type_vals[] = {
{ 0x01, "RENDEZVOUS" }, /* RFC 5204 */
{ 0x02, "RELAY_UDP_HIP" }, /* RFC 5770 */
{ 0, NULL }
};
/* RFC 5201 section 5.2.8 */
static const value_string sig_alg_vals[] = {
{ 0x0, "Reserved" },
{ HI_ALG_DSA, "DSA" },
{ HI_ALG_RSA, "RSA" },
{ 0, NULL }
};
/* RFC 5770 */
static const value_string mode_id_vals[] = {
{ 0x0, "Reserved" },
{ 0x01, "UDP-encapsulation" },
{ 0x02, "ICE-STUN-UDP" },
{ 0, NULL }
};
static const value_string hi_hdr_flags_vals[] = {
{ 0x0, "Other" },
{ 0x0200, "Key is associated with a user" },
{ 0x0201, "Zone key" },
{ 0x0202, "Key is associated with non-zone entity" },
{ 0, NULL }
};
/* RFC 2535 section 3.1.3 */
static 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" },
{ 0, NULL }
};
/* RFC 2535 section 3.2 */
static 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" },
{ 0, NULL }
};
/* RFC 5201 */
static const value_string notification_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" },
{ 0, NULL }
};
#if 0
/* RFC 5770 */
static const value_string nat_traversal_mode_vals[] = {
{ 0, "Reserved"},
{ 1, "UDP-encapsulation"},
{ 2, "ICE-STUN-UDP"},
{ 0, NULL }
};
#endif
/* HIPv2 draft-ietf-hip-rfc5201-bis-08 Section 5.2 */
static const value_string cipher_vals[] = {
{ 0x0, "Reserved" },
{ 0x01, "NULL-ENCRYPT" },
{ 0x02, "AES-128-CBC" },
{ 0x03, "3DES-CBC" },
{ 0x04, "AES-256-CBC" },
{ 0, NULL }
};
static const value_string hit_suite_vals[] = {
{ 0x00, "Reserved" },
{ 0x01, "RSA,DSA/SHA-256" },
{ 0x02, "ECDSA/SHA384" },
{ 0x03, "ECDSA_LOW/SHA-1" },
{ 0, NULL }
};
/* functions */
static int dissect_hip_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_item *ti, int type, int tlv_len);
static int proto_hip = -1;
static int hf_hip_proto = -1;
static int hf_hip_hdr_len = -1;
static int hf_hip_shim6_fixed_bit_p = -1;
static int hf_hip_packet_type = -1;
static int hf_hip_version = -1;
static int hf_hip_shim6_fixed_bit_s = -1;
static int hf_hip_controls = -1;
static int hf_hip_controls_anon = -1;
static int hf_hip_checksum = -1;
static int hf_hip_checksum_status = -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_solution_k = -1;
static int hf_hip_tlv_solution_reserved = -1;
static int hf_hip_tlv_solution_o = -1;
static int hf_hip_tlv_solution_i = -1;
static int hf_hip_tlv_solution_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_dh_pv_length = -1;
static int hf_hip_tlv_trans_id = -1;
static int hf_hip_tlv_esp_reserved = -1;
static int hf_hip_tlv_cipher_id = -1;
static int hf_hip_tlv_hit_suite_id = -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_notification_res = -1;
static int hf_hip_tlv_notification_type = -1;
static int hf_hip_tlv_notification_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_enc_reserved = -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 hf_hip_tlv_locator_port = -1;
static int hf_hip_tlv_locator_transport_protocol = -1;
static int hf_hip_tlv_locator_kind = -1;
static int hf_hip_tlv_locator_priority = -1;
static int hf_hip_tlv_locator_spi = -1;
static int hf_hip_tlv_locator_address = -1;
static int hf_hip_tlv_cert_group = -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_from_address = -1;
static int hf_hip_tlv_rvs_address = -1;
static int hf_hip_tlv_nat_traversal_mode_id = -1;
static int hf_hip_tlv_transaction_minta = -1;
static int hf_hip_tlv_relay_from_port = -1;
static int hf_hip_tlv_relay_from_protocol = -1;
static int hf_hip_tlv_relay_from_reserved = -1;
static int hf_hip_tlv_relay_from_address = -1;
static int hf_hip_tlv_relay_to_port = -1;
static int hf_hip_tlv_relay_to_protocol = -1;
static int hf_hip_tlv_relay_to_reserved = -1;
static int hf_hip_tlv_relay_to_address = -1;
static int hf_hip_tlv_reg_from_port = -1;
static int hf_hip_tlv_reg_from_protocol = -1;
static int hf_hip_tlv_reg_from_reserved = -1;
static int hf_hip_tlv_reg_from_address = -1;
static int hf_hip_encrypted_parameter_data = -1;
static int hf_hip_fqdn = -1;
static int hf_hip_nai = -1;
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;
static gint ett_hip_locator_data = -1;
static expert_field ei_hip_tlv_host_id_len = EI_INIT;
/* static expert_field ei_hip_tlv_host_id_e_len = EI_INIT; */
static expert_field ei_hip_tlv_host_id_hdr_alg = EI_INIT;
static expert_field ei_hip_checksum = EI_INIT;
/* Dissect the HIP packet */
static void
dissect_hip_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean udp)
{
proto_tree *hip_tree, *hip_tlv_tree=NULL;
proto_item *ti, *ti_tlv;
int length, offset = 0, newoffset = 0;
guint16 control_h, checksum_h;
guint16 tlv_type_h, tlv_length_h; /* For storing in host order */
guint len;
guint reported_len;
vec_t cksum_vec[4];
guint32 phdr[2];
/* Payload format RFC 5201 section 5.1 */
/* hiph_proto; */ /* payload protocol */
guint8 hiph_hdr_len; /* header length */
guint8 hiph_shim6_fixed_bit_s; /* This is always 0 */
guint8 hiph_packet_type; /* packet type */
guint8 hiph_res_ver, hiph_version, hiph_reserved;
/* byte for reserved and version */
guint8 hiph_shim6_fixed_bit_p; /* This is always 1 */
/* checksum_h */ /* checksum */
/* control_h */ /* control */
/* HIP parameters ... */
/* load the top pane info. This should be overwritten by
the next protocol in the stack */
col_set_str(pinfo->cinfo, COL_PROTOCOL, "HIP");
col_clear(pinfo->cinfo, COL_INFO);
newoffset = offset;
/* hiph Proto */
newoffset++;
hiph_hdr_len = tvb_get_guint8(tvb, newoffset);
newoffset++;
hiph_packet_type = tvb_get_guint8(tvb, newoffset);
/* draft-ietf-shim6-proto-12 see section 5.3 */
hiph_shim6_fixed_bit_p = (hiph_packet_type & HIP_SHIM6_FIXED_BIT_P_MASK) >> 7;
hiph_packet_type = hiph_packet_type & HIP_PACKET_TYPE_MASK;
newoffset++;
hiph_res_ver = tvb_get_guint8(tvb, newoffset);
/* divide to reserved and version and shim6_fixed_bit_s
draft-ietf-shim6-proto-12 see section 5.3 */
hiph_version = (hiph_res_ver & HIP_VERSION_MASK) >> 4;
hiph_reserved = hiph_res_ver & HIP_RESERVED_MASK;
hiph_shim6_fixed_bit_s = hiph_res_ver & HIP_SHIM6_FIXED_BIT_S_MASK;
newoffset++;
checksum_h = tvb_get_ntohs(tvb, newoffset);
newoffset += 2;
control_h = tvb_get_ntohs(tvb, newoffset);
col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(hiph_packet_type, pinfo_vals, "Unknown"));
/* populate a tree in the second pane with the status of the link layer (i.e. none) */
ti = proto_tree_add_item(tree, proto_hip, tvb, 0, -1, ENC_NA);
hip_tree = proto_item_add_subtree(ti, ett_hip);
proto_tree_add_item(hip_tree, hf_hip_proto, tvb, offset, 1, ENC_BIG_ENDIAN);
proto_tree_add_item(hip_tree, hf_hip_hdr_len, tvb, offset+1, 1, ENC_BIG_ENDIAN);
proto_tree_add_uint_format(hip_tree, hf_hip_shim6_fixed_bit_p, tvb, offset+2, 1,
hiph_shim6_fixed_bit_p,
"Fixed P-bit: %u (Always zero)",
hiph_shim6_fixed_bit_p);
proto_tree_add_uint(hip_tree, hf_hip_packet_type, tvb, offset+2, 1,
hiph_packet_type);
proto_tree_add_uint_format_value(hip_tree, hf_hip_version, tvb, offset+3, 1,
hiph_version, "%u, Reserved: %u",
hiph_version, hiph_reserved);
proto_tree_add_uint_format(hip_tree, hf_hip_shim6_fixed_bit_s, tvb, offset+3, 1,
hiph_shim6_fixed_bit_s,
"Fixed S-bit: %u (%s)",
hiph_shim6_fixed_bit_s,
((hiph_shim6_fixed_bit_s) ? "HIP" : "SHIM6"));
/* Checksum - this is the same algorithm from UDP, ICMPv6 */
reported_len = tvb_reported_length(tvb);
len = tvb_captured_length(tvb);
if (!pinfo->fragmented && len >= reported_len) {
/* IPv4 or IPv6 addresses */
SET_CKSUM_VEC_PTR(cksum_vec[0], (const guint8 *)pinfo->src.data, pinfo->src.len);
SET_CKSUM_VEC_PTR(cksum_vec[1], (const guint8 *)pinfo->dst.data, pinfo->dst.len);
/* the rest of the pseudo-header */
if (pinfo->src.type == AT_IPv6) {
phdr[0] = reported_len;
phdr[0] = g_htonl(phdr[0]); /* Note: g_htonl() macro may eval arg multiple times */
phdr[1] = g_htonl(IP_PROTO_HIP);
SET_CKSUM_VEC_PTR(cksum_vec[2], (const guint8 *)&phdr, 8);
} else {
phdr[0] = (IP_PROTO_HIP<<16)+reported_len;
phdr[0] = g_htonl(phdr[0]); /* Note: g_htonl() macro may eval arg multiple times */
SET_CKSUM_VEC_PTR(cksum_vec[2], (const guint8 *)&phdr, 4);
}
/* pointer to the HIP header (packet data) */
SET_CKSUM_VEC_TVB(cksum_vec[3], tvb, 0, reported_len);
if (checksum_h == 0 && udp) {
proto_tree_add_checksum(hip_tree, tvb, offset+4, hf_hip_checksum, hf_hip_checksum_status, &ei_hip_checksum, pinfo, 0,
ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY);
} else {
proto_tree_add_checksum(hip_tree, tvb, offset+4, hf_hip_checksum, hf_hip_checksum_status, &ei_hip_checksum, pinfo, in_cksum(cksum_vec, 4),
ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY|PROTO_CHECKSUM_IN_CKSUM);
}
} else {
proto_tree_add_checksum(hip_tree, tvb, offset+4, hf_hip_checksum, hf_hip_checksum_status, &ei_hip_checksum, pinfo, 0,
ENC_BIG_ENDIAN, PROTO_CHECKSUM_NO_FLAGS);
}
ti = proto_tree_add_item(hip_tree, hf_hip_controls, tvb, offset+6, 2, ENC_BIG_ENDIAN);
if (ti) {
/* HIP Controls subtree */
ti = proto_item_add_subtree(ti, ett_hip_controls);
proto_tree_add_boolean(ti, hf_hip_controls_anon, tvb,
offset+7,1, control_h);
}
offset += 8;
proto_tree_add_item(hip_tree, hf_hip_hit_sndr, tvb, offset,
16, ENC_NA);
offset += 16;
proto_tree_add_item(hip_tree, hf_hip_hit_rcvr, tvb, offset,
16, ENC_NA);
offset += 16;
length = (hiph_hdr_len + 1) * 8;
/* Begin TLV parsing */
if (offset < length) {
hip_tlv_tree = proto_tree_add_subtree(hip_tree, tvb, offset,
-1, ett_hip_tlv, NULL, "HIP Parameters");
}
/* Parse type and length in TLV */
while (offset < length)
{
tlv_type_h = tvb_get_ntohs(tvb, offset);
tlv_length_h = tvb_get_ntohs(tvb, offset + 2);
ti_tlv = proto_tree_add_uint_format(hip_tlv_tree, hf_hip_type, tvb,
offset, 4 + tlv_length_h, tlv_type_h,
"%s (type=%u, length=%u)",
val_to_str_const(tlv_type_h, hip_param_vals, "Unknown"),
tlv_type_h, tlv_length_h);
/* Parse value */
dissect_hip_tlv(tvb, pinfo, offset, ti_tlv, tlv_type_h, tlv_length_h);
offset += 11 + tlv_length_h - (tlv_length_h + 3) % 8;
}
}
static int
dissect_hip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
dissect_hip_common(tvb, pinfo, tree, FALSE);
return tvb_captured_length(tvb);
}
static int
dissect_hip_in_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
{
guint32 nullbytes;
tvbuff_t *newtvb;
if (tvb_captured_length(tvb) < 4)
return 0;
nullbytes = tvb_get_ntohl(tvb, 0);
if (nullbytes != 0)
return 0;
newtvb = tvb_new_subset_remaining(tvb, 4);
dissect_hip_common(newtvb, pinfo, tree, TRUE);
return tvb_captured_length(tvb);
}
static int
dissect_hip_tlv(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_item *ti, int type, int tlv_len)
{
proto_tree *t=NULL;
proto_item *ti_tlv, *ti_loc, *hi_len_item, *e_len_item, *arg_item;
guint8 n, algorithm, reg_type;
guint16 trans, hi_len, di_len, di_type, e_len, pv_len;
guint32 reserved, hi_hdr;
guint8 transport_proto;
guint8 locator_type;
int newoffset, newlen, hi_t;
/* move over the TLV */
newoffset = offset + 4;
t = proto_item_add_subtree(ti, ett_hip_tlv_data);
switch (type)
{
case PARAM_ESP_INFO:
/* Reserved */
proto_tree_add_item(t, hf_hip_tlv_ei_res, tvb, newoffset, 2, ENC_BIG_ENDIAN);
/* KEYMAT index */
newoffset += 2;
proto_tree_add_item(t, hf_hip_tlv_ei_keyidx, tvb, newoffset, 2, ENC_BIG_ENDIAN);
/* OLD SPI */
newoffset += 2;
proto_tree_add_item(t, hf_hip_tlv_ei_oldspi, tvb, newoffset, 4, ENC_BIG_ENDIAN);
/* NEW SPI */
newoffset += 4;
proto_tree_add_item(t, hf_hip_tlv_ei_newspi, tvb, newoffset, 4, ENC_BIG_ENDIAN);
break;
case PARAM_R1_COUNTER:
/* Reserved */
proto_tree_add_item(t, hf_hip_tlv_r1_res, tvb, newoffset, 4, ENC_BIG_ENDIAN);
/* R1 generation counter */
newoffset += 4;
proto_tree_add_item(t, hf_hip_tlv_r1count, tvb, newoffset, 8, ENC_NA);
break;
case PARAM_LOCATOR:
/* RFC 5206 section 4. and RFC 5770 section 5.7. for type 2 locators
*/
tlv_len -= 4;
/* loop through included locators */
while (tlv_len > 0) {
/* Every locator to new tree node
* Skip ahead and read the 0 or 1 type locator from 8 bytes
* and type 2 locator from 20 bytes to be used as the top level
* tree_item for this subtree
*/
locator_type = tvb_get_guint8(tvb, newoffset + 1);
if (locator_type == 0) {
ti_loc = proto_tree_add_item(t, hf_hip_tlv_locator_address,
tvb, newoffset + 8, 16, ENC_NA);
} else if (locator_type == 1) {
ti_loc = proto_tree_add_item(t, hf_hip_tlv_locator_address,
tvb, newoffset + 12, 16, ENC_NA);
} else if (locator_type == 2) {
ti_loc = proto_tree_add_item(t, hf_hip_tlv_locator_address,
tvb, newoffset + 20, 16, ENC_NA);
} else {
/* unknown or malformed locator type jumping over it */
ti_loc = NULL;
newoffset += (1 + tvb_get_guint8(tvb, newoffset + 2));
tlv_len -= (1 + tvb_get_guint8(tvb, newoffset + 2));
}
if (locator_type <= 2) {
ti_loc = proto_item_add_subtree(ti_loc, ett_hip_locator_data);
/* Traffic type */
proto_tree_add_item(ti_loc, hf_hip_tlv_locator_traffic_type, tvb,
newoffset, 1, ENC_BIG_ENDIAN);
newoffset++;
/* Locator type */
#if 0
locator_type = tvb_get_guint8(tvb, newoffset);
#endif
proto_tree_add_item(ti_loc, hf_hip_tlv_locator_type, tvb, newoffset, 1, ENC_BIG_ENDIAN);
newoffset++;
/* Locator length */
proto_tree_add_item(ti_loc, hf_hip_tlv_locator_len, tvb, newoffset, 1, ENC_BIG_ENDIAN);
newoffset++;
/* Reserved includes the Preferred bit */
reserved = tvb_get_guint8(tvb, newoffset);
proto_tree_add_uint_format_value(ti_loc, hf_hip_tlv_locator_reserved, tvb,
newoffset, 1, reserved,
"0x%x %s", reserved,
(reserved >> 31) ? "(Preferred)" : "");
newoffset++;
/* Locator lifetime */
proto_tree_add_item(ti_loc, hf_hip_tlv_locator_lifetime, tvb,
newoffset, 4, ENC_BIG_ENDIAN);
newoffset += 4;
if (locator_type == 0) {
/* Locator types 1 and 0 RFC 5206 section 4.2.*/
/* Locator */
proto_tree_add_item(ti_loc, hf_hip_tlv_locator_address,
tvb, newoffset, 16, ENC_NA);
newoffset += 16;
tlv_len -= 24;
} else if (locator_type == 1) {
/* Locator types 1 and 0 RFC 5206 section 4.2.*/
/* SPI */
proto_tree_add_item(ti_loc, hf_hip_tlv_locator_spi, tvb,
newoffset, 4, ENC_BIG_ENDIAN);
newoffset += 4;
/* Locator */
proto_tree_add_item(ti_loc, hf_hip_tlv_locator_address,
tvb, newoffset, 16, ENC_NA);
newoffset += 16;
tlv_len -= 28;
} else if (locator_type == 2) {
/* Locator type 2 RFC 5770 section 5.7. */
/* Tansport port */
proto_tree_add_item(ti_loc, hf_hip_tlv_locator_port, tvb,
newoffset, 2, ENC_BIG_ENDIAN);
newoffset += 2;
/* Transport protocol */
transport_proto = tvb_get_guint8(tvb, newoffset);
/* RFC 5770 section 5.6 */
proto_tree_add_uint_format(ti_loc, hf_hip_tlv_locator_transport_protocol,
tvb, newoffset, 1, transport_proto,
"Transport protocol: %d %s",
transport_proto,
(transport_proto == 17) ?
"(UDP)" : "");
newoffset++;
/* Kind */
proto_tree_add_item(ti_loc, hf_hip_tlv_locator_kind, tvb,
newoffset, 1, ENC_BIG_ENDIAN);
newoffset++;
/* Priority */
proto_tree_add_item(ti_loc, hf_hip_tlv_locator_priority, tvb,
newoffset, 4, ENC_BIG_ENDIAN);
newoffset += 4;
/* SPI */
proto_tree_add_item(ti_loc, hf_hip_tlv_locator_spi, tvb,
newoffset, 4, ENC_BIG_ENDIAN);
newoffset += 4;
/* Locator */
proto_tree_add_item(ti_loc, hf_hip_tlv_locator_address,
tvb, newoffset, 16, ENC_NA);
newoffset += 16;
tlv_len -= 36;
}
}
}
break;
case PARAM_PUZZLE:
/* K number of verified bits */
proto_tree_add_item(t, hf_hip_tlv_puzzle_k, tvb, newoffset, 1, ENC_BIG_ENDIAN);
/* Puzzle lifetime */
newoffset++;
proto_tree_add_item(t, hf_hip_tlv_puzzle_life, tvb, newoffset, 1, ENC_BIG_ENDIAN);
/* Puzzle O*/
newoffset++;
proto_tree_add_item(t, hf_hip_tlv_puzzle_o, tvb, newoffset, 2, ENC_BIG_ENDIAN);
/* Puzzle I */
newoffset += 2;
proto_tree_add_item(t, hf_hip_tlv_puzzle_i, tvb,newoffset, tlv_len - 4, ENC_NA);
break;
case PARAM_SOLUTION:
/* K number of verified bits */
proto_tree_add_item(t, hf_hip_tlv_solution_k, tvb, newoffset, 1, ENC_BIG_ENDIAN);
/* Solution Reserved */
newoffset++;
proto_tree_add_item(t, hf_hip_tlv_solution_reserved, tvb, newoffset, 1, ENC_BIG_ENDIAN);
/* Solution Opaque */
newoffset++;
proto_tree_add_item(t, hf_hip_tlv_solution_o, tvb,newoffset, 2, ENC_BIG_ENDIAN);
/* Solution I */
newoffset += 2;
proto_tree_add_item(t, hf_hip_tlv_solution_i, tvb, newoffset, (tlv_len - 4)/2, ENC_NA);
/* Solution J */
newoffset += (tlv_len - 4) /2;
proto_tree_add_item(t, hf_hip_tlv_solution_j, tvb, newoffset, (tlv_len -4)/2, ENC_NA);
break;
case PARAM_SEQ:
/* Update ID */
proto_tree_add_item(t, hf_hip_tlv_seq_updid, tvb, newoffset, 4, ENC_BIG_ENDIAN);
break;
case PARAM_ACK:
/* Can contain multiple Update IDs from peer */
while (tlv_len > 0) {
/* peer Update ID */
proto_tree_add_item(t, hf_hip_tlv_ack_updid, tvb, newoffset, 4, ENC_BIG_ENDIAN);
newoffset += 4;
tlv_len -= 4;
}
break;
case PARAM_DIFFIE_HELLMAN:
n = tvb_get_guint8(tvb, newoffset);
/* First Group ID*/
proto_tree_add_uint_format(t, hf_hip_tlv_dh_group_id, tvb, newoffset,
1, n, "%u (%s)", n,
val_to_str_const(n, dh_group_id_vals, "Unknown"));
/* First Public value len */
newoffset++;
pv_len = tvb_get_ntohs(tvb, newoffset);
proto_tree_add_item(t, hf_hip_tlv_dh_pv_length, tvb, newoffset, 2, ENC_BIG_ENDIAN);
/* First Public value */
newoffset += 2;
proto_tree_add_item(t, hf_hip_tlv_dh_pub, tvb, newoffset, pv_len, ENC_NA);
/* Check for the second group */
if ((pv_len + newoffset) < tlv_len) {
/* Second Group ID*/
newoffset += pv_len;
proto_tree_add_uint_format(t, hf_hip_tlv_dh_group_id, tvb, newoffset,
1, n, "%u (%s)", n,
val_to_str_const(n, dh_group_id_vals, "Unknown"));
/* Second Public value len */
newoffset += 1;
pv_len = tvb_get_ntohs(tvb, newoffset);
proto_tree_add_item(t, hf_hip_tlv_dh_pv_length, tvb, newoffset, 2, ENC_BIG_ENDIAN);
/* Second Public Value */
newoffset += 2;
proto_tree_add_item(t, hf_hip_tlv_dh_pub, tvb, newoffset,
pv_len, ENC_NA);
}
break;
case PARAM_ESP_TRANSFORM:
/* Reserved */
proto_tree_add_item(t, hf_hip_tlv_esp_reserved, tvb, newoffset, 2, ENC_BIG_ENDIAN);
newoffset +=2;
tlv_len -= 2;
while (tlv_len > 0) {
/* Suite # 1, 2, ..., n
* two bytes per transform id
*/
trans = tvb_get_ntohs(tvb, newoffset);
proto_tree_add_uint_format(t, hf_hip_tlv_trans_id, tvb,
newoffset, 2, trans, "%u (%s)", trans,
val_to_str_const(trans, transform_id_vals, "Unknown"));
tlv_len -= 2;
newoffset += 2;
}
break;
case PARAM_HIP_TRANSFORM:
while (tlv_len > 0) {
/* Suite # 1, 2, ..., n
two bytes per transform id */
trans = tvb_get_ntohs(tvb, newoffset);
proto_tree_add_uint_format(t, hf_hip_tlv_trans_id, tvb,
newoffset, 2, trans, "%u (%s)", trans,
val_to_str_const(trans, transform_id_vals, "Unknown"));
tlv_len -= 2;
newoffset += 2;
}
break;
case PARAM_NAT_TRAVERSAL_MODE:
/* Reserved */
proto_tree_add_item(t, hf_hip_tlv_esp_reserved, tvb, newoffset, 2, ENC_BIG_ENDIAN);
newoffset += 2;
tlv_len -= 2;
while (tlv_len > 0) {
/* Suite # 1, 2, ..., n
two bytes per mode id */
trans = tvb_get_ntohs(tvb, newoffset);
proto_tree_add_uint_format(t, hf_hip_tlv_nat_traversal_mode_id, tvb,
newoffset, 2, trans, "%u (%s)", trans,
val_to_str_const(trans, mode_id_vals, "Unknown"));
tlv_len -= 2;
newoffset += 2;
}
break;
case PARAM_TRANSACTION_PACING:
/* Min Ta */
proto_tree_add_item(t, hf_hip_tlv_transaction_minta, tvb, newoffset, 4, ENC_BIG_ENDIAN);
break;
case PARAM_ENCRYPTED:
/* Reserved */
proto_tree_add_item(t, hf_hip_tlv_enc_reserved, tvb, newoffset, 4, ENC_BIG_ENDIAN);
newoffset += 4;
/* IV
* 16 bytes IV for AES CBC RFC 3602
* 8 bytes IV for 3DES CBC RFC 2405
* 0 bytes IV for NULL
* and
* encrypted data after that.
*/
proto_tree_add_item(t, hf_hip_encrypted_parameter_data, tvb, newoffset, tlv_len - 4, ENC_NA);
break;
case PARAM_HIP_CIPHER:
while (tlv_len > 0) {
/* Suite # 1, 2, ..., n
two bytes per Cipher Suite id */
proto_tree_add_item(t, hf_hip_tlv_cipher_id, tvb, newoffset, 2, ENC_BIG_ENDIAN);
tlv_len -= 2;
newoffset += 2;
}
break;
case PARAM_HIT_SUITE_LIST:
while (tlv_len > 0) {
/* Suite # 1, 2, ..., n
one byte per HIT Suite id.
According to specification, HIT_SUITE_LIST is defined as eight-bit field,
current four-bit HIT Suite-IDs only use the four higher order bits in the ID Field.*/
proto_tree_add_item(t, hf_hip_tlv_hit_suite_id, tvb, newoffset, 1, ENC_BIG_ENDIAN);
tlv_len -= 1;
newoffset += 1;
}
break;
case PARAM_HOST_ID:
hi_len = tvb_get_ntohs(tvb, newoffset);
hi_len_item = proto_tree_add_item(t, hf_hip_tlv_host_id_len, tvb, newoffset, 2, ENC_BIG_ENDIAN);
newoffset += 2;
di_len = tvb_get_ntohs(tvb, newoffset);
di_type = (di_len >> 12) & 0x000F; /* get 4 bits for DI type */
di_len = di_len & 0x0FFF; /* 12 bits for DI length */
/* DI type */
proto_tree_add_item(t, hf_hip_tlv_host_di_type, tvb, newoffset, 1, ENC_BIG_ENDIAN);
/* DI len */
proto_tree_add_item(t, hf_hip_tlv_host_di_len, tvb, newoffset, 2, ENC_BIG_ENDIAN);
newoffset += 2;
/* hi_hdr - first 4 bytes are 0200ff03 (KEY RR in RFC 2535)
* flags 2 octets
* protocol 1 octet
* algorithm 1 octet (DSA or RSA)
* <public key>
*/
hi_hdr = tvb_get_ntohl(tvb, newoffset);
ti_tlv = proto_tree_add_item(t, hf_hip_tlv_host_id_hdr,
tvb, newoffset, 4, ENC_BIG_ENDIAN);
ti_tlv = proto_item_add_subtree(ti_tlv, ett_hip_tlv_host_id_hdr);
/* HDR Flags*/
proto_tree_add_uint(ti_tlv, hf_hip_tlv_host_id_hdr_flags, tvb,
newoffset, 2, hi_hdr);
newoffset += 2;
/* HDR Protocol */
proto_tree_add_uint(ti_tlv, hf_hip_tlv_host_id_hdr_proto, tvb,
newoffset, 1, hi_hdr);
newoffset += 1;
/* HDR Algorithm */
algorithm = tvb_get_guint8(tvb, newoffset);
arg_item = proto_tree_add_uint(ti_tlv, hf_hip_tlv_host_id_hdr_alg, tvb,
newoffset, 1, hi_hdr);
switch (algorithm) {
case HI_ALG_DSA:
/* DSA KEY RR RFC 2536
* T 1 octet
* Q 20 octets
* P 64 + T*8 octets
* G 64 + T*8 octets
* Y 64 + T*8 octets
*/
newoffset++; /* 12 + offset */
/* T */
proto_tree_add_item(t, hf_hip_tlv_host_id_t, tvb, newoffset, 1, ENC_BIG_ENDIAN);
hi_t = tvb_get_guint8(tvb, newoffset);
newoffset++;
/* Q */
proto_tree_add_item(t, hf_hip_tlv_host_id_q, tvb, newoffset,
20, ENC_NA);
newoffset += 20;
if (hi_t > 56) /* max 4096 bits */
break;
/* P */
newlen = 64 + (hi_t * 8);
proto_tree_add_item(t, hf_hip_tlv_host_id_p, tvb, newoffset,
newlen, ENC_NA);
/* G */
newoffset += newlen;
proto_tree_add_item(t, hf_hip_tlv_host_id_g, tvb, newoffset,
newlen, ENC_NA);
/* Y */
newoffset += newlen;
proto_tree_add_item(t, hf_hip_tlv_host_id_y, tvb, newoffset,
newlen, ENC_NA);
break;
case HI_ALG_RSA:
/* RSA KEY RR RFC 3110
* e_len 1 or 3 octets
* e specified by e_len
* n variable length public modulus
*/
newoffset++; /* 12 + offset */
/* E len */
e_len = tvb_get_guint8(tvb, newoffset);
e_len_item = proto_tree_add_item(t, hf_hip_tlv_host_id_e_len, tvb, newoffset,
(e_len > 255) ? 3 : 1, ENC_BIG_ENDIAN);
newoffset++;
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, newoffset);
newoffset += 2;
hi_len -= 2;
}
if (e_len > 512) { /* per, RFC 3110 < 4096 bits */
expert_add_info(pinfo, e_len_item, &ei_hip_tlv_host_id_len);
break;
}
/* e */
proto_tree_add_item(t, hf_hip_tlv_host_id_e, tvb, newoffset,
e_len, ENC_NA);
newoffset += e_len;
hi_len -= e_len;
if (hi_len > 512) {
expert_add_info(pinfo, hi_len_item, &ei_hip_tlv_host_id_len);
break;
}
/* RSA public modulus n */
proto_tree_add_item(t, hf_hip_tlv_host_id_n, tvb, newoffset,
hi_len, ENC_NA);
break;
default:
expert_add_info(pinfo, arg_item, &ei_hip_tlv_host_id_hdr_alg);
break;
}
/* FQDN */
if (di_type == 0)
break;
if (di_type == 1) {
/* RFC 1035 */
proto_tree_add_item(t, hf_hip_fqdn, tvb, offset+16+hi_len, di_len, ENC_ASCII|ENC_NA);
} else if (di_type == 2) {
/* RFC 4282 */
proto_tree_add_item(t, hf_hip_nai, tvb, offset+16+hi_len, di_len, ENC_ASCII|ENC_NA);
}
break;
case PARAM_CERT: /* CERT */
/* Cert Group */
proto_tree_add_item(t, hf_hip_tlv_cert_group, tvb, newoffset, 1, ENC_BIG_ENDIAN);
newoffset++;
/* Cert Count */
proto_tree_add_item(t, hf_hip_tlv_cert_count, tvb, newoffset, 1, ENC_BIG_ENDIAN);
newoffset++;
/* Cert ID */
proto_tree_add_item(t, hf_hip_tlv_cert_id, tvb, newoffset, 1, ENC_BIG_ENDIAN);
newoffset++;
/* Cert Type */
proto_tree_add_item(t, hf_hip_tlv_cert_type, tvb, newoffset, 1, ENC_BIG_ENDIAN);
newoffset++;
/* Certificate */
proto_tree_add_item(t, hf_hip_tlv_certificate, tvb, newoffset,
tlv_len-4, ENC_NA);
break;
case PARAM_NOTIFICATION:
/* Reserved */
proto_tree_add_item(t, hf_hip_tlv_notification_res, tvb, newoffset, 2, ENC_BIG_ENDIAN);
newoffset += 2;
/* Notification Message Type */
proto_tree_add_item(t, hf_hip_tlv_notification_type, tvb, newoffset, 2, ENC_BIG_ENDIAN);
newoffset += 2;
/* Notification Data */
proto_tree_add_item(t, hf_hip_tlv_notification_data, tvb, newoffset,
tlv_len-4, ENC_NA);
break;
case PARAM_ECHO_REQUEST_SIGNED:
case PARAM_ECHO_RESPONSE_SIGNED:
case PARAM_ECHO_REQUEST_UNSIGNED:
case PARAM_ECHO_RESPONSE_UNSIGNED:
/* Variable length Opaque Data */
proto_tree_add_item(t, hf_hip_tlv_opaque_data, tvb, newoffset,
tlv_len, ENC_NA);
break;
case PARAM_REG_INFO:
case PARAM_REG_REQUEST:
case PARAM_REG_RESPONSE:
case PARAM_REG_FAILED:
if (type == PARAM_REG_INFO) {
/* Min Lifetime */
proto_tree_add_item(t, hf_hip_tlv_reg_ltmin, tvb, newoffset, 1, ENC_BIG_ENDIAN);
newoffset++;
/* Max Lifetime */
proto_tree_add_item(t, hf_hip_tlv_reg_ltmax, tvb, newoffset, 1, ENC_BIG_ENDIAN);
newoffset++;
tlv_len -= 2;
} else if (type == PARAM_REG_FAILED) {
/* Failure Type */
proto_tree_add_item(t, hf_hip_tlv_reg_failtype, tvb, newoffset, 1, ENC_BIG_ENDIAN);
newoffset++;
tlv_len--;
} else {
/* Lifetime */
proto_tree_add_item(t, hf_hip_tlv_reg_lt, tvb, newoffset, 1, ENC_BIG_ENDIAN);
newoffset++;
tlv_len--;
}
/* Reg Type 1 ... n, Padding */
while (tlv_len > 0) {
reg_type = tvb_get_guint8(tvb, newoffset);
proto_tree_add_uint_format(t, hf_hip_tlv_reg_type, tvb,
newoffset, 1, reg_type, "%u (%s)", reg_type,
val_to_str_const(reg_type, reg_type_vals, "Unknown"));
/* one byte per registration type */
tlv_len--;
newoffset++;
}
break;
case PARAM_HMAC:
case PARAM_HMAC_2:
case PARAM_RVS_HMAC:
case PARAM_RELAY_HMAC:
/* HMAC */
proto_tree_add_item(t, hf_hip_tlv_hmac, tvb, offset+4,
tlv_len, ENC_NA);
break;
case PARAM_HIP_SIGNATURE:
case PARAM_HIP_SIGNATURE_2:
/* Signature algorithm */
n = tvb_get_guint8(tvb, offset+4);
proto_tree_add_uint_format(t, hf_hip_tlv_sig_alg, tvb, newoffset, 1,
n, "%u (%s)", n,
val_to_str_const(n, sig_alg_vals, "Unknown"));
newoffset++;
/* Signature */
proto_tree_add_item(t, hf_hip_tlv_sig, tvb, newoffset, tlv_len-1,
ENC_NA);
break;
case PARAM_FROM:
/* Address */
proto_tree_add_item(t, hf_hip_tlv_from_address, tvb, newoffset, 16, ENC_NA);
break;
case PARAM_VIA_RVS:
/* RVS Addresses */
while (tlv_len > 0) {
proto_tree_add_item(t, hf_hip_tlv_rvs_address, tvb, newoffset, 16, ENC_NA);
tlv_len -= 16;
newoffset += 16;
}
break;
case PARAM_RELAY_FROM:
/* Port */
proto_tree_add_item(t, hf_hip_tlv_relay_from_port, tvb, newoffset, 2, ENC_BIG_ENDIAN);
newoffset += 2;
/* Protocol */
proto_tree_add_item(t, hf_hip_tlv_relay_from_protocol, tvb, newoffset, 1, ENC_BIG_ENDIAN);
newoffset += 1;
/* Reserved */
proto_tree_add_item(t, hf_hip_tlv_relay_from_reserved, tvb, newoffset, 1, ENC_BIG_ENDIAN);
newoffset += 1;
/* Address */
proto_tree_add_item(t, hf_hip_tlv_relay_from_address, tvb, newoffset, 16, ENC_NA);
break;
case PARAM_RELAY_TO:
/* Port */
proto_tree_add_item(t, hf_hip_tlv_relay_to_port, tvb, newoffset, 2, ENC_BIG_ENDIAN);
newoffset += 2;
/* Protocol */
proto_tree_add_item(t, hf_hip_tlv_relay_to_protocol, tvb, newoffset, 1, ENC_BIG_ENDIAN);
newoffset += 1;
/* Reserved */
proto_tree_add_item(t, hf_hip_tlv_relay_to_reserved, tvb, newoffset, 1, ENC_BIG_ENDIAN);
newoffset += 1;
/* Address */
proto_tree_add_item(t, hf_hip_tlv_relay_to_address, tvb, newoffset, 16, ENC_NA);
break;
case PARAM_REG_FROM:
/* Port */
proto_tree_add_item(t, hf_hip_tlv_reg_from_port, tvb, newoffset, 2, ENC_BIG_ENDIAN);
newoffset += 2;
/* Protocol */
proto_tree_add_item(t, hf_hip_tlv_reg_from_protocol, tvb, newoffset, 1, ENC_BIG_ENDIAN);
newoffset += 1;
/* Reserved */
proto_tree_add_item(t, hf_hip_tlv_reg_from_reserved, tvb, newoffset, 1, ENC_BIG_ENDIAN);
newoffset += 1;
/* Address */
proto_tree_add_item(t, hf_hip_tlv_reg_from_address, tvb, newoffset, 16, ENC_NA);
break;
default:
break;
}
return (0);
}
void
proto_register_hip(void)
{
static hf_register_info hf[] = {
{ &hf_hip_proto,
{ "Payload Protocol", "hip.proto",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_hdr_len,
{ "Header Length", "hip.hdr_len",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_packet_type,
{ "Packet Type", "hip.packet_type",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_shim6_fixed_bit_p,
{ "Header fixed bit P", "hip.shim6_fixed_p",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_version,
{ "Version", "hip.version",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_shim6_fixed_bit_s,
{ "Header fixed bit S", "hip.shim6_fixed_s",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_controls,
{ "HIP Controls", "hip.controls",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_controls_anon,
{ "Anonymous (Sender's HI is anonymous)", "hip.controls.a",
FT_BOOLEAN, 16, NULL, HIP_CONTROL_A_MASK, NULL, HFILL }},
{ &hf_hip_checksum,
{ "Checksum", "hip.checksum",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_checksum_status,
{ "Checksum Status", "hip.checksum.status",
FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0x0, NULL, HFILL }},
{ &hf_hip_hit_sndr,
{ "Sender's HIT", "hip.hit_sndr",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_hit_rcvr,
{ "Receiver's HIT", "hip.hit_rcvr",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_type,
{ "Type", "hip.type",
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_r1_res,
{ "Reserved", "hip.tlv.r1_reserved",
FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_r1count,
{ "R1 Counter", "hip.tlv.r1_counter",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_puzzle_k,
{ "Difficulty (K)", "hip.tlv_puzzle_k",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_puzzle_life,
{ "Lifetime", "hip.tlv_puzzle_lifetime",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_puzzle_o,
{ "Opaque Data", "hip.tlv_puzzle_opaque",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_puzzle_i,
{ "Random number (I)", "hip.tlv.puzzle_random_i",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_solution_k,
{ "Difficulty (K)", "hip.tlv_solution_k",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_solution_reserved,
{ "Reserved", "hip.tlv_solution_reserved",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_solution_o,
{ "Opaque Data", "hip.tlv_solution_opaque",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_solution_i,
{ "Random number (I)", "hip.tlv.solution_random_i",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_solution_j,
{ "Solution (J)", "hip.tlv_solution_j",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_ei_res,
{ "Reserved", "hip.tlv_esp_info_reserved",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_ei_keyidx,
{ "Keymaterial Index", "hip.tlv_esp_info_key_index",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_ei_oldspi,
{ "Old SPI", "hip.tlv_esp_info_old_spi",
FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_ei_newspi,
{ "New SPI", "hip.tlv_esp_info_new_spi",
FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_seq_updid,
{ "Seq Update ID", "hip.tlv_seq_update_id",
FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_ack_updid,
{ "ACKed Peer Update ID", "hip.tlv_ack_updid",
FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_dh_group_id,
{ "Group ID", "hip.tlv.dh_group_id",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_dh_pv_length,
{ "Public Value Length", "hip.tlv.dh_pv_length",
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_dh_pub,
{ "Public Value", "hip.tlv.dh_public_value",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_trans_id,
{ "Transform ID", "hip.tlv.trans_id",
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_esp_reserved,
{ "Reserved", "hip.tlv.esp_trans_res",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_cipher_id,
{ "Cipher ID", "hip.tlv.cipher_id",
FT_UINT16, BASE_DEC, VALS(cipher_vals), 0x0, NULL, HFILL }},
{ &hf_hip_tlv_hit_suite_id,
{ "HIT Suite ID", "hip.tlv.hit_suite_id",
FT_UINT8, BASE_DEC, VALS(hit_suite_vals), 0xF0, NULL, HFILL }},
{ &hf_hip_tlv_host_id_len,
{ "Host Identity Length", "hip.tlv.host_id_length",
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_host_di_type,
{ "Domain Identifier Type", "hip.tlv.host_domain_id_type",
FT_UINT8, BASE_DEC, NULL, 0xF0, NULL, HFILL }},
{ &hf_hip_tlv_host_di_len,
{ "Domain Identifier Length", "hip.tlv.host_domain_id_length",
FT_UINT16, BASE_DEC, NULL, 0x0FFF, NULL, HFILL }},
{ &hf_hip_tlv_host_id_hdr,
{ "Host Identity flags", "hip.tlv.host_id_hdr",
FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_host_id_hdr_flags,
{ "Host Identity Header Flags", "hip.tlv.host_id_header_flags",
FT_UINT32, BASE_HEX, VALS(hi_hdr_flags_vals),
HI_HDR_FLAGS_MASK, NULL, HFILL }},
{ &hf_hip_tlv_host_id_hdr_proto,
{ "Host Identity Header Protocol", "hip.tlv.host_id_header_proto",
FT_UINT32, BASE_HEX, VALS(hi_hdr_proto_vals),
HI_HDR_PROTO_MASK, NULL, HFILL }},
{ &hf_hip_tlv_host_id_hdr_alg,
{ "Host Identity Header Algorithm", "hip.tlv.host_id_header_algo",
FT_UINT32, BASE_HEX, VALS(hi_hdr_alg_vals),
HI_HDR_ALG_MASK, NULL, HFILL }},
{ &hf_hip_tlv_host_id_t,
{ "Host Identity T", "hip.tlv.host_identity_t",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_host_id_q,
{ "Host Identity Q", "hip.tlv.host_identity_q",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_host_id_p,
{ "Host Identity P", "hip.tlv.host_id_p",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_host_id_g,
{ "Host Identity G", "hip.tlv.host_id_g",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_host_id_y,
{ "Host Identity Y (public value)", "hip.tlv.host_id_y",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_host_id_e_len,
{ "RSA Host Identity exponent length (e_len)", "hip.tlv.host_id_e_length",
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_host_id_e,
{ "RSA Host Identity exponent (e)", "hip.tlv.host_id_e",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_host_id_n,
{ "RSA Host Identity public modulus (n)", "hip.tlv.host_id_n",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_notification_res,
{ "Notification Reserved", "hip.tlv.notification_res",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_notification_type,
{ "Notification Message Type", "hip.tlv.notification_type",
FT_UINT16, BASE_DEC, VALS(notification_vals), 0xFFFF, NULL, HFILL }},
{ &hf_hip_tlv_notification_data,
{ "Notification Data", "hip.tlv.notification_data",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_opaque_data,
{ "Opaque Data", "hip.tlv.opaque_data",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_reg_ltmin,
{ "Minimum Registration Lifetime", "hip.tlv.reg_ltmin",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_reg_ltmax,
{ "Maximum Registration Lifetime", "hip.tlv.reg_ltmax",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_reg_lt,
{ "Registration Lifetime", "hip.tlv.reg_lt",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_reg_type,
{ "Registration Type", "hip.tlv.reg_type",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_reg_failtype,
{ "Registration Failure Type", "hip.tlv.reg_failtype",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_hmac,
{ "HMAC", "hip.tlv.hmac",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_sig_alg,
{ "Signature Algorithm", "hip.tlv.sig_alg",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_sig,
{ "Signature", "hip.tlv.sig",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_enc_reserved,
{ "Reserved", "hip.tlv.enc_reserved",
FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_locator_traffic_type,
{ "Traffic Type", "hip.tlv.locator_traffic_type",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_locator_type,
{ "Locator Type", "hip.tlv.locator_type",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_locator_len,
{ "Locator Length", "hip.tlv.locator_len",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_locator_reserved,
{ "Reserved", "hip.tlv.locator_reserved",
FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_locator_lifetime,
{ "Locator Lifetime", "hip.tlv.locator_lifetime",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_locator_port,
{ "Locator port", "hip.tlv.locator_port",
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_locator_transport_protocol,
{ "Locator transport protocol", "hip.tlv.locator_transport_protocol",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_locator_kind,
{ "Locator kind", "hip.tlv.locator_kind",
FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_locator_priority,
{ "Locator priority", "hip.tlv.locator_priority",
FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_locator_spi,
{ "Locator SPI", "hip.tlv.locator_spi",
FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_locator_address,
{ "Locator" , "hip.tlv.locator_address",
FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_cert_group,
{ "Cert group", "hip.tlv.cert_group",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_cert_count,
{ "Cert count", "hip.tlv.cert_count",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_cert_id,
{ "Cert ID", "hip.tlv.cert_id",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_cert_type,
{ "Cert type", "hip.tlv.cert_type",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_certificate,
{ "Certificate", "hip.tlv.certificate",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_nat_traversal_mode_id,
{ "NAT Traversal Mode ID", "hip.tlv.nat_traversal_mode_id",
FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_relay_from_port,
{ "Relay From Port", "hip.tlv.relay_from_port",
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_relay_to_port,
{ "Relay To Port", "hip.tlv.relay_to_port",
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_reg_from_port,
{ "Port", "hip.tlv.reg_from_port",
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_transaction_minta,
{ "Min Ta" , "hip.tlv_transaction_minta",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_from_address,
{ "Address" , "hip.tlv_from_address",
FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_rvs_address,
{ "RVS Address" , "hip.tlv_rvs_address",
FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_relay_from_protocol,
{ "Protocol" , "hip.tlv_relay_from_protocol",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_relay_from_reserved,
{ "Reserved" , "hip.tlv_relay_from_reserved",
FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_relay_from_address,
{ "Address" , "hip.tlv_relay_from_address",
FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_relay_to_protocol,
{ "Protocol" , "hip.tlv_relay_to_protocol",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_relay_to_reserved,
{ "Reserved" , "hip.tlv_relay_to_reserved",
FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_relay_to_address,
{ "Address" , "hip.tlv_relay_to_address",
FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_reg_from_protocol,
{ "Protocol" , "hip.tlv_reg_from_protocol",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_reg_from_reserved,
{ "Reserved" , "hip.tlv_reg_from_reserved",
FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_tlv_reg_from_address,
{ "Address" , "hip.tlv_reg_from_address",
FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_encrypted_parameter_data,
{ "Encrypted Parameter Data" , "hip.encrypted_parameter_data",
FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_fqdn,
{ "FQDN" , "hip.fqdn",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
{ &hf_hip_nai,
{ "NAI" , "hip.nai",
FT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL }},
};
static gint *ett[] = {
&ett_hip,
&ett_hip_controls,
&ett_hip_tlv,
&ett_hip_tlv_data,
&ett_hip_tlv_host_id_hdr,
&ett_hip_locator_data,
};
static ei_register_info ei[] = {
{ &ei_hip_tlv_host_id_len, { "hip.tlv.host_id_length.invalid", PI_PROTOCOL, PI_WARN, "Invalid HI length", EXPFILL }},
#if 0
{ &ei_hip_tlv_host_id_e_len, { "hip.tlv.host_id_e_length.invalid", PI_PROTOCOL, PI_WARN, "e_len too large", EXPFILL }},
#endif
{ &ei_hip_tlv_host_id_hdr_alg, { "hip.tlv.host_id_header_algo.invalid", PI_PROTOCOL, PI_WARN, "Unknown algorithm type", EXPFILL }},
{ &ei_hip_checksum, { "hip.bad_checksum", PI_CHECKSUM, PI_ERROR, "Bad checksum", EXPFILL }},
};
expert_module_t* expert_hip;
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));
expert_hip = expert_register_protocol(proto_hip);
expert_register_field_array(expert_hip, ei, array_length(ei));
}
void
proto_reg_handoff_hip(void)
{
dissector_handle_t hip_handle;
dissector_handle_t hip_handle2;
hip_handle = create_dissector_handle(dissect_hip, proto_hip);
dissector_add_uint("ip.proto", IP_PROTO_HIP, hip_handle);
hip_handle2 = create_dissector_handle(dissect_hip_in_udp, proto_hip);
dissector_add_uint_with_preference("udp.port", HIP_UDP_PORT, hip_handle2);
}
/*
* Editor modelines - http://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 8
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=8 tabstop=8 expandtab:
* :indentSize=8:tabSize=8:noTabs=true:
*/