dbb3cb726cfcdad3ecb710db60ecfa4d55e92042
[metze/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 <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44
45 #include <epan/packet.h>
46 #include <epan/addr_resolv.h>
47
48 #include <epan/ipproto.h>
49 #include <epan/in_cksum.h>
50
51 #define HI_ALG_DSA 3
52 #define HI_ALG_RSA 5
53
54 /* HIP packet types */
55 typedef enum {
56         HIP_I1=1,
57         HIP_R1,
58         HIP_I2,
59         HIP_R2,
60         UPDATE=16,
61         NOTIFY=17,
62         CLOSE=18,
63         CLOSE_ACK=19
64 } HIP_PACKETS;
65
66 /* HIP TLV parameters listed in order of RFCs */
67
68 /* RFC 5201 */
69 #define PARAM_R1_COUNTER                128
70 #define PARAM_PUZZLE                    257
71 #define PARAM_SOLUTION                  321
72 #define PARAM_SEQ                       385
73 #define PARAM_ACK                       449
74 #define PARAM_DIFFIE_HELLMAN            513
75 #define PARAM_HIP_TRANSFORM             577
76 #define PARAM_ENCRYPTED                 641
77 #define PARAM_HOST_ID                   705
78 /* Type number defined in RFC 5201 contents 
79    in draft-ietf-hip-cert-00 */
80 #define PARAM_CERT                      768
81 #define PARAM_NOTIFICATION              832
82 #define PARAM_ECHO_REQUEST_SIGNED       897
83 #define PARAM_ECHO_RESPONSE_SIGNED      961
84 #define PARAM_HMAC                      61505
85 #define PARAM_HMAC_2                    61569
86 #define PARAM_HIP_SIGNATURE_2           61633
87 #define PARAM_HIP_SIGNATURE             61697
88 #define PARAM_ECHO_REQUEST_UNSIGNED     63661
89 #define PARAM_ECHO_RESPONSE_UNSIGNED    63425
90 /* RFC 5202 */
91 #define PARAM_ESP_INFO                  65
92 #define PARAM_ESP_TRANSFORM             4095
93 /* RFC 5203 */
94 #define PARAM_REG_INFO                  930
95 #define PARAM_REG_REQUEST               932
96 #define PARAM_REG_RESPONSE              934
97 #define PARAM_REG_FAILED                936
98 /* RFC 5204 */
99 #define PARAM_FROM                      65498
100 #define PARAM_RVS_HMAC                  65500
101 #define PARAM_VIA_RVS                   65502
102 /* RFC 5206 */
103 #define PARAM_LOCATOR                   193
104 /* draft-ietf-hip-nat-raversal-06.txt */
105 #define PARAM_NAT_TRAVERSAL_MODE        608
106 #define PARAM_TRANSACTION_PACING        610
107 #define PARAM_REG_FROM                  950
108 #define PARAM_RELAY_FROM                63998
109 #define PARAM_RELAY_TO                  64002
110  
111 /* Bit masks */
112 #define PARAM_CRITICAL_BIT              0x0001
113 /* See RFC 5201 section 5.1 */
114 #define HIP_PACKET_TYPE_MASK            0x7F
115 /* draft-ietf-shim6-proto-12 see section 5.3 */
116 #define HIP_SHIM6_FIXED_BIT_P_MASK      0x80
117 #define HIP_SHIM6_FIXED_BIT_S_MASK      0x01
118 /* 00001110 Excluding the shim6 compatibility bit */
119 #define HIP_RESERVED_MASK               0x0E 
120 #define HIP_VERSION_MASK                0xF0
121 #define HIP_CONTROL_A_MASK              0x0001
122 #define HIP_CONTROL_C_MASK              0x0002
123
124 #define HI_HDR_FLAGS_MASK               0xFFFF0000
125 #define HI_HDR_PROTO_MASK               0x0000FF00
126 #define HI_HDR_ALG_MASK                 0x000000FF
127
128 static const value_string pinfo_vals[] = {
129         { HIP_I1, "HIP I1 (HIP Initiator Packet)" },
130         { HIP_R1, "HIP R1 (HIP Responder Packet)" },
131         { HIP_I2, "HIP I2 (Second HIP Initiator Packet)" },
132         { HIP_R2, "HIP R2 (Second HIP Responder Packet)" },
133         { UPDATE, "HIP UPDATE (HIP Update Packet)" },
134         { NOTIFY, "HIP NOTIFY (HIP Notify Packet)" },
135         { CLOSE, "HIP CLOSE (HIP Close Packet)" },
136         { CLOSE_ACK, "HIP CLOSE_ACK (HIP Close Acknowledgement Packet)" },
137         { 0, NULL }
138 };
139
140 static const value_string hip_param_vals[] = {
141         { PARAM_ESP_INFO, "ESP_INFO" },
142         { PARAM_R1_COUNTER, "R1_COUNTER" },
143         { PARAM_LOCATOR, "LOCATOR" },
144         { PARAM_PUZZLE, "PUZZLE" },
145         { PARAM_SOLUTION, "SOLUTION" },
146         { PARAM_SEQ, "SEQ" },
147         { PARAM_ACK, "ACK" },
148         { PARAM_DIFFIE_HELLMAN, "DIFFIE_HELLMAN" },
149         { PARAM_HIP_TRANSFORM, "HIP_TRANSFORM" },
150         { PARAM_ENCRYPTED, "ENCRYPTED" },
151         { PARAM_HOST_ID, "HOST_ID" },
152         { PARAM_CERT, "CERT" },
153         { PARAM_NOTIFICATION, "NOTIFICATION" },
154         { PARAM_ECHO_REQUEST_SIGNED, "ECHO_REQUEST_SIGNED" },
155         { PARAM_ECHO_RESPONSE_SIGNED, "ECHO_RESPONSE_SIGNED" },
156         { PARAM_ESP_TRANSFORM, "ESP_TRANSFORM" },
157         { PARAM_HMAC, "HMAC" },
158         { PARAM_HMAC_2, "HMAC_2" },
159         { PARAM_HIP_SIGNATURE, "HIP_SIGNATURE" },
160         { PARAM_HIP_SIGNATURE_2, "HIP_SIGNATURE_2" },
161         { PARAM_ECHO_REQUEST_UNSIGNED, "ECHO_REQUEST_UNSIGNED" },
162         { PARAM_ECHO_RESPONSE_UNSIGNED, "ECHO_RESPONSE_UNSIGNED" },
163         { PARAM_NAT_TRAVERSAL_MODE, "NAT_TRAVERSAL_MODE" },
164         { PARAM_TRANSACTION_PACING, "TRANSACTION_PACING" },
165         { PARAM_RELAY_FROM, "RELAY_FROM" },
166         { PARAM_RELAY_TO, "RELAY_TO" },
167         { PARAM_REG_INFO, "REG_INFO" },
168         { PARAM_REG_REQUEST, "REG_REQUEST" },
169         { PARAM_REG_RESPONSE, "REG_RESPONSE" },
170         { PARAM_REG_FROM, "REG_FROM" },
171         { 0, NULL }
172 };
173
174 /* RFC 5201 section 5.2.6. */
175 static const value_string dh_group_id_vals[] = {
176         { 0x0, "Reserved" }, 
177         { 0x01, "384-bit group" },
178         { 0x02, "OAKLEY well-known group 1" },
179         { 0x03, "1536-bit MODP group" }, 
180         { 0x04, "3072-bit MODP group" },
181         { 0x05, "6144-bit MODP group" },
182         { 0x06, "8192-bit MODP group" },
183         { 0, NULL }
184 };
185
186 /* RFC 5202 section 5.1.2. */       
187 static const value_string transform_id_vals[] = {
188         { 0x0, "Reserved" },
189         { 0x01, "AES-CBC with HMAC-SHA1" },
190         { 0x02, "3DES-CBC with HMAC-SHA1" },
191         { 0x03, "3DES-CBC with HMAC-MD5" },
192         { 0x04, "BLOWFISH-CBC with HMAC-SHA1" },
193         { 0x05, "NULL with HMAC-SHA1" },
194         { 0x06, "NULL with HMAC-MD5" },
195         { 0, NULL }
196 };
197  
198 static const value_string reg_type_vals[] = {
199         { 0x01, "RENDEZVOUS" }, /* RFC 5204 */
200         { 0x02, "REALY_UDP_HIP" }, /* draft-ietf-hip-nat-raversal-06.txt */
201         { 0, NULL }
202 };
203
204 /* RFC 5201 section 5.2.8 */
205 static const value_string sig_alg_vals[] = {
206         { 0x0, "Reserved" },
207         { HI_ALG_DSA, "DSA" },
208         { HI_ALG_RSA, "RSA" },
209         { 0, NULL }
210 }; 
211
212 /* draft-ietf-hip-nat-traversal-06.txt */
213 static const value_string mode_id_vals[] = {
214         { 0x0, "Reserved" },
215         { 0x01, "UDP-encapsulation" },
216         { 0x02, "ICE-STUN-UDP" },
217         { 0, NULL }
218 };
219
220 static const value_string hi_hdr_flags_vals[] = {
221         { 0x0, "Other" },
222         { 0x0200, "Key is associated with a user" },
223         { 0x0201, "Zone key" },
224         { 0x0202, "Key is associated with non-zone entity" },
225         { 0, NULL }
226 };
227
228 /* RFC 2535 section 3.1.3 */
229 static const value_string hi_hdr_proto_vals[] = {
230         { 0x01, "Key is used for TLS" },
231         { 0x02, "Key is used for email" },
232         { 0x03, "Key is used for DNS security" },
233         { 0x04, "Key is used for Oakley/IPSEC" },
234         { 0xFF, "Key is valid for any protocol" },
235         { 0, NULL }
236 };
237
238 /* RFC 2535 section 3.2 */
239 static const value_string hi_hdr_alg_vals[] = {
240         { 0x00, "Reserved" },
241         { 0x01, "RSA/MD5" },
242         { 0x02, "Diffie-Hellman" },
243         { 0x03, "DSA" },
244         { 0x04, "elliptic curve crypto" },
245         { 0x05, "RSA" },
246         { 0xFF, "Reserved" },
247         { 0, NULL }
248 };
249
250 /* RFC 5201 */
251 static const value_string notification_vals[] = {
252         { 1,  "Unsupported critical parameter type" },
253         { 7,  "Invalid syntax" },
254         { 14, "No Diffie-Hellman proposal chosen" },
255         { 15, "Invalid Diffie-Hellman chosen" },
256         { 16, "No HIP proposal chosen" },
257         { 17, "Invalid HIP transform chosen" },
258         { 18, "No ESP proposal chosen" },
259         { 19, "Invalid ESP transform chosen" },
260         { 24, "Authentication failed" },
261         { 26, "Checksum failed" },
262         { 28, "HMAC failed" },
263         { 32, "Encryption failed" },
264         { 40, "Invalid HIT" },
265         { 42, "Blocked by policy" },
266         { 44, "Server busy please retry" },
267         { 0, NULL }
268 };
269
270 /* draft-ietf-hip-nat-raversal-06.txt */
271 static const value_string nat_traversal_mode_vals[] = {
272         { 0, "Reserved"},
273         { 1, "UDP-encapsulation"},
274         { 2, "ICE-STUN-UDP"},
275         { 0, NULL }
276 };
277  
278 /* functions */
279 static int dissect_hip_tlv(tvbuff_t *tvb, int offset, proto_item *ti, int type, int tlv_len);
280
281 static int proto_hip = -1;
282 static int hf_hip_proto = -1;
283 static int hf_hip_hdr_len = -1;
284 static int hf_hip_shim6_fixed_bit_p = -1;
285 static int hf_hip_packet_type = -1;
286 static int hf_hip_version = -1;
287 static int hf_hip_shim6_fixed_bit_s = -1;
288 static int hf_hip_controls = -1;
289 static int hf_hip_controls_anon = -1;
290 static int hf_hip_checksum = -1;
291 static int hf_hip_hit_sndr = -1;
292 static int hf_hip_hit_rcvr = -1;
293
294 static int hf_hip_type = -1;
295 static int hf_hip_tlv_ei_res = -1;
296 static int hf_hip_tlv_ei_keyidx = -1;
297 static int hf_hip_tlv_ei_oldspi = -1;
298 static int hf_hip_tlv_ei_newspi = -1;
299 static int hf_hip_tlv_r1_res = -1;
300 static int hf_hip_tlv_r1count = -1;
301 static int hf_hip_tlv_puzzle_k = -1;
302 static int hf_hip_tlv_puzzle_life = -1;
303 static int hf_hip_tlv_puzzle_o = -1;
304 static int hf_hip_tlv_puzzle_i = -1;
305 static int hf_hip_tlv_solution_k = -1;
306 static int hf_hip_tlv_solution_reserved = -1;
307 static int hf_hip_tlv_solution_o = -1;
308 static int hf_hip_tlv_solution_i = -1;
309 static int hf_hip_tlv_solution_j = -1;
310 static int hf_hip_tlv_seq_updid = -1;
311 static int hf_hip_tlv_ack_updid = -1;
312 static int hf_hip_tlv_dh_group_id = -1;
313 static int hf_hip_tlv_dh_pub = -1;
314 static int hf_hip_tlv_dh_pv_length = -1;
315 static int hf_hip_tlv_trans_id = -1;
316 static int hf_hip_tlv_esp_reserved = -1;
317 static int hf_hip_tlv_host_id_len = -1;
318 static int hf_hip_tlv_host_di_type = -1;
319 static int hf_hip_tlv_host_di_len = -1;
320 static int hf_hip_tlv_host_id_hdr = -1;
321 static int hf_hip_tlv_host_id_hdr_flags = -1;
322 static int hf_hip_tlv_host_id_hdr_proto = -1;
323 static int hf_hip_tlv_host_id_hdr_alg = -1;
324 static int hf_hip_tlv_host_id_t = -1;
325 static int hf_hip_tlv_host_id_q = -1;
326 static int hf_hip_tlv_host_id_p = -1;
327 static int hf_hip_tlv_host_id_g = -1;
328 static int hf_hip_tlv_host_id_y = -1;
329 static int hf_hip_tlv_host_id_e_len = -1;
330 static int hf_hip_tlv_host_id_e = -1;
331 static int hf_hip_tlv_host_id_n = -1;
332 static int hf_hip_tlv_notification_res = -1;
333 static int hf_hip_tlv_notification_type = -1;
334 static int hf_hip_tlv_notification_data = -1;
335 static int hf_hip_tlv_opaque_data = -1;
336 static int hf_hip_tlv_reg_ltmin = -1;
337 static int hf_hip_tlv_reg_ltmax = -1;
338 static int hf_hip_tlv_reg_lt = -1;
339 static int hf_hip_tlv_reg_type = -1;
340 static int hf_hip_tlv_reg_failtype = -1;
341 static int hf_hip_tlv_hmac = -1;
342 static int hf_hip_tlv_sig_alg = -1;
343 static int hf_hip_tlv_sig = -1;
344 static int hf_hip_tlv_enc_reserved = -1;
345 static int hf_hip_tlv_locator_traffic_type = -1;
346 static int hf_hip_tlv_locator_type = -1;
347 static int hf_hip_tlv_locator_len = -1;
348 static int hf_hip_tlv_locator_reserved = -1;
349 static int hf_hip_tlv_locator_lifetime = -1;
350 static int hf_hip_tlv_locator_port = -1;
351 static int hf_hip_tlv_locator_transport_protocol = -1;
352 static int hf_hip_tlv_locator_kind = -1;
353 static int hf_hip_tlv_locator_priority = -1;
354 static int hf_hip_tlv_locator_spi = -1;
355 static int hf_hip_tlv_locator_address = -1;
356
357 static int hf_hip_tlv_cert_group = -1;
358 static int hf_hip_tlv_cert_count = -1;
359 static int hf_hip_tlv_cert_id = -1;
360 static int hf_hip_tlv_cert_type = -1;
361 static int hf_hip_tlv_certificate = -1;
362
363 static int hf_hip_tlv_from_address = -1;
364 static int hf_hip_tlv_rvs_address = -1;
365
366 static int hf_hip_tlv_nat_traversal_mode_id = -1;
367 static int hf_hip_tlv_transaction_minta = -1;
368 static int hf_hip_tlv_relay_from_port = -1;
369 static int hf_hip_tlv_relay_from_protocol = -1;
370 static int hf_hip_tlv_relay_from_reserved = -1;
371 static int hf_hip_tlv_relay_from_address = -1;
372 static int hf_hip_tlv_relay_to_port = -1;
373 static int hf_hip_tlv_relay_to_protocol = -1;
374 static int hf_hip_tlv_relay_to_reserved = -1;
375 static int hf_hip_tlv_relay_to_address = -1;
376 static int hf_hip_tlv_reg_from_port = -1;
377 static int hf_hip_tlv_reg_from_protocol = -1;
378 static int hf_hip_tlv_reg_from_reserved = -1;
379 static int hf_hip_tlv_reg_from_address = -1;
380
381 static gint ett_hip = -1;
382 static gint ett_hip_controls = -1;
383 static gint ett_hip_tlv = -1;
384 static gint ett_hip_tlv_data = -1;
385 static gint ett_hip_tlv_host_id_hdr = -1;
386
387 /* Dissect the HIP packet */
388 static void 
389 dissect_hip(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) 
390 {
391         proto_tree *hip_tree, *hip_tlv_tree=NULL;
392         proto_item *ti, *ti_tlv;        
393         int length, offset = 0, newoffset = 0;
394         guint16 control_h, checksum_h, computed_checksum;
395         guint16 tlv_type_h, tlv_length_h; /* For storing in host order */
396         vec_t cksum_vec[4];
397         guint32 phdr[2];
398  
399         /* Payload format RFC 5201 section 5.1 */
400         guint8 hiph_proto;                /* payload protocol              */
401         guint8 hiph_hdr_len;              /* header length                 */
402         guint8 hiph_shim6_fixed_bit_s;    /* This is always 0              */
403         guint8 hiph_packet_type;          /* packet type                   */
404         guint8 hiph_res_ver, hiph_version, hiph_reserved;              
405                                           /* byte for reserved and version */
406         guint8 hiph_shim6_fixed_bit_p;    /* This is always 1              */
407         /* checksum_h */                  /* checksum                      */
408         /* control_h */                   /* control                       */
409         /* HIP parameters ...  */ 
410
411         /*  load the top pane info. This should be overwritten by
412             the next protocol in the stack */
413         col_set_str(pinfo->cinfo, COL_PROTOCOL, "HIP");
414         col_clear(pinfo->cinfo, COL_INFO);
415
416         newoffset = offset;
417         hiph_proto = tvb_get_guint8(tvb, newoffset);    
418         newoffset++;
419         hiph_hdr_len = tvb_get_guint8(tvb, newoffset);  
420         newoffset++;
421         hiph_packet_type = tvb_get_guint8(tvb, newoffset);
422         /* draft-ietf-shim6-proto-12 see section 5.3 */
423         hiph_shim6_fixed_bit_p = (hiph_packet_type & HIP_SHIM6_FIXED_BIT_P_MASK) >> 7;
424         hiph_packet_type = hiph_packet_type & HIP_PACKET_TYPE_MASK;
425         newoffset++;
426         hiph_res_ver = tvb_get_guint8(tvb, newoffset);  
427         /* divide to reserved and version and shim6_fixed_bit_s 
428            draft-ietf-shim6-proto-12 see section 5.3 */
429         hiph_version = (hiph_res_ver & HIP_VERSION_MASK) >> 4;
430         hiph_reserved = hiph_res_ver & HIP_RESERVED_MASK;       
431         hiph_shim6_fixed_bit_s = hiph_res_ver & HIP_SHIM6_FIXED_BIT_S_MASK;
432         newoffset++;
433         checksum_h = tvb_get_ntohs(tvb, newoffset);
434         newoffset += 2;
435         control_h = tvb_get_ntohs(tvb, newoffset);
436         newoffset += 2;
437
438         col_set_str(pinfo->cinfo, COL_INFO, val_to_str(hiph_packet_type, pinfo_vals, "Unknown"));
439
440         /* populate a tree in the second pane with the status of the link layer (i.e. none) */
441         if(tree) {
442                 ti = proto_tree_add_item(tree, proto_hip, tvb, 0, -1, FALSE);
443
444                 hip_tree = proto_item_add_subtree(ti, ett_hip);
445                 proto_tree_add_item(hip_tree, hf_hip_proto, tvb, offset, 1, FALSE);
446                 proto_tree_add_item(hip_tree, hf_hip_hdr_len, tvb, offset+1, 1, FALSE);
447                 proto_tree_add_uint_format(hip_tree, hf_hip_shim6_fixed_bit_p, tvb, offset+2, 1, 
448                                            hiph_shim6_fixed_bit_p, 
449                                            "Fixed P-bit: %u (Always zero)", 
450                                            hiph_shim6_fixed_bit_p);  
451                 proto_tree_add_uint(hip_tree, hf_hip_packet_type, tvb, offset+2, 1, 
452                                     hiph_packet_type);
453                 proto_tree_add_uint_format(hip_tree, hf_hip_version, tvb, offset+3, 1, 
454                                            hiph_version, "Version: %u, Reserved: %u", 
455                                            hiph_version, hiph_reserved); 
456                 proto_tree_add_uint_format(hip_tree, hf_hip_shim6_fixed_bit_s, tvb, offset+3, 1, 
457                                            hiph_shim6_fixed_bit_s, 
458                                            "Fixed S-bit: %u (%s)", 
459                                            hiph_shim6_fixed_bit_s, 
460                                            ((hiph_shim6_fixed_bit_s) ? "HIP" : "SHIM6"));
461         
462                 /* Checksum - this is the same algorithm from UDP, ICMPv6 */
463                 if (!pinfo->fragmented) {
464                         /* IPv4 or IPv6 addresses */
465                         cksum_vec[0].ptr = pinfo->src.data;
466                         cksum_vec[0].len = pinfo->src.len;
467                         cksum_vec[1].ptr = pinfo->dst.data;
468                         cksum_vec[1].len = pinfo->dst.len;
469
470                         /* the rest of the pseudo-header */
471                         if (pinfo->src.type == AT_IPv6) {
472                                 cksum_vec[2].ptr = (const guint8 *)&phdr;
473                                 phdr[0] = g_htonl(tvb_reported_length(tvb));
474                                 phdr[1] = g_htonl(IP_PROTO_HIP);
475                                 cksum_vec[2].len = 8;
476                         } else {
477                                 cksum_vec[2].ptr = (const guint8 *)&phdr;
478                                 phdr[0] = g_htonl((IP_PROTO_HIP<<16)+tvb_reported_length(tvb));
479                                 cksum_vec[2].len = 4;
480                         }
481                         /* pointer to the HIP header (packet data) */
482                         cksum_vec[3].len = tvb_reported_length(tvb);
483                         cksum_vec[3].ptr = tvb_get_ptr(tvb, 0, cksum_vec[3].len);
484                         computed_checksum = in_cksum(cksum_vec, 4);
485                         if (computed_checksum == 0) {
486                                 proto_tree_add_uint_format(hip_tree, hf_hip_checksum, tvb, 
487                                                            offset+4, 2, checksum_h, 
488                                                            "Checksum: 0x%04x (correct)",
489                                                            checksum_h);
490                         } else {
491                                 proto_tree_add_uint_format(hip_tree, hf_hip_checksum, tvb,
492                                                            offset+4, 2, checksum_h,
493                                                            "Checksum: 0x%04x (incorrect, "
494                                                            "should be 0x%04x)",
495                                                            checksum_h,
496                                                            in_cksum_shouldbe(checksum_h, 
497                                                                              computed_checksum));
498                         }
499                 } else {
500                         proto_tree_add_uint_format(hip_tree, hf_hip_checksum, tvb,
501                                                    offset+4, 2, checksum_h,
502                                                    "Checksum: 0x%04x (unverified)",
503                                                    checksum_h);
504                 }
505
506                 ti = proto_tree_add_item(hip_tree, hf_hip_controls, tvb, offset+6, 2, FALSE);
507                 if (ti) { 
508                         /* HIP Controls subtree */
509                         ti = proto_item_add_subtree(ti, ett_hip_controls);                      
510                         proto_tree_add_boolean(ti, hf_hip_controls_anon, tvb, 
511                                                offset+7,1, control_h);
512                 }
513         
514                 offset += 8;
515                 proto_tree_add_item(hip_tree, hf_hip_hit_sndr, tvb, offset, 
516                                      16, FALSE);
517                 offset += 16;
518                 proto_tree_add_item(hip_tree, hf_hip_hit_rcvr, tvb, offset, 
519                                      16, FALSE);
520                 offset += 16;
521                 
522                 length = (hiph_hdr_len + 1) * 8;
523                 /* Begin TLV parsing */
524                 if (offset < length) {
525                         ti_tlv = proto_tree_add_text(hip_tree, tvb, offset, 
526                                                      tvb_length(tvb), "HIP Parameters");
527                         hip_tlv_tree = proto_item_add_subtree(ti_tlv, ett_hip_tlv);
528                 }
529                 /* Parse type and length in TLV */
530                 while (offset < length)
531                 {                        
532                         tlv_type_h = tvb_get_ntohs(tvb, offset);
533                         tlv_length_h = tvb_get_ntohs(tvb, offset + 2);
534                         ti_tlv = proto_tree_add_uint_format(hip_tlv_tree, hf_hip_type, tvb,
535                                                             offset, 4 + tlv_length_h, tlv_type_h, 
536                                                             "%s (type=%u, length=%u)",
537                                                             val_to_str(tlv_type_h, hip_param_vals, "Unknown"),
538                                                             tlv_type_h, tlv_length_h);
539             
540                         /* Parse value */
541                         dissect_hip_tlv(tvb, offset, ti_tlv, tlv_type_h, tlv_length_h);
542                         
543                         offset += 11 + tlv_length_h - (tlv_length_h + 3) % 8;
544                 }
545                 
546         }
547 }
548
549 static void 
550 dissect_hip_in_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
551 {
552         guint32 nullbytes;
553         nullbytes = tvb_get_ntohl(tvb, 0);
554         if (nullbytes == 0)
555         {
556                 tvbuff_t *newtvb = tvb_new_subset_remaining(tvb, 4);
557                 dissect_hip(newtvb, pinfo, tree);
558         }
559 }
560
561    
562 static int 
563 dissect_hip_tlv(tvbuff_t *tvb, int offset, proto_item *ti, int type, int tlv_len)
564 {
565         proto_tree *t=NULL;
566         proto_item *ti_tlv;
567         guint8 n, algorithm, reg_type;
568         guint16 trans, hi_len, di_len, di_type, e_len, pv_len;
569         guint32 reserved, hi_hdr;
570         guint8 transport_proto;
571         guint8 locator_type;
572         int newoffset, newlen, hi_t;
573         
574         /* move over the TLV */
575         newoffset = offset + 4;
576         switch (type)
577         {
578         case PARAM_ESP_INFO: 
579                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
580                 /* Reserved */
581                 proto_tree_add_item(t, hf_hip_tlv_ei_res, tvb, newoffset, 2, FALSE);
582                 /* KEYMAT index */
583                 newoffset += 2;
584                 proto_tree_add_item(t, hf_hip_tlv_ei_keyidx, tvb, newoffset, 2, FALSE);
585                 /* OLD SPI */ 
586                 newoffset += 2;
587                 proto_tree_add_item(t, hf_hip_tlv_ei_oldspi, tvb, newoffset, 4, FALSE);
588                 /* NEW SPI */ 
589                 newoffset += 4;
590                 proto_tree_add_item(t, hf_hip_tlv_ei_newspi, tvb, newoffset, 4, FALSE); 
591                 break;
592         case PARAM_R1_COUNTER: 
593                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
594                 /* Reserved */
595                 proto_tree_add_item(t, hf_hip_tlv_r1_res, tvb, newoffset, 4, FALSE);
596                 /* R1 generation counter */
597                 newoffset += 4;
598                 proto_tree_add_item(t, hf_hip_tlv_r1count, tvb, newoffset, 8, FALSE);
599                 break;
600         case PARAM_LOCATOR: 
601                 /* RFC 5206 section 4. and 
602                    draft-ietf-hip-nat-raversal-06.txt section 5.7. 
603                    for type 2 locators */
604                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
605                 tlv_len -= 4;
606                 /* loop through included locators */ 
607                 while (tlv_len > 0) {
608                         /* Traffic type */
609                         proto_tree_add_item(t, hf_hip_tlv_locator_traffic_type, tvb,
610                                             newoffset, 1, FALSE);
611                         newoffset++; 
612                         /* Locator type */
613                         locator_type = tvb_get_guint8(tvb, newoffset);
614                         proto_tree_add_item(t, hf_hip_tlv_locator_type, tvb, newoffset, 1, FALSE);
615                         newoffset++;
616                         /* Locator length */
617                         proto_tree_add_item(t, hf_hip_tlv_locator_len, tvb, newoffset, 1, FALSE);
618                         newoffset++;
619                         /* Reserved includes the Preferred bit */
620                         reserved = tvb_get_guint8(tvb, newoffset);
621                         proto_tree_add_uint_format(t, hf_hip_tlv_locator_reserved, tvb, 
622                                                    newoffset, 1, reserved,      
623                                                    "Reserved: 0x%x %s", reserved,
624                                                    (reserved >> 31) ? "(Preferred)" : "");
625                         newoffset++;
626                         /* Locator lifetime */ 
627                         proto_tree_add_item(t, hf_hip_tlv_locator_lifetime, tvb,
628                                             newoffset, 4, FALSE);
629                         newoffset += 4;
630                         /* Locator types 1 and 0 RFC 5206 section 4.2.*/
631                         if (locator_type == 1 || locator_type == 0) {
632                                 /* Locator */
633                                 proto_tree_add_item(t, hf_hip_tlv_locator_address, tvb, newoffset, 16, FALSE);
634                                 newoffset += 16;
635                                 tlv_len -= 24;
636                         /* Locator type 2 draft-ietf-hip-nat-raversal-06.txt section 5.7. */
637                         } else if (locator_type == 2) {
638                                 /* Tansport port */
639                                 proto_tree_add_item(t, hf_hip_tlv_locator_port, tvb, 
640                                                     newoffset, 2, FALSE);
641                                 newoffset += 2; 
642                                 /* Transport protocol */
643                                 transport_proto = tvb_get_guint8(tvb, newoffset);
644                                 /* draft-ietf-hip-nat-traversal-06 section 5.6 */
645                                 proto_tree_add_uint_format(t, hf_hip_tlv_locator_transport_protocol,
646                                                            tvb, newoffset, 1, transport_proto,  
647                                                            "Transport protocol: %d %s", 
648                                                            transport_proto,
649                                                            (transport_proto == 17) ? 
650                                                            "(UDP)" : "");
651                                 newoffset++;
652                                 /* Kind */
653                                 proto_tree_add_item(t, hf_hip_tlv_locator_kind, tvb, 
654                                                     newoffset, 1, FALSE);
655                                 newoffset++;
656                                 /* Priority */
657                                 proto_tree_add_item(t, hf_hip_tlv_locator_priority, tvb,
658                                                     newoffset, 4, FALSE);
659                                 newoffset += 4;    
660                                 /* SPI */
661                                 proto_tree_add_item(t, hf_hip_tlv_locator_spi, tvb,
662                                                     newoffset, 4, FALSE);
663                                 newoffset += 4; 
664                                 /* Locator */
665                                 proto_tree_add_item(t, hf_hip_tlv_locator_address, tvb, newoffset, 16, FALSE);
666                                 newoffset += 16;
667                                 tlv_len -= 36;                        
668                         }
669                 }
670                 break;
671         case PARAM_PUZZLE:
672                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
673                 /* K number of verified bits */
674                 proto_tree_add_item(t, hf_hip_tlv_puzzle_k, tvb, newoffset, 1, FALSE);
675                 /* Puzzle lifetime */
676                 newoffset++;
677                 proto_tree_add_item(t, hf_hip_tlv_puzzle_life, tvb, newoffset, 1, FALSE);
678                 /* Puzzle O*/
679                 newoffset++;
680                 proto_tree_add_item(t, hf_hip_tlv_puzzle_o, tvb, newoffset, 2, FALSE);
681                 /* Puzzle I */
682                 newoffset += 2;
683                 proto_tree_add_item(t, hf_hip_tlv_puzzle_i, tvb,offset+8, 8, FALSE);
684                 break;
685         case PARAM_SOLUTION:
686                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
687                 /* K number of verified bits */
688                 proto_tree_add_item(t, hf_hip_tlv_solution_k, tvb, newoffset, 1, FALSE);
689                 /* Solution Reserved */
690                 newoffset++;
691                 proto_tree_add_item(t, hf_hip_tlv_solution_reserved, tvb, newoffset, 1, FALSE);
692                 /* Solution Opaque */
693                 newoffset++;
694                 proto_tree_add_item(t, hf_hip_tlv_solution_o, tvb,newoffset, 2, FALSE);
695                 /* Solution I */
696                 newoffset += 2;
697                 proto_tree_add_item(t, hf_hip_tlv_solution_i, tvb, newoffset, 8, FALSE);
698                 /* Solution J */
699                 newoffset += 8;
700                 proto_tree_add_item(t, hf_hip_tlv_solution_j, tvb, newoffset, 8, FALSE);
701                 break;
702         case PARAM_SEQ: 
703                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
704                 /* Update ID */
705                 proto_tree_add_item(t, hf_hip_tlv_seq_updid, tvb, newoffset, 4, FALSE);
706                 break;
707         case PARAM_ACK: 
708                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
709                 /* Can contain multiple Update IDs from peer */
710                 while (tlv_len > 0) {
711                         /* peer Update ID */
712                         proto_tree_add_item(t, hf_hip_tlv_ack_updid, tvb, newoffset, 4, FALSE);
713                         newoffset += 4;
714                         tlv_len -= 4;
715                 }
716                 break;
717         case PARAM_DIFFIE_HELLMAN: 
718                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
719                 n = tvb_get_guint8(tvb, newoffset);
720                 /* First Group ID*/
721                 proto_tree_add_uint_format(t, hf_hip_tlv_dh_group_id, tvb, newoffset,
722                                            1, n, "%u (%s)", n, 
723                                            val_to_str(n, dh_group_id_vals, "Unknown"));
724                 /* First Public value len */
725                 newoffset++;            
726                 pv_len = tvb_get_ntohs(tvb, newoffset);                
727                 proto_tree_add_item(t, hf_hip_tlv_dh_pv_length, tvb, newoffset, 2, FALSE);
728
729                 /* First Public value */
730                 newoffset += 2;
731                 proto_tree_add_item(t, hf_hip_tlv_dh_pub, tvb, newoffset, pv_len, FALSE);
732                 /* Check for the second group */
733                 if ((pv_len + newoffset) < tlv_len) {
734                         /* Second Group ID*/
735                         newoffset += pv_len;
736                         proto_tree_add_uint_format(t, hf_hip_tlv_dh_group_id, tvb, newoffset,
737                                                    1, n, "%u (%s)", n,
738                                                    val_to_str(n, dh_group_id_vals, "Unknown"));
739                         /* Second Public value len */
740                         newoffset += 1;
741                         pv_len = tvb_get_ntohs(tvb, newoffset);
742                         proto_tree_add_item(t, hf_hip_tlv_dh_pv_length, tvb, newoffset, 2, FALSE);
743                         /* Second Public Value */
744                         newoffset += 2;
745                         proto_tree_add_item(t, hf_hip_tlv_dh_pub, tvb, newoffset, 
746                                              pv_len, FALSE);
747                 }
748                 break;
749         case PARAM_ESP_TRANSFORM:
750                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
751                 /* Reserved */
752                 proto_tree_add_item(t, hf_hip_tlv_esp_reserved, tvb, newoffset, 2, FALSE);
753                 newoffset +=2;
754                 tlv_len -= 2;
755                 while (tlv_len > 0) {
756                         /* Suite # 1, 2, ...,  n
757                            two bytes per transform id */
758                         trans = tvb_get_ntohs(tvb, newoffset);
759                         proto_tree_add_uint_format(t, hf_hip_tlv_trans_id, tvb, 
760                                                    newoffset, 2, trans, "%u (%s)", trans,
761                                                    val_to_str(trans, transform_id_vals, "Unknown"));
762                         tlv_len -= 2;
763                         newoffset += 2;
764                 }
765                 break; 
766         case PARAM_HIP_TRANSFORM: 
767                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
768                 while (tlv_len > 0) {
769                         /* Suite # 1, 2, ...,  n
770                            two bytes per transform id */
771                         trans = tvb_get_ntohs(tvb, newoffset);
772                         proto_tree_add_uint_format(t, hf_hip_tlv_trans_id, tvb, 
773                                                    newoffset, 2, trans, "%u (%s)", trans,
774                                                    val_to_str(trans, transform_id_vals, "Unknown"));
775                         tlv_len -= 2; 
776                         newoffset += 2;
777                 }
778                 break;
779         case PARAM_NAT_TRAVERSAL_MODE: 
780                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
781                 /* Reserved */
782                 proto_tree_add_item(t, hf_hip_tlv_esp_reserved, tvb, newoffset, 2, FALSE);
783                 newoffset += 2;
784                 tlv_len -= 2;
785                 while (tlv_len > 0) {
786                         /* Suite # 1, 2, ...,  n
787                            two bytes per mode id */
788                         trans = tvb_get_ntohs(tvb, newoffset);
789                         proto_tree_add_uint_format(t, hf_hip_tlv_nat_traversal_mode_id, tvb, 
790                                                    newoffset, 2, trans, "%u (%s)", trans,
791                                                    val_to_str(trans, mode_id_vals, "Unknown"));
792                         tlv_len -= 2; 
793                         newoffset += 2;
794                 }
795                 break; 
796         case PARAM_TRANSACTION_PACING: 
797                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
798                 /* Min Ta */
799                 proto_tree_add_item(t, hf_hip_tlv_transaction_minta, tvb, newoffset, 4, FALSE);
800                 break;
801         case PARAM_ENCRYPTED: 
802                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
803                 /* Reserved */
804                 proto_tree_add_item(t, hf_hip_tlv_enc_reserved, tvb, newoffset, 4, FALSE);
805                 newoffset += 4;
806                 /* IV 
807                    16 bytes IV for AES CBC RFC 3602 
808                     8 bytes IV for 3DES CBC RFC 2405                
809                     0 bytes IV for NULL 
810                     and 
811                     encrypted data after that.
812                 */
813                 proto_tree_add_text(t, tvb, newoffset, tlv_len - 4, 
814                                     "Encrypted Parameter Data (%u bytes)",  tlv_len - 4);
815                 break;
816         case PARAM_HOST_ID: 
817                 if (type != PARAM_ENCRYPTED)
818                         t = proto_item_add_subtree(ti, ett_hip_tlv_data);              
819                 hi_len = tvb_get_ntohs(tvb, newoffset);
820                 proto_tree_add_item(t, hf_hip_tlv_host_id_len, tvb, newoffset, 2, FALSE);
821                 newoffset += 2;
822                 di_len = tvb_get_ntohs(tvb, newoffset);
823                 di_type = (di_len >> 12) & 0x000F;      /* get 4 bits for DI type */
824                 di_len = di_len & 0x0FFF;               /* 12 bits for DI length */
825                 /* DI type */
826                 proto_tree_add_item(t, hf_hip_tlv_host_di_type, tvb, newoffset, 1, FALSE);
827                 /* DI len */
828                 proto_tree_add_item(t, hf_hip_tlv_host_di_len, tvb, newoffset, 2, FALSE);
829                 newoffset += 2;
830                 /* hi_hdr - first 4 bytes are 0200ff03 (KEY RR in RFC 2535)
831                  *   flags     2  octets
832                  *   protocol  1  octet
833                  *   algorithm 1  octet (DSA or RSA)
834                  *   <public key>
835                  */
836                 hi_hdr = tvb_get_ntohl(tvb, newoffset);
837                 ti_tlv = proto_tree_add_item(t, hf_hip_tlv_host_id_hdr, 
838                                              tvb, newoffset, 4, FALSE);
839                 if (ti_tlv) {
840                         ti_tlv = proto_item_add_subtree(ti_tlv, ett_hip_tlv_host_id_hdr);
841                         /* HDR Flags*/
842                         proto_tree_add_uint(ti_tlv, hf_hip_tlv_host_id_hdr_flags, tvb, 
843                                             newoffset, 2, hi_hdr);
844                         newoffset += 2;
845                         /* HDR Protocol */
846                         proto_tree_add_uint(ti_tlv, hf_hip_tlv_host_id_hdr_proto, tvb, 
847                                             newoffset, 1,  hi_hdr);
848                         newoffset += 1;
849                         /* HDR Algorithm */
850                         proto_tree_add_uint(ti_tlv, hf_hip_tlv_host_id_hdr_alg, tvb, 
851                                             newoffset, 1, hi_hdr);
852                 }
853                 algorithm = tvb_get_guint8(tvb, newoffset); 
854                 switch (algorithm) {
855                 case HI_ALG_DSA:
856                         /* DSA KEY RR RFC 2536  
857                          *   T         1  octet
858                          *   Q         20  octets
859                          *   P         64 + T*8  octets
860                          *   G         64 + T*8  octets
861                          *   Y         64 + T*8  octets
862                          */
863                         newoffset++; /* 12 + offset */
864                         /* T */ 
865                         proto_tree_add_item(t, hf_hip_tlv_host_id_t, tvb, newoffset, 1, FALSE);
866                         hi_t = tvb_get_guint8(tvb, newoffset);
867                         newoffset++;
868                         /* Q */ 
869                         proto_tree_add_item(t, hf_hip_tlv_host_id_q, tvb, newoffset, 
870                                              20, FALSE);
871                         newoffset += 20;
872                         if (hi_t > 56) /* max 4096 bits */
873                                 break;
874                         /* P */
875                         newlen = 64 + (hi_t * 8);
876                         proto_tree_add_item(t, hf_hip_tlv_host_id_p, tvb, newoffset,
877                                              newlen, FALSE);
878                         /* G */
879                         newoffset += newlen;
880                         proto_tree_add_item(t, hf_hip_tlv_host_id_g, tvb, newoffset,
881                                              newlen, FALSE);
882                         /* Y */
883                         newoffset += newlen;
884                         proto_tree_add_item(t, hf_hip_tlv_host_id_y, tvb, newoffset,
885                                              newlen, FALSE);
886                         break;
887                 case HI_ALG_RSA:
888                         /* RSA KEY RR RFC 3110
889                          * e_len        1 or 3 octets
890                          * e            specified by e_len
891                          * n            variable length public modulus
892                          */
893                         newoffset++; /* 12 + offset */
894                         /* E len */
895                         e_len = tvb_get_guint8(tvb, newoffset); 
896                         proto_tree_add_item(t, hf_hip_tlv_host_id_e_len, tvb, newoffset,
897                                             (e_len > 255) ? 3 : 1, FALSE);
898                         newoffset++;
899                         hi_len -= 5; /* subtract RDATA + e_len */
900                         if (e_len == 0) { /* e_len is 0 followed by 16-bit value */
901                                 e_len = tvb_get_ntohs(tvb, newoffset);
902                                 newoffset += 2;
903                                 hi_len -= 2;
904                         }
905                         if (e_len > 512) { /* per, RFC 3110 < 4096 bits */
906                                 proto_tree_add_text(t, tvb, newoffset, 2,
907                                                     "<< e_len too large >>");
908                                 break;
909                         }
910                         /* e */
911                         proto_tree_add_item(t, hf_hip_tlv_host_id_e, tvb, newoffset,
912                                              e_len, FALSE);
913                         newoffset += e_len;
914                         hi_len -= e_len;
915                         
916                         if (hi_len > 512) {
917                                 proto_tree_add_text(t, tvb, newoffset, 1,
918                                                     "<< Invalid HI length >>");
919                                 break;
920                         }
921                         
922                         /* RSA public modulus n */
923                         proto_tree_add_item(t, hf_hip_tlv_host_id_n, tvb, newoffset,
924                                              hi_len, FALSE);
925                         break;
926                 default:
927                         proto_tree_add_text(t, tvb, newoffset, 1,
928                                             "Unknown algorithm type (%d).\n", algorithm);
929                         
930                         break;
931                 }
932                 /* FQDN */
933                 if (di_type == 0)
934                         break;
935                 if (di_type == 1) {
936                         /* RFC 1035 */
937                         proto_tree_add_text(t, tvb, offset+16+hi_len, di_len,
938                                             "FQDN: %s", tvb_get_ephemeral_string (tvb, offset+16+hi_len, di_len));
939                 } else if (di_type == 2) { 
940                         /* RFC 4282 */
941                         proto_tree_add_text(t, tvb, offset+16+hi_len, di_len,
942                                             "NAI: %s", tvb_get_ephemeral_string (tvb, offset+16+hi_len, di_len));
943                 }
944                 break;
945         case PARAM_CERT: /* CERT */
946                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
947                 /* Cert Group */
948                 proto_tree_add_item(t, hf_hip_tlv_cert_group, tvb, newoffset, 1, FALSE);
949                 newoffset++;
950                 /* Cert Count */
951                 proto_tree_add_item(t, hf_hip_tlv_cert_count, tvb, newoffset, 1, FALSE);
952                 newoffset++;
953                 /* Cert ID */
954                 proto_tree_add_item(t, hf_hip_tlv_cert_id, tvb, newoffset, 1, FALSE);
955                 newoffset++;
956                 /* Cert Type */
957                 proto_tree_add_item(t, hf_hip_tlv_cert_type, tvb, newoffset, 1, FALSE);
958                 newoffset++;
959                 /* Certificate */
960                 proto_tree_add_item(t, hf_hip_tlv_certificate, tvb, newoffset,
961                                      tlv_len-4, FALSE);
962                 break;
963         case PARAM_NOTIFICATION: 
964                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
965                 /* Reserved */
966                 proto_tree_add_item(t, hf_hip_tlv_notification_res, tvb, newoffset, 2, FALSE);
967                 newoffset += 2;
968                 /* Notification Message Type */
969                 proto_tree_add_item(t, hf_hip_tlv_notification_type, tvb, newoffset, 2, FALSE);
970                 newoffset += 2;
971                 /* Notification Data */
972                 proto_tree_add_item(t, hf_hip_tlv_notification_data, tvb, newoffset,
973                                      tlv_len-4, FALSE);
974                 break;
975         case PARAM_ECHO_REQUEST_SIGNED:
976         case PARAM_ECHO_RESPONSE_SIGNED: 
977         case PARAM_ECHO_REQUEST_UNSIGNED: 
978         case PARAM_ECHO_RESPONSE_UNSIGNED: 
979                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
980                 /* Variable length Opaque Data */
981                 proto_tree_add_item(t, hf_hip_tlv_opaque_data, tvb, newoffset,
982                                      tlv_len, FALSE);
983                 break;
984         case PARAM_REG_INFO:
985         case PARAM_REG_REQUEST:
986         case PARAM_REG_RESPONSE:
987         case PARAM_REG_FAILED:
988                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
989                 if (type == PARAM_REG_INFO) { 
990                         /* Min Lifetime */
991                         proto_tree_add_item(t, hf_hip_tlv_reg_ltmin, tvb, newoffset, 1, FALSE);
992                         newoffset++;
993                         /* Max Lifetime */
994                         proto_tree_add_item(t, hf_hip_tlv_reg_ltmax, tvb, newoffset, 1, FALSE);
995                         newoffset++;
996                         tlv_len -= 2;
997                 } else if (type == PARAM_REG_FAILED) { 
998                         /* Failure Type */
999                         proto_tree_add_item(t, hf_hip_tlv_reg_failtype, tvb, newoffset, 1, FALSE);
1000                         newoffset++;;
1001                         tlv_len--;
1002                 } else { 
1003                         /* Lifetime */
1004                         proto_tree_add_item(t, hf_hip_tlv_reg_lt, tvb, newoffset, 1, FALSE);
1005                         newoffset++;
1006                         tlv_len--;
1007                 }
1008                 /* Reg Type 1 ... n, Padding */
1009                 while (tlv_len > 0) {
1010                         reg_type = tvb_get_guint8(tvb, newoffset);
1011                         proto_tree_add_uint_format(t, hf_hip_tlv_reg_type, tvb, 
1012                                                    newoffset, 1, reg_type, "%u (%s)", reg_type,
1013                                                    val_to_str(reg_type, reg_type_vals, "Unknown"));
1014                         /* one byte per registration type */
1015                         tlv_len--; 
1016                         newoffset++;
1017                 }
1018                 break;
1019         case PARAM_HMAC: 
1020         case PARAM_HMAC_2: 
1021         case PARAM_RVS_HMAC: 
1022                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1023                 /* HMAC */
1024                 proto_tree_add_item(t, hf_hip_tlv_hmac, tvb, offset+4,
1025                                      tlv_len, FALSE);
1026                 break;
1027         case PARAM_HIP_SIGNATURE:
1028         case PARAM_HIP_SIGNATURE_2: 
1029                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1030                 /* Signature algorithm */
1031                 n = tvb_get_guint8(tvb, offset+4);
1032                 proto_tree_add_uint_format(t, hf_hip_tlv_sig_alg, tvb, newoffset, 1,
1033                                            n, "%u (%s)", n, 
1034                                            val_to_str(n, sig_alg_vals, "Unknown"));
1035                 newoffset++;
1036                 /* Signature */
1037                 proto_tree_add_item(t, hf_hip_tlv_sig, tvb, newoffset, tlv_len-1,
1038                                     FALSE);
1039                 break;
1040         case PARAM_FROM:
1041                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1042                 /* Address */
1043                 proto_tree_add_item(t, hf_hip_tlv_from_address, tvb, newoffset, 16, FALSE);
1044                 break;
1045         case PARAM_VIA_RVS:
1046                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1047                 /* RVS Addresses  */
1048                 while (tlv_len > 0) {
1049                         proto_tree_add_item(t, hf_hip_tlv_rvs_address, tvb, newoffset, 16, FALSE);
1050                         tlv_len -= 16;
1051                         newoffset += 16;
1052                 }
1053                 break;
1054         case PARAM_RELAY_FROM:
1055                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1056                 /* Port */
1057                 proto_tree_add_item(t, hf_hip_tlv_relay_from_port, tvb, newoffset, 2, FALSE);
1058                 newoffset += 2; 
1059                 /* Protocol */
1060                 proto_tree_add_item(t, hf_hip_tlv_relay_from_protocol, tvb, newoffset, 1, FALSE);
1061                 newoffset += 1; 
1062                 /* Reserved */
1063                 proto_tree_add_item(t, hf_hip_tlv_relay_from_reserved, tvb, newoffset, 1, FALSE);
1064                 newoffset += 1; 
1065                 /* Address */
1066                 proto_tree_add_item(t, hf_hip_tlv_relay_to_address, tvb, newoffset, 16, FALSE);
1067                 break;
1068         case PARAM_RELAY_TO:
1069                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1070                 /* Port */
1071                 proto_tree_add_item(t, hf_hip_tlv_relay_to_port, tvb, newoffset, 2, FALSE);
1072                 newoffset += 2; 
1073                 /* Protocol */
1074                 proto_tree_add_item(t, hf_hip_tlv_relay_to_protocol, tvb, newoffset, 1, FALSE);
1075                 newoffset += 1; 
1076                 /* Reserved */
1077                 proto_tree_add_item(t, hf_hip_tlv_relay_to_reserved, tvb, newoffset, 1, FALSE);
1078                 newoffset += 1; 
1079                 /* Address */
1080                 proto_tree_add_item(t, hf_hip_tlv_relay_to_address, tvb, newoffset, 16, FALSE);
1081                 break;
1082         case PARAM_REG_FROM:
1083                 t = proto_item_add_subtree(ti, ett_hip_tlv_data);
1084                 /* Port */
1085                 proto_tree_add_item(t, hf_hip_tlv_reg_from_port, tvb, newoffset, 2, FALSE);
1086                 newoffset += 2; 
1087                 /* Protocol */
1088                 proto_tree_add_item(t, hf_hip_tlv_reg_from_protocol, tvb, newoffset, 1, FALSE);
1089                 newoffset += 1; 
1090                 /* Reserved */
1091                 proto_tree_add_item(t, hf_hip_tlv_reg_from_reserved, tvb, newoffset, 1, FALSE);
1092                 newoffset += 1; 
1093                 /* Address */
1094                 proto_tree_add_item(t, hf_hip_tlv_reg_from_address, tvb, newoffset, 16, FALSE);
1095                 break;
1096
1097         default:
1098                 break;
1099         }
1100         return (0);
1101 }
1102
1103 void
1104 proto_register_hip(void)
1105 {
1106         static hf_register_info hf[] = {
1107                 { &hf_hip_proto,
1108                   { "Payload Protocol", "hip.proto", 
1109                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1110                 
1111                 { &hf_hip_hdr_len,
1112                   { "Header Length", "hip.hdr_len", 
1113                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1114                 
1115                 { &hf_hip_packet_type,
1116                   { "Packet Type", "hip.packet_type", 
1117                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1118                 
1119                 { &hf_hip_shim6_fixed_bit_p,
1120                   { "Header fixed bit P", "hip.shim6_fixed_p", 
1121                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1122
1123                 { &hf_hip_version,
1124                   { "Version", "hip.version", 
1125                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1126                 
1127                 { &hf_hip_shim6_fixed_bit_s,
1128                   { "Header fixed bit S", "hip.shim6_fixed_s", 
1129                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1130                 
1131                 { &hf_hip_controls,
1132                   { "HIP Controls", "hip.controls", 
1133                     FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1134                                 
1135                 { &hf_hip_controls_anon,
1136                   { "Anonymous (Sender's HI is anonymous)", "hip.controls.a", 
1137                     FT_BOOLEAN, 16, NULL, HIP_CONTROL_A_MASK, NULL, HFILL }},
1138                 
1139                 { &hf_hip_checksum,
1140                   { "Checksum", "hip.checksum", 
1141                     FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1142                 
1143                 { &hf_hip_hit_sndr,
1144                   { "Sender's HIT", "hip.hit_sndr", 
1145                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1146                 
1147                 { &hf_hip_hit_rcvr,
1148                   { "Receiver's HIT", "hip.hit_rcvr", 
1149                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1150                 
1151                 { &hf_hip_type,
1152                   { "Type", "hip.type", 
1153                     FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1154                 
1155                 { &hf_hip_tlv_r1_res,
1156                   { "Reserved", "hip.tlv.r1_reserved", 
1157                     FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1158                 
1159                 { &hf_hip_tlv_r1count,
1160                   { "R1 Counter", "hip.tlv.r1_counter", 
1161                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1162                 
1163                 { &hf_hip_tlv_puzzle_k,
1164                   { "Difficulty (K)", "hip.tlv_puzzle_k", 
1165                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1166                 
1167                 { &hf_hip_tlv_puzzle_life,
1168                   { "Lifetime", "hip.tlv_puzzle_lifetime", 
1169                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1170                 
1171                 { &hf_hip_tlv_puzzle_o,
1172                   { "Opaque Data", "hip.tlv_puzzle_opaque", 
1173                     FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1174                 
1175                 { &hf_hip_tlv_puzzle_i,
1176                   { "Random number (I)", "hip.tlv.puzzle_random_i", 
1177                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1178
1179                 { &hf_hip_tlv_solution_k,
1180                   { "Difficulty (K)", "hip.tlv_solution_k", 
1181                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1182                 
1183                 { &hf_hip_tlv_solution_reserved,
1184                   { "Reserved", "hip.tlv_solution_reserved", 
1185                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1186                 
1187                 { &hf_hip_tlv_solution_o,
1188                   { "Opaque Data", "hip.tlv_solution_opaque", 
1189                     FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1190                 
1191                 { &hf_hip_tlv_solution_i,
1192                   { "Random number (I)", "hip.tlv.solution_random_i", 
1193                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1194                 
1195                 { &hf_hip_tlv_solution_j,
1196                   { "Solution (J)", "hip.tlv_solution_j", 
1197                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1198                                 
1199                 { &hf_hip_tlv_ei_res,
1200                 { "Reserved", "hip.tlv_esp_info_reserved", 
1201                   FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1202                 
1203                 { &hf_hip_tlv_ei_keyidx,
1204                   { "Keymaterial Index", "hip.tlv_esp_info_key_index", 
1205                     FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1206                 
1207                 { &hf_hip_tlv_ei_oldspi,
1208                   { "Old SPI", "hip.tlv_esp_info_old_spi", 
1209                     FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1210                 
1211                 { &hf_hip_tlv_ei_newspi,
1212                   { "New SPI", "hip.tlv_esp_info_new_spi", 
1213                     FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1214                 
1215                 { &hf_hip_tlv_seq_updid,
1216                   { "Seq Update ID", "hip.tlv_seq_update_id", 
1217                     FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1218                 
1219                 { &hf_hip_tlv_ack_updid,
1220                   { "ACKed Peer Update ID", "hip.tlv_ack_updid", 
1221                     FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1222                 
1223                 { &hf_hip_tlv_dh_group_id,
1224                   { "Group ID", "hip.tlv.dh_group_id", 
1225                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1226
1227                 { &hf_hip_tlv_dh_pv_length,
1228                   { "Public Value Length", "hip.tlv.dh_pv_length", 
1229                     FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1230
1231                 { &hf_hip_tlv_dh_pub,
1232                   { "Public Value", "hip.tlv.dh_public_value", 
1233                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1234                 
1235                 { &hf_hip_tlv_trans_id,
1236                   { "Transform ID", "hip.tlv.trans_id", 
1237                     FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1238                 
1239                 { &hf_hip_tlv_esp_reserved,
1240                   { "Reserved", "hip.tlv.esp_trans_res", 
1241                     FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1242                 
1243                 { &hf_hip_tlv_host_id_len,
1244                   { "Host Identity Length", "hip.tlv.host_id_length", 
1245                     FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1246                 
1247                 { &hf_hip_tlv_host_di_type,
1248                   { "Domain Identifier Type", "hip.tlv.host_domain_id_type", 
1249                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1250                 
1251                 { &hf_hip_tlv_host_di_len,
1252                   { "Domain Identifier Length", "hip.tlv.host_domain_id_length", 
1253                     FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1254                 
1255                 { &hf_hip_tlv_host_id_hdr,
1256                   { "Host Identity flags", "hip.tlv.host_id_hdr", 
1257                     FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1258                 
1259                 { &hf_hip_tlv_host_id_hdr_flags,
1260                   { "Host Identity Header Flags", "hip.tlv.host_id_header_flags", 
1261                     FT_UINT32, BASE_HEX, VALS(hi_hdr_flags_vals), 
1262                     HI_HDR_FLAGS_MASK, NULL, HFILL }},
1263                 
1264                 { &hf_hip_tlv_host_id_hdr_proto,
1265                   { "Host Identity Header Protocol", "hip.tlv.host_id_header_proto", 
1266                     FT_UINT32, BASE_HEX, VALS(hi_hdr_proto_vals), 
1267                     HI_HDR_PROTO_MASK, NULL, HFILL }},
1268                 
1269                 { &hf_hip_tlv_host_id_hdr_alg,
1270                   { "Host Identity Header Algorithm", "hip.tlv.host_id_header_algo", 
1271                     FT_UINT32, BASE_HEX, VALS(hi_hdr_alg_vals), 
1272                     HI_HDR_ALG_MASK, NULL, HFILL }},
1273                 
1274                 { &hf_hip_tlv_host_id_t,
1275                   { "Host Identity T", "hip.tlv.host_identity_t", 
1276                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1277                 
1278                 { &hf_hip_tlv_host_id_q,
1279                   { "Host Identity Q", "hip.tlv.host_identity_q", 
1280                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1281                 
1282                 { &hf_hip_tlv_host_id_p,
1283                   { "Host Identity P", "hip.tlv.host_id_p", 
1284                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1285
1286                 { &hf_hip_tlv_host_id_g,
1287                   { "Host Identity G", "hip.tlv.host_id_g", 
1288                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1289
1290                 { &hf_hip_tlv_host_id_y,
1291                   { "Host Identity Y (public value)", "hip.tlv.host_id_y", 
1292                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1293                 
1294                 { &hf_hip_tlv_host_id_e_len,
1295                   { "RSA Host Identity exponent length (e_len)", "hip.tlv.host_id_e_length",
1296                     FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1297                 
1298                 { &hf_hip_tlv_host_id_e,
1299                   { "RSA Host Identity exponent (e)", "hip.tlv.host_id_e", 
1300                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1301                 
1302                 { &hf_hip_tlv_host_id_n,
1303                   { "RSA Host Identity public modulus (n)", "hip.tlv.host_id_n", 
1304                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1305                                 
1306                 { &hf_hip_tlv_notification_res,
1307                   { "Notification Reserved", "hip.tlv.notification_res", 
1308                     FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1309                 
1310                 { &hf_hip_tlv_notification_type,
1311                   { "Notification Message Type", "hip.tlv.notification_type", 
1312                     FT_UINT16, BASE_DEC, VALS(notification_vals), 0xFFFF, NULL, HFILL }},
1313                 
1314                 { &hf_hip_tlv_notification_data,
1315                   { "Notification Data", "hip.tlv.notification_data", 
1316                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1317                 
1318                 { &hf_hip_tlv_opaque_data,
1319                   { "Opaque Data", "hip.tlv.opaque_data", 
1320                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1321                 
1322                 { &hf_hip_tlv_reg_ltmin,
1323                   { "Minimum Registration Lifetime", "hip.tlv.reg_ltmin", 
1324                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1325                 
1326                 { &hf_hip_tlv_reg_ltmax,
1327                   { "Maximum Registration Lifetime", "hip.tlv.reg_ltmax", 
1328                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1329                 
1330                 { &hf_hip_tlv_reg_lt,
1331                   { "Registration Lifetime", "hip.tlv.reg_lt", 
1332                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1333                 
1334                 { &hf_hip_tlv_reg_type,
1335                   { "Registration Type", "hip.tlv.reg_type", 
1336                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1337                 
1338                 { &hf_hip_tlv_reg_failtype,
1339                   { "Registration Failure Type", "hip.tlv.reg_failtype", 
1340                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1341                 
1342                 { &hf_hip_tlv_hmac,
1343                   { "HMAC", "hip.tlv.hmac", 
1344                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1345                 
1346                 { &hf_hip_tlv_sig_alg,
1347                   { "Signature Algorithm", "hip.tlv.sig_alg", 
1348                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1349                 
1350                 { &hf_hip_tlv_sig,
1351                   { "Signature", "hip.tlv.sig", 
1352                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1353                 
1354                 { &hf_hip_tlv_enc_reserved,
1355                   { "Reserved", "hip.tlv.enc_reserved", 
1356                     FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1357
1358                 { &hf_hip_tlv_locator_traffic_type,
1359                   { "Traffic Type", "hip.tlv.locator_traffic_type", 
1360                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1361
1362                 { &hf_hip_tlv_locator_type,
1363                   { "Locator Type", "hip.tlv.locator_type", 
1364                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1365
1366                 { &hf_hip_tlv_locator_len,
1367                   { "Locator Length", "hip.tlv.locator_len", 
1368                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1369
1370                 { &hf_hip_tlv_locator_reserved,
1371                   { "Reserved", "hip.tlv.locator_reserved", 
1372                     FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1373
1374                 { &hf_hip_tlv_locator_lifetime,
1375                   { "Locator Lifetime", "hip.tlv.locator_lifetime", 
1376                     FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1377
1378                 { &hf_hip_tlv_locator_port,
1379                   { "Locator port", "hip.tlv.locator_port", 
1380                     FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1381
1382                 { &hf_hip_tlv_locator_transport_protocol,
1383                   { "Locator transport protocol", "hip.tlv.locator_transport_protocol", 
1384                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1385
1386                 { &hf_hip_tlv_locator_kind,
1387                   { "Locator kind", "hip.tlv.locator_kind", 
1388                     FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1389
1390                 { &hf_hip_tlv_locator_priority,
1391                   { "Locator priority", "hip.tlv.locator_priority", 
1392                     FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1393
1394                 { &hf_hip_tlv_locator_spi,
1395                   { "Locator spi", "hip.tlv.locator_spi", 
1396                     FT_UINT32, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1397
1398                 { &hf_hip_tlv_locator_address,
1399                   { "Locator" , "hip.tlv.locator_address", 
1400                     FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1401
1402                 { &hf_hip_tlv_cert_group,
1403                   { "Cert group", "hip.tlv.cert_group", 
1404                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1405
1406                 { &hf_hip_tlv_cert_count,
1407                   { "Cert count", "hip.tlv.cert_count", 
1408                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1409                 
1410                 { &hf_hip_tlv_cert_id,
1411                   { "Cert ID", "hip.tlv.cert_id", 
1412                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1413                 
1414                 { &hf_hip_tlv_cert_type,
1415                   { "Cert type", "hip.tlv.cert_type", 
1416                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1417                 
1418                 { &hf_hip_tlv_certificate,
1419                   { "Certificate", "hip.tlv.certificate", 
1420                     FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1421
1422                 { &hf_hip_tlv_nat_traversal_mode_id,
1423                   { "NAT Traversal Mode ID", "hip.tlv.nat_traversal_mode_id", 
1424                     FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1425
1426                 { &hf_hip_tlv_relay_from_port,
1427                   { "Relay From Port", "hip.tlv.relay_from_port", 
1428                     FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1429
1430                 { &hf_hip_tlv_relay_to_port,
1431                   { "Relay To Port", "hip.tlv.relay_to_port", 
1432                     FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1433                 
1434                 { &hf_hip_tlv_reg_from_port,
1435                   { "Port", "hip.tlv.reg_from_port", 
1436                     FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1437
1438                 { &hf_hip_tlv_transaction_minta,
1439                   { "Min Ta" , "hip.tlv_transaction_minta", 
1440                     FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1441
1442                 { &hf_hip_tlv_from_address,
1443                   { "Address" , "hip.tlv_from_address", 
1444                     FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1445
1446                 { &hf_hip_tlv_rvs_address,
1447                   { "RVS Address" , "hip.tlv_rvs_address", 
1448                     FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1449
1450                 { &hf_hip_tlv_relay_from_protocol,
1451                   { "Protocol" , "hip.tlv_relay_from_protocol", 
1452                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1453
1454                 { &hf_hip_tlv_relay_from_reserved,
1455                   { "Reserved" , "hip.tlv_relay_from_reserved", 
1456                     FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1457
1458                 { &hf_hip_tlv_relay_from_address,
1459                   { "Address" , "hip.tlv_relay_from_address", 
1460                     FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1461
1462                 { &hf_hip_tlv_relay_to_protocol,
1463                   { "Protocol" , "hip.tlv_relay_to_protocol", 
1464                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1465
1466                 { &hf_hip_tlv_relay_to_reserved,
1467                   { "Reserved" , "hip.tlv_relay_to_reserved", 
1468                     FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1469
1470                 { &hf_hip_tlv_relay_to_address,
1471                   { "Address" , "hip.tlv_relay_to_address", 
1472                     FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1473
1474                 { &hf_hip_tlv_reg_from_protocol,
1475                   { "Protocol" , "hip.tlv_reg_from_protocol", 
1476                     FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
1477
1478                 { &hf_hip_tlv_reg_from_reserved,
1479                   { "Reserved" , "hip.tlv_reg_from_reserved", 
1480                     FT_UINT8, BASE_HEX, NULL, 0x0, NULL, HFILL }},
1481
1482                 { &hf_hip_tlv_reg_from_address,
1483                   { "Address" , "hip.tlv_reg_from_address", 
1484                     FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
1485
1486         };
1487
1488         static gint *ett[] = {
1489                 &ett_hip,
1490                 &ett_hip_controls,
1491                 &ett_hip_tlv,
1492                 &ett_hip_tlv_data,
1493                 &ett_hip_tlv_host_id_hdr,
1494         };
1495
1496         proto_hip = proto_register_protocol("Host Identity Protocol",
1497                                             "HIP", "hip");
1498
1499         proto_register_field_array(proto_hip, hf, array_length(hf));
1500         proto_register_subtree_array(ett, array_length(ett));
1501 }
1502
1503 void
1504 proto_reg_handoff_hip(void)
1505 {
1506         dissector_handle_t hip_handle;
1507         dissector_handle_t hip_handle2;
1508         
1509         hip_handle = create_dissector_handle(dissect_hip, proto_hip);
1510         dissector_add("ip.proto", IP_PROTO_HIP, hip_handle);
1511
1512         hip_handle2 = create_dissector_handle(dissect_hip_in_udp, proto_hip);
1513         dissector_add("udp.port", 50500, hip_handle2);
1514 }