2 * Definitions and routines for HIP control packet disassembly
3 * Samu Varjonen <samu.varjonen@hiit.fi>
7 * Based on dissector originally created by
8 * Jeff Ahrenholz <jeffrey.m.ahrenholz@boeing.com>
9 * Thomas Henderson <thomas.r.henderson@boeing.com>
10 * Samu Varjonen <samu.varjonen@hiit.fi>
11 * Thomas Jansen <mithi@mithi.net>
13 * Packet dissector for Host Identity Protocol (HIP) packets.
14 * This tool displays the TLV structure, verifies checksums,
15 * and shows NULL encrypted parameters, but will not verify
16 * signatures or decode encrypted parameters.
18 * Wireshark - Network traffic analyzer
19 * By Gerald Combs <gerald@wireshark.org>
20 * Copyright 1998 Gerald Combs
22 * This program is free software; you can redistribute it and/or
23 * modify it under the terms of the GNU General Public License
24 * as published by the Free Software Foundation; either version 2
25 * of the License, or (at your option) any later version.
27 * This program is distributed in the hope that it will be useful,
28 * but WITHOUT ANY WARRANTY; without even the implied warranty of
29 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 * GNU General Public License for more details.
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
41 #include <epan/packet.h>
42 #include <epan/addr_resolv.h>
44 #include <epan/ipproto.h>
45 #include <epan/in_cksum.h>
50 /* HIP packet types */
62 /* HIP TLV parameters listed in order of RFCs */
65 #define PARAM_R1_COUNTER 128
66 #define PARAM_PUZZLE 257
67 #define PARAM_SOLUTION 321
70 #define PARAM_DIFFIE_HELLMAN 513
71 #define PARAM_HIP_TRANSFORM 577
72 #define PARAM_ENCRYPTED 641
73 #define PARAM_HOST_ID 705
74 /* Type number defined in RFC 5201 contents
75 in draft-ietf-hip-cert-00 */
76 #define PARAM_CERT 768
77 #define PARAM_NOTIFICATION 832
78 #define PARAM_ECHO_REQUEST_SIGNED 897
79 #define PARAM_ECHO_RESPONSE_SIGNED 961
80 #define PARAM_HMAC 61505
81 #define PARAM_HMAC_2 61569
82 #define PARAM_HIP_SIGNATURE_2 61633
83 #define PARAM_HIP_SIGNATURE 61697
84 #define PARAM_ECHO_REQUEST_UNSIGNED 63661
85 #define PARAM_ECHO_RESPONSE_UNSIGNED 63425
87 #define PARAM_ESP_INFO 65
88 #define PARAM_ESP_TRANSFORM 4095
90 #define PARAM_REG_INFO 930
91 #define PARAM_REG_REQUEST 932
92 #define PARAM_REG_RESPONSE 934
93 #define PARAM_REG_FAILED 936
95 #define PARAM_FROM 65498
96 #define PARAM_RVS_HMAC 65500
97 #define PARAM_VIA_RVS 65502
99 #define PARAM_LOCATOR 193
100 /* RFC-ietf-hip-nat-traversal-09.txt */
101 #define PARAM_NAT_TRAVERSAL_MODE 608
102 #define PARAM_TRANSACTION_PACING 610
103 #define PARAM_REG_FROM 950
104 #define PARAM_RELAY_FROM 63998
105 #define PARAM_RELAY_TO 64002
106 #define PARAM_RELAY_HMAC 65520
109 #define PARAM_CRITICAL_BIT 0x0001
110 /* See RFC 5201 section 5.1 */
111 #define HIP_PACKET_TYPE_MASK 0x7F
112 /* draft-ietf-shim6-proto-12 see section 5.3 */
113 #define HIP_SHIM6_FIXED_BIT_P_MASK 0x80
114 #define HIP_SHIM6_FIXED_BIT_S_MASK 0x01
115 /* 00001110 Excluding the shim6 compatibility bit */
116 #define HIP_RESERVED_MASK 0x0E
117 #define HIP_VERSION_MASK 0xF0
118 #define HIP_CONTROL_A_MASK 0x0001
119 #define HIP_CONTROL_C_MASK 0x0002
120 #define HI_HDR_FLAGS_MASK 0xFFFF0000
121 #define HI_HDR_PROTO_MASK 0x0000FF00
122 #define HI_HDR_ALG_MASK 0x000000FF
124 static const value_string pinfo_vals[] = {
125 { HIP_I1, "HIP I1 (HIP Initiator Packet)" },
126 { HIP_R1, "HIP R1 (HIP Responder Packet)" },
127 { HIP_I2, "HIP I2 (Second HIP Initiator Packet)" },
128 { HIP_R2, "HIP R2 (Second HIP Responder Packet)" },
129 { HIP_UPDATE, "HIP UPDATE (HIP Update Packet)" },
130 { HIP_NOTIFY, "HIP NOTIFY (HIP Notify Packet)" },
131 { HIP_CLOSE, "HIP CLOSE (HIP Close Packet)" },
132 { HIP_CLOSE_ACK, "HIP CLOSE_ACK (HIP Close Acknowledgment Packet)" },
136 static const value_string hip_param_vals[] = {
137 { PARAM_ESP_INFO, "ESP_INFO" },
138 { PARAM_R1_COUNTER, "R1_COUNTER" },
139 { PARAM_LOCATOR, "LOCATOR" },
140 { PARAM_PUZZLE, "PUZZLE" },
141 { PARAM_SOLUTION, "SOLUTION" },
142 { PARAM_SEQ, "SEQ" },
143 { PARAM_ACK, "ACK" },
144 { PARAM_DIFFIE_HELLMAN, "DIFFIE_HELLMAN" },
145 { PARAM_HIP_TRANSFORM, "HIP_TRANSFORM" },
146 { PARAM_ENCRYPTED, "ENCRYPTED" },
147 { PARAM_HOST_ID, "HOST_ID" },
148 { PARAM_CERT, "CERT" },
149 { PARAM_NOTIFICATION, "NOTIFICATION" },
150 { PARAM_ECHO_REQUEST_SIGNED, "ECHO_REQUEST_SIGNED" },
151 { PARAM_ECHO_RESPONSE_SIGNED, "ECHO_RESPONSE_SIGNED" },
152 { PARAM_ESP_TRANSFORM, "ESP_TRANSFORM" },
153 { PARAM_HMAC, "HMAC" },
154 { PARAM_HMAC_2, "HMAC_2" },
155 { PARAM_HIP_SIGNATURE, "HIP_SIGNATURE" },
156 { PARAM_HIP_SIGNATURE_2, "HIP_SIGNATURE_2" },
157 { PARAM_ECHO_REQUEST_UNSIGNED, "ECHO_REQUEST_UNSIGNED" },
158 { PARAM_ECHO_RESPONSE_UNSIGNED, "ECHO_RESPONSE_UNSIGNED" },
159 { PARAM_NAT_TRAVERSAL_MODE, "NAT_TRAVERSAL_MODE" },
160 { PARAM_TRANSACTION_PACING, "TRANSACTION_PACING" },
161 { PARAM_RELAY_FROM, "RELAY_FROM" },
162 { PARAM_RELAY_TO, "RELAY_TO" },
163 { PARAM_RELAY_HMAC, "RELAY_HMAC" },
164 { PARAM_REG_INFO, "REG_INFO" },
165 { PARAM_REG_REQUEST, "REG_REQUEST" },
166 { PARAM_REG_RESPONSE, "REG_RESPONSE" },
167 { PARAM_REG_FROM, "REG_FROM" },
171 /* RFC 5201 section 5.2.6. */
172 static const value_string dh_group_id_vals[] = {
174 { 0x01, "384-bit group" },
175 { 0x02, "OAKLEY well-known group 1" },
176 { 0x03, "1536-bit MODP group" },
177 { 0x04, "3072-bit MODP group" },
178 { 0x05, "6144-bit MODP group" },
179 { 0x06, "8192-bit MODP group" },
183 /* RFC 5202 section 5.1.2. */
184 static const value_string transform_id_vals[] = {
186 { 0x01, "AES-CBC with HMAC-SHA1" },
187 { 0x02, "3DES-CBC with HMAC-SHA1" },
188 { 0x03, "3DES-CBC with HMAC-MD5" },
189 { 0x04, "BLOWFISH-CBC with HMAC-SHA1" },
190 { 0x05, "NULL with HMAC-SHA1" },
191 { 0x06, "NULL with HMAC-MD5" },
195 static const value_string reg_type_vals[] = {
196 { 0x01, "RENDEZVOUS" }, /* RFC 5204 */
197 { 0x02, "RELAY_UDP_HIP" }, /* draft-ietf-hip-nat-traversal-09.txt */
201 /* RFC 5201 section 5.2.8 */
202 static const value_string sig_alg_vals[] = {
204 { HI_ALG_DSA, "DSA" },
205 { HI_ALG_RSA, "RSA" },
209 /* draft-ietf-hip-nat-traversal-09.txt */
210 static const value_string mode_id_vals[] = {
212 { 0x01, "UDP-encapsulation" },
213 { 0x02, "ICE-STUN-UDP" },
217 static const value_string hi_hdr_flags_vals[] = {
219 { 0x0200, "Key is associated with a user" },
220 { 0x0201, "Zone key" },
221 { 0x0202, "Key is associated with non-zone entity" },
225 /* RFC 2535 section 3.1.3 */
226 static const value_string hi_hdr_proto_vals[] = {
227 { 0x01, "Key is used for TLS" },
228 { 0x02, "Key is used for email" },
229 { 0x03, "Key is used for DNS security" },
230 { 0x04, "Key is used for Oakley/IPSEC" },
231 { 0xFF, "Key is valid for any protocol" },
235 /* RFC 2535 section 3.2 */
236 static const value_string hi_hdr_alg_vals[] = {
237 { 0x00, "Reserved" },
239 { 0x02, "Diffie-Hellman" },
241 { 0x04, "elliptic curve crypto" },
243 { 0xFF, "Reserved" },
248 static const value_string notification_vals[] = {
249 { 1, "Unsupported critical parameter type" },
250 { 7, "Invalid syntax" },
251 { 14, "No Diffie-Hellman proposal chosen" },
252 { 15, "Invalid Diffie-Hellman chosen" },
253 { 16, "No HIP proposal chosen" },
254 { 17, "Invalid HIP transform chosen" },
255 { 18, "No ESP proposal chosen" },
256 { 19, "Invalid ESP transform chosen" },
257 { 24, "Authentication failed" },
258 { 26, "Checksum failed" },
259 { 28, "HMAC failed" },
260 { 32, "Encryption failed" },
261 { 40, "Invalid HIT" },
262 { 42, "Blocked by policy" },
263 { 44, "Server busy please retry" },
267 /* draft-ietf-hip-nat-traversal-09.txt */
268 static const value_string nat_traversal_mode_vals[] = {
270 { 1, "UDP-encapsulation"},
271 { 2, "ICE-STUN-UDP"},
276 static int dissect_hip_tlv(tvbuff_t *tvb, int offset, proto_item *ti, int type, int tlv_len);
278 static int proto_hip = -1;
279 static int hf_hip_proto = -1;
280 static int hf_hip_hdr_len = -1;
281 static int hf_hip_shim6_fixed_bit_p = -1;
282 static int hf_hip_packet_type = -1;
283 static int hf_hip_version = -1;
284 static int hf_hip_shim6_fixed_bit_s = -1;
285 static int hf_hip_controls = -1;
286 static int hf_hip_controls_anon = -1;
287 static int hf_hip_checksum = -1;
288 static int hf_hip_hit_sndr = -1;
289 static int hf_hip_hit_rcvr = -1;
291 static int hf_hip_type = -1;
292 static int hf_hip_tlv_ei_res = -1;
293 static int hf_hip_tlv_ei_keyidx = -1;
294 static int hf_hip_tlv_ei_oldspi = -1;
295 static int hf_hip_tlv_ei_newspi = -1;
296 static int hf_hip_tlv_r1_res = -1;
297 static int hf_hip_tlv_r1count = -1;
298 static int hf_hip_tlv_puzzle_k = -1;
299 static int hf_hip_tlv_puzzle_life = -1;
300 static int hf_hip_tlv_puzzle_o = -1;
301 static int hf_hip_tlv_puzzle_i = -1;
302 static int hf_hip_tlv_solution_k = -1;
303 static int hf_hip_tlv_solution_reserved = -1;
304 static int hf_hip_tlv_solution_o = -1;
305 static int hf_hip_tlv_solution_i = -1;
306 static int hf_hip_tlv_solution_j = -1;
307 static int hf_hip_tlv_seq_updid = -1;
308 static int hf_hip_tlv_ack_updid = -1;
309 static int hf_hip_tlv_dh_group_id = -1;
310 static int hf_hip_tlv_dh_pub = -1;
311 static int hf_hip_tlv_dh_pv_length = -1;
312 static int hf_hip_tlv_trans_id = -1;
313 static int hf_hip_tlv_esp_reserved = -1;
314 static int hf_hip_tlv_host_id_len = -1;
315 static int hf_hip_tlv_host_di_type = -1;
316 static int hf_hip_tlv_host_di_len = -1;
317 static int hf_hip_tlv_host_id_hdr = -1;
318 static int hf_hip_tlv_host_id_hdr_flags = -1;
319 static int hf_hip_tlv_host_id_hdr_proto = -1;
320 static int hf_hip_tlv_host_id_hdr_alg = -1;
321 static int hf_hip_tlv_host_id_t = -1;
322 static int hf_hip_tlv_host_id_q = -1;
323 static int hf_hip_tlv_host_id_p = -1;
324 static int hf_hip_tlv_host_id_g = -1;
325 static int hf_hip_tlv_host_id_y = -1;
326 static int hf_hip_tlv_host_id_e_len = -1;
327 static int hf_hip_tlv_host_id_e = -1;
328 static int hf_hip_tlv_host_id_n = -1;
329 static int hf_hip_tlv_notification_res = -1;
330 static int hf_hip_tlv_notification_type = -1;
331 static int hf_hip_tlv_notification_data = -1;
332 static int hf_hip_tlv_opaque_data = -1;
333 static int hf_hip_tlv_reg_ltmin = -1;
334 static int hf_hip_tlv_reg_ltmax = -1;
335 static int hf_hip_tlv_reg_lt = -1;
336 static int hf_hip_tlv_reg_type = -1;
337 static int hf_hip_tlv_reg_failtype = -1;
338 static int hf_hip_tlv_hmac = -1;
339 static int hf_hip_tlv_sig_alg = -1;
340 static int hf_hip_tlv_sig = -1;
341 static int hf_hip_tlv_enc_reserved = -1;
342 static int hf_hip_tlv_locator_traffic_type = -1;
343 static int hf_hip_tlv_locator_type = -1;
344 static int hf_hip_tlv_locator_len = -1;
345 static int hf_hip_tlv_locator_reserved = -1;
346 static int hf_hip_tlv_locator_lifetime = -1;
347 static int hf_hip_tlv_locator_port = -1;
348 static int hf_hip_tlv_locator_transport_protocol = -1;
349 static int hf_hip_tlv_locator_kind = -1;
350 static int hf_hip_tlv_locator_priority = -1;
351 static int hf_hip_tlv_locator_spi = -1;
352 static int hf_hip_tlv_locator_address = -1;
354 static int hf_hip_tlv_cert_group = -1;
355 static int hf_hip_tlv_cert_count = -1;
356 static int hf_hip_tlv_cert_id = -1;
357 static int hf_hip_tlv_cert_type = -1;
358 static int hf_hip_tlv_certificate = -1;
360 static int hf_hip_tlv_from_address = -1;
361 static int hf_hip_tlv_rvs_address = -1;
363 static int hf_hip_tlv_nat_traversal_mode_id = -1;
364 static int hf_hip_tlv_transaction_minta = -1;
365 static int hf_hip_tlv_relay_from_port = -1;
366 static int hf_hip_tlv_relay_from_protocol = -1;
367 static int hf_hip_tlv_relay_from_reserved = -1;
368 static int hf_hip_tlv_relay_from_address = -1;
369 static int hf_hip_tlv_relay_to_port = -1;
370 static int hf_hip_tlv_relay_to_protocol = -1;
371 static int hf_hip_tlv_relay_to_reserved = -1;
372 static int hf_hip_tlv_relay_to_address = -1;
373 static int hf_hip_tlv_reg_from_port = -1;
374 static int hf_hip_tlv_reg_from_protocol = -1;
375 static int hf_hip_tlv_reg_from_reserved = -1;
376 static int hf_hip_tlv_reg_from_address = -1;
378 static gint ett_hip = -1;
379 static gint ett_hip_controls = -1;
380 static gint ett_hip_tlv = -1;
381 static gint ett_hip_tlv_data = -1;
382 static gint ett_hip_tlv_host_id_hdr = -1;
383 static gint ett_hip_locator_data = -1;
385 /* Dissect the HIP packet */
387 dissect_hip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
389 proto_tree *hip_tree, *hip_tlv_tree=NULL;
390 proto_item *ti, *ti_tlv;
391 int length, offset = 0, newoffset = 0;
392 guint16 control_h, checksum_h, computed_checksum;
393 guint16 tlv_type_h, tlv_length_h; /* For storing in host order */
397 /* Payload format RFC 5201 section 5.1 */
398 guint8 hiph_proto; /* payload protocol */
399 guint8 hiph_hdr_len; /* header length */
400 guint8 hiph_shim6_fixed_bit_s; /* This is always 0 */
401 guint8 hiph_packet_type; /* packet type */
402 guint8 hiph_res_ver, hiph_version, hiph_reserved;
403 /* byte for reserved and version */
404 guint8 hiph_shim6_fixed_bit_p; /* This is always 1 */
405 /* checksum_h */ /* checksum */
406 /* control_h */ /* control */
407 /* HIP parameters ... */
409 /* load the top pane info. This should be overwritten by
410 the next protocol in the stack */
411 col_set_str(pinfo->cinfo, COL_PROTOCOL, "HIP");
412 col_clear(pinfo->cinfo, COL_INFO);
415 hiph_proto = tvb_get_guint8(tvb, newoffset);
417 hiph_hdr_len = tvb_get_guint8(tvb, newoffset);
419 hiph_packet_type = tvb_get_guint8(tvb, newoffset);
420 /* draft-ietf-shim6-proto-12 see section 5.3 */
421 hiph_shim6_fixed_bit_p = (hiph_packet_type & HIP_SHIM6_FIXED_BIT_P_MASK) >> 7;
422 hiph_packet_type = hiph_packet_type & HIP_PACKET_TYPE_MASK;
424 hiph_res_ver = tvb_get_guint8(tvb, newoffset);
425 /* divide to reserved and version and shim6_fixed_bit_s
426 draft-ietf-shim6-proto-12 see section 5.3 */
427 hiph_version = (hiph_res_ver & HIP_VERSION_MASK) >> 4;
428 hiph_reserved = hiph_res_ver & HIP_RESERVED_MASK;
429 hiph_shim6_fixed_bit_s = hiph_res_ver & HIP_SHIM6_FIXED_BIT_S_MASK;
431 checksum_h = tvb_get_ntohs(tvb, newoffset);
433 control_h = tvb_get_ntohs(tvb, newoffset);
436 col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(hiph_packet_type, pinfo_vals, "Unknown"));
438 /* populate a tree in the second pane with the status of the link layer (i.e. none) */
440 ti = proto_tree_add_item(tree, proto_hip, tvb, 0, -1, FALSE);
442 hip_tree = proto_item_add_subtree(ti, ett_hip);
443 proto_tree_add_item(hip_tree, hf_hip_proto, tvb, offset, 1, FALSE);
444 proto_tree_add_item(hip_tree, hf_hip_hdr_len, tvb, offset+1, 1, FALSE);
445 proto_tree_add_uint_format(hip_tree, hf_hip_shim6_fixed_bit_p, tvb, offset+2, 1,
446 hiph_shim6_fixed_bit_p,
447 "Fixed P-bit: %u (Always zero)",
448 hiph_shim6_fixed_bit_p);
449 proto_tree_add_uint(hip_tree, hf_hip_packet_type, tvb, offset+2, 1,
451 proto_tree_add_uint_format(hip_tree, hf_hip_version, tvb, offset+3, 1,
452 hiph_version, "Version: %u, Reserved: %u",
453 hiph_version, hiph_reserved);
454 proto_tree_add_uint_format(hip_tree, hf_hip_shim6_fixed_bit_s, tvb, offset+3, 1,
455 hiph_shim6_fixed_bit_s,
456 "Fixed S-bit: %u (%s)",
457 hiph_shim6_fixed_bit_s,
458 ((hiph_shim6_fixed_bit_s) ? "HIP" : "SHIM6"));
460 /* Checksum - this is the same algorithm from UDP, ICMPv6 */
461 if (!pinfo->fragmented) {
462 /* IPv4 or IPv6 addresses */
463 cksum_vec[0].ptr = pinfo->src.data;
464 cksum_vec[0].len = pinfo->src.len;
465 cksum_vec[1].ptr = pinfo->dst.data;
466 cksum_vec[1].len = pinfo->dst.len;
468 /* the rest of the pseudo-header */
469 if (pinfo->src.type == AT_IPv6) {
470 cksum_vec[2].ptr = (const guint8 *)&phdr;
471 phdr[0] = g_htonl(tvb_reported_length(tvb));
472 phdr[1] = g_htonl(IP_PROTO_HIP);
473 cksum_vec[2].len = 8;
475 cksum_vec[2].ptr = (const guint8 *)&phdr;
476 phdr[0] = g_htonl((IP_PROTO_HIP<<16)+tvb_reported_length(tvb));
477 cksum_vec[2].len = 4;
479 /* pointer to the HIP header (packet data) */
480 cksum_vec[3].len = tvb_reported_length(tvb);
481 cksum_vec[3].ptr = tvb_get_ptr(tvb, 0, cksum_vec[3].len);
482 computed_checksum = in_cksum(cksum_vec, 4);
483 if (computed_checksum == 0) {
484 proto_tree_add_uint_format(hip_tree, hf_hip_checksum, tvb,
485 offset+4, 2, checksum_h,
486 "Checksum: 0x%04x (correct)",
489 proto_tree_add_uint_format(hip_tree, hf_hip_checksum, tvb,
490 offset+4, 2, checksum_h,
491 "Checksum: 0x%04x (incorrect, "
494 in_cksum_shouldbe(checksum_h,
498 proto_tree_add_uint_format(hip_tree, hf_hip_checksum, tvb,
499 offset+4, 2, checksum_h,
500 "Checksum: 0x%04x (unverified)",
504 ti = proto_tree_add_item(hip_tree, hf_hip_controls, tvb, offset+6, 2, FALSE);
506 /* HIP Controls subtree */
507 ti = proto_item_add_subtree(ti, ett_hip_controls);
508 proto_tree_add_boolean(ti, hf_hip_controls_anon, tvb,
509 offset+7,1, control_h);
513 proto_tree_add_item(hip_tree, hf_hip_hit_sndr, tvb, offset,
516 proto_tree_add_item(hip_tree, hf_hip_hit_rcvr, tvb, offset,
520 length = (hiph_hdr_len + 1) * 8;
521 /* Begin TLV parsing */
522 if (offset < length) {
523 ti_tlv = proto_tree_add_text(hip_tree, tvb, offset,
524 tvb_length(tvb), "HIP Parameters");
525 hip_tlv_tree = proto_item_add_subtree(ti_tlv, ett_hip_tlv);
527 /* Parse type and length in TLV */
528 while (offset < length)
530 tlv_type_h = tvb_get_ntohs(tvb, offset);
531 tlv_length_h = tvb_get_ntohs(tvb, offset + 2);
532 ti_tlv = proto_tree_add_uint_format(hip_tlv_tree, hf_hip_type, tvb,
533 offset, 4 + tlv_length_h, tlv_type_h,
534 "%s (type=%u, length=%u)",
535 val_to_str(tlv_type_h, hip_param_vals, "Unknown"),
536 tlv_type_h, tlv_length_h);
539 dissect_hip_tlv(tvb, offset, ti_tlv, tlv_type_h, tlv_length_h);
541 offset += 11 + tlv_length_h - (tlv_length_h + 3) % 8;
548 dissect_hip_in_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
551 nullbytes = tvb_get_ntohl(tvb, 0);
554 tvbuff_t *newtvb = tvb_new_subset_remaining(tvb, 4);
555 dissect_hip(newtvb, pinfo, tree);
561 dissect_hip_tlv(tvbuff_t *tvb, int offset, proto_item *ti, int type, int tlv_len)
564 proto_item *ti_tlv, *ti_loc;
565 guint8 n, algorithm, reg_type;
566 guint16 trans, hi_len, di_len, di_type, e_len, pv_len;
567 guint32 reserved, hi_hdr;
568 guint8 transport_proto;
570 int newoffset, newlen, hi_t;
572 /* move over the TLV */
573 newoffset = offset + 4;
577 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
579 proto_tree_add_item(t, hf_hip_tlv_ei_res, tvb, newoffset, 2, FALSE);
582 proto_tree_add_item(t, hf_hip_tlv_ei_keyidx, tvb, newoffset, 2, FALSE);
585 proto_tree_add_item(t, hf_hip_tlv_ei_oldspi, tvb, newoffset, 4, FALSE);
588 proto_tree_add_item(t, hf_hip_tlv_ei_newspi, tvb, newoffset, 4, FALSE);
590 case PARAM_R1_COUNTER:
591 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
593 proto_tree_add_item(t, hf_hip_tlv_r1_res, tvb, newoffset, 4, FALSE);
594 /* R1 generation counter */
596 proto_tree_add_item(t, hf_hip_tlv_r1count, tvb, newoffset, 8, FALSE);
599 /* RFC 5206 section 4. and
600 * draft-ietf-hip-nat-raversal-06.txt section 5.7.
601 * for type 2 locators
603 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
605 /* loop through included locators */
606 while (tlv_len > 0) {
607 /* Every locator to new tree node
608 * Skip ahead and read the 0 or 1 type locator from 8 bytes
609 * and type 2 locator from 20 bytes to be used as the top level
610 * tree_item for this subtree
612 locator_type = tvb_get_guint8(tvb, newoffset + 1);
613 if (locator_type == 1 || locator_type == 0) {
614 ti_loc = proto_tree_add_item(t, hf_hip_tlv_locator_address,
615 tvb, newoffset + 8, 16, FALSE);
616 } else if (locator_type == 2) {
617 ti_loc = proto_tree_add_item(t, hf_hip_tlv_locator_address,
618 tvb, newoffset + 20, 16, FALSE);
620 /* unknown or malformed locator type jumping over it */
622 newoffset += (1 + tvb_get_guint8(tvb, newoffset + 2));
623 tlv_len -= (1 + tvb_get_guint8(tvb, newoffset + 2));
626 ti_loc = proto_item_add_subtree(ti_loc, ett_hip_locator_data);
628 proto_tree_add_item(ti_loc, hf_hip_tlv_locator_traffic_type, tvb,
629 newoffset, 1, FALSE);
633 locator_type = tvb_get_guint8(tvb, newoffset);
635 proto_tree_add_item(ti_loc, hf_hip_tlv_locator_type, tvb, newoffset, 1, FALSE);
638 proto_tree_add_item(ti_loc, hf_hip_tlv_locator_len, tvb, newoffset, 1, FALSE);
640 /* Reserved includes the Preferred bit */
641 reserved = tvb_get_guint8(tvb, newoffset);
642 proto_tree_add_uint_format(ti_loc, hf_hip_tlv_locator_reserved, tvb,
643 newoffset, 1, reserved,
644 "Reserved: 0x%x %s", reserved,
645 (reserved >> 31) ? "(Preferred)" : "");
647 /* Locator lifetime */
648 proto_tree_add_item(ti_loc, hf_hip_tlv_locator_lifetime, tvb,
649 newoffset, 4, FALSE);
651 /* Locator types 1 and 0 RFC 5206 section 4.2.*/
652 if (locator_type == 1 || locator_type == 0) {
654 proto_tree_add_item(ti_loc, hf_hip_tlv_locator_address,
655 tvb, newoffset, 16, FALSE);
658 /* Locator type 2 draft-ietf-hip-nat-raversal-06.txt section 5.7. */
659 } else if (locator_type == 2) {
661 proto_tree_add_item(ti_loc, hf_hip_tlv_locator_port, tvb,
662 newoffset, 2, FALSE);
664 /* Transport protocol */
665 transport_proto = tvb_get_guint8(tvb, newoffset);
666 /* draft-ietf-hip-nat-traversal-09 section 5.6 */
667 proto_tree_add_uint_format(ti_loc, hf_hip_tlv_locator_transport_protocol,
668 tvb, newoffset, 1, transport_proto,
669 "Transport protocol: %d %s",
671 (transport_proto == 17) ?
675 proto_tree_add_item(ti_loc, hf_hip_tlv_locator_kind, tvb,
676 newoffset, 1, FALSE);
679 proto_tree_add_item(ti_loc, hf_hip_tlv_locator_priority, tvb,
680 newoffset, 4, FALSE);
683 proto_tree_add_item(ti_loc, hf_hip_tlv_locator_spi, tvb,
684 newoffset, 4, FALSE);
687 proto_tree_add_item(ti_loc, hf_hip_tlv_locator_address,
688 tvb, newoffset, 16, FALSE);
696 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
697 /* K number of verified bits */
698 proto_tree_add_item(t, hf_hip_tlv_puzzle_k, tvb, newoffset, 1, FALSE);
699 /* Puzzle lifetime */
701 proto_tree_add_item(t, hf_hip_tlv_puzzle_life, tvb, newoffset, 1, FALSE);
704 proto_tree_add_item(t, hf_hip_tlv_puzzle_o, tvb, newoffset, 2, FALSE);
707 proto_tree_add_item(t, hf_hip_tlv_puzzle_i, tvb,offset+8, 8, FALSE);
710 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
711 /* K number of verified bits */
712 proto_tree_add_item(t, hf_hip_tlv_solution_k, tvb, newoffset, 1, FALSE);
713 /* Solution Reserved */
715 proto_tree_add_item(t, hf_hip_tlv_solution_reserved, tvb, newoffset, 1, FALSE);
716 /* Solution Opaque */
718 proto_tree_add_item(t, hf_hip_tlv_solution_o, tvb,newoffset, 2, FALSE);
721 proto_tree_add_item(t, hf_hip_tlv_solution_i, tvb, newoffset, 8, FALSE);
724 proto_tree_add_item(t, hf_hip_tlv_solution_j, tvb, newoffset, 8, FALSE);
727 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
729 proto_tree_add_item(t, hf_hip_tlv_seq_updid, tvb, newoffset, 4, FALSE);
732 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
733 /* Can contain multiple Update IDs from peer */
734 while (tlv_len > 0) {
736 proto_tree_add_item(t, hf_hip_tlv_ack_updid, tvb, newoffset, 4, FALSE);
741 case PARAM_DIFFIE_HELLMAN:
742 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
743 n = tvb_get_guint8(tvb, newoffset);
745 proto_tree_add_uint_format(t, hf_hip_tlv_dh_group_id, tvb, newoffset,
747 val_to_str(n, dh_group_id_vals, "Unknown"));
748 /* First Public value len */
750 pv_len = tvb_get_ntohs(tvb, newoffset);
751 proto_tree_add_item(t, hf_hip_tlv_dh_pv_length, tvb, newoffset, 2, FALSE);
753 /* First Public value */
755 proto_tree_add_item(t, hf_hip_tlv_dh_pub, tvb, newoffset, pv_len, FALSE);
756 /* Check for the second group */
757 if ((pv_len + newoffset) < tlv_len) {
760 proto_tree_add_uint_format(t, hf_hip_tlv_dh_group_id, tvb, newoffset,
762 val_to_str(n, dh_group_id_vals, "Unknown"));
763 /* Second Public value len */
765 pv_len = tvb_get_ntohs(tvb, newoffset);
766 proto_tree_add_item(t, hf_hip_tlv_dh_pv_length, tvb, newoffset, 2, FALSE);
767 /* Second Public Value */
769 proto_tree_add_item(t, hf_hip_tlv_dh_pub, tvb, newoffset,
773 case PARAM_ESP_TRANSFORM:
774 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
776 proto_tree_add_item(t, hf_hip_tlv_esp_reserved, tvb, newoffset, 2, FALSE);
779 while (tlv_len > 0) {
780 /* Suite # 1, 2, ..., n
781 * two bytes per transform id
783 trans = tvb_get_ntohs(tvb, newoffset);
784 proto_tree_add_uint_format(t, hf_hip_tlv_trans_id, tvb,
785 newoffset, 2, trans, "%u (%s)", trans,
786 val_to_str(trans, transform_id_vals, "Unknown"));
791 case PARAM_HIP_TRANSFORM:
792 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
793 while (tlv_len > 0) {
794 /* Suite # 1, 2, ..., n
795 two bytes per transform id */
796 trans = tvb_get_ntohs(tvb, newoffset);
797 proto_tree_add_uint_format(t, hf_hip_tlv_trans_id, tvb,
798 newoffset, 2, trans, "%u (%s)", trans,
799 val_to_str(trans, transform_id_vals, "Unknown"));
804 case PARAM_NAT_TRAVERSAL_MODE:
805 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
807 proto_tree_add_item(t, hf_hip_tlv_esp_reserved, tvb, newoffset, 2, FALSE);
810 while (tlv_len > 0) {
811 /* Suite # 1, 2, ..., n
812 two bytes per mode id */
813 trans = tvb_get_ntohs(tvb, newoffset);
814 proto_tree_add_uint_format(t, hf_hip_tlv_nat_traversal_mode_id, tvb,
815 newoffset, 2, trans, "%u (%s)", trans,
816 val_to_str(trans, mode_id_vals, "Unknown"));
821 case PARAM_TRANSACTION_PACING:
822 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
824 proto_tree_add_item(t, hf_hip_tlv_transaction_minta, tvb, newoffset, 4, FALSE);
826 case PARAM_ENCRYPTED:
827 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
829 proto_tree_add_item(t, hf_hip_tlv_enc_reserved, tvb, newoffset, 4, FALSE);
832 * 16 bytes IV for AES CBC RFC 3602
833 * 8 bytes IV for 3DES CBC RFC 2405
834 * 0 bytes IV for NULL
836 * encrypted data after that.
838 proto_tree_add_text(t, tvb, newoffset, tlv_len - 4,
839 "Encrypted Parameter Data (%u bytes)", tlv_len - 4);
842 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
843 hi_len = tvb_get_ntohs(tvb, newoffset);
844 proto_tree_add_item(t, hf_hip_tlv_host_id_len, tvb, newoffset, 2, FALSE);
846 di_len = tvb_get_ntohs(tvb, newoffset);
847 di_type = (di_len >> 12) & 0x000F; /* get 4 bits for DI type */
848 di_len = di_len & 0x0FFF; /* 12 bits for DI length */
850 proto_tree_add_item(t, hf_hip_tlv_host_di_type, tvb, newoffset, 1, FALSE);
852 proto_tree_add_item(t, hf_hip_tlv_host_di_len, tvb, newoffset, 2, FALSE);
854 /* hi_hdr - first 4 bytes are 0200ff03 (KEY RR in RFC 2535)
857 * algorithm 1 octet (DSA or RSA)
860 hi_hdr = tvb_get_ntohl(tvb, newoffset);
861 ti_tlv = proto_tree_add_item(t, hf_hip_tlv_host_id_hdr,
862 tvb, newoffset, 4, FALSE);
864 ti_tlv = proto_item_add_subtree(ti_tlv, ett_hip_tlv_host_id_hdr);
866 proto_tree_add_uint(ti_tlv, hf_hip_tlv_host_id_hdr_flags, tvb,
867 newoffset, 2, hi_hdr);
870 proto_tree_add_uint(ti_tlv, hf_hip_tlv_host_id_hdr_proto, tvb,
871 newoffset, 1, hi_hdr);
874 proto_tree_add_uint(ti_tlv, hf_hip_tlv_host_id_hdr_alg, tvb,
875 newoffset, 1, hi_hdr);
877 algorithm = tvb_get_guint8(tvb, newoffset);
880 /* DSA KEY RR RFC 2536
887 newoffset++; /* 12 + offset */
889 proto_tree_add_item(t, hf_hip_tlv_host_id_t, tvb, newoffset, 1, FALSE);
890 hi_t = tvb_get_guint8(tvb, newoffset);
893 proto_tree_add_item(t, hf_hip_tlv_host_id_q, tvb, newoffset,
896 if (hi_t > 56) /* max 4096 bits */
899 newlen = 64 + (hi_t * 8);
900 proto_tree_add_item(t, hf_hip_tlv_host_id_p, tvb, newoffset,
904 proto_tree_add_item(t, hf_hip_tlv_host_id_g, tvb, newoffset,
908 proto_tree_add_item(t, hf_hip_tlv_host_id_y, tvb, newoffset,
912 /* RSA KEY RR RFC 3110
913 * e_len 1 or 3 octets
914 * e specified by e_len
915 * n variable length public modulus
917 newoffset++; /* 12 + offset */
919 e_len = tvb_get_guint8(tvb, newoffset);
920 proto_tree_add_item(t, hf_hip_tlv_host_id_e_len, tvb, newoffset,
921 (e_len > 255) ? 3 : 1, FALSE);
923 hi_len -= 5; /* subtract RDATA + e_len */
924 if (e_len == 0) { /* e_len is 0 followed by 16-bit value */
925 e_len = tvb_get_ntohs(tvb, newoffset);
929 if (e_len > 512) { /* per, RFC 3110 < 4096 bits */
930 proto_tree_add_text(t, tvb, newoffset, 2,
931 "<< e_len too large >>");
935 proto_tree_add_item(t, hf_hip_tlv_host_id_e, tvb, newoffset,
941 proto_tree_add_text(t, tvb, newoffset, 1,
942 "<< Invalid HI length >>");
946 /* RSA public modulus n */
947 proto_tree_add_item(t, hf_hip_tlv_host_id_n, tvb, newoffset,
951 proto_tree_add_text(t, tvb, newoffset, 1,
952 "Unknown algorithm type (%d).\n", algorithm);
961 proto_tree_add_text(t, tvb, offset+16+hi_len, di_len,
962 "FQDN: %s", tvb_get_ephemeral_string (tvb, offset+16+hi_len, di_len));
963 } else if (di_type == 2) {
965 proto_tree_add_text(t, tvb, offset+16+hi_len, di_len,
966 "NAI: %s", tvb_get_ephemeral_string (tvb, offset+16+hi_len, di_len));
969 case PARAM_CERT: /* CERT */
970 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
972 proto_tree_add_item(t, hf_hip_tlv_cert_group, tvb, newoffset, 1, FALSE);
975 proto_tree_add_item(t, hf_hip_tlv_cert_count, tvb, newoffset, 1, FALSE);
978 proto_tree_add_item(t, hf_hip_tlv_cert_id, tvb, newoffset, 1, FALSE);
981 proto_tree_add_item(t, hf_hip_tlv_cert_type, tvb, newoffset, 1, FALSE);
984 proto_tree_add_item(t, hf_hip_tlv_certificate, tvb, newoffset,
987 case PARAM_NOTIFICATION:
988 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
990 proto_tree_add_item(t, hf_hip_tlv_notification_res, tvb, newoffset, 2, FALSE);
992 /* Notification Message Type */
993 proto_tree_add_item(t, hf_hip_tlv_notification_type, tvb, newoffset, 2, FALSE);
995 /* Notification Data */
996 proto_tree_add_item(t, hf_hip_tlv_notification_data, tvb, newoffset,
999 case PARAM_ECHO_REQUEST_SIGNED:
1000 case PARAM_ECHO_RESPONSE_SIGNED:
1001 case PARAM_ECHO_REQUEST_UNSIGNED:
1002 case PARAM_ECHO_RESPONSE_UNSIGNED:
1003 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1004 /* Variable length Opaque Data */
1005 proto_tree_add_item(t, hf_hip_tlv_opaque_data, tvb, newoffset,
1008 case PARAM_REG_INFO:
1009 case PARAM_REG_REQUEST:
1010 case PARAM_REG_RESPONSE:
1011 case PARAM_REG_FAILED:
1012 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1013 if (type == PARAM_REG_INFO) {
1015 proto_tree_add_item(t, hf_hip_tlv_reg_ltmin, tvb, newoffset, 1, FALSE);
1018 proto_tree_add_item(t, hf_hip_tlv_reg_ltmax, tvb, newoffset, 1, FALSE);
1021 } else if (type == PARAM_REG_FAILED) {
1023 proto_tree_add_item(t, hf_hip_tlv_reg_failtype, tvb, newoffset, 1, FALSE);
1028 proto_tree_add_item(t, hf_hip_tlv_reg_lt, tvb, newoffset, 1, FALSE);
1032 /* Reg Type 1 ... n, Padding */
1033 while (tlv_len > 0) {
1034 reg_type = tvb_get_guint8(tvb, newoffset);
1035 proto_tree_add_uint_format(t, hf_hip_tlv_reg_type, tvb,
1036 newoffset, 1, reg_type, "%u (%s)", reg_type,
1037 val_to_str(reg_type, reg_type_vals, "Unknown"));
1038 /* one byte per registration type */
1045 case PARAM_RVS_HMAC:
1046 case PARAM_RELAY_HMAC:
1047 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1049 proto_tree_add_item(t, hf_hip_tlv_hmac, tvb, offset+4,
1052 case PARAM_HIP_SIGNATURE:
1053 case PARAM_HIP_SIGNATURE_2:
1054 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1055 /* Signature algorithm */
1056 n = tvb_get_guint8(tvb, offset+4);
1057 proto_tree_add_uint_format(t, hf_hip_tlv_sig_alg, tvb, newoffset, 1,
1059 val_to_str(n, sig_alg_vals, "Unknown"));
1062 proto_tree_add_item(t, hf_hip_tlv_sig, tvb, newoffset, tlv_len-1,
1066 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1068 proto_tree_add_item(t, hf_hip_tlv_from_address, tvb, newoffset, 16, FALSE);
1071 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1073 while (tlv_len > 0) {
1074 proto_tree_add_item(t, hf_hip_tlv_rvs_address, tvb, newoffset, 16, FALSE);
1079 case PARAM_RELAY_FROM:
1080 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1082 proto_tree_add_item(t, hf_hip_tlv_relay_from_port, tvb, newoffset, 2, FALSE);
1085 proto_tree_add_item(t, hf_hip_tlv_relay_from_protocol, tvb, newoffset, 1, FALSE);
1088 proto_tree_add_item(t, hf_hip_tlv_relay_from_reserved, tvb, newoffset, 1, FALSE);
1091 proto_tree_add_item(t, hf_hip_tlv_relay_to_address, tvb, newoffset, 16, FALSE);
1093 case PARAM_RELAY_TO:
1094 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1096 proto_tree_add_item(t, hf_hip_tlv_relay_to_port, tvb, newoffset, 2, FALSE);
1099 proto_tree_add_item(t, hf_hip_tlv_relay_to_protocol, tvb, newoffset, 1, FALSE);
1102 proto_tree_add_item(t, hf_hip_tlv_relay_to_reserved, tvb, newoffset, 1, FALSE);
1105 proto_tree_add_item(t, hf_hip_tlv_relay_to_address, tvb, newoffset, 16, FALSE);
1107 case PARAM_REG_FROM:
1108 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1110 proto_tree_add_item(t, hf_hip_tlv_reg_from_port, tvb, newoffset, 2, FALSE);
1113 proto_tree_add_item(t, hf_hip_tlv_reg_from_protocol, tvb, newoffset, 1, FALSE);
1116 proto_tree_add_item(t, hf_hip_tlv_reg_from_reserved, tvb, newoffset, 1, FALSE);
1119 proto_tree_add_item(t, hf_hip_tlv_reg_from_address, tvb, newoffset, 16, FALSE);
1128 proto_register_hip(void)
1130 static hf_register_info hf[] = {
1132 { "Payload Protocol", "hip.proto",
1133 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1136 { "Header Length", "hip.hdr_len",
1137 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1139 { &hf_hip_packet_type,
1140 { "Packet Type", "hip.packet_type",
1141 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1143 { &hf_hip_shim6_fixed_bit_p,
1144 { "Header fixed bit P", "hip.shim6_fixed_p",
1145 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1148 { "Version", "hip.version",
1149 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1151 { &hf_hip_shim6_fixed_bit_s,
1152 { "Header fixed bit S", "hip.shim6_fixed_s",
1153 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1156 { "HIP Controls", "hip.controls",
1157 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1159 { &hf_hip_controls_anon,
1160 { "Anonymous (Sender's HI is anonymous)", "hip.controls.a",
1161 FT_BOOLEAN, 16, NULL, HIP_CONTROL_A_MASK, NULL, HFILL }},
1164 { "Checksum", "hip.checksum",
1165 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1168 { "Sender's HIT", "hip.hit_sndr",
1169 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1172 { "Receiver's HIT", "hip.hit_rcvr",
1173 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1176 { "Type", "hip.type",
1177 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1179 { &hf_hip_tlv_r1_res,
1180 { "Reserved", "hip.tlv.r1_reserved",
1181 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1183 { &hf_hip_tlv_r1count,
1184 { "R1 Counter", "hip.tlv.r1_counter",
1185 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1187 { &hf_hip_tlv_puzzle_k,
1188 { "Difficulty (K)", "hip.tlv_puzzle_k",
1189 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1191 { &hf_hip_tlv_puzzle_life,
1192 { "Lifetime", "hip.tlv_puzzle_lifetime",
1193 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1195 { &hf_hip_tlv_puzzle_o,
1196 { "Opaque Data", "hip.tlv_puzzle_opaque",
1197 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1199 { &hf_hip_tlv_puzzle_i,
1200 { "Random number (I)", "hip.tlv.puzzle_random_i",
1201 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1203 { &hf_hip_tlv_solution_k,
1204 { "Difficulty (K)", "hip.tlv_solution_k",
1205 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1207 { &hf_hip_tlv_solution_reserved,
1208 { "Reserved", "hip.tlv_solution_reserved",
1209 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1211 { &hf_hip_tlv_solution_o,
1212 { "Opaque Data", "hip.tlv_solution_opaque",
1213 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1215 { &hf_hip_tlv_solution_i,
1216 { "Random number (I)", "hip.tlv.solution_random_i",
1217 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1219 { &hf_hip_tlv_solution_j,
1220 { "Solution (J)", "hip.tlv_solution_j",
1221 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1223 { &hf_hip_tlv_ei_res,
1224 { "Reserved", "hip.tlv_esp_info_reserved",
1225 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1227 { &hf_hip_tlv_ei_keyidx,
1228 { "Keymaterial Index", "hip.tlv_esp_info_key_index",
1229 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1231 { &hf_hip_tlv_ei_oldspi,
1232 { "Old SPI", "hip.tlv_esp_info_old_spi",
1233 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1235 { &hf_hip_tlv_ei_newspi,
1236 { "New SPI", "hip.tlv_esp_info_new_spi",
1237 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1239 { &hf_hip_tlv_seq_updid,
1240 { "Seq Update ID", "hip.tlv_seq_update_id",
1241 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1243 { &hf_hip_tlv_ack_updid,
1244 { "ACKed Peer Update ID", "hip.tlv_ack_updid",
1245 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1247 { &hf_hip_tlv_dh_group_id,
1248 { "Group ID", "hip.tlv.dh_group_id",
1249 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1251 { &hf_hip_tlv_dh_pv_length,
1252 { "Public Value Length", "hip.tlv.dh_pv_length",
1253 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1255 { &hf_hip_tlv_dh_pub,
1256 { "Public Value", "hip.tlv.dh_public_value",
1257 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1259 { &hf_hip_tlv_trans_id,
1260 { "Transform ID", "hip.tlv.trans_id",
1261 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1263 { &hf_hip_tlv_esp_reserved,
1264 { "Reserved", "hip.tlv.esp_trans_res",
1265 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1267 { &hf_hip_tlv_host_id_len,
1268 { "Host Identity Length", "hip.tlv.host_id_length",
1269 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1271 { &hf_hip_tlv_host_di_type,
1272 { "Domain Identifier Type", "hip.tlv.host_domain_id_type",
1273 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1275 { &hf_hip_tlv_host_di_len,
1276 { "Domain Identifier Length", "hip.tlv.host_domain_id_length",
1277 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1279 { &hf_hip_tlv_host_id_hdr,
1280 { "Host Identity flags", "hip.tlv.host_id_hdr",
1281 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1283 { &hf_hip_tlv_host_id_hdr_flags,
1284 { "Host Identity Header Flags", "hip.tlv.host_id_header_flags",
1285 FT_UINT32, BASE_HEX, VALS(hi_hdr_flags_vals),
1286 HI_HDR_FLAGS_MASK, NULL, HFILL }},
1288 { &hf_hip_tlv_host_id_hdr_proto,
1289 { "Host Identity Header Protocol", "hip.tlv.host_id_header_proto",
1290 FT_UINT32, BASE_HEX, VALS(hi_hdr_proto_vals),
1291 HI_HDR_PROTO_MASK, NULL, HFILL }},
1293 { &hf_hip_tlv_host_id_hdr_alg,
1294 { "Host Identity Header Algorithm", "hip.tlv.host_id_header_algo",
1295 FT_UINT32, BASE_HEX, VALS(hi_hdr_alg_vals),
1296 HI_HDR_ALG_MASK, NULL, HFILL }},
1298 { &hf_hip_tlv_host_id_t,
1299 { "Host Identity T", "hip.tlv.host_identity_t",
1300 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1302 { &hf_hip_tlv_host_id_q,
1303 { "Host Identity Q", "hip.tlv.host_identity_q",
1304 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1306 { &hf_hip_tlv_host_id_p,
1307 { "Host Identity P", "hip.tlv.host_id_p",
1308 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1310 { &hf_hip_tlv_host_id_g,
1311 { "Host Identity G", "hip.tlv.host_id_g",
1312 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1314 { &hf_hip_tlv_host_id_y,
1315 { "Host Identity Y (public value)", "hip.tlv.host_id_y",
1316 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1318 { &hf_hip_tlv_host_id_e_len,
1319 { "RSA Host Identity exponent length (e_len)", "hip.tlv.host_id_e_length",
1320 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1322 { &hf_hip_tlv_host_id_e,
1323 { "RSA Host Identity exponent (e)", "hip.tlv.host_id_e",
1324 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1326 { &hf_hip_tlv_host_id_n,
1327 { "RSA Host Identity public modulus (n)", "hip.tlv.host_id_n",
1328 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1330 { &hf_hip_tlv_notification_res,
1331 { "Notification Reserved", "hip.tlv.notification_res",
1332 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1334 { &hf_hip_tlv_notification_type,
1335 { "Notification Message Type", "hip.tlv.notification_type",
1336 FT_UINT16, BASE_DEC, VALS(notification_vals), 0xFFFF, NULL, HFILL }},
1338 { &hf_hip_tlv_notification_data,
1339 { "Notification Data", "hip.tlv.notification_data",
1340 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1342 { &hf_hip_tlv_opaque_data,
1343 { "Opaque Data", "hip.tlv.opaque_data",
1344 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1346 { &hf_hip_tlv_reg_ltmin,
1347 { "Minimum Registration Lifetime", "hip.tlv.reg_ltmin",
1348 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1350 { &hf_hip_tlv_reg_ltmax,
1351 { "Maximum Registration Lifetime", "hip.tlv.reg_ltmax",
1352 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1354 { &hf_hip_tlv_reg_lt,
1355 { "Registration Lifetime", "hip.tlv.reg_lt",
1356 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1358 { &hf_hip_tlv_reg_type,
1359 { "Registration Type", "hip.tlv.reg_type",
1360 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1362 { &hf_hip_tlv_reg_failtype,
1363 { "Registration Failure Type", "hip.tlv.reg_failtype",
1364 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1367 { "HMAC", "hip.tlv.hmac",
1368 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1370 { &hf_hip_tlv_sig_alg,
1371 { "Signature Algorithm", "hip.tlv.sig_alg",
1372 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1375 { "Signature", "hip.tlv.sig",
1376 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1378 { &hf_hip_tlv_enc_reserved,
1379 { "Reserved", "hip.tlv.enc_reserved",
1380 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1382 { &hf_hip_tlv_locator_traffic_type,
1383 { "Traffic Type", "hip.tlv.locator_traffic_type",
1384 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1386 { &hf_hip_tlv_locator_type,
1387 { "Locator Type", "hip.tlv.locator_type",
1388 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1390 { &hf_hip_tlv_locator_len,
1391 { "Locator Length", "hip.tlv.locator_len",
1392 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1394 { &hf_hip_tlv_locator_reserved,
1395 { "Reserved", "hip.tlv.locator_reserved",
1396 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1398 { &hf_hip_tlv_locator_lifetime,
1399 { "Locator Lifetime", "hip.tlv.locator_lifetime",
1400 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1402 { &hf_hip_tlv_locator_port,
1403 { "Locator port", "hip.tlv.locator_port",
1404 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1406 { &hf_hip_tlv_locator_transport_protocol,
1407 { "Locator transport protocol", "hip.tlv.locator_transport_protocol",
1408 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1410 { &hf_hip_tlv_locator_kind,
1411 { "Locator kind", "hip.tlv.locator_kind",
1412 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1414 { &hf_hip_tlv_locator_priority,
1415 { "Locator priority", "hip.tlv.locator_priority",
1416 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1418 { &hf_hip_tlv_locator_spi,
1419 { "Locator spi", "hip.tlv.locator_spi",
1420 FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1422 { &hf_hip_tlv_locator_address,
1423 { "Locator" , "hip.tlv.locator_address",
1424 FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1426 { &hf_hip_tlv_cert_group,
1427 { "Cert group", "hip.tlv.cert_group",
1428 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1430 { &hf_hip_tlv_cert_count,
1431 { "Cert count", "hip.tlv.cert_count",
1432 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1434 { &hf_hip_tlv_cert_id,
1435 { "Cert ID", "hip.tlv.cert_id",
1436 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1438 { &hf_hip_tlv_cert_type,
1439 { "Cert type", "hip.tlv.cert_type",
1440 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1442 { &hf_hip_tlv_certificate,
1443 { "Certificate", "hip.tlv.certificate",
1444 FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1446 { &hf_hip_tlv_nat_traversal_mode_id,
1447 { "NAT Traversal Mode ID", "hip.tlv.nat_traversal_mode_id",
1448 FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1450 { &hf_hip_tlv_relay_from_port,
1451 { "Relay From Port", "hip.tlv.relay_from_port",
1452 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1454 { &hf_hip_tlv_relay_to_port,
1455 { "Relay To Port", "hip.tlv.relay_to_port",
1456 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1458 { &hf_hip_tlv_reg_from_port,
1459 { "Port", "hip.tlv.reg_from_port",
1460 FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1462 { &hf_hip_tlv_transaction_minta,
1463 { "Min Ta" , "hip.tlv_transaction_minta",
1464 FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1466 { &hf_hip_tlv_from_address,
1467 { "Address" , "hip.tlv_from_address",
1468 FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1470 { &hf_hip_tlv_rvs_address,
1471 { "RVS Address" , "hip.tlv_rvs_address",
1472 FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1474 { &hf_hip_tlv_relay_from_protocol,
1475 { "Protocol" , "hip.tlv_relay_from_protocol",
1476 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1478 { &hf_hip_tlv_relay_from_reserved,
1479 { "Reserved" , "hip.tlv_relay_from_reserved",
1480 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1482 { &hf_hip_tlv_relay_from_address,
1483 { "Address" , "hip.tlv_relay_from_address",
1484 FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1486 { &hf_hip_tlv_relay_to_protocol,
1487 { "Protocol" , "hip.tlv_relay_to_protocol",
1488 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1490 { &hf_hip_tlv_relay_to_reserved,
1491 { "Reserved" , "hip.tlv_relay_to_reserved",
1492 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1494 { &hf_hip_tlv_relay_to_address,
1495 { "Address" , "hip.tlv_relay_to_address",
1496 FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1498 { &hf_hip_tlv_reg_from_protocol,
1499 { "Protocol" , "hip.tlv_reg_from_protocol",
1500 FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1502 { &hf_hip_tlv_reg_from_reserved,
1503 { "Reserved" , "hip.tlv_reg_from_reserved",
1504 FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1506 { &hf_hip_tlv_reg_from_address,
1507 { "Address" , "hip.tlv_reg_from_address",
1508 FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1512 static gint *ett[] = {
1517 &ett_hip_tlv_host_id_hdr,
1518 &ett_hip_locator_data,
1521 proto_hip = proto_register_protocol("Host Identity Protocol",
1524 proto_register_field_array(proto_hip, hf, array_length(hf));
1525 proto_register_subtree_array(ett, array_length(ett));
1529 proto_reg_handoff_hip(void)
1531 dissector_handle_t hip_handle;
1532 dissector_handle_t hip_handle2;
1534 hip_handle = create_dissector_handle(dissect_hip, proto_hip);
1535 dissector_add_uint("ip.proto", IP_PROTO_HIP, hip_handle);
1537 hip_handle2 = create_dissector_handle(dissect_hip_in_udp, proto_hip);
1538 dissector_add_uint("udp.port", 10500, hip_handle2);