2 * Routines for NBMA Next Hop Resolution Protocol
3 * RFC 2332 plus Cisco extensions (documented where?), plus extensions from:
4 * RFC 2520: NHRP with Mobile NHCs
5 * RFC 2735: NHRP Support for Virtual Private Networks
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
27 * CIE decoding for extensions and Cisco 12.4T extensions
28 * added by Timo Teras <timo.teras@iki.fi>
37 #include <epan/packet.h>
38 #include <epan/addr_resolv.h>
39 #include <epan/expert.h>
40 #include <epan/etypes.h>
41 #include <epan/ipproto.h>
42 #include <epan/greproto.h>
43 #include <epan/nlpid.h>
46 #include <epan/in_cksum.h>
47 #include <epan/iana_snap_pid.h>
48 #include <epan/dissectors/packet-llc.h>
49 #include "packet-nhrp.h"
51 /* forward reference */
52 static void _dissect_nhrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
53 gboolean nested, gboolean codeinfo);
55 static int proto_nhrp = -1;
56 static int hf_nhrp_hdr_afn = -1;
57 static int hf_nhrp_hdr_pro_type = -1;
58 static int hf_nhrp_hdr_pro_snap_oui = -1;
59 static int hf_nhrp_hdr_pro_snap_pid = -1;
60 static int hf_nhrp_hdr_hopcnt = -1;
61 static int hf_nhrp_hdr_pktsz = -1;
62 static int hf_nhrp_hdr_chksum = -1;
63 static int hf_nhrp_hdr_extoff = -1;
64 static int hf_nhrp_hdr_version = -1;
65 static int hf_nhrp_hdr_op_type = -1;
66 static int hf_nhrp_hdr_shtl = -1;
67 static int hf_nhrp_hdr_shtl_type = -1;
68 static int hf_nhrp_hdr_shtl_len = -1;
69 static int hf_nhrp_hdr_sstl = -1;
70 static int hf_nhrp_hdr_sstl_type = -1;
71 static int hf_nhrp_hdr_sstl_len = -1;
73 static int hf_nhrp_src_proto_len = -1;
74 static int hf_nhrp_dst_proto_len = -1;
75 static int hf_nhrp_flags = -1;
76 static int hf_nhrp_flag_Q = -1;
77 static int hf_nhrp_flag_N = -1;
78 static int hf_nhrp_flag_A = -1;
79 static int hf_nhrp_flag_D = -1;
80 static int hf_nhrp_flag_U1 = -1;
81 static int hf_nhrp_flag_U2 = -1;
82 static int hf_nhrp_flag_S = -1;
83 static int hf_nhrp_flag_NAT = -1;
84 static int hf_nhrp_src_nbma_addr = -1;
86 static int hf_nhrp_src_nbma_saddr = -1; /* TBD: Not used */
88 static int hf_nhrp_src_prot_addr = -1;
89 static int hf_nhrp_dst_prot_addr = -1;
90 static int hf_nhrp_request_id = -1;
92 static int hf_nhrp_code = -1;
93 static int hf_nhrp_prefix_len = -1;
94 static int hf_nhrp_unused = -1;
95 static int hf_nhrp_mtu = -1;
96 static int hf_nhrp_holding_time = -1;
97 static int hf_nhrp_cli_addr_tl = -1;
98 static int hf_nhrp_cli_addr_tl_type = -1;
99 static int hf_nhrp_cli_addr_tl_len = -1;
100 static int hf_nhrp_cli_saddr_tl = -1;
101 static int hf_nhrp_cli_saddr_tl_type = -1;
102 static int hf_nhrp_cli_saddr_tl_len = -1;
103 static int hf_nhrp_cli_prot_len = -1;
104 static int hf_nhrp_pref = -1;
105 static int hf_nhrp_client_nbma_addr = -1;
107 static int hf_nhrp_client_nbma_saddr = -1; /* TBD: Not used */
109 static int hf_nhrp_client_prot_addr = -1;
110 static int hf_nhrp_ext_C = -1;
111 static int hf_nhrp_ext_type = -1;
112 static int hf_nhrp_ext_len = -1;
114 static int hf_nhrp_ext_value = -1; /* TBD: Not used */
116 static int hf_nhrp_error_code = -1;
117 static int hf_nhrp_error_offset = -1;
119 static int hf_nhrp_error_packet = -1; /* TBD: Not used */
122 static int hf_nhrp_auth_ext_reserved = -1;
123 static int hf_nhrp_auth_ext_spi = -1;
124 static int hf_nhrp_auth_ext_src_addr = -1;
125 static int hf_nhrp_vendor_ext_id = -1;
126 static int hf_nhrp_devcap_ext_srccap = -1;
127 static int hf_nhrp_devcap_ext_srccap_V = -1;
128 static int hf_nhrp_devcap_ext_dstcap = -1;
129 static int hf_nhrp_devcap_ext_dstcap_V = -1;
130 static int hf_nhrp_unknown_ext_value = -1;
132 static gint ett_nhrp = -1;
133 static gint ett_nhrp_hdr = -1;
134 static gint ett_nhrp_hdr_shtl = -1;
135 static gint ett_nhrp_hdr_sstl = -1;
136 static gint ett_nhrp_mand = -1;
137 static gint ett_nhrp_ext = -1;
138 static gint ett_nhrp_mand_flag = -1;
139 static gint ett_nhrp_cie = -1;
140 static gint ett_nhrp_cie_cli_addr_tl = -1;
141 static gint ett_nhrp_cie_cli_saddr_tl = -1;
142 static gint ett_nhrp_indication = -1;
143 static gint ett_nhrp_auth_ext = -1;
144 static gint ett_nhrp_vendor_ext = -1;
145 static gint ett_nhrp_devcap_ext = -1;
146 static gint ett_nhrp_devcap_ext_srccap = -1;
147 static gint ett_nhrp_devcap_ext_dstcap = -1;
149 /* NHRP Packet Types */
150 #define NHRP_RESOLUTION_REQ 1
151 #define NHRP_RESOLUTION_REPLY 2
152 #define NHRP_REGISTRATION_REQ 3
153 #define NHRP_REGISTRATION_REPLY 4
154 #define NHRP_PURGE_REQ 5
155 #define NHRP_PURGE_REPLY 6
156 #define NHRP_ERROR_INDICATION 7
157 #define NHRP_TRAFFIC_INDICATION 8
159 /* NHRP Extension Types */
160 #define NHRP_EXT_NULL 0 /* End of Extension */
161 #define NHRP_EXT_RESP_ADDR 3 /* Responder Address Extension */
162 #define NHRP_EXT_FWD_RECORD 4 /* NHRP Forward Transit NHS Record Extension */
163 #define NHRP_EXT_REV_RECORD 5 /* NHRP Reverse Transit NHS Record Extension */
164 #define NHRP_EXT_AUTH 7 /* NHRP Authentication Extension */
165 #define NHRP_EXT_VENDOR_PRIV 8 /* NHRP Vendor Private Extension */
166 #define NHRP_EXT_NAT_ADDRESS 9 /* Cisco NAT Address Extension */
167 #define NHRP_EXT_DEV_CAPABILITIES 9 /* RFC 2735: Device Capabilities Extension */
168 #define NHRP_EXT_MOBILE_AUTH 10 /* RFC 2520: NHRP Mobile NHC Authentication Extension */
170 /* NHRP Error Codes */
171 #define NHRP_ERR_UNRECOGNIZED_EXT 0x0001
172 #define NHRP_ERR_NHRP_LOOP_DETECT 0x0003
173 #define NHRP_ERR_PROT_ADDR_UNREACHABLE 0x0006
174 #define NHRP_ERR_PROT_ERROR 0x0007
175 #define NHRP_ERR_SDU_SIZE_EXCEEDED 0x0008
176 #define NHRP_ERR_INV_EXT 0x0009
177 #define NHRP_ERR_INV_RESOLUTION_REPLY 0x000a
178 #define NHRP_ERR_AUTH_FAILURE 0x000b
179 #define NHRP_ERR_HOP_COUNT_EXCEEDED 0x000f
180 #define NHRP_ERR_VPN_MISMATCH 0x0010 /* RFC 2735 */
181 #define NHRP_ERR_VPN_UNSUPPORTED 0x0011 /* RFC 2735 */
184 #define NHRP_CODE_SUCCESS 0x00
185 #define NHRP_CODE_ADMIN_PROHIBITED 0x04
186 #define NHRP_CODE_INSUFFICIENT_RESOURCES 0x05
187 #define NHRP_CODE_NO_BINDING_EXISTS 0x0c
188 #define NHRP_CODE_NON_UNIQUE_BINDING 0x0d
189 #define NHRP_CODE_ALREADY_REGISTERED 0x0e
191 /* NHRP Subnetwork layer address type/length */
192 #define NHRP_SHTL_TYPE_MASK 0x40
193 #define NHRP_SHTL_LEN_MASK 0x3F
194 #define NHRP_SHTL_TYPE(val) (((val) & (NHRP_SHTL_TYPE_MASK)) >> 6)
195 #define NHRP_SHTL_LEN(val) ((val) & (NHRP_SHTL_LEN_MASK))
197 #define NHRP_SHTL_TYPE_NSAP 0
198 #define NHRP_SHTL_TYPE_E164 1
200 static const value_string nhrp_shtl_type_vals[] = {
201 { NHRP_SHTL_TYPE_NSAP, "NSAP format" },
202 { NHRP_SHTL_TYPE_E164, "Native E.164 format" },
206 static const value_string nhrp_op_type_vals[] = {
207 { NHRP_RESOLUTION_REQ, "NHRP Resolution Request" },
208 { NHRP_RESOLUTION_REPLY, "NHRP Resolution Reply" },
209 { NHRP_REGISTRATION_REQ, "NHRP Registration Request" },
210 { NHRP_REGISTRATION_REPLY, "NHRP Registration Reply" },
211 { NHRP_PURGE_REQ, "NHRP Purge Request" },
212 { NHRP_PURGE_REPLY, "NHRP Purge Reply" },
213 { NHRP_ERROR_INDICATION, "NHRP Error Indication" },
214 { NHRP_TRAFFIC_INDICATION, "NHRP Traffic Indication" },
218 static const value_string ext_type_vals[] = {
219 { NHRP_EXT_NULL, "End of Extension" },
220 { NHRP_EXT_RESP_ADDR, "Responder Address Extension" },
221 { NHRP_EXT_FWD_RECORD, "Forward Transit NHS Record Extension" },
222 { NHRP_EXT_REV_RECORD, "Reverse Transit NHS Record Extension" },
223 { NHRP_EXT_AUTH, "NHRP Authentication Extension" },
224 { NHRP_EXT_VENDOR_PRIV, "NHRP Vendor Private Extension" },
225 { NHRP_EXT_NAT_ADDRESS, "Cisco NAT Address Extension" },
226 #if 0 /* Dup (which is handled in the code) */
227 { NHRP_EXT_DEV_CAPABILITIES,"Device Capabilities Extension" },
229 { NHRP_EXT_MOBILE_AUTH, "Mobile NHC Authentication Extension" },
233 static const value_string nhrp_error_code_vals[] = {
234 { NHRP_ERR_UNRECOGNIZED_EXT, "Unrecognized Extension" },
235 { NHRP_ERR_NHRP_LOOP_DETECT, "NHRP Loop Detected" },
236 { NHRP_ERR_PROT_ADDR_UNREACHABLE, "Protocol Address Unreachable" },
237 { NHRP_ERR_PROT_ERROR, "Protocol Error" },
238 { NHRP_ERR_SDU_SIZE_EXCEEDED, "NHRP SDU Size Exceeded" },
239 { NHRP_ERR_INV_EXT, "Invalid Extension" },
240 { NHRP_ERR_INV_RESOLUTION_REPLY, "Invalid NHRP Resolution Reply Received" },
241 { NHRP_ERR_AUTH_FAILURE, "Authentication Failure" },
242 { NHRP_ERR_HOP_COUNT_EXCEEDED, "Hop Count Exceeded" },
243 { NHRP_ERR_VPN_MISMATCH, "VPN Mismatch" },
244 { NHRP_ERR_VPN_UNSUPPORTED, "VPN Unsupported" },
248 static const value_string nhrp_cie_code_vals[] = {
249 { NHRP_CODE_SUCCESS, "Success" },
250 { NHRP_CODE_ADMIN_PROHIBITED, "Administratively Prohibited" },
251 { NHRP_CODE_INSUFFICIENT_RESOURCES, "Insufficient Resources" },
252 { NHRP_CODE_NO_BINDING_EXISTS, "No Interworking Layer Address to NBMA Address Binding Exists" },
253 { NHRP_CODE_NON_UNIQUE_BINDING, "Binding Exists But Is Not Unique" },
254 { NHRP_CODE_ALREADY_REGISTERED, "Unique Internetworking Layer Address Already Registered" },
258 static dissector_table_t osinl_subdissector_table;
259 static dissector_table_t osinl_excl_subdissector_table;
260 static dissector_table_t ethertype_subdissector_table;
262 static dissector_handle_t data_handle;
264 typedef struct _e_nhrp {
267 guint32 ar_pro_type_oui;
268 guint16 ar_pro_type_pid;
273 guint8 ar_op_version;
279 static guint16 nhrp_checksum(const guint8 *ptr, int len)
283 cksum_vec[0].ptr = ptr;
284 cksum_vec[0].len = len;
285 return in_cksum(&cksum_vec[0], 1);
288 void dissect_nhrp_hdr(tvbuff_t *tvb,
294 oui_info_t **pOuiInfo,
297 gint offset = *pOffset;
298 const gchar *pro_type_str;
299 guint total_len = tvb_reported_length(tvb);
300 guint16 ipcsum, rx_chksum;
302 proto_item *nhrp_tree_item;
303 proto_tree *nhrp_tree;
304 proto_item *shtl_tree_item;
305 proto_tree *shtl_tree;
306 proto_item *sstl_tree_item;
307 proto_tree *sstl_tree;
310 nhrp_tree_item = proto_tree_add_text(tree, tvb, offset, 20, "NHRP Fixed Header");
311 nhrp_tree = proto_item_add_subtree(nhrp_tree_item, ett_nhrp_hdr);
313 hdr->ar_pktsz = tvb_get_ntohs(tvb, 10);
314 if (total_len > hdr->ar_pktsz) {
315 total_len = hdr->ar_pktsz;
318 hdr->ar_afn = tvb_get_ntohs(tvb, offset);
319 proto_tree_add_item(nhrp_tree, hf_nhrp_hdr_afn, tvb, offset, 2, ENC_BIG_ENDIAN);
322 hdr->ar_pro_type = tvb_get_ntohs(tvb, offset);
323 if (hdr->ar_pro_type <= 0xFF) {
325 pro_type_str = val_to_str_const(hdr->ar_pro_type, nlpid_vals,
327 } else if (hdr->ar_pro_type <= 0x3FF) {
328 /* Reserved for future use by the IETF */
329 pro_type_str = "Reserved for future use by the IETF";
330 } else if (hdr->ar_pro_type <= 0x04FF) {
331 /* Allocated for use by the ATM Forum */
332 pro_type_str = "Allocated for use by the ATM Forum";
333 } else if (hdr->ar_pro_type <= 0x05FF) {
334 /* Experimental/Local use */
335 pro_type_str = "Experimental/Local use";
337 pro_type_str = val_to_str_const(hdr->ar_pro_type, etype_vals,
338 "Unknown Ethertype");
340 proto_tree_add_uint_format(nhrp_tree, hf_nhrp_hdr_pro_type, tvb, offset, 2,
341 hdr->ar_pro_type, "Protocol Type (short form): %s (0x%04x)",
342 pro_type_str, hdr->ar_pro_type);
345 if (hdr->ar_pro_type == NLPID_SNAP) {
347 * The long form protocol type is a SNAP OUI and PID.
349 hdr->ar_pro_type_oui = tvb_get_ntoh24(tvb, offset);
350 proto_tree_add_uint(nhrp_tree, hf_nhrp_hdr_pro_snap_oui,
351 tvb, offset, 3, hdr->ar_pro_type_oui);
354 hdr->ar_pro_type_pid = tvb_get_ntohs(tvb, offset);
355 *pOuiInfo = get_snap_oui_info(hdr->ar_pro_type_oui);
356 if (*pOuiInfo != NULL) {
357 proto_tree_add_uint(nhrp_tree,
358 *(*pOuiInfo)->field_info->p_id,
359 tvb, offset, 2, hdr->ar_pro_type_pid);
361 proto_tree_add_uint(nhrp_tree, hf_nhrp_hdr_pro_snap_pid,
362 tvb, offset, 2, hdr->ar_pro_type_pid);
366 * XXX - we should check that this is zero, as RFC 2332
367 * says it should be zero.
369 proto_tree_add_text(nhrp_tree, tvb, offset, 5,
370 "Protocol Type (long form): %s",
371 tvb_bytes_to_str(tvb, offset, 5));
375 proto_tree_add_item(nhrp_tree, hf_nhrp_hdr_hopcnt, tvb, offset, 1, ENC_BIG_ENDIAN);
378 proto_tree_add_item(nhrp_tree, hf_nhrp_hdr_pktsz, tvb, offset, 2, ENC_BIG_ENDIAN);
381 rx_chksum = tvb_get_ntohs(tvb, offset);
382 if (tvb_bytes_exist(tvb, 0, total_len)) {
383 ipcsum = nhrp_checksum(tvb_get_ptr(tvb, 0, total_len),
386 proto_tree_add_uint_format(nhrp_tree, hf_nhrp_hdr_chksum, tvb, offset, 2, rx_chksum,
387 "NHRP Packet checksum: 0x%04x [correct]", rx_chksum);
389 proto_tree_add_uint_format(nhrp_tree, hf_nhrp_hdr_chksum, tvb, offset, 2, rx_chksum,
390 "NHRP Packet checksum: 0x%04x [incorrect, should be 0x%04x]", rx_chksum,
391 in_cksum_shouldbe(rx_chksum, ipcsum));
394 proto_tree_add_uint_format(nhrp_tree, hf_nhrp_hdr_chksum, tvb, offset, 2, rx_chksum,
395 "NHRP Packet checksum: 0x%04x [not all data available]", rx_chksum);
399 hdr->ar_extoff = tvb_get_ntohs(tvb, offset);
400 ti = proto_tree_add_item(nhrp_tree, hf_nhrp_hdr_extoff, tvb, offset, 2, ENC_BIG_ENDIAN);
401 if (hdr->ar_extoff != 0 && hdr->ar_extoff < 20) {
402 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
403 "Extension offset is less than the fixed header length");
407 hdr->ar_op_version = tvb_get_guint8(tvb, offset);
408 proto_tree_add_uint_format(nhrp_tree, hf_nhrp_hdr_version, tvb, offset, 1,
409 hdr->ar_op_version, "Version : %u (%s)", hdr->ar_op_version,
410 (hdr->ar_op_version == 1) ? "NHRP - rfc2332" : "Unknown");
412 proto_tree_add_item(nhrp_tree, hf_nhrp_hdr_op_type, tvb, offset, 1, ENC_BIG_ENDIAN);
415 hdr->ar_shtl = tvb_get_guint8(tvb, offset);
416 shtl_tree_item = proto_tree_add_uint_format(nhrp_tree, hf_nhrp_hdr_shtl,
417 tvb, offset, 1, hdr->ar_shtl, "Source Address Type/Len: %s/%u",
418 val_to_str_const(NHRP_SHTL_TYPE(hdr->ar_shtl), nhrp_shtl_type_vals, "Unknown Type"),
419 NHRP_SHTL_LEN(hdr->ar_shtl));
420 shtl_tree = proto_item_add_subtree(shtl_tree_item, ett_nhrp_hdr_shtl);
421 proto_tree_add_item(shtl_tree, hf_nhrp_hdr_shtl_type, tvb, offset, 1, ENC_BIG_ENDIAN);
422 proto_tree_add_item(shtl_tree, hf_nhrp_hdr_shtl_len, tvb, offset, 1, ENC_BIG_ENDIAN);
425 hdr->ar_sstl = tvb_get_guint8(tvb, offset);
426 sstl_tree_item = proto_tree_add_uint_format(nhrp_tree, hf_nhrp_hdr_sstl,
427 tvb, offset, 1, hdr->ar_sstl, "Source SubAddress Type/Len: %s/%u",
428 val_to_str_const(NHRP_SHTL_TYPE(hdr->ar_sstl), nhrp_shtl_type_vals, "Unknown Type"),
429 NHRP_SHTL_LEN(hdr->ar_sstl));
430 sstl_tree = proto_item_add_subtree(sstl_tree_item, ett_nhrp_hdr_sstl);
431 proto_tree_add_item(sstl_tree, hf_nhrp_hdr_sstl_type, tvb, offset, 1, ENC_BIG_ENDIAN);
432 proto_tree_add_item(sstl_tree, hf_nhrp_hdr_sstl_len, tvb, offset, 1, ENC_BIG_ENDIAN);
436 if (hdr->ar_extoff != 0) {
437 if (hdr->ar_extoff >= 20) {
438 *pMandLen = hdr->ar_extoff - 20;
439 *pExtLen = total_len - hdr->ar_extoff;
448 *pMandLen = total_len - 20;
450 /* "Can't happen" - we would have thrown an exception */
457 void dissect_cie_list(tvbuff_t *tvb,
466 proto_item *cli_addr_tree_item;
467 proto_tree *cli_addr_tree;
468 proto_item *cli_saddr_tree_item;
469 proto_tree *cli_saddr_tree;
472 while ((offset + 12) <= cieEnd) {
473 guint cli_addr_len = tvb_get_guint8(tvb, offset + 8);
474 guint cli_saddr_len = tvb_get_guint8(tvb, offset + 9);
475 guint cli_prot_len = tvb_get_guint8(tvb, offset + 10);
476 guint cie_len = 12 + cli_addr_len + cli_saddr_len + cli_prot_len;
477 proto_item *cie_tree_item = proto_tree_add_text(tree, tvb, offset, cie_len, "Client Information Entry");
478 proto_tree *cie_tree = proto_item_add_subtree(cie_tree_item, ett_nhrp_cie);
481 proto_tree_add_item(cie_tree, hf_nhrp_code, tvb, offset, 1, ENC_BIG_ENDIAN);
484 guint8 code = tvb_get_guint8(tvb, offset);
486 col_append_fstr(pinfo->cinfo, COL_INFO, ", Code=%s",
487 val_to_str(code, nhrp_cie_code_vals, "Unknown (%u)"));
489 proto_tree_add_text(cie_tree, tvb, offset, 1, "Code: %s",
490 val_to_str(code, nhrp_cie_code_vals, "Unknown (%u)"));
494 proto_tree_add_item(cie_tree, hf_nhrp_prefix_len, tvb, offset, 1, ENC_BIG_ENDIAN);
497 proto_tree_add_item(cie_tree, hf_nhrp_unused, tvb, offset, 2, ENC_BIG_ENDIAN);
500 proto_tree_add_item(cie_tree, hf_nhrp_mtu, tvb, offset, 2, ENC_BIG_ENDIAN);
503 proto_tree_add_item(cie_tree, hf_nhrp_holding_time, tvb, offset, 2, ENC_BIG_ENDIAN);
506 val = tvb_get_guint8(tvb, offset);
507 cli_addr_tree_item = proto_tree_add_uint_format(cie_tree,
508 hf_nhrp_cli_addr_tl, tvb, offset, 1, val,
509 "Client Address Type/Len: %s/%u",
510 val_to_str_const(NHRP_SHTL_TYPE(val), nhrp_shtl_type_vals, "Unknown Type"),
512 cli_addr_tree = proto_item_add_subtree(cli_addr_tree_item, ett_nhrp_cie_cli_addr_tl);
513 proto_tree_add_item(cli_addr_tree, hf_nhrp_cli_addr_tl_type, tvb, offset, 1, ENC_BIG_ENDIAN);
514 proto_tree_add_item(cli_addr_tree, hf_nhrp_cli_addr_tl_len, tvb, offset, 1, ENC_BIG_ENDIAN);
517 val = tvb_get_guint8(tvb, offset);
518 cli_saddr_tree_item = proto_tree_add_uint_format(cie_tree,
519 hf_nhrp_cli_saddr_tl, tvb, offset, 1, val,
520 "Client Sub Address Type/Len: %s/%u",
521 val_to_str_const(NHRP_SHTL_TYPE(val), nhrp_shtl_type_vals, "Unknown Type"),
523 cli_saddr_tree = proto_item_add_subtree(cli_saddr_tree_item, ett_nhrp_cie_cli_saddr_tl);
524 proto_tree_add_item(cli_saddr_tree, hf_nhrp_cli_saddr_tl_type, tvb, offset, 1, ENC_BIG_ENDIAN);
525 proto_tree_add_item(cli_saddr_tree, hf_nhrp_cli_saddr_tl_len, tvb, offset, 1, ENC_BIG_ENDIAN);
528 proto_tree_add_item(cie_tree, hf_nhrp_cli_prot_len, tvb, offset, 1, ENC_BIG_ENDIAN);
531 proto_tree_add_item(cie_tree, hf_nhrp_pref, tvb, offset, 1, ENC_BIG_ENDIAN);
535 switch (hdr->ar_afn) {
538 if (cli_addr_len == 4)
539 proto_tree_add_item(cie_tree, hf_nhrp_client_nbma_addr, tvb, offset, 4, ENC_BIG_ENDIAN);
541 proto_tree_add_text(cie_tree, tvb, offset, cli_addr_len,
542 "Client NBMA Address: %s",
543 tvb_bytes_to_str(tvb, offset, cli_addr_len));
548 proto_tree_add_text(cie_tree, tvb, offset, cli_addr_len,
549 "Client NBMA Address: %s",
550 tvb_bytes_to_str(tvb, offset, cli_addr_len));
553 offset += cli_addr_len;
557 proto_tree_add_text(cie_tree, tvb, offset, cli_saddr_len,
558 "Client NBMA Sub Address: %s",
559 tvb_bytes_to_str(tvb, offset, cli_saddr_len));
563 if (cli_prot_len == 4)
564 proto_tree_add_item(cie_tree, hf_nhrp_client_prot_addr, tvb, offset, 4, ENC_BIG_ENDIAN);
566 proto_tree_add_text(cie_tree, tvb, offset, cli_prot_len,
567 "Client Protocol Address: %s",
568 tvb_bytes_to_str(tvb, offset, cli_prot_len));
570 offset += cli_prot_len;
575 void dissect_nhrp_mand(tvbuff_t *tvb,
580 oui_info_t *oui_info,
585 gint offset = *pOffset;
586 gint mandEnd = offset + mandLen;
590 gboolean isReq = FALSE;
591 gboolean isErr = FALSE;
592 gboolean isInd = FALSE;
594 proto_item *nhrp_tree_item;
595 proto_tree *nhrp_tree;
597 tvb_ensure_bytes_exist(tvb, offset, mandLen);
599 switch (hdr->ar_op_type)
601 case NHRP_RESOLUTION_REPLY:
602 case NHRP_REGISTRATION_REPLY:
603 case NHRP_PURGE_REPLY:
605 case NHRP_RESOLUTION_REQ:
606 case NHRP_REGISTRATION_REQ:
610 case NHRP_ERROR_INDICATION: /* This needs special treatment */
614 case NHRP_TRAFFIC_INDICATION:
618 nhrp_tree_item = proto_tree_add_text(tree, tvb, offset, mandLen, "NHRP Mandatory Part");
619 nhrp_tree = proto_item_add_subtree(nhrp_tree_item, ett_nhrp_mand);
621 *srcLen = tvb_get_guint8(tvb, offset);
622 proto_tree_add_item(nhrp_tree, hf_nhrp_src_proto_len, tvb, offset, 1, ENC_BIG_ENDIAN);
625 dstLen = tvb_get_guint8(tvb, offset);
626 proto_tree_add_item(nhrp_tree, hf_nhrp_dst_proto_len, tvb, offset, 1, ENC_BIG_ENDIAN);
630 proto_item *flag_item;
631 proto_tree *flag_tree;
632 flags = tvb_get_ntohs(tvb, offset);
633 flag_item = proto_tree_add_uint(nhrp_tree, hf_nhrp_flags, tvb, offset, 2, flags);
634 flag_tree = proto_item_add_subtree(flag_item, ett_nhrp_mand_flag);
636 switch (hdr->ar_op_type)
638 case NHRP_RESOLUTION_REQ:
639 case NHRP_RESOLUTION_REPLY:
640 proto_tree_add_boolean(flag_tree, hf_nhrp_flag_Q, tvb, offset, 2, flags);
641 proto_tree_add_boolean(flag_tree, hf_nhrp_flag_A, tvb, offset, 2, flags);
642 proto_tree_add_boolean(flag_tree, hf_nhrp_flag_D, tvb, offset, 2, flags);
643 proto_tree_add_boolean(flag_tree, hf_nhrp_flag_U1, tvb, offset, 2, flags);
644 proto_tree_add_boolean(flag_tree, hf_nhrp_flag_S, tvb, offset, 2, flags);
646 case NHRP_REGISTRATION_REQ:
647 case NHRP_REGISTRATION_REPLY:
648 proto_tree_add_boolean(flag_tree, hf_nhrp_flag_U2, tvb, offset, 2, flags);
652 case NHRP_PURGE_REPLY:
653 proto_tree_add_boolean(flag_tree, hf_nhrp_flag_N, tvb, offset, 2, flags);
656 proto_tree_add_boolean(flag_tree, hf_nhrp_flag_NAT, tvb, offset, 2, flags);
660 col_append_fstr(pinfo->cinfo, COL_INFO, ", ID=%u", tvb_get_ntohl(tvb, offset));
661 proto_tree_add_item(nhrp_tree, hf_nhrp_request_id, tvb, offset, 4, ENC_BIG_ENDIAN);
667 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
668 val_to_str(tvb_get_ntohs(tvb, offset), nhrp_error_code_vals, "Unknown Error (%u)"));
669 proto_tree_add_item(nhrp_tree, hf_nhrp_error_code, tvb, offset, 2, ENC_BIG_ENDIAN);
672 proto_tree_add_item(nhrp_tree, hf_nhrp_error_offset, tvb, offset, 2, ENC_BIG_ENDIAN);
679 shl = NHRP_SHTL_LEN(hdr->ar_shtl);
681 switch (hdr->ar_afn) {
685 proto_tree_add_item(nhrp_tree, hf_nhrp_src_nbma_addr, tvb, offset, 4, ENC_BIG_ENDIAN);
687 proto_tree_add_text(nhrp_tree, tvb, offset, shl,
688 "Source NBMA Address: %s",
689 tvb_bytes_to_str(tvb, offset, shl));
694 proto_tree_add_text(nhrp_tree, tvb, offset, shl,
695 "Source NBMA Address: %s",
696 tvb_bytes_to_str(tvb, offset, shl));
702 ssl = NHRP_SHTL_LEN(hdr->ar_sstl);
704 proto_tree_add_text(nhrp_tree, tvb, offset, ssl,
705 "Source NBMA Sub Address: %s",
706 tvb_bytes_to_str(tvb, offset, ssl));
711 proto_tree_add_item(nhrp_tree, hf_nhrp_src_prot_addr, tvb, offset, 4, ENC_BIG_ENDIAN);
715 proto_tree_add_text(nhrp_tree, tvb, offset, *srcLen,
716 "Source Protocol Address: %s",
717 tvb_bytes_to_str(tvb, offset, *srcLen));
722 proto_tree_add_item(nhrp_tree, hf_nhrp_dst_prot_addr, tvb, offset, 4, ENC_BIG_ENDIAN);
726 proto_tree_add_text(nhrp_tree, tvb, offset, dstLen,
727 "Destination Protocol Address: %s",
728 tvb_bytes_to_str(tvb, offset, dstLen));
733 gboolean save_in_error_pkt;
734 gint pkt_len = mandEnd - offset;
735 proto_item *ind_tree_item = proto_tree_add_text(tree, tvb, offset, pkt_len, "Packet Causing Indication");
736 proto_tree *ind_tree = proto_item_add_subtree(ind_tree_item, ett_nhrp_indication);
740 save_in_error_pkt = pinfo->flags.in_error_pkt;
741 pinfo->flags.in_error_pkt = TRUE;
742 sub_tvb = tvb_new_subset_remaining(tvb, offset);
744 _dissect_nhrp(sub_tvb, pinfo, ind_tree, TRUE, FALSE);
747 if (hdr->ar_pro_type <= 0xFF) {
749 if (hdr->ar_pro_type == NLPID_SNAP) {
751 * Dissect based on the SNAP OUI
754 if (hdr->ar_pro_type_oui == 0x000000) {
756 * "Should not happen", as
757 * the protocol type should
758 * be the Ethertype, but....
760 dissected = dissector_try_uint(
761 ethertype_subdissector_table,
762 hdr->ar_pro_type_pid,
763 sub_tvb, pinfo, ind_tree);
766 * If we have a dissector
767 * table, use it, otherwise
768 * just dissect as data.
770 if (oui_info != NULL) {
771 dissected = dissector_try_uint(
773 hdr->ar_pro_type_pid,
781 * Dissect based on the NLPID.
783 dissected = dissector_try_uint(
784 osinl_subdissector_table,
785 hdr->ar_pro_type, sub_tvb, pinfo,
788 osinl_excl_subdissector_table,
789 hdr->ar_pro_type, sub_tvb, pinfo,
792 } else if (hdr->ar_pro_type <= 0x3FF) {
793 /* Reserved for future use by the IETF */
795 } else if (hdr->ar_pro_type <= 0x04FF) {
796 /* Allocated for use by the ATM Forum */
798 } else if (hdr->ar_pro_type <= 0x05FF) {
799 /* Experimental/Local use */
802 dissected = dissector_try_uint(
803 ethertype_subdissector_table,
804 hdr->ar_pro_type, sub_tvb, pinfo, ind_tree);
807 call_dissector(data_handle, sub_tvb, pinfo,
811 pinfo->flags.in_error_pkt = save_in_error_pkt;
815 /* According to RFC 2332, section 5.2.7, there shouldn't be any extensions
816 * in the Error Indication packet. */
817 if (isErr && tvb_reported_length_remaining(tvb, offset)) {
818 expert_add_info_format(pinfo, tree, PI_MALFORMED, PI_ERROR,
819 "Extensions not allowed per RFC2332 section 5.2.7");
822 dissect_cie_list(tvb, pinfo, nhrp_tree, offset, mandEnd, hdr, isReq, codeinfo);
827 void dissect_nhrp_ext(tvbuff_t *tvb,
836 gint offset = *pOffset;
837 gint extEnd = offset + extLen;
841 tvb_ensure_bytes_exist(tvb, offset, extLen);
843 while ((offset + 4) <= extEnd)
845 proto_item *nhrp_tree_item;
846 proto_tree *nhrp_tree;
847 gint extTypeC = tvb_get_ntohs(tvb, offset);
848 gint extType = extTypeC & 0x3FFF;
849 guint len = tvb_get_ntohs(tvb, offset+2);
851 if ((extType == NHRP_EXT_NAT_ADDRESS) && (len == 8)) {
852 /* Assume it's not really a Cisco NAT extension, but a device
853 * capabilities extension instead (see RFC 2735). */
854 nhrp_tree_item = proto_tree_add_text(tree, tvb, offset,
855 len + 4, "Device Capabilities Extension");
858 nhrp_tree_item = proto_tree_add_text(tree, tvb, offset,
860 val_to_str(extType, ext_type_vals, "Unknown (%u)"));
862 nhrp_tree = proto_item_add_subtree(nhrp_tree_item, ett_nhrp_ext);
863 proto_tree_add_boolean(nhrp_tree, hf_nhrp_ext_C, tvb, offset, 2, extTypeC);
864 proto_tree_add_item(nhrp_tree, hf_nhrp_ext_type, tvb, offset, 2, ENC_BIG_ENDIAN);
867 proto_tree_add_item(nhrp_tree, hf_nhrp_ext_len, tvb, offset, 2, ENC_BIG_ENDIAN);
870 if (len && (extType != NHRP_EXT_NULL)) {
871 tvb_ensure_bytes_exist(tvb, offset, len);
872 if ((extType == NHRP_EXT_NAT_ADDRESS) && (len == 8)) {
873 /* Assume it's not really a Cisco NAT extension, but a device
874 * capabilities extension instead (see RFC 2735). */
875 proto_item *devcap_item;
876 proto_tree *devcap_tree;
877 proto_item *cap_item;
878 proto_tree *cap_tree;
880 devcap_item = proto_tree_add_text(nhrp_tree, tvb, offset, len,
881 "Extension Data: Src is %sVPN-aware; Dst is %sVPN-aware",
882 tvb_get_ntohl(tvb, offset) & 1 ? "" : "non-",
883 tvb_get_ntohl(tvb, offset + 4) & 1 ? "" : "non-");
884 devcap_tree = proto_item_add_subtree(devcap_item, ett_nhrp_devcap_ext);
885 cap_item = proto_tree_add_item(devcap_tree, hf_nhrp_devcap_ext_srccap, tvb, offset, 4, ENC_BIG_ENDIAN);
886 cap_tree = proto_item_add_subtree(cap_item, ett_nhrp_devcap_ext_srccap);
887 proto_tree_add_item(cap_tree, hf_nhrp_devcap_ext_srccap_V, tvb, offset, 4, ENC_BIG_ENDIAN);
889 cap_item = proto_tree_add_item(devcap_tree, hf_nhrp_devcap_ext_dstcap, tvb, offset + 4, 4, ENC_BIG_ENDIAN);
890 cap_tree = proto_item_add_subtree(cap_item, ett_nhrp_devcap_ext_dstcap);
891 proto_tree_add_item(cap_tree, hf_nhrp_devcap_ext_dstcap_V, tvb, offset + 4, 4, ENC_BIG_ENDIAN);
896 case NHRP_EXT_RESP_ADDR:
897 case NHRP_EXT_FWD_RECORD:
898 case NHRP_EXT_REV_RECORD:
899 case NHRP_EXT_NAT_ADDRESS:
900 dissect_cie_list(tvb, pinfo, nhrp_tree,
901 offset, offset + len, hdr, 0, FALSE);
905 case NHRP_EXT_MOBILE_AUTH:
906 if (len < (4 + srcLen)) {
907 ti = proto_tree_add_text(nhrp_tree, tvb, offset, len,
908 "Malformed Extension: %s",
909 tvb_bytes_to_str(tvb, offset, len));
910 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
911 "Incomplete Authentication Extension");
914 proto_item *auth_item;
915 proto_tree *auth_tree;
917 auth_item = proto_tree_add_text(nhrp_tree, tvb, offset, len,
918 "Extension Data: SPI=%u: Data=%s", tvb_get_ntohs(tvb, offset + 2),
919 tvb_bytes_to_str(tvb, offset + 4, len - 4));
920 auth_tree = proto_item_add_subtree(auth_item, ett_nhrp_auth_ext);
921 proto_tree_add_item(auth_tree, hf_nhrp_auth_ext_reserved, tvb, offset, 2, ENC_BIG_ENDIAN);
922 proto_tree_add_item(auth_tree, hf_nhrp_auth_ext_spi, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
924 proto_tree_add_item(auth_tree, hf_nhrp_auth_ext_src_addr, tvb, offset + 4, 4, ENC_BIG_ENDIAN);
926 proto_tree_add_text(auth_tree, tvb, offset + 4, srcLen,
927 "Source Address: %s",
928 tvb_bytes_to_str(tvb, offset + 4, srcLen));
930 if (len > (4 + srcLen)) {
931 proto_tree_add_text(auth_tree, tvb, offset + 4 + srcLen, len - (4 + srcLen),
932 "Data: %s", tvb_bytes_to_str(tvb, offset + 4 + srcLen, len - (4 + srcLen)));
937 case NHRP_EXT_VENDOR_PRIV:
939 ti = proto_tree_add_text(nhrp_tree, tvb, offset, len,
940 "Malformed Extension: %s",
941 tvb_bytes_to_str(tvb, offset, len));
942 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
943 "Incomplete Vendor-Private Extension");
946 proto_item *vendor_item;
947 proto_tree *vendor_tree;
950 tvb_memcpy(tvb, manuf, offset, 3);
951 vendor_item = proto_tree_add_text(nhrp_tree, tvb, offset, len,
952 "Extension Data: Vendor ID=%s, Data=%s", get_manuf_name(manuf),
953 tvb_bytes_to_str(tvb, offset + 3, len - 3));
954 vendor_tree = proto_item_add_subtree(vendor_item, ett_nhrp_vendor_ext);
955 proto_tree_add_bytes_format(vendor_tree, hf_nhrp_vendor_ext_id, tvb,
956 offset, 3, manuf, "Vendor ID: %s", get_manuf_name(manuf));
958 proto_tree_add_text(vendor_tree, tvb, offset + 3, len - 3,
959 "Data: %s", tvb_bytes_to_str(tvb, offset + 3, len - 3));
965 proto_tree_add_item(nhrp_tree, hf_nhrp_unknown_ext_value, tvb,
966 offset, len, ENC_NA);
974 len = tvb_reported_length_remaining(tvb, offset);
975 if ((extType == NHRP_EXT_NULL) && len) {
976 ti = proto_tree_add_text(tree, tvb, offset, len,
977 "Unknown Data (%d bytes)", len);
978 expert_add_info_format(pinfo, ti, PI_MALFORMED, PI_ERROR,
979 "Superfluous data follows End Extension");
988 void dissect_nhrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
990 _dissect_nhrp(tvb, pinfo, tree, FALSE, TRUE);
993 static void _dissect_nhrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
994 gboolean nested, gboolean codeinfo)
1001 proto_tree *nhrp_tree;
1002 oui_info_t *oui_info = NULL;
1006 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NHRP");
1007 col_clear(pinfo->cinfo, COL_INFO);
1010 memset(&hdr, 0, sizeof(e_nhrp_hdr));
1011 hdr.ar_op_type = tvb_get_guint8(tvb, 17);
1014 col_add_str(pinfo->cinfo, COL_INFO,
1015 val_to_str(hdr.ar_op_type, nhrp_op_type_vals,
1016 "0x%02X - unknown"));
1019 ti = proto_tree_add_protocol_format(tree, proto_nhrp, tvb, 0, -1,
1020 "Next Hop Resolution Protocol (%s)",
1021 val_to_str(hdr.ar_op_type, nhrp_op_type_vals, "0x%02X - unknown"));
1022 nhrp_tree = proto_item_add_subtree(ti, ett_nhrp);
1024 dissect_nhrp_hdr(tvb, pinfo, nhrp_tree, &offset, &mandLen, &extLen,
1027 dissect_nhrp_mand(tvb, pinfo, nhrp_tree, &offset, mandLen,
1028 oui_info, &hdr, &srcLen, codeinfo);
1032 dissect_nhrp_ext(tvb, pinfo, nhrp_tree, &offset, extLen, &hdr, srcLen, nested);
1037 proto_register_nhrp(void)
1039 static hf_register_info hf[] = {
1042 { "Address Family Number", "nhrp.hdr.afn",
1043 FT_UINT16, BASE_HEX_DEC, VALS(afn_vals), 0x0,
1046 { &hf_nhrp_hdr_pro_type,
1047 { "Protocol Type (short form)", "nhrp.hdr.pro.type",
1048 FT_UINT16, BASE_HEX_DEC, NULL, 0x0,
1051 { &hf_nhrp_hdr_pro_snap_oui,
1052 { "Protocol Type (long form) - OUI", "nhrp.hdr.pro.snap.oui",
1053 FT_UINT24, BASE_HEX, VALS(oui_vals), 0x0,
1056 { &hf_nhrp_hdr_pro_snap_pid,
1057 { "Protocol Type (long form) - PID", "nhrp.hdr.pro.snap.pid",
1058 FT_UINT16, BASE_HEX, NULL, 0x0,
1061 { &hf_nhrp_hdr_hopcnt,
1062 { "Hop Count", "nhrp.hdr.hopcnt",
1063 FT_UINT8, BASE_DEC, NULL, 0x0,
1066 { &hf_nhrp_hdr_pktsz,
1067 { "Packet Length", "nhrp.hdr.pktsz",
1068 FT_UINT16, BASE_DEC, NULL, 0x0,
1071 { &hf_nhrp_hdr_chksum,
1072 { "Packet Checksum", "nhrp.hdr.chksum",
1073 FT_UINT16, BASE_HEX, NULL, 0x0,
1076 { &hf_nhrp_hdr_extoff,
1077 { "Extension Offset", "nhrp.hdr.extoff",
1078 FT_UINT16, BASE_DEC, NULL, 0x0,
1081 { &hf_nhrp_hdr_version,
1082 { "Version", "nhrp.hdr.version",
1083 FT_UINT8, BASE_DEC, NULL, 0x0,
1086 { &hf_nhrp_hdr_op_type,
1087 { "NHRP Packet Type", "nhrp.hdr.op.type",
1088 FT_UINT8, BASE_DEC, VALS(nhrp_op_type_vals), 0x0,
1091 { &hf_nhrp_hdr_shtl,
1092 { "Source Address Type/Len", "nhrp.hdr.shtl",
1093 FT_UINT8, BASE_DEC, NULL, 0x0,
1096 { &hf_nhrp_hdr_shtl_type,
1097 { "Type", "nhrp.hdr.shtl.type",
1098 FT_UINT8, BASE_DEC, VALS(nhrp_shtl_type_vals), NHRP_SHTL_TYPE_MASK,
1101 { &hf_nhrp_hdr_shtl_len,
1102 { "Length", "nhrp.hdr.shtl.len",
1103 FT_UINT8, BASE_DEC, NULL, NHRP_SHTL_LEN_MASK,
1106 { &hf_nhrp_hdr_sstl,
1107 { "Source SubAddress Type/Len", "nhrp.hdr.sstl",
1108 FT_UINT8, BASE_DEC, NULL, 0x0,
1111 { &hf_nhrp_hdr_sstl_type,
1112 { "Type", "nhrp.hdr.sstl.type",
1113 FT_UINT8, BASE_DEC, VALS(nhrp_shtl_type_vals), NHRP_SHTL_TYPE_MASK,
1116 { &hf_nhrp_hdr_sstl_len,
1117 { "Length", "nhrp.hdr.sstl.len",
1118 FT_UINT8, BASE_DEC, NULL, NHRP_SHTL_LEN_MASK,
1122 { &hf_nhrp_src_proto_len,
1123 { "Source Protocol Len", "nhrp.src.prot.len",
1124 FT_UINT16, BASE_DEC, NULL, 0x0,
1127 { &hf_nhrp_dst_proto_len,
1128 { "Destination Protocol Len", "nhrp.dst.prot.len",
1129 FT_UINT16, BASE_DEC, NULL, 0x0,
1133 { "Flags", "nhrp.flags",
1134 FT_UINT16, BASE_HEX, NULL, 0x0,
1138 { "Is Router", "nhrp.flag.q",
1139 FT_BOOLEAN, 16, NULL, 0x8000,
1143 { "Expected Purge Reply", "nhrp.flag.n",
1144 FT_BOOLEAN, 16, NULL, 0x8000,
1148 { "Authoritative", "nhrp.flag.a",
1149 FT_BOOLEAN, 16, NULL, 0x4000,
1153 { "Stable Association", "nhrp.flag.d",
1154 FT_BOOLEAN, 16, NULL, 0x2000,
1158 { "Uniqueness Bit", "nhrp.flag.u1",
1159 FT_BOOLEAN, 16, NULL, 0x1000,
1163 { "Uniqueness Bit", "nhrp.flag.u1",
1164 FT_BOOLEAN, 16, NULL, 0x8000,
1168 { "Stable Binding", "nhrp.flag.s",
1169 FT_BOOLEAN, 16, NULL, 0x0800,
1172 { &hf_nhrp_flag_NAT,
1173 { "Cisco NAT Supported", "nhrp.flag.nat",
1174 FT_BOOLEAN, 16, NULL, 0x0002,
1177 { &hf_nhrp_request_id,
1178 { "Request ID", "nhrp.reqid",
1179 FT_UINT32, BASE_HEX_DEC, NULL, 0x0,
1182 { &hf_nhrp_src_nbma_addr,
1183 { "Source NBMA Address", "nhrp.src.nbma.addr",
1184 FT_IPv4, BASE_NONE, NULL, 0x0,
1188 { &hf_nhrp_src_nbma_saddr,
1189 { "Source NBMA Sub Address", "nhrp.src.nbma.saddr",
1190 FT_UINT_BYTES, BASE_NONE, NULL, 0x0,
1194 { &hf_nhrp_src_prot_addr,
1195 { "Source Protocol Address", "nhrp.src.prot.addr",
1196 FT_IPv4, BASE_NONE, NULL, 0x0,
1199 { &hf_nhrp_dst_prot_addr,
1200 { "Destination Protocol Address", "nhrp.dst.prot.addr",
1201 FT_IPv4, BASE_NONE, NULL, 0x0,
1206 { "Code", "nhrp.code",
1207 FT_UINT8, BASE_DEC, NULL, 0x0,
1210 { &hf_nhrp_prefix_len,
1211 { "Prefix Length", "nhrp.prefix",
1212 FT_UINT8, BASE_DEC, NULL, 0x0,
1216 { "Unused", "nhrp.unused",
1217 FT_UINT16, BASE_DEC, NULL, 0x0,
1221 { "Max Transmission Unit", "nhrp.mtu",
1222 FT_UINT16, BASE_DEC, NULL, 0x0,
1225 { &hf_nhrp_holding_time,
1226 { "Holding Time (s)", "nhrp.htime",
1227 FT_UINT16, BASE_DEC, NULL, 0x0,
1230 { &hf_nhrp_cli_addr_tl,
1231 { "Client Address Type/Len", "nhrp.cli.addr_tl",
1232 FT_UINT8, BASE_DEC, NULL, 0x0,
1235 { &hf_nhrp_cli_addr_tl_type,
1236 { "Type", "nhrp.cli.addr_tl.type",
1237 FT_UINT8, BASE_DEC, VALS(nhrp_shtl_type_vals), NHRP_SHTL_TYPE_MASK,
1240 { &hf_nhrp_cli_addr_tl_len,
1241 { "Length", "nhrp.cli.addr_tl.len",
1242 FT_UINT8, BASE_DEC, NULL, NHRP_SHTL_LEN_MASK,
1245 { &hf_nhrp_cli_saddr_tl,
1246 { "Client Sub Address Type/Len", "nhrp.cli.saddr_tl",
1247 FT_UINT8, BASE_DEC, NULL, 0x0,
1250 { &hf_nhrp_cli_saddr_tl_type,
1251 { "Type", "nhrp.cli.saddr_tl.type",
1252 FT_UINT8, BASE_DEC, VALS(nhrp_shtl_type_vals), NHRP_SHTL_TYPE_MASK,
1255 { &hf_nhrp_cli_saddr_tl_len,
1256 { "Length", "nhrp.cli.saddr_tl.len",
1257 FT_UINT8, BASE_DEC, NULL, NHRP_SHTL_LEN_MASK,
1260 { &hf_nhrp_cli_prot_len,
1261 { "Client Protocol Length", "nhrp.prot.len",
1262 FT_UINT8, BASE_DEC, NULL, 0x0,
1266 { "CIE Preference Value", "nhrp.pref",
1267 FT_UINT8, BASE_DEC, NULL, 0x0,
1270 { &hf_nhrp_client_nbma_addr,
1271 { "Client NBMA Address", "nhrp.client.nbma.addr",
1272 FT_IPv4, BASE_NONE, NULL, 0x0,
1276 { &hf_nhrp_client_nbma_saddr,
1277 { "Client NBMA Sub Address", "nhrp.client.nbma.saddr",
1278 FT_UINT_BYTES, BASE_NONE, NULL, 0x0,
1282 { &hf_nhrp_client_prot_addr,
1283 { "Client Protocol Address", "nhrp.client.prot.addr",
1284 FT_IPv4, BASE_NONE, NULL, 0x0,
1289 { "Compulsory Flag", "nhrp.ext.c",
1290 FT_BOOLEAN, 16, NULL, 0x8000,
1293 { &hf_nhrp_ext_type,
1294 { "Extension Type", "nhrp.ext.type",
1295 FT_UINT16, BASE_HEX, NULL, 0x3FFF,
1299 { "Extension length", "nhrp.ext.len",
1300 FT_UINT16, BASE_DEC, NULL, 0x0,
1304 { &hf_nhrp_ext_value,
1305 { "Extension Value", "nhrp.ext.val",
1306 FT_UINT_BYTES, BASE_NONE, NULL, 0x0,
1311 { &hf_nhrp_error_code,
1312 { "Error Code", "nhrp.err.code",
1313 FT_UINT16, BASE_DEC, VALS(nhrp_error_code_vals), 0x0,
1316 { &hf_nhrp_error_offset,
1317 { "Error Offset", "nhrp.err.offset",
1318 FT_UINT16, BASE_DEC, NULL, 0x0,
1322 { &hf_nhrp_error_packet,
1323 { "Errored Packet", "nhrp.err.pkt",
1324 FT_UINT_BYTES, BASE_NONE, NULL, 0x0,
1328 { &hf_nhrp_auth_ext_reserved,
1329 { "Reserved", "nhrp.auth_ext.reserved",
1330 FT_UINT16, BASE_DEC, NULL, 0x0,
1333 { &hf_nhrp_auth_ext_spi,
1334 { "SPI", "nhrp.auth_ext.spi",
1335 FT_UINT16, BASE_DEC, NULL, 0x0,
1336 "Security Parameter Index", HFILL }
1338 { &hf_nhrp_auth_ext_src_addr,
1339 { "Source Address", "nhrp.auth_ext.src_addr",
1340 FT_IPv4, BASE_NONE, NULL, 0x0,
1343 { &hf_nhrp_vendor_ext_id ,
1344 { "Vendor ID", "nhrp.vendor_ext.id",
1345 FT_BYTES, BASE_NONE, NULL, 0x0,
1348 { &hf_nhrp_devcap_ext_srccap,
1349 { "Source Capabilities", "nhrp.devcap_ext.srccap",
1350 FT_UINT32, BASE_HEX, NULL, 0x0,
1353 { &hf_nhrp_devcap_ext_srccap_V,
1354 { "VPN-aware", "nhrp.devcap_ext.srccap.V",
1355 FT_BOOLEAN, 32, NULL, 0x00000001,
1358 { &hf_nhrp_devcap_ext_dstcap,
1359 { "Destination Capabilities", "nhrp.devcap_ext.dstcap",
1360 FT_UINT32, BASE_HEX, NULL, 0x0,
1363 { &hf_nhrp_devcap_ext_dstcap_V,
1364 { "VPN-aware", "nhrp.devcap_ext.dstcap.V",
1365 FT_BOOLEAN, 32, NULL, 0x00000001,
1368 { &hf_nhrp_unknown_ext_value,
1369 { "Extension Value", "nhrp.unknown_ext.value",
1370 FT_BYTES, BASE_NONE, NULL, 0x0,
1375 static gint *ett[] = {
1382 &ett_nhrp_mand_flag,
1384 &ett_nhrp_cie_cli_addr_tl,
1385 &ett_nhrp_cie_cli_saddr_tl,
1386 &ett_nhrp_indication,
1388 &ett_nhrp_vendor_ext,
1389 &ett_nhrp_devcap_ext,
1390 &ett_nhrp_devcap_ext_srccap,
1391 &ett_nhrp_devcap_ext_dstcap
1394 proto_nhrp = proto_register_protocol(
1395 "NBMA Next Hop Resolution Protocol",
1398 proto_register_field_array(proto_nhrp, hf, array_length(hf));
1399 proto_register_subtree_array(ett, array_length(ett));
1403 proto_reg_handoff_nhrp(void)
1405 dissector_handle_t nhrp_handle;
1407 data_handle = find_dissector("data");
1409 osinl_subdissector_table = find_dissector_table("osinl");
1410 osinl_excl_subdissector_table = find_dissector_table("osinl.excl");
1411 ethertype_subdissector_table = find_dissector_table("ethertype");
1413 nhrp_handle = create_dissector_handle(dissect_nhrp, proto_nhrp);
1414 dissector_add_uint("ip.proto", IP_PROTO_NARP, nhrp_handle);
1415 dissector_add_uint("gre.proto", GRE_NHRP, nhrp_handle);
1416 dissector_add_uint("llc.iana_pid", IANA_PID_MARS_NHRP_CONTROL, nhrp_handle);