3fbcb9bdce33fc4f00cb7a975286a82e449f2946
[obnox/wireshark/wip.git] / epan / dissectors / packet-hip.c
1 /* packet-hip.c
2  * Definitions and routines for HIP control packet disassembly
3  * Samu Varjonen <samu.varjonen@hiit.fi>
4  *
5  * $Id$
6  *
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>
12  *
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.
17  *
18  * Wireshark - Network traffic analyzer
19  * By Gerald Combs <gerald@wireshark.org>
20  * Copyright 1998 Gerald Combs
21  *
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.
26  *
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.
31  *
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.
35  */
36
37 #ifdef HAVE_CONFIG_H
38 # include "config.h"
39 #endif
40
41 #include <epan/packet.h>
42 #include <epan/addr_resolv.h>
43
44 #include <epan/ipproto.h>
45 #include <epan/in_cksum.h>
46
47 #define HI_ALG_DSA 3
48 #define HI_ALG_RSA 5
49
50 /* HIP packet types */
51 typedef enum {
52         HIP_I1=1,
53         HIP_R1,
54         HIP_I2,
55         HIP_R2,
56         HIP_UPDATE=16,
57         HIP_NOTIFY=17,
58         HIP_CLOSE=18,
59         HIP_CLOSE_ACK=19
60 } HIP_PACKETS;
61
62 /* HIP TLV parameters listed in order of RFCs */
63
64 /* RFC 5201 */
65 #define PARAM_R1_COUNTER                128
66 #define PARAM_PUZZLE                    257
67 #define PARAM_SOLUTION                  321
68 #define PARAM_SEQ                       385
69 #define PARAM_ACK                       449
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
86 /* RFC 5202 */
87 #define PARAM_ESP_INFO                  65
88 #define PARAM_ESP_TRANSFORM             4095
89 /* RFC 5203 */
90 #define PARAM_REG_INFO                  930
91 #define PARAM_REG_REQUEST               932
92 #define PARAM_REG_RESPONSE              934
93 #define PARAM_REG_FAILED                936
94 /* RFC 5204 */
95 #define PARAM_FROM                      65498
96 #define PARAM_RVS_HMAC                  65500
97 #define PARAM_VIA_RVS                   65502
98 /* RFC 5206 */
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
107
108 /* Bit masks */
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
123
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)" },
133         { 0, NULL }
134 };
135
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" },
168         { 0, NULL }
169 };
170
171 /* RFC 5201 section 5.2.6. */
172 static const value_string dh_group_id_vals[] = {
173         { 0x0, "Reserved" },
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" },
180         { 0, NULL }
181 };
182
183 /* RFC 5202 section 5.1.2. */
184 static const value_string transform_id_vals[] = {
185         { 0x0, "Reserved" },
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" },
192         { 0, NULL }
193 };
194
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 */
198         { 0, NULL }
199 };
200
201 /* RFC 5201 section 5.2.8 */
202 static const value_string sig_alg_vals[] = {
203         { 0x0, "Reserved" },
204         { HI_ALG_DSA, "DSA" },
205         { HI_ALG_RSA, "RSA" },
206         { 0, NULL }
207 };
208
209 /* draft-ietf-hip-nat-traversal-09.txt */
210 static const value_string mode_id_vals[] = {
211         { 0x0, "Reserved" },
212         { 0x01, "UDP-encapsulation" },
213         { 0x02, "ICE-STUN-UDP" },
214         { 0, NULL }
215 };
216
217 static const value_string hi_hdr_flags_vals[] = {
218         { 0x0, "Other" },
219         { 0x0200, "Key is associated with a user" },
220         { 0x0201, "Zone key" },
221         { 0x0202, "Key is associated with non-zone entity" },
222         { 0, NULL }
223 };
224
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" },
232         { 0, NULL }
233 };
234
235 /* RFC 2535 section 3.2 */
236 static const value_string hi_hdr_alg_vals[] = {
237         { 0x00, "Reserved" },
238         { 0x01, "RSA/MD5" },
239         { 0x02, "Diffie-Hellman" },
240         { 0x03, "DSA" },
241         { 0x04, "elliptic curve crypto" },
242         { 0x05, "RSA" },
243         { 0xFF, "Reserved" },
244         { 0, NULL }
245 };
246
247 /* RFC 5201 */
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" },
264         { 0, NULL }
265 };
266
267 /* draft-ietf-hip-nat-traversal-09.txt */
268 static const value_string nat_traversal_mode_vals[] = {
269         { 0, "Reserved"},
270         { 1, "UDP-encapsulation"},
271         { 2, "ICE-STUN-UDP"},
272         { 0, NULL }
273 };
274
275 /* functions */
276 static int dissect_hip_tlv(tvbuff_t *tvb, int offset, proto_item *ti, int type, int tlv_len);
277
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;
290
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;
353
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;
359
360 static int hf_hip_tlv_from_address = -1;
361 static int hf_hip_tlv_rvs_address = -1;
362
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;
377
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;
384
385 /* Dissect the HIP packet */
386 static void
387 dissect_hip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
388 {
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 */
394         vec_t cksum_vec[4];
395         guint32 phdr[2];
396
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 ...  */
408
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);
413
414         newoffset = offset;
415         hiph_proto = tvb_get_guint8(tvb, newoffset);
416         newoffset++;
417         hiph_hdr_len = tvb_get_guint8(tvb, newoffset);
418         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;
423         newoffset++;
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;
430         newoffset++;
431         checksum_h = tvb_get_ntohs(tvb, newoffset);
432         newoffset += 2;
433         control_h = tvb_get_ntohs(tvb, newoffset);
434         newoffset += 2;
435
436         col_set_str(pinfo->cinfo, COL_INFO, val_to_str_const(hiph_packet_type, pinfo_vals, "Unknown"));
437
438         /* populate a tree in the second pane with the status of the link layer (i.e. none) */
439         if(tree) {
440                 ti = proto_tree_add_item(tree, proto_hip, tvb, 0, -1, FALSE);
441
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,
450                                     hiph_packet_type);
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"));
459
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;
467
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;
474                         } else {
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;
478                         }
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)",
487                                                            checksum_h);
488                         } else {
489                                 proto_tree_add_uint_format(hip_tree, hf_hip_checksum, tvb,
490                                                            offset+4, 2, checksum_h,
491                                                            "Checksum: 0x%04x (incorrect, "
492                                                            "should be 0x%04x)",
493                                                            checksum_h,
494                                                            in_cksum_shouldbe(checksum_h,
495                                                                              computed_checksum));
496                         }
497                 } else {
498                         proto_tree_add_uint_format(hip_tree, hf_hip_checksum, tvb,
499                                                    offset+4, 2, checksum_h,
500                                                    "Checksum: 0x%04x (unverified)",
501                                                    checksum_h);
502                 }
503
504                 ti = proto_tree_add_item(hip_tree, hf_hip_controls, tvb, offset+6, 2, FALSE);
505                 if (ti) {
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);
510                 }
511
512                 offset += 8;
513                 proto_tree_add_item(hip_tree, hf_hip_hit_sndr, tvb, offset,
514                                      16, FALSE);
515                 offset += 16;
516                 proto_tree_add_item(hip_tree, hf_hip_hit_rcvr, tvb, offset,
517                                      16, FALSE);
518                 offset += 16;
519
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);
526                 }
527                 /* Parse type and length in TLV */
528                 while (offset < length)
529                 {
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);
537
538                         /* Parse value */
539                         dissect_hip_tlv(tvb, offset, ti_tlv, tlv_type_h, tlv_length_h);
540
541                         offset += 11 + tlv_length_h - (tlv_length_h + 3) % 8;
542                 }
543
544         }
545 }
546
547 static void
548 dissect_hip_in_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
549 {
550         guint32 nullbytes;
551         nullbytes = tvb_get_ntohl(tvb, 0);
552         if (nullbytes == 0)
553         {
554                 tvbuff_t *newtvb = tvb_new_subset_remaining(tvb, 4);
555                 dissect_hip(newtvb, pinfo, tree);
556         }
557 }
558
559
560 static int
561 dissect_hip_tlv(tvbuff_t *tvb, int offset, proto_item *ti, int type, int tlv_len)
562 {
563         proto_tree *t=NULL;
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;
569         guint8 locator_type;
570         int newoffset, newlen, hi_t;
571
572         /* move over the TLV */
573         newoffset = offset + 4;
574         switch (type)
575         {
576         case PARAM_ESP_INFO:
577                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
578                 /* Reserved */
579                 proto_tree_add_item(t, hf_hip_tlv_ei_res, tvb, newoffset, 2, FALSE);
580                 /* KEYMAT index */
581                 newoffset += 2;
582                 proto_tree_add_item(t, hf_hip_tlv_ei_keyidx, tvb, newoffset, 2, FALSE);
583                 /* OLD SPI */
584                 newoffset += 2;
585                 proto_tree_add_item(t, hf_hip_tlv_ei_oldspi, tvb, newoffset, 4, FALSE);
586                 /* NEW SPI */
587                 newoffset += 4;
588                 proto_tree_add_item(t, hf_hip_tlv_ei_newspi, tvb, newoffset, 4, FALSE);
589                 break;
590         case PARAM_R1_COUNTER:
591                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
592                 /* Reserved */
593                 proto_tree_add_item(t, hf_hip_tlv_r1_res, tvb, newoffset, 4, FALSE);
594                 /* R1 generation counter */
595                 newoffset += 4;
596                 proto_tree_add_item(t, hf_hip_tlv_r1count, tvb, newoffset, 8, FALSE);
597                 break;
598         case PARAM_LOCATOR:
599                 /* RFC 5206 section 4. and
600                  * draft-ietf-hip-nat-raversal-06.txt section 5.7.
601                  * for type 2 locators
602                  */
603                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
604                 tlv_len -= 4;
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
611                          */
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);
619                         } else {
620                                 /* unknown or malformed locator type jumping over it */
621                                 ti_loc = NULL;
622                                 newoffset += (1 + tvb_get_guint8(tvb, newoffset + 2));
623                                 tlv_len -= (1 + tvb_get_guint8(tvb, newoffset + 2));
624                         }
625                         if (ti_loc) {
626                                 ti_loc = proto_item_add_subtree(ti_loc, ett_hip_locator_data);
627                                 /* Traffic type */
628                                 proto_tree_add_item(ti_loc, hf_hip_tlv_locator_traffic_type, tvb,
629                                                     newoffset, 1, FALSE);
630                                 newoffset++;
631                                 /* Locator type */
632 #if 0
633                                 locator_type = tvb_get_guint8(tvb, newoffset);
634 #endif
635                                 proto_tree_add_item(ti_loc, hf_hip_tlv_locator_type, tvb, newoffset, 1, FALSE);
636                                 newoffset++;
637                                 /* Locator length */
638                                 proto_tree_add_item(ti_loc, hf_hip_tlv_locator_len, tvb, newoffset, 1, FALSE);
639                                 newoffset++;
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)" : "");
646                                 newoffset++;
647                                 /* Locator lifetime */
648                                 proto_tree_add_item(ti_loc, hf_hip_tlv_locator_lifetime, tvb,
649                                                     newoffset, 4, FALSE);
650                                 newoffset += 4;
651                                 /* Locator types 1 and 0 RFC 5206 section 4.2.*/
652                                 if (locator_type == 1 || locator_type == 0) {
653                                         /* Locator */
654                                         proto_tree_add_item(ti_loc, hf_hip_tlv_locator_address,
655                                                             tvb, newoffset, 16, FALSE);
656                                         newoffset += 16;
657                                         tlv_len -= 24;
658                                         /* Locator type 2 draft-ietf-hip-nat-raversal-06.txt section 5.7. */
659                                 } else if (locator_type == 2) {
660                                         /* Tansport port */
661                                         proto_tree_add_item(ti_loc, hf_hip_tlv_locator_port, tvb,
662                                                             newoffset, 2, FALSE);
663                                         newoffset += 2;
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",
670                                                                    transport_proto,
671                                                                    (transport_proto == 17) ?
672                                                                    "(UDP)" : "");
673                                         newoffset++;
674                                         /* Kind */
675                                         proto_tree_add_item(ti_loc, hf_hip_tlv_locator_kind, tvb,
676                                                             newoffset, 1, FALSE);
677                                         newoffset++;
678                                         /* Priority */
679                                         proto_tree_add_item(ti_loc, hf_hip_tlv_locator_priority, tvb,
680                                                             newoffset, 4, FALSE);
681                                         newoffset += 4;
682                                         /* SPI */
683                                         proto_tree_add_item(ti_loc, hf_hip_tlv_locator_spi, tvb,
684                                                             newoffset, 4, FALSE);
685                                         newoffset += 4;
686                                         /* Locator */
687                                         proto_tree_add_item(ti_loc, hf_hip_tlv_locator_address,
688                                                             tvb, newoffset, 16, FALSE);
689                                         newoffset += 16;
690                                         tlv_len -= 36;
691                                 }
692                         }
693                 }
694                 break;
695         case PARAM_PUZZLE:
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 */
700                 newoffset++;
701                 proto_tree_add_item(t, hf_hip_tlv_puzzle_life, tvb, newoffset, 1, FALSE);
702                 /* Puzzle O*/
703                 newoffset++;
704                 proto_tree_add_item(t, hf_hip_tlv_puzzle_o, tvb, newoffset, 2, FALSE);
705                 /* Puzzle I */
706                 newoffset += 2;
707                 proto_tree_add_item(t, hf_hip_tlv_puzzle_i, tvb,offset+8, 8, FALSE);
708                 break;
709         case PARAM_SOLUTION:
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 */
714                 newoffset++;
715                 proto_tree_add_item(t, hf_hip_tlv_solution_reserved, tvb, newoffset, 1, FALSE);
716                 /* Solution Opaque */
717                 newoffset++;
718                 proto_tree_add_item(t, hf_hip_tlv_solution_o, tvb,newoffset, 2, FALSE);
719                 /* Solution I */
720                 newoffset += 2;
721                 proto_tree_add_item(t, hf_hip_tlv_solution_i, tvb, newoffset, 8, FALSE);
722                 /* Solution J */
723                 newoffset += 8;
724                 proto_tree_add_item(t, hf_hip_tlv_solution_j, tvb, newoffset, 8, FALSE);
725                 break;
726         case PARAM_SEQ:
727                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
728                 /* Update ID */
729                 proto_tree_add_item(t, hf_hip_tlv_seq_updid, tvb, newoffset, 4, FALSE);
730                 break;
731         case PARAM_ACK:
732                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
733                 /* Can contain multiple Update IDs from peer */
734                 while (tlv_len > 0) {
735                         /* peer Update ID */
736                         proto_tree_add_item(t, hf_hip_tlv_ack_updid, tvb, newoffset, 4, FALSE);
737                         newoffset += 4;
738                         tlv_len -= 4;
739                 }
740                 break;
741         case PARAM_DIFFIE_HELLMAN:
742                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
743                 n = tvb_get_guint8(tvb, newoffset);
744                 /* First Group ID*/
745                 proto_tree_add_uint_format(t, hf_hip_tlv_dh_group_id, tvb, newoffset,
746                                            1, n, "%u (%s)", n,
747                                            val_to_str(n, dh_group_id_vals, "Unknown"));
748                 /* First Public value len */
749                 newoffset++;
750                 pv_len = tvb_get_ntohs(tvb, newoffset);
751                 proto_tree_add_item(t, hf_hip_tlv_dh_pv_length, tvb, newoffset, 2, FALSE);
752
753                 /* First Public value */
754                 newoffset += 2;
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) {
758                         /* Second Group ID*/
759                         newoffset += pv_len;
760                         proto_tree_add_uint_format(t, hf_hip_tlv_dh_group_id, tvb, newoffset,
761                                                    1, n, "%u (%s)", n,
762                                                    val_to_str(n, dh_group_id_vals, "Unknown"));
763                         /* Second Public value len */
764                         newoffset += 1;
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 */
768                         newoffset += 2;
769                         proto_tree_add_item(t, hf_hip_tlv_dh_pub, tvb, newoffset,
770                                              pv_len, FALSE);
771                 }
772                 break;
773         case PARAM_ESP_TRANSFORM:
774                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
775                 /* Reserved */
776                 proto_tree_add_item(t, hf_hip_tlv_esp_reserved, tvb, newoffset, 2, FALSE);
777                 newoffset +=2;
778                 tlv_len -= 2;
779                 while (tlv_len > 0) {
780                         /* Suite # 1, 2, ...,  n
781                          * two bytes per transform id
782                          */
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"));
787                         tlv_len -= 2;
788                         newoffset += 2;
789                 }
790                 break;
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"));
800                         tlv_len -= 2;
801                         newoffset += 2;
802                 }
803                 break;
804         case PARAM_NAT_TRAVERSAL_MODE:
805                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
806                 /* Reserved */
807                 proto_tree_add_item(t, hf_hip_tlv_esp_reserved, tvb, newoffset, 2, FALSE);
808                 newoffset += 2;
809                 tlv_len -= 2;
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"));
817                         tlv_len -= 2;
818                         newoffset += 2;
819                 }
820                 break;
821         case PARAM_TRANSACTION_PACING:
822                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
823                 /* Min Ta */
824                 proto_tree_add_item(t, hf_hip_tlv_transaction_minta, tvb, newoffset, 4, FALSE);
825                 break;
826         case PARAM_ENCRYPTED:
827                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
828                 /* Reserved */
829                 proto_tree_add_item(t, hf_hip_tlv_enc_reserved, tvb, newoffset, 4, FALSE);
830                 newoffset += 4;
831                 /* IV
832                  * 16 bytes IV for AES CBC RFC 3602
833                  *  8 bytes IV for 3DES CBC RFC 2405
834                  *  0 bytes IV for NULL
835                  *  and
836                  *  encrypted data after that.
837                  */
838                 proto_tree_add_text(t, tvb, newoffset, tlv_len - 4,
839                                     "Encrypted Parameter Data (%u bytes)",  tlv_len - 4);
840                 break;
841         case PARAM_HOST_ID:
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);
845                 newoffset += 2;
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 */
849                 /* DI type */
850                 proto_tree_add_item(t, hf_hip_tlv_host_di_type, tvb, newoffset, 1, FALSE);
851                 /* DI len */
852                 proto_tree_add_item(t, hf_hip_tlv_host_di_len, tvb, newoffset, 2, FALSE);
853                 newoffset += 2;
854                 /* hi_hdr - first 4 bytes are 0200ff03 (KEY RR in RFC 2535)
855                  *   flags     2  octets
856                  *   protocol  1  octet
857                  *   algorithm 1  octet (DSA or RSA)
858                  *   <public key>
859                  */
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);
863                 if (ti_tlv) {
864                         ti_tlv = proto_item_add_subtree(ti_tlv, ett_hip_tlv_host_id_hdr);
865                         /* HDR Flags*/
866                         proto_tree_add_uint(ti_tlv, hf_hip_tlv_host_id_hdr_flags, tvb,
867                                             newoffset, 2, hi_hdr);
868                         newoffset += 2;
869                         /* HDR Protocol */
870                         proto_tree_add_uint(ti_tlv, hf_hip_tlv_host_id_hdr_proto, tvb,
871                                             newoffset, 1,  hi_hdr);
872                         newoffset += 1;
873                         /* HDR Algorithm */
874                         proto_tree_add_uint(ti_tlv, hf_hip_tlv_host_id_hdr_alg, tvb,
875                                             newoffset, 1, hi_hdr);
876                 }
877                 algorithm = tvb_get_guint8(tvb, newoffset);
878                 switch (algorithm) {
879                 case HI_ALG_DSA:
880                         /* DSA KEY RR RFC 2536
881                          *   T         1  octet
882                          *   Q         20  octets
883                          *   P         64 + T*8  octets
884                          *   G         64 + T*8  octets
885                          *   Y         64 + T*8  octets
886                          */
887                         newoffset++; /* 12 + offset */
888                         /* T */
889                         proto_tree_add_item(t, hf_hip_tlv_host_id_t, tvb, newoffset, 1, FALSE);
890                         hi_t = tvb_get_guint8(tvb, newoffset);
891                         newoffset++;
892                         /* Q */
893                         proto_tree_add_item(t, hf_hip_tlv_host_id_q, tvb, newoffset,
894                                              20, FALSE);
895                         newoffset += 20;
896                         if (hi_t > 56) /* max 4096 bits */
897                                 break;
898                         /* P */
899                         newlen = 64 + (hi_t * 8);
900                         proto_tree_add_item(t, hf_hip_tlv_host_id_p, tvb, newoffset,
901                                              newlen, FALSE);
902                         /* G */
903                         newoffset += newlen;
904                         proto_tree_add_item(t, hf_hip_tlv_host_id_g, tvb, newoffset,
905                                              newlen, FALSE);
906                         /* Y */
907                         newoffset += newlen;
908                         proto_tree_add_item(t, hf_hip_tlv_host_id_y, tvb, newoffset,
909                                              newlen, FALSE);
910                         break;
911                 case HI_ALG_RSA:
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
916                          */
917                         newoffset++; /* 12 + offset */
918                         /* E len */
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);
922                         newoffset++;
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);
926                                 newoffset += 2;
927                                 hi_len -= 2;
928                         }
929                         if (e_len > 512) { /* per, RFC 3110 < 4096 bits */
930                                 proto_tree_add_text(t, tvb, newoffset, 2,
931                                                     "<< e_len too large >>");
932                                 break;
933                         }
934                         /* e */
935                         proto_tree_add_item(t, hf_hip_tlv_host_id_e, tvb, newoffset,
936                                              e_len, FALSE);
937                         newoffset += e_len;
938                         hi_len -= e_len;
939
940                         if (hi_len > 512) {
941                                 proto_tree_add_text(t, tvb, newoffset, 1,
942                                                     "<< Invalid HI length >>");
943                                 break;
944                         }
945
946                         /* RSA public modulus n */
947                         proto_tree_add_item(t, hf_hip_tlv_host_id_n, tvb, newoffset,
948                                              hi_len, FALSE);
949                         break;
950                 default:
951                         proto_tree_add_text(t, tvb, newoffset, 1,
952                                             "Unknown algorithm type (%d).\n", algorithm);
953
954                         break;
955                 }
956                 /* FQDN */
957                 if (di_type == 0)
958                         break;
959                 if (di_type == 1) {
960                         /* RFC 1035 */
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) {
964                         /* RFC 4282 */
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));
967                 }
968                 break;
969         case PARAM_CERT: /* CERT */
970                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
971                 /* Cert Group */
972                 proto_tree_add_item(t, hf_hip_tlv_cert_group, tvb, newoffset, 1, FALSE);
973                 newoffset++;
974                 /* Cert Count */
975                 proto_tree_add_item(t, hf_hip_tlv_cert_count, tvb, newoffset, 1, FALSE);
976                 newoffset++;
977                 /* Cert ID */
978                 proto_tree_add_item(t, hf_hip_tlv_cert_id, tvb, newoffset, 1, FALSE);
979                 newoffset++;
980                 /* Cert Type */
981                 proto_tree_add_item(t, hf_hip_tlv_cert_type, tvb, newoffset, 1, FALSE);
982                 newoffset++;
983                 /* Certificate */
984                 proto_tree_add_item(t, hf_hip_tlv_certificate, tvb, newoffset,
985                                      tlv_len-4, FALSE);
986                 break;
987         case PARAM_NOTIFICATION:
988                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
989                 /* Reserved */
990                 proto_tree_add_item(t, hf_hip_tlv_notification_res, tvb, newoffset, 2, FALSE);
991                 newoffset += 2;
992                 /* Notification Message Type */
993                 proto_tree_add_item(t, hf_hip_tlv_notification_type, tvb, newoffset, 2, FALSE);
994                 newoffset += 2;
995                 /* Notification Data */
996                 proto_tree_add_item(t, hf_hip_tlv_notification_data, tvb, newoffset,
997                                      tlv_len-4, FALSE);
998                 break;
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,
1006                                      tlv_len, FALSE);
1007                 break;
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) {
1014                         /* Min Lifetime */
1015                         proto_tree_add_item(t, hf_hip_tlv_reg_ltmin, tvb, newoffset, 1, FALSE);
1016                         newoffset++;
1017                         /* Max Lifetime */
1018                         proto_tree_add_item(t, hf_hip_tlv_reg_ltmax, tvb, newoffset, 1, FALSE);
1019                         newoffset++;
1020                         tlv_len -= 2;
1021                 } else if (type == PARAM_REG_FAILED) {
1022                         /* Failure Type */
1023                         proto_tree_add_item(t, hf_hip_tlv_reg_failtype, tvb, newoffset, 1, FALSE);
1024                         newoffset++;;
1025                         tlv_len--;
1026                 } else {
1027                         /* Lifetime */
1028                         proto_tree_add_item(t, hf_hip_tlv_reg_lt, tvb, newoffset, 1, FALSE);
1029                         newoffset++;
1030                         tlv_len--;
1031                 }
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 */
1039                         tlv_len--;
1040                         newoffset++;
1041                 }
1042                 break;
1043         case PARAM_HMAC:
1044         case PARAM_HMAC_2:
1045         case PARAM_RVS_HMAC:
1046         case PARAM_RELAY_HMAC:
1047                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1048                 /* HMAC */
1049                 proto_tree_add_item(t, hf_hip_tlv_hmac, tvb, offset+4,
1050                                      tlv_len, FALSE);
1051                 break;
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,
1058                                            n, "%u (%s)", n,
1059                                            val_to_str(n, sig_alg_vals, "Unknown"));
1060                 newoffset++;
1061                 /* Signature */
1062                 proto_tree_add_item(t, hf_hip_tlv_sig, tvb, newoffset, tlv_len-1,
1063                                     FALSE);
1064                 break;
1065         case PARAM_FROM:
1066                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1067                 /* Address */
1068                 proto_tree_add_item(t, hf_hip_tlv_from_address, tvb, newoffset, 16, FALSE);
1069                 break;
1070         case PARAM_VIA_RVS:
1071                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1072                 /* RVS Addresses  */
1073                 while (tlv_len > 0) {
1074                         proto_tree_add_item(t, hf_hip_tlv_rvs_address, tvb, newoffset, 16, FALSE);
1075                         tlv_len -= 16;
1076                         newoffset += 16;
1077                 }
1078                 break;
1079         case PARAM_RELAY_FROM:
1080                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1081                 /* Port */
1082                 proto_tree_add_item(t, hf_hip_tlv_relay_from_port, tvb, newoffset, 2, FALSE);
1083                 newoffset += 2;
1084                 /* Protocol */
1085                 proto_tree_add_item(t, hf_hip_tlv_relay_from_protocol, tvb, newoffset, 1, FALSE);
1086                 newoffset += 1;
1087                 /* Reserved */
1088                 proto_tree_add_item(t, hf_hip_tlv_relay_from_reserved, tvb, newoffset, 1, FALSE);
1089                 newoffset += 1;
1090                 /* Address */
1091                 proto_tree_add_item(t, hf_hip_tlv_relay_to_address, tvb, newoffset, 16, FALSE);
1092                 break;
1093         case PARAM_RELAY_TO:
1094                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1095                 /* Port */
1096                 proto_tree_add_item(t, hf_hip_tlv_relay_to_port, tvb, newoffset, 2, FALSE);
1097                 newoffset += 2;
1098                 /* Protocol */
1099                 proto_tree_add_item(t, hf_hip_tlv_relay_to_protocol, tvb, newoffset, 1, FALSE);
1100                 newoffset += 1;
1101                 /* Reserved */
1102                 proto_tree_add_item(t, hf_hip_tlv_relay_to_reserved, tvb, newoffset, 1, FALSE);
1103                 newoffset += 1;
1104                 /* Address */
1105                 proto_tree_add_item(t, hf_hip_tlv_relay_to_address, tvb, newoffset, 16, FALSE);
1106                 break;
1107         case PARAM_REG_FROM:
1108                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1109                 /* Port */
1110                 proto_tree_add_item(t, hf_hip_tlv_reg_from_port, tvb, newoffset, 2, FALSE);
1111                 newoffset += 2;
1112                 /* Protocol */
1113                 proto_tree_add_item(t, hf_hip_tlv_reg_from_protocol, tvb, newoffset, 1, FALSE);
1114                 newoffset += 1;
1115                 /* Reserved */
1116                 proto_tree_add_item(t, hf_hip_tlv_reg_from_reserved, tvb, newoffset, 1, FALSE);
1117                 newoffset += 1;
1118                 /* Address */
1119                 proto_tree_add_item(t, hf_hip_tlv_reg_from_address, tvb, newoffset, 16, FALSE);
1120                 break;
1121         default:
1122                 break;
1123         }
1124         return (0);
1125 }
1126
1127 void
1128 proto_register_hip(void)
1129 {
1130         static hf_register_info hf[] = {
1131                 { &hf_hip_proto,
1132                   { "Payload Protocol", "hip.proto",
1133                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1134
1135                 { &hf_hip_hdr_len,
1136                   { "Header Length", "hip.hdr_len",
1137                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1138
1139                 { &hf_hip_packet_type,
1140                   { "Packet Type", "hip.packet_type",
1141                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1142
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 }},
1146
1147                 { &hf_hip_version,
1148                   { "Version", "hip.version",
1149                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1150
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 }},
1154
1155                 { &hf_hip_controls,
1156                   { "HIP Controls", "hip.controls",
1157                     FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1158
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 }},
1162
1163                 { &hf_hip_checksum,
1164                   { "Checksum", "hip.checksum",
1165                     FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1166
1167                 { &hf_hip_hit_sndr,
1168                   { "Sender's HIT", "hip.hit_sndr",
1169                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1170
1171                 { &hf_hip_hit_rcvr,
1172                   { "Receiver's HIT", "hip.hit_rcvr",
1173                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1174
1175                 { &hf_hip_type,
1176                   { "Type", "hip.type",
1177                     FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1178
1179                 { &hf_hip_tlv_r1_res,
1180                   { "Reserved", "hip.tlv.r1_reserved",
1181                     FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1182
1183                 { &hf_hip_tlv_r1count,
1184                   { "R1 Counter", "hip.tlv.r1_counter",
1185                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1186
1187                 { &hf_hip_tlv_puzzle_k,
1188                   { "Difficulty (K)", "hip.tlv_puzzle_k",
1189                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1190
1191                 { &hf_hip_tlv_puzzle_life,
1192                   { "Lifetime", "hip.tlv_puzzle_lifetime",
1193                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1194
1195                 { &hf_hip_tlv_puzzle_o,
1196                   { "Opaque Data", "hip.tlv_puzzle_opaque",
1197                     FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1198
1199                 { &hf_hip_tlv_puzzle_i,
1200                   { "Random number (I)", "hip.tlv.puzzle_random_i",
1201                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1202
1203                 { &hf_hip_tlv_solution_k,
1204                   { "Difficulty (K)", "hip.tlv_solution_k",
1205                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1206
1207                 { &hf_hip_tlv_solution_reserved,
1208                   { "Reserved", "hip.tlv_solution_reserved",
1209                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1210
1211                 { &hf_hip_tlv_solution_o,
1212                   { "Opaque Data", "hip.tlv_solution_opaque",
1213                     FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1214
1215                 { &hf_hip_tlv_solution_i,
1216                   { "Random number (I)", "hip.tlv.solution_random_i",
1217                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1218
1219                 { &hf_hip_tlv_solution_j,
1220                   { "Solution (J)", "hip.tlv_solution_j",
1221                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1222
1223                 { &hf_hip_tlv_ei_res,
1224                   { "Reserved", "hip.tlv_esp_info_reserved",
1225                   FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1226
1227                 { &hf_hip_tlv_ei_keyidx,
1228                   { "Keymaterial Index", "hip.tlv_esp_info_key_index",
1229                     FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1230
1231                 { &hf_hip_tlv_ei_oldspi,
1232                   { "Old SPI", "hip.tlv_esp_info_old_spi",
1233                     FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1234
1235                 { &hf_hip_tlv_ei_newspi,
1236                   { "New SPI", "hip.tlv_esp_info_new_spi",
1237                     FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1238
1239                 { &hf_hip_tlv_seq_updid,
1240                   { "Seq Update ID", "hip.tlv_seq_update_id",
1241                     FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1242
1243                 { &hf_hip_tlv_ack_updid,
1244                   { "ACKed Peer Update ID", "hip.tlv_ack_updid",
1245                     FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1246
1247                 { &hf_hip_tlv_dh_group_id,
1248                   { "Group ID", "hip.tlv.dh_group_id",
1249                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1250
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 }},
1254
1255                 { &hf_hip_tlv_dh_pub,
1256                   { "Public Value", "hip.tlv.dh_public_value",
1257                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1258
1259                 { &hf_hip_tlv_trans_id,
1260                   { "Transform ID", "hip.tlv.trans_id",
1261                     FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1262
1263                 { &hf_hip_tlv_esp_reserved,
1264                   { "Reserved", "hip.tlv.esp_trans_res",
1265                     FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1266
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 }},
1270
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 }},
1274
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 }},
1278
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 }},
1282
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 }},
1287
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 }},
1292
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 }},
1297
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 }},
1301
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 }},
1305
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 }},
1309
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 }},
1313
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 }},
1317
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 }},
1321
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 }},
1325
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 }},
1329
1330                 { &hf_hip_tlv_notification_res,
1331                   { "Notification Reserved", "hip.tlv.notification_res",
1332                     FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1333
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 }},
1337
1338                 { &hf_hip_tlv_notification_data,
1339                   { "Notification Data", "hip.tlv.notification_data",
1340                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1341
1342                 { &hf_hip_tlv_opaque_data,
1343                   { "Opaque Data", "hip.tlv.opaque_data",
1344                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1345
1346                 { &hf_hip_tlv_reg_ltmin,
1347                   { "Minimum Registration Lifetime", "hip.tlv.reg_ltmin",
1348                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1349
1350                 { &hf_hip_tlv_reg_ltmax,
1351                   { "Maximum Registration Lifetime", "hip.tlv.reg_ltmax",
1352                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1353
1354                 { &hf_hip_tlv_reg_lt,
1355                   { "Registration Lifetime", "hip.tlv.reg_lt",
1356                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1357
1358                 { &hf_hip_tlv_reg_type,
1359                   { "Registration Type", "hip.tlv.reg_type",
1360                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1361
1362                 { &hf_hip_tlv_reg_failtype,
1363                   { "Registration Failure Type", "hip.tlv.reg_failtype",
1364                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1365
1366                 { &hf_hip_tlv_hmac,
1367                   { "HMAC", "hip.tlv.hmac",
1368                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1369
1370                 { &hf_hip_tlv_sig_alg,
1371                   { "Signature Algorithm", "hip.tlv.sig_alg",
1372                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1373
1374                 { &hf_hip_tlv_sig,
1375                   { "Signature", "hip.tlv.sig",
1376                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1377
1378                 { &hf_hip_tlv_enc_reserved,
1379                   { "Reserved", "hip.tlv.enc_reserved",
1380                     FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1381
1382                 { &hf_hip_tlv_locator_traffic_type,
1383                   { "Traffic Type", "hip.tlv.locator_traffic_type",
1384                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1385
1386                 { &hf_hip_tlv_locator_type,
1387                   { "Locator Type", "hip.tlv.locator_type",
1388                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1389
1390                 { &hf_hip_tlv_locator_len,
1391                   { "Locator Length", "hip.tlv.locator_len",
1392                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1393
1394                 { &hf_hip_tlv_locator_reserved,
1395                   { "Reserved", "hip.tlv.locator_reserved",
1396                     FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1397
1398                 { &hf_hip_tlv_locator_lifetime,
1399                   { "Locator Lifetime", "hip.tlv.locator_lifetime",
1400                     FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1401
1402                 { &hf_hip_tlv_locator_port,
1403                   { "Locator port", "hip.tlv.locator_port",
1404                     FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1405
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 }},
1409
1410                 { &hf_hip_tlv_locator_kind,
1411                   { "Locator kind", "hip.tlv.locator_kind",
1412                     FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1413
1414                 { &hf_hip_tlv_locator_priority,
1415                   { "Locator priority", "hip.tlv.locator_priority",
1416                     FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1417
1418                 { &hf_hip_tlv_locator_spi,
1419                   { "Locator spi", "hip.tlv.locator_spi",
1420                     FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1421
1422                 { &hf_hip_tlv_locator_address,
1423                   { "Locator" , "hip.tlv.locator_address",
1424                     FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1425
1426                 { &hf_hip_tlv_cert_group,
1427                   { "Cert group", "hip.tlv.cert_group",
1428                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1429
1430                 { &hf_hip_tlv_cert_count,
1431                   { "Cert count", "hip.tlv.cert_count",
1432                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1433
1434                 { &hf_hip_tlv_cert_id,
1435                   { "Cert ID", "hip.tlv.cert_id",
1436                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1437
1438                 { &hf_hip_tlv_cert_type,
1439                   { "Cert type", "hip.tlv.cert_type",
1440                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1441
1442                 { &hf_hip_tlv_certificate,
1443                   { "Certificate", "hip.tlv.certificate",
1444                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1445
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 }},
1449
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 }},
1453
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 }},
1457
1458                 { &hf_hip_tlv_reg_from_port,
1459                   { "Port", "hip.tlv.reg_from_port",
1460                     FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1461
1462                 { &hf_hip_tlv_transaction_minta,
1463                   { "Min Ta" , "hip.tlv_transaction_minta",
1464                     FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1465
1466                 { &hf_hip_tlv_from_address,
1467                   { "Address" , "hip.tlv_from_address",
1468                     FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1469
1470                 { &hf_hip_tlv_rvs_address,
1471                   { "RVS Address" , "hip.tlv_rvs_address",
1472                     FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1473
1474                 { &hf_hip_tlv_relay_from_protocol,
1475                   { "Protocol" , "hip.tlv_relay_from_protocol",
1476                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1477
1478                 { &hf_hip_tlv_relay_from_reserved,
1479                   { "Reserved" , "hip.tlv_relay_from_reserved",
1480                     FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1481
1482                 { &hf_hip_tlv_relay_from_address,
1483                   { "Address" , "hip.tlv_relay_from_address",
1484                     FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1485
1486                 { &hf_hip_tlv_relay_to_protocol,
1487                   { "Protocol" , "hip.tlv_relay_to_protocol",
1488                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1489
1490                 { &hf_hip_tlv_relay_to_reserved,
1491                   { "Reserved" , "hip.tlv_relay_to_reserved",
1492                     FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1493
1494                 { &hf_hip_tlv_relay_to_address,
1495                   { "Address" , "hip.tlv_relay_to_address",
1496                     FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1497
1498                 { &hf_hip_tlv_reg_from_protocol,
1499                   { "Protocol" , "hip.tlv_reg_from_protocol",
1500                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1501
1502                 { &hf_hip_tlv_reg_from_reserved,
1503                   { "Reserved" , "hip.tlv_reg_from_reserved",
1504                     FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1505
1506                 { &hf_hip_tlv_reg_from_address,
1507                   { "Address" , "hip.tlv_reg_from_address",
1508                     FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1509
1510         };
1511
1512         static gint *ett[] = {
1513                 &ett_hip,
1514                 &ett_hip_controls,
1515                 &ett_hip_tlv,
1516                 &ett_hip_tlv_data,
1517                 &ett_hip_tlv_host_id_hdr,
1518                 &ett_hip_locator_data,
1519         };
1520
1521         proto_hip = proto_register_protocol("Host Identity Protocol",
1522                                             "HIP", "hip");
1523
1524         proto_register_field_array(proto_hip, hf, array_length(hf));
1525         proto_register_subtree_array(ett, array_length(ett));
1526 }
1527
1528 void
1529 proto_reg_handoff_hip(void)
1530 {
1531         dissector_handle_t hip_handle;
1532         dissector_handle_t hip_handle2;
1533
1534         hip_handle = create_dissector_handle(dissect_hip, proto_hip);
1535         dissector_add_uint("ip.proto", IP_PROTO_HIP, hip_handle);
1536
1537         hip_handle2 = create_dissector_handle(dissect_hip_in_udp, proto_hip);
1538         dissector_add_uint("udp.port", 10500, hip_handle2);
1539 }