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 */
87 static int hf_nhrp_src_prot_addr
= -1;
88 static int hf_nhrp_dst_prot_addr
= -1;
89 static int hf_nhrp_request_id
= -1;
91 static int hf_nhrp_code
= -1;
92 static int hf_nhrp_prefix_len
= -1;
93 static int hf_nhrp_unused
= -1;
94 static int hf_nhrp_mtu
= -1;
95 static int hf_nhrp_holding_time
= -1;
96 static int hf_nhrp_cli_addr_tl
= -1;
97 static int hf_nhrp_cli_addr_tl_type
= -1;
98 static int hf_nhrp_cli_addr_tl_len
= -1;
99 static int hf_nhrp_cli_saddr_tl
= -1;
100 static int hf_nhrp_cli_saddr_tl_type
= -1;
101 static int hf_nhrp_cli_saddr_tl_len
= -1;
102 static int hf_nhrp_cli_prot_len
= -1;
103 static int hf_nhrp_pref
= -1;
104 static int hf_nhrp_client_nbma_addr
= -1;
105 /* static int hf_nhrp_client_nbma_saddr = -1; */ /* TBD: Not used */
106 static int hf_nhrp_client_prot_addr
= -1;
107 static int hf_nhrp_ext_C
= -1;
108 static int hf_nhrp_ext_type
= -1;
109 static int hf_nhrp_ext_len
= -1;
110 /* static int hf_nhrp_ext_value = -1; */ /* TBD: Not used */
111 static int hf_nhrp_error_code
= -1;
112 static int hf_nhrp_error_offset
= -1;
113 /* static int hf_nhrp_error_packet = -1; */ /* TBD: Not used */
115 static int hf_nhrp_auth_ext_reserved
= -1;
116 static int hf_nhrp_auth_ext_spi
= -1;
117 static int hf_nhrp_auth_ext_src_addr
= -1;
118 static int hf_nhrp_vendor_ext_id
= -1;
119 static int hf_nhrp_devcap_ext_srccap
= -1;
120 static int hf_nhrp_devcap_ext_srccap_V
= -1;
121 static int hf_nhrp_devcap_ext_dstcap
= -1;
122 static int hf_nhrp_devcap_ext_dstcap_V
= -1;
123 static int hf_nhrp_unknown_ext_value
= -1;
125 static gint ett_nhrp
= -1;
126 static gint ett_nhrp_hdr
= -1;
127 static gint ett_nhrp_hdr_shtl
= -1;
128 static gint ett_nhrp_hdr_sstl
= -1;
129 static gint ett_nhrp_mand
= -1;
130 static gint ett_nhrp_ext
= -1;
131 static gint ett_nhrp_mand_flag
= -1;
132 static gint ett_nhrp_cie
= -1;
133 static gint ett_nhrp_cie_cli_addr_tl
= -1;
134 static gint ett_nhrp_cie_cli_saddr_tl
= -1;
135 static gint ett_nhrp_indication
= -1;
136 static gint ett_nhrp_auth_ext
= -1;
137 static gint ett_nhrp_vendor_ext
= -1;
138 static gint ett_nhrp_devcap_ext
= -1;
139 static gint ett_nhrp_devcap_ext_srccap
= -1;
140 static gint ett_nhrp_devcap_ext_dstcap
= -1;
142 static expert_field ei_nhrp_ext_not_allowed
= EI_INIT
;
143 static expert_field ei_nhrp_hdr_extoff
= EI_INIT
;
144 static expert_field ei_nhrp_ext_malformed
= EI_INIT
;
145 static expert_field ei_nhrp_ext_extra
= EI_INIT
;
147 /* NHRP Packet Types */
148 #define NHRP_RESOLUTION_REQ 1
149 #define NHRP_RESOLUTION_REPLY 2
150 #define NHRP_REGISTRATION_REQ 3
151 #define NHRP_REGISTRATION_REPLY 4
152 #define NHRP_PURGE_REQ 5
153 #define NHRP_PURGE_REPLY 6
154 #define NHRP_ERROR_INDICATION 7
155 #define NHRP_TRAFFIC_INDICATION 8
157 /* NHRP Extension Types */
158 #define NHRP_EXT_NULL 0 /* End of Extension */
159 #define NHRP_EXT_RESP_ADDR 3 /* Responder Address Extension */
160 #define NHRP_EXT_FWD_RECORD 4 /* NHRP Forward Transit NHS Record Extension */
161 #define NHRP_EXT_REV_RECORD 5 /* NHRP Reverse Transit NHS Record Extension */
162 #define NHRP_EXT_AUTH 7 /* NHRP Authentication Extension */
163 #define NHRP_EXT_VENDOR_PRIV 8 /* NHRP Vendor Private Extension */
164 #define NHRP_EXT_NAT_ADDRESS 9 /* Cisco NAT Address Extension */
165 #define NHRP_EXT_DEV_CAPABILITIES 9 /* RFC 2735: Device Capabilities Extension */
166 #define NHRP_EXT_MOBILE_AUTH 10 /* RFC 2520: NHRP Mobile NHC Authentication Extension */
168 /* NHRP Error Codes */
169 #define NHRP_ERR_UNRECOGNIZED_EXT 0x0001
170 #define NHRP_ERR_NHRP_LOOP_DETECT 0x0003
171 #define NHRP_ERR_PROT_ADDR_UNREACHABLE 0x0006
172 #define NHRP_ERR_PROT_ERROR 0x0007
173 #define NHRP_ERR_SDU_SIZE_EXCEEDED 0x0008
174 #define NHRP_ERR_INV_EXT 0x0009
175 #define NHRP_ERR_INV_RESOLUTION_REPLY 0x000a
176 #define NHRP_ERR_AUTH_FAILURE 0x000b
177 #define NHRP_ERR_HOP_COUNT_EXCEEDED 0x000f
178 #define NHRP_ERR_VPN_MISMATCH 0x0010 /* RFC 2735 */
179 #define NHRP_ERR_VPN_UNSUPPORTED 0x0011 /* RFC 2735 */
182 #define NHRP_CODE_SUCCESS 0x00
183 #define NHRP_CODE_ADMIN_PROHIBITED 0x04
184 #define NHRP_CODE_INSUFFICIENT_RESOURCES 0x05
185 #define NHRP_CODE_NO_BINDING_EXISTS 0x0c
186 #define NHRP_CODE_NON_UNIQUE_BINDING 0x0d
187 #define NHRP_CODE_ALREADY_REGISTERED 0x0e
189 /* NHRP Subnetwork layer address type/length */
190 #define NHRP_SHTL_TYPE_MASK 0x40
191 #define NHRP_SHTL_LEN_MASK 0x3F
192 #define NHRP_SHTL_TYPE(val) (((val) & (NHRP_SHTL_TYPE_MASK)) >> 6)
193 #define NHRP_SHTL_LEN(val) ((val) & (NHRP_SHTL_LEN_MASK))
195 #define NHRP_SHTL_TYPE_NSAP 0
196 #define NHRP_SHTL_TYPE_E164 1
198 static const value_string nhrp_shtl_type_vals
[] = {
199 { NHRP_SHTL_TYPE_NSAP
, "NSAP format" },
200 { NHRP_SHTL_TYPE_E164
, "Native E.164 format" },
204 static const value_string nhrp_op_type_vals
[] = {
205 { NHRP_RESOLUTION_REQ
, "NHRP Resolution Request" },
206 { NHRP_RESOLUTION_REPLY
, "NHRP Resolution Reply" },
207 { NHRP_REGISTRATION_REQ
, "NHRP Registration Request" },
208 { NHRP_REGISTRATION_REPLY
, "NHRP Registration Reply" },
209 { NHRP_PURGE_REQ
, "NHRP Purge Request" },
210 { NHRP_PURGE_REPLY
, "NHRP Purge Reply" },
211 { NHRP_ERROR_INDICATION
, "NHRP Error Indication" },
212 { NHRP_TRAFFIC_INDICATION
, "NHRP Traffic Indication" },
216 static const value_string ext_type_vals
[] = {
217 { NHRP_EXT_NULL
, "End of Extension" },
218 { NHRP_EXT_RESP_ADDR
, "Responder Address Extension" },
219 { NHRP_EXT_FWD_RECORD
, "Forward Transit NHS Record Extension" },
220 { NHRP_EXT_REV_RECORD
, "Reverse Transit NHS Record Extension" },
221 { NHRP_EXT_AUTH
, "NHRP Authentication Extension" },
222 { NHRP_EXT_VENDOR_PRIV
, "NHRP Vendor Private Extension" },
223 { NHRP_EXT_NAT_ADDRESS
, "Cisco NAT Address Extension" },
224 #if 0 /* Dup (which is handled in the code) */
225 { NHRP_EXT_DEV_CAPABILITIES
,"Device Capabilities Extension" },
227 { NHRP_EXT_MOBILE_AUTH
, "Mobile NHC Authentication Extension" },
231 static const value_string nhrp_error_code_vals
[] = {
232 { NHRP_ERR_UNRECOGNIZED_EXT
, "Unrecognized Extension" },
233 { NHRP_ERR_NHRP_LOOP_DETECT
, "NHRP Loop Detected" },
234 { NHRP_ERR_PROT_ADDR_UNREACHABLE
, "Protocol Address Unreachable" },
235 { NHRP_ERR_PROT_ERROR
, "Protocol Error" },
236 { NHRP_ERR_SDU_SIZE_EXCEEDED
, "NHRP SDU Size Exceeded" },
237 { NHRP_ERR_INV_EXT
, "Invalid Extension" },
238 { NHRP_ERR_INV_RESOLUTION_REPLY
, "Invalid NHRP Resolution Reply Received" },
239 { NHRP_ERR_AUTH_FAILURE
, "Authentication Failure" },
240 { NHRP_ERR_HOP_COUNT_EXCEEDED
, "Hop Count Exceeded" },
241 { NHRP_ERR_VPN_MISMATCH
, "VPN Mismatch" },
242 { NHRP_ERR_VPN_UNSUPPORTED
, "VPN Unsupported" },
246 static const value_string nhrp_cie_code_vals
[] = {
247 { NHRP_CODE_SUCCESS
, "Success" },
248 { NHRP_CODE_ADMIN_PROHIBITED
, "Administratively Prohibited" },
249 { NHRP_CODE_INSUFFICIENT_RESOURCES
, "Insufficient Resources" },
250 { NHRP_CODE_NO_BINDING_EXISTS
, "No Interworking Layer Address to NBMA Address Binding Exists" },
251 { NHRP_CODE_NON_UNIQUE_BINDING
, "Binding Exists But Is Not Unique" },
252 { NHRP_CODE_ALREADY_REGISTERED
, "Unique Internetworking Layer Address Already Registered" },
256 static dissector_table_t osinl_incl_subdissector_table
;
257 static dissector_table_t osinl_excl_subdissector_table
;
258 static dissector_table_t ethertype_subdissector_table
;
260 static dissector_handle_t data_handle
;
262 typedef struct _e_nhrp
{
265 guint32 ar_pro_type_oui
;
266 guint16 ar_pro_type_pid
;
271 guint8 ar_op_version
;
277 static guint16
nhrp_checksum(const guint8
*ptr
, int len
)
281 cksum_vec
[0].ptr
= ptr
;
282 cksum_vec
[0].len
= len
;
283 return in_cksum(&cksum_vec
[0], 1);
286 void dissect_nhrp_hdr(tvbuff_t
*tvb
,
292 oui_info_t
**pOuiInfo
,
295 gint offset
= *pOffset
;
296 const gchar
*pro_type_str
;
297 guint total_len
= tvb_reported_length(tvb
);
298 guint16 ipcsum
, rx_chksum
;
300 proto_item
*nhrp_tree_item
;
301 proto_tree
*nhrp_tree
;
302 proto_item
*shtl_tree_item
;
303 proto_tree
*shtl_tree
;
304 proto_item
*sstl_tree_item
;
305 proto_tree
*sstl_tree
;
308 nhrp_tree_item
= proto_tree_add_text(tree
, tvb
, offset
, 20, "NHRP Fixed Header");
309 nhrp_tree
= proto_item_add_subtree(nhrp_tree_item
, ett_nhrp_hdr
);
311 hdr
->ar_pktsz
= tvb_get_ntohs(tvb
, 10);
312 if (total_len
> hdr
->ar_pktsz
) {
313 total_len
= hdr
->ar_pktsz
;
316 hdr
->ar_afn
= tvb_get_ntohs(tvb
, offset
);
317 proto_tree_add_item(nhrp_tree
, hf_nhrp_hdr_afn
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
320 hdr
->ar_pro_type
= tvb_get_ntohs(tvb
, offset
);
321 if (hdr
->ar_pro_type
<= 0xFF) {
323 pro_type_str
= val_to_str_const(hdr
->ar_pro_type
, nlpid_vals
,
325 } else if (hdr
->ar_pro_type
<= 0x3FF) {
326 /* Reserved for future use by the IETF */
327 pro_type_str
= "Reserved for future use by the IETF";
328 } else if (hdr
->ar_pro_type
<= 0x04FF) {
329 /* Allocated for use by the ATM Forum */
330 pro_type_str
= "Allocated for use by the ATM Forum";
331 } else if (hdr
->ar_pro_type
<= 0x05FF) {
332 /* Experimental/Local use */
333 pro_type_str
= "Experimental/Local use";
335 pro_type_str
= val_to_str_const(hdr
->ar_pro_type
, etype_vals
,
336 "Unknown Ethertype");
338 proto_tree_add_uint_format_value(nhrp_tree
, hf_nhrp_hdr_pro_type
, tvb
, offset
, 2,
339 hdr
->ar_pro_type
, "%s (0x%04x)",
340 pro_type_str
, hdr
->ar_pro_type
);
343 if (hdr
->ar_pro_type
== NLPID_SNAP
) {
345 * The long form protocol type is a SNAP OUI and PID.
347 hdr
->ar_pro_type_oui
= tvb_get_ntoh24(tvb
, offset
);
348 proto_tree_add_uint(nhrp_tree
, hf_nhrp_hdr_pro_snap_oui
,
349 tvb
, offset
, 3, hdr
->ar_pro_type_oui
);
352 hdr
->ar_pro_type_pid
= tvb_get_ntohs(tvb
, offset
);
353 *pOuiInfo
= get_snap_oui_info(hdr
->ar_pro_type_oui
);
354 if (*pOuiInfo
!= NULL
) {
355 proto_tree_add_uint(nhrp_tree
,
356 *(*pOuiInfo
)->field_info
->p_id
,
357 tvb
, offset
, 2, hdr
->ar_pro_type_pid
);
359 proto_tree_add_uint(nhrp_tree
, hf_nhrp_hdr_pro_snap_pid
,
360 tvb
, offset
, 2, hdr
->ar_pro_type_pid
);
364 * XXX - we should check that this is zero, as RFC 2332
365 * says it should be zero.
367 proto_tree_add_text(nhrp_tree
, tvb
, offset
, 5,
368 "Protocol Type (long form): %s",
369 tvb_bytes_to_str(tvb
, offset
, 5));
373 proto_tree_add_item(nhrp_tree
, hf_nhrp_hdr_hopcnt
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
376 proto_tree_add_item(nhrp_tree
, hf_nhrp_hdr_pktsz
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
379 rx_chksum
= tvb_get_ntohs(tvb
, offset
);
380 if (tvb_bytes_exist(tvb
, 0, total_len
)) {
381 ipcsum
= nhrp_checksum(tvb_get_ptr(tvb
, 0, total_len
),
384 proto_tree_add_uint_format_value(nhrp_tree
, hf_nhrp_hdr_chksum
, tvb
, offset
, 2, rx_chksum
,
385 "0x%04x [correct]", rx_chksum
);
387 proto_tree_add_uint_format_value(nhrp_tree
, hf_nhrp_hdr_chksum
, tvb
, offset
, 2, rx_chksum
,
388 "0x%04x [incorrect, should be 0x%04x]", rx_chksum
,
389 in_cksum_shouldbe(rx_chksum
, ipcsum
));
392 proto_tree_add_uint_format_value(nhrp_tree
, hf_nhrp_hdr_chksum
, tvb
, offset
, 2, rx_chksum
,
393 "0x%04x [not all data available]", rx_chksum
);
397 hdr
->ar_extoff
= tvb_get_ntohs(tvb
, offset
);
398 ti
= proto_tree_add_item(nhrp_tree
, hf_nhrp_hdr_extoff
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
399 if (hdr
->ar_extoff
!= 0 && hdr
->ar_extoff
< 20) {
400 expert_add_info(pinfo
, ti
, &ei_nhrp_hdr_extoff
);
404 hdr
->ar_op_version
= tvb_get_guint8(tvb
, offset
);
405 proto_tree_add_uint_format_value(nhrp_tree
, hf_nhrp_hdr_version
, tvb
, offset
, 1,
406 hdr
->ar_op_version
, "%u (%s)", hdr
->ar_op_version
,
407 (hdr
->ar_op_version
== 1) ? "NHRP - rfc2332" : "Unknown");
409 proto_tree_add_item(nhrp_tree
, hf_nhrp_hdr_op_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
412 hdr
->ar_shtl
= tvb_get_guint8(tvb
, offset
);
413 shtl_tree_item
= proto_tree_add_uint_format_value(nhrp_tree
, hf_nhrp_hdr_shtl
,
414 tvb
, offset
, 1, hdr
->ar_shtl
, "%s/%u",
415 val_to_str_const(NHRP_SHTL_TYPE(hdr
->ar_shtl
), nhrp_shtl_type_vals
, "Unknown Type"),
416 NHRP_SHTL_LEN(hdr
->ar_shtl
));
417 shtl_tree
= proto_item_add_subtree(shtl_tree_item
, ett_nhrp_hdr_shtl
);
418 proto_tree_add_item(shtl_tree
, hf_nhrp_hdr_shtl_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
419 proto_tree_add_item(shtl_tree
, hf_nhrp_hdr_shtl_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
422 hdr
->ar_sstl
= tvb_get_guint8(tvb
, offset
);
423 sstl_tree_item
= proto_tree_add_uint_format_value(nhrp_tree
, hf_nhrp_hdr_sstl
,
424 tvb
, offset
, 1, hdr
->ar_sstl
, "%s/%u",
425 val_to_str_const(NHRP_SHTL_TYPE(hdr
->ar_sstl
), nhrp_shtl_type_vals
, "Unknown Type"),
426 NHRP_SHTL_LEN(hdr
->ar_sstl
));
427 sstl_tree
= proto_item_add_subtree(sstl_tree_item
, ett_nhrp_hdr_sstl
);
428 proto_tree_add_item(sstl_tree
, hf_nhrp_hdr_sstl_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
429 proto_tree_add_item(sstl_tree
, hf_nhrp_hdr_sstl_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
433 if (hdr
->ar_extoff
!= 0) {
434 if (hdr
->ar_extoff
>= 20) {
435 *pMandLen
= hdr
->ar_extoff
- 20;
436 *pExtLen
= total_len
- hdr
->ar_extoff
;
445 *pMandLen
= total_len
- 20;
447 /* "Can't happen" - we would have thrown an exception */
454 void dissect_cie_list(tvbuff_t
*tvb
,
463 proto_item
*cli_addr_tree_item
;
464 proto_tree
*cli_addr_tree
;
465 proto_item
*cli_saddr_tree_item
;
466 proto_tree
*cli_saddr_tree
;
469 while ((offset
+ 12) <= cieEnd
) {
470 guint cli_addr_len
= tvb_get_guint8(tvb
, offset
+ 8);
471 guint cli_saddr_len
= tvb_get_guint8(tvb
, offset
+ 9);
472 guint cli_prot_len
= tvb_get_guint8(tvb
, offset
+ 10);
473 guint cie_len
= 12 + cli_addr_len
+ cli_saddr_len
+ cli_prot_len
;
474 proto_item
*cie_tree_item
= proto_tree_add_text(tree
, tvb
, offset
, cie_len
, "Client Information Entry");
475 proto_tree
*cie_tree
= proto_item_add_subtree(cie_tree_item
, ett_nhrp_cie
);
478 proto_tree_add_item(cie_tree
, hf_nhrp_code
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
481 guint8 code
= tvb_get_guint8(tvb
, offset
);
483 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", Code=%s",
484 val_to_str(code
, nhrp_cie_code_vals
, "Unknown (%u)"));
486 proto_tree_add_text(cie_tree
, tvb
, offset
, 1, "Code: %s",
487 val_to_str(code
, nhrp_cie_code_vals
, "Unknown (%u)"));
491 proto_tree_add_item(cie_tree
, hf_nhrp_prefix_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
494 proto_tree_add_item(cie_tree
, hf_nhrp_unused
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
497 proto_tree_add_item(cie_tree
, hf_nhrp_mtu
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
500 proto_tree_add_item(cie_tree
, hf_nhrp_holding_time
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
503 val
= tvb_get_guint8(tvb
, offset
);
504 cli_addr_tree_item
= proto_tree_add_uint_format_value(cie_tree
,
505 hf_nhrp_cli_addr_tl
, tvb
, offset
, 1, val
, "%s/%u",
506 val_to_str_const(NHRP_SHTL_TYPE(val
), nhrp_shtl_type_vals
, "Unknown Type"),
508 cli_addr_tree
= proto_item_add_subtree(cli_addr_tree_item
, ett_nhrp_cie_cli_addr_tl
);
509 proto_tree_add_item(cli_addr_tree
, hf_nhrp_cli_addr_tl_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
510 proto_tree_add_item(cli_addr_tree
, hf_nhrp_cli_addr_tl_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
513 val
= tvb_get_guint8(tvb
, offset
);
514 cli_saddr_tree_item
= proto_tree_add_uint_format_value(cie_tree
,
515 hf_nhrp_cli_saddr_tl
, tvb
, offset
, 1, val
, "%s/%u",
516 val_to_str_const(NHRP_SHTL_TYPE(val
), nhrp_shtl_type_vals
, "Unknown Type"),
518 cli_saddr_tree
= proto_item_add_subtree(cli_saddr_tree_item
, ett_nhrp_cie_cli_saddr_tl
);
519 proto_tree_add_item(cli_saddr_tree
, hf_nhrp_cli_saddr_tl_type
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
520 proto_tree_add_item(cli_saddr_tree
, hf_nhrp_cli_saddr_tl_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
523 proto_tree_add_item(cie_tree
, hf_nhrp_cli_prot_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
526 proto_tree_add_item(cie_tree
, hf_nhrp_pref
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
530 switch (hdr
->ar_afn
) {
533 if (cli_addr_len
== 4)
534 proto_tree_add_item(cie_tree
, hf_nhrp_client_nbma_addr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
536 proto_tree_add_text(cie_tree
, tvb
, offset
, cli_addr_len
,
537 "Client NBMA Address: %s",
538 tvb_bytes_to_str(tvb
, offset
, cli_addr_len
));
543 proto_tree_add_text(cie_tree
, tvb
, offset
, cli_addr_len
,
544 "Client NBMA Address: %s",
545 tvb_bytes_to_str(tvb
, offset
, cli_addr_len
));
548 offset
+= cli_addr_len
;
552 proto_tree_add_text(cie_tree
, tvb
, offset
, cli_saddr_len
,
553 "Client NBMA Sub Address: %s",
554 tvb_bytes_to_str(tvb
, offset
, cli_saddr_len
));
558 if (cli_prot_len
== 4)
559 proto_tree_add_item(cie_tree
, hf_nhrp_client_prot_addr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
561 proto_tree_add_text(cie_tree
, tvb
, offset
, cli_prot_len
,
562 "Client Protocol Address: %s",
563 tvb_bytes_to_str(tvb
, offset
, cli_prot_len
));
565 offset
+= cli_prot_len
;
570 void dissect_nhrp_mand(tvbuff_t
*tvb
,
575 oui_info_t
*oui_info
,
580 gint offset
= *pOffset
;
581 gint mandEnd
= offset
+ mandLen
;
585 gboolean isReq
= FALSE
;
586 gboolean isErr
= FALSE
;
587 gboolean isInd
= FALSE
;
589 proto_item
*nhrp_tree_item
;
590 proto_tree
*nhrp_tree
;
592 tvb_ensure_bytes_exist(tvb
, offset
, mandLen
);
594 switch (hdr
->ar_op_type
)
596 case NHRP_RESOLUTION_REPLY
:
597 case NHRP_REGISTRATION_REPLY
:
598 case NHRP_PURGE_REPLY
:
600 case NHRP_RESOLUTION_REQ
:
601 case NHRP_REGISTRATION_REQ
:
605 case NHRP_ERROR_INDICATION
: /* This needs special treatment */
609 case NHRP_TRAFFIC_INDICATION
:
613 nhrp_tree_item
= proto_tree_add_text(tree
, tvb
, offset
, mandLen
, "NHRP Mandatory Part");
614 nhrp_tree
= proto_item_add_subtree(nhrp_tree_item
, ett_nhrp_mand
);
616 *srcLen
= tvb_get_guint8(tvb
, offset
);
617 proto_tree_add_item(nhrp_tree
, hf_nhrp_src_proto_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
620 dstLen
= tvb_get_guint8(tvb
, offset
);
621 proto_tree_add_item(nhrp_tree
, hf_nhrp_dst_proto_len
, tvb
, offset
, 1, ENC_BIG_ENDIAN
);
625 proto_item
*flag_item
;
626 proto_tree
*flag_tree
;
627 flags
= tvb_get_ntohs(tvb
, offset
);
628 flag_item
= proto_tree_add_uint(nhrp_tree
, hf_nhrp_flags
, tvb
, offset
, 2, flags
);
629 flag_tree
= proto_item_add_subtree(flag_item
, ett_nhrp_mand_flag
);
631 switch (hdr
->ar_op_type
)
633 case NHRP_RESOLUTION_REQ
:
634 case NHRP_RESOLUTION_REPLY
:
635 proto_tree_add_boolean(flag_tree
, hf_nhrp_flag_Q
, tvb
, offset
, 2, flags
);
636 proto_tree_add_boolean(flag_tree
, hf_nhrp_flag_A
, tvb
, offset
, 2, flags
);
637 proto_tree_add_boolean(flag_tree
, hf_nhrp_flag_D
, tvb
, offset
, 2, flags
);
638 proto_tree_add_boolean(flag_tree
, hf_nhrp_flag_U1
, tvb
, offset
, 2, flags
);
639 proto_tree_add_boolean(flag_tree
, hf_nhrp_flag_S
, tvb
, offset
, 2, flags
);
641 case NHRP_REGISTRATION_REQ
:
642 case NHRP_REGISTRATION_REPLY
:
643 proto_tree_add_boolean(flag_tree
, hf_nhrp_flag_U2
, tvb
, offset
, 2, flags
);
647 case NHRP_PURGE_REPLY
:
648 proto_tree_add_boolean(flag_tree
, hf_nhrp_flag_N
, tvb
, offset
, 2, flags
);
651 proto_tree_add_boolean(flag_tree
, hf_nhrp_flag_NAT
, tvb
, offset
, 2, flags
);
655 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", ID=%u", tvb_get_ntohl(tvb
, offset
));
656 proto_tree_add_item(nhrp_tree
, hf_nhrp_request_id
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
662 col_append_fstr(pinfo
->cinfo
, COL_INFO
, ", %s",
663 val_to_str(tvb_get_ntohs(tvb
, offset
), nhrp_error_code_vals
, "Unknown Error (%u)"));
664 proto_tree_add_item(nhrp_tree
, hf_nhrp_error_code
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
667 proto_tree_add_item(nhrp_tree
, hf_nhrp_error_offset
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
674 shl
= NHRP_SHTL_LEN(hdr
->ar_shtl
);
676 switch (hdr
->ar_afn
) {
680 proto_tree_add_item(nhrp_tree
, hf_nhrp_src_nbma_addr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
682 proto_tree_add_text(nhrp_tree
, tvb
, offset
, shl
,
683 "Source NBMA Address: %s",
684 tvb_bytes_to_str(tvb
, offset
, shl
));
689 proto_tree_add_text(nhrp_tree
, tvb
, offset
, shl
,
690 "Source NBMA Address: %s",
691 tvb_bytes_to_str(tvb
, offset
, shl
));
697 ssl
= NHRP_SHTL_LEN(hdr
->ar_sstl
);
699 proto_tree_add_text(nhrp_tree
, tvb
, offset
, ssl
,
700 "Source NBMA Sub Address: %s",
701 tvb_bytes_to_str(tvb
, offset
, ssl
));
706 proto_tree_add_item(nhrp_tree
, hf_nhrp_src_prot_addr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
710 proto_tree_add_text(nhrp_tree
, tvb
, offset
, *srcLen
,
711 "Source Protocol Address: %s",
712 tvb_bytes_to_str(tvb
, offset
, *srcLen
));
717 proto_tree_add_item(nhrp_tree
, hf_nhrp_dst_prot_addr
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
721 proto_tree_add_text(nhrp_tree
, tvb
, offset
, dstLen
,
722 "Destination Protocol Address: %s",
723 tvb_bytes_to_str(tvb
, offset
, dstLen
));
728 gboolean save_in_error_pkt
;
729 gint pkt_len
= mandEnd
- offset
;
730 proto_item
*ind_tree_item
= proto_tree_add_text(tree
, tvb
, offset
, pkt_len
, "Packet Causing Indication");
731 proto_tree
*ind_tree
= proto_item_add_subtree(ind_tree_item
, ett_nhrp_indication
);
735 save_in_error_pkt
= pinfo
->flags
.in_error_pkt
;
736 pinfo
->flags
.in_error_pkt
= TRUE
;
737 sub_tvb
= tvb_new_subset_remaining(tvb
, offset
);
739 _dissect_nhrp(sub_tvb
, pinfo
, ind_tree
, TRUE
, FALSE
);
742 if (hdr
->ar_pro_type
<= 0xFF) {
744 if (hdr
->ar_pro_type
== NLPID_SNAP
) {
746 * Dissect based on the SNAP OUI
749 if (hdr
->ar_pro_type_oui
== 0x000000) {
751 * "Should not happen", as
752 * the protocol type should
753 * be the Ethertype, but....
755 dissected
= dissector_try_uint(
756 ethertype_subdissector_table
,
757 hdr
->ar_pro_type_pid
,
758 sub_tvb
, pinfo
, ind_tree
);
761 * If we have a dissector
762 * table, use it, otherwise
763 * just dissect as data.
765 if (oui_info
!= NULL
) {
766 dissected
= dissector_try_uint(
768 hdr
->ar_pro_type_pid
,
776 * Dissect based on the NLPID.
778 dissected
= dissector_try_uint(
779 osinl_incl_subdissector_table
,
780 hdr
->ar_pro_type
, sub_tvb
, pinfo
,
783 osinl_excl_subdissector_table
,
784 hdr
->ar_pro_type
, sub_tvb
, pinfo
,
787 } else if (hdr
->ar_pro_type
<= 0x3FF) {
788 /* Reserved for future use by the IETF */
790 } else if (hdr
->ar_pro_type
<= 0x04FF) {
791 /* Allocated for use by the ATM Forum */
793 } else if (hdr
->ar_pro_type
<= 0x05FF) {
794 /* Experimental/Local use */
797 dissected
= dissector_try_uint(
798 ethertype_subdissector_table
,
799 hdr
->ar_pro_type
, sub_tvb
, pinfo
, ind_tree
);
802 call_dissector(data_handle
, sub_tvb
, pinfo
,
806 pinfo
->flags
.in_error_pkt
= save_in_error_pkt
;
810 /* According to RFC 2332, section 5.2.7, there shouldn't be any extensions
811 * in the Error Indication packet. */
812 if (isErr
&& tvb_reported_length_remaining(tvb
, offset
)) {
813 expert_add_info(pinfo
, tree
, &ei_nhrp_ext_not_allowed
);
816 dissect_cie_list(tvb
, pinfo
, nhrp_tree
, offset
, mandEnd
, hdr
, isReq
, codeinfo
);
821 void dissect_nhrp_ext(tvbuff_t
*tvb
,
830 gint offset
= *pOffset
;
831 gint extEnd
= offset
+ extLen
;
835 tvb_ensure_bytes_exist(tvb
, offset
, extLen
);
837 while ((offset
+ 4) <= extEnd
)
839 proto_item
*nhrp_tree_item
;
840 proto_tree
*nhrp_tree
;
841 gint extTypeC
= tvb_get_ntohs(tvb
, offset
);
842 gint extType
= extTypeC
& 0x3FFF;
843 guint len
= tvb_get_ntohs(tvb
, offset
+2);
845 if ((extType
== NHRP_EXT_NAT_ADDRESS
) && (len
== 8)) {
846 /* Assume it's not really a Cisco NAT extension, but a device
847 * capabilities extension instead (see RFC 2735). */
848 nhrp_tree_item
= proto_tree_add_text(tree
, tvb
, offset
,
849 len
+ 4, "Device Capabilities Extension");
852 nhrp_tree_item
= proto_tree_add_text(tree
, tvb
, offset
,
854 val_to_str(extType
, ext_type_vals
, "Unknown (%u)"));
856 nhrp_tree
= proto_item_add_subtree(nhrp_tree_item
, ett_nhrp_ext
);
857 proto_tree_add_boolean(nhrp_tree
, hf_nhrp_ext_C
, tvb
, offset
, 2, extTypeC
);
858 proto_tree_add_item(nhrp_tree
, hf_nhrp_ext_type
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
861 proto_tree_add_item(nhrp_tree
, hf_nhrp_ext_len
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
864 if (len
&& (extType
!= NHRP_EXT_NULL
)) {
865 tvb_ensure_bytes_exist(tvb
, offset
, len
);
866 if ((extType
== NHRP_EXT_NAT_ADDRESS
) && (len
== 8)) {
867 /* Assume it's not really a Cisco NAT extension, but a device
868 * capabilities extension instead (see RFC 2735). */
869 proto_item
*devcap_item
;
870 proto_tree
*devcap_tree
;
871 proto_item
*cap_item
;
872 proto_tree
*cap_tree
;
874 devcap_item
= proto_tree_add_text(nhrp_tree
, tvb
, offset
, len
,
875 "Extension Data: Src is %sVPN-aware; Dst is %sVPN-aware",
876 tvb_get_ntohl(tvb
, offset
) & 1 ? "" : "non-",
877 tvb_get_ntohl(tvb
, offset
+ 4) & 1 ? "" : "non-");
878 devcap_tree
= proto_item_add_subtree(devcap_item
, ett_nhrp_devcap_ext
);
879 cap_item
= proto_tree_add_item(devcap_tree
, hf_nhrp_devcap_ext_srccap
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
880 cap_tree
= proto_item_add_subtree(cap_item
, ett_nhrp_devcap_ext_srccap
);
881 proto_tree_add_item(cap_tree
, hf_nhrp_devcap_ext_srccap_V
, tvb
, offset
, 4, ENC_BIG_ENDIAN
);
883 cap_item
= proto_tree_add_item(devcap_tree
, hf_nhrp_devcap_ext_dstcap
, tvb
, offset
+ 4, 4, ENC_BIG_ENDIAN
);
884 cap_tree
= proto_item_add_subtree(cap_item
, ett_nhrp_devcap_ext_dstcap
);
885 proto_tree_add_item(cap_tree
, hf_nhrp_devcap_ext_dstcap_V
, tvb
, offset
+ 4, 4, ENC_BIG_ENDIAN
);
890 case NHRP_EXT_RESP_ADDR
:
891 case NHRP_EXT_FWD_RECORD
:
892 case NHRP_EXT_REV_RECORD
:
893 case NHRP_EXT_NAT_ADDRESS
:
894 dissect_cie_list(tvb
, pinfo
, nhrp_tree
,
895 offset
, offset
+ len
, hdr
, 0, FALSE
);
899 case NHRP_EXT_MOBILE_AUTH
:
900 if (len
< (4 + srcLen
)) {
901 ti
= proto_tree_add_text(nhrp_tree
, tvb
, offset
, len
,
902 "Malformed Extension: %s",
903 tvb_bytes_to_str(tvb
, offset
, len
));
904 expert_add_info_format(pinfo
, ti
, &ei_nhrp_ext_malformed
, "Incomplete Authentication Extension");
907 proto_item
*auth_item
;
908 proto_tree
*auth_tree
;
910 auth_item
= proto_tree_add_text(nhrp_tree
, tvb
, offset
, len
,
911 "Extension Data: SPI=%u: Data=%s", tvb_get_ntohs(tvb
, offset
+ 2),
912 tvb_bytes_to_str(tvb
, offset
+ 4, len
- 4));
913 auth_tree
= proto_item_add_subtree(auth_item
, ett_nhrp_auth_ext
);
914 proto_tree_add_item(auth_tree
, hf_nhrp_auth_ext_reserved
, tvb
, offset
, 2, ENC_BIG_ENDIAN
);
915 proto_tree_add_item(auth_tree
, hf_nhrp_auth_ext_spi
, tvb
, offset
+ 2, 2, ENC_BIG_ENDIAN
);
917 proto_tree_add_item(auth_tree
, hf_nhrp_auth_ext_src_addr
, tvb
, offset
+ 4, 4, ENC_BIG_ENDIAN
);
919 proto_tree_add_text(auth_tree
, tvb
, offset
+ 4, srcLen
,
920 "Source Address: %s",
921 tvb_bytes_to_str(tvb
, offset
+ 4, srcLen
));
923 if (len
> (4 + srcLen
)) {
924 proto_tree_add_text(auth_tree
, tvb
, offset
+ 4 + srcLen
, len
- (4 + srcLen
),
925 "Data: %s", tvb_bytes_to_str(tvb
, offset
+ 4 + srcLen
, len
- (4 + srcLen
)));
930 case NHRP_EXT_VENDOR_PRIV
:
932 ti
= proto_tree_add_text(nhrp_tree
, tvb
, offset
, len
,
933 "Malformed Extension: %s",
934 tvb_bytes_to_str(tvb
, offset
, len
));
935 expert_add_info_format(pinfo
, ti
, &ei_nhrp_ext_malformed
, "Incomplete Vendor-Private Extension");
938 proto_item
*vendor_item
;
939 proto_tree
*vendor_tree
;
942 tvb_memcpy(tvb
, manuf
, offset
, 3);
943 vendor_item
= proto_tree_add_text(nhrp_tree
, tvb
, offset
, len
,
944 "Extension Data: Vendor ID=%s, Data=%s", get_manuf_name(manuf
),
945 tvb_bytes_to_str(tvb
, offset
+ 3, len
- 3));
946 vendor_tree
= proto_item_add_subtree(vendor_item
, ett_nhrp_vendor_ext
);
947 proto_tree_add_bytes_format_value(vendor_tree
, hf_nhrp_vendor_ext_id
, tvb
,
948 offset
, 3, manuf
, "%s", get_manuf_name(manuf
));
950 proto_tree_add_text(vendor_tree
, tvb
, offset
+ 3, len
- 3,
951 "Data: %s", tvb_bytes_to_str(tvb
, offset
+ 3, len
- 3));
957 proto_tree_add_item(nhrp_tree
, hf_nhrp_unknown_ext_value
, tvb
,
958 offset
, len
, ENC_NA
);
966 len
= tvb_reported_length_remaining(tvb
, offset
);
967 if ((extType
== NHRP_EXT_NULL
) && len
) {
968 ti
= proto_tree_add_text(tree
, tvb
, offset
, len
,
969 "Unknown Data (%d bytes)", len
);
970 expert_add_info(pinfo
, ti
, &ei_nhrp_ext_extra
);
979 void dissect_nhrp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
981 _dissect_nhrp(tvb
, pinfo
, tree
, FALSE
, TRUE
);
984 static void _dissect_nhrp(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
985 gboolean nested
, gboolean codeinfo
)
992 proto_tree
*nhrp_tree
;
993 oui_info_t
*oui_info
= NULL
;
997 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "NHRP");
998 col_clear(pinfo
->cinfo
, COL_INFO
);
1001 memset(&hdr
, 0, sizeof(e_nhrp_hdr
));
1002 hdr
.ar_op_type
= tvb_get_guint8(tvb
, 17);
1005 col_add_str(pinfo
->cinfo
, COL_INFO
,
1006 val_to_str(hdr
.ar_op_type
, nhrp_op_type_vals
,
1007 "0x%02X - unknown"));
1010 ti
= proto_tree_add_protocol_format(tree
, proto_nhrp
, tvb
, 0, -1,
1011 "Next Hop Resolution Protocol (%s)",
1012 val_to_str(hdr
.ar_op_type
, nhrp_op_type_vals
, "0x%02X - unknown"));
1013 nhrp_tree
= proto_item_add_subtree(ti
, ett_nhrp
);
1015 dissect_nhrp_hdr(tvb
, pinfo
, nhrp_tree
, &offset
, &mandLen
, &extLen
,
1018 dissect_nhrp_mand(tvb
, pinfo
, nhrp_tree
, &offset
, mandLen
,
1019 oui_info
, &hdr
, &srcLen
, codeinfo
);
1023 dissect_nhrp_ext(tvb
, pinfo
, nhrp_tree
, &offset
, extLen
, &hdr
, srcLen
, nested
);
1028 proto_register_nhrp(void)
1030 static hf_register_info hf
[] = {
1033 { "Address Family Number", "nhrp.hdr.afn",
1034 FT_UINT16
, BASE_HEX_DEC
, VALS(afn_vals
), 0x0,
1037 { &hf_nhrp_hdr_pro_type
,
1038 { "Protocol Type (short form)", "nhrp.hdr.pro.type",
1039 FT_UINT16
, BASE_HEX_DEC
, NULL
, 0x0,
1042 { &hf_nhrp_hdr_pro_snap_oui
,
1043 { "Protocol Type (long form) - OUI", "nhrp.hdr.pro.snap.oui",
1044 FT_UINT24
, BASE_HEX
, VALS(oui_vals
), 0x0,
1047 { &hf_nhrp_hdr_pro_snap_pid
,
1048 { "Protocol Type (long form) - PID", "nhrp.hdr.pro.snap.pid",
1049 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1052 { &hf_nhrp_hdr_hopcnt
,
1053 { "Hop Count", "nhrp.hdr.hopcnt",
1054 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1057 { &hf_nhrp_hdr_pktsz
,
1058 { "Packet Length", "nhrp.hdr.pktsz",
1059 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1062 { &hf_nhrp_hdr_chksum
,
1063 { "NHRP Packet Checksum", "nhrp.hdr.chksum",
1064 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1067 { &hf_nhrp_hdr_extoff
,
1068 { "Extension Offset", "nhrp.hdr.extoff",
1069 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1072 { &hf_nhrp_hdr_version
,
1073 { "Version", "nhrp.hdr.version",
1074 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1077 { &hf_nhrp_hdr_op_type
,
1078 { "NHRP Packet Type", "nhrp.hdr.op.type",
1079 FT_UINT8
, BASE_DEC
, VALS(nhrp_op_type_vals
), 0x0,
1082 { &hf_nhrp_hdr_shtl
,
1083 { "Source Address Type/Len", "nhrp.hdr.shtl",
1084 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1087 { &hf_nhrp_hdr_shtl_type
,
1088 { "Type", "nhrp.hdr.shtl.type",
1089 FT_UINT8
, BASE_DEC
, VALS(nhrp_shtl_type_vals
), NHRP_SHTL_TYPE_MASK
,
1092 { &hf_nhrp_hdr_shtl_len
,
1093 { "Length", "nhrp.hdr.shtl.len",
1094 FT_UINT8
, BASE_DEC
, NULL
, NHRP_SHTL_LEN_MASK
,
1097 { &hf_nhrp_hdr_sstl
,
1098 { "Source SubAddress Type/Len", "nhrp.hdr.sstl",
1099 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1102 { &hf_nhrp_hdr_sstl_type
,
1103 { "Type", "nhrp.hdr.sstl.type",
1104 FT_UINT8
, BASE_DEC
, VALS(nhrp_shtl_type_vals
), NHRP_SHTL_TYPE_MASK
,
1107 { &hf_nhrp_hdr_sstl_len
,
1108 { "Length", "nhrp.hdr.sstl.len",
1109 FT_UINT8
, BASE_DEC
, NULL
, NHRP_SHTL_LEN_MASK
,
1113 { &hf_nhrp_src_proto_len
,
1114 { "Source Protocol Len", "nhrp.src.prot.len",
1115 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1118 { &hf_nhrp_dst_proto_len
,
1119 { "Destination Protocol Len", "nhrp.dst.prot.len",
1120 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1124 { "Flags", "nhrp.flags",
1125 FT_UINT16
, BASE_HEX
, NULL
, 0x0,
1129 { "Is Router", "nhrp.flag.q",
1130 FT_BOOLEAN
, 16, NULL
, 0x8000,
1134 { "Expected Purge Reply", "nhrp.flag.n",
1135 FT_BOOLEAN
, 16, NULL
, 0x8000,
1139 { "Authoritative", "nhrp.flag.a",
1140 FT_BOOLEAN
, 16, NULL
, 0x4000,
1144 { "Stable Association", "nhrp.flag.d",
1145 FT_BOOLEAN
, 16, NULL
, 0x2000,
1149 { "Uniqueness Bit", "nhrp.flag.u",
1150 FT_BOOLEAN
, 16, NULL
, 0x1000,
1154 { "Uniqueness Bit", "nhrp.flag.u",
1155 FT_BOOLEAN
, 16, NULL
, 0x8000,
1159 { "Stable Binding", "nhrp.flag.s",
1160 FT_BOOLEAN
, 16, NULL
, 0x0800,
1163 { &hf_nhrp_flag_NAT
,
1164 { "Cisco NAT Supported", "nhrp.flag.nat",
1165 FT_BOOLEAN
, 16, NULL
, 0x0002,
1168 { &hf_nhrp_request_id
,
1169 { "Request ID", "nhrp.reqid",
1170 FT_UINT32
, BASE_HEX_DEC
, NULL
, 0x0,
1173 { &hf_nhrp_src_nbma_addr
,
1174 { "Source NBMA Address", "nhrp.src.nbma.addr",
1175 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
1179 { &hf_nhrp_src_nbma_saddr
,
1180 { "Source NBMA Sub Address", "nhrp.src.nbma.saddr",
1181 FT_UINT_BYTES
, BASE_NONE
, NULL
, 0x0,
1185 { &hf_nhrp_src_prot_addr
,
1186 { "Source Protocol Address", "nhrp.src.prot.addr",
1187 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
1190 { &hf_nhrp_dst_prot_addr
,
1191 { "Destination Protocol Address", "nhrp.dst.prot.addr",
1192 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
1197 { "Code", "nhrp.code",
1198 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1201 { &hf_nhrp_prefix_len
,
1202 { "Prefix Length", "nhrp.prefix",
1203 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1207 { "Unused", "nhrp.unused",
1208 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1212 { "Max Transmission Unit", "nhrp.mtu",
1213 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1216 { &hf_nhrp_holding_time
,
1217 { "Holding Time (s)", "nhrp.htime",
1218 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1221 { &hf_nhrp_cli_addr_tl
,
1222 { "Client Address Type/Len", "nhrp.cli.addr_tl",
1223 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1226 { &hf_nhrp_cli_addr_tl_type
,
1227 { "Type", "nhrp.cli.addr_tl.type",
1228 FT_UINT8
, BASE_DEC
, VALS(nhrp_shtl_type_vals
), NHRP_SHTL_TYPE_MASK
,
1231 { &hf_nhrp_cli_addr_tl_len
,
1232 { "Length", "nhrp.cli.addr_tl.len",
1233 FT_UINT8
, BASE_DEC
, NULL
, NHRP_SHTL_LEN_MASK
,
1236 { &hf_nhrp_cli_saddr_tl
,
1237 { "Client Sub Address Type/Len", "nhrp.cli.saddr_tl",
1238 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1241 { &hf_nhrp_cli_saddr_tl_type
,
1242 { "Type", "nhrp.cli.saddr_tl.type",
1243 FT_UINT8
, BASE_DEC
, VALS(nhrp_shtl_type_vals
), NHRP_SHTL_TYPE_MASK
,
1246 { &hf_nhrp_cli_saddr_tl_len
,
1247 { "Length", "nhrp.cli.saddr_tl.len",
1248 FT_UINT8
, BASE_DEC
, NULL
, NHRP_SHTL_LEN_MASK
,
1251 { &hf_nhrp_cli_prot_len
,
1252 { "Client Protocol Length", "nhrp.prot.len",
1253 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1257 { "CIE Preference Value", "nhrp.pref",
1258 FT_UINT8
, BASE_DEC
, NULL
, 0x0,
1261 { &hf_nhrp_client_nbma_addr
,
1262 { "Client NBMA Address", "nhrp.client.nbma.addr",
1263 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
1267 { &hf_nhrp_client_nbma_saddr
,
1268 { "Client NBMA Sub Address", "nhrp.client.nbma.saddr",
1269 FT_UINT_BYTES
, BASE_NONE
, NULL
, 0x0,
1273 { &hf_nhrp_client_prot_addr
,
1274 { "Client Protocol Address", "nhrp.client.prot.addr",
1275 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
1280 { "Compulsory Flag", "nhrp.ext.c",
1281 FT_BOOLEAN
, 16, NULL
, 0x8000,
1284 { &hf_nhrp_ext_type
,
1285 { "Extension Type", "nhrp.ext.type",
1286 FT_UINT16
, BASE_HEX
, NULL
, 0x3FFF,
1290 { "Extension length", "nhrp.ext.len",
1291 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1295 { &hf_nhrp_ext_value
,
1296 { "Extension Value", "nhrp.ext.val",
1297 FT_UINT_BYTES
, BASE_NONE
, NULL
, 0x0,
1302 { &hf_nhrp_error_code
,
1303 { "Error Code", "nhrp.err.code",
1304 FT_UINT16
, BASE_DEC
, VALS(nhrp_error_code_vals
), 0x0,
1307 { &hf_nhrp_error_offset
,
1308 { "Error Offset", "nhrp.err.offset",
1309 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1313 { &hf_nhrp_error_packet
,
1314 { "Errored Packet", "nhrp.err.pkt",
1315 FT_UINT_BYTES
, BASE_NONE
, NULL
, 0x0,
1319 { &hf_nhrp_auth_ext_reserved
,
1320 { "Reserved", "nhrp.auth_ext.reserved",
1321 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1324 { &hf_nhrp_auth_ext_spi
,
1325 { "SPI", "nhrp.auth_ext.spi",
1326 FT_UINT16
, BASE_DEC
, NULL
, 0x0,
1327 "Security Parameter Index", HFILL
}
1329 { &hf_nhrp_auth_ext_src_addr
,
1330 { "Source Address", "nhrp.auth_ext.src_addr",
1331 FT_IPv4
, BASE_NONE
, NULL
, 0x0,
1334 { &hf_nhrp_vendor_ext_id
,
1335 { "Vendor ID", "nhrp.vendor_ext.id",
1336 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1339 { &hf_nhrp_devcap_ext_srccap
,
1340 { "Source Capabilities", "nhrp.devcap_ext.srccap",
1341 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1344 { &hf_nhrp_devcap_ext_srccap_V
,
1345 { "VPN-aware", "nhrp.devcap_ext.srccap.V",
1346 FT_BOOLEAN
, 32, NULL
, 0x00000001,
1349 { &hf_nhrp_devcap_ext_dstcap
,
1350 { "Destination Capabilities", "nhrp.devcap_ext.dstcap",
1351 FT_UINT32
, BASE_HEX
, NULL
, 0x0,
1354 { &hf_nhrp_devcap_ext_dstcap_V
,
1355 { "VPN-aware", "nhrp.devcap_ext.dstcap.V",
1356 FT_BOOLEAN
, 32, NULL
, 0x00000001,
1359 { &hf_nhrp_unknown_ext_value
,
1360 { "Extension Value", "nhrp.unknown_ext.value",
1361 FT_BYTES
, BASE_NONE
, NULL
, 0x0,
1366 static gint
*ett
[] = {
1373 &ett_nhrp_mand_flag
,
1375 &ett_nhrp_cie_cli_addr_tl
,
1376 &ett_nhrp_cie_cli_saddr_tl
,
1377 &ett_nhrp_indication
,
1379 &ett_nhrp_vendor_ext
,
1380 &ett_nhrp_devcap_ext
,
1381 &ett_nhrp_devcap_ext_srccap
,
1382 &ett_nhrp_devcap_ext_dstcap
1385 static ei_register_info ei
[] = {
1386 { &ei_nhrp_hdr_extoff
, { "nhrp.hdr.extoff.invalid", PI_MALFORMED
, PI_ERROR
, "Extension offset is less than the fixed header length", EXPFILL
}},
1387 { &ei_nhrp_ext_not_allowed
, { "nhrp.ext.not_allowed", PI_MALFORMED
, PI_ERROR
, "Extensions not allowed per RFC2332 section 5.2.7", EXPFILL
}},
1388 { &ei_nhrp_ext_malformed
, { "nhrp.ext.malformed", PI_MALFORMED
, PI_ERROR
, "Incomplete Authentication Extension", EXPFILL
}},
1389 { &ei_nhrp_ext_extra
, { "nhrp.ext.extra", PI_MALFORMED
, PI_ERROR
, "Superfluous data follows End Extension", EXPFILL
}},
1392 expert_module_t
* expert_nhrp
;
1394 proto_nhrp
= proto_register_protocol("NBMA Next Hop Resolution Protocol", "NHRP", "nhrp");
1395 proto_register_field_array(proto_nhrp
, hf
, array_length(hf
));
1396 proto_register_subtree_array(ett
, array_length(ett
));
1397 expert_nhrp
= expert_register_protocol(proto_nhrp
);
1398 expert_register_field_array(expert_nhrp
, ei
, array_length(ei
));
1402 proto_reg_handoff_nhrp(void)
1404 dissector_handle_t nhrp_handle
;
1406 data_handle
= find_dissector("data");
1408 osinl_incl_subdissector_table
= find_dissector_table("osinl.incl");
1409 osinl_excl_subdissector_table
= find_dissector_table("osinl.excl");
1410 ethertype_subdissector_table
= find_dissector_table("ethertype");
1412 nhrp_handle
= create_dissector_handle(dissect_nhrp
, proto_nhrp
);
1413 dissector_add_uint("ip.proto", IP_PROTO_NARP
, nhrp_handle
);
1414 dissector_add_uint("gre.proto", GRE_NHRP
, nhrp_handle
);
1415 dissector_add_uint("llc.iana_pid", IANA_PID_MARS_NHRP_CONTROL
, nhrp_handle
);