2 * Routines for EIGRP dissection
3 * Copyright 2011, Donnie V Savage <dsavage@cisco.com>
5 * Complete re-write and replaces previous file of same name authored by:
6 * Copyright 2009, Jochen Bartl <jochen.bartl@gmail.co
7 * Copyright 2000, Paul Ionescu <paul@acorp.ro>
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.
30 #include <epan/packet.h>
31 #include <epan/guid-utils.h>
32 #include <epan/addr_resolv.h>
33 #include <epan/atalk-utils.h>
34 #include <epan/addr_and_mask.h>
35 #include <epan/ipproto.h>
37 #include <epan/expert.h>
38 #include <epan/reassemble.h>
40 #include "packet-ipx.h"
41 #include "packet-osi.h"
44 * EIGRP Header size in bytes
46 #define EIGRP_HEADER_LENGTH 20
49 * EIGRP Packet Opcodes
51 #define EIGRP_OPC_UPDATE 1 /*!< packet containing routing information */
52 #define EIGRP_OPC_REQUEST 2 /*!< sent to request one or more routes */
53 #define EIGRP_OPC_QUERY 3 /*!< sent when a routing is in active start */
54 #define EIGRP_OPC_REPLY 4 /*!< sent in response to a query */
55 #define EIGRP_OPC_HELLO 5 /*!< sent to maintain a peering session */
56 #define EIGRP_OPC_IPXSAP 6 /*!< IPX SAP information */
57 #define EIGRP_OPC_PROBE 7 /*!< for test purposes */
58 #define EIGRP_OPC_ACK 8 /*!< acknowledge */
59 #define EIGRP_OPC_STUB 9 /*!< peering operating in restricted mode */
60 #define EIGRP_OPC_SIAQUERY 10 /*!< QUERY - with relaxed restrictions */
61 #define EIGRP_OPC_SIAREPLY 11 /*!< REPLY - may contain old routing information */
64 * EIGRP TLV Range definitions
67 * IPv4 0x0100 ** TLVs for one and all
68 * ATALK 0x0200 ** legacy
69 * IPX 0x0300 ** discontinued
70 * IPv6 0x0400 ** legacy
71 * Multiprotocol 0x0600 ** wide metrics
72 * MultiTopology 0x00f0 ** deprecated
74 #define EIGRP_TLV_RANGEMASK 0xfff0 /*!< should be 0xff00 - opps */
75 #define EIGRP_TLV_GENERAL 0x0000
78 * 1.2 TLV Definitions ** legacy
79 * These have been deprecated and should not be used for future packets
81 #define EIGRP_TLV_IPv4 0x0100 /*!< Classic IPv4 TLV encoding */
82 #define EIGRP_TLV_ATALK 0x0200 /*!< Classic Appletalk TLV encoding*/
83 #define EIGRP_TLV_IPX 0x0300 /*!< Classic IPX TLV encoding */
84 #define EIGRP_TLV_IPv6 0x0400 /*!< Classic IPv6 TLV encoding */
87 * 2.0 Multi-Protocol TLV Definitions
88 * These have been deprecated and should not be used for future packets
90 #define EIGRP_TLV_MP 0x0600 /*!< Non-PDM specific encoding */
93 * 3.0 TLV Definitions ** deprecated
94 * These have been deprecated and should not be used for future packets
96 #define EIGRP_TLV_MTR 0x00f0 /*!< MTR TLV encoding */
99 * TLV type definitions. Generic (protocol-independent) TLV types are
100 * defined here. Protocol-specific ones are defined elsewhere.
102 #define EIGRP_TLV_PARAMETER (EIGRP_TLV_GENERAL | 0x0001) /*!< eigrp parameters */
103 #define EIGRP_TLV_AUTH (EIGRP_TLV_GENERAL | 0x0002) /*!< authentication */
104 #define EIGRP_TLV_SEQ (EIGRP_TLV_GENERAL | 0x0003) /*!< sequenced packet */
105 #define EIGRP_TLV_SW_VERSION (EIGRP_TLV_GENERAL | 0x0004) /*!< software version */
106 #define EIGRP_TLV_NEXT_MCAST_SEQ (EIGRP_TLV_GENERAL | 0x0005) /*!< */
107 #define EIGRP_TLV_PEER_STUBINFO (EIGRP_TLV_GENERAL | 0x0006) /*!< stub information */
108 #define EIGRP_TLV_PEER_TERMINATION (EIGRP_TLV_GENERAL | 0x0007) /*!< peer termination */
109 #define EIGRP_TLV_PEER_TIDLIST (EIGRP_TLV_GENERAL | 0x0008) /*!< peer sub-topology list */
114 #define EIGRP_TLV_TYPEMASK 0x000f
115 #define EIGRP_TLV_REQUEST 0x0001
116 #define EIGRP_TLV_INTERNAL 0x0002
117 #define EIGRP_TLV_EXTERNAL 0x0003
118 #define EIGRP_TLV_COMMUNITY 0x0004
120 /* Legacy TLV formats */
121 #define EIGRP_TLV_IPv4_REQ (EIGRP_TLV_IPv4 | EIGRP_TLV_REQUEST)
122 #define EIGRP_TLV_IPv4_INT (EIGRP_TLV_IPv4 | EIGRP_TLV_INTERNAL)
123 #define EIGRP_TLV_IPv4_EXT (EIGRP_TLV_IPv4 | EIGRP_TLV_EXTERNAL)
124 #define EIGRP_TLV_IPv4_COM (EIGRP_TLV_IPv4 | EIGRP_TLV_COMMUNITY)
125 #define EIGRP_TLV_IPX_INT (EIGRP_TLV_IPX | EIGRP_TLV_INTERNAL)
126 #define EIGRP_TLV_IPX_EXT (EIGRP_TLV_IPX | EIGRP_TLV_EXTERNAL)
127 #define EIGRP_TLV_IPX_COM (EIGRP_TLV_IPX | EIGRP_TLV_COMMUNITY)
128 #define EIGRP_TLV_IPv6_INT (EIGRP_TLV_IPv6 | EIGRP_TLV_INTERNAL)
129 #define EIGRP_TLV_IPv6_EXT (EIGRP_TLV_IPv6 | EIGRP_TLV_EXTERNAL)
130 #define EIGRP_TLV_IPv6_COM (EIGRP_TLV_IPv6 | EIGRP_TLV_COMMUNITY)
132 /* Deprecated TLV formats */
133 #define EIGRP_TLV_AT_INT (EIGRP_TLV_ATALK | EIGRP_TLV_INTERNAL)
134 #define EIGRP_TLV_AT_EXT (EIGRP_TLV_ATALK | EIGRP_TLV_EXTERNAL)
135 #define EIGRP_TLV_AT_CBL (EIGRP_TLV_ATALK | 0x04)
136 #define EIGRP_TLV_MTR_REQ (EIGRP_TLV_MTR | EIGRP_TLV_REQUEST)
137 #define EIGRP_TLV_MTR_INT (EIGRP_TLV_MTR | EIGRP_TLV_INTERNAL)
138 #define EIGRP_TLV_MTR_EXT (EIGRP_TLV_MTR | EIGRP_TLV_EXTERNAL)
139 #define EIGRP_TLV_MTR_COM (EIGRP_TLV_MTR | EIGRP_TLV_COMMUNITY)
140 #define EIGRP_TLV_MTR_TIDLIST (EIGRP_TLV_MTR | 0x0005)
142 /* Current "Wide Metric" TLV formats */
143 #define EIGRP_TLV_MP_REQ (EIGRP_TLV_MP | EIGRP_TLV_REQUEST)
144 #define EIGRP_TLV_MP_INT (EIGRP_TLV_MP | EIGRP_TLV_INTERNAL)
145 #define EIGRP_TLV_MP_EXT (EIGRP_TLV_MP | EIGRP_TLV_EXTERNAL)
146 #define EIGRP_TLV_MP_COM (EIGRP_TLV_MP | EIGRP_TLV_COMMUNITY)
149 * External routes originate from some other protocol - these are them
151 #define NULL_PROTID 0 /*!< unknown protocol */
152 #define IGRP1_PROTID 1 /*!< IGRP.. whos your daddy! */
153 #define IGRP2_PROTID 2 /*!< EIGRP - Just flat out the best */
154 #define STATIC_PROTID 3 /*!< Staticly configured source */
155 #define RIP_PROTID 4 /*!< Routing Information Protocol */
156 #define HELLO_PROTID 5 /*!< Hello? RFC-891 you there? */
157 #define OSPF_PROTID 6 /*!< OSPF - Open Shortest Path First */
158 #define ISIS_PROTID 7 /*!< Intermediate System To Intermediate System */
159 #define EGP_PROTID 8 /*!< Exterior Gateway Protocol */
160 #define BGP_PROTID 9 /*!< Border Gateway Protocol */
161 #define IDRP_PROTID 10 /*!< InterDomain Routing Protocol */
162 #define CONN_PROTID 11 /*!< Connected source */
166 * extdata flag field definitions
168 #define EIGRP_OPAQUE_EXT 0x01 /*!< Route is external */
169 #define EIGRP_OPAQUE_CD 0x02 /*!< Candidate default route */
172 * Address-Family types are taken from:
173 * http://www.iana.org/assignments/address-family-numbers
174 * to provide a standards based exchange of AFI information between
177 #define EIGRP_AF_IPv4 1 /*!< IPv4 (IP version 4) */
178 #define EIGRP_AF_IPv6 2 /*!< IPv6 (IP version 6) */
179 #define EIGRP_AF_IPX 11 /*!< IPX */
180 #define EIGRP_AF_ATALK 12 /*!< Appletalk */
181 #define EIGRP_SF_COMMON 16384 /*!< Cisco Service Family */
182 #define EIGRP_SF_IPv4 16385 /*!< Cisco IPv4 Service Family */
183 #define EIGRP_SF_IPv6 16386 /*!< Cisco IPv6 Service Family */
186 * Authentication types supported by EIGRP
188 #define EIGRP_AUTH_TYPE_NONE 0
189 #define EIGRP_AUTH_TYPE_TEXT 1
190 #define EIGRP_AUTH_TYPE_MD5 2
191 #define EIGRP_AUTH_TYPE_MD5_LEN 16
192 #define EIGRP_AUTH_TYPE_SHA256 3
193 #define EIGRP_AUTH_TYPE_SHA256_LEN 32
196 * opaque flag field definitions
198 #define EIGRP_OPAQUE_SRCWD 0x01 /*!< Route Source Withdraw */
199 #define EIGRP_OPAQUE_ACTIVE 0x04 /*!< Route is currently in active state */
200 #define EIGRP_OPAQUE_REPL 0x08 /*!< Route is replicated from different tableid */
203 * pak flag bit field definitions - 0 (none)-7 source priority
205 #define EIGRP_PRIV_DEFAULT 0x00 /* 0 (none)-7 source priority */
206 #define EIGRP_PRIV_LOW 0x01
207 #define EIGRP_PRIV_MEDIUM 0x04
208 #define EIGRP_PRIV_HIGH 0x07
211 * stub bit definitions
213 #define EIGRP_PEER_ALLOWS_CONNECTED 0x0001
214 #define EIGRP_PEER_ALLOWS_STATIC 0x0002
215 #define EIGRP_PEER_ALLOWS_SUMMARY 0x0004
216 #define EIGRP_PEER_ALLOWS_REDIST 0x0008
217 #define EIGRP_PEER_ALLOWS_LEAKING 0x0010
218 #define EIGRP_PEER_ALLOWS_RCVONLY 0x0020
221 * Init bit definition. First unicast transmitted Update has this
222 * bit set in the flags field of the fixed header. It tells the neighbor
223 * to down-load his topology table.
225 #define EIGRP_INIT_FLAG 0x01
228 * CR bit (Conditionally Received) definition in flags field on header. Any
229 * packets with the CR-bit set can be accepted by an EIGRP speaker if and
230 * only if a previous Hello was received with the SEQUENCE_TYPE TLV present.
232 * This allows multicasts to be transmitted in order and reliably at the
233 * same time as unicasts are transmitted.
235 #define EIGRP_CR_FLAG 0x02
238 * RS bit. The Restart flag is set in the hello and the init
239 * update packets during the nsf signaling period. A nsf-aware
240 * router looks at the RS flag to detect if a peer is restarting
241 * and maintain the adjacency. A restarting router looks at
242 * this flag to determine if the peer is helping out with the restart.
244 #define EIGRP_RS_FLAG 0x04
247 * EOT bit. The End-of-Table flag marks the end of the start-up updates
248 * sent to a new peer. A nsf restarting router looks at this flag to
249 * determine if it has finished receiving the start-up updates from all
250 * peers. A nsf-aware router waits for this flag before cleaning up
251 * the stale routes from the restarting peer.
253 #define EIGRP_EOT_FLAG 0x08
256 * EIGRP Virtual Router ID
258 * Define values to deal with EIGRP virtual router ids. Virtual
259 * router IDs are stored in the upper short of the EIGRP fixed packet
260 * header. The lower short of the packet header continues to be used
263 * Virtual Router IDs are PDM-independent. All PDMs will use
264 * VRID_BASE to indicate the 'base' or 'legacy' EIGRP instance.
265 * All PDMs need to initialize their vrid to VRID_BASE for compatibility
266 * with legacy routers.
267 * Once IPv6 supports 'MTR Multicast', it will use the same VRID as
268 * IPv4. No current plans to support VRIDs on IPX. :)
269 * Initial usage of VRID is to signal usage of Multicast topology for
272 * VRID_MCAST is a well known constant, other VRIDs will be determined
275 * With the addition of SAF the VRID space has been divided into two
276 * segments 0x0000-0x7fff is for EIGRP and vNets, 0x8000-0xffff is
277 * for saf and its associated vNets.
279 #define EIGRP_VRID_MASK 0x8001
280 #define EIGRP_VRID_AF_BASE 0x0000
281 #define EIGRP_VRID_MCAST_BASE 0x0001
282 #define EIGRP_VRID_SF_BASE 0x8000
284 /* Extended Attributes for a destination */
285 #define EIGRP_ATTR_HDRLEN (2)
286 #define EIGRP_ATTR_MAXDATA (512)
288 #define EIGRP_ATTR_NOOP 0 /*!< No-Op used as offset padding */
289 #define EIGRP_ATTR_SCALED 1 /*!< Scaled metric values */
290 #define EIGRP_ATTR_TAG 2 /*!< Tag assigned by Admin for dest */
291 #define EIGRP_ATTR_COMM 3 /*!< Community attribute for dest */
292 #define EIGRP_ATTR_JITTER 4 /*!< Variation in path delay */
293 #define EIGRP_ATTR_QENERGY 5 /*!< Non-Active energy usage along path */
294 #define EIGRP_ATTR_ENERGY 6 /*!< Active energy usage along path */
297 * Begin EIGRP-BGP interoperability communities
299 #define EIGRP_EXTCOMM_SOO_ASFMT 0x0003 /* Site-of-Origin, BGP AS format */
300 #define EIGRP_EXTCOMM_SOO_ADRFMT 0x0103 /* Site-of-Origin, BGP/EIGRP addr format */
303 * EIGRP Specific communities
305 #define EIGRP_EXTCOMM_EIGRP 0x8800 /* EIGRP route information appended*/
306 #define EIGRP_EXTCOMM_DAD 0x8801 /* EIGRP AS + Delay */
307 #define EIGRP_EXTCOMM_VRHB 0x8802 /* EIGRP Vector: Reliability + Hop + BW */
308 #define EIGRP_EXTCOMM_SRLM 0x8803 /* EIGRP System: Reserve +Load + MTU */
309 #define EIGRP_EXTCOMM_SAR 0x8804 /* EIGRP System: Remote AS + Remote ID */
310 #define EIGRP_EXTCOMM_RPM 0x8805 /* EIGRP Remote: Protocol + Metric */
311 #define EIGRP_EXTCOMM_VRR 0x8806 /* EIGRP Vecmet: Rsvd + (internal) Routerid */
314 #define EIGRP_SVCDATA_COMPLETE 0x01 /*!< Data is attached */
315 #define EIGRP_SVCDATA_TRIMMED 0x02 /*!< Data was trimmed from service */
317 /* SAF Defined Numbers */
318 #define SAF_SERVICE_ID_CAPMAN 100 /*!< Capabilities Manager */
319 #define SAF_SERVICE_ID_UC 101 /*!< Unified Communications */
320 #define SAF_SERVICE_ID_PFR 102 /*!< Performance Routing */
322 /* Forward declaration we need below (if using proto_reg_handoff...
323 as a prefs callback) */
324 void proto_reg_handoff_eigrp(void);
325 void proto_register_eigrp(void);
327 /* Initialize the protocol and registered fields */
328 static int proto_eigrp = -1;
331 static gint hf_eigrp_version = -1;
332 static gint hf_eigrp_opcode = -1;
333 static gint hf_eigrp_flags = -1;
334 static gint hf_eigrp_sequence = -1;
335 static gint hf_eigrp_acknowledge = -1;
336 static gint hf_eigrp_vrid = -1;
337 static gint hf_eigrp_as = -1;
338 static gint ett_eigrp = -1;
340 /* packet header flags */
341 static gint hf_eigrp_flags_init = -1;
342 static gint hf_eigrp_flags_restart = -1;
343 static gint hf_eigrp_flags_eot = -1;
344 static gint hf_eigrp_flags_condrecv = -1;
346 static gint ett_eigrp_flags = -1;
347 static const int *eigrp_flag_fields[] = {
348 &hf_eigrp_flags_init,
349 &hf_eigrp_flags_condrecv,
350 &hf_eigrp_flags_restart,
356 static gint hf_eigrp_tlv_type = -1;
357 static gint hf_eigrp_tlv_len = -1;
358 static gint hf_eigrp_tid = -1;
359 static gint hf_eigrp_afi = -1;
360 static gint hf_eigrp_nullpad = -1;
362 static gint ett_eigrp_tlv = -1;
363 static gint ett_eigrp_tlv_metric = -1;
364 static gint ett_eigrp_tlv_attr = -1;
365 static gint ett_eigrp_tlv_extdata = -1;
368 static gint hf_eigrp_par_k1 = -1;
369 static gint hf_eigrp_par_k2 = -1;
370 static gint hf_eigrp_par_k3 = -1;
371 static gint hf_eigrp_par_k4 = -1;
372 static gint hf_eigrp_par_k5 = -1;
373 static gint hf_eigrp_par_k6 = -1;
374 static gint hf_eigrp_par_holdtime = -1;
377 static gint hf_eigrp_auth_type = -1;
378 static gint hf_eigrp_auth_len = -1;
379 static gint hf_eigrp_auth_keyid = -1;
380 static gint hf_eigrp_auth_keyseq = -1;
381 static gint hf_eigrp_auth_digest = -1;
384 static gint hf_eigrp_seq_addrlen = -1;
385 static gint hf_eigrp_seq_ipv4addr = -1;
386 static gint hf_eigrp_seq_ipv6addr = -1;
389 static gint hf_eigrp_next_mcast_seq = -1;
392 static gint hf_eigrp_stub_flags = -1;
393 static gint hf_eigrp_stub_flags_connected = -1;
394 static gint hf_eigrp_stub_flags_static = -1;
395 static gint hf_eigrp_stub_flags_summary = -1;
396 static gint hf_eigrp_stub_flags_recvonly = -1;
397 static gint hf_eigrp_stub_flags_redist = -1;
398 static gint hf_eigrp_stub_flags_leakmap = -1;
400 static gint ett_eigrp_stub_flags = -1;
401 static const int *eigrp_stub_flag_fields[] = {
402 &hf_eigrp_stub_flags_connected,
403 &hf_eigrp_stub_flags_static,
404 &hf_eigrp_stub_flags_summary,
405 &hf_eigrp_stub_flags_redist,
406 &hf_eigrp_stub_flags_leakmap,
407 &hf_eigrp_stub_flags_recvonly,
412 static gint hf_eigrp_tidlist_tid = -1;
413 static gint hf_eigrp_tidlist_flags = -1;
414 static gint hf_eigrp_tidlist_len = -1;
415 static gint ett_eigrp_tidlist = -1;
417 /* 1.2 and 3.0 metric */
418 static gint hf_eigrp_legacy_metric_delay = -1;
419 static gint hf_eigrp_legacy_metric_bw = -1;
420 static gint hf_eigrp_legacy_metric_mtu = -1;
421 static gint hf_eigrp_legacy_metric_hopcount = -1;
422 static gint hf_eigrp_legacy_metric_rel = -1;
423 static gint hf_eigrp_legacy_metric_load = -1;
424 static gint hf_eigrp_legacy_metric_intag = -1;
427 static gint hf_eigrp_legacy_metric_tag = -1;
430 static gint hf_eigrp_metric_offset = -1;
431 static gint hf_eigrp_metric_priority = -1;
432 static gint hf_eigrp_metric_rel = -1;
433 static gint hf_eigrp_metric_load = -1;
434 static gint hf_eigrp_metric_mtu = -1;
435 static gint hf_eigrp_metric_hopcount = -1;
436 static gint hf_eigrp_metric_reserved = -1;
439 static gint hf_eigrp_routerid = -1;
441 /* protocol dependent module route flags */
442 static gint hf_eigrp_metric_flags_srcwd = -1;
443 static gint hf_eigrp_metric_flags_active = -1;
444 static gint hf_eigrp_metric_flags_repl = -1;
445 static gint ett_eigrp_metric_flags = -1;
447 /* extended metrics */
448 static gint hf_eigrp_attr_opcode = -1;
449 static gint hf_eigrp_attr_offset = -1;
450 static gint hf_eigrp_attr_scaled = -1;
451 static gint hf_eigrp_attr_tag = -1;
452 static gint hf_eigrp_attr_jitter = -1;
453 static gint hf_eigrp_attr_qenergy = -1;
454 static gint hf_eigrp_attr_energy = -1;
456 /* route external data */
457 static gint hf_eigrp_extdata_origrid = -1;
458 static gint hf_eigrp_extdata_as = -1;
459 static gint hf_eigrp_extdata_tag = -1;
460 static gint hf_eigrp_extdata_metric = -1;
461 static gint hf_eigrp_extdata_reserved = -1;
462 static gint hf_eigrp_extdata_proto = -1;
464 static gint hf_eigrp_extdata_flag_ext = -1;
465 static gint hf_eigrp_extdata_flag_cd = -1;
466 static gint ett_eigrp_extdata_flags = -1;
469 static gint hf_eigrp_ipv4_nexthop = -1;
470 static gint hf_eigrp_ipv4_prefixlen = -1;
473 static gint hf_eigrp_ipv6_nexthop = -1;
474 static gint hf_eigrp_ipv6_prefixlen = -1;
477 static gint hf_eigrp_ipx_nexthop_net = -1;
478 static gint hf_eigrp_ipx_nexthop_host = -1;
479 static gint hf_eigrp_ipx_extdata_routerid = -1;
480 static gint hf_eigrp_ipx_extdata_delay = -1;
481 static gint hf_eigrp_ipx_extdata_metric = -1;
482 static gint hf_eigrp_ipx_dest = -1;
484 /* appletalk address */
485 static gint hf_eigrp_atalk_routerid = -1;
488 static gint hf_eigrp_saf_service = -1;
489 static gint hf_eigrp_saf_subservice = -1;
490 static gint hf_eigrp_saf_guid = -1;
492 static gint hf_eigrp_saf_reachability_afi = -1;
493 static gint hf_eigrp_saf_reachability_port = -1;
494 static gint hf_eigrp_saf_reachability_protocol = -1;
495 static gint hf_eigrp_saf_reachability_addr_ipv4 = -1;
496 static gint hf_eigrp_saf_reachability_addr_ipv6 = -1;
497 static gint hf_eigrp_saf_reachability_addr_hex = -1;
498 static gint ett_eigrp_saf_reachability = -1;
500 static gint hf_eigrp_saf_data_length = -1;
501 static gint hf_eigrp_saf_data_sequence = -1;
502 static gint hf_eigrp_saf_data_type = -1;
504 static expert_field ei_eigrp_checksum_bad = EI_INIT;
505 static expert_field ei_eigrp_unreachable = EI_INIT;
506 static expert_field ei_eigrp_seq_addrlen = EI_INIT;
507 static expert_field ei_eigrp_peer_termination = EI_INIT;
508 static expert_field ei_eigrp_tlv_type = EI_INIT;
509 static expert_field ei_eigrp_auth_type = EI_INIT;
510 static expert_field ei_eigrp_peer_termination_graceful = EI_INIT;
511 static expert_field ei_eigrp_auth_len = EI_INIT;
512 static expert_field ei_eigrp_tlv_len = EI_INIT;
513 static expert_field ei_eigrp_afi = EI_INIT;
514 static expert_field ei_eigrp_prefixlen = EI_INIT;
516 /* some extra handle that might be needed */
517 static dissector_handle_t ipxsap_handle = NULL;
518 static dissector_table_t media_type_table = NULL;
520 static const value_string eigrp_opcode2string[] = {
521 { EIGRP_OPC_UPDATE, "Update" },
522 { EIGRP_OPC_REQUEST, "Request" },
523 { EIGRP_OPC_QUERY, "Query" },
524 { EIGRP_OPC_REPLY, "Reply" },
525 { EIGRP_OPC_HELLO, "Hello" },
526 { EIGRP_OPC_IPXSAP, "IPX/SAP Update" },
527 { EIGRP_OPC_PROBE, "Route Probe" },
528 { EIGRP_OPC_ACK, "Hello (Ack)" },
529 { EIGRP_OPC_STUB, "Stub-Info" },
530 { EIGRP_OPC_SIAQUERY, "SIA-Query" },
531 { EIGRP_OPC_SIAREPLY, "SIA-Reply" },
535 static const value_string eigrp_tlv2string[] = {
536 /* General TLV formats */
537 { EIGRP_TLV_PARAMETER, "Parameters"},
538 { EIGRP_TLV_AUTH, "Authentication"},
539 { EIGRP_TLV_SEQ, "Sequence"},
540 { EIGRP_TLV_SW_VERSION, "Software Version"},
541 { EIGRP_TLV_NEXT_MCAST_SEQ, "Next multicast sequence"},
542 { EIGRP_TLV_PEER_STUBINFO, "Peer Stub Information"},
543 { EIGRP_TLV_PEER_TERMINATION, "Peer Termination"},
544 { EIGRP_TLV_PEER_TIDLIST, "Peer Topology ID List"},
546 /* Legacy TLV formats */
547 { EIGRP_TLV_IPv4_INT, "Internal Route(IPv4)"},
548 { EIGRP_TLV_IPv4_EXT, "External Route(IPv4)"},
549 { EIGRP_TLV_IPv4_COM, "Ext-Community(IPv4)"},
550 { EIGRP_TLV_IPv6_INT, "Internal Route(IPv6)"},
551 { EIGRP_TLV_IPv6_EXT, "External Route(IPv6)"},
552 { EIGRP_TLV_IPv6_COM, "Ext-Community(IPv6)"},
553 { EIGRP_TLV_IPX_INT, "IPX Internal Route(IPX)"},
554 { EIGRP_TLV_IPX_EXT, "IPX External Route(IPX)"},
556 /* Deprecated TLV formats */
557 { EIGRP_TLV_AT_INT, "Internal Route(ATALK)"},
558 { EIGRP_TLV_AT_EXT, "External Route(ATALK)"},
559 { EIGRP_TLV_AT_CBL, "Cable Configuration(ATALK)"},
560 { EIGRP_TLV_MTR_REQ, "Request(MTR)"},
561 { EIGRP_TLV_MTR_INT, "Internal Route(MTR)"},
562 { EIGRP_TLV_MTR_EXT, "External Route(MTR)"},
563 { EIGRP_TLV_MTR_COM, "Ext-Community(MTR)"},
564 { EIGRP_TLV_MTR_TIDLIST, "TopologyID List"},
566 /* Current "Wide Metric" TLV formats */
567 { EIGRP_TLV_MP_REQ, "Request"},
568 { EIGRP_TLV_MP_INT, "Internal Route"},
569 { EIGRP_TLV_MP_EXT, "External Route"},
570 { EIGRP_TLV_MP_COM, "Ext-Community"},
575 static const value_string eigrp_proto2string[] = {
576 { IGRP1_PROTID, "IGRP"},
577 { IGRP2_PROTID, "EIGRP"},
578 { STATIC_PROTID, "Static Route"},
579 { RIP_PROTID, "RIP"},
580 { HELLO_PROTID, "Hello"},
581 { OSPF_PROTID, "OSPF"},
582 { ISIS_PROTID, "IS-IS"},
583 { EGP_PROTID, "EGP"},
584 { BGP_PROTID, "BGP"},
585 { IDRP_PROTID, "IDRP"},
586 { CONN_PROTID, "Connected Route"},
590 static const value_string eigrp_auth2string[] = {
591 { EIGRP_AUTH_TYPE_TEXT, "TEXT"},
592 { EIGRP_AUTH_TYPE_MD5, "MD5"},
593 { EIGRP_AUTH_TYPE_SHA256, "SHA256"},
597 static const value_string eigrp_vrid2string[] = {
598 { EIGRP_VRID_AF_BASE, "(Address-Family)"},
599 { EIGRP_VRID_SF_BASE, "(Service-Family)"},
600 { EIGRP_VRID_MCAST_BASE, "(Multi-Cast)"},
604 static const value_string eigrp_afi2string[] = {
605 { EIGRP_AF_IPv4, "IPv4"},
606 { EIGRP_AF_IPv6, "IPv6"},
607 { EIGRP_AF_IPX, "IPX"},
608 { EIGRP_AF_ATALK, "Appletalk"},
609 { EIGRP_SF_COMMON, "Service Family"},
610 { EIGRP_SF_IPv4, "IPv4 Service Family"},
611 { EIGRP_SF_IPv6, "IPv6 Service Family"},
615 static const value_string eigrp_attr_opcode2string[] = {
616 { EIGRP_ATTR_NOOP, "NO-OP for padding"},
617 { EIGRP_ATTR_SCALED, "Scaled Metric"},
618 { EIGRP_ATTR_TAG, "Admin Tag"},
619 { EIGRP_ATTR_COMM, "Community"},
620 { EIGRP_ATTR_JITTER, "Jitter"},
621 { EIGRP_ATTR_QENERGY, "Non-Active energy"},
622 { EIGRP_ATTR_ENERGY, "Active energy"},
626 static const value_string eigrp_saf_type2string[] = {
627 { EIGRP_SVCDATA_COMPLETE, "Attached Service Data"},
628 { EIGRP_SVCDATA_TRIMMED, "Trimmed Service Data"},
632 static const value_string eigrp_saf_srv2string[] = {
633 { SAF_SERVICE_ID_CAPMAN, "Capabilities Manager"},
634 { SAF_SERVICE_ID_UC, "Unified Communications"},
635 { SAF_SERVICE_ID_PFR, "Performance Routing"},
640 *@fn void dissect_eigrp_parameter (proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
643 * @param[in,out] tree detail dissection result
644 * @param[in] tvb packet data
645 * @param[in] pinfo general data about the protocol
646 * @param[in] ti protocol item
649 * Dissect the Parameter TLV, which is used to convey metric weights and the
653 * Note the addition of K6 for the new extended metrics, and does not apply to
654 * older TLV packet formats.
657 dissect_eigrp_parameter (proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
661 guint8 k1, k2, k3, k4, k5;
663 k1 = tvb_get_guint8(tvb, offset);
664 proto_tree_add_item(tree, hf_eigrp_par_k1, tvb, offset, 1, ENC_BIG_ENDIAN);
667 k2 = tvb_get_guint8(tvb, offset);
668 proto_tree_add_item(tree, hf_eigrp_par_k2, tvb, offset, 1, ENC_BIG_ENDIAN);
671 k3 = tvb_get_guint8(tvb, offset);
672 proto_tree_add_item(tree, hf_eigrp_par_k3, tvb, offset, 1, ENC_BIG_ENDIAN);
675 k4 = tvb_get_guint8(tvb, offset);
676 proto_tree_add_item(tree, hf_eigrp_par_k4, tvb, offset, 1, ENC_BIG_ENDIAN);
679 k5 = tvb_get_guint8(tvb, offset);
680 proto_tree_add_item(tree, hf_eigrp_par_k5, tvb, offset, 1, ENC_BIG_ENDIAN);
683 proto_tree_add_item(tree, hf_eigrp_par_k6, tvb, offset, 1, ENC_BIG_ENDIAN);
686 proto_tree_add_item(tree, hf_eigrp_par_holdtime, tvb, offset, 2, ENC_BIG_ENDIAN);
688 if (k1 == 255 && k2 == 255 && k3 == 255 && k4 == 255 && k5 == 255) {
689 proto_item_append_text(ti, ": Peer Termination");
690 expert_add_info(pinfo, ti, &ei_eigrp_peer_termination);
695 *@fn void dissect_eigrp_auth_tlv (proto_tree *tree, tvbuff_t *tvb,
696 * packet_info *pinfo, proto_item *ti)
698 * @param[in,out] tree detail dissection result
699 * @param[in] tvb packet data
700 * @param[in] pinfo general data about the protocol
701 * @param[in] ti protocol item
704 * Dissect the Authentication TLV and display digest. Currently MD5 and SHA256
705 * HMAC is supported. For SHA256, a "secret key" with the HMAC-SHA-256
706 * password, the source address from which the packet is sent. This combined
707 * string is used as the key for hash calculation.
710 dissect_eigrp_auth_tlv (proto_tree *tree, tvbuff_t *tvb,
711 packet_info *pinfo, proto_item *ti)
713 proto_item *ti_auth_type, *ti_auth_len;
715 guint16 auth_type, auth_len;
717 /* print out what family we dealing with... */
719 auth_type = tvb_get_ntohs(tvb, 0);
720 auth_len = tvb_get_ntohs(tvb, 2);
722 proto_item_append_text(ti, " %s", val_to_str_const(auth_type, eigrp_auth2string, ""));
724 ti_auth_type = proto_tree_add_item(tree, hf_eigrp_auth_type, tvb, offset, 2, ENC_BIG_ENDIAN);
726 ti_auth_len = proto_tree_add_item(tree, hf_eigrp_auth_len, tvb, offset, 2, ENC_BIG_ENDIAN);
728 proto_tree_add_item(tree, hf_eigrp_auth_keyid, tvb, offset, 4, ENC_BIG_ENDIAN);
730 proto_tree_add_item(tree, hf_eigrp_auth_keyseq, tvb, offset, 4, ENC_BIG_ENDIAN);
732 proto_tree_add_item(tree, hf_eigrp_nullpad, tvb, offset, 8, ENC_NA);
736 case EIGRP_AUTH_TYPE_MD5:
737 if (EIGRP_AUTH_TYPE_MD5_LEN != auth_len) {
738 expert_add_info_format(pinfo, ti_auth_len, &ei_eigrp_auth_len, "Invalid auth len %u", auth_len);
740 proto_tree_add_item(tree, hf_eigrp_auth_digest, tvb, offset,
741 EIGRP_AUTH_TYPE_MD5_LEN, ENC_NA);
745 case EIGRP_AUTH_TYPE_SHA256:
746 if (EIGRP_AUTH_TYPE_SHA256_LEN != auth_len) {
747 expert_add_info_format(pinfo, ti_auth_len, &ei_eigrp_auth_len, "Invalid auth len %u", auth_len);
750 proto_tree_add_item(tree, hf_eigrp_auth_digest, tvb, offset,
751 EIGRP_AUTH_TYPE_SHA256_LEN, ENC_NA);
755 case EIGRP_AUTH_TYPE_NONE:
756 case EIGRP_AUTH_TYPE_TEXT:
758 expert_add_info_format(pinfo, ti_auth_type, &ei_eigrp_auth_type, "Invalid auth type %u", auth_type);
764 *@fn void dissect_eigrp_seq_tlv (proto_tree *tree, tvbuff_t *tvb,
765 * packet_info *pinfo)
767 * @param[in,out] tree detail dissection result
768 * @param[in] tvb packet data
769 * @param[in] pinfo general data about the protocol
772 * Dissect the Sequence TLV which consist of the address of peers that must
773 * not receive the next multicast packet transmitted.
776 dissect_eigrp_seq_tlv (proto_tree *tree, tvbuff_t *tvb,
779 proto_item *ti_addrlen;
783 addr_len = tvb_get_guint8(tvb, 0);
784 ti_addrlen = proto_tree_add_item(tree, hf_eigrp_seq_addrlen, tvb, offset, 1, ENC_BIG_ENDIAN);
790 proto_tree_add_item(tree, hf_eigrp_seq_ipv4addr, tvb, offset, addr_len, ENC_BIG_ENDIAN);
794 proto_tree_add_text(tree, tvb, offset, addr_len,
795 "IPX Address = %08x.%04x.%04x.%04x",
796 tvb_get_ntohl(tvb, 1), tvb_get_ntohs(tvb, 5),
797 tvb_get_ntohs(tvb, 7), tvb_get_ntohs(tvb, 9));
801 proto_tree_add_item(tree, hf_eigrp_seq_ipv6addr, tvb, offset, addr_len,
805 expert_add_info(pinfo, ti_addrlen, &ei_eigrp_seq_addrlen);
810 *@fn void dissect_eigrp_sw_version (tvbuff_t *tvb, proto_tree *tree,
813 * @param[in,out] tree detail dissection result
814 * @param[in] tvb packet data
815 * @param[in] ti protocol item
818 * Dissect Software Version TLV. The older versions of EIGRP sent the IOS
819 * version along with the TLV Version. When EIGRP "plugins" were created,
820 * this as change to send the "Release" of EIGRP to better identify where fixes
821 * are present(missing)
824 dissect_eigrp_sw_version (tvbuff_t *tvb, proto_tree *tree,
828 guint8 ios_rel_major, ios_rel_minor;
829 guint8 eigrp_rel_major, eigrp_rel_minor;
831 ios_rel_major = tvb_get_guint8(tvb, 0);
832 ios_rel_minor = tvb_get_guint8(tvb, 1);
833 proto_tree_add_text(tree, tvb, offset, 2, "EIGRP Release: %u.%u",
834 ios_rel_major, ios_rel_minor);
836 proto_item_append_text(ti, ": EIGRP=%u.%u", ios_rel_major, ios_rel_minor);
838 eigrp_rel_major = tvb_get_guint8(tvb, 2);
839 eigrp_rel_minor = tvb_get_guint8(tvb, 3);
840 proto_tree_add_text(tree,tvb,offset, 2, "EIGRP TLV version: %u.%u",
841 eigrp_rel_major, eigrp_rel_minor);
842 proto_item_append_text(ti, ", TLV=%u.%u",
843 eigrp_rel_major, eigrp_rel_minor);
847 *@fn void dissect_eigrp_next_mcast_seq (tvbuff_t *tvb, proto_tree *tree,
850 * @param[in,out] tree detail dissection result
851 * @param[in] tvb packet data
852 * @param[in] ti protocol item
855 * Dissect Next Multicast Sequence TLV, which is part of the Hello with a
856 * Sequence TLV; this gives a two-way binding between the packets and plugs a
857 * hole where a multicast could be received by the wrong peers (due to a
858 * string of lost packets).
861 dissect_eigrp_next_mcast_seq (tvbuff_t *tvb, proto_tree *tree,
864 proto_tree_add_item(tree, hf_eigrp_next_mcast_seq, tvb, 0, 4,
866 proto_item_append_text(ti, ": %u", tvb_get_ntohl(tvb, 0));
870 *@fn void dissect_eigrp_peer_stubinfo (tvbuff_t *tvb, proto_tree *tree)
873 * @param[in,out] tree detail dissection result
874 * @param[in] tvb packet data
877 * Dissect the PEER STUB TLV which contains the route types which the Peer will
878 * advertise. This is used to suppress QUERYs from being sent to the Peer
881 dissect_eigrp_peer_stubinfo (tvbuff_t *tvb, proto_tree *tree)
883 proto_tree_add_bitmask(tree, tvb, 0, hf_eigrp_stub_flags, ett_eigrp_stub_flags,
884 eigrp_stub_flag_fields, ENC_BIG_ENDIAN);
888 *@fn void dissect_eigrp_peer_termination (packet_info *pinfo, proto_item *ti)
890 * @param[in] pinfo general data about the protocol
891 * @param[in] ti protocol item
894 * Dissect Peer Termination TLV. This TLV has no parameters and is used to
895 * signal an adjacency should be tore down
898 dissect_eigrp_peer_termination (packet_info *pinfo, proto_item *ti)
900 expert_add_info(pinfo, ti, &ei_eigrp_peer_termination_graceful);
904 *@fn void dissect_eigrp_peer_tidlist (proto_tree *tree, tvbuff_t *tvb)
906 * @param[in,out] tree detail dissection result
907 * @param[in] tvb packet data
910 * Dissect the Topology Identifier List TLV. This TLV was introduced as part
911 * of the "MTR (Multi-Topology Routing) Project to support sub topologies
912 * within a given Autonomous System. The following represents the format of
916 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
917 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
919 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
920 * | Variable Length TID (two bytes) list |
921 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
924 dissect_eigrp_peer_tidlist (proto_tree *tree, tvbuff_t *tvb)
927 proto_tree *sub_tree;
931 proto_tree_add_item(tree, hf_eigrp_tidlist_flags, tvb, offset, 2,
935 size = tvb_get_ntohs(tvb, offset) / 2;
936 proto_tree_add_item(tree, hf_eigrp_tidlist_len, tvb, offset, 2,
940 sub_ti = proto_tree_add_text(tree, tvb, offset, (size*2), "%d TIDs", size);
941 sub_tree = proto_item_add_subtree(sub_ti, ett_eigrp_tidlist);
942 for (; size ; size--) {
943 proto_tree_add_item(sub_tree, hf_eigrp_tidlist_tid, tvb, offset, 2,
950 *@fn int dissect_eigrp_extdata_flags (proto_tree *tree, tvbuff_t *tvb, int offset)
952 * @param[in,out] tree detail dissection result
953 * @param[in] tvb packet data
954 * @param[in] offset current byte offset in packet being processed
956 * @return int number of bytes process
959 * Dissect the Flags field in the external data section of an external
960 * route.The following represents the format of the bit field
967 * | +- Route is External *not used*
968 * +--- Route is Candidate Default
971 dissect_eigrp_extdata_flags (proto_tree *tree, tvbuff_t *tvb, int offset)
974 proto_tree *sub_tree;
977 /* Decode the route flags field */
978 sub_ti = proto_tree_add_text(tree, tvb, offset, 1, "External Flags");
979 sub_tree = proto_item_add_subtree(sub_ti, ett_eigrp_extdata_flags);
980 sub_tvb = tvb_new_subset_remaining(tvb, offset);
982 proto_tree_add_item(sub_tree, hf_eigrp_extdata_flag_ext, sub_tvb, 0, 1,
984 proto_tree_add_item(sub_tree, hf_eigrp_extdata_flag_cd, sub_tvb, 0, 1,
992 *@fn int dissect_eigrp_metric_flags (proto_tree *tree, tvbuff_t *tvb, int offset, int limit)
994 * @param[in,out] tree detail dissection result
995 * @param[in] tvb packet data
996 * @param[in] offset current byte offset in packet being processed
997 * @param[in] limit maximum number of bytes which can be process
999 * @return int number of bytes process
1002 * Dissect Protocol Dependent Module (PDM) Flags field in the route metric
1003 * section of an internal and external route. The following represents the
1004 * format of the bit field
1007 * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
1008 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1009 * | Flags | MP Flags |
1010 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1012 * | | +- Route is Replicated
1013 * | +--- Route is Active
1014 * +----- Source Withdraw
1017 dissect_eigrp_metric_flags (proto_tree *tree, tvbuff_t *tvb, int offset, int limit)
1020 proto_tree *sub_tree;
1023 /* Decode the route flags field */
1024 sub_ti = proto_tree_add_text(tree, tvb, offset, limit, "Flags");
1025 sub_tree = proto_item_add_subtree(sub_ti, ett_eigrp_metric_flags);
1026 sub_tvb = tvb_new_subset(tvb, offset, limit, -1);
1028 /* just care about 'flags' byte, there are no MP flags for now */
1029 proto_tree_add_item(sub_tree, hf_eigrp_metric_flags_srcwd, sub_tvb, 0, 1,
1031 proto_tree_add_item(sub_tree, hf_eigrp_metric_flags_active, sub_tvb, 0, 1,
1033 proto_tree_add_item(sub_tree, hf_eigrp_metric_flags_repl, sub_tvb, 0, 1,
1041 *@fn int dissect_eigrp_ipv4_addr (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1042 * packet_info *pinfo, int offset, int unreachable)
1044 * @param[in,out] tree detail dissection result
1045 * @param[in] tvb packet data
1046 * @param[in] pinfo general data about the protocol
1047 * @param[in] offset current byte offset in packet being processed
1049 * @return int number of bytes process
1052 * Dissect all IPv4 address from offset though the end of the packet
1055 dissect_eigrp_ipv4_addr (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1056 packet_info *pinfo, int offset, int unreachable)
1058 guint8 ip_addr[4], length;
1060 proto_item *ti_prefixlen, *ti_dst;
1063 for (; tvb_length_remaining(tvb, offset) > 0; offset += (1 + addr_len)) {
1064 length = tvb_get_guint8(tvb, offset);
1065 addr_len = ipv4_addr_and_mask(tvb, offset + 1, ip_addr, length);
1068 ti_prefixlen = proto_tree_add_item(tree, hf_eigrp_ipv4_prefixlen,
1069 tvb, offset, 1, ENC_BIG_ENDIAN);
1070 expert_add_info_format(pinfo, ti_prefixlen, &ei_eigrp_prefixlen, "Invalid prefix length %u, must be <= 32", length);
1071 addr_len = 4; /* assure we can exit the loop */
1074 proto_tree_add_item(tree, hf_eigrp_ipv4_prefixlen, tvb, offset, 1,
1077 ti_dst = proto_tree_add_text(tree, tvb, offset, addr_len,
1078 "Destination: %s", ip_to_str(ip_addr));
1080 /* add it to the top level line */
1081 proto_item_append_text(ti," %c %s/%u", first ? '=':',',
1082 ip_to_str(ip_addr), length);
1085 expert_add_info(pinfo, ti_dst, &ei_eigrp_unreachable);
1094 *@fn int dissect_eigrp_ipv6_addr (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1095 * packet_info *pinfo, int offset, int unreachable)
1097 * @param[in,out] tree detail dissection result
1098 * @param[in] tvb packet data
1099 * @param[in] pinfo general data about the protocol
1100 * @param[in] offset current byte offset in packet being processed
1102 * @return int number of bytes process
1105 * Dissect all IPv6 address from offset though the end of the packet
1108 dissect_eigrp_ipv6_addr (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1109 packet_info *pinfo, int offset, int unreachable)
1113 struct e_in6_addr addr;
1114 proto_item *ti_prefixlen, *ti_dst;
1117 for (; tvb_length_remaining(tvb, offset) > 0; offset += (1 + addr_len)) {
1118 length = tvb_get_guint8(tvb, offset);
1119 addr_len = ipv6_addr_and_mask(tvb, offset + 1, &addr, length);
1122 ti_prefixlen = proto_tree_add_item(tree, hf_eigrp_ipv6_prefixlen,
1123 tvb, offset, 1, ENC_BIG_ENDIAN);
1124 expert_add_info_format(pinfo, ti_prefixlen, &ei_eigrp_prefixlen, "Invalid prefix length %u, must be <= 128", length);
1125 addr_len = 16; /* assure we can exit the loop */
1127 proto_tree_add_item(tree, hf_eigrp_ipv6_prefixlen, tvb, offset, 1,
1131 if ((length < 128) && (length % 8 == 0)) {
1135 ti_dst = proto_tree_add_text(tree, tvb, offset, addr_len,
1136 "Destination: %s", ip6_to_str(&addr));
1138 /* add it to the top level line */
1139 proto_item_append_text(ti," %c %s/%u", first ? '=':',',
1140 ip6_to_str(&addr), length);
1143 expert_add_info(pinfo, ti_dst, &ei_eigrp_unreachable);
1152 *@fn int dissect_eigrp_ipx_addr (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1153 * packet_info *pinfo, int offset, int unreachable)
1155 * @param[in,out] tree detail dissection result
1156 * @param[in] tvb packet data
1157 * @param[in] pinfo general data about the protocol
1158 * @param[in] offset current byte offset in packet being processed
1160 * @return int number of bytes process
1163 * Dissect all IPX address from offset though the end of the packet
1166 dissect_eigrp_ipx_addr (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1167 packet_info *pinfo, int offset, int unreachable)
1171 ti_dst = proto_tree_add_item(tree, hf_eigrp_ipx_dest, tvb, offset, 4,
1174 /* add it to the top level line */
1175 proto_item_append_text(ti," = %s",
1176 ipxnet_to_string(tvb_get_ptr(tvb, offset, 4)));
1179 expert_add_info(pinfo, ti_dst, &ei_eigrp_unreachable);
1187 *@fn int dissect_eigrp_service (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1188 * packet_info *pinfo, int offset)
1190 * @param[in,out] tree detail dissection result
1191 * @param[in] tvb packet data
1192 * @param[in] pinfo general data about the protocol
1193 * @param[in] ti protocol item
1194 * @param[in] offset current byte offset in packet being processed
1196 * @return int number of bytes process
1199 * Dissect all SAF Services from offset though the end of the packet. The
1200 * following represents the format of a SAF Service:
1203 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1204 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1205 * | Service | SubService |
1206 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1208 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1210 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1212 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1214 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1216 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1217 * | Reachability AFI | Reachability Port |
1218 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1219 * | Reachability Protocol | Reachability Addr |
1220 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1221 * | Reachability Addr(cont) |
1222 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1223 * | Reachability Addr(cont) |
1224 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1225 * | Reachability Addr(cont) |
1226 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1227 * | Reachability Addr(cont) | Sequence |
1228 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1229 * | Sequence(cont) |\/\/\/ Service Data \/\/\/|
1230 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1234 dissect_eigrp_service (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1235 packet_info *pinfo, int offset)
1237 int afi, length, remaining;
1239 proto_item *sub_ti, *reach_ti;
1240 proto_tree *sub_tree, *reach_tree;
1241 tvbuff_t *sub_tvb, *reach_tvb;
1242 guint16 service, sub_service;
1244 remaining = tvb_length_remaining(tvb, offset);
1245 sub_ti = proto_tree_add_text(tree, tvb, offset, remaining, "SAF Service ");
1246 sub_tree = proto_item_add_subtree(sub_ti, ett_eigrp_tlv_metric);
1247 sub_tvb = tvb_new_subset(tvb, offset, remaining, -1);
1250 for (; tvb_length_remaining(sub_tvb, sub_offset) > 0; ) {
1251 service = tvb_get_ntohs(sub_tvb, sub_offset);
1252 proto_item_append_text(sub_ti, "%c %s", (sub_offset == 0 ? '=':','),
1253 val_to_str_const(service, eigrp_saf_srv2string, ""));
1255 sub_service = tvb_get_ntohs(sub_tvb, sub_offset+2);
1256 proto_item_append_text(ti, "%c %u:%u", (sub_offset == 0 ? '=':','),
1257 service, sub_service);
1259 proto_tree_add_item(sub_tree, hf_eigrp_saf_service, sub_tvb,
1260 sub_offset, 2, ENC_BIG_ENDIAN);
1262 proto_tree_add_item(sub_tree, hf_eigrp_saf_subservice, sub_tvb,
1263 sub_offset, 2, ENC_BIG_ENDIAN);
1265 proto_tree_add_item(sub_tree, hf_eigrp_saf_guid, sub_tvb,
1266 sub_offset, GUID_LEN, ENC_BIG_ENDIAN);
1267 sub_offset += GUID_LEN;
1269 proto_tree_add_item(sub_tree, hf_eigrp_saf_data_type, sub_tvb,
1270 sub_offset, 2, ENC_BIG_ENDIAN);
1272 length = tvb_get_ntohs(sub_tvb, sub_offset);
1273 proto_tree_add_item(sub_tree, hf_eigrp_saf_data_length, sub_tvb,
1274 sub_offset, 2, ENC_BIG_ENDIAN);
1278 * Reachability information
1280 reach_ti = proto_tree_add_text(sub_tree, sub_tvb, sub_offset, 22,
1282 reach_tree = proto_item_add_subtree(reach_ti, ett_eigrp_saf_reachability);
1283 reach_tvb = tvb_new_subset(sub_tvb, sub_offset, 22, -1);
1285 afi = tvb_get_ntohs(reach_tvb, 0);
1286 proto_tree_add_item(reach_tree, hf_eigrp_saf_reachability_afi,
1287 reach_tvb, 0, 2, ENC_BIG_ENDIAN);
1288 proto_tree_add_item(reach_tree, hf_eigrp_saf_reachability_port,
1289 reach_tvb, 2, 2, ENC_BIG_ENDIAN);
1290 proto_tree_add_item(reach_tree, hf_eigrp_saf_reachability_protocol,
1291 reach_tvb, 4, 2, ENC_BIG_ENDIAN);
1295 proto_tree_add_item(reach_tree, hf_eigrp_saf_reachability_addr_ipv4,
1296 reach_tvb, 6, 4, ENC_BIG_ENDIAN);
1297 proto_tree_add_item(reach_tree, hf_eigrp_nullpad, reach_tvb, 10, 12,
1302 proto_tree_add_item(reach_tree, hf_eigrp_saf_reachability_addr_ipv6,
1303 reach_tvb, 6, 16, ENC_NA);
1306 /* just print zeros... */
1307 proto_tree_add_item(reach_tree, hf_eigrp_saf_reachability_addr_hex,
1308 reach_tvb, 6, 16, ENC_NA);
1313 proto_tree_add_item(sub_tree, hf_eigrp_saf_data_sequence, sub_tvb,
1314 sub_offset, 4, ENC_BIG_ENDIAN);
1319 guint8 *test_string, *tok;
1322 * Service-Data is usually (but not always) plain text, specifically
1323 * XML. If it "looks like" XML (begins with optional white-space
1324 * followed by a '<'), try XML. Otherwise, try plain-text.
1326 xml_tvb = tvb_new_subset(sub_tvb, sub_offset, length, length);
1327 test_string = tvb_get_string(wmem_packet_scope(), xml_tvb, 0, (length < 32 ?
1329 tok = strtok(test_string, " \t\r\n");
1331 if (tok && tok[0] == '<') {
1332 /* Looks like XML */
1333 dissector_try_string(media_type_table, "application/xml",
1334 xml_tvb, pinfo, sub_tree, NULL);
1336 /* Try plain text */
1337 dissector_try_string(media_type_table, "text/plain",
1338 xml_tvb, pinfo, sub_tree, NULL);
1341 sub_offset += length;
1344 offset += sub_offset;
1349 *@fn int dissect_eigrp_legacy_metric (proto_tree *tree, tvbuff_t *tvb, int offset)
1351 * @param[in,out] tree detail dissection result
1352 * @param[in] tvb packet data
1353 * @param[in] offset current byte offset in packet being processed
1355 * @return int number of bytes process
1358 * Dissect the TLV Versions 1.2 (legacy) and 3.0 (deprecated) metric
1359 * sections. The following represents the format
1362 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1363 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1365 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1366 * | Scaled Bandwidth |
1367 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1368 * | MTU | Hopcount |
1369 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1370 * | Reliability | Load | Internal Tag | Flag |
1371 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1375 dissect_eigrp_legacy_metric (proto_tree *tree, tvbuff_t *tvb, int offset)
1378 proto_tree *sub_tree;
1381 sub_ti = proto_tree_add_text(tree, tvb, offset, 16, "Legacy Metric");
1382 sub_tree = proto_item_add_subtree(sub_ti, ett_eigrp_tlv_metric);
1383 sub_tvb = tvb_new_subset(tvb, offset, 16, -1);
1385 proto_tree_add_item(sub_tree, hf_eigrp_legacy_metric_delay, sub_tvb,
1386 0, 4, ENC_BIG_ENDIAN);
1387 proto_tree_add_item(sub_tree, hf_eigrp_legacy_metric_bw, sub_tvb,
1388 4, 4, ENC_BIG_ENDIAN);
1389 proto_tree_add_item(sub_tree, hf_eigrp_legacy_metric_mtu, sub_tvb,
1390 8, 3, ENC_BIG_ENDIAN);
1391 proto_tree_add_item(sub_tree, hf_eigrp_legacy_metric_hopcount, sub_tvb,
1392 11, 1, ENC_BIG_ENDIAN);
1393 proto_tree_add_item(sub_tree, hf_eigrp_legacy_metric_rel, sub_tvb,
1394 12, 1, ENC_BIG_ENDIAN);
1395 proto_tree_add_item(sub_tree, hf_eigrp_legacy_metric_load, sub_tvb,
1396 13, 1, ENC_BIG_ENDIAN);
1397 proto_tree_add_item(sub_tree, hf_eigrp_legacy_metric_intag, sub_tvb,
1398 14, 1, ENC_BIG_ENDIAN);
1400 /* Decode the route flags field */
1401 dissect_eigrp_metric_flags(sub_tree, sub_tvb, 15, 1);
1408 *@fn int dissect_eigrp_ipx_extdata (proto_tree *tree, tvbuff_t *tvb, int offset)
1410 * @param[in,out] tree detail dissection result
1411 * @param[in] tvb packet data
1412 * @param[in] offset current byte offset in packet being processed
1414 * @return int number of bytes process
1417 * Dissect the IPX External data for the TLV versions 1.2 and 3.0.
1418 * The following represents the format
1421 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1422 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1424 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1426 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1427 * | Ext Autonomous System Number |
1428 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1430 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1431 * | Ext Protocol | Ext Flags | External Metric |
1432 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1433 * | External Delay |
1434 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1437 dissect_eigrp_ipx_extdata (proto_tree *tree, tvbuff_t *tvb, int offset)
1440 proto_tree *sub_tree;
1444 sub_ti = proto_tree_add_text(tree, tvb, offset, 20, "External Data");
1445 sub_tree = proto_item_add_subtree(sub_ti, ett_eigrp_tlv_extdata);
1446 sub_tvb = tvb_new_subset(tvb, offset, 20, -1);
1448 /* Decode the external route source info */
1449 proto_tree_add_item(sub_tree, hf_eigrp_ipx_extdata_routerid, sub_tvb,
1450 sub_offset, 6, ENC_NA);
1452 proto_tree_add_item(sub_tree, hf_eigrp_extdata_as, sub_tvb,
1453 sub_offset, 4, ENC_BIG_ENDIAN);
1455 proto_tree_add_item(sub_tree, hf_eigrp_extdata_tag, sub_tvb,
1456 sub_offset, 4, ENC_BIG_ENDIAN);
1458 proto_tree_add_item(sub_tree, hf_eigrp_extdata_proto, sub_tvb,
1459 sub_offset, 1, ENC_BIG_ENDIAN);
1462 /* Decode the external route flags */
1463 dissect_eigrp_extdata_flags(sub_tree, sub_tvb, sub_offset);
1466 /* and the rest of it... */
1467 proto_tree_add_item(sub_tree, hf_eigrp_ipx_extdata_metric,
1468 sub_tvb, sub_offset, 2, ENC_BIG_ENDIAN);
1470 proto_tree_add_item(sub_tree, hf_eigrp_ipx_extdata_delay,
1471 sub_tvb, sub_offset, 2, ENC_BIG_ENDIAN);
1474 offset += sub_offset;
1479 *@fn int dissect_eigrp_extdata (proto_tree *tree, tvbuff_t *tvb, int offset)
1481 * @param[in,out] tree detail dissection result
1482 * @param[in] tvb packet data
1483 * @param[in] offset current byte offset in packet being processed
1485 * @return int number of bytes process
1488 * Dissect the external route data for TLV versions 1.2 and 3.0 for all
1489 * protocols except IPX. The following represents the format
1492 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1493 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1495 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1496 * | Ext Autonomous System Number |
1497 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1499 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1500 * | External Metric |
1501 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1502 * | Reserved | Ext Protocol | Ext Flags |
1503 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1506 dissect_eigrp_extdata (proto_tree *tree, tvbuff_t *tvb, int offset)
1509 proto_tree *sub_tree;
1513 sub_ti = proto_tree_add_text(tree, tvb, offset, 20, "External Data");
1514 sub_tree = proto_item_add_subtree(sub_ti, ett_eigrp_tlv_extdata);
1515 sub_tvb = tvb_new_subset(tvb, offset, 20, -1);
1517 /* Decode the external route source info */
1518 proto_tree_add_item(sub_tree, hf_eigrp_extdata_origrid, sub_tvb,
1519 sub_offset, 4, ENC_BIG_ENDIAN);
1521 proto_tree_add_item(sub_tree, hf_eigrp_extdata_as, sub_tvb,
1522 sub_offset, 4, ENC_BIG_ENDIAN);
1524 proto_tree_add_item(sub_tree, hf_eigrp_extdata_tag, sub_tvb,
1525 sub_offset, 4, ENC_BIG_ENDIAN);
1527 proto_tree_add_item(sub_tree, hf_eigrp_extdata_metric, sub_tvb,
1528 sub_offset, 4, ENC_BIG_ENDIAN);
1530 proto_tree_add_item(sub_tree, hf_eigrp_extdata_reserved, sub_tvb,
1531 sub_offset, 2, ENC_BIG_ENDIAN);
1533 proto_tree_add_item(sub_tree, hf_eigrp_extdata_proto, sub_tvb,
1534 sub_offset, 1, ENC_BIG_ENDIAN);
1537 /* Decode the external route flags */
1538 dissect_eigrp_extdata_flags(sub_tree, sub_tvb, sub_offset);
1541 offset += sub_offset;
1546 *@fn int dissect_eigrp_nexthop (proto_tree *tree, tvbuff_t *tvb, guint16 afi, int offset)
1548 * @param[in,out] tree detail dissection result
1549 * @param[in] tvb packet data
1550 * @param[in] afi IANA address family indicator
1551 * @param[in] offset current byte offset in packet being processed
1553 * @return int number of bytes process
1556 * Dissect the next hop field which is in the "route TLVs". This function will
1557 * handle all the various protocol AFIs and return the appropriate number of
1561 dissect_eigrp_nexthop (proto_tree *tree, tvbuff_t *tvb, guint16 afi, int offset)
1563 /* dissect dest information */
1567 proto_tree_add_item(tree, hf_eigrp_ipv4_nexthop, tvb, offset, 4,
1574 proto_tree_add_item(tree, hf_eigrp_ipv6_nexthop, tvb, offset, 16,
1580 proto_tree_add_item(tree, hf_eigrp_ipx_nexthop_net, tvb, offset, 4,
1583 proto_tree_add_item(tree, hf_eigrp_ipx_nexthop_host, tvb, offset, 6,
1588 case EIGRP_SF_COMMON:
1599 *@fn void dissect_eigrp_general_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1600 * packet_info *pinfo, guint16 tlv)
1602 * @param[in,out] tree detail dissection result
1603 * @param[in] tvb packet data
1604 * @param[in] pinfo general data about the protocol
1605 * @param[in] ti protocol item
1606 * @param[in] tlv Specific TLV in to be dissected
1609 * General EIGRP parameters carry EIGRP management information and are not
1610 * specific to any one routed protocol.
1614 dissect_eigrp_general_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1615 packet_info *pinfo, guint16 tlv)
1618 case EIGRP_TLV_PARAMETER:
1619 dissect_eigrp_parameter(tree, tvb, pinfo, ti);
1621 case EIGRP_TLV_AUTH:
1622 dissect_eigrp_auth_tlv(tree, tvb, pinfo, ti);
1625 dissect_eigrp_seq_tlv(tree, tvb, pinfo);
1627 case EIGRP_TLV_SW_VERSION:
1628 dissect_eigrp_sw_version(tvb, tree, ti);
1630 case EIGRP_TLV_NEXT_MCAST_SEQ:
1631 dissect_eigrp_next_mcast_seq(tvb, tree, ti);
1633 case EIGRP_TLV_PEER_STUBINFO:
1634 dissect_eigrp_peer_stubinfo(tvb, tree);
1636 case EIGRP_TLV_PEER_TERMINATION:
1637 dissect_eigrp_peer_termination(pinfo, ti);
1639 case EIGRP_TLV_PEER_TIDLIST:
1640 dissect_eigrp_peer_tidlist(tree, tvb);
1643 expert_add_info_format(pinfo, ti, &ei_eigrp_tlv_type, "Unknown Generic TLV (0x%04x)", tlv);
1649 *@fn int dissect_eigrp_ipv4_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1650 * packet_info *pinfo, guint16 tlv)
1652 * @param[in,out] tree detail dissection result
1653 * @param[in] tvb packet data
1654 * @param[in] pinfo general data about the protocol
1655 * @param[in] tlv Specific TLV in to be dissected
1657 * @return int number of bytes process
1660 * Dissect the Legacy IPv4 route TLV; handles both the internal and external
1661 * TLV types; This packet format is being deprecated and replaced with the
1662 * Multi-Protocol packet formats as of EIGRP Release-8. This TLV format is used
1663 * to maintain backward compatibility between older version so EIGRP, "MTR"
1664 * EIGRP, and current shipping code.
1667 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1668 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1670 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1672 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1673 * | Scaled Bandwidth |
1674 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1675 * | MTU | Hopcount |
1676 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1677 * | Reliability | Load | Internal Tag | Flag |
1678 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1681 dissect_eigrp_ipv4_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1682 packet_info *pinfo, guint16 tlv)
1685 int unreachable = FALSE;
1687 proto_tree_add_item(tree, hf_eigrp_ipv4_nexthop, tvb, offset, 4,
1691 /* dissect external data if needed */
1692 if ((tlv & EIGRP_TLV_TYPEMASK) == EIGRP_TLV_EXTERNAL) {
1693 offset = dissect_eigrp_extdata(tree, tvb, offset);
1696 /* dissect the metric */
1697 offset = dissect_eigrp_legacy_metric(tree, tvb, offset);
1699 /* dissect addresses */
1700 offset = dissect_eigrp_ipv4_addr(ti, tree, tvb, pinfo, offset, unreachable);
1706 *@fn void dissect_eigrp_atalk_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1707 * proto_item *ti, guint16 tlv)
1709 * @param[in,out] tree detail dissection result
1710 * @param[in] tvb packet data
1711 * @param[in] tlv Specific TLV in to be dissected
1714 * Dissect the legacy AppleTalk route TLV; handles both the internal and external
1715 * TLV type. The following represents the format
1718 dissect_eigrp_atalk_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1724 if (EIGRP_TLV_AT_CBL == tlv) {
1725 proto_tree_add_text(tree, tvb, 0, 4, "AppleTalk Cable Range = %u-%u",
1726 tvb_get_ntohs(tvb, 0), tvb_get_ntohs(tvb, 2));
1727 proto_tree_add_item(tree, hf_eigrp_atalk_routerid, tvb, 4, 4,
1729 proto_item_append_text(ti, ": Cable range= %u-%u, Router ID= %u",
1730 tvb_get_ntohs(tvb, 0), tvb_get_ntohs(tvb, 2),
1731 tvb_get_ntohl(tvb, 4));
1734 proto_tree_add_text(tree, tvb, offset, 4, "NextHop Address = %u.%u",
1735 tvb_get_ntohs(tvb, 0), tvb_get_ntohs(tvb, 2));
1738 /* dissect external data if needed */
1739 if ((tlv & EIGRP_TLV_TYPEMASK) == EIGRP_TLV_EXTERNAL) {
1740 offset = dissect_eigrp_extdata(tree, tvb,offset);
1743 /* dissect the metric */
1744 offset = dissect_eigrp_legacy_metric(tree, tvb, offset);
1746 /* dissect cable range */
1747 proto_tree_add_text(tree, tvb, offset, 4, "Cable range = %u-%u",
1748 tvb_get_ntohs(tvb, 36), tvb_get_ntohs(tvb, 38));
1749 proto_item_append_text(ti, ": %u-%u",
1750 tvb_get_ntohs(tvb, 36), tvb_get_ntohs(tvb, 38));
1756 *@fn void dissect_eigrp_ipv6_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1757 * packet_info *pinfo, guint16 tlv)
1759 * @param[in,out] tree detail dissection result
1760 * @param[in] tvb packet data
1761 * @param[in] pinfo general data about the protocol
1762 * @param[in] tlv Specific TLV in to be dissected
1765 * Dissect the Legacy IPv6 route TLV; handles both the internal and external
1766 * TLV types; This packet format is being deprecated and replaced with the
1767 * Multi-Protocol packet formats as of EIGRP Release-8. This TLV format is used
1768 * to maintain backward compatibility between older version so EIGRP, "MTR"
1769 * EIGRP, and current shipping code.
1772 dissect_eigrp_ipv6_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1773 packet_info *pinfo, guint16 tlv)
1776 int unreachable = FALSE;
1778 proto_tree_add_item(tree, hf_eigrp_ipv6_nexthop, tvb, offset, 16,
1782 /* dissect external data if needed */
1783 if ((tlv & EIGRP_TLV_TYPEMASK) == EIGRP_TLV_EXTERNAL) {
1784 offset = dissect_eigrp_extdata(tree, tvb, offset);
1787 /* dissect the metric */
1788 offset = dissect_eigrp_legacy_metric(tree, tvb, offset);
1790 /* dissect addresses */
1791 dissect_eigrp_ipv6_addr(ti, tree, tvb, pinfo, offset, unreachable);
1796 *@fn int dissect_eigrp_ipx_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1797 * packet_info *pinfo, guint16 tlv)
1799 * @param[in,out] tree detail dissection result
1800 * @param[in] tvb packet data
1801 * @param[in] pinfo general data about the protocol
1802 * @param[in] tlv Specific TLV in to be dissected
1804 * @return int number of bytes process
1807 * Dissect the legacy IPX route TLV; handles both the internal and external
1808 * TLV type. The following represents the format
1811 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1812 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1814 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1816 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1817 * | Nexthop Host(cont) |
1818 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1820 * Optional External Data:
1821 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1823 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1825 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1826 * | Ext Autonomous System Number |
1827 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1829 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1830 * | Ext Protocol | Ext Flags | External Metric |
1831 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1832 * | External Delay |
1833 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1835 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1837 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1838 * | Scaled Delay | Scaled Bandwidth |
1839 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1840 * | Scaled Bandwidth | MTU |
1841 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1842 * | MTU(cont) | Hopcount | Reliability | Load |
1843 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1844 * | Internal Tag | Flag |
1845 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1850 dissect_eigrp_ipx_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1851 packet_info *pinfo, guint16 tlv)
1854 int unreachable = FALSE;
1856 /* nexthop for route... */
1857 offset = dissect_eigrp_nexthop(tree, tvb, EIGRP_AF_IPX, offset);
1859 /* dissect external data if needed */
1860 if ((tlv & EIGRP_TLV_TYPEMASK) == EIGRP_TLV_EXTERNAL) {
1861 offset = dissect_eigrp_ipx_extdata(tree, tvb, offset);
1864 /* dissect the metric */
1865 offset = dissect_eigrp_legacy_metric(tree, tvb, offset);
1867 /* dissect addresses */
1868 offset = dissect_eigrp_ipx_addr(ti, tree, tvb, pinfo, offset, unreachable);
1874 *@fn void dissect_eigrp_ipv4_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1875 * packet_info *pinfo, proto_item *ti, guint16 tlv)
1877 * @param[in,out] tree detail dissection result
1878 * @param[in] tvb packet data
1879 * @param[in] pinfo general data about the protocol
1880 * @param[in] ti protocol item
1881 * @param[in] tlv Specific TLV in to be dissected
1883 * @return int number of bytes process
1886 * Dissect the Multi-Topology route TLV; This packet format has been deprecated
1887 * and replaced with the Multi-Protocol packet formats as of EIGRP Release-8. Of
1888 * course this means it will be around for a long long while. The following
1889 * represents the format
1892 * 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
1893 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1895 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1896 * | Topology Identifier | Family Identifier |
1897 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1899 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1901 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1903 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1904 * | Scaled Bandwidth |
1905 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1906 * | MTU | Hopcount |
1907 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1908 * | Reliability | Load | Internal Tag | Flag |
1909 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1910 * |\/\/\/ NextHop (Family Specific Length) \/\/\/|
1911 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1912 * |\/\/\/ External Route Data (Optional) \/\/\/|
1913 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1914 * |\/\/\/ Destination (Family Specific Length) \/\/\/|
1915 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1919 dissect_eigrp_multi_topology_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1920 packet_info *pinfo, guint16 tlv)
1924 int unreachable = FALSE;
1927 proto_tree_add_item(tree, hf_eigrp_tid, tvb, offset, 2, ENC_BIG_ENDIAN);
1930 /* now it's all about the family */
1931 afi = tvb_get_ntohs(tvb, offset);
1932 proto_tree_add_item(tree, hf_eigrp_afi, tvb, offset, 2, ENC_BIG_ENDIAN);
1935 /* gota have an id... */
1936 proto_tree_add_item(tree, hf_eigrp_routerid, tvb, offset, 4, ENC_BIG_ENDIAN);
1939 /* tag.. your it! */
1940 proto_tree_add_item(tree, hf_eigrp_legacy_metric_tag, tvb, offset, 4, ENC_BIG_ENDIAN);
1943 /* dissect the metric */
1944 offset = dissect_eigrp_legacy_metric(tree, tvb, offset);
1946 /* dissect nexthop */
1947 offset = dissect_eigrp_nexthop(tree, tvb, afi, offset);
1949 /* dissect external data if needed */
1950 if ((tlv & EIGRP_TLV_TYPEMASK) == EIGRP_TLV_EXTERNAL) {
1951 if (afi == EIGRP_AF_IPX) {
1952 offset = dissect_eigrp_ipx_extdata(tree, tvb, offset);
1954 offset = dissect_eigrp_extdata(tree, tvb, offset);
1958 /* dissect dest information */
1961 offset = dissect_eigrp_ipv4_addr(ti, tree, tvb, pinfo, offset, unreachable);
1964 offset = dissect_eigrp_ipv6_addr(ti, tree, tvb, pinfo, offset, unreachable);
1967 offset = dissect_eigrp_ipx_addr(ti, tree, tvb, pinfo, offset, unreachable);
1970 case EIGRP_SF_COMMON:
1973 offset = dissect_eigrp_service(ti, tree, tvb, pinfo, offset);
1977 proto_tree_add_expert(tree, pinfo, &ei_eigrp_afi, tvb, offset, -1);
1984 *@fn int dissect_eigrp_metric_comm (proto_tree *tree, tvbuff_t *tvb, int offset, int limit)
1986 * @param[in,out] tree detail dissection result
1987 * @param[in] tvb packet data
1988 * @param[in] offset current byte offset in packet being processed
1989 * @param[in] limit maximum number of bytes which can be process
1991 * @return int number of bytes process
1994 * Dissect extended community attached to metric TLVs to support VPNv4
1995 * deployments, The following represents the format
1998 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1999 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2000 * | Type high | Type low(*) | |
2001 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Value |
2003 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2006 dissect_eigrp_metric_comm (proto_tree *tree, tvbuff_t *tvb, int offset, int limit)
2011 comm_type = tvb_get_ntohs(tvb, offset);
2014 switch (comm_type) {
2016 * Tag for this route. It is present for all EIGRP VPNv4
2017 * routes, internal and external
2019 case EIGRP_EXTCOMM_EIGRP:
2020 proto_tree_add_text(tree, tvb, offset, 8,
2021 "Type(EIGRP_EXTCOMM_EIGRP): Flag(0x%02x) Tag(%u)",
2022 tvb_get_ntohs(tvb, 0),
2023 tvb_get_ntohl(tvb, 2));
2025 case EIGRP_EXTCOMM_VRR:
2026 proto_tree_add_text(tree, tvb, offset, 8,
2027 "Type(EIGRP_EXTCOMM_VRR)): RES(0x%02x) RID(0x%04x)",
2028 tvb_get_ntohs(tvb, 0),
2029 tvb_get_ntohl(tvb, 2));
2033 * Vecmetric information for given EIGRP VPNv4 route,
2034 * applies to both internal and external
2036 case EIGRP_EXTCOMM_DAD:
2037 proto_tree_add_text(tree, tvb, offset, 8,
2038 "Type(EIGRP_EXTCOMM_DAD): AS(%u):SDLY(%u)",
2039 tvb_get_ntohs(tvb, 0),
2040 tvb_get_ntohl(tvb, 2));
2042 case EIGRP_EXTCOMM_VRHB:
2043 proto_tree_add_text(tree, tvb, offset, 8,
2044 "Type(EIGRP_EXTCOMM_VRHB): REL(%u) HOP(%u) SBW(%u)",
2045 tvb_get_guint8(tvb, 0),
2046 tvb_get_guint8(tvb, 1),
2047 tvb_get_ntohl(tvb, 2));
2049 case EIGRP_EXTCOMM_SRLM:
2050 proto_tree_add_text(tree, tvb, offset, 8,
2051 "Type(EIGRP_EXTCOMM_SRLM): RES(%u) LOAD(%u) MTU(%u)",
2052 tvb_get_guint8(tvb, 0),
2053 tvb_get_guint8(tvb, 1),
2054 tvb_get_ntohl(tvb, 2));
2058 * External information for given EIGRP VPNv4 route,
2059 * applies to only to external routes
2061 case EIGRP_EXTCOMM_SAR:
2062 proto_tree_add_text(tree, tvb, offset, 8,
2063 "Type(EIGRP_EXTCOMM_SAR): xAS(%u) xRID(%u)",
2064 tvb_get_ntohs(tvb, 0),
2065 tvb_get_ntohl(tvb, 2));
2067 case EIGRP_EXTCOMM_RPM:
2068 proto_tree_add_text(tree, tvb, offset, 8,
2069 "Type(EIGRP_EXTCOMM_RPM): xProto(%u) xMETRIC(%u)",
2070 tvb_get_ntohs(tvb, 0),
2071 tvb_get_ntohl(tvb, 2));
2074 case EIGRP_EXTCOMM_SOO_ASFMT:
2075 case EIGRP_EXTCOMM_SOO_ADRFMT:
2076 proto_tree_add_text(tree, tvb, offset, 8,
2077 "Type(EIGRP_EXTCOMM_SOO): AS(%u) TAG(%u)",
2078 tvb_get_ntohs(tvb, 0),
2079 tvb_get_ntohl(tvb, 2));
2097 *@fn int dissect_eigrp_wide_metric_attr (proto_tree *tree, tvbuff_t *tvb,
2098 * int offset, int limit)
2100 * @param[in,out] tree detail dissection result
2101 * @param[in] tvb packet data
2102 * @param[in] offset current byte offset in packet being processed
2103 * @param[in] limit maximum number of words which should be process
2105 * @return int number of bytes process
2108 * Dissect the Metric Attributes which (optionally) are part of the wide-metric
2109 * route TLV. Some of the attributes which effect the metric are controlled by
2110 * K6 which is now part of the Parameter TLV. Also, eh extended community TLV is
2111 * no longer used, as it's now appended to the route
2114 dissect_eigrp_wide_metric_attr (proto_tree *tree, tvbuff_t *tvb,
2115 int offset, int limit)
2118 proto_tree *sub_tree;
2122 guint16 attr_offset = 0;
2123 guint8 attr_opcode = 0;
2125 limit *= 2; /* words to bytes */
2127 sub_ti = proto_tree_add_text(tree, tvb, offset, limit, "Attributes");
2128 sub_tree = proto_item_add_subtree(sub_ti, ett_eigrp_tlv_attr);
2129 sub_tvb = tvb_new_subset(tvb, offset, limit, -1);
2133 attr_opcode = tvb_get_guint8(sub_tvb, sub_offset);
2134 proto_tree_add_item(sub_tree, hf_eigrp_attr_opcode, sub_tvb,
2135 sub_offset, 1, ENC_BIG_ENDIAN);
2138 attr_offset = tvb_get_guint8(sub_tvb, sub_offset) * 2;
2139 proto_tree_add_item(sub_tree, hf_eigrp_attr_offset, sub_tvb,
2140 sub_offset, 1, ENC_BIG_ENDIAN);
2143 switch (attr_opcode) {
2144 case EIGRP_ATTR_NOOP:
2147 case EIGRP_ATTR_SCALED:
2148 proto_tree_add_item(sub_tree, hf_eigrp_attr_scaled, sub_tvb,
2149 sub_offset, 4, ENC_BIG_ENDIAN);
2152 case EIGRP_ATTR_TAG:
2153 proto_tree_add_item(sub_tree, hf_eigrp_attr_tag, sub_tvb,
2154 sub_offset, 4, ENC_BIG_ENDIAN);
2157 case EIGRP_ATTR_COMM:
2158 dissect_eigrp_metric_comm(sub_tree,
2159 tvb_new_subset(sub_tvb, sub_offset, 8, -1),
2163 case EIGRP_ATTR_JITTER:
2164 proto_tree_add_item(sub_tree, hf_eigrp_attr_jitter, sub_tvb,
2165 sub_offset, 4, ENC_BIG_ENDIAN);
2168 case EIGRP_ATTR_QENERGY:
2169 proto_tree_add_item(sub_tree, hf_eigrp_attr_qenergy, sub_tvb,
2170 sub_offset, 4, ENC_BIG_ENDIAN);
2173 case EIGRP_ATTR_ENERGY:
2174 proto_tree_add_item(sub_tree, hf_eigrp_attr_energy, sub_tvb,
2175 sub_offset, 4, ENC_BIG_ENDIAN);
2181 sub_offset += attr_offset;
2182 limit -= (EIGRP_ATTR_HDRLEN + attr_offset);
2185 offset += sub_offset;
2190 *@fn int dissect_eigrp_wide_metric (proto_tree *tree, tvbuff_t *tvb, int offset)
2192 * @param[in,out] tree detail dissection result
2193 * @param[in] tvb packet data
2194 * @param[in] offset current byte offset in packet being processed
2196 * @return int number of bytes process
2199 * Dissect the latest-n-greatest "Wide"Metric" definition for EIGRP. This
2200 * definition was created to address the higher speed links and should handle
2201 * things until we break the speed of light *wink*
2204 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2205 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2206 * | Offset | Priority | Reliability | Load |
2207 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2208 * | MTU | Hopcount |
2209 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2211 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2212 * | Delay | Bandwidth |
2213 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2215 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2216 * | Reserved | Flags |
2217 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2218 * |\/\/\/ Extended Metrics (Variable Length) \/\/\/|
2219 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2223 dissect_eigrp_wide_metric (proto_tree *tree, tvbuff_t *tvb, int offset)
2226 proto_tree *sub_tree;
2228 gint8 attr_size = 0;
2231 sub_ti = proto_tree_add_text(tree, tvb, offset, 24, "Wide Metric");
2232 sub_tree = proto_item_add_subtree(sub_ti, ett_eigrp_tlv_metric);
2233 sub_tvb = tvb_new_subset(tvb, offset, 24, -1);
2235 attr_size = tvb_get_guint8(sub_tvb, 0);
2237 proto_tree_add_item(sub_tree, hf_eigrp_metric_offset,
2238 sub_tvb, 0, 1, ENC_BIG_ENDIAN);
2239 proto_tree_add_item(sub_tree, hf_eigrp_metric_priority,
2240 sub_tvb, 1, 1, ENC_BIG_ENDIAN);
2241 proto_tree_add_item(sub_tree, hf_eigrp_metric_rel,
2242 sub_tvb, 2, 1, ENC_BIG_ENDIAN);
2243 proto_tree_add_item(sub_tree, hf_eigrp_metric_load,
2244 sub_tvb, 3, 1, ENC_BIG_ENDIAN);
2245 proto_tree_add_item(sub_tree, hf_eigrp_metric_mtu,
2246 sub_tvb, 4, 3, ENC_BIG_ENDIAN);
2247 proto_tree_add_item(sub_tree, hf_eigrp_metric_hopcount,
2248 sub_tvb, 7, 1, ENC_BIG_ENDIAN);
2250 /* The one-way latency along an unloaded path to the destination
2251 * expressed in units of nanoseconds per kilobyte. This number is not
2252 * scaled, as is the case with scaled delay. A delay of 0xFFFFFFFFFFFF
2253 * indicates an unreachable route. */
2254 big_num = tvb_get_ntoh64(sub_tvb, 8);
2256 if (big_num == G_GUINT64_CONSTANT(0x0000ffffffffffff)) {
2257 proto_tree_add_text(sub_tree, sub_tvb, 8, 6, "Delay: Infinity");
2259 proto_tree_add_text(sub_tree, sub_tvb, 8, 6, "Delay: %" G_GINT64_MODIFIER "u", big_num);
2262 /* The path bandwidth measured in kilobyte per second as presented by
2263 * the interface. This number is not scaled, as is the case with scaled
2264 * bandwidth. A bandwidth of 0xFFFFFFFFFFFF indicates an unreachable
2267 big_num = tvb_get_ntoh64(sub_tvb, 14);
2269 if (big_num == G_GUINT64_CONSTANT(0x0000ffffffffffff)) {
2270 proto_tree_add_text(sub_tree, sub_tvb, 14, 6, "Bandwidth: Infinity");
2272 proto_tree_add_text(sub_tree, sub_tvb, 14, 6, "Bandwidth: %" G_GINT64_MODIFIER "u", big_num);
2274 proto_tree_add_item(sub_tree, hf_eigrp_metric_reserved, sub_tvb, 20, 2,
2277 /* Decode the route flags field */
2278 dissect_eigrp_metric_flags(sub_tree, sub_tvb, 22, 2);
2281 /* any extended metric attributes? */
2282 if (attr_size > 0) {
2283 offset = dissect_eigrp_wide_metric_attr(tree, tvb, offset, attr_size);
2290 *@fn int dissect_eigrp_multi_protocol_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
2291 * packet_info *pinfo, guint16 tlv)
2294 * @param[in,out] tree detail dissection result
2295 * @param[in] tvb packet data
2296 * @param[in] ti protocol item
2297 * @param[in] pinfo general data about the protocol
2299 * @return int number of bytes process
2302 * Dissect the Multi-Protocol (TLV Version 2.0) TLV format definition. The following
2303 * represents the format
2306 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2307 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2308 * | Topology Identifier | Family Identifier |
2309 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2311 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2313 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2314 * |\/\/\/ Extended Metrics (Variable Length) \/\/\/|
2315 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2316 * |\/\/\/ NextHop (Family Specific Length) \/\/\/|
2317 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2318 * |\/\/\/ External Route Data (Optional) \/\/\/|
2319 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2320 * |\/\/\/ Destination (Family Specific Length) \/\/\/|
2321 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2324 dissect_eigrp_multi_protocol_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
2325 packet_info *pinfo, guint16 tlv)
2329 int unreachable = FALSE;
2332 proto_tree_add_item(tree, hf_eigrp_tid, tvb, offset, 2, ENC_BIG_ENDIAN);
2335 /* now it's all about the family */
2336 afi = tvb_get_ntohs(tvb, offset);
2337 proto_tree_add_item(tree, hf_eigrp_afi, tvb, offset, 2, ENC_BIG_ENDIAN);
2340 /* gota have an id... */
2341 proto_tree_add_item(tree, hf_eigrp_routerid, tvb, offset, 4, ENC_BIG_ENDIAN);
2344 /* decode the wide metric */
2345 offset = dissect_eigrp_wide_metric(tree, tvb, offset);
2347 /* dissect nexthop */
2348 offset = dissect_eigrp_nexthop(tree, tvb, afi, offset);
2350 /* dissect external data if needed */
2351 if ((tlv & EIGRP_TLV_TYPEMASK) == EIGRP_TLV_EXTERNAL) {
2352 if (afi == EIGRP_AF_IPX) {
2353 offset = dissect_eigrp_ipx_extdata(tree, tvb, offset);
2355 offset = dissect_eigrp_extdata(tree, tvb, offset);
2359 /* dissect dest information */
2362 offset = dissect_eigrp_ipv4_addr(ti, tree, tvb, pinfo, offset, unreachable);
2366 offset = dissect_eigrp_ipv6_addr(ti, tree, tvb, pinfo, offset, unreachable);
2370 offset = dissect_eigrp_ipx_addr(ti, tree, tvb, pinfo, offset, unreachable);
2373 case EIGRP_SF_COMMON:
2376 offset = dissect_eigrp_service(ti, tree, tvb, pinfo, offset);
2380 proto_tree_add_expert(tree, pinfo, &ei_eigrp_afi, tvb, offset, -1);
2387 *@fn int dissect_eigrp (proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, void *data)
2389 * @param[in] tvb packet data
2390 * @param[in] pinfo general data about the protocol
2391 * @param[in,out] tree detail dissection result
2393 * @return int 0 if packet is not for this decoder
2396 * This function is called to dissect the packets presented to it. The packet
2397 * data is held in a special buffer referenced here as tvb. The packet info
2398 * structure contains general data about the protocol, and can update
2399 * information here. The tree parameter is where the detail dissection takes
2402 #include <epan/in_cksum.h>
2404 static guint16 ip_checksum(const guint8 *ptr, int len)
2408 cksum_vec[0].ptr = ptr;
2409 cksum_vec[0].len = len;
2410 return in_cksum(&cksum_vec[0], 1);
2413 dissect_eigrp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2416 proto_tree *eigrp_tree = NULL, *tlv_tree;
2418 guint16 tlv, checksum, cacl_checksum;
2419 guint32 ack, size, offset = EIGRP_HEADER_LENGTH;
2421 /* Make entries in Protocol column and Info column on summary display */
2422 col_set_str(pinfo->cinfo, COL_PROTOCOL, "EIGRP");
2424 /* This field shows up as the "Info" column in the display; you should use
2425 * it, if possible, to summarize what's in the packet, so that a user
2426 * looking at the list of packets can tell what type of packet it is. See
2427 * section 1.5 for more information.
2429 col_clear(pinfo->cinfo, COL_INFO);
2431 opcode = tvb_get_guint8(tvb, 1);
2432 ack = tvb_get_ntohl(tvb, 12);
2433 if ((opcode == EIGRP_OPC_HELLO) && (0 != ack)) {
2434 opcode = EIGRP_OPC_ACK;
2437 col_add_str(pinfo->cinfo, COL_INFO,
2438 val_to_str(opcode, eigrp_opcode2string, "Unknown OpCode (0x%04x)"));
2440 /* A protocol dissector may be called in 2 different ways - with, or
2441 * without a non-null "tree" argument.
2442 * Note also that there is no guarantee, the first time the dissector is
2443 * called, whether "tree" will be null or not; your dissector must work
2444 * correctly, building or updating whatever state information is necessary,
2447 /* NOTE: The offset and length values in the call to
2448 * "proto_tree_add_item()" define what data bytes to highlight in the
2449 * hex display window when the line in the protocol tree display
2450 * corresponding to that item is selected.
2453 /* create display subtree for the protocol */
2454 ti = proto_tree_add_protocol_format(tree, proto_eigrp, tvb, 0, -1,
2456 eigrp_tree = proto_item_add_subtree(ti, ett_eigrp);
2457 proto_tree_add_item(eigrp_tree, hf_eigrp_version, tvb, 0, 1,
2459 proto_tree_add_item(eigrp_tree, hf_eigrp_opcode, tvb, 1, 1,
2462 size = tvb_length(tvb);
2463 checksum = tvb_get_ntohs(tvb, 2);
2464 cacl_checksum = ip_checksum(tvb_get_ptr(tvb, 0, size), size);
2466 if (cacl_checksum == checksum) {
2467 proto_tree_add_text(eigrp_tree, tvb, 2, 2,
2468 "Checksum: 0x%02x [incorrect]",
2470 expert_add_info(pinfo, ti, &ei_eigrp_checksum_bad);
2472 proto_tree_add_text(eigrp_tree, tvb, 2, 2,
2473 "Checksum: 0x%02x [correct]", checksum);
2476 /* Decode the EIGRP Flags Field */
2477 proto_tree_add_bitmask(eigrp_tree, tvb, 4, hf_eigrp_flags, ett_eigrp_flags,
2478 eigrp_flag_fields, ENC_BIG_ENDIAN);
2480 proto_tree_add_item(eigrp_tree, hf_eigrp_sequence, tvb, 8, 4,
2482 proto_tree_add_item(eigrp_tree, hf_eigrp_acknowledge, tvb, 12, 4,
2485 /* print out what family we dealing with... */
2486 ti = proto_tree_add_item(eigrp_tree, hf_eigrp_vrid, tvb, 16, 2,
2488 vrid = (tvb_get_ntohs(tvb, 16) & EIGRP_VRID_MASK);
2489 proto_item_append_text(ti, " %s", val_to_str_const(vrid, eigrp_vrid2string, ""));
2491 /* print autonomous-system */
2492 proto_tree_add_item(eigrp_tree, hf_eigrp_as, tvb, 18, 2,
2496 case EIGRP_OPC_IPXSAP:
2497 call_dissector(ipxsap_handle,
2498 tvb_new_subset_remaining(tvb, EIGRP_HEADER_LENGTH), pinfo,
2503 while (tvb_reported_length_remaining(tvb, offset) > 0) {
2504 tlv = tvb_get_ntohs(tvb, offset);
2506 /* it's a rose by the wrong name... */
2507 if (tlv == EIGRP_TLV_MTR_TIDLIST) {
2508 tlv = EIGRP_TLV_PEER_TIDLIST;
2511 size = tvb_get_ntohs(tvb, offset + 2);
2513 proto_tree_add_expert(eigrp_tree, pinfo, &ei_eigrp_tlv_len, tvb, offset, -1);
2514 return(tvb_length(tvb));
2517 ti = proto_tree_add_text(eigrp_tree, tvb, offset, size, "%s",
2518 val_to_str(tlv, eigrp_tlv2string, "Unknown TLV (0x%04x)"));
2520 tlv_tree = proto_item_add_subtree(ti, ett_eigrp_tlv);
2521 proto_tree_add_item(tlv_tree, hf_eigrp_tlv_type, tvb,
2522 offset, 2, ENC_BIG_ENDIAN);
2523 proto_tree_add_item(tlv_tree, hf_eigrp_tlv_len, tvb,
2524 (offset + 2), 2, ENC_BIG_ENDIAN);
2526 switch (tlv & EIGRP_TLV_RANGEMASK) {
2527 case EIGRP_TLV_GENERAL:
2528 dissect_eigrp_general_tlv(ti, tlv_tree, tvb_new_subset(tvb, (offset + 4), (size - 4), -1), pinfo, tlv);
2531 case EIGRP_TLV_IPv4:
2532 dissect_eigrp_ipv4_tlv(ti, tlv_tree, tvb_new_subset(tvb, (offset + 4), (size - 4), -1), pinfo, tlv);
2535 case EIGRP_TLV_ATALK:
2536 dissect_eigrp_atalk_tlv(ti, tlv_tree, tvb_new_subset(tvb, (offset + 4), (size - 4), -1), tlv);
2540 dissect_eigrp_ipx_tlv(ti, tlv_tree, tvb_new_subset(tvb, (offset + 4), (size - 4), -1), pinfo, tlv);
2543 case EIGRP_TLV_IPv6:
2544 dissect_eigrp_ipv6_tlv(ti, tlv_tree, tvb_new_subset(tvb, (offset + 4), (size - 4), -1), pinfo, tlv);
2548 dissect_eigrp_multi_protocol_tlv(ti, tlv_tree, tvb_new_subset(tvb, (offset + 4), (size - 4), -1),
2553 dissect_eigrp_multi_topology_tlv(ti, tlv_tree, tvb_new_subset(tvb, (offset + 4), (size - 4), -1),
2558 expert_add_info_format(pinfo, ti, &ei_eigrp_tlv_type, "Unknown TLV Group (0x%04x)", tlv);
2566 /* Return the amount of data this dissector was able to dissect */
2567 return(tvb_length(tvb));
2571 *@fn void proto _ register _ eigrp (void)
2574 * you can not have the function name inside a comment or else Wireshark
2575 * will fail with "duplicate protocol" error. Dont you hate it when tools
2576 * try to be to smart :(
2579 * Register the protocol with Wireshark
2580 * this format is require because a script is used to build the C function
2581 * that calls all the protocol registration.
2584 proto_register_eigrp(void)
2586 /* Setup list of header fields See Section 1.6.1 for details
2588 static hf_register_info hf[] = {
2591 * EIGRP Packet Header definitions
2594 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
2595 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2596 * |Ver | Opcode | Checksum |
2597 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2599 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2600 * | Sequence number |
2601 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2602 * | Acknowledgement number |
2603 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2604 * | Virtual Router ID | Autonomous system number |
2605 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2607 { &hf_eigrp_version,
2608 { "Version", "eigrp.version",
2609 FT_UINT8, BASE_DEC, NULL, 0x0,
2610 "Version - Version of EIGRP packet format", HFILL }
2613 { "Opcode", "eigrp.opcode",
2614 FT_UINT8, BASE_DEC, VALS(eigrp_opcode2string), 0x0,
2615 "Opcode - Operation code indicating the message type", HFILL }
2618 { "Flags", "eigrp.flags",
2619 FT_UINT32, BASE_HEX, NULL, 0x0,
2620 "Flag - Initialization bit and is used in establishing "
2621 "a new neighbor relationship", HFILL }
2623 { &hf_eigrp_sequence,
2624 { "Sequence", "eigrp.seq",
2625 FT_UINT32, BASE_DEC, NULL, 0x0,
2626 "Sequence number -- used to send messages reliably", HFILL }
2628 { &hf_eigrp_acknowledge,
2629 { "Acknowledge", "eigrp.ack",
2630 FT_UINT32, BASE_DEC, NULL, 0x0,
2631 "Acknowledge number -- used to send messages reliably", HFILL }
2634 { "Virtual Router ID", "eigrp.vrid",
2635 FT_UINT16, BASE_DEC, NULL, 0,
2636 "Virtual Router ID - For each Virtual Router, there is a separate topology "
2637 "table and routing/service table; even for matching AS. "
2638 "This field allows the gateway to select which set router to use.", HFILL }
2641 { "Autonomous System", "eigrp.as",
2642 FT_UINT16, BASE_DEC, NULL, 0x0,
2643 "Autonomous system number - Each AS has a separate topology table "
2644 "which for a give routing/service table. A gateway can participate "
2645 "in more than one AS. This field allows the gateway to"
2646 "select which set of topology tables to use.", HFILL }
2650 * Define eigrp_flags bits here
2652 * Init bit definition. First unicast transmitted Update has this
2653 * bit set in the flags field of the fixed header. It tells the neighbor
2654 * to send its full topology table.
2656 { &hf_eigrp_flags_init,
2657 { "Init", "eigrp.flags.init",
2658 FT_BOOLEAN, 32, TFS(&tfs_set_notset), EIGRP_INIT_FLAG,
2659 "Init - tells the neighbor to send its full topology table", HFILL }
2663 * Conditionally Received - Any packet with the CR-bit set can
2664 * be accepted by an EIGRP speaker if and only if a previous Hello was
2665 * received with the SEQUENCE_TYPE TLV present.
2666 * This allows multicasts to be transmitted in order and reliably at the
2667 * same time as unicasts are transmitted.
2669 { &hf_eigrp_flags_condrecv,
2670 { "Conditional Receive", "eigrp.flags.condrecv",
2671 FT_BOOLEAN, 32, TFS(&tfs_set_notset), EIGRP_CR_FLAG,
2672 "Conditionally Received the next packet if address was in listed "
2673 "in the previous HELLO", HFILL }
2677 * Restart flag is set in the hello and the init update
2678 * packets during the nsf signaling period. A nsf-aware
2679 * router looks at the RS flag to detect if a peer is restarting
2680 * and maintain the adjacency. A restarting router looks at
2681 * this flag to determine if the peer is helping out with the restart.
2683 { &hf_eigrp_flags_restart,
2684 { "Restart", "eigrp.flags.restart",
2685 FT_BOOLEAN, 32, TFS(&tfs_set_notset), EIGRP_RS_FLAG,
2686 "Restart flag - Set in the HELLO and the initial "
2687 "UPDATE packets during the nsf signaling period.", HFILL },
2691 * EOT bit. The End-of-Table flag marks the end of the start-up updates
2692 * sent to a new peer. A nsf restarting router looks at this flag to
2693 * determine if it has finished receiving the start-up updates from all
2694 * peers. A nsf-aware router waits for this flag before cleaning up
2695 * the stale routes from the restarting peer.
2697 { &hf_eigrp_flags_eot,
2698 { "End Of Table", "eigrp.flags.eot",
2699 FT_BOOLEAN, 32, TFS(&tfs_set_notset), EIGRP_EOT_FLAG,
2700 "End-of-Table - Marks the end of the start-up UPDATES indicating the "
2701 "complete topology database has been sent to a new peer", HFILL }
2705 * TLV type definitions. Generic (protocol-independent) TLV types are
2706 * defined here. Protocol-specific ones are defined later
2708 * +-----+------------------+
2710 * | Type| Len | Vector |
2712 * +-----+------------------+
2714 * TLV type definitions. Generic (protocol-independent) TLV types are
2715 * defined here. Protocol-specific ones are defined elsewhere.
2717 * EIGRP_PARAMETER 0x0001 parameter
2718 * EIGRP_AUTH 0x0002 authentication
2719 * EIGRP_SEQUENCE 0x0003 sequenced packet
2720 * EIGRP_SW_VERSION 0x0004 software version
2721 * EIGRP_NEXT_MCAST_SEQ 0x0005 multicast sequence
2722 * EIGRP_PEER_STUBINFO 0x0006 stub information
2723 * EIGRP_PEER_TERMINATION 0x0007 peer termination
2725 { &hf_eigrp_tlv_type,
2726 { "Type", "eigrp.tlv_type",
2727 FT_UINT16, BASE_HEX, VALS(eigrp_tlv2string), 0x0,
2730 { &hf_eigrp_tlv_len,
2731 { "Length", "eigrp.tlv.len",
2732 FT_UINT16, BASE_DEC, NULL, 0x0,
2733 "TLV Length", HFILL }
2736 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2739 { &hf_eigrp_par_k1, { "K1", "eigrp.par.k1", FT_UINT8, BASE_DEC, NULL, 0x0,
2740 "Bandwidth/Throughput Coefficient", HFILL }},
2741 { &hf_eigrp_par_k2, { "K2", "eigrp.par.k2", FT_UINT8, BASE_DEC, NULL, 0x0,
2742 "Load Coefficient", HFILL }},
2743 { &hf_eigrp_par_k3, { "K3", "eigrp.par.k3", FT_UINT8, BASE_DEC, NULL, 0x0,
2744 "Delay/Latency Coefficient", HFILL }},
2745 { &hf_eigrp_par_k4, { "K4", "eigrp.par.k4", FT_UINT8, BASE_DEC, NULL, 0x0,
2746 "Reliability Coefficient", HFILL }},
2747 { &hf_eigrp_par_k5, { "K5", "eigrp.par.k5", FT_UINT8, BASE_DEC, NULL, 0x0,
2748 "Reliability Coefficient", HFILL }},
2749 { &hf_eigrp_par_k6, { "K6", "eigrp.par.k6", FT_UINT8, BASE_DEC, NULL, 0x0,
2750 "Extended Metric Coefficient", HFILL }},
2751 { &hf_eigrp_par_holdtime,
2752 { "Hold Time", "eigrp.par.holdtime", FT_UINT16, BASE_DEC, NULL, 0x0,
2753 "How long to ignore lost HELLO's", HFILL }
2756 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2757 * Authentication TLV
2759 { &hf_eigrp_auth_type,
2760 { "Type", "eigrp.auth.type",
2761 FT_UINT16, BASE_DEC, VALS(eigrp_auth2string), 0x0,
2764 { &hf_eigrp_auth_len,
2765 { "Length", "eigrp.auth.length",
2766 FT_UINT16, BASE_DEC, NULL, 0x0,
2769 { &hf_eigrp_auth_keyid,
2770 { "Key ID", "eigrp.auth.keyid",
2771 FT_UINT32, BASE_DEC, NULL, 0x0,
2774 { &hf_eigrp_auth_keyseq,
2775 { "Key Sequence", "eigrp.auth.keyseq",
2776 FT_UINT32, BASE_DEC, NULL, 0x0,
2779 { &hf_eigrp_auth_digest,
2780 { "Digest", "eigrp.auth.digest",
2781 FT_BYTES, BASE_NONE, NULL, 0x0,
2785 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2788 { &hf_eigrp_seq_addrlen,
2789 { "Address length", "eigrp.seq.addrlen",
2790 FT_UINT8, BASE_DEC, NULL, 0x0,
2793 { &hf_eigrp_seq_ipv4addr,
2794 { "IP Address", "eigrp.seq.ipv4addr",
2795 FT_IPv4, BASE_NONE, NULL, 0x0,
2798 { &hf_eigrp_seq_ipv6addr,
2799 { "IPv6 Address", "eigrp.seq.ipv6addr",
2800 FT_IPv6, BASE_NONE, NULL, 0x0,
2804 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2805 * Next Multicast Sequence
2808 * This was added to the hello containing the sequence TLV so that the
2809 * hello packet could be more tightly bound to the multicast packet bearing
2810 * the CR bit that follows it. The sequence number of the impending multicast
2811 * is carried herein.
2813 { &hf_eigrp_next_mcast_seq,
2814 { "Multicast Sequence", "eigrp.next_mcast_seq",
2815 FT_UINT32, BASE_DEC, NULL, 0x0,
2819 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2820 * Peer Stub Information TLV
2822 { &hf_eigrp_stub_flags,
2823 { "Stub Options", "eigrp.stub_options",
2824 FT_UINT16, BASE_HEX, NULL, 0x0,
2829 * Define eigrp_stub_flags bits here
2831 { &hf_eigrp_stub_flags_connected,
2832 { "Connected", "eigrp.stub_options.connected",
2833 FT_BOOLEAN, 16, TFS(&tfs_set_notset), EIGRP_PEER_ALLOWS_CONNECTED,
2836 { &hf_eigrp_stub_flags_static,
2837 { "Static", "eigrp.stub_options.static",
2838 FT_BOOLEAN, 16, TFS(&tfs_set_notset), EIGRP_PEER_ALLOWS_STATIC,
2841 { &hf_eigrp_stub_flags_summary,
2842 { "Summary", "eigrp.stub_options.summary",
2843 FT_BOOLEAN, 16, TFS(&tfs_set_notset), EIGRP_PEER_ALLOWS_SUMMARY,
2846 { &hf_eigrp_stub_flags_redist,
2847 { "Redistributed", "eigrp.stub_options.redist",
2848 FT_BOOLEAN, 16, TFS(&tfs_set_notset), EIGRP_PEER_ALLOWS_REDIST,
2851 { &hf_eigrp_stub_flags_leakmap,
2852 { "Leak-Map", "eigrp.stub_options.leakmap",
2853 FT_BOOLEAN, 16, TFS(&tfs_set_notset), EIGRP_PEER_ALLOWS_LEAKING,
2856 { &hf_eigrp_stub_flags_recvonly,
2857 { "Receive-Only", "eigrp.stub_options.recvonly",
2858 FT_BOOLEAN, 16, TFS(&tfs_set_notset), EIGRP_PEER_ALLOWS_RCVONLY,
2862 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2863 * Peer Termination TLV
2865 /* Place holder - this TLV has no options */
2867 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2868 * EIGRP 3.0 Vector Header (deprecated)
2871 * common header for all version 3 tlvs
2874 { "Topology", "eigrp.tid",
2875 FT_UINT16, BASE_DEC, NULL, 0x0,
2879 { "AFI", "eigrp.afi",
2880 FT_UINT16, BASE_DEC, VALS(eigrp_afi2string), 0x0,
2884 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2885 * EIGRP TLV 1.2 (legacy) and TLV 3.0 Metric (deprecated) definition
2887 { &hf_eigrp_legacy_metric_delay,
2888 { "Scaled Delay", "eigrp.old_metric.delay",
2889 FT_UINT32, BASE_DEC, NULL, 0x0,
2890 "delay, in 39.1 nanosec interments", HFILL }
2892 { &hf_eigrp_legacy_metric_bw,
2893 { "Scaled BW", "eigrp.old_metric.bw",
2894 FT_UINT32, BASE_DEC, NULL, 0x0,
2895 "bandwidth, in units of 1 Kbit/sec", HFILL }
2897 { &hf_eigrp_legacy_metric_mtu,
2898 { "MTU", "eigrp.old_metric.mtu",
2899 FT_UINT24, BASE_DEC, NULL, 0x0,
2900 "MTU, in octets", HFILL }
2902 { &hf_eigrp_legacy_metric_hopcount,
2903 { "Hop Count", "eigrp.old_metric.hopcount",
2904 FT_UINT8, BASE_DEC, NULL, 0x0,
2905 "Number of hops to destination", HFILL }
2907 { &hf_eigrp_legacy_metric_rel,
2908 { "Reliability", "eigrp.old_metric.rel",
2909 FT_UINT8, BASE_DEC, NULL, 0x0,
2910 "percent packets successfully tx/rx", HFILL }
2912 { &hf_eigrp_legacy_metric_load,
2913 { "Load", "eigrp.old_metric.load",
2914 FT_UINT8, BASE_DEC, NULL, 0x0,
2915 "percent of channel occupied", HFILL }
2917 { &hf_eigrp_legacy_metric_intag,
2918 { "Route Tag", "eigrp.old_metric.intag",
2919 FT_UINT8, BASE_DEC, NULL, 0x0,
2920 "Internal Route Tag", HFILL }
2923 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2924 * EIGRP 3.0 TIDLIST TLV (only survivor in MTR)
2926 { &hf_eigrp_tidlist_tid,
2927 { "TID List", "eigrp.tidlist",
2928 FT_UINT16, BASE_DEC, NULL, 0x0,
2931 { &hf_eigrp_tidlist_flags,
2932 { "TID List Flags", "eigrp.tidlist.flags",
2933 FT_UINT16, BASE_HEX, NULL, 0x0,
2936 { &hf_eigrp_tidlist_len,
2937 { "TID List Size", "eigrp.tidlist.len",
2938 FT_UINT16, BASE_DEC, NULL, 0x0,
2941 { &hf_eigrp_routerid,
2942 { "RouterID", "eigrp.routerid",
2943 FT_IPv4, BASE_NONE, NULL, 0x0,
2944 "Router ID of injecting router", HFILL }
2946 { &hf_eigrp_legacy_metric_tag,
2947 { "Tag", "eigrp.old_metric.tag",
2948 FT_UINT32, BASE_DEC, NULL, 0x0,
2949 "route tag", HFILL }
2952 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2954 * PDM opaque flag field definitions
2956 { &hf_eigrp_metric_flags_srcwd,
2957 { "Source Withdraw", "eigrp.metric.flags.srcwd",
2958 FT_BOOLEAN, 8, TFS(&tfs_true_false), EIGRP_OPAQUE_SRCWD,
2959 "Route Source Withdraw", HFILL }
2961 { &hf_eigrp_metric_flags_active,
2962 { "Route is Active", "eigrp.metric.flags.active",
2963 FT_BOOLEAN, 8, TFS(&tfs_true_false), EIGRP_OPAQUE_ACTIVE,
2964 "Route is currently in active state", HFILL }
2966 { &hf_eigrp_metric_flags_repl,
2967 { "Route is Replicated", "eigrp.metric.flags.repl",
2968 FT_BOOLEAN, 8, TFS(&tfs_true_false), EIGRP_OPAQUE_REPL,
2969 "Route is replicated from different tableid", HFILL }
2972 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2973 * EIGRP TLV 1.2/3.0 ExtData Definitions
2975 { &hf_eigrp_extdata_origrid,
2976 { "Originating RouterID", "eigrp.extdata.origrid",
2977 FT_IPv4, BASE_NONE, NULL, 0x0,
2978 "Router ID of redistributing router", HFILL }
2981 { &hf_eigrp_extdata_as,
2982 { "Originating A.S.", "eigrp.extdata.as",
2983 FT_UINT32, BASE_DEC, NULL, 0x0,
2984 "Autonomous System of redistributing protocol", HFILL }
2987 { &hf_eigrp_extdata_tag,
2988 { "Administrative Tag", "eigrp.extdata.tag",
2989 FT_UINT32, BASE_DEC, NULL, 0x0,
2990 "Administrative Route Tag", HFILL }
2992 { &hf_eigrp_extdata_metric,
2993 { "External Metric", "eigrp.extdata.metric",
2994 FT_UINT32, BASE_DEC, NULL, 0x0,
2995 "Metric reported by redistributing protocol", HFILL }
2997 { &hf_eigrp_extdata_reserved,
2998 { "Reserved", "eigrp.extdata.reserved",
2999 FT_UINT16, BASE_DEC, NULL, 0x0,
3003 /* IPX ExtData Definitions */
3004 { &hf_eigrp_ipx_extdata_delay,
3005 { "External Delay", "eigrp.extdata.ipx_delay",
3006 FT_UINT16, BASE_DEC, NULL, 0x0,
3007 "Delay reported by redistributing protocol", HFILL }
3009 { &hf_eigrp_ipx_extdata_metric,
3010 { "External Metric", "eigrp.extdata.ipx_metric",
3011 FT_UINT16, BASE_DEC, NULL, 0x0,
3012 "Delay reported by redistributing protocol", HFILL }
3015 { &hf_eigrp_extdata_proto,
3016 { "External Protocol ID", "eigrp.extdata.proto",
3017 FT_UINT8, BASE_DEC, VALS(eigrp_proto2string), 0x0,
3021 { &hf_eigrp_extdata_flag_ext,
3022 { "Route is External", "eigrp.opaque.flag.ext",
3023 FT_BOOLEAN, 8, TFS(&tfs_true_false), EIGRP_OPAQUE_EXT,
3024 "External route", HFILL }
3026 { &hf_eigrp_extdata_flag_cd,
3027 { "Route is Candidate Default", "eigrp.opaque.flag.cd",
3028 FT_BOOLEAN, 8, TFS(&tfs_true_false), EIGRP_OPAQUE_CD,
3029 "Candidate-Default route", HFILL }
3032 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
3033 * EIGRP TLV 2.0 "Wide" Metric format definition
3035 /* Number of 16bit words in the metric section, used to determine the
3036 * start of the destination/attribute information.
3038 { &hf_eigrp_metric_offset,
3039 { "Offset", "eigrp.metric.offset",
3040 FT_UINT8, BASE_DEC, NULL, 0x0,
3041 "Number of 16bit words to reach the start of the"
3042 "destination/attribute information", HFILL }
3045 /* Priority of the prefix when transmitting a group of destination
3046 * addresses to neighboring routers. A priority of zero indicates no
3049 { &hf_eigrp_metric_priority,
3050 { "Priority", "eigrp.metric.priority",
3051 FT_UINT8, BASE_DEC, NULL, 0x0,
3052 "Priority of the prefix for ordering transmission", HFILL }
3055 /** The current error rate for the path. Measured as an error
3056 * percentage. A value of 255 indicates 100% reliability
3058 { &hf_eigrp_metric_rel,
3059 { "Reliability", "eigrp.metric.reliability",
3060 FT_UINT8, BASE_DEC, NULL, 0x0,
3061 "percent packets successfully tx/rx", HFILL }
3064 /** The load utilization of the path to the destination. Measured as a
3065 * percentage of load. A value of 255 indicates 100% load.
3067 { &hf_eigrp_metric_load,
3068 { "Load", "eigrp.metric.load",
3069 FT_UINT8, BASE_DEC, NULL, 0x0,
3070 "percent of channel occupied", HFILL }
3073 /** The minimum maximum transmission unit size for the path to the
3074 * destination. Not used in metric calculation, but available to
3075 * underlying protocols
3077 { &hf_eigrp_metric_mtu,
3078 { "MTU", "eigrp.metric.mtu",
3079 FT_UINT24, BASE_DEC, NULL, 0x0,
3080 "MTU, in octets", HFILL }
3083 /** number of router traversals to the destination */
3084 { &hf_eigrp_metric_hopcount,
3085 { "Hop Count", "eigrp.metric.hopcount",
3086 FT_UINT8, BASE_DEC, NULL, 0x0,
3087 "Number of hops to destination", HFILL }
3090 /* Reserved - Transmitted as 0x0000 */
3091 { &hf_eigrp_metric_reserved,
3092 { "Reserved", "eigrp.metric.reserved",
3093 FT_UINT16, BASE_HEX, NULL, 0x0,
3097 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
3098 * EIGRP TLV 2.0 Extended Metric Attributes
3100 { &hf_eigrp_attr_opcode,
3101 { "Opcode", "eigrp.attr.opcode",
3102 FT_UINT8, BASE_DEC, VALS(eigrp_attr_opcode2string), 0x0,
3103 "Opcode - Operation code indicating the attribute type", HFILL }
3105 { &hf_eigrp_attr_offset,
3106 { "Offset", "eigrp.attr.offset",
3107 FT_UINT8, BASE_DEC, NULL, 0x0,
3108 "Number of 2 byte words of data", HFILL }
3110 { &hf_eigrp_attr_scaled,
3111 { "Legacy Metric", "eigrp.attr.scaled",
3112 FT_UINT16, BASE_DEC, NULL, 0x0,
3113 "Metric calculated from legacy TLVs", HFILL }
3115 { &hf_eigrp_attr_tag,
3116 { "Tag", "eigrp.attr.tag",
3117 FT_UINT16, BASE_DEC, NULL, 0x0,
3118 "Tag assigned by admin for dest", HFILL }
3120 { &hf_eigrp_attr_jitter,
3121 { "Jitter", "eigrp.attr.jitter",
3122 FT_UINT16, BASE_DEC, NULL, 0x0,
3123 "Variation in path delay", HFILL }
3125 { &hf_eigrp_attr_qenergy,
3126 { "Q-Energy", "eigrp.attr.qenergy",
3127 FT_UINT16, BASE_DEC, NULL, 0x0,
3128 "Non-Active energy usage along path", HFILL }
3130 { &hf_eigrp_attr_energy,
3131 { "Energy", "eigrp.attr.energy",
3132 FT_UINT16, BASE_DEC, NULL, 0x0,
3133 "Active energy usage along path", HFILL }
3136 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
3138 * IPv4 specific address definitions
3140 { &hf_eigrp_ipv4_nexthop,
3141 { "NextHop", "eigrp.ipv4.nexthop",
3142 FT_IPv4, BASE_NONE, NULL, 0x0,
3145 { &hf_eigrp_ipv4_prefixlen,
3146 { "Prefix Length", "eigrp.ipv4.prefixlen",
3147 FT_UINT8, BASE_DEC, NULL, 0x0,
3151 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
3153 * IPv6 specific address definitions
3155 { &hf_eigrp_ipv6_nexthop,
3156 { "NextHop", "eigrp.ipv6.nexthop",
3157 FT_IPv6, BASE_NONE, NULL, 0x0,
3161 { &hf_eigrp_ipv6_prefixlen,
3162 { "Prefix Length", "eigrp.ipv6.prefixlen",
3163 FT_UINT8, BASE_DEC, NULL, 0x0,
3167 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
3169 * IPX specific address definitions
3171 { &hf_eigrp_ipx_nexthop_net,
3172 { "NextHop Net", "eigrp.ipx.nexthop_net",
3173 FT_IPXNET, BASE_NONE, NULL, 0x0,
3176 { &hf_eigrp_ipx_nexthop_host,
3177 { "NextHop Host", "eigrp.ipx.nexthop_host",
3178 FT_ETHER, BASE_NONE, NULL, 0x0,
3181 { &hf_eigrp_ipx_extdata_routerid,
3182 { "External RouterID", "eigrp.ipx.routerid",
3183 FT_ETHER, BASE_NONE, NULL, 0x0,
3184 "Router ID of redistributing router", HFILL }
3186 { &hf_eigrp_ipx_dest,
3187 { "Destination", "eigrp.ipx.dest",
3188 FT_IPXNET, BASE_NONE, NULL, 0x0,
3192 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
3194 * AppleTalk specific address definitions
3196 { &hf_eigrp_atalk_routerid,
3197 { "AppleTalk Router ID", "eigrp.atalk.routerid",
3198 FT_UINT32, BASE_DEC, NULL, 0x0,
3202 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
3203 * Service Advertisement Framework definitions
3205 { &hf_eigrp_saf_service,
3206 { "Service", "eigrp.saf.service",
3207 FT_UINT16, BASE_DEC, VALS(eigrp_saf_srv2string), 0x0,
3210 { &hf_eigrp_saf_subservice,
3211 { "Sub-Service", "eigrp.saf.subservice",
3212 FT_UINT16, BASE_DEC, NULL, 0x0,
3215 { &hf_eigrp_saf_guid,
3216 { "GUID", "eigrp.saf.guid",
3217 FT_GUID, BASE_NONE, NULL, 0x0,
3220 { &hf_eigrp_saf_data_type,
3221 { "Type", "eigrp.saf.data.type",
3222 FT_UINT16, BASE_HEX, VALS(eigrp_saf_type2string), 0x0,
3223 "SAF Message Data Type", HFILL }
3225 { &hf_eigrp_saf_data_length,
3226 { "Length", "eigrp.saf.data.length",
3227 FT_UINT16, BASE_DEC, NULL, 0x0,
3230 { &hf_eigrp_saf_data_sequence,
3231 { "Sequence", "eigrp.saf.data.sequence",
3232 FT_UINT32, BASE_DEC, NULL, 0x0,
3235 { &hf_eigrp_saf_reachability_afi,
3236 { "AFI", "eigrp.saf.data.reachability.afi",
3237 FT_UINT16, BASE_DEC, VALS(eigrp_afi2string), 0x0,
3240 { &hf_eigrp_saf_reachability_port,
3241 { "Port", "eigrp.saf.data.reachability.port",
3242 FT_UINT16, BASE_DEC, NULL, 0x0,
3245 { &hf_eigrp_saf_reachability_protocol,
3246 { "Protocol", "eigrp.saf.data.reachability.protocol",
3247 FT_UINT16, BASE_DEC, NULL, 0x0,
3250 { &hf_eigrp_saf_reachability_addr_ipv4,
3251 { "IPv4 Addr", "eigrp.saf.data.reachability.addr_ipv4",
3252 FT_IPv4, BASE_NONE, NULL, 0x0,
3255 { &hf_eigrp_saf_reachability_addr_ipv6,
3256 { "IPv6 Addr", "eigrp.saf.data.reachability.addr_ipv6",
3257 FT_IPv6, BASE_NONE, NULL, 0x0,
3260 { &hf_eigrp_saf_reachability_addr_hex,
3261 { "Addr", "eigrp.saf.data.reachability.addr_hex",
3262 FT_BYTES, BASE_NONE, NULL, 0x0,
3266 /* misc field used in a couple places */
3267 { &hf_eigrp_nullpad,
3268 { "Nullpad", "eigrp.nullpad",
3269 FT_BYTES, BASE_NONE, NULL, 0x0,
3274 /* Setup protocol subtree array */
3275 static gint *ett[] = {
3282 &ett_eigrp_tlv_metric,
3283 &ett_eigrp_tlv_attr,
3284 &ett_eigrp_tlv_extdata,
3287 &ett_eigrp_stub_flags,
3288 &ett_eigrp_saf_reachability,
3290 /* metric tlv specific */
3291 &ett_eigrp_metric_flags,
3292 &ett_eigrp_extdata_flags,
3295 static ei_register_info ei[] = {
3296 { &ei_eigrp_peer_termination, { "eigrp.peer_termination", PI_RESPONSE_CODE, PI_NOTE, "Peer Termination", EXPFILL }},
3297 { &ei_eigrp_auth_len, { "eigrp.auth.length.invalid", PI_MALFORMED, PI_WARN, "Invalid auth len", EXPFILL }},
3298 { &ei_eigrp_auth_type, { "eigrp.auth.type.invalid", PI_PROTOCOL, PI_WARN, "Invalid auth type", EXPFILL }},
3299 { &ei_eigrp_seq_addrlen, { "eigrp.seq.addrlen.invalid", PI_MALFORMED, PI_ERROR, "Invalid address length", EXPFILL }},
3300 { &ei_eigrp_peer_termination_graceful, { "eigrp.peer_termination_graceful", PI_RESPONSE_CODE, PI_NOTE, "Peer Termination (Graceful Shutdown)", EXPFILL }},
3301 { &ei_eigrp_prefixlen, { "eigrp.prefixlen.invalid", PI_MALFORMED, PI_WARN, "Invalid prefix length", EXPFILL }},
3302 { &ei_eigrp_unreachable, { "eigrp.unreachable", PI_RESPONSE_CODE, PI_NOTE, "Unreachable", EXPFILL }},
3303 { &ei_eigrp_tlv_type, { "eigrp.tlv_type.unknown", PI_PROTOCOL, PI_WARN, "Unknown TLV", EXPFILL }},
3304 { &ei_eigrp_afi, { "eigrp.afi.unknown", PI_PROTOCOL, PI_WARN, "Unknown AFI", EXPFILL }},
3305 { &ei_eigrp_checksum_bad, { "eigrp.checksum.bad", PI_CHECKSUM, PI_WARN, "Bad Checksum", EXPFILL }},
3306 { &ei_eigrp_tlv_len, { "eigrp.tlv.len.invalid", PI_MALFORMED, PI_ERROR, "Corrupt TLV (Zero Size)", EXPFILL }},
3309 expert_module_t* expert_eigrp;
3311 /* Register the protocol name and description */
3312 proto_eigrp = proto_register_protocol(
3313 "Enhanced Interior Gateway Routing Protocol", /* name */
3314 "EIGRP", /* short name */
3315 "eigrp" /* abbrev */
3318 /* Required function calls to register the header fields and subtrees used */
3319 proto_register_field_array(proto_eigrp, hf, array_length(hf));
3320 proto_register_subtree_array(ett, array_length(ett));
3321 expert_eigrp = expert_register_protocol(proto_eigrp);
3322 expert_register_field_array(expert_eigrp, ei, array_length(ei));
3326 *@fn void proto_reg_handoff_eigrp(void)
3329 * This exact format is required because a script is used to find these
3330 * routines and create the code that calls these routines.
3333 * If this dissector uses sub-dissector registration add a registration routine.
3335 * This form of the reg_handoff function is used if if you perform registration
3336 * functions which are dependent upon prefs. If this function is registered as
3337 * a prefs callback (see prefs_register_protocol above) this function is also
3338 * called by preferences whenever "Apply" is pressed;
3340 * In that case, it should accommodate being called more than once.
3343 proto_reg_handoff_eigrp(void)
3345 dissector_handle_t eigrp_handle;
3347 ipxsap_handle = find_dissector("ipxsap");
3348 media_type_table = find_dissector_table("media_type");
3350 eigrp_handle = new_create_dissector_handle(dissect_eigrp, proto_eigrp);
3352 dissector_add_uint("ip.proto", IP_PROTO_EIGRP, eigrp_handle);
3353 dissector_add_uint("ddp.type", DDP_EIGRP, eigrp_handle);
3354 dissector_add_uint("ipx.socket", IPX_SOCKET_EIGRP, eigrp_handle);