2 * Routines for NBMA Next Hop Resolution Protocol
3 * RFC 2332 plus Cisco extensions:
4 * I-D draft-detienne-dmvpn-01: Flexible Dynamic Mesh VPN
5 * others? (documented where?)
6 * plus extensions from:
7 * RFC 2520: NHRP with Mobile NHCs
8 * RFC 2735: NHRP Support for Virtual Private Networks
10 * Wireshark - Network traffic analyzer
11 * By Gerald Combs <gerald@wireshark.org>
12 * Copyright 1998 Gerald Combs
14 * SPDX-License-Identifier: GPL-2.0-or-later
16 * CIE decoding for extensions and Cisco 12.4T extensions
17 * added by Timo Teras <timo.teras@iki.fi>
23 #include <epan/packet.h>
24 #include <epan/prefs.h>
25 #include <epan/addr_resolv.h>
26 #include <epan/expert.h>
27 #include <epan/etypes.h>
28 #include <epan/ipproto.h>
29 #include <epan/nlpid.h>
31 #include <epan/in_cksum.h>
32 #include "packet-iana-oui.h"
33 #include "packet-llc.h"
34 #include "packet-gre.h"
36 void proto_register_nhrp(void);
37 void proto_reg_handoff_nhrp(void);
39 static dissector_handle_t nhrp_handle
;
41 /* forward reference */
42 static void _dissect_nhrp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
43 bool nested
, bool codeinfo
);
45 static int proto_nhrp
;
46 static int hf_nhrp_hdr_afn
;
47 static int hf_nhrp_hdr_pro_type
;
48 static int hf_nhrp_hdr_pro_snap_oui
;
49 static int hf_nhrp_hdr_pro_snap_pid
;
50 static int hf_nhrp_hdr_hopcnt
;
51 static int hf_nhrp_hdr_pktsz
;
52 static int hf_nhrp_hdr_chksum
;
53 static int hf_nhrp_hdr_chksum_status
;
54 static int hf_nhrp_hdr_extoff
;
55 static int hf_nhrp_hdr_version
;
56 static int hf_nhrp_hdr_op_type
;
57 static int hf_nhrp_hdr_shtl
;
58 static int hf_nhrp_hdr_shtl_type
;
59 static int hf_nhrp_hdr_shtl_len
;
60 static int hf_nhrp_hdr_sstl
;
61 static int hf_nhrp_hdr_sstl_type
;
62 static int hf_nhrp_hdr_sstl_len
;
64 static int hf_nhrp_src_proto_len
;
65 static int hf_nhrp_dst_proto_len
;
66 static int hf_nhrp_flags
;
67 static int hf_nhrp_flag_Q
;
68 static int hf_nhrp_flag_N
;
69 static int hf_nhrp_flag_A
;
70 static int hf_nhrp_flag_D
;
71 static int hf_nhrp_flag_U1
;
72 static int hf_nhrp_flag_U2
;
73 static int hf_nhrp_flag_S
;
74 static int hf_nhrp_flag_NAT
;
75 static int hf_nhrp_src_nbma_addr
;
76 static int hf_nhrp_src_nbma_saddr
;
77 static int hf_nhrp_src_prot_addr
;
78 static int hf_nhrp_dst_prot_addr
;
79 static int hf_nhrp_request_id
;
81 static int hf_nhrp_code
;
82 static int hf_nhrp_prefix_len
;
83 static int hf_nhrp_unused
;
84 static int hf_nhrp_mtu
;
85 static int hf_nhrp_holding_time
;
86 static int hf_nhrp_cli_addr_tl
;
87 static int hf_nhrp_cli_addr_tl_type
;
88 static int hf_nhrp_cli_addr_tl_len
;
89 static int hf_nhrp_cli_saddr_tl
;
90 static int hf_nhrp_cli_saddr_tl_type
;
91 static int hf_nhrp_cli_saddr_tl_len
;
92 static int hf_nhrp_cli_prot_len
;
93 static int hf_nhrp_pref
;
94 static int hf_nhrp_client_nbma_addr
;
95 static int hf_nhrp_client_nbma_saddr
;
96 static int hf_nhrp_client_prot_addr
;
97 static int hf_nhrp_ext_C
;
98 static int hf_nhrp_ext_type
;
99 static int hf_nhrp_ext_len
;
100 /* static int hf_nhrp_ext_value; */ /* TBD: Not used */
101 static int hf_nhrp_error_code
;
102 static int hf_nhrp_error_offset
;
103 static int hf_nhrp_traffic_code
;
104 /* static int hf_nhrp_error_packet; */ /* TBD: Not used */
106 static int hf_nhrp_auth_ext_reserved
;
107 static int hf_nhrp_auth_ext_spi
;
108 static int hf_nhrp_auth_ext_src_addr
;
109 static int hf_nhrp_vendor_ext_id
;
110 static int hf_nhrp_devcap_ext_srccap
;
111 static int hf_nhrp_devcap_ext_srccap_V
;
112 static int hf_nhrp_devcap_ext_dstcap
;
113 static int hf_nhrp_devcap_ext_dstcap_V
;
114 static int hf_nhrp_unknown_ext_value
;
116 /* Generated from convert_proto_tree_add_text.pl */
117 static int hf_nhrp_dst_prot_addr_bytes
;
118 static int hf_nhrp_auth_ext_src_addr_bytes
;
119 static int hf_nhrp_vendor_ext_data
;
120 static int hf_nhrp_protocol_type
;
121 static int hf_nhrp_src_nbma_addr_bytes
;
122 static int hf_nhrp_client_nbma_address_bytes
;
123 static int hf_nhrp_client_prot_addr_bytes
;
124 static int hf_nhrp_auth_data
;
125 static int hf_nhrp_src_prot_addr_bytes
;
128 static int ett_nhrp_hdr
;
129 static int ett_nhrp_hdr_shtl
;
130 static int ett_nhrp_hdr_sstl
;
131 static int ett_nhrp_mand
;
132 static int ett_nhrp_ext
;
133 static int ett_nhrp_mand_flag
;
134 static int ett_nhrp_cie
;
135 static int ett_nhrp_cie_cli_addr_tl
;
136 static int ett_nhrp_cie_cli_saddr_tl
;
137 static int ett_nhrp_indication
;
138 static int ett_nhrp_auth_ext
;
139 static int ett_nhrp_vendor_ext
;
140 static int ett_nhrp_devcap_ext
;
141 static int ett_nhrp_devcap_ext_srccap
;
142 static int ett_nhrp_devcap_ext_dstcap
;
144 static expert_field ei_nhrp_hdr_pktsz
;
145 static expert_field ei_nhrp_hdr_extoff
;
146 static expert_field ei_nhrp_hdr_chksum
;
147 static expert_field ei_nhrp_ext_not_allowed
;
148 static expert_field ei_nhrp_ext_malformed
;
149 static expert_field ei_nhrp_ext_extra
;
151 static bool pref_auth_ext_has_addr
= true;
153 /* NHRP Packet Types */
154 #define NHRP_RESOLUTION_REQ 1
155 #define NHRP_RESOLUTION_REPLY 2
156 #define NHRP_REGISTRATION_REQ 3
157 #define NHRP_REGISTRATION_REPLY 4
158 #define NHRP_PURGE_REQ 5
159 #define NHRP_PURGE_REPLY 6
160 #define NHRP_ERROR_INDICATION 7
161 #define NHRP_TRAFFIC_INDICATION 8
163 /* NHRP Extension Types */
164 #define NHRP_EXT_NULL 0 /* End of Extension */
165 #define NHRP_EXT_RESP_ADDR 3 /* Responder Address Extension */
166 #define NHRP_EXT_FWD_RECORD 4 /* NHRP Forward Transit NHS Record Extension */
167 #define NHRP_EXT_REV_RECORD 5 /* NHRP Reverse Transit NHS Record Extension */
168 #define NHRP_EXT_AUTH 7 /* NHRP Authentication Extension */
169 #define NHRP_EXT_VENDOR_PRIV 8 /* NHRP Vendor Private Extension */
170 #define NHRP_EXT_NAT_ADDRESS 9 /* Cisco NAT Address Extension */
171 #define NHRP_EXT_DEV_CAPABILITIES 9 /* RFC 2735: Device Capabilities Extension */
172 #define NHRP_EXT_MOBILE_AUTH 10 /* RFC 2520: NHRP Mobile NHC Authentication Extension */
174 /* NHRP Error Codes */
175 #define NHRP_ERR_UNRECOGNIZED_EXT 0x0001
176 #define NHRP_ERR_NHRP_LOOP_DETECT 0x0003
177 #define NHRP_ERR_PROT_ADDR_UNREACHABLE 0x0006
178 #define NHRP_ERR_PROT_ERROR 0x0007
179 #define NHRP_ERR_SDU_SIZE_EXCEEDED 0x0008
180 #define NHRP_ERR_INV_EXT 0x0009
181 #define NHRP_ERR_INV_RESOLUTION_REPLY 0x000a
182 #define NHRP_ERR_AUTH_FAILURE 0x000b
183 #define NHRP_ERR_HOP_COUNT_EXCEEDED 0x000f
184 #define NHRP_ERR_VPN_MISMATCH 0x0010 /* RFC 2735 */
185 #define NHRP_ERR_VPN_UNSUPPORTED 0x0011 /* RFC 2735 */
188 #define NHRP_CODE_SUCCESS 0x00
189 #define NHRP_CODE_ADMIN_PROHIBITED 0x04
190 #define NHRP_CODE_INSUFFICIENT_RESOURCES 0x05
191 #define NHRP_CODE_NO_BINDING_EXISTS 0x0c
192 #define NHRP_CODE_NON_UNIQUE_BINDING 0x0d
193 #define NHRP_CODE_ALREADY_REGISTERED 0x0e
195 /* NHRP Subnetwork layer address type/length */
196 #define NHRP_SHTL_TYPE_MASK 0x40
197 #define NHRP_SHTL_LEN_MASK 0x3F
198 #define NHRP_SHTL_TYPE(val) (((val) & (NHRP_SHTL_TYPE_MASK)) >> 6)
199 #define NHRP_SHTL_LEN(val) ((val) & (NHRP_SHTL_LEN_MASK))
201 #define NHRP_SHTL_TYPE_NSAP 0
202 #define NHRP_SHTL_TYPE_E164 1
204 static const value_string nhrp_shtl_type_vals
[] = {
205 { NHRP_SHTL_TYPE_NSAP
, "NSAP format" },
206 { NHRP_SHTL_TYPE_E164
, "Native E.164 format" },
210 static const value_string nhrp_op_type_vals
[] = {
211 { NHRP_RESOLUTION_REQ
, "NHRP Resolution Request" },
212 { NHRP_RESOLUTION_REPLY
, "NHRP Resolution Reply" },
213 { NHRP_REGISTRATION_REQ
, "NHRP Registration Request" },
214 { NHRP_REGISTRATION_REPLY
, "NHRP Registration Reply" },
215 { NHRP_PURGE_REQ
, "NHRP Purge Request" },
216 { NHRP_PURGE_REPLY
, "NHRP Purge Reply" },
217 { NHRP_ERROR_INDICATION
, "NHRP Error Indication" },
218 { NHRP_TRAFFIC_INDICATION
, "NHRP Traffic Indication" },
222 static const value_string ext_type_vals
[] = {
223 { NHRP_EXT_NULL
, "End of Extension" },
224 { NHRP_EXT_RESP_ADDR
, "Responder Address Extension" },
225 { NHRP_EXT_FWD_RECORD
, "Forward Transit NHS Record Extension" },
226 { NHRP_EXT_REV_RECORD
, "Reverse Transit NHS Record Extension" },
227 { NHRP_EXT_AUTH
, "NHRP Authentication Extension" },
228 { NHRP_EXT_VENDOR_PRIV
, "NHRP Vendor Private Extension" },
229 { NHRP_EXT_NAT_ADDRESS
, "Cisco NAT Address Extension" },
230 #if 0 /* Dup (which is handled in the code) */
231 { NHRP_EXT_DEV_CAPABILITIES
,"Device Capabilities Extension" },
233 { NHRP_EXT_MOBILE_AUTH
, "Mobile NHC Authentication Extension" },
237 static const value_string nhrp_error_code_vals
[] = {
238 { NHRP_ERR_UNRECOGNIZED_EXT
, "Unrecognized Extension" },
239 { NHRP_ERR_NHRP_LOOP_DETECT
, "NHRP Loop Detected" },
240 { NHRP_ERR_PROT_ADDR_UNREACHABLE
, "Protocol Address Unreachable" },
241 { NHRP_ERR_PROT_ERROR
, "Protocol Error" },
242 { NHRP_ERR_SDU_SIZE_EXCEEDED
, "NHRP SDU Size Exceeded" },
243 { NHRP_ERR_INV_EXT
, "Invalid Extension" },
244 { NHRP_ERR_INV_RESOLUTION_REPLY
, "Invalid NHRP Resolution Reply Received" },
245 { NHRP_ERR_AUTH_FAILURE
, "Authentication Failure" },
246 { NHRP_ERR_HOP_COUNT_EXCEEDED
, "Hop Count Exceeded" },
247 { NHRP_ERR_VPN_MISMATCH
, "VPN Mismatch" },
248 { NHRP_ERR_VPN_UNSUPPORTED
, "VPN Unsupported" },
252 static const value_string nhrp_traffic_code_vals
[] = {
253 { 0, "NHRP traffic redirect/indirection" },
257 static const value_string nhrp_cie_code_vals
[] = {
258 { NHRP_CODE_SUCCESS
, "Success" },
259 { NHRP_CODE_ADMIN_PROHIBITED
, "Administratively Prohibited" },
260 { NHRP_CODE_INSUFFICIENT_RESOURCES
, "Insufficient Resources" },
261 { NHRP_CODE_NO_BINDING_EXISTS
, "No Interworking Layer Address to NBMA Address Binding Exists" },
262 { NHRP_CODE_NON_UNIQUE_BINDING
, "Binding Exists But Is Not Unique" },
263 { NHRP_CODE_ALREADY_REGISTERED
, "Unique Internetworking Layer Address Already Registered" },
267 static dissector_table_t osinl_incl_subdissector_table
;
268 static dissector_table_t osinl_excl_subdissector_table
;
269 static dissector_table_t ethertype_subdissector_table
;
272 * The header fields needed outside of dissect_nhrp_hdr().
273 * This is not all of the fields.
275 typedef struct _e_nhrp
{
277 uint16_t ar_pro_type
;
278 uint32_t ar_pro_type_oui
;
279 uint16_t ar_pro_type_pid
;
285 static bool dissect_nhrp_hdr(tvbuff_t
*tvb
,
291 oui_info_t
**pOuiInfo
,
294 int offset
= *pOffset
;
295 const char *pro_type_str
;
297 proto_tree
*nhrp_tree
;
298 proto_item
*nhrp_item
;
299 proto_item
*shtl_tree_item
;
300 proto_tree
*shtl_tree
;
301 proto_item
*sstl_tree_item
;
302 proto_tree
*sstl_tree
;
303 proto_item
*ti
, *ti_extoff
;
311 nhrp_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, -1, ett_nhrp_hdr
, &nhrp_item
, "NHRP Fixed Header");
313 proto_tree_add_item_ret_uint(nhrp_tree
, hf_nhrp_hdr_afn
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &afn
);
314 hdr
->ar_afn
= (uint16_t)afn
;
317 /* XXX - range_string? */
318 hdr
->ar_pro_type
= tvb_get_ntohs(tvb
, offset
);
319 if (hdr
->ar_pro_type
<= 0xFF) {
321 pro_type_str
= val_to_str_const(hdr
->ar_pro_type
, nlpid_vals
,
323 } else if (hdr
->ar_pro_type
<= 0x3FF) {
324 /* Reserved for future use by the IETF */
325 pro_type_str
= "Reserved for future use by the IETF";
326 } else if (hdr
->ar_pro_type
<= 0x04FF) {
327 /* Allocated for use by the ATM Forum */
328 pro_type_str
= "Allocated for use by the ATM Forum";
329 } else if (hdr
->ar_pro_type
<= 0x05FF) {
330 /* Experimental/Local use */
331 pro_type_str
= "Experimental/Local use";
333 pro_type_str
= val_to_str_const(hdr
->ar_pro_type
, etype_vals
,
334 "Unknown Ethertype");
336 proto_tree_add_uint_format_value(nhrp_tree
, hf_nhrp_hdr_pro_type
, tvb
, offset
, 2,
337 hdr
->ar_pro_type
, "%s (0x%04x)",
338 pro_type_str
, hdr
->ar_pro_type
);
341 if (hdr
->ar_pro_type
== NLPID_SNAP
) {
343 * The long form protocol type is a SNAP OUI and PID.
345 proto_tree_add_item_ret_uint(nhrp_tree
, hf_nhrp_hdr_pro_snap_oui
,
346 tvb
, offset
, 3, hdr
->ar_pro_type_oui
, &oui
);
348 hdr
->ar_pro_type_oui
= oui
;
350 *pOuiInfo
= get_snap_oui_info(hdr
->ar_pro_type_oui
);
351 if (*pOuiInfo
!= NULL
) {
352 proto_tree_add_item_ret_uint(nhrp_tree
,
353 *(*pOuiInfo
)->field_info
->p_id
,
354 tvb
, offset
, 2, ENC_BIG_ENDIAN
, &pid
);
356 proto_tree_add_item_ret_uint(nhrp_tree
, hf_nhrp_hdr_pro_snap_pid
,
357 tvb
, offset
, 2, ENC_BIG_ENDIAN
, &pid
);
359 hdr
->ar_pro_type_pid
= (uint16_t)pid
;
362 * XXX - we should check that this is zero, as RFC 2332
363 * says it should be zero.
365 proto_tree_add_item(nhrp_tree
, hf_nhrp_protocol_type
, tvb
, offset
, 5, ENC_NA
);
369 proto_tree_add_item(nhrp_tree
, hf_nhrp_hdr_hopcnt
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
372 ti
= proto_tree_add_item_ret_uint(nhrp_tree
, hf_nhrp_hdr_pktsz
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &pktsz
);
375 * The total packet size isn't large enough for a full header.
377 expert_add_info(pinfo
, ti
, &ei_nhrp_hdr_pktsz
);
378 proto_item_set_end(nhrp_item
, tvb
, offset
+ 2);
383 if (tvb_bytes_exist(tvb
, 0, pktsz
)) {
385 SET_CKSUM_VEC_TVB(cksum_vec
[0], tvb
, 0, pktsz
);
387 proto_tree_add_checksum(nhrp_tree
, tvb
, offset
, hf_nhrp_hdr_chksum
, hf_nhrp_hdr_chksum_status
, &ei_nhrp_hdr_chksum
,
388 pinfo
, in_cksum(&cksum_vec
[0], 1), ENC_BIG_ENDIAN
, PROTO_CHECKSUM_VERIFY
|PROTO_CHECKSUM_IN_CKSUM
);
390 proto_tree_add_checksum(nhrp_tree
, tvb
, offset
, hf_nhrp_hdr_chksum
, hf_nhrp_hdr_chksum_status
, &ei_nhrp_hdr_chksum
,
391 pinfo
, 0, ENC_BIG_ENDIAN
, PROTO_CHECKSUM_NO_FLAGS
);
395 ti_extoff
= proto_tree_add_item_ret_uint(nhrp_tree
, hf_nhrp_hdr_extoff
, tvb
, offset
, 2, ENC_BIG_ENDIAN
, &extoff
);
397 if (extoff
< 20 || extoff
> pktsz
) {
398 /* Bogus value; keep dissecting the header */
399 expert_add_info(pinfo
, ti_extoff
, &ei_nhrp_hdr_extoff
);
401 switch (hdr
->ar_op_type
)
403 case NHRP_ERROR_INDICATION
:
404 /* According to RFC 2332, section 5.2.7, there shouldn't be any
405 * extensions in the Error Indication packet. */
406 expert_add_info(pinfo
, ti_extoff
, &ei_nhrp_ext_not_allowed
);
414 version
= tvb_get_uint8(tvb
, offset
);
415 proto_tree_add_uint_format_value(nhrp_tree
, hf_nhrp_hdr_version
, tvb
, offset
, 1,
416 version
, "%u (%s)", version
,
417 (version
== 1) ? "NHRP - rfc2332" : "Unknown");
419 proto_tree_add_item(nhrp_tree
, hf_nhrp_hdr_op_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
422 hdr
->ar_shtl
= tvb_get_uint8(tvb
, offset
);
423 shtl_tree_item
= proto_tree_add_uint_format_value(nhrp_tree
, hf_nhrp_hdr_shtl
,
424 tvb
, offset
, 1, hdr
->ar_shtl
, "%s/%u",
425 val_to_str_const(NHRP_SHTL_TYPE(hdr
->ar_shtl
), nhrp_shtl_type_vals
, "Unknown Type"),
426 NHRP_SHTL_LEN(hdr
->ar_shtl
));
427 shtl_tree
= proto_item_add_subtree(shtl_tree_item
, ett_nhrp_hdr_shtl
);
428 proto_tree_add_item(shtl_tree
, hf_nhrp_hdr_shtl_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
429 proto_tree_add_item(shtl_tree
, hf_nhrp_hdr_shtl_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
432 hdr
->ar_sstl
= tvb_get_uint8(tvb
, offset
);
433 sstl_tree_item
= proto_tree_add_uint_format_value(nhrp_tree
, hf_nhrp_hdr_sstl
,
434 tvb
, offset
, 1, hdr
->ar_sstl
, "%s/%u",
435 val_to_str_const(NHRP_SHTL_TYPE(hdr
->ar_sstl
), nhrp_shtl_type_vals
, "Unknown Type"),
436 NHRP_SHTL_LEN(hdr
->ar_sstl
));
437 sstl_tree
= proto_item_add_subtree(sstl_tree_item
, ett_nhrp_hdr_sstl
);
438 proto_tree_add_item(sstl_tree
, hf_nhrp_hdr_sstl_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
439 proto_tree_add_item(sstl_tree
, hf_nhrp_hdr_sstl_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
442 proto_item_set_end(nhrp_item
, tvb
, offset
);
445 if (extoff
< 20 || extoff
> pktsz
) {
449 *pMandLen
= extoff
- 20;
450 *pExtLen
= pktsz
- extoff
;
453 *pMandLen
= pktsz
- 20;
459 static void dissect_cie_list(tvbuff_t
*tvb
,
468 proto_item
*cli_addr_tree_item
;
469 proto_tree
*cli_addr_tree
;
470 proto_item
*cli_saddr_tree_item
;
471 proto_tree
*cli_saddr_tree
;
474 while ((offset
+ 12) <= cieEnd
) {
475 unsigned cli_addr_len
= tvb_get_uint8(tvb
, offset
+ 8);
476 unsigned cli_saddr_len
= tvb_get_uint8(tvb
, offset
+ 9);
477 unsigned cli_prot_len
= tvb_get_uint8(tvb
, offset
+ 10);
478 unsigned cie_len
= 12 + cli_addr_len
+ cli_saddr_len
+ cli_prot_len
;
479 proto_tree
*cie_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, cie_len
, ett_nhrp_cie
, NULL
, "Client Information Entry");
482 proto_tree_add_item(cie_tree
, hf_nhrp_code
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
485 uint8_t code
= tvb_get_uint8(tvb
, offset
);
487 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", Code=%s",
488 val_to_str(code
, nhrp_cie_code_vals
, "Unknown (%u)"));
490 proto_tree_add_item(cie_tree
, hf_nhrp_code
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
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_uint8(tvb
, offset
);
507 cli_addr_tree_item
= proto_tree_add_uint_format_value(cie_tree
,
508 hf_nhrp_cli_addr_tl
, tvb
, offset
, 1, val
, "%s/%u",
509 val_to_str_const(NHRP_SHTL_TYPE(val
), nhrp_shtl_type_vals
, "Unknown Type"),
511 cli_addr_tree
= proto_item_add_subtree(cli_addr_tree_item
, ett_nhrp_cie_cli_addr_tl
);
512 proto_tree_add_item(cli_addr_tree
, hf_nhrp_cli_addr_tl_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
513 proto_tree_add_item(cli_addr_tree
, hf_nhrp_cli_addr_tl_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
516 val
= tvb_get_uint8(tvb
, offset
);
517 cli_saddr_tree_item
= proto_tree_add_uint_format_value(cie_tree
,
518 hf_nhrp_cli_saddr_tl
, tvb
, offset
, 1, val
, "%s/%u",
519 val_to_str_const(NHRP_SHTL_TYPE(val
), nhrp_shtl_type_vals
, "Unknown Type"),
521 cli_saddr_tree
= proto_item_add_subtree(cli_saddr_tree_item
, ett_nhrp_cie_cli_saddr_tl
);
522 proto_tree_add_item(cli_saddr_tree
, hf_nhrp_cli_saddr_tl_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
523 proto_tree_add_item(cli_saddr_tree
, hf_nhrp_cli_saddr_tl_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
526 proto_tree_add_item(cie_tree
, hf_nhrp_cli_prot_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
529 proto_tree_add_item(cie_tree
, hf_nhrp_pref
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
533 switch (hdr
->ar_afn
) {
536 if (cli_addr_len
== 4)
537 proto_tree_add_item(cie_tree
, hf_nhrp_client_nbma_addr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
539 proto_tree_add_item(cie_tree
, hf_nhrp_client_nbma_address_bytes
, tvb
, offset
, cli_addr_len
, ENC_NA
);
544 proto_tree_add_item(cie_tree
, hf_nhrp_client_nbma_address_bytes
, tvb
, offset
, cli_addr_len
, ENC_NA
);
547 offset
+= cli_addr_len
;
551 proto_tree_add_item(cie_tree
, hf_nhrp_client_nbma_saddr
, tvb
, offset
, cli_saddr_len
, ENC_NA
);
555 if (cli_prot_len
== 4)
556 proto_tree_add_item(cie_tree
, hf_nhrp_client_prot_addr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
558 proto_tree_add_item(cie_tree
, hf_nhrp_client_prot_addr_bytes
, tvb
, offset
, cli_prot_len
, ENC_NA
);
560 offset
+= cli_prot_len
;
565 // NOLINTNEXTLINE(misc-no-recursion)
566 static void dissect_nhrp_mand(tvbuff_t
*tvb
,
569 oui_info_t
*oui_info
,
575 int mandEnd
= tvb_reported_length(tvb
);
579 proto_tree
*nhrp_tree
;
580 proto_item
*nhrp_item
;
582 proto_tree
*ind_tree
;
583 proto_item
*ind_item
;
584 bool save_in_error_pkt
;
588 nhrp_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, -1, ett_nhrp_mand
, &nhrp_item
, "NHRP Mandatory Part");
590 /* Src Proto Len, present in all current packet types */
591 *srcLen
= tvb_get_uint8(tvb
, offset
);
592 proto_tree_add_item(nhrp_tree
, hf_nhrp_src_proto_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
595 /* Dst Proto Len, present in all current packet types */
596 dstLen
= tvb_get_uint8(tvb
, offset
);
597 proto_tree_add_item(nhrp_tree
, hf_nhrp_dst_proto_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
601 * Flags: different flags are used for different packet types, and
602 * aren't even present in all packet types.
604 * Next 4 bytes: request ID in most packet types, error code and
605 * offset in Error Indication, traffic code and unused field in
606 * Traffic Indication.
608 switch (hdr
->ar_op_type
)
610 case NHRP_RESOLUTION_REQ
:
611 case NHRP_RESOLUTION_REPLY
:
613 static int * const flags
[] = {
622 proto_tree_add_bitmask(nhrp_tree
, tvb
, offset
, hf_nhrp_flags
, ett_nhrp_mand_flag
, flags
, ENC_BIG_ENDIAN
);
625 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", ID=%u", tvb_get_ntohl(tvb
, offset
));
626 proto_tree_add_item(nhrp_tree
, hf_nhrp_request_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
630 case NHRP_REGISTRATION_REQ
:
631 case NHRP_REGISTRATION_REPLY
:
633 static int * const flags
[] = {
638 proto_tree_add_bitmask(nhrp_tree
, tvb
, offset
, hf_nhrp_flags
, ett_nhrp_mand_flag
, flags
, ENC_BIG_ENDIAN
);
641 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", ID=%u", tvb_get_ntohl(tvb
, offset
));
642 proto_tree_add_item(nhrp_tree
, hf_nhrp_request_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
648 case NHRP_PURGE_REPLY
:
650 static int * const flags
[] = {
655 proto_tree_add_bitmask(nhrp_tree
, tvb
, offset
, hf_nhrp_flags
, ett_nhrp_mand_flag
, flags
, ENC_BIG_ENDIAN
);
658 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", ID=%u", tvb_get_ntohl(tvb
, offset
));
659 proto_tree_add_item(nhrp_tree
, hf_nhrp_request_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
663 case NHRP_ERROR_INDICATION
:
665 /* Skip unused field */
668 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", %s",
669 val_to_str(tvb_get_ntohs(tvb
, offset
), nhrp_error_code_vals
, "Unknown Error (%u)"));
670 proto_tree_add_item(nhrp_tree
, hf_nhrp_error_code
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
673 proto_tree_add_item(nhrp_tree
, hf_nhrp_error_offset
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
677 case NHRP_TRAFFIC_INDICATION
:
679 /* Skip unused field */
682 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", %s",
683 val_to_str(tvb_get_ntohs(tvb
, offset
), nhrp_traffic_code_vals
, "Unknown traffic code (%u)"));
684 proto_tree_add_item(nhrp_tree
, hf_nhrp_traffic_code
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
687 /* Skip unused field */
692 /* Unknown packet type */
697 shl
= NHRP_SHTL_LEN(hdr
->ar_shtl
);
699 switch (hdr
->ar_afn
) {
703 proto_tree_add_item(nhrp_tree
, hf_nhrp_src_nbma_addr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
705 proto_tree_add_item(nhrp_tree
, hf_nhrp_src_nbma_addr_bytes
, tvb
, offset
, shl
, ENC_NA
);
710 proto_tree_add_item(nhrp_tree
, hf_nhrp_src_nbma_addr_bytes
, tvb
, offset
, shl
, ENC_NA
);
716 ssl
= NHRP_SHTL_LEN(hdr
->ar_sstl
);
718 proto_tree_add_item(nhrp_tree
, hf_nhrp_src_nbma_saddr
, tvb
, offset
, ssl
, ENC_NA
);
723 proto_tree_add_item(nhrp_tree
, hf_nhrp_src_prot_addr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
727 proto_tree_add_item(nhrp_tree
, hf_nhrp_src_prot_addr_bytes
, tvb
, offset
, *srcLen
, ENC_NA
);
732 proto_tree_add_item(nhrp_tree
, hf_nhrp_dst_prot_addr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
736 proto_tree_add_item(nhrp_tree
, hf_nhrp_dst_prot_addr_bytes
, tvb
, offset
, dstLen
, ENC_NA
);
741 * CIE list in most packet types, NHRP packet in error in Error
742 * Indication, data packet in Traffic Indication.
744 switch (hdr
->ar_op_type
)
746 case NHRP_RESOLUTION_REQ
:
747 case NHRP_REGISTRATION_REQ
:
749 dissect_cie_list(tvb
, pinfo
, nhrp_tree
, offset
, mandEnd
, hdr
, true, codeinfo
);
751 case NHRP_RESOLUTION_REPLY
:
752 case NHRP_REGISTRATION_REPLY
:
753 case NHRP_PURGE_REPLY
:
754 dissect_cie_list(tvb
, pinfo
, nhrp_tree
, offset
, mandEnd
, hdr
, false, codeinfo
);
756 case NHRP_ERROR_INDICATION
:
757 ind_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, -1, ett_nhrp_indication
, &ind_item
, "Packet Causing Indication");
758 save_in_error_pkt
= pinfo
->flags
.in_error_pkt
;
759 pinfo
->flags
.in_error_pkt
= true;
760 sub_tvb
= tvb_new_subset_remaining(tvb
, offset
);
761 // We recurse here, but we'll run out of packet before we run out of stack.
762 _dissect_nhrp(sub_tvb
, pinfo
, ind_tree
, true, false);
763 pinfo
->flags
.in_error_pkt
= save_in_error_pkt
;
765 case NHRP_TRAFFIC_INDICATION
:
766 ind_tree
= proto_tree_add_subtree(tree
, tvb
, offset
, -1, ett_nhrp_indication
, &ind_item
, "Packet Causing Indication");
767 save_in_error_pkt
= pinfo
->flags
.in_error_pkt
;
768 pinfo
->flags
.in_error_pkt
= true;
769 sub_tvb
= tvb_new_subset_remaining(tvb
, offset
);
770 if (hdr
->ar_pro_type
<= 0xFF) {
772 if (hdr
->ar_pro_type
== NLPID_SNAP
) {
774 * Dissect based on the SNAP OUI and PID.
776 if (hdr
->ar_pro_type_oui
== 0x000000) {
778 * "Should not happen", as the protocol type should
779 * be the Ethertype, but....
781 dissected
= dissector_try_uint(
782 ethertype_subdissector_table
,
783 hdr
->ar_pro_type_pid
,
784 sub_tvb
, pinfo
, ind_tree
);
787 * If we have a dissector table, use it, otherwise
788 * just dissect as data.
790 if (oui_info
!= NULL
) {
791 dissected
= dissector_try_uint(
793 hdr
->ar_pro_type_pid
,
801 * Dissect based on the NLPID.
803 dissected
= dissector_try_uint(
804 osinl_incl_subdissector_table
,
805 hdr
->ar_pro_type
, sub_tvb
, pinfo
,
808 osinl_excl_subdissector_table
,
809 hdr
->ar_pro_type
, sub_tvb
, pinfo
,
812 } else if (hdr
->ar_pro_type
<= 0x3FF) {
813 /* Reserved for future use by the IETF */
815 } else if (hdr
->ar_pro_type
<= 0x04FF) {
816 /* Allocated for use by the ATM Forum */
818 } else if (hdr
->ar_pro_type
<= 0x05FF) {
819 /* Experimental/Local use */
822 dissected
= dissector_try_uint(
823 ethertype_subdissector_table
,
824 hdr
->ar_pro_type
, sub_tvb
, pinfo
, ind_tree
);
827 call_data_dissector(sub_tvb
, pinfo
, ind_tree
);
829 pinfo
->flags
.in_error_pkt
= save_in_error_pkt
;
836 static void dissect_nhrp_ext(tvbuff_t
*tvb
,
845 int offset
= *pOffset
;
846 int extEnd
= offset
+ extLen
;
848 while ((offset
+ 4) <= extEnd
)
850 proto_tree
*nhrp_tree
;
851 proto_item
*nhrp_item
;
852 int extTypeC
= tvb_get_ntohs(tvb
, offset
);
853 int extType
= extTypeC
& 0x3FFF;
854 unsigned len
= tvb_get_ntohs(tvb
, offset
+2);
856 if ((extType
== NHRP_EXT_NAT_ADDRESS
) && (len
== 8)) {
857 /* Assume it's not really a Cisco NAT extension, but a device
858 * capabilities extension instead (see RFC 2735). */
859 nhrp_tree
= proto_tree_add_subtree(tree
, tvb
, offset
,
860 -1, ett_nhrp_ext
, &nhrp_item
, "Device Capabilities Extension");
863 nhrp_tree
= proto_tree_add_subtree(tree
, tvb
, offset
,
864 -1, ett_nhrp_ext
, &nhrp_item
,
865 val_to_str(extType
, ext_type_vals
, "Unknown (%u)"));
867 proto_tree_add_boolean(nhrp_tree
, hf_nhrp_ext_C
, tvb
, offset
, 2, extTypeC
);
868 proto_tree_add_item(nhrp_tree
, hf_nhrp_ext_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
871 proto_tree_add_item(nhrp_tree
, hf_nhrp_ext_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
874 if (len
&& (extType
!= NHRP_EXT_NULL
)) {
875 if ((extType
== NHRP_EXT_NAT_ADDRESS
) && (len
== 8)) {
876 /* Assume it's not really a Cisco NAT extension, but a device
877 * capabilities extension instead (see RFC 2735). */
878 proto_tree
*devcap_tree
;
879 proto_item
*cap_item
;
880 proto_tree
*cap_tree
;
882 devcap_tree
= proto_tree_add_subtree_format(nhrp_tree
, tvb
, offset
, len
,
883 ett_nhrp_devcap_ext
, NULL
, "Extension Data: Src is %sVPN-aware; Dst is %sVPN-aware",
884 tvb_get_ntohl(tvb
, offset
) & 1 ? "" : "non-",
885 tvb_get_ntohl(tvb
, offset
+ 4) & 1 ? "" : "non-");
886 cap_item
= proto_tree_add_item(devcap_tree
, hf_nhrp_devcap_ext_srccap
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
887 cap_tree
= proto_item_add_subtree(cap_item
, ett_nhrp_devcap_ext_srccap
);
888 proto_tree_add_item(cap_tree
, hf_nhrp_devcap_ext_srccap_V
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
890 cap_item
= proto_tree_add_item(devcap_tree
, hf_nhrp_devcap_ext_dstcap
, tvb
, offset
+ 4, 4, ENC_BIG_ENDIAN
);
891 cap_tree
= proto_item_add_subtree(cap_item
, ett_nhrp_devcap_ext_dstcap
);
892 proto_tree_add_item(cap_tree
, hf_nhrp_devcap_ext_dstcap_V
, tvb
, offset
+ 4, 4, ENC_BIG_ENDIAN
);
897 case NHRP_EXT_RESP_ADDR
:
898 case NHRP_EXT_FWD_RECORD
:
899 case NHRP_EXT_REV_RECORD
:
900 case NHRP_EXT_NAT_ADDRESS
:
901 dissect_cie_list(tvb
, pinfo
, nhrp_tree
,
902 offset
, offset
+ len
, hdr
, 0, false);
906 /* This is ugly, but this is the only place srcLen is actually
907 * used so we manipulate it here.
909 if (!pref_auth_ext_has_addr
)
912 case NHRP_EXT_MOBILE_AUTH
:
913 if (len
< (4 + srcLen
)) {
914 proto_tree_add_expert_format(nhrp_tree
, pinfo
, &ei_nhrp_ext_malformed
, tvb
, offset
, len
,
915 "Incomplete Authentication Extension");
918 proto_tree
*auth_tree
;
919 proto_item
*auth_item
;
922 auth_tree
= proto_tree_add_subtree_format(nhrp_tree
, tvb
, offset
, -1,
923 ett_nhrp_auth_ext
, &auth_item
, "Extension Data");
924 proto_tree_add_item(auth_tree
, hf_nhrp_auth_ext_reserved
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
925 proto_tree_add_item_ret_uint(auth_tree
, hf_nhrp_auth_ext_spi
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
, &spi
);
926 proto_item_append_text(auth_item
, ": SPI=%u", spi
);
928 proto_tree_add_item(auth_tree
, hf_nhrp_auth_ext_src_addr
, tvb
, offset
+ 4, 4, ENC_BIG_ENDIAN
);
930 proto_tree_add_item(auth_tree
, hf_nhrp_auth_ext_src_addr_bytes
, tvb
, offset
+ 4, srcLen
, ENC_NA
);
932 if (len
> (4 + srcLen
)) {
933 proto_tree_add_item(auth_tree
, hf_nhrp_auth_data
, tvb
, offset
+ 4 + srcLen
, len
- (4 + srcLen
), ENC_NA
);
934 proto_item_append_text(auth_item
, ": Data=%s",
935 tvb_bytes_to_str(pinfo
->pool
, tvb
, offset
+ 4 + srcLen
, len
- (4 + srcLen
)));
937 proto_item_set_len(auth_item
, len
);
941 case NHRP_EXT_VENDOR_PRIV
:
943 proto_tree_add_expert_format(nhrp_tree
, pinfo
, &ei_nhrp_ext_malformed
, tvb
, offset
, len
,
944 "Incomplete Vendor-Private Extension");
947 proto_tree
*vendor_tree
;
948 proto_item
*vendor_item
;
952 vendor_tree
= proto_tree_add_subtree(nhrp_tree
, tvb
, offset
, len
,
953 ett_nhrp_vendor_ext
, &vendor_item
, "Extension Data:");
954 proto_tree_add_item_ret_uint(vendor_tree
, hf_nhrp_vendor_ext_id
, tvb
, offset
, 3, ENC_BIG_ENDIAN
, &manuf
);
955 oui
= uint_get_manuf_name_if_known(manuf
);
957 proto_item_append_text(vendor_item
, " Vendor ID=%s", oui
);
959 proto_item_append_text(vendor_item
, " Vendor ID=Unknown");
962 proto_tree_add_item(vendor_tree
, hf_nhrp_vendor_ext_data
, tvb
, offset
+ 3, len
- 3, ENC_NA
);
963 proto_item_append_text(vendor_item
, ", Data=%s", tvb_bytes_to_str(pinfo
->pool
, tvb
, offset
+ 3, len
- 3));
965 proto_item_append_text(vendor_item
, ", Data=<none>");
971 proto_tree_add_item(nhrp_tree
, hf_nhrp_unknown_ext_value
, tvb
,
972 offset
, len
, ENC_NA
);
978 proto_item_set_end(nhrp_item
, tvb
, offset
);
981 len
= tvb_reported_length_remaining(tvb
, offset
);
982 if ((extType
== NHRP_EXT_NULL
) && len
) {
983 proto_tree_add_expert_format(tree
, pinfo
, &ei_nhrp_ext_extra
, tvb
, offset
, len
,
984 "Unknown Data (%d bytes)", len
);
993 static int dissect_nhrp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
995 _dissect_nhrp(tvb
, pinfo
, tree
, false, true);
996 return tvb_captured_length(tvb
);
999 // NOLINTNEXTLINE(misc-no-recursion)
1000 static void _dissect_nhrp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1001 bool nested
, bool codeinfo
)
1008 proto_tree
*nhrp_tree
;
1009 oui_info_t
*oui_info
= NULL
;
1010 unsigned srcLen
= 0;
1013 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "NHRP");
1014 col_clear(pinfo
->cinfo
, COL_INFO
);
1017 memset(&hdr
, 0, sizeof(e_nhrp_hdr
));
1018 hdr
.ar_op_type
= tvb_get_uint8(tvb
, 17);
1021 col_add_str(pinfo
->cinfo
, COL_INFO
,
1022 val_to_str(hdr
.ar_op_type
, nhrp_op_type_vals
,
1023 "0x%02X - unknown"));
1026 ti
= proto_tree_add_protocol_format(tree
, proto_nhrp
, tvb
, 0, -1,
1027 "Next Hop Resolution Protocol (%s)",
1028 val_to_str(hdr
.ar_op_type
, nhrp_op_type_vals
, "0x%02X - unknown"));
1029 nhrp_tree
= proto_item_add_subtree(ti
, ett_nhrp
);
1031 if (!dissect_nhrp_hdr(tvb
, pinfo
, nhrp_tree
, &offset
, &mandLen
, &extLen
,
1034 * Header is bogus in a way that we can't dissect any further.
1039 tvbuff_t
*mand_tvb
= tvb_new_subset_length(tvb
, offset
, mandLen
);
1040 // We recurse here, but we'll run out of packet before we run out of stack.
1041 dissect_nhrp_mand(mand_tvb
, pinfo
, nhrp_tree
, oui_info
, &hdr
, &srcLen
,
1047 dissect_nhrp_ext(tvb
, pinfo
, nhrp_tree
, &offset
, extLen
, &hdr
, srcLen
, nested
);
1052 proto_register_nhrp(void)
1054 static hf_register_info hf
[] = {
1057 { "Address Family Number", "nhrp.hdr.afn",
1058 FT_UINT16
, BASE_HEX_DEC
, VALS(afn_vals
), 0x0,
1061 { &hf_nhrp_hdr_pro_type
,
1062 { "Protocol Type (short form)", "nhrp.hdr.pro.type",
1063 FT_UINT16
, BASE_HEX_DEC
, NULL
, 0x0,
1066 { &hf_nhrp_hdr_pro_snap_oui
,
1067 { "Protocol Type (long form) - OUI", "nhrp.hdr.pro.snap.oui",
1068 FT_UINT24
, BASE_OUI
, NULL
, 0x0,
1071 { &hf_nhrp_hdr_pro_snap_pid
,
1072 { "Protocol Type (long form) - PID", "nhrp.hdr.pro.snap.pid",
1073 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1076 { &hf_nhrp_hdr_hopcnt
,
1077 { "Hop Count", "nhrp.hdr.hopcnt",
1078 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1081 { &hf_nhrp_hdr_pktsz
,
1082 { "Packet Length", "nhrp.hdr.pktsz",
1083 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1086 { &hf_nhrp_hdr_chksum
,
1087 { "NHRP Packet Checksum", "nhrp.hdr.chksum",
1088 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1091 { &hf_nhrp_hdr_chksum_status
,
1092 { "NHRP Packet Checksum Status", "nhrp.hdr.chksum.status",
1093 FT_UINT8
, BASE_NONE
, VALS(proto_checksum_vals
), 0x0,
1096 { &hf_nhrp_hdr_extoff
,
1097 { "Extension Offset", "nhrp.hdr.extoff",
1098 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1101 { &hf_nhrp_hdr_version
,
1102 { "Version", "nhrp.hdr.version",
1103 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1106 { &hf_nhrp_hdr_op_type
,
1107 { "NHRP Packet Type", "nhrp.hdr.op.type",
1108 FT_UINT8
, BASE_DEC
, VALS(nhrp_op_type_vals
), 0x0,
1111 { &hf_nhrp_hdr_shtl
,
1112 { "Source Address Type/Len", "nhrp.hdr.shtl",
1113 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1116 { &hf_nhrp_hdr_shtl_type
,
1117 { "Type", "nhrp.hdr.shtl.type",
1118 FT_UINT8
, BASE_DEC
, VALS(nhrp_shtl_type_vals
), NHRP_SHTL_TYPE_MASK
,
1121 { &hf_nhrp_hdr_shtl_len
,
1122 { "Length", "nhrp.hdr.shtl.len",
1123 FT_UINT8
, BASE_DEC
, NULL
, NHRP_SHTL_LEN_MASK
,
1126 { &hf_nhrp_hdr_sstl
,
1127 { "Source SubAddress Type/Len", "nhrp.hdr.sstl",
1128 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1131 { &hf_nhrp_hdr_sstl_type
,
1132 { "Type", "nhrp.hdr.sstl.type",
1133 FT_UINT8
, BASE_DEC
, VALS(nhrp_shtl_type_vals
), NHRP_SHTL_TYPE_MASK
,
1136 { &hf_nhrp_hdr_sstl_len
,
1137 { "Length", "nhrp.hdr.sstl.len",
1138 FT_UINT8
, BASE_DEC
, NULL
, NHRP_SHTL_LEN_MASK
,
1142 { &hf_nhrp_src_proto_len
,
1143 { "Source Protocol Len", "nhrp.src.prot.len",
1144 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1147 { &hf_nhrp_dst_proto_len
,
1148 { "Destination Protocol Len", "nhrp.dst.prot.len",
1149 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1153 { "Flags", "nhrp.flags",
1154 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1158 { "Is Router", "nhrp.flag.q",
1159 FT_BOOLEAN
, 16, NULL
, 0x8000,
1163 { "Expected Purge Reply", "nhrp.flag.n",
1164 FT_BOOLEAN
, 16, NULL
, 0x8000,
1168 { "Authoritative", "nhrp.flag.a",
1169 FT_BOOLEAN
, 16, NULL
, 0x4000,
1173 { "Stable Association", "nhrp.flag.d",
1174 FT_BOOLEAN
, 16, NULL
, 0x2000,
1178 { "Uniqueness Bit", "nhrp.flag.u",
1179 FT_BOOLEAN
, 16, NULL
, 0x1000,
1183 { "Uniqueness Bit", "nhrp.flag.u",
1184 FT_BOOLEAN
, 16, NULL
, 0x8000,
1188 { "Stable Binding", "nhrp.flag.s",
1189 FT_BOOLEAN
, 16, NULL
, 0x0800,
1192 { &hf_nhrp_flag_NAT
,
1193 { "Cisco NAT Supported", "nhrp.flag.nat",
1194 FT_BOOLEAN
, 16, NULL
, 0x0002,
1197 { &hf_nhrp_request_id
,
1198 { "Request ID", "nhrp.reqid",
1199 FT_UINT32
, BASE_HEX_DEC
, NULL
, 0x0,
1202 { &hf_nhrp_src_nbma_addr
,
1203 { "Source NBMA Address", "nhrp.src.nbma.addr",
1204 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
1207 { &hf_nhrp_src_nbma_saddr
,
1208 { "Source NBMA Sub Address", "nhrp.src.nbma.saddr",
1209 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1212 { &hf_nhrp_src_prot_addr
,
1213 { "Source Protocol Address", "nhrp.src.prot.addr",
1214 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
1217 { &hf_nhrp_dst_prot_addr
,
1218 { "Destination Protocol Address", "nhrp.dst.prot.addr",
1219 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
1224 { "Code", "nhrp.code",
1225 FT_UINT8
, BASE_DEC
, VALS(nhrp_cie_code_vals
), 0x0,
1228 { &hf_nhrp_prefix_len
,
1229 { "Prefix Length", "nhrp.prefix",
1230 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1234 { "Unused", "nhrp.unused",
1235 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1239 { "Max Transmission Unit", "nhrp.mtu",
1240 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1243 { &hf_nhrp_holding_time
,
1244 { "Holding Time (s)", "nhrp.htime",
1245 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1248 { &hf_nhrp_cli_addr_tl
,
1249 { "Client Address Type/Len", "nhrp.cli.addr_tl",
1250 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1253 { &hf_nhrp_cli_addr_tl_type
,
1254 { "Type", "nhrp.cli.addr_tl.type",
1255 FT_UINT8
, BASE_DEC
, VALS(nhrp_shtl_type_vals
), NHRP_SHTL_TYPE_MASK
,
1258 { &hf_nhrp_cli_addr_tl_len
,
1259 { "Length", "nhrp.cli.addr_tl.len",
1260 FT_UINT8
, BASE_DEC
, NULL
, NHRP_SHTL_LEN_MASK
,
1263 { &hf_nhrp_cli_saddr_tl
,
1264 { "Client Sub Address Type/Len", "nhrp.cli.saddr_tl",
1265 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1268 { &hf_nhrp_cli_saddr_tl_type
,
1269 { "Type", "nhrp.cli.saddr_tl.type",
1270 FT_UINT8
, BASE_DEC
, VALS(nhrp_shtl_type_vals
), NHRP_SHTL_TYPE_MASK
,
1273 { &hf_nhrp_cli_saddr_tl_len
,
1274 { "Length", "nhrp.cli.saddr_tl.len",
1275 FT_UINT8
, BASE_DEC
, NULL
, NHRP_SHTL_LEN_MASK
,
1278 { &hf_nhrp_cli_prot_len
,
1279 { "Client Protocol Length", "nhrp.prot.len",
1280 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1284 { "CIE Preference Value", "nhrp.pref",
1285 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1288 { &hf_nhrp_client_nbma_addr
,
1289 { "Client NBMA Address", "nhrp.client.nbma.addr",
1290 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
1293 { &hf_nhrp_client_nbma_saddr
,
1294 { "Client NBMA Sub Address", "nhrp.client.nbma.saddr",
1295 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1298 { &hf_nhrp_client_prot_addr
,
1299 { "Client Protocol Address", "nhrp.client.prot.addr",
1300 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
1305 { "Compulsory Flag", "nhrp.ext.c",
1306 FT_BOOLEAN
, 16, NULL
, 0x8000,
1309 { &hf_nhrp_ext_type
,
1310 { "Extension Type", "nhrp.ext.type",
1311 FT_UINT16
, BASE_HEX
, VALS(ext_type_vals
), 0x3FFF,
1315 { "Extension length", "nhrp.ext.len",
1316 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1320 { &hf_nhrp_ext_value
,
1321 { "Extension Value", "nhrp.ext.val",
1322 FT_UINT_BYTES
, BASE_NONE
, NULL
, 0x0,
1327 { &hf_nhrp_error_code
,
1328 { "Error Code", "nhrp.err.code",
1329 FT_UINT16
, BASE_DEC
, VALS(nhrp_error_code_vals
), 0x0,
1332 { &hf_nhrp_error_offset
,
1333 { "Error Offset", "nhrp.err.offset",
1334 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1338 { &hf_nhrp_error_packet
,
1339 { "Errored Packet", "nhrp.err.pkt",
1340 FT_UINT_BYTES
, BASE_NONE
, NULL
, 0x0,
1344 { &hf_nhrp_traffic_code
,
1345 { "Traffic Code", "nhrp.tind.code",
1346 FT_UINT16
, BASE_DEC
, VALS(nhrp_traffic_code_vals
), 0x0,
1349 { &hf_nhrp_auth_ext_reserved
,
1350 { "Reserved", "nhrp.auth_ext.reserved",
1351 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1354 { &hf_nhrp_auth_ext_spi
,
1355 { "SPI", "nhrp.auth_ext.spi",
1356 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1357 "Security Parameter Index", HFILL
}
1359 { &hf_nhrp_auth_ext_src_addr
,
1360 { "Source Address", "nhrp.auth_ext.src_addr",
1361 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
1364 { &hf_nhrp_vendor_ext_id
,
1365 { "Vendor ID", "nhrp.vendor_ext.id",
1366 FT_UINT24
, BASE_DEC
, NULL
, 0x0,
1369 { &hf_nhrp_devcap_ext_srccap
,
1370 { "Source Capabilities", "nhrp.devcap_ext.srccap",
1371 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1374 { &hf_nhrp_devcap_ext_srccap_V
,
1375 { "VPN-aware", "nhrp.devcap_ext.srccap.V",
1376 FT_BOOLEAN
, 32, NULL
, 0x00000001,
1379 { &hf_nhrp_devcap_ext_dstcap
,
1380 { "Destination Capabilities", "nhrp.devcap_ext.dstcap",
1381 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1384 { &hf_nhrp_devcap_ext_dstcap_V
,
1385 { "VPN-aware", "nhrp.devcap_ext.dstcap.V",
1386 FT_BOOLEAN
, 32, NULL
, 0x00000001,
1389 { &hf_nhrp_unknown_ext_value
,
1390 { "Extension Value", "nhrp.unknown_ext.value",
1391 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1395 /* Generated from convert_proto_tree_add_text.pl */
1396 { &hf_nhrp_protocol_type
, { "Protocol Type (long form)", "nhrp.protocol_type", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1397 { &hf_nhrp_client_nbma_address_bytes
, { "Client NBMA Address", "nhrp.client.nbma.addr_bytes", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1398 { &hf_nhrp_client_prot_addr_bytes
, { "Client Protocol Address", "nhrp.client.prot.addr_bytes", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1399 { &hf_nhrp_src_nbma_addr_bytes
, { "Source NBMA Address", "nhrp.src.nbma.addr_bytes", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1400 { &hf_nhrp_src_prot_addr_bytes
, { "Source Protocol Address", "nhrp.src.prot.addr_bytes", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1401 { &hf_nhrp_dst_prot_addr_bytes
, { "Destination Protocol Address", "nhrp.dst.prot.addr_byets", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1402 { &hf_nhrp_auth_ext_src_addr_bytes
, { "Source Address", "nhrp.auth_ext.src_addr_bytes", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1403 { &hf_nhrp_auth_data
, { "Data", "nhrp.auth_ext.data", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1404 { &hf_nhrp_vendor_ext_data
, { "Data", "nhrp.vendor_ext.data", FT_BYTES
, BASE_NONE
, NULL
, 0x0, NULL
, HFILL
}},
1407 static int *ett
[] = {
1414 &ett_nhrp_mand_flag
,
1416 &ett_nhrp_cie_cli_addr_tl
,
1417 &ett_nhrp_cie_cli_saddr_tl
,
1418 &ett_nhrp_indication
,
1420 &ett_nhrp_vendor_ext
,
1421 &ett_nhrp_devcap_ext
,
1422 &ett_nhrp_devcap_ext_srccap
,
1423 &ett_nhrp_devcap_ext_dstcap
1426 static ei_register_info ei
[] = {
1427 { &ei_nhrp_hdr_pktsz
, { "nhrp.hdr.pktsz.invalid", PI_MALFORMED
, PI_ERROR
, "Packet length is less than the fixed header length", EXPFILL
}},
1428 { &ei_nhrp_hdr_extoff
, { "nhrp.hdr.extoff.invalid", PI_MALFORMED
, PI_ERROR
, "Extension offset is less than the fixed header length or larger than the packet size", EXPFILL
}},
1429 { &ei_nhrp_hdr_chksum
, { "nhrp.hdr.bad_checksum", PI_CHECKSUM
, PI_ERROR
, "Bad checksum", EXPFILL
}},
1430 { &ei_nhrp_ext_not_allowed
, { "nhrp.ext.not_allowed", PI_MALFORMED
, PI_ERROR
, "Extensions not allowed per RFC2332 section 5.2.7", EXPFILL
}},
1431 { &ei_nhrp_ext_malformed
, { "nhrp.ext.malformed", PI_MALFORMED
, PI_ERROR
, "Incomplete Authentication Extension", EXPFILL
}},
1432 { &ei_nhrp_ext_extra
, { "nhrp.ext.extra", PI_MALFORMED
, PI_ERROR
, "Superfluous data follows End Extension", EXPFILL
}},
1435 module_t
*nhrp_module
;
1436 expert_module_t
* expert_nhrp
;
1438 proto_nhrp
= proto_register_protocol("NBMA Next Hop Resolution Protocol", "NHRP", "nhrp");
1439 proto_register_field_array(proto_nhrp
, hf
, array_length(hf
));
1440 proto_register_subtree_array(ett
, array_length(ett
));
1441 nhrp_module
= prefs_register_protocol(proto_nhrp
, NULL
);
1442 prefs_register_bool_preference(nhrp_module
, "auth_ext_has_addr",
1443 "Authentication Extension data contains the source address",
1444 "Whether the Authentication Extension data contains the source address. "
1445 "Some Cisco IOS implementations forgo this part of RFC2332.",
1446 &pref_auth_ext_has_addr
);
1447 expert_nhrp
= expert_register_protocol(proto_nhrp
);
1448 expert_register_field_array(expert_nhrp
, ei
, array_length(ei
));
1450 nhrp_handle
= register_dissector("nhrp", dissect_nhrp
, proto_nhrp
);
1454 proto_reg_handoff_nhrp(void)
1456 osinl_incl_subdissector_table
= find_dissector_table("osinl.incl");
1457 osinl_excl_subdissector_table
= find_dissector_table("osinl.excl");
1458 ethertype_subdissector_table
= find_dissector_table("ethertype");
1460 dissector_add_uint("ip.proto", IP_PROTO_NARP
, nhrp_handle
);
1461 dissector_add_uint("gre.proto", GRE_NHRP
, nhrp_handle
);
1462 dissector_add_uint("llc.iana_pid", IANA_PID_MARS_NHRP_CONTROL
, nhrp_handle
);
1466 * Editor modelines - https://www.wireshark.org/tools/modelines.html
1471 * indent-tabs-mode: nil
1474 * vi: set shiftwidth=4 tabstop=8 expandtab:
1475 * :indentSize=4:tabSize=8:noTabs=true: