1 /* packet-eigrp.c
2 * Routines for EIGRP dissection
3 * Copyright 2011, Donnie V Savage <dsavage@cisco.com>
4 *
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>
8 *
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
12 *
13 * SPDX-License-Identifier: GPL-2.0-or-later
14 */
15 #include "config.h"
16
17 #include <epan/packet.h>
18 #include <epan/addr_resolv.h>
19 #include <epan/addr_and_mask.h>
20 #include <epan/ipproto.h>
21 #include <epan/expert.h>
22
23 #include "packet-eigrp.h"
24 #include "packet-ipx.h"
25 #include "packet-atalk.h"
26
27 /*
28 * Originally Cisco proprietary; now the subject of RFC 7868.
29 */
30
31 /**
32 * EIGRP Header size in bytes
33 */
34 #define EIGRP_HEADER_LENGTH 20
35
36 /**
37 * EIGRP Packet Opcodes
38 */
39 #define EIGRP_OPC_UPDATE 1 /*!< packet containing routing information */
40 #define EIGRP_OPC_REQUEST 2 /*!< sent to request one or more routes */
41 #define EIGRP_OPC_QUERY 3 /*!< sent when a routing is in active start */
42 #define EIGRP_OPC_REPLY 4 /*!< sent in response to a query */
43 #define EIGRP_OPC_HELLO 5 /*!< sent to maintain a peering session */
44 #define EIGRP_OPC_IPXSAP 6 /*!< IPX SAP information */
45 #define EIGRP_OPC_PROBE 7 /*!< for test purposes */
46 #define EIGRP_OPC_ACK 8 /*!< acknowledge */
47 #define EIGRP_OPC_STUB 9 /*!< peering operating in restricted mode */
48 #define EIGRP_OPC_SIAQUERY 10 /*!< QUERY - with relaxed restrictions */
49 #define EIGRP_OPC_SIAREPLY 11 /*!< REPLY - may contain old routing information */
50
51 /**
52 * EIGRP TLV Range definitions
53 * PDM TLV Range
54 * General 0x0000
55 * IPv4 0x0100 ** TLVs for one and all
56 * ATALK 0x0200 ** legacy
57 * IPX 0x0300 ** discontinued
58 * IPv6 0x0400 ** legacy
59 * Multiprotocol 0x0600 ** wide metrics
60 * MultiTopology 0x00f0 ** deprecated
61 */
62 #define EIGRP_TLV_RANGEMASK 0xfff0 /*!< should be 0xff00 - opps */
63 #define EIGRP_TLV_GENERAL 0x0000
64
65 /**
66 * 1.2 TLV Definitions ** legacy
67 * These have been deprecated and should not be used for future packets
68 */
69 #define EIGRP_TLV_IPv4 0x0100 /*!< Classic IPv4 TLV encoding */
70 #define EIGRP_TLV_ATALK 0x0200 /*!< Classic Appletalk TLV encoding*/
71 #define EIGRP_TLV_IPX 0x0300 /*!< Classic IPX TLV encoding */
72 #define EIGRP_TLV_IPv6 0x0400 /*!< Classic IPv6 TLV encoding */
73
74 /**
75 * 2.0 Multi-Protocol TLV Definitions
76 * These have been deprecated and should not be used for future packets
77 */
78 #define EIGRP_TLV_MP 0x0600 /*!< Non-PDM specific encoding */
79
80 /**
81 * 3.0 TLV Definitions ** deprecated
82 * These have been deprecated and should not be used for future packets
83 */
84 #define EIGRP_TLV_MTR 0x00f0 /*!< MTR TLV encoding */
85
86 /**
87 * TLV type definitions. Generic (protocol-independent) TLV types are
88 * defined here. Protocol-specific ones are defined elsewhere.
89 */
90 #define EIGRP_TLV_PARAMETER (EIGRP_TLV_GENERAL | 0x0001) /*!< eigrp parameters */
91 #define EIGRP_TLV_AUTH (EIGRP_TLV_GENERAL | 0x0002) /*!< authentication */
92 #define EIGRP_TLV_SEQ (EIGRP_TLV_GENERAL | 0x0003) /*!< sequenced packet */
93 #define EIGRP_TLV_SW_VERSION (EIGRP_TLV_GENERAL | 0x0004) /*!< software version */
94 #define EIGRP_TLV_NEXT_MCAST_SEQ (EIGRP_TLV_GENERAL | 0x0005) /*!< */
95 #define EIGRP_TLV_PEER_STUBINFO (EIGRP_TLV_GENERAL | 0x0006) /*!< stub information */
96 #define EIGRP_TLV_PEER_TERMINATION (EIGRP_TLV_GENERAL | 0x0007) /*!< peer termination */
97 #define EIGRP_TLV_PEER_TIDLIST (EIGRP_TLV_GENERAL | 0x0008) /*!< peer sub-topology list */
98
99 /**
100 * Route Based TLVs
101 */
102 #define EIGRP_TLV_TYPEMASK 0x000f
103 #define EIGRP_TLV_REQUEST 0x0001
104 #define EIGRP_TLV_INTERNAL 0x0002
105 #define EIGRP_TLV_EXTERNAL 0x0003
106 #define EIGRP_TLV_COMMUNITY 0x0004
107
108 /* Legacy TLV formats */
109 #define EIGRP_TLV_IPv4_REQ (EIGRP_TLV_IPv4 | EIGRP_TLV_REQUEST)
110 #define EIGRP_TLV_IPv4_INT (EIGRP_TLV_IPv4 | EIGRP_TLV_INTERNAL)
111 #define EIGRP_TLV_IPv4_EXT (EIGRP_TLV_IPv4 | EIGRP_TLV_EXTERNAL)
112 #define EIGRP_TLV_IPv4_COM (EIGRP_TLV_IPv4 | EIGRP_TLV_COMMUNITY)
113 #define EIGRP_TLV_IPX_INT (EIGRP_TLV_IPX | EIGRP_TLV_INTERNAL)
114 #define EIGRP_TLV_IPX_EXT (EIGRP_TLV_IPX | EIGRP_TLV_EXTERNAL)
115 #define EIGRP_TLV_IPX_COM (EIGRP_TLV_IPX | EIGRP_TLV_COMMUNITY)
116 #define EIGRP_TLV_IPv6_INT (EIGRP_TLV_IPv6 | EIGRP_TLV_INTERNAL)
117 #define EIGRP_TLV_IPv6_EXT (EIGRP_TLV_IPv6 | EIGRP_TLV_EXTERNAL)
118 #define EIGRP_TLV_IPv6_COM (EIGRP_TLV_IPv6 | EIGRP_TLV_COMMUNITY)
119
120 /* Deprecated TLV formats */
121 #define EIGRP_TLV_AT_INT (EIGRP_TLV_ATALK | EIGRP_TLV_INTERNAL)
122 #define EIGRP_TLV_AT_EXT (EIGRP_TLV_ATALK | EIGRP_TLV_EXTERNAL)
123 #define EIGRP_TLV_AT_CBL (EIGRP_TLV_ATALK | 0x04)
124 #define EIGRP_TLV_MTR_REQ (EIGRP_TLV_MTR | EIGRP_TLV_REQUEST)
125 #define EIGRP_TLV_MTR_INT (EIGRP_TLV_MTR | EIGRP_TLV_INTERNAL)
126 #define EIGRP_TLV_MTR_EXT (EIGRP_TLV_MTR | EIGRP_TLV_EXTERNAL)
127 #define EIGRP_TLV_MTR_COM (EIGRP_TLV_MTR | EIGRP_TLV_COMMUNITY)
128 #define EIGRP_TLV_MTR_TIDLIST (EIGRP_TLV_MTR | 0x0005)
129
130 /* Current "Wide Metric" TLV formats */
131 #define EIGRP_TLV_MP_REQ (EIGRP_TLV_MP | EIGRP_TLV_REQUEST)
132 #define EIGRP_TLV_MP_INT (EIGRP_TLV_MP | EIGRP_TLV_INTERNAL)
133 #define EIGRP_TLV_MP_EXT (EIGRP_TLV_MP | EIGRP_TLV_EXTERNAL)
134 #define EIGRP_TLV_MP_COM (EIGRP_TLV_MP | EIGRP_TLV_COMMUNITY)
135
136 /**
137 * External routes originate from some other protocol - these are them
138 */
139 #define NULL_PROTID 0 /*!< unknown protocol */
140 #define IGRP1_PROTID 1 /*!< IGRP.. who's your daddy! */
141 #define IGRP2_PROTID 2 /*!< EIGRP - Just flat out the best */
142 #define STATIC_PROTID 3 /*!< Staticly configured source */
143 #define RIP_PROTID 4 /*!< Routing Information Protocol */
144 #define HELLO_PROTID 5 /*!< Hello? RFC-891 you there? */
145 #define OSPF_PROTID 6 /*!< OSPF - Open Shortest Path First */
146 #define ISIS_PROTID 7 /*!< Intermediate System To Intermediate System */
147 #define EGP_PROTID 8 /*!< Exterior Gateway Protocol */
148 #define BGP_PROTID 9 /*!< Border Gateway Protocol */
149 #define IDRP_PROTID 10 /*!< InterDomain Routing Protocol */
150 #define CONN_PROTID 11 /*!< Connected source */
151
152 /**
153 *
154 * extdata flag field definitions
155 */
156 #define EIGRP_OPAQUE_EXT 0x01 /*!< Route is external */
157 #define EIGRP_OPAQUE_CD 0x02 /*!< Candidate default route */
158
159 /**
160 * Address-Family types are taken from:
161 * http://www.iana.org/assignments/address-family-numbers
162 * to provide a standards based exchange of AFI information between
163 * EIGRP routers.
164 */
165 #define EIGRP_AF_IPv4 1 /*!< IPv4 (IP version 4) */
166 #define EIGRP_AF_IPv6 2 /*!< IPv6 (IP version 6) */
167 #define EIGRP_AF_IPX 11 /*!< IPX */
168 #define EIGRP_AF_ATALK 12 /*!< Appletalk */
169 #define EIGRP_SF_COMMON 16384 /*!< Cisco Service Family */
170 #define EIGRP_SF_IPv4 16385 /*!< Cisco IPv4 Service Family */
171 #define EIGRP_SF_IPv6 16386 /*!< Cisco IPv6 Service Family */
172
173 /**
174 * Authentication types supported by EIGRP
175 */
176 #define EIGRP_AUTH_TYPE_NONE 0
177 #define EIGRP_AUTH_TYPE_TEXT 1
178 #define EIGRP_AUTH_TYPE_MD5 2
179 #define EIGRP_AUTH_TYPE_MD5_LEN 16
180 #define EIGRP_AUTH_TYPE_SHA256 3
181 #define EIGRP_AUTH_TYPE_SHA256_LEN 32
182
183 /**
184 * opaque flag field definitions
185 */
186 #define EIGRP_OPAQUE_SRCWD 0x01 /*!< Route Source Withdraw */
187 #define EIGRP_OPAQUE_CD 0x02 /*!< Candidate Default */
188 #define EIGRP_OPAQUE_ACTIVE 0x04 /*!< Route is currently in active state */
189 #define EIGRP_OPAQUE_REPL 0x08 /*!< Route is replicated from different tableid */
190
191 /**
192 * pak flag bit field definitions - 0 (none)-7 source priority
193 */
194 #define EIGRP_PRIV_DEFAULT 0x00 /* 0 (none)-7 source priority */
195 #define EIGRP_PRIV_LOW 0x01
196 #define EIGRP_PRIV_MEDIUM 0x04
197 #define EIGRP_PRIV_HIGH 0x07
198
199 /**
200 * stub bit definitions
201 */
202 #define EIGRP_PEER_ALLOWS_CONNECTED 0x0001
203 #define EIGRP_PEER_ALLOWS_STATIC 0x0002
204 #define EIGRP_PEER_ALLOWS_SUMMARY 0x0004
205 #define EIGRP_PEER_ALLOWS_REDIST 0x0008
206 #define EIGRP_PEER_ALLOWS_LEAKING 0x0010
207 #define EIGRP_PEER_ALLOWS_RCVONLY 0x0020
208
209 /*
210 * Init bit definition. First unicast transmitted Update has this
211 * bit set in the flags field of the fixed header. It tells the neighbor
212 * to down-load his topology table.
213 */
214 #define EIGRP_INIT_FLAG 0x01
215
216 /*
217 * CR bit (Conditionally Received) definition in flags field on header. Any
218 * packets with the CR-bit set can be accepted by an EIGRP speaker if and
219 * only if a previous Hello was received with the SEQUENCE_TYPE TLV present.
220 *
221 * This allows multicasts to be transmitted in order and reliably at the
222 * same time as unicasts are transmitted.
223 */
224 #define EIGRP_CR_FLAG 0x02
225
226 /*
227 * RS bit. The Restart flag is set in the hello and the init
228 * update packets during the nsf signaling period. A nsf-aware
229 * router looks at the RS flag to detect if a peer is restarting
230 * and maintain the adjacency. A restarting router looks at
231 * this flag to determine if the peer is helping out with the restart.
232 */
233 #define EIGRP_RS_FLAG 0x04
234
235 /*
236 * EOT bit. The End-of-Table flag marks the end of the start-up updates
237 * sent to a new peer. A nsf restarting router looks at this flag to
238 * determine if it has finished receiving the start-up updates from all
239 * peers. A nsf-aware router waits for this flag before cleaning up
240 * the stale routes from the restarting peer.
241 */
242 #define EIGRP_EOT_FLAG 0x08
243
244 /**
245 * EIGRP Virtual Router ID
246 *
247 * Define values to deal with EIGRP virtual router ids. Virtual
248 * router IDs are stored in the upper short of the EIGRP fixed packet
249 * header. The lower short of the packet header continues to be used
250 * as asystem number.
251 *
252 * Virtual Router IDs are PDM-independent. All PDMs will use
253 * VRID_BASE to indicate the 'base' or 'legacy' EIGRP instance.
254 * All PDMs need to initialize their vrid to VRID_BASE for compatibility
255 * with legacy routers.
256 * Once IPv6 supports 'MTR Multicast', it will use the same VRID as
257 * IPv4. No current plans to support VRIDs on IPX. :)
258 * Initial usage of VRID is to signal usage of Multicast topology for
259 * MTR.
260 *
261 * VRID_MCAST is a well known constant, other VRIDs will be determined
262 * programmatic...
263 *
264 * With the addition of SAF the VRID space has been divided into two
265 * segments 0x0000-0x7fff is for EIGRP and vNets, 0x8000-0xffff is
266 * for saf and its associated vNets.
267 */
268 #define EIGRP_VRID_MASK 0x8001
269 #define EIGRP_VRID_AF_BASE 0x0000
270 #define EIGRP_VRID_MCAST_BASE 0x0001
271 #define EIGRP_VRID_SF_BASE 0x8000
272
273 /* Extended Attributes for a destination */
274 #define EIGRP_ATTR_HDRLEN (2)
275 #define EIGRP_ATTR_MAXDATA (512)
276
277 #define EIGRP_ATTR_NOOP 0 /*!< No-Op used as offset padding */
278 #define EIGRP_ATTR_SCALED 1 /*!< Scaled metric values */
279 #define EIGRP_ATTR_TAG 2 /*!< Tag assigned by Admin for dest */
280 #define EIGRP_ATTR_COMM 3 /*!< Community attribute for dest */
281 #define EIGRP_ATTR_JITTER 4 /*!< Variation in path delay */
282 #define EIGRP_ATTR_QENERGY 5 /*!< Non-Active energy usage along path */
283 #define EIGRP_ATTR_ENERGY 6 /*!< Active energy usage along path */
284
285 /*
286 * Begin EIGRP-BGP interoperability communities
287 */
288 #define EIGRP_EXTCOMM_SOO_ASFMT 0x0003 /* Site-of-Origin, BGP AS format */
289 #define EIGRP_EXTCOMM_SOO_ADRFMT 0x0103 /* Site-of-Origin, BGP/EIGRP addr format */
290
291 /*
292 * EIGRP Specific communities
293 */
294 #define EIGRP_EXTCOMM_EIGRP 0x8800 /* EIGRP route information appended*/
295 #define EIGRP_EXTCOMM_DAD 0x8801 /* EIGRP AS + Delay */
296 #define EIGRP_EXTCOMM_VRHB 0x8802 /* EIGRP Vector: Reliability + Hop + BW */
297 #define EIGRP_EXTCOMM_SRLM 0x8803 /* EIGRP System: Reserve +Load + MTU */
298 #define EIGRP_EXTCOMM_SAR 0x8804 /* EIGRP System: Remote AS + Remote ID */
299 #define EIGRP_EXTCOMM_RPM 0x8805 /* EIGRP Remote: Protocol + Metric */
300 #define EIGRP_EXTCOMM_VRR 0x8806 /* EIGRP Vecmet: Rsvd + (internal) Routerid */
301
302 /* SAF types */
303 #define EIGRP_SVCDATA_COMPLETE 0x01 /*!< Data is attached */
304 #define EIGRP_SVCDATA_TRIMMED 0x02 /*!< Data was trimmed from service */
305
306 /* SAF Defined Numbers */
307 #define SAF_SERVICE_ID_CAPMAN 100 /*!< Capabilities Manager */
308 #define SAF_SERVICE_ID_UC 101 /*!< Unified Communications */
309 #define SAF_SERVICE_ID_PFR 102 /*!< Performance Routing */
310
311 /* Forward declaration we need below (if using proto_reg_handoff...
312 as a prefs callback) */
313 void proto_reg_handoff_eigrp(void);
314 void proto_register_eigrp(void);
315
316 /* Initialize the protocol and registered fields */
317 static int proto_eigrp = -1;
318
319 /* header */
320 static gint hf_eigrp_version = -1;
321 static gint hf_eigrp_opcode = -1;
322 static gint hf_eigrp_flags = -1;
323 static gint hf_eigrp_sequence = -1;
324 static gint hf_eigrp_acknowledge = -1;
325 static gint hf_eigrp_vrid = -1;
326 static gint hf_eigrp_as = -1;
327 static gint ett_eigrp = -1;
328
329 /* packet header flags */
330 static gint hf_eigrp_flags_init = -1;
331 static gint hf_eigrp_flags_restart = -1;
332 static gint hf_eigrp_flags_eot = -1;
333 static gint hf_eigrp_flags_condrecv = -1;
334
335 static gint ett_eigrp_flags = -1;
336 static int * const eigrp_flag_fields[] = {
337 &hf_eigrp_flags_init,
338 &hf_eigrp_flags_condrecv,
339 &hf_eigrp_flags_restart,
340 &hf_eigrp_flags_eot,
341 NULL
342 };
343
344 /* tlv */
345 static gint hf_eigrp_tlv_type = -1;
346 static gint hf_eigrp_tlv_len = -1;
347 static gint hf_eigrp_tid = -1;
348 static gint hf_eigrp_afi = -1;
349 static gint hf_eigrp_nullpad = -1;
350
351 static gint ett_eigrp_tlv = -1;
352 static gint ett_eigrp_tlv_metric = -1;
353 static gint ett_eigrp_tlv_attr = -1;
354 static gint ett_eigrp_tlv_extdata = -1;
355
356 /* param */
357 static gint hf_eigrp_par_k1 = -1;
358 static gint hf_eigrp_par_k2 = -1;
359 static gint hf_eigrp_par_k3 = -1;
360 static gint hf_eigrp_par_k4 = -1;
361 static gint hf_eigrp_par_k5 = -1;
362 static gint hf_eigrp_par_k6 = -1;
363 static gint hf_eigrp_par_holdtime = -1;
364
365 /* auth */
366 static gint hf_eigrp_auth_type = -1;
367 static gint hf_eigrp_auth_len = -1;
368 static gint hf_eigrp_auth_keyid = -1;
369 static gint hf_eigrp_auth_keyseq = -1;
370 static gint hf_eigrp_auth_digest = -1;
371
372 /* seq */
373 static gint hf_eigrp_seq_addrlen = -1;
374 static gint hf_eigrp_seq_ipv4addr = -1;
375 static gint hf_eigrp_seq_ipv6addr = -1;
376
377 /* multicast seq */
378 static gint hf_eigrp_next_mcast_seq = -1;
379
380 /* stub flags */
381 static gint hf_eigrp_stub_flags = -1;
382 static gint hf_eigrp_stub_flags_connected = -1;
383 static gint hf_eigrp_stub_flags_static = -1;
384 static gint hf_eigrp_stub_flags_summary = -1;
385 static gint hf_eigrp_stub_flags_recvonly = -1;
386 static gint hf_eigrp_stub_flags_redist = -1;
387 static gint hf_eigrp_stub_flags_leakmap = -1;
388
389 static gint ett_eigrp_stub_flags = -1;
390 static int * const eigrp_stub_flag_fields[] = {
391 &hf_eigrp_stub_flags_connected,
392 &hf_eigrp_stub_flags_static,
393 &hf_eigrp_stub_flags_summary,
394 &hf_eigrp_stub_flags_redist,
395 &hf_eigrp_stub_flags_leakmap,
396 &hf_eigrp_stub_flags_recvonly,
397 NULL
398 };
399
400 /* tid */
401 static gint hf_eigrp_tidlist_tid = -1;
402 static gint hf_eigrp_tidlist_flags = -1;
403 static gint hf_eigrp_tidlist_len = -1;
404 static gint ett_eigrp_tidlist = -1;
405
406 /* 1.2 and 3.0 metric */
407 static gint hf_eigrp_legacy_metric_delay = -1;
408 static gint hf_eigrp_legacy_metric_bw = -1;
409 static gint hf_eigrp_legacy_metric_mtu = -1;
410 static gint hf_eigrp_legacy_metric_hopcount = -1;
411 static gint hf_eigrp_legacy_metric_rel = -1;
412 static gint hf_eigrp_legacy_metric_load = -1;
413 static gint hf_eigrp_legacy_metric_intag = -1;
414
415 /* 3.0 metric */
416 static gint hf_eigrp_legacy_metric_tag = -1;
417
418 /* 2.0 metric */
419 static gint hf_eigrp_metric_offset = -1;
420 static gint hf_eigrp_metric_priority = -1;
421 static gint hf_eigrp_metric_rel = -1;
422 static gint hf_eigrp_metric_load = -1;
423 static gint hf_eigrp_metric_mtu = -1;
424 static gint hf_eigrp_metric_hopcount = -1;
425 static gint hf_eigrp_metric_reserved = -1;
426
427 /* router id*/
428 static gint hf_eigrp_routerid = -1;
429
430 /* protocol dependent module route flags */
431 static gint hf_eigrp_metric_flags_srcwd = -1;
432 static gint hf_eigrp_metric_flags_cd = -1;
433 static gint hf_eigrp_metric_flags_active = -1;
434 static gint hf_eigrp_metric_flags_repl = -1;
435 static gint ett_eigrp_metric_flags = -1;
436
437 /* extended metrics */
438 static gint hf_eigrp_attr_opcode = -1;
439 static gint hf_eigrp_attr_offset = -1;
440 static gint hf_eigrp_attr_scaled = -1;
441 static gint hf_eigrp_attr_tag = -1;
442 static gint hf_eigrp_attr_jitter = -1;
443 static gint hf_eigrp_attr_qenergy = -1;
444 static gint hf_eigrp_attr_energy = -1;
445
446 /* route external data */
447 static gint hf_eigrp_extdata_origrid = -1;
448 static gint hf_eigrp_extdata_as = -1;
449 static gint hf_eigrp_extdata_tag = -1;
450 static gint hf_eigrp_extdata_metric = -1;
451 static gint hf_eigrp_extdata_reserved = -1;
452 static gint hf_eigrp_extdata_proto = -1;
453
454 static gint hf_eigrp_extdata_flag_ext = -1;
455 static gint hf_eigrp_extdata_flag_cd = -1;
456 static gint ett_eigrp_extdata_flags = -1;
457
458 /* ipv4 address */
459 static gint hf_eigrp_ipv4_nexthop = -1;
460 static gint hf_eigrp_ipv4_prefixlen = -1;
461
462 /* ipv6 address */
463 static gint hf_eigrp_ipv6_nexthop = -1;
464 static gint hf_eigrp_ipv6_prefixlen = -1;
465
466 /* ipx address */
467 static gint hf_eigrp_ipx_nexthop_net = -1;
468 static gint hf_eigrp_ipx_nexthop_host = -1;
469 static gint hf_eigrp_ipx_extdata_routerid = -1;
470 static gint hf_eigrp_ipx_extdata_delay = -1;
471 static gint hf_eigrp_ipx_extdata_metric = -1;
472 static gint hf_eigrp_ipx_dest = -1;
473
474 /* appletalk address */
475 static gint hf_eigrp_atalk_routerid = -1;
476
477 /* SAF services */
478 static gint hf_eigrp_saf_service = -1;
479 static gint hf_eigrp_saf_subservice = -1;
480 static gint hf_eigrp_saf_guid = -1;
481
482 static gint hf_eigrp_saf_reachability_afi = -1;
483 static gint hf_eigrp_saf_reachability_port = -1;
484 static gint hf_eigrp_saf_reachability_protocol = -1;
485 static gint hf_eigrp_saf_reachability_addr_ipv4 = -1;
486 static gint hf_eigrp_saf_reachability_addr_ipv6 = -1;
487 static gint hf_eigrp_saf_reachability_addr_hex = -1;
488 static gint ett_eigrp_saf_reachability = -1;
489
490 static gint hf_eigrp_saf_data_length = -1;
491 static gint hf_eigrp_saf_data_sequence = -1;
492 static gint hf_eigrp_saf_data_type = -1;
493
494 /* Generated from convert_proto_tree_add_text.pl */
495 static int hf_eigrp_ipx_address = -1;
496 static int hf_eigrp_release = -1;
497 static int hf_eigrp_tlv_version = -1;
498 static int hf_eigrp_ipv4_destination = -1;
499 static int hf_eigrp_ipv6_destination = -1;
500 static int hf_eigrp_appletalk_cable_range = -1;
501 static int hf_eigrp_nexthop_address = -1;
502 static int hf_eigrp_cable_range = -1;
503 static int hf_eigrp_metric_delay = -1;
504 static int hf_eigrp_metric_bandwidth = -1;
505 static int hf_eigrp_checksum = -1;
506 static int hf_eigrp_checksum_status = -1;
507 static int hf_eigrp_metric_comm_type = -1;
508 static int ett_metric_comm_type = -1;
509 static int hf_eigrp_extcomm_eigrp_flag = -1;
510 static int hf_eigrp_extcomm_eigrp_tag = -1;
511 static int hf_eigrp_extcomm_eigrp_res = -1;
512 static int hf_eigrp_extcomm_eigrp_rid = -1;
513 static int hf_eigrp_extcomm_eigrp_as = -1;
514 static int hf_eigrp_extcomm_eigrp_sdly = -1;
515 static int hf_eigrp_extcomm_eigrp_rel = -1;
516 static int hf_eigrp_extcomm_eigrp_hop = -1;
517 static int hf_eigrp_extcomm_eigrp_sbw = -1;
518 static int hf_eigrp_extcomm_eigrp_load = -1;
519 static int hf_eigrp_extcomm_eigrp_mtu = -1;
520 static int hf_eigrp_extcomm_eigrp_xas = -1;
521 static int hf_eigrp_extcomm_eigrp_xrid = -1;
522 static int hf_eigrp_extcomm_eigrp_xproto = -1;
523 static int hf_eigrp_extcomm_eigrp_xmetric = -1;
524
525
526
527 static expert_field ei_eigrp_checksum_bad = EI_INIT;
528 static expert_field ei_eigrp_unreachable = EI_INIT;
529 static expert_field ei_eigrp_seq_addrlen = EI_INIT;
530 static expert_field ei_eigrp_peer_termination = EI_INIT;
531 static expert_field ei_eigrp_tlv_type = EI_INIT;
532 static expert_field ei_eigrp_auth_type = EI_INIT;
533 static expert_field ei_eigrp_peer_termination_graceful = EI_INIT;
534 static expert_field ei_eigrp_auth_len = EI_INIT;
535 static expert_field ei_eigrp_tlv_len = EI_INIT;
536 static expert_field ei_eigrp_afi = EI_INIT;
537 static expert_field ei_eigrp_prefixlen = EI_INIT;
538 static expert_field ei_eigrp_tlv_trunc = EI_INIT;
539
540 /* some extra handle that might be needed */
541 static dissector_handle_t ipxsap_handle = NULL;
542 static dissector_table_t media_type_table = NULL;
543
544 static const value_string eigrp_opcode2string[] = {
545 { EIGRP_OPC_UPDATE, "Update" },
546 { EIGRP_OPC_REQUEST, "Request" },
547 { EIGRP_OPC_QUERY, "Query" },
548 { EIGRP_OPC_REPLY, "Reply" },
549 { EIGRP_OPC_HELLO, "Hello" },
550 { EIGRP_OPC_IPXSAP, "IPX/SAP Update" },
551 { EIGRP_OPC_PROBE, "Route Probe" },
552 { EIGRP_OPC_ACK, "Hello (Ack)" },
553 { EIGRP_OPC_STUB, "Stub-Info" },
554 { EIGRP_OPC_SIAQUERY, "SIA-Query" },
555 { EIGRP_OPC_SIAREPLY, "SIA-Reply" },
556 { 0, NULL }
557 };
558
559 static const value_string eigrp_tlv2string[] = {
560 /* General TLV formats */
561 { EIGRP_TLV_PARAMETER, "Parameters"},
562 { EIGRP_TLV_AUTH, "Authentication"},
563 { EIGRP_TLV_SEQ, "Sequence"},
564 { EIGRP_TLV_SW_VERSION, "Software Version"},
565 { EIGRP_TLV_NEXT_MCAST_SEQ, "Next multicast sequence"},
566 { EIGRP_TLV_PEER_STUBINFO, "Peer Stub Information"},
567 { EIGRP_TLV_PEER_TERMINATION, "Peer Termination"},
568 { EIGRP_TLV_PEER_TIDLIST, "Peer Topology ID List"},
569
570 /* Legacy TLV formats */
571 { EIGRP_TLV_IPv4_INT, "Internal Route(IPv4)"},
572 { EIGRP_TLV_IPv4_EXT, "External Route(IPv4)"},
573 { EIGRP_TLV_IPv4_COM, "Ext-Community(IPv4)"},
574 { EIGRP_TLV_IPv6_INT, "Internal Route(IPv6)"},
575 { EIGRP_TLV_IPv6_EXT, "External Route(IPv6)"},
576 { EIGRP_TLV_IPv6_COM, "Ext-Community(IPv6)"},
577 { EIGRP_TLV_IPX_INT, "IPX Internal Route(IPX)"},
578 { EIGRP_TLV_IPX_EXT, "IPX External Route(IPX)"},
579
580 /* Deprecated TLV formats */
581 { EIGRP_TLV_AT_INT, "Internal Route(ATALK)"},
582 { EIGRP_TLV_AT_EXT, "External Route(ATALK)"},
583 { EIGRP_TLV_AT_CBL, "Cable Configuration(ATALK)"},
584 { EIGRP_TLV_MTR_REQ, "Request(MTR)"},
585 { EIGRP_TLV_MTR_INT, "Internal Route(MTR)"},
586 { EIGRP_TLV_MTR_EXT, "External Route(MTR)"},
587 { EIGRP_TLV_MTR_COM, "Ext-Community(MTR)"},
588 { EIGRP_TLV_MTR_TIDLIST, "TopologyID List"},
589
590 /* Current "Wide Metric" TLV formats */
591 { EIGRP_TLV_MP_REQ, "Request"},
592 { EIGRP_TLV_MP_INT, "Internal Route"},
593 { EIGRP_TLV_MP_EXT, "External Route"},
594 { EIGRP_TLV_MP_COM, "Ext-Community"},
595
596 { 0, NULL}
597 };
598
599 const value_string eigrp_proto2string[] = {
600 { IGRP1_PROTID, "IGRP"},
601 { IGRP2_PROTID, "EIGRP"},
602 { STATIC_PROTID, "Static Route"},
603 { RIP_PROTID, "RIP"},
604 { HELLO_PROTID, "Hello"},
605 { OSPF_PROTID, "OSPF"},
606 { ISIS_PROTID, "IS-IS"},
607 { EGP_PROTID, "EGP"},
608 { BGP_PROTID, "BGP"},
609 { IDRP_PROTID, "IDRP"},
610 { CONN_PROTID, "Connected Route"},
611 { 0, NULL}
612 };
613
614 static const value_string eigrp_auth2string[] = {
615 { EIGRP_AUTH_TYPE_TEXT, "TEXT"},
616 { EIGRP_AUTH_TYPE_MD5, "MD5"},
617 { EIGRP_AUTH_TYPE_SHA256, "SHA256"},
618 { 0, NULL},
619 };
620
621 static const value_string eigrp_vrid2string[] = {
622 { EIGRP_VRID_AF_BASE, "(Address-Family)"},
623 { EIGRP_VRID_SF_BASE, "(Service-Family)"},
624 { EIGRP_VRID_MCAST_BASE, "(Multi-Cast)"},
625 { 0, NULL}
626 };
627
628 static const value_string eigrp_afi2string[] = {
629 { EIGRP_AF_IPv4, "IPv4"},
630 { EIGRP_AF_IPv6, "IPv6"},
631 { EIGRP_AF_IPX, "IPX"},
632 { EIGRP_AF_ATALK, "Appletalk"},
633 { EIGRP_SF_COMMON, "Service Family"},
634 { EIGRP_SF_IPv4, "IPv4 Service Family"},
635 { EIGRP_SF_IPv6, "IPv6 Service Family"},
636 { 0, NULL}
637 };
638
639 static const value_string eigrp_attr_opcode2string[] = {
640 { EIGRP_ATTR_NOOP, "NO-OP for padding"},
641 { EIGRP_ATTR_SCALED, "Scaled Metric"},
642 { EIGRP_ATTR_TAG, "Admin Tag"},
643 { EIGRP_ATTR_COMM, "Community"},
644 { EIGRP_ATTR_JITTER, "Jitter"},
645 { EIGRP_ATTR_QENERGY, "Non-Active energy"},
646 { EIGRP_ATTR_ENERGY, "Active energy"},
647 { 0, NULL}
648 };
649
650 static const value_string eigrp_saf_type2string[] = {
651 { EIGRP_SVCDATA_COMPLETE, "Attached Service Data"},
652 { EIGRP_SVCDATA_TRIMMED, "Trimmed Service Data"},
653 { 0, NULL}
654 };
655
656 static const value_string eigrp_saf_srv2string[] = {
657 { SAF_SERVICE_ID_CAPMAN, "Capabilities Manager"},
658 { SAF_SERVICE_ID_UC, "Unified Communications"},
659 { SAF_SERVICE_ID_PFR, "Performance Routing"},
660 { 0, NULL}
661 };
662
663 static const value_string eigrp_metric_comm_type_vals[] = {
664 { EIGRP_EXTCOMM_EIGRP, "EIGRP_EXTCOMM_EIGRP"},
665 { EIGRP_EXTCOMM_VRR, "EIGRP_EXTCOMM_VRR"},
666 { EIGRP_EXTCOMM_DAD, "EIGRP_EXTCOMM_DAD"},
667 { EIGRP_EXTCOMM_VRHB, "EIGRP_EXTCOMM_VRHB"},
668 { EIGRP_EXTCOMM_SRLM, "EIGRP_EXTCOMM_SRLM"},
669 { EIGRP_EXTCOMM_SAR, "EIGRP_EXTCOMM_SAR"},
670 { EIGRP_EXTCOMM_RPM, "EIGRP_EXTCOMM_RPM"},
671 { EIGRP_EXTCOMM_SOO_ASFMT, "EIGRP_EXTCOMM_SOO"},
672 { EIGRP_EXTCOMM_SOO_ADRFMT, "EIGRP_EXTCOMM_SOO"},
673 { 0, NULL}
674 };
675
676
677 /**
678 *@fn void dissect_eigrp_parameter (proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, proto_item *ti)
679 *
680 *
681 * @param[in,out] tree detail dissection result
682 * @param[in] tvb packet data
683 * @param[in] pinfo general data about the protocol
684 * @param[in] ti protocol item
685 *
686 * @par
687 * Dissect the Parameter TLV, which is used to convey metric weights and the
688 * hold time.
689 *
690 * @brief
691 * Note the addition of K6 for the new extended metrics, and does not apply to
692 * older TLV packet formats.
693 */
694 static void
dissect_eigrp_parameter(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,proto_item * ti)695 dissect_eigrp_parameter (proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo,
696 proto_item *ti)
697 {
698 int offset = 0;
699 guint8 k1, k2, k3, k4, k5;
700
701 k1 = tvb_get_guint8(tvb, offset);
702 proto_tree_add_item(tree, hf_eigrp_par_k1, tvb, offset, 1, ENC_BIG_ENDIAN);
703
704 offset += 1;
705 k2 = tvb_get_guint8(tvb, offset);
706 proto_tree_add_item(tree, hf_eigrp_par_k2, tvb, offset, 1, ENC_BIG_ENDIAN);
707
708 offset += 1;
709 k3 = tvb_get_guint8(tvb, offset);
710 proto_tree_add_item(tree, hf_eigrp_par_k3, tvb, offset, 1, ENC_BIG_ENDIAN);
711
712 offset += 1;
713 k4 = tvb_get_guint8(tvb, offset);
714 proto_tree_add_item(tree, hf_eigrp_par_k4, tvb, offset, 1, ENC_BIG_ENDIAN);
715
716 offset += 1;
717 k5 = tvb_get_guint8(tvb, offset);
718 proto_tree_add_item(tree, hf_eigrp_par_k5, tvb, offset, 1, ENC_BIG_ENDIAN);
719
720 offset += 1;
721 proto_tree_add_item(tree, hf_eigrp_par_k6, tvb, offset, 1, ENC_BIG_ENDIAN);
722
723 offset += 1;
724 proto_tree_add_item(tree, hf_eigrp_par_holdtime, tvb, offset, 2, ENC_BIG_ENDIAN);
725
726 if (k1 == 255 && k2 == 255 && k3 == 255 && k4 == 255 && k5 == 255) {
727 proto_item_append_text(ti, ": Peer Termination");
728 expert_add_info(pinfo, ti, &ei_eigrp_peer_termination);
729 }
730 }
731
732 /**
733 *@fn void dissect_eigrp_auth_tlv (proto_tree *tree, tvbuff_t *tvb,
734 * packet_info *pinfo, proto_item *ti)
735 *
736 * @param[in,out] tree detail dissection result
737 * @param[in] tvb packet data
738 * @param[in] pinfo general data about the protocol
739 * @param[in] ti protocol item
740 *
741 * @par
742 * Dissect the Authentication TLV and display digest. Currently MD5 and SHA256
743 * HMAC is supported. For SHA256, a "secret key" with the HMAC-SHA-256
744 * password, the source address from which the packet is sent. This combined
745 * string is used as the key for hash calculation.
746 */
747 static void
dissect_eigrp_auth_tlv(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,proto_item * ti)748 dissect_eigrp_auth_tlv (proto_tree *tree, tvbuff_t *tvb,
749 packet_info *pinfo, proto_item *ti)
750 {
751 proto_item *ti_auth_type, *ti_auth_len;
752 int offset = 0;
753 guint16 auth_type, auth_len;
754
755 /* print out what family we dealing with... */
756
757 auth_type = tvb_get_ntohs(tvb, 0);
758 auth_len = tvb_get_ntohs(tvb, 2);
759
760 proto_item_append_text(ti, " %s", val_to_str_const(auth_type, eigrp_auth2string, ""));
761
762 ti_auth_type = proto_tree_add_item(tree, hf_eigrp_auth_type, tvb, offset, 2, ENC_BIG_ENDIAN);
763 offset += 2;
764 ti_auth_len = proto_tree_add_item(tree, hf_eigrp_auth_len, tvb, offset, 2, ENC_BIG_ENDIAN);
765 offset += 2;
766 proto_tree_add_item(tree, hf_eigrp_auth_keyid, tvb, offset, 4, ENC_BIG_ENDIAN);
767 offset += 4;
768 proto_tree_add_item(tree, hf_eigrp_auth_keyseq, tvb, offset, 4, ENC_BIG_ENDIAN);
769 offset += 4;
770 proto_tree_add_item(tree, hf_eigrp_nullpad, tvb, offset, 8, ENC_NA);
771 offset += 8;
772
773 switch (auth_type) {
774 case EIGRP_AUTH_TYPE_MD5:
775 if (EIGRP_AUTH_TYPE_MD5_LEN != auth_len) {
776 expert_add_info_format(pinfo, ti_auth_len, &ei_eigrp_auth_len, "Invalid auth len %u", auth_len);
777 } else {
778 proto_tree_add_item(tree, hf_eigrp_auth_digest, tvb, offset,
779 EIGRP_AUTH_TYPE_MD5_LEN, ENC_NA);
780 }
781 break;
782
783 case EIGRP_AUTH_TYPE_SHA256:
784 if (EIGRP_AUTH_TYPE_SHA256_LEN != auth_len) {
785 expert_add_info_format(pinfo, ti_auth_len, &ei_eigrp_auth_len, "Invalid auth len %u", auth_len);
786
787 } else {
788 proto_tree_add_item(tree, hf_eigrp_auth_digest, tvb, offset,
789 EIGRP_AUTH_TYPE_SHA256_LEN, ENC_NA);
790 }
791 break;
792
793 case EIGRP_AUTH_TYPE_NONE:
794 case EIGRP_AUTH_TYPE_TEXT:
795 default:
796 expert_add_info_format(pinfo, ti_auth_type, &ei_eigrp_auth_type, "Invalid auth type %u", auth_type);
797 break;
798 }
799 }
800
801 /**
802 *@fn void dissect_eigrp_seq_tlv (proto_tree *tree, tvbuff_t *tvb,
803 * packet_info *pinfo, proto_item *ti)
804 *
805 * @param[in,out] tree detail dissection result
806 * @param[in] tvb packet data
807 * @param[in] pinfo general data about the protocol
808 * @param[in] ti protocol item
809 *
810 * @par
811 * Dissect the Sequence TLV which consists of the addresses of peers that must
812 * not receive the next multicast packet transmitted.
813 */
814 static void
dissect_eigrp_seq_tlv(proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,proto_item * ti)815 dissect_eigrp_seq_tlv (proto_tree *tree, tvbuff_t *tvb,
816 packet_info *pinfo, proto_item *ti)
817 {
818 proto_item *ti_addrlen;
819 int offset = 0;
820 guint8 addr_len;
821
822 while (tvb_reported_length_remaining(tvb, offset) > 0) {
823 addr_len = tvb_get_guint8(tvb, offset);
824 ti_addrlen = proto_tree_add_item(tree, hf_eigrp_seq_addrlen, tvb, offset, 1, ENC_BIG_ENDIAN);
825 offset += 1;
826
827 if (tvb_reported_length_remaining(tvb, offset) < addr_len) {
828 /* The remaining part of the TLV is shorter than the address it should contain */
829 expert_add_info(pinfo, ti, &ei_eigrp_tlv_trunc);
830 break;
831 }
832
833 switch (addr_len) {
834 case 4:
835 /* IPv4 */
836 proto_tree_add_item(tree, hf_eigrp_seq_ipv4addr, tvb, offset, addr_len, ENC_BIG_ENDIAN);
837 break;
838 case 10:
839 /* IPX */
840 proto_tree_add_bytes_format_value(tree, hf_eigrp_ipx_address, tvb, offset, addr_len, NULL,
841 "IPX Address: %s", tvb_address_to_str(pinfo->pool, tvb, AT_IPX, 1));
842 break;
843 case 16:
844 /* IPv6 */
845 proto_tree_add_item(tree, hf_eigrp_seq_ipv6addr, tvb, offset, addr_len,
846 ENC_NA);
847 break;
848 default:
849 expert_add_info(pinfo, ti_addrlen, &ei_eigrp_seq_addrlen);
850 }
851
852 offset += addr_len;
853 }
854 }
855
856 /**
857 *@fn void dissect_eigrp_sw_version (tvbuff_t *tvb, proto_tree *tree,
858 * proto_item *ti)
859 *
860 * @param[in,out] tree detail dissection result
861 * @param[in] tvb packet data
862 * @param[in] ti protocol item
863 *
864 * @par
865 * Dissect Software Version TLV. The older versions of EIGRP sent the IOS
866 * version along with the TLV Version. When EIGRP "plugins" were created,
867 * this as change to send the "Release" of EIGRP to better identify where fixes
868 * are present(missing)
869 */
870 static void
dissect_eigrp_sw_version(tvbuff_t * tvb,proto_tree * tree,proto_item * ti)871 dissect_eigrp_sw_version (tvbuff_t *tvb, proto_tree *tree,
872 proto_item *ti)
873 {
874 int offset = 0;
875 guint8 ios_rel_major, ios_rel_minor;
876 guint8 eigrp_rel_major, eigrp_rel_minor;
877
878 ios_rel_major = tvb_get_guint8(tvb, 0);
879 ios_rel_minor = tvb_get_guint8(tvb, 1);
880 proto_tree_add_item(tree, hf_eigrp_release, tvb, offset, 2, ENC_BIG_ENDIAN);
881 offset += 2;
882 proto_item_append_text(ti, ": EIGRP=%u.%u", ios_rel_major, ios_rel_minor);
883
884 eigrp_rel_major = tvb_get_guint8(tvb, 2);
885 eigrp_rel_minor = tvb_get_guint8(tvb, 3);
886 proto_tree_add_item(tree, hf_eigrp_tlv_version, tvb, offset, 2, ENC_BIG_ENDIAN);
887 proto_item_append_text(ti, ", TLV=%u.%u",
888 eigrp_rel_major, eigrp_rel_minor);
889 }
890
891 /**
892 *@fn void dissect_eigrp_next_mcast_seq (tvbuff_t *tvb, proto_tree *tree,
893 * proto_item *ti)
894 *
895 * @param[in,out] tree detail dissection result
896 * @param[in] tvb packet data
897 * @param[in] ti protocol item
898 *
899 * @par
900 * Dissect Next Multicast Sequence TLV, which is part of the Hello with a
901 * Sequence TLV; this gives a two-way binding between the packets and plugs a
902 * hole where a multicast could be received by the wrong peers (due to a
903 * string of lost packets).
904 */
905 static void
dissect_eigrp_next_mcast_seq(tvbuff_t * tvb,proto_tree * tree,proto_item * ti)906 dissect_eigrp_next_mcast_seq (tvbuff_t *tvb, proto_tree *tree,
907 proto_item *ti)
908 {
909 proto_tree_add_item(tree, hf_eigrp_next_mcast_seq, tvb, 0, 4,
910 ENC_BIG_ENDIAN);
911 proto_item_append_text(ti, ": %u", tvb_get_ntohl(tvb, 0));
912 }
913
914 /**
915 *@fn void dissect_eigrp_peer_stubinfo (tvbuff_t *tvb, proto_tree *tree)
916 *
917 *
918 * @param[in,out] tree detail dissection result
919 * @param[in] tvb packet data
920 *
921 * @par
922 * Dissect the PEER STUB TLV which contains the route types which the Peer will
923 * advertise. This is used to suppress QUERYs from being sent to the Peer
924 */
925 static void
dissect_eigrp_peer_stubinfo(tvbuff_t * tvb,proto_tree * tree)926 dissect_eigrp_peer_stubinfo (tvbuff_t *tvb, proto_tree *tree)
927 {
928 proto_tree_add_bitmask(tree, tvb, 0, hf_eigrp_stub_flags, ett_eigrp_stub_flags,
929 eigrp_stub_flag_fields, ENC_BIG_ENDIAN);
930 }
931
932 /**
933 *@fn void dissect_eigrp_peer_termination (packet_info *pinfo, proto_item *ti)
934 *
935 * @param[in] pinfo general data about the protocol
936 * @param[in] ti protocol item
937 *
938 * @par
939 * Dissect Peer Termination TLV. This TLV has no parameters and is used to
940 * signal an adjacency should be tore down
941 */
942 static void
dissect_eigrp_peer_termination(packet_info * pinfo,proto_item * ti)943 dissect_eigrp_peer_termination (packet_info *pinfo, proto_item *ti)
944 {
945 expert_add_info(pinfo, ti, &ei_eigrp_peer_termination_graceful);
946 }
947
948 /**
949 *@fn void dissect_eigrp_peer_tidlist (proto_tree *tree, tvbuff_t *tvb)
950 *
951 * @param[in,out] tree detail dissection result
952 * @param[in] tvb packet data
953 *
954 * @par
955 * Dissect the Topology Identifier List TLV. This TLV was introduced as part
956 * of the "MTR (Multi-Topology Routing) Project to support sub topologies
957 * within a given Autonomous System. The following represents the format of
958 * the TID list
959 *
960 * 0 1 2 3
961 * 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
962 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
963 * | Flags | Length |
964 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
965 * | Variable Length TID (two bytes) list |
966 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
967 */
968 static void
dissect_eigrp_peer_tidlist(proto_tree * tree,tvbuff_t * tvb)969 dissect_eigrp_peer_tidlist (proto_tree *tree, tvbuff_t *tvb)
970 {
971 proto_tree *sub_tree;
972 int offset = 0;
973 guint16 size;
974
975 proto_tree_add_item(tree, hf_eigrp_tidlist_flags, tvb, offset, 2,
976 ENC_BIG_ENDIAN);
977 offset += 2;
978
979 size = tvb_get_ntohs(tvb, offset) / 2;
980 proto_tree_add_item(tree, hf_eigrp_tidlist_len, tvb, offset, 2,
981 ENC_BIG_ENDIAN);
982 offset += 2;
983
984 sub_tree = proto_tree_add_subtree_format(tree, tvb, offset, (size*2), ett_eigrp_tidlist, NULL, "%d TIDs", size);
985 for (; size ; size--) {
986 proto_tree_add_item(sub_tree, hf_eigrp_tidlist_tid, tvb, offset, 2,
987 ENC_BIG_ENDIAN);
988 offset += 2;
989 }
990 }
991
992 /**
993 *@fn int dissect_eigrp_extdata_flags (proto_tree *tree, tvbuff_t *tvb, int offset)
994 *
995 * @param[in,out] tree detail dissection result
996 * @param[in] tvb packet data
997 * @param[in] offset current byte offset in packet being processed
998 *
999 * @return int number of bytes process
1000 *
1001 * @par
1002 * Dissect the Flags field in the external data section of an external
1003 * route.The following represents the format of the bit field
1004 *
1005 * 7 6 5 4 3 2 1 0
1006 * +-+-+-+-+-+-+-+-+
1007 * | Flags |
1008 * +-+-+-+-+-+-+-+-+
1009 * | |
1010 * | +- Route is External *not used*
1011 * +--- Route is Candidate Default
1012 */
1013 static int
dissect_eigrp_extdata_flags(proto_tree * tree,tvbuff_t * tvb,int offset)1014 dissect_eigrp_extdata_flags (proto_tree *tree, tvbuff_t *tvb, int offset)
1015 {
1016 proto_tree *sub_tree;
1017 tvbuff_t *sub_tvb;
1018
1019 /* Decode the route flags field */
1020 sub_tree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_eigrp_extdata_flags, NULL, "External Flags");
1021 sub_tvb = tvb_new_subset_remaining(tvb, offset);
1022
1023 proto_tree_add_item(sub_tree, hf_eigrp_extdata_flag_ext, sub_tvb, 0, 1,
1024 ENC_BIG_ENDIAN);
1025 proto_tree_add_item(sub_tree, hf_eigrp_extdata_flag_cd, sub_tvb, 0, 1,
1026 ENC_BIG_ENDIAN);
1027
1028 offset += 1;
1029 return(offset);
1030 }
1031
1032 /**
1033 *@fn int dissect_eigrp_metric_flags (proto_tree *tree, tvbuff_t *tvb, int offset, int limit)
1034 *
1035 * @param[in,out] tree detail dissection result
1036 * @param[in] tvb packet data
1037 * @param[in] offset current byte offset in packet being processed
1038 * @param[in] limit maximum number of bytes which can be process
1039 *
1040 * @return int number of bytes process
1041 *
1042 * @par
1043 * Dissect Protocol Dependent Module (PDM) Flags field in the route metric
1044 * section of an internal and external route. The following represents the
1045 * format of the bit field
1046 *
1047 * MSB LSB
1048 * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0
1049 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1050 * | Flags | MP Flags |
1051 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1052 * | | |
1053 * | | +- Route is Replicated
1054 * | +--- Route is Active
1055 * +----- Source Withdraw
1056 */
1057 static int
dissect_eigrp_metric_flags(proto_tree * tree,tvbuff_t * tvb,int offset,int limit)1058 dissect_eigrp_metric_flags (proto_tree *tree, tvbuff_t *tvb, int offset, int limit)
1059 {
1060 proto_tree *sub_tree;
1061 tvbuff_t *sub_tvb;
1062
1063 /* Decode the route flags field */
1064 sub_tree = proto_tree_add_subtree(tree, tvb, offset, limit, ett_eigrp_metric_flags, NULL, "Flags");
1065 sub_tvb = tvb_new_subset_length_caplen(tvb, offset, limit, -1);
1066
1067 /* just care about 'flags' byte, there are no MP flags for now */
1068 proto_tree_add_item(sub_tree, hf_eigrp_metric_flags_srcwd, sub_tvb, 0, 1,
1069 ENC_BIG_ENDIAN);
1070 proto_tree_add_item(sub_tree, hf_eigrp_metric_flags_cd, sub_tvb, 0, 1,
1071 ENC_BIG_ENDIAN);
1072 proto_tree_add_item(sub_tree, hf_eigrp_metric_flags_active, sub_tvb, 0, 1,
1073 ENC_BIG_ENDIAN);
1074 proto_tree_add_item(sub_tree, hf_eigrp_metric_flags_repl, sub_tvb, 0, 1,
1075 ENC_BIG_ENDIAN);
1076
1077 offset += limit;
1078 return(offset);
1079 }
1080
1081 /**
1082 *@fn void dissect_eigrp_ipv4_addrs (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1083 * packet_info *pinfo, int offset, int unreachable)
1084 *
1085 * @param[in,out] tree detail dissection result
1086 * @param[in] tvb packet data
1087 * @param[in] pinfo general data about the protocol
1088 * @param[in] offset current byte offset in packet being processed
1089 *
1090 * @par
1091 * Dissect all IPv4 address from offset though the end of the packet
1092 */
1093 static void
dissect_eigrp_ipv4_addrs(proto_item * ti,proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,int offset,int unreachable)1094 dissect_eigrp_ipv4_addrs (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1095 packet_info *pinfo, int offset, int unreachable)
1096 {
1097 guint8 length;
1098 ws_in4_addr ip_addr;
1099 int addr_len;
1100 proto_item *ti_prefixlen, *ti_dst;
1101 int first = TRUE;
1102
1103 for (; tvb_reported_length_remaining(tvb, offset) > 0; offset += (1 + addr_len)) {
1104 length = tvb_get_guint8(tvb, offset);
1105 addr_len = tvb_get_ipv4_addr_with_prefix_len(tvb, offset + 1, &ip_addr, length);
1106
1107 if (addr_len < 0) {
1108 /* Invalid prefix length, more than 32 bits */
1109 ti_prefixlen = proto_tree_add_item(tree, hf_eigrp_ipv4_prefixlen,
1110 tvb, offset, 1, ENC_BIG_ENDIAN);
1111 expert_add_info_format(pinfo, ti_prefixlen, &ei_eigrp_prefixlen, "Invalid prefix length %u, must be <= 32", length);
1112 break; /* We don't know how long this address is */
1113 } else {
1114 address addr;
1115
1116 proto_tree_add_item(tree, hf_eigrp_ipv4_prefixlen, tvb, offset, 1,
1117 ENC_BIG_ENDIAN);
1118 offset += 1;
1119 set_address(&addr, AT_IPv4, 4, &ip_addr);
1120 ti_dst = proto_tree_add_ipv4(tree, hf_eigrp_ipv4_destination, tvb, offset, addr_len, ip_addr);
1121
1122 /* add it to the top level line */
1123 proto_item_append_text(ti," %c %s/%u", first ? '=':',',
1124 address_to_str(pinfo->pool, &addr), length);
1125
1126 if (unreachable) {
1127 expert_add_info(pinfo, ti_dst, &ei_eigrp_unreachable);
1128 }
1129 }
1130 first = FALSE;
1131 }
1132 }
1133
1134 /**
1135 *@fn void dissect_eigrp_ipv6_addrs (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1136 * packet_info *pinfo, int offset, int unreachable)
1137 *
1138 * @param[in,out] tree detail dissection result
1139 * @param[in] tvb packet data
1140 * @param[in] pinfo general data about the protocol
1141 * @param[in] offset current byte offset in packet being processed
1142 *
1143 * @par
1144 * Dissect all IPv6 address from offset though the end of the packet
1145 */
1146 static void
dissect_eigrp_ipv6_addrs(proto_item * ti,proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,int offset,int unreachable)1147 dissect_eigrp_ipv6_addrs (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1148 packet_info *pinfo, int offset, int unreachable)
1149 {
1150 guint8 length;
1151 int addr_len;
1152 ws_in6_addr addr;
1153 address addr_str;
1154 proto_item *ti_prefixlen, *ti_dst;
1155 int first = TRUE;
1156
1157 for (; tvb_reported_length_remaining(tvb, offset) > 0; offset += (1 + addr_len)) {
1158 length = tvb_get_guint8(tvb, offset);
1159 addr_len = tvb_get_ipv6_addr_with_prefix_len(tvb, offset + 1, &addr, length);
1160
1161 if (addr_len < 0) {
1162 /* Invalid prefix length, more than 128 bits */
1163 ti_prefixlen = proto_tree_add_item(tree, hf_eigrp_ipv6_prefixlen,
1164 tvb, offset, 1, ENC_BIG_ENDIAN);
1165 expert_add_info_format(pinfo, ti_prefixlen, &ei_eigrp_prefixlen, "Invalid prefix length %u, must be <= 128", length);
1166 break; /* We don't know how long this address is */
1167 } else {
1168 proto_tree_add_item(tree, hf_eigrp_ipv6_prefixlen, tvb, offset, 1,
1169 ENC_BIG_ENDIAN);
1170 offset += 1;
1171
1172 if ((length < 128) && (length % 8 == 0)) {
1173 addr_len++;
1174 }
1175
1176 set_address(&addr_str, AT_IPv6, 16, addr.bytes);
1177 ti_dst = proto_tree_add_ipv6(tree, hf_eigrp_ipv6_destination, tvb, offset, addr_len, &addr);
1178
1179 /* add it to the top level line */
1180 proto_item_append_text(ti," %c %s/%u", first ? '=':',',
1181 address_to_str(pinfo->pool, &addr_str), length);
1182
1183 if (unreachable) {
1184 expert_add_info(pinfo, ti_dst, &ei_eigrp_unreachable);
1185 }
1186 }
1187 first = FALSE;
1188 }
1189 }
1190
1191 /**
1192 *@fn int dissect_eigrp_ipx_addrs (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1193 * packet_info *pinfo, int offset, int unreachable)
1194 *
1195 * @param[in,out] tree detail dissection result
1196 * @param[in] tvb packet data
1197 * @param[in] pinfo general data about the protocol
1198 * @param[in] offset current byte offset in packet being processed
1199 *
1200 * @return int number of bytes process
1201 *
1202 * @par
1203 * Dissect all IPX address from offset though the end of the packet
1204 */
1205 static int
dissect_eigrp_ipx_addrs(proto_item * ti,proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,int offset,int unreachable)1206 dissect_eigrp_ipx_addrs (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1207 packet_info *pinfo, int offset, int unreachable)
1208 {
1209 proto_item *ti_dst;
1210
1211 ti_dst = proto_tree_add_item(tree, hf_eigrp_ipx_dest, tvb, offset, 4,
1212 ENC_NA);
1213
1214 /* add it to the top level line */
1215 proto_item_append_text(ti," = %s", ipxnet_to_str_punct(pinfo->pool, tvb_get_ntohl(tvb, offset), ' '));
1216
1217 if (unreachable) {
1218 expert_add_info(pinfo, ti_dst, &ei_eigrp_unreachable);
1219 }
1220
1221 offset +=4;
1222 return(offset);
1223 }
1224
1225 /**
1226 *@fn void dissect_eigrp_services (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1227 * packet_info *pinfo, int offset)
1228 *
1229 * @param[in,out] tree detail dissection result
1230 * @param[in] tvb packet data
1231 * @param[in] pinfo general data about the protocol
1232 * @param[in] ti protocol item
1233 * @param[in] offset current byte offset in packet being processed
1234 *
1235 * @par
1236 * Dissect all SAF Services from offset though the end of the packet. The
1237 * following represents the format of a SAF Service:
1238 *
1239 * 0 1 2 3
1240 * 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
1241 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1242 * | Service | SubService |
1243 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1244 * | GUID |
1245 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1246 * | GUID(cont) |
1247 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1248 * | GUID(cont) |
1249 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1250 * | GUID(cont) |
1251 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1252 * | Type | Length |
1253 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1254 * | Reachability AFI | Reachability Port |
1255 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1256 * | Reachability Protocol | Reachability Addr |
1257 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1258 * | Reachability Addr(cont) |
1259 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1260 * | Reachability Addr(cont) |
1261 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1262 * | Reachability Addr(cont) |
1263 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1264 * | Reachability Addr(cont) | Sequence |
1265 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1266 * | Sequence(cont) |\/\/\/ Service Data \/\/\/|
1267 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1268 *
1269 */
1270 static void
dissect_eigrp_services(proto_item * ti,proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,int offset)1271 dissect_eigrp_services (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1272 packet_info *pinfo, int offset)
1273 {
1274 int afi, length, remaining;
1275 int sub_offset;
1276 proto_item *sub_ti;
1277 proto_tree *sub_tree, *reach_tree;
1278 tvbuff_t *sub_tvb, *reach_tvb;
1279 guint16 service, sub_service;
1280
1281 remaining = tvb_captured_length_remaining(tvb, offset);
1282 sub_tree = proto_tree_add_subtree(tree, tvb, offset, remaining, ett_eigrp_tlv_metric, &sub_ti, "SAF Service ");
1283 sub_tvb = tvb_new_subset_length_caplen(tvb, offset, remaining, -1);
1284 sub_offset = 0;
1285
1286 for (; tvb_reported_length_remaining(sub_tvb, sub_offset) > 0; ) {
1287 service = tvb_get_ntohs(sub_tvb, sub_offset);
1288 proto_item_append_text(sub_ti, "%c %s", (sub_offset == 0 ? '=':','),
1289 val_to_str_const(service, eigrp_saf_srv2string, ""));
1290
1291 sub_service = tvb_get_ntohs(sub_tvb, sub_offset+2);
1292 proto_item_append_text(ti, "%c %u:%u", (sub_offset == 0 ? '=':','),
1293 service, sub_service);
1294
1295 proto_tree_add_item(sub_tree, hf_eigrp_saf_service, sub_tvb,
1296 sub_offset, 2, ENC_BIG_ENDIAN);
1297 sub_offset += 2;
1298 proto_tree_add_item(sub_tree, hf_eigrp_saf_subservice, sub_tvb,
1299 sub_offset, 2, ENC_BIG_ENDIAN);
1300 sub_offset += 2;
1301 proto_tree_add_item(sub_tree, hf_eigrp_saf_guid, sub_tvb,
1302 sub_offset, GUID_LEN, ENC_BIG_ENDIAN);
1303 sub_offset += GUID_LEN;
1304
1305 proto_tree_add_item(sub_tree, hf_eigrp_saf_data_type, sub_tvb,
1306 sub_offset, 2, ENC_BIG_ENDIAN);
1307 sub_offset += 2;
1308 length = tvb_get_ntohs(sub_tvb, sub_offset);
1309 proto_tree_add_item(sub_tree, hf_eigrp_saf_data_length, sub_tvb,
1310 sub_offset, 2, ENC_BIG_ENDIAN);
1311 sub_offset += 2;
1312
1313 /*
1314 * Reachability information
1315 */
1316 reach_tree = proto_tree_add_subtree(sub_tree, sub_tvb, sub_offset, 22,
1317 ett_eigrp_saf_reachability, NULL, "Reachability");
1318 reach_tvb = tvb_new_subset_length_caplen(sub_tvb, sub_offset, 22, -1);
1319
1320 afi = tvb_get_ntohs(reach_tvb, 0);
1321 proto_tree_add_item(reach_tree, hf_eigrp_saf_reachability_afi,
1322 reach_tvb, 0, 2, ENC_BIG_ENDIAN);
1323 proto_tree_add_item(reach_tree, hf_eigrp_saf_reachability_port,
1324 reach_tvb, 2, 2, ENC_BIG_ENDIAN);
1325 proto_tree_add_item(reach_tree, hf_eigrp_saf_reachability_protocol,
1326 reach_tvb, 4, 2, ENC_BIG_ENDIAN);
1327
1328 switch (afi) {
1329 case EIGRP_AF_IPv4:
1330 proto_tree_add_item(reach_tree, hf_eigrp_saf_reachability_addr_ipv4,
1331 reach_tvb, 6, 4, ENC_BIG_ENDIAN);
1332 proto_tree_add_item(reach_tree, hf_eigrp_nullpad, reach_tvb, 10, 12,
1333 ENC_NA);
1334 break;
1335
1336 case EIGRP_AF_IPv6:
1337 proto_tree_add_item(reach_tree, hf_eigrp_saf_reachability_addr_ipv6,
1338 reach_tvb, 6, 16, ENC_NA);
1339 break;
1340 default:
1341 /* just print zeros... */
1342 proto_tree_add_item(reach_tree, hf_eigrp_saf_reachability_addr_hex,
1343 reach_tvb, 6, 16, ENC_NA);
1344 break;
1345 }
1346 sub_offset += 22;
1347
1348 proto_tree_add_item(sub_tree, hf_eigrp_saf_data_sequence, sub_tvb,
1349 sub_offset, 4, ENC_BIG_ENDIAN);
1350 sub_offset += 4;
1351
1352 if (length > 0) {
1353 tvbuff_t *xml_tvb;
1354 guint8 *test_string, *tok;
1355
1356 /*
1357 * Service-Data is usually (but not always) plain text, specifically
1358 * XML. If it "looks like" XML (begins with optional white-space
1359 * followed by a '<'), try XML. Otherwise, try plain-text.
1360 */
1361 xml_tvb = tvb_new_subset_length(sub_tvb, sub_offset, length);
1362 test_string = tvb_get_string_enc(pinfo->pool, xml_tvb, 0, (length < 32 ?
1363 length : 32), ENC_ASCII);
1364 tok = strtok(test_string, " \t\r\n");
1365
1366 if (tok && tok[0] == '<') {
1367 /* Looks like XML */
1368 dissector_try_string(media_type_table, "application/xml",
1369 xml_tvb, pinfo, sub_tree, NULL);
1370 } else {
1371 /* Try plain text */
1372 dissector_try_string(media_type_table, "text/plain",
1373 xml_tvb, pinfo, sub_tree, NULL);
1374 }
1375 }
1376 sub_offset += length;
1377 }
1378 }
1379
1380 /**
1381 *@fn int dissect_eigrp_legacy_metric (proto_tree *tree, tvbuff_t *tvb, int offset)
1382 *
1383 * @param[in,out] tree detail dissection result
1384 * @param[in] tvb packet data
1385 * @param[in] offset current byte offset in packet being processed
1386 *
1387 * @return int number of bytes process
1388 *
1389 * @par
1390 * Dissect the TLV Versions 1.2 (legacy) and 3.0 (deprecated) metric
1391 * sections. The following represents the format
1392 *
1393 * 0 1 2 3
1394 * 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
1395 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1396 * | Scaled Delay |
1397 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1398 * | Scaled Bandwidth |
1399 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1400 * | MTU | Hopcount |
1401 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1402 * | Reliability | Load | Internal Tag | Flag |
1403 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1404 *
1405 */
1406 static int
dissect_eigrp_legacy_metric(proto_tree * tree,tvbuff_t * tvb,int offset)1407 dissect_eigrp_legacy_metric (proto_tree *tree, tvbuff_t *tvb, int offset)
1408 {
1409 proto_tree *sub_tree;
1410 tvbuff_t *sub_tvb;
1411
1412 sub_tree = proto_tree_add_subtree(tree, tvb, offset, 16, ett_eigrp_tlv_metric, NULL, "Legacy Metric");
1413 sub_tvb = tvb_new_subset_length_caplen(tvb, offset, 16, -1);
1414
1415 proto_tree_add_item(sub_tree, hf_eigrp_legacy_metric_delay, sub_tvb,
1416 0, 4, ENC_BIG_ENDIAN);
1417 proto_tree_add_item(sub_tree, hf_eigrp_legacy_metric_bw, sub_tvb,
1418 4, 4, ENC_BIG_ENDIAN);
1419 proto_tree_add_item(sub_tree, hf_eigrp_legacy_metric_mtu, sub_tvb,
1420 8, 3, ENC_BIG_ENDIAN);
1421 proto_tree_add_item(sub_tree, hf_eigrp_legacy_metric_hopcount, sub_tvb,
1422 11, 1, ENC_BIG_ENDIAN);
1423 proto_tree_add_item(sub_tree, hf_eigrp_legacy_metric_rel, sub_tvb,
1424 12, 1, ENC_BIG_ENDIAN);
1425 proto_tree_add_item(sub_tree, hf_eigrp_legacy_metric_load, sub_tvb,
1426 13, 1, ENC_BIG_ENDIAN);
1427 proto_tree_add_item(sub_tree, hf_eigrp_legacy_metric_intag, sub_tvb,
1428 14, 1, ENC_BIG_ENDIAN);
1429
1430 /* Decode the route flags field */
1431 dissect_eigrp_metric_flags(sub_tree, sub_tvb, 15, 1);
1432
1433 offset += 16;
1434 return(offset);
1435 }
1436
1437 /**
1438 *@fn int dissect_eigrp_ipx_extdata (proto_tree *tree, tvbuff_t *tvb, int offset)
1439 *
1440 * @param[in,out] tree detail dissection result
1441 * @param[in] tvb packet data
1442 * @param[in] offset current byte offset in packet being processed
1443 *
1444 * @return int number of bytes process
1445 *
1446 * @par
1447 * Dissect the IPX External data for the TLV versions 1.2 and 3.0.
1448 * The following represents the format
1449 *
1450 * 0 1 2 3
1451 * 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
1452 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1453 * | Ext RouterID |
1454 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1455 * | Ext Router ID |
1456 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1457 * | Ext Autonomous System Number |
1458 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1459 * | Route Tag |
1460 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1461 * | Ext Protocol | Ext Flags | External Metric |
1462 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1463 * | External Delay |
1464 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1465 */
1466 static int
dissect_eigrp_ipx_extdata(proto_tree * tree,tvbuff_t * tvb,int offset)1467 dissect_eigrp_ipx_extdata (proto_tree *tree, tvbuff_t *tvb, int offset)
1468 {
1469 proto_tree *sub_tree;
1470 tvbuff_t *sub_tvb;
1471 int sub_offset = 0;
1472
1473 sub_tree = proto_tree_add_subtree(tree, tvb, offset, 20, ett_eigrp_tlv_extdata, NULL, "External Data");
1474 sub_tvb = tvb_new_subset_length_caplen(tvb, offset, 20, -1);
1475
1476 /* Decode the external route source info */
1477 proto_tree_add_item(sub_tree, hf_eigrp_ipx_extdata_routerid, sub_tvb,
1478 sub_offset, 6, ENC_NA);
1479 sub_offset += 6;
1480 proto_tree_add_item(sub_tree, hf_eigrp_extdata_as, sub_tvb,
1481 sub_offset, 4, ENC_BIG_ENDIAN);
1482 sub_offset += 4;
1483 proto_tree_add_item(sub_tree, hf_eigrp_extdata_tag, sub_tvb,
1484 sub_offset, 4, ENC_BIG_ENDIAN);
1485 sub_offset += 4;
1486 proto_tree_add_item(sub_tree, hf_eigrp_extdata_proto, sub_tvb,
1487 sub_offset, 1, ENC_BIG_ENDIAN);
1488 sub_offset += 1;
1489
1490 /* Decode the external route flags */
1491 dissect_eigrp_extdata_flags(sub_tree, sub_tvb, sub_offset);
1492 sub_offset += 1;
1493
1494 /* and the rest of it... */
1495 proto_tree_add_item(sub_tree, hf_eigrp_ipx_extdata_metric,
1496 sub_tvb, sub_offset, 2, ENC_BIG_ENDIAN);
1497 sub_offset += 2;
1498 proto_tree_add_item(sub_tree, hf_eigrp_ipx_extdata_delay,
1499 sub_tvb, sub_offset, 2, ENC_BIG_ENDIAN);
1500 sub_offset += 2;
1501
1502 offset += sub_offset;
1503 return(offset);
1504 }
1505
1506 /**
1507 *@fn int dissect_eigrp_extdata (proto_tree *tree, tvbuff_t *tvb, int offset)
1508 *
1509 * @param[in,out] tree detail dissection result
1510 * @param[in] tvb packet data
1511 * @param[in] offset current byte offset in packet being processed
1512 *
1513 * @return int number of bytes process
1514 *
1515 * @par
1516 * Dissect the external route data for TLV versions 1.2 and 3.0 for all
1517 * protocols except IPX. The following represents the format
1518 *
1519 * 0 1 2 3
1520 * 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
1521 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1522 * | Ext Router ID |
1523 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1524 * | Ext Autonomous System Number |
1525 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1526 * | Route Tag |
1527 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1528 * | External Metric |
1529 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1530 * | Reserved | Ext Protocol | Ext Flags |
1531 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1532 */
1533 static int
dissect_eigrp_extdata(proto_tree * tree,tvbuff_t * tvb,int offset)1534 dissect_eigrp_extdata (proto_tree *tree, tvbuff_t *tvb, int offset)
1535 {
1536 proto_tree *sub_tree;
1537 tvbuff_t *sub_tvb;
1538 int sub_offset = 0;
1539
1540 sub_tree = proto_tree_add_subtree(tree, tvb, offset, 20, ett_eigrp_tlv_extdata, NULL, "External Data");
1541 sub_tvb = tvb_new_subset_length_caplen(tvb, offset, 20, -1);
1542
1543 /* Decode the external route source info */
1544 proto_tree_add_item(sub_tree, hf_eigrp_extdata_origrid, sub_tvb,
1545 sub_offset, 4, ENC_BIG_ENDIAN);
1546 sub_offset += 4;
1547 proto_tree_add_item(sub_tree, hf_eigrp_extdata_as, sub_tvb,
1548 sub_offset, 4, ENC_BIG_ENDIAN);
1549 sub_offset += 4;
1550 proto_tree_add_item(sub_tree, hf_eigrp_extdata_tag, sub_tvb,
1551 sub_offset, 4, ENC_BIG_ENDIAN);
1552 sub_offset += 4;
1553 proto_tree_add_item(sub_tree, hf_eigrp_extdata_metric, sub_tvb,
1554 sub_offset, 4, ENC_BIG_ENDIAN);
1555 sub_offset += 4;
1556 proto_tree_add_item(sub_tree, hf_eigrp_extdata_reserved, sub_tvb,
1557 sub_offset, 2, ENC_BIG_ENDIAN);
1558 sub_offset += 2;
1559 proto_tree_add_item(sub_tree, hf_eigrp_extdata_proto, sub_tvb,
1560 sub_offset, 1, ENC_BIG_ENDIAN);
1561 sub_offset += 1;
1562
1563 /* Decode the external route flags */
1564 dissect_eigrp_extdata_flags(sub_tree, sub_tvb, sub_offset);
1565 sub_offset += 1;
1566
1567 offset += sub_offset;
1568 return(offset);
1569 }
1570
1571 /**
1572 *@fn int dissect_eigrp_nexthop (proto_tree *tree, tvbuff_t *tvb, guint16 afi, int offset)
1573 *
1574 * @param[in,out] tree detail dissection result
1575 * @param[in] tvb packet data
1576 * @param[in] afi IANA address family indicator
1577 * @param[in] offset current byte offset in packet being processed
1578 *
1579 * @return int number of bytes process
1580 *
1581 * @par
1582 * Dissect the next hop field which is in the "route TLVs". This function will
1583 * handle all the various protocol AFIs and return the appropriate number of
1584 * bytes processed
1585 */
1586 static int
dissect_eigrp_nexthop(proto_tree * tree,tvbuff_t * tvb,guint16 afi,int offset)1587 dissect_eigrp_nexthop (proto_tree *tree, tvbuff_t *tvb, guint16 afi, int offset)
1588 {
1589 /* dissect dest information */
1590 switch (afi) {
1591 case EIGRP_SF_IPv4:
1592 case EIGRP_AF_IPv4:
1593 proto_tree_add_item(tree, hf_eigrp_ipv4_nexthop, tvb, offset, 4,
1594 ENC_BIG_ENDIAN);
1595 offset += 4;
1596 break;
1597
1598 case EIGRP_SF_IPv6:
1599 case EIGRP_AF_IPv6:
1600 proto_tree_add_item(tree, hf_eigrp_ipv6_nexthop, tvb, offset, 16,
1601 ENC_NA);
1602 offset += 16;
1603 break;
1604
1605 case EIGRP_AF_IPX:
1606 proto_tree_add_item(tree, hf_eigrp_ipx_nexthop_net, tvb, offset, 4,
1607 ENC_NA);
1608 offset += 4;
1609 proto_tree_add_item(tree, hf_eigrp_ipx_nexthop_host, tvb, offset, 6,
1610 ENC_NA);
1611 offset += 6;
1612 break;
1613
1614 case EIGRP_SF_COMMON:
1615 break;
1616
1617 default:
1618 break;
1619 }
1620
1621 return(offset);
1622 }
1623
1624 /**
1625 *@fn void dissect_eigrp_general_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1626 * packet_info *pinfo, guint16 tlv)
1627 *
1628 * @param[in,out] tree detail dissection result
1629 * @param[in] tvb packet data
1630 * @param[in] pinfo general data about the protocol
1631 * @param[in] ti protocol item
1632 * @param[in] tlv Specific TLV in to be dissected
1633 *
1634 * @par
1635 * General EIGRP parameters carry EIGRP management information and are not
1636 * specific to any one routed protocol.
1637 *
1638 */
1639 static void
dissect_eigrp_general_tlv(proto_item * ti,proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,guint16 tlv)1640 dissect_eigrp_general_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1641 packet_info *pinfo, guint16 tlv)
1642 {
1643 switch (tlv) {
1644 case EIGRP_TLV_PARAMETER:
1645 dissect_eigrp_parameter(tree, tvb, pinfo, ti);
1646 break;
1647 case EIGRP_TLV_AUTH:
1648 dissect_eigrp_auth_tlv(tree, tvb, pinfo, ti);
1649 break;
1650 case EIGRP_TLV_SEQ:
1651 dissect_eigrp_seq_tlv(tree, tvb, pinfo, ti);
1652 break;
1653 case EIGRP_TLV_SW_VERSION:
1654 dissect_eigrp_sw_version(tvb, tree, ti);
1655 break;
1656 case EIGRP_TLV_NEXT_MCAST_SEQ:
1657 dissect_eigrp_next_mcast_seq(tvb, tree, ti);
1658 break;
1659 case EIGRP_TLV_PEER_STUBINFO:
1660 dissect_eigrp_peer_stubinfo(tvb, tree);
1661 break;
1662 case EIGRP_TLV_PEER_TERMINATION:
1663 dissect_eigrp_peer_termination(pinfo, ti);
1664 break;
1665 case EIGRP_TLV_PEER_TIDLIST:
1666 dissect_eigrp_peer_tidlist(tree, tvb);
1667 break;
1668 default:
1669 expert_add_info_format(pinfo, ti, &ei_eigrp_tlv_type, "Unknown Generic TLV (0x%04x)", tlv);
1670 break;
1671 }
1672 }
1673
1674 /**
1675 *@fn void dissect_eigrp_ipv4_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1676 * packet_info *pinfo, guint16 tlv)
1677 *
1678 * @param[in,out] tree detail dissection result
1679 * @param[in] tvb packet data
1680 * @param[in] pinfo general data about the protocol
1681 * @param[in] tlv Specific TLV in to be dissected
1682 *
1683 * @par
1684 * Dissect the Legacy IPv4 route TLV; handles both the internal and external
1685 * TLV types; This packet format is being deprecated and replaced with the
1686 * Multi-Protocol packet formats as of EIGRP Release-8. This TLV format is used
1687 * to maintain backward compatibility between older version so EIGRP, "MTR"
1688 * EIGRP, and current shipping code.
1689 *
1690 * 0 1 2 3
1691 * 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
1692 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1693 * | IPv4 Nexthop |
1694 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1695 * | Scaled Delay |
1696 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1697 * | Scaled Bandwidth |
1698 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1699 * | MTU | Hopcount |
1700 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1701 * | Reliability | Load | Internal Tag | Flag |
1702 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1703 */
1704 static void
dissect_eigrp_ipv4_tlv(proto_item * ti,proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,guint16 tlv)1705 dissect_eigrp_ipv4_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1706 packet_info *pinfo, guint16 tlv)
1707 {
1708 int offset = 0;
1709 int unreachable = FALSE;
1710
1711 proto_tree_add_item(tree, hf_eigrp_ipv4_nexthop, tvb, offset, 4,
1712 ENC_BIG_ENDIAN);
1713 offset += 4;
1714
1715 /* dissect external data if needed */
1716 if ((tlv & EIGRP_TLV_TYPEMASK) == EIGRP_TLV_EXTERNAL) {
1717 offset = dissect_eigrp_extdata(tree, tvb, offset);
1718 }
1719
1720 /* dissect the metric */
1721 offset = dissect_eigrp_legacy_metric(tree, tvb, offset);
1722
1723 /* dissect addresses */
1724 dissect_eigrp_ipv4_addrs(ti, tree, tvb, pinfo, offset, unreachable);
1725 }
1726
1727 /**
1728 *@fn void dissect_eigrp_atalk_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1729 * proto_item *ti, guint16 tlv)
1730 *
1731 * @param[in,out] tree detail dissection result
1732 * @param[in] tvb packet data
1733 * @param[in] tlv Specific TLV in to be dissected
1734 *
1735 * @par
1736 * Dissect the legacy AppleTalk route TLV; handles both the internal and external
1737 * TLV type. The following represents the format
1738 */
1739 static void
dissect_eigrp_atalk_tlv(proto_item * ti,proto_tree * tree,tvbuff_t * tvb,guint16 tlv)1740 dissect_eigrp_atalk_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1741 guint16 tlv)
1742 {
1743 int offset = 0;
1744
1745 /* cable tlv? */
1746 if (EIGRP_TLV_AT_CBL == tlv) {
1747 proto_tree_add_item(tree, hf_eigrp_appletalk_cable_range, tvb, 0, 4, ENC_BIG_ENDIAN);
1748 proto_tree_add_item(tree, hf_eigrp_atalk_routerid, tvb, 4, 4,
1749 ENC_BIG_ENDIAN);
1750 proto_item_append_text(ti, ": Cable range= %u-%u, Router ID= %u",
1751 tvb_get_ntohs(tvb, 0), tvb_get_ntohs(tvb, 2),
1752 tvb_get_ntohl(tvb, 4));
1753
1754 } else {
1755 proto_tree_add_item(tree, hf_eigrp_nexthop_address, tvb, offset, 4, ENC_BIG_ENDIAN);
1756 offset += 4;
1757
1758 /* dissect external data if needed */
1759 if ((tlv & EIGRP_TLV_TYPEMASK) == EIGRP_TLV_EXTERNAL) {
1760 offset = dissect_eigrp_extdata(tree, tvb,offset);
1761 }
1762
1763 /* dissect the metric */
1764 offset = dissect_eigrp_legacy_metric(tree, tvb, offset);
1765
1766 /* dissect cable range */
1767 proto_tree_add_item(tree, hf_eigrp_cable_range, tvb, offset, 4, ENC_BIG_ENDIAN);
1768 proto_item_append_text(ti, ": %u-%u",
1769 tvb_get_ntohs(tvb, 36), tvb_get_ntohs(tvb, 38));
1770 }
1771 }
1772
1773 /**
1774 *@fn void dissect_eigrp_ipv6_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1775 * packet_info *pinfo, guint16 tlv)
1776 *
1777 * @param[in,out] tree detail dissection result
1778 * @param[in] tvb packet data
1779 * @param[in] pinfo general data about the protocol
1780 * @param[in] tlv Specific TLV in to be dissected
1781 *
1782 * @par
1783 * Dissect the Legacy IPv6 route TLV; handles both the internal and external
1784 * TLV types; This packet format is being deprecated and replaced with the
1785 * Multi-Protocol packet formats as of EIGRP Release-8. This TLV format is used
1786 * to maintain backward compatibility between older version so EIGRP, "MTR"
1787 * EIGRP, and current shipping code.
1788 */
1789 static void
dissect_eigrp_ipv6_tlv(proto_item * ti,proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,guint16 tlv)1790 dissect_eigrp_ipv6_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1791 packet_info *pinfo, guint16 tlv)
1792 {
1793 int offset = 0;
1794 int unreachable = FALSE;
1795
1796 proto_tree_add_item(tree, hf_eigrp_ipv6_nexthop, tvb, offset, 16,
1797 ENC_NA);
1798 offset += 16;
1799
1800 /* dissect external data if needed */
1801 if ((tlv & EIGRP_TLV_TYPEMASK) == EIGRP_TLV_EXTERNAL) {
1802 offset = dissect_eigrp_extdata(tree, tvb, offset);
1803 }
1804
1805 /* dissect the metric */
1806 offset = dissect_eigrp_legacy_metric(tree, tvb, offset);
1807
1808 /* dissect addresses */
1809 dissect_eigrp_ipv6_addrs(ti, tree, tvb, pinfo, offset, unreachable);
1810 }
1811
1812 /**
1813 *@fn void dissect_eigrp_ipx_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1814 * packet_info *pinfo, guint16 tlv)
1815 *
1816 * @param[in,out] tree detail dissection result
1817 * @param[in] tvb packet data
1818 * @param[in] pinfo general data about the protocol
1819 * @param[in] tlv Specific TLV in to be dissected
1820 *
1821 * @par
1822 * Dissect the legacy IPX route TLV; handles both the internal and external
1823 * TLV type. The following represents the format
1824 *
1825 * 0 1 2 3
1826 * 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
1827 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1828 * | Nexthop Net |
1829 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1830 * | Nexthop Host |
1831 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1832 * | Nexthop Host(cont) |
1833 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1834 *
1835 * Optional External Data:
1836 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1837 * | Ext RouterID |
1838 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1839 * | Ext Router ID |
1840 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1841 * | Ext Autonomous System Number |
1842 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1843 * | Route Tag |
1844 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1845 * | Ext Protocol | Ext Flags | External Metric |
1846 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1847 * | External Delay |
1848 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1849 *
1850 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1851 * | Scaled Delay |
1852 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1853 * | Scaled Delay | Scaled Bandwidth |
1854 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1855 * | Scaled Bandwidth | MTU |
1856 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1857 * | MTU(cont) | Hopcount | Reliability | Load |
1858 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1859 * | Internal Tag | Flag |
1860 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1861 *
1862 *
1863 */
1864 static void
dissect_eigrp_ipx_tlv(proto_item * ti,proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,guint16 tlv)1865 dissect_eigrp_ipx_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1866 packet_info *pinfo, guint16 tlv)
1867 {
1868 int offset = 0;
1869 int unreachable = FALSE;
1870
1871 /* nexthop for route... */
1872 offset = dissect_eigrp_nexthop(tree, tvb, EIGRP_AF_IPX, offset);
1873
1874 /* dissect external data if needed */
1875 if ((tlv & EIGRP_TLV_TYPEMASK) == EIGRP_TLV_EXTERNAL) {
1876 offset = dissect_eigrp_ipx_extdata(tree, tvb, offset);
1877 }
1878
1879 /* dissect the metric */
1880 offset = dissect_eigrp_legacy_metric(tree, tvb, offset);
1881
1882 /* dissect addresses */
1883 dissect_eigrp_ipx_addrs(ti, tree, tvb, pinfo, offset, unreachable);
1884 }
1885
1886 /**
1887 *@fn void dissect_eigrp_multi_topology_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1888 * packet_info *pinfo, proto_item *ti, guint16 tlv)
1889 *
1890 * @param[in,out] tree detail dissection result
1891 * @param[in] tvb packet data
1892 * @param[in] pinfo general data about the protocol
1893 * @param[in] ti protocol item
1894 * @param[in] tlv Specific TLV in to be dissected
1895 *
1896 * @par
1897 * Dissect the Multi-Topology route TLV; This packet format has been deprecated
1898 * and replaced with the Multi-Protocol packet formats as of EIGRP Release-8. Of
1899 * course this means it will be around for a long long while. The following
1900 * represents the format
1901 *
1902 * 1 2 3 0 1 1
1903 * 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
1904 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1905 * | Reserved |
1906 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1907 * | Topology Identifier | Family Identifier |
1908 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1909 * | Router ID |
1910 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1911 * | Route Tag |
1912 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1913 * | Scaled Delay |
1914 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1915 * | Scaled Bandwidth |
1916 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1917 * | MTU | Hopcount |
1918 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1919 * | Reliability | Load | Internal Tag | Flag |
1920 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1921 * |\/\/\/ NextHop (Family Specific Length) \/\/\/|
1922 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1923 * |\/\/\/ External Route Data (Optional) \/\/\/|
1924 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1925 * |\/\/\/ Destination (Family Specific Length) \/\/\/|
1926 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1927 *
1928 */
1929 static void
dissect_eigrp_multi_topology_tlv(proto_item * ti,proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,guint16 tlv)1930 dissect_eigrp_multi_topology_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
1931 packet_info *pinfo, guint16 tlv)
1932 {
1933 guint16 afi;
1934 int offset = 2;
1935 int unreachable = FALSE;
1936
1937 /* tid for you */
1938 proto_tree_add_item(tree, hf_eigrp_tid, tvb, offset, 2, ENC_BIG_ENDIAN);
1939 offset += 2;
1940
1941 /* now it's all about the family */
1942 afi = tvb_get_ntohs(tvb, offset);
1943 proto_tree_add_item(tree, hf_eigrp_afi, tvb, offset, 2, ENC_BIG_ENDIAN);
1944 offset += 2;
1945
1946 /* gota have an id... */
1947 proto_tree_add_item(tree, hf_eigrp_routerid, tvb, offset, 4, ENC_BIG_ENDIAN);
1948 offset += 4;
1949
1950 /* tag.. your it! */
1951 proto_tree_add_item(tree, hf_eigrp_legacy_metric_tag, tvb, offset, 4, ENC_BIG_ENDIAN);
1952 offset += 4;
1953
1954 /* dissect the metric */
1955 offset = dissect_eigrp_legacy_metric(tree, tvb, offset);
1956
1957 /* dissect nexthop */
1958 offset = dissect_eigrp_nexthop(tree, tvb, afi, offset);
1959
1960 /* dissect external data if needed */
1961 if ((tlv & EIGRP_TLV_TYPEMASK) == EIGRP_TLV_EXTERNAL) {
1962 if (afi == EIGRP_AF_IPX) {
1963 offset = dissect_eigrp_ipx_extdata(tree, tvb, offset);
1964 } else {
1965 offset = dissect_eigrp_extdata(tree, tvb, offset);
1966 }
1967 }
1968
1969 /* dissect dest information */
1970 switch (afi) {
1971 case EIGRP_AF_IPv4:
1972 dissect_eigrp_ipv4_addrs(ti, tree, tvb, pinfo, offset, unreachable);
1973 break;
1974 case EIGRP_AF_IPv6:
1975 dissect_eigrp_ipv6_addrs(ti, tree, tvb, pinfo, offset, unreachable);
1976 break;
1977 case EIGRP_AF_IPX:
1978 dissect_eigrp_ipx_addrs(ti, tree, tvb, pinfo, offset, unreachable);
1979 break;
1980
1981 case EIGRP_SF_COMMON:
1982 case EIGRP_SF_IPv4:
1983 case EIGRP_SF_IPv6:
1984 dissect_eigrp_services(ti, tree, tvb, pinfo, offset);
1985 break;
1986
1987 default:
1988 proto_tree_add_expert(tree, pinfo, &ei_eigrp_afi, tvb, offset, -1);
1989 }
1990 }
1991
1992 /**
1993 *@fn int dissect_eigrp_metric_comm (proto_tree *tree, tvbuff_t *tvb, int offset, int limit)
1994 *
1995 * @param[in,out] tree detail dissection result
1996 * @param[in] tvb packet data
1997 * @param[in] offset current byte offset in packet being processed
1998 * @param[in] limit maximum number of bytes which can be process
1999 *
2000 * @return int number of bytes process
2001 *
2002 * @par
2003 * Dissect extended community attached to metric TLVs to support VPNv4
2004 * deployments, The following represents the format
2005 *
2006 * 0 1 2 3
2007 * 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
2008 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2009 * | Type high | Type low(*) | |
2010 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ Value |
2011 * | |
2012 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2013 */
2014 static int
dissect_eigrp_metric_comm(proto_tree * tree,tvbuff_t * tvb,int offset,int limit)2015 dissect_eigrp_metric_comm (proto_tree *tree, tvbuff_t *tvb, int offset, int limit)
2016 {
2017 int comm_type;
2018 proto_item* ti;
2019 proto_tree* type_tree;
2020
2021 while (limit > 0) {
2022 comm_type = tvb_get_ntohs(tvb, offset);
2023 ti = proto_tree_add_uint(tree, hf_eigrp_metric_comm_type, tvb, offset, 2, comm_type);
2024 type_tree = proto_item_add_subtree(ti, ett_metric_comm_type);
2025
2026 offset += 2;
2027
2028 switch (comm_type) {
2029 /*
2030 * Tag for this route. It is present for all EIGRP VPNv4
2031 * routes, internal and external
2032 */
2033 case EIGRP_EXTCOMM_EIGRP:
2034 proto_tree_add_item(type_tree, hf_eigrp_extcomm_eigrp_flag, tvb, offset, 2, ENC_BIG_ENDIAN);
2035 proto_tree_add_item(type_tree, hf_eigrp_extcomm_eigrp_tag, tvb, offset+2, 4, ENC_BIG_ENDIAN);
2036 break;
2037
2038 case EIGRP_EXTCOMM_VRR:
2039 proto_tree_add_item(type_tree, hf_eigrp_extcomm_eigrp_res, tvb, offset, 2, ENC_BIG_ENDIAN);
2040 proto_tree_add_item(type_tree, hf_eigrp_extcomm_eigrp_rid, tvb, offset+2, 4, ENC_BIG_ENDIAN);
2041 break;
2042
2043 /*
2044 * Vecmetric information for given EIGRP VPNv4 route,
2045 * applies to both internal and external
2046 */
2047 case EIGRP_EXTCOMM_DAD:
2048 proto_tree_add_item(type_tree, hf_eigrp_extcomm_eigrp_as, tvb, offset, 2, ENC_BIG_ENDIAN);
2049 proto_tree_add_item(type_tree, hf_eigrp_extcomm_eigrp_sdly, tvb, offset+2, 4, ENC_BIG_ENDIAN);
2050 break;
2051
2052 case EIGRP_EXTCOMM_VRHB:
2053 proto_tree_add_item(type_tree, hf_eigrp_extcomm_eigrp_rel, tvb, offset, 1, ENC_BIG_ENDIAN);
2054 proto_tree_add_item(type_tree, hf_eigrp_extcomm_eigrp_hop, tvb, offset+1, 1, ENC_BIG_ENDIAN);
2055 proto_tree_add_item(type_tree, hf_eigrp_extcomm_eigrp_sbw, tvb, offset+2, 4, ENC_BIG_ENDIAN);
2056 break;
2057
2058 case EIGRP_EXTCOMM_SRLM:
2059 proto_tree_add_item(type_tree, hf_eigrp_extcomm_eigrp_res, tvb, offset, 1, ENC_BIG_ENDIAN);
2060 proto_tree_add_item(type_tree, hf_eigrp_extcomm_eigrp_load, tvb, offset+1, 1, ENC_BIG_ENDIAN);
2061 proto_tree_add_item(type_tree, hf_eigrp_extcomm_eigrp_mtu, tvb, offset+2, 4, ENC_BIG_ENDIAN);
2062 break;
2063
2064 /*
2065 * External information for given EIGRP VPNv4 route,
2066 * applies to only to external routes
2067 */
2068 case EIGRP_EXTCOMM_SAR:
2069 proto_tree_add_item(type_tree, hf_eigrp_extcomm_eigrp_xas, tvb, offset, 2, ENC_BIG_ENDIAN);
2070 proto_tree_add_item(type_tree, hf_eigrp_extcomm_eigrp_xrid, tvb, offset+2, 4, ENC_BIG_ENDIAN);
2071 break;
2072
2073 case EIGRP_EXTCOMM_RPM:
2074 proto_tree_add_item(type_tree, hf_eigrp_extcomm_eigrp_xproto, tvb, offset, 2, ENC_BIG_ENDIAN);
2075 proto_tree_add_item(type_tree, hf_eigrp_extcomm_eigrp_xmetric, tvb, offset+2, 4, ENC_BIG_ENDIAN);
2076 break;
2077
2078 case EIGRP_EXTCOMM_SOO_ASFMT:
2079 case EIGRP_EXTCOMM_SOO_ADRFMT:
2080 proto_tree_add_item(type_tree, hf_eigrp_extcomm_eigrp_as, tvb, offset, 2, ENC_BIG_ENDIAN);
2081 proto_tree_add_item(type_tree, hf_eigrp_extcomm_eigrp_tag, tvb, offset+2, 4, ENC_BIG_ENDIAN);
2082 break;
2083 }
2084
2085 proto_item_set_len(ti, 8);
2086
2087 /*on to the next */
2088 offset += 6;
2089 limit -= 8;
2090
2091 if (0 != limit%8) {
2092 break;
2093 }
2094
2095 }
2096
2097 return(offset);
2098 }
2099
2100 /**
2101 *@fn int dissect_eigrp_wide_metric_attr (proto_tree *tree, tvbuff_t *tvb,
2102 * int offset, int limit)
2103 *
2104 * @param[in,out] tree detail dissection result
2105 * @param[in] tvb packet data
2106 * @param[in] offset current byte offset in packet being processed
2107 * @param[in] limit maximum number of words which should be process
2108 *
2109 * @return int number of bytes process
2110 *
2111 * @par
2112 * Dissect the Metric Attributes which (optionally) are part of the wide-metric
2113 * route TLV. Some of the attributes which effect the metric are controlled by
2114 * K6 which is now part of the Parameter TLV. Also, eh extended community TLV is
2115 * no longer used, as it's now appended to the route
2116 */
2117 static int
dissect_eigrp_wide_metric_attr(proto_tree * tree,tvbuff_t * tvb,int offset,int limit)2118 dissect_eigrp_wide_metric_attr (proto_tree *tree, tvbuff_t *tvb,
2119 int offset, int limit)
2120 {
2121 proto_tree *sub_tree;
2122 tvbuff_t *sub_tvb;
2123 int sub_offset;
2124
2125 guint16 attr_offset = 0;
2126 guint8 attr_opcode = 0;
2127
2128 limit *= 2; /* words to bytes */
2129
2130 sub_tree = proto_tree_add_subtree(tree, tvb, offset, limit, ett_eigrp_tlv_attr, NULL, "Attributes");
2131 sub_tvb = tvb_new_subset_length_caplen(tvb, offset, limit, -1);
2132 sub_offset = 0;
2133
2134 while (limit > 0) {
2135 attr_opcode = tvb_get_guint8(sub_tvb, sub_offset);
2136 proto_tree_add_item(sub_tree, hf_eigrp_attr_opcode, sub_tvb,
2137 sub_offset, 1, ENC_BIG_ENDIAN);
2138 sub_offset += 1;
2139
2140 attr_offset = tvb_get_guint8(sub_tvb, sub_offset) * 2;
2141 proto_tree_add_item(sub_tree, hf_eigrp_attr_offset, sub_tvb,
2142 sub_offset, 1, ENC_BIG_ENDIAN);
2143 sub_offset += 1;
2144
2145 switch (attr_opcode) {
2146 case EIGRP_ATTR_NOOP:
2147 break;
2148
2149 case EIGRP_ATTR_SCALED:
2150 proto_tree_add_item(sub_tree, hf_eigrp_attr_scaled, sub_tvb,
2151 sub_offset, 4, ENC_BIG_ENDIAN);
2152 break;
2153
2154 case EIGRP_ATTR_TAG:
2155 proto_tree_add_item(sub_tree, hf_eigrp_attr_tag, sub_tvb,
2156 sub_offset, 4, ENC_BIG_ENDIAN);
2157 break;
2158
2159 case EIGRP_ATTR_COMM:
2160 dissect_eigrp_metric_comm(sub_tree,
2161 tvb_new_subset_length_caplen(sub_tvb, sub_offset, 8, -1),
2162 sub_offset, limit);
2163 break;
2164
2165 case EIGRP_ATTR_JITTER:
2166 proto_tree_add_item(sub_tree, hf_eigrp_attr_jitter, sub_tvb,
2167 sub_offset, 4, ENC_BIG_ENDIAN);
2168 break;
2169
2170 case EIGRP_ATTR_QENERGY:
2171 proto_tree_add_item(sub_tree, hf_eigrp_attr_qenergy, sub_tvb,
2172 sub_offset, 4, ENC_BIG_ENDIAN);
2173 break;
2174
2175 case EIGRP_ATTR_ENERGY:
2176 proto_tree_add_item(sub_tree, hf_eigrp_attr_energy, sub_tvb,
2177 sub_offset, 4, ENC_BIG_ENDIAN);
2178 break;
2179
2180 default:
2181 break;
2182 }
2183 sub_offset += attr_offset;
2184 limit -= (EIGRP_ATTR_HDRLEN + attr_offset);
2185 }
2186
2187 offset += sub_offset;
2188 return(offset);
2189 }
2190
2191 /**
2192 *@fn int dissect_eigrp_wide_metric (proto_tree *tree, tvbuff_t *tvb, int offset)
2193 *
2194 * @param[in,out] tree detail dissection result
2195 * @param[in] tvb packet data
2196 * @param[in] offset current byte offset in packet being processed
2197 *
2198 * @return int number of bytes process
2199 *
2200 * @par
2201 * Dissect the latest-n-greatest "Wide"Metric" definition for EIGRP. This
2202 * definition was created to address the higher speed links and should handle
2203 * things until we break the speed of light *wink*
2204 *
2205 * 0 1 2 3
2206 * 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
2207 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2208 * | Offset | Priority | Reliability | Load |
2209 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2210 * | MTU | Hopcount |
2211 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2212 * | Delay |
2213 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2214 * | Delay | Bandwidth |
2215 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2216 * | Bandwidth |
2217 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2218 * | Reserved | Flags |
2219 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2220 * |\/\/\/ Extended Metrics (Variable Length) \/\/\/|
2221 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2222 *
2223 */
2224 static int
dissect_eigrp_wide_metric(proto_tree * tree,tvbuff_t * tvb,int offset)2225 dissect_eigrp_wide_metric (proto_tree *tree, tvbuff_t *tvb, int offset)
2226 {
2227 proto_tree *sub_tree;
2228 tvbuff_t *sub_tvb;
2229 gint8 attr_size = 0;
2230 guint64 big_num;
2231
2232 sub_tree = proto_tree_add_subtree(tree, tvb, offset, 24, ett_eigrp_tlv_metric, NULL, "Wide Metric");
2233 sub_tvb = tvb_new_subset_length_caplen(tvb, offset, 24, -1);
2234
2235 attr_size = tvb_get_guint8(sub_tvb, 0);
2236
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);
2249
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);
2255 big_num >>= 16;
2256 if (big_num == G_GUINT64_CONSTANT(0x0000ffffffffffff)) {
2257 proto_tree_add_uint64_format_value(sub_tree, hf_eigrp_metric_delay, sub_tvb, 8, 6, big_num, "Infinity");
2258 } else {
2259 proto_tree_add_uint64(sub_tree, hf_eigrp_metric_delay, sub_tvb, 8, 6, big_num);
2260 }
2261
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
2265 * route.
2266 */
2267 big_num = tvb_get_ntoh64(sub_tvb, 14);
2268 big_num >>= 16;
2269 if (big_num == G_GUINT64_CONSTANT(0x0000ffffffffffff)) {
2270 proto_tree_add_uint64_format_value(sub_tree, hf_eigrp_metric_bandwidth, sub_tvb, 14, 6, big_num, "Infinity");
2271 } else {
2272 proto_tree_add_uint64(sub_tree, hf_eigrp_metric_bandwidth, sub_tvb, 14, 6, big_num);
2273 }
2274 proto_tree_add_item(sub_tree, hf_eigrp_metric_reserved, sub_tvb, 20, 2,
2275 ENC_BIG_ENDIAN);
2276
2277 /* Decode the route flags field */
2278 dissect_eigrp_metric_flags(sub_tree, sub_tvb, 22, 2);
2279 offset += 24;
2280
2281 /* any extended metric attributes? */
2282 if (attr_size > 0) {
2283 offset = dissect_eigrp_wide_metric_attr(tree, tvb, offset, attr_size);
2284 }
2285
2286 return(offset);
2287 }
2288
2289 /**
2290 *@fn void dissect_eigrp_multi_protocol_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
2291 * packet_info *pinfo, guint16 tlv)
2292
2293 *
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
2298 *
2299 * @par
2300 * Dissect the Multi-Protocol (TLV Version 2.0) TLV format definition. The following
2301 * represents the format
2302 *
2303 * 0 1 2 3
2304 * 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
2305 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2306 * | Topology Identifier | Family Identifier |
2307 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2308 * | Router ID |
2309 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2310 * | Wide Metric |
2311 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2312 * |\/\/\/ Extended Metrics (Variable Length) \/\/\/|
2313 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2314 * |\/\/\/ NextHop (Family Specific Length) \/\/\/|
2315 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2316 * |\/\/\/ External Route Data (Optional) \/\/\/|
2317 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2318 * |\/\/\/ Destination (Family Specific Length) \/\/\/|
2319 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2320 */
2321 static void
dissect_eigrp_multi_protocol_tlv(proto_item * ti,proto_tree * tree,tvbuff_t * tvb,packet_info * pinfo,guint16 tlv)2322 dissect_eigrp_multi_protocol_tlv (proto_item *ti, proto_tree *tree, tvbuff_t *tvb,
2323 packet_info *pinfo, guint16 tlv)
2324 {
2325 int offset = 0;
2326 guint16 afi;
2327 int unreachable = FALSE;
2328
2329 /* tid for you */
2330 proto_tree_add_item(tree, hf_eigrp_tid, tvb, offset, 2, ENC_BIG_ENDIAN);
2331 offset += 2;
2332
2333 /* now it's all about the family */
2334 afi = tvb_get_ntohs(tvb, offset);
2335 proto_tree_add_item(tree, hf_eigrp_afi, tvb, offset, 2, ENC_BIG_ENDIAN);
2336 offset += 2;
2337
2338 /* gota have an id... */
2339 proto_tree_add_item(tree, hf_eigrp_routerid, tvb, offset, 4, ENC_BIG_ENDIAN);
2340 offset += 4;
2341
2342 /* decode the wide metric */
2343 offset = dissect_eigrp_wide_metric(tree, tvb, offset);
2344
2345 /* dissect nexthop */
2346 offset = dissect_eigrp_nexthop(tree, tvb, afi, offset);
2347
2348 /* dissect external data if needed */
2349 if ((tlv & EIGRP_TLV_TYPEMASK) == EIGRP_TLV_EXTERNAL) {
2350 if (afi == EIGRP_AF_IPX) {
2351 offset = dissect_eigrp_ipx_extdata(tree, tvb, offset);
2352 } else {
2353 offset = dissect_eigrp_extdata(tree, tvb, offset);
2354 }
2355 }
2356
2357 /* dissect dest information */
2358 switch (afi) {
2359 case EIGRP_AF_IPv4:
2360 dissect_eigrp_ipv4_addrs(ti, tree, tvb, pinfo, offset, unreachable);
2361 break;
2362
2363 case EIGRP_AF_IPv6:
2364 dissect_eigrp_ipv6_addrs(ti, tree, tvb, pinfo, offset, unreachable);
2365 break;
2366
2367 case EIGRP_AF_IPX:
2368 dissect_eigrp_ipx_addrs(ti, tree, tvb, pinfo, offset, unreachable);
2369 break;
2370
2371 case EIGRP_SF_COMMON:
2372 case EIGRP_SF_IPv4:
2373 case EIGRP_SF_IPv6:
2374 dissect_eigrp_services(ti, tree, tvb, pinfo, offset);
2375 break;
2376
2377 default:
2378 proto_tree_add_expert(tree, pinfo, &ei_eigrp_afi, tvb, offset, -1);
2379 }
2380 }
2381
2382 /**
2383 *@fn int dissect_eigrp (proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, void *data)
2384 *
2385 * @param[in] tvb packet data
2386 * @param[in] pinfo general data about the protocol
2387 * @param[in,out] tree detail dissection result
2388 *
2389 * @return int 0 if packet is not for this decoder
2390 *
2391 * @par
2392 * This function is called to dissect the packets presented to it. The packet
2393 * data is held in a special buffer referenced here as tvb. The packet info
2394 * structure contains general data about the protocol, and can update
2395 * information here. The tree parameter is where the detail dissection takes
2396 * place.
2397 */
2398 #include <epan/in_cksum.h>
2399
2400 static int
dissect_eigrp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)2401 dissect_eigrp (tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2402 {
2403 proto_item *ti;
2404 proto_tree *eigrp_tree, *tlv_tree;
2405 guint opcode, vrid;
2406 guint16 tlv;
2407 guint32 ack, size, offset = EIGRP_HEADER_LENGTH;
2408
2409 /* Make entries in Protocol column and Info column on summary display */
2410 col_set_str(pinfo->cinfo, COL_PROTOCOL, "EIGRP");
2411
2412 /* This field shows up as the "Info" column in the display; you should use
2413 * it, if possible, to summarize what's in the packet, so that a user
2414 * looking at the list of packets can tell what type of packet it is. See
2415 * section 1.5 for more information.
2416 */
2417 col_clear(pinfo->cinfo, COL_INFO);
2418
2419 opcode = tvb_get_guint8(tvb, 1);
2420 ack = tvb_get_ntohl(tvb, 12);
2421 if ((opcode == EIGRP_OPC_HELLO) && (0 != ack)) {
2422 opcode = EIGRP_OPC_ACK;
2423 }
2424
2425 col_add_str(pinfo->cinfo, COL_INFO,
2426 val_to_str(opcode, eigrp_opcode2string, "Unknown OpCode (0x%04x)"));
2427
2428 /* A protocol dissector may be called in 2 different ways - with, or
2429 * without a non-null "tree" argument.
2430 * Note also that there is no guarantee, the first time the dissector is
2431 * called, whether "tree" will be null or not; your dissector must work
2432 * correctly, building or updating whatever state information is necessary,
2433 * in either case.
2434 */
2435 /* NOTE: The offset and length values in the call to
2436 * "proto_tree_add_item()" define what data bytes to highlight in the
2437 * hex display window when the line in the protocol tree display
2438 * corresponding to that item is selected.
2439 */
2440
2441 /* create display subtree for the protocol */
2442 ti = proto_tree_add_protocol_format(tree, proto_eigrp, tvb, 0, -1,
2443 "Cisco EIGRP");
2444 eigrp_tree = proto_item_add_subtree(ti, ett_eigrp);
2445 proto_tree_add_item(eigrp_tree, hf_eigrp_version, tvb, 0, 1,
2446 ENC_BIG_ENDIAN);
2447 proto_tree_add_item(eigrp_tree, hf_eigrp_opcode, tvb, 1, 1,
2448 ENC_BIG_ENDIAN);
2449
2450 size = tvb_captured_length(tvb);
2451 proto_tree_add_checksum(eigrp_tree, tvb, 2, hf_eigrp_checksum, hf_eigrp_checksum_status, &ei_eigrp_checksum_bad,
2452 pinfo, ip_checksum_tvb(tvb, 0, size), ENC_BIG_ENDIAN, PROTO_CHECKSUM_VERIFY|PROTO_CHECKSUM_IN_CKSUM);
2453
2454 /* Decode the EIGRP Flags Field */
2455 proto_tree_add_bitmask(eigrp_tree, tvb, 4, hf_eigrp_flags, ett_eigrp_flags,
2456 eigrp_flag_fields, ENC_BIG_ENDIAN);
2457
2458 proto_tree_add_item(eigrp_tree, hf_eigrp_sequence, tvb, 8, 4,
2459 ENC_BIG_ENDIAN);
2460 proto_tree_add_item(eigrp_tree, hf_eigrp_acknowledge, tvb, 12, 4,
2461 ENC_BIG_ENDIAN);
2462
2463 /* print out what family we dealing with... */
2464 ti = proto_tree_add_item(eigrp_tree, hf_eigrp_vrid, tvb, 16, 2,
2465 ENC_BIG_ENDIAN);
2466 vrid = (tvb_get_ntohs(tvb, 16) & EIGRP_VRID_MASK);
2467 proto_item_append_text(ti, " %s", val_to_str_const(vrid, eigrp_vrid2string, ""));
2468
2469 /* print autonomous-system */
2470 proto_tree_add_item(eigrp_tree, hf_eigrp_as, tvb, 18, 2,
2471 ENC_BIG_ENDIAN);
2472
2473 switch (opcode) {
2474 case EIGRP_OPC_IPXSAP:
2475 call_dissector(ipxsap_handle,
2476 tvb_new_subset_remaining(tvb, EIGRP_HEADER_LENGTH), pinfo,
2477 eigrp_tree);
2478 break;
2479
2480 default:
2481 while (tvb_reported_length_remaining(tvb, offset) > 0) {
2482 tlv = tvb_get_ntohs(tvb, offset);
2483
2484 /* it's a rose by the wrong name... */
2485 if (tlv == EIGRP_TLV_MTR_TIDLIST) {
2486 tlv = EIGRP_TLV_PEER_TIDLIST;
2487 }
2488
2489 size = tvb_get_ntohs(tvb, offset + 2);
2490 if (size < 4) {
2491 /*
2492 * As the draft says, in section 6.6.2 "Length Field Encoding",
2493 * "The value does includes[sic] the Type and Length fields".
2494 *
2495 * Therefore, it must be at least 4.
2496 */
2497 proto_tree_add_expert(eigrp_tree, pinfo, &ei_eigrp_tlv_len, tvb, offset, -1);
2498 return(tvb_captured_length(tvb));
2499 }
2500
2501 tlv_tree = proto_tree_add_subtree(eigrp_tree, tvb, offset, size, ett_eigrp_tlv, &ti,
2502 val_to_str(tlv, eigrp_tlv2string, "Unknown TLV (0x%04x)"));
2503
2504 proto_tree_add_item(tlv_tree, hf_eigrp_tlv_type, tvb,
2505 offset, 2, ENC_BIG_ENDIAN);
2506 proto_tree_add_item(tlv_tree, hf_eigrp_tlv_len, tvb,
2507 (offset + 2), 2, ENC_BIG_ENDIAN);
2508
2509 switch (tlv & EIGRP_TLV_RANGEMASK) {
2510 case EIGRP_TLV_GENERAL:
2511 dissect_eigrp_general_tlv(ti, tlv_tree, tvb_new_subset_length(tvb, (offset + 4), (size - 4)), pinfo, tlv);
2512 break;
2513
2514 case EIGRP_TLV_IPv4:
2515 dissect_eigrp_ipv4_tlv(ti, tlv_tree, tvb_new_subset_length(tvb, (offset + 4), (size - 4)), pinfo, tlv);
2516 break;
2517
2518 case EIGRP_TLV_ATALK:
2519 dissect_eigrp_atalk_tlv(ti, tlv_tree, tvb_new_subset_length(tvb, (offset + 4), (size - 4)), tlv);
2520 break;
2521
2522 case EIGRP_TLV_IPX:
2523 dissect_eigrp_ipx_tlv(ti, tlv_tree, tvb_new_subset_length(tvb, (offset + 4), (size - 4)), pinfo, tlv);
2524 break;
2525
2526 case EIGRP_TLV_IPv6:
2527 dissect_eigrp_ipv6_tlv(ti, tlv_tree, tvb_new_subset_length(tvb, (offset + 4), (size - 4)), pinfo, tlv);
2528 break;
2529
2530 case EIGRP_TLV_MP:
2531 dissect_eigrp_multi_protocol_tlv(ti, tlv_tree, tvb_new_subset_length(tvb, (offset + 4), (size - 4)),
2532 pinfo, tlv);
2533 break;
2534
2535 case EIGRP_TLV_MTR:
2536 dissect_eigrp_multi_topology_tlv(ti, tlv_tree, tvb_new_subset_length(tvb, (offset + 4), (size - 4)),
2537 pinfo, tlv);
2538 break;
2539
2540 default:
2541 expert_add_info_format(pinfo, ti, &ei_eigrp_tlv_type, "Unknown TLV Group (0x%04x)", tlv);
2542 }
2543
2544 offset += size;
2545 }
2546 break;
2547 }
2548
2549 /* Return the amount of data this dissector was able to dissect */
2550 return(tvb_captured_length(tvb));
2551 }
2552
2553 static void
eigrp_fmt_cable_range(gchar * result,guint32 revision)2554 eigrp_fmt_cable_range(gchar *result, guint32 revision )
2555 {
2556 g_snprintf( result, ITEM_LABEL_LENGTH, "%u-%u", (guint16)(( revision & 0xFFFF0000 ) >> 16), (guint16)(revision & 0xFFFF) );
2557 }
2558
2559 static void
eigrp_fmt_nexthop_address(gchar * result,guint32 revision)2560 eigrp_fmt_nexthop_address(gchar *result, guint32 revision )
2561 {
2562 g_snprintf( result, ITEM_LABEL_LENGTH, "%u.%u", (guint16)(( revision & 0xFFFF0000 ) >> 16), (guint16)(revision & 0xFFFF) );
2563 }
2564
2565 static void
eigrp_fmt_version(gchar * result,guint32 revision)2566 eigrp_fmt_version(gchar *result, guint32 revision )
2567 {
2568 g_snprintf( result, ITEM_LABEL_LENGTH, "%d.%02d", (guint8)(( revision & 0xFF00 ) >> 8), (guint8)(revision & 0xFF) );
2569 }
2570
2571 /**
2572 *@fn void proto_register_eigrp (void)
2573 *
2574 * @usage
2575 * you can not have the function name inside a comment or else Wireshark
2576 * will fail with "duplicate protocol" error. Don't you hate it when tools
2577 * try to be to smart :(
2578 *
2579 * @par
2580 * Register the protocol with Wireshark
2581 * this format is require because a script is used to build the C function
2582 * that calls all the protocol registration.
2583 */
2584 void
proto_register_eigrp(void)2585 proto_register_eigrp(void)
2586 {
2587 /* Setup list of header fields See Section 1.6.1 for details
2588 */
2589 static hf_register_info hf[] = {
2590 /*
2591 *
2592 * EIGRP Packet Header definitions
2593 *
2594 * 0 1 2 3
2595 * 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
2596 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2597 * |Ver | Opcode | Checksum |
2598 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2599 * | Flags |
2600 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2601 * | Sequence number |
2602 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2603 * | Acknowledgement number |
2604 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2605 * | Virtual Router ID | Autonomous system number |
2606 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
2607 */
2608 { &hf_eigrp_version,
2609 { "Version", "eigrp.version",
2610 FT_UINT8, BASE_DEC, NULL, 0x0,
2611 "Version - Version of EIGRP packet format", HFILL }
2612 },
2613 { &hf_eigrp_opcode,
2614 { "Opcode", "eigrp.opcode",
2615 FT_UINT8, BASE_DEC, VALS(eigrp_opcode2string), 0x0,
2616 "Opcode - Operation code indicating the message type", HFILL }
2617 },
2618 { &hf_eigrp_flags,
2619 { "Flags", "eigrp.flags",
2620 FT_UINT32, BASE_HEX, NULL, 0x0,
2621 "Flag - Initialization bit and is used in establishing "
2622 "a new neighbor relationship", HFILL }
2623 },
2624 { &hf_eigrp_sequence,
2625 { "Sequence", "eigrp.seq",
2626 FT_UINT32, BASE_DEC, NULL, 0x0,
2627 "Sequence number -- used to send messages reliably", HFILL }
2628 },
2629 { &hf_eigrp_acknowledge,
2630 { "Acknowledge", "eigrp.ack",
2631 FT_UINT32, BASE_DEC, NULL, 0x0,
2632 "Acknowledge number -- used to send messages reliably", HFILL }
2633 },
2634 { &hf_eigrp_vrid,
2635 { "Virtual Router ID", "eigrp.vrid",
2636 FT_UINT16, BASE_DEC, NULL, 0,
2637 "Virtual Router ID - For each Virtual Router, there is a separate topology "
2638 "table and routing/service table; even for matching AS. "
2639 "This field allows the gateway to select which set router to use.", HFILL }
2640 },
2641 { &hf_eigrp_as,
2642 { "Autonomous System", "eigrp.as",
2643 FT_UINT16, BASE_DEC, NULL, 0x0,
2644 "Autonomous system number - Each AS has a separate topology table "
2645 "which for a give routing/service table. A gateway can participate "
2646 "in more than one AS. This field allows the gateway to"
2647 "select which set of topology tables to use.", HFILL }
2648 },
2649
2650 /*
2651 * Define eigrp_flags bits here
2652 *
2653 * Init bit definition. First unicast transmitted Update has this
2654 * bit set in the flags field of the fixed header. It tells the neighbor
2655 * to send its full topology table.
2656 */
2657 { &hf_eigrp_flags_init,
2658 { "Init", "eigrp.flags.init",
2659 FT_BOOLEAN, 32, TFS(&tfs_set_notset), EIGRP_INIT_FLAG,
2660 "Init - tells the neighbor to send its full topology table", HFILL }
2661 },
2662
2663 /*
2664 * Conditionally Received - Any packet with the CR-bit set can
2665 * be accepted by an EIGRP speaker if and only if a previous Hello was
2666 * received with the SEQUENCE_TYPE TLV present.
2667 * This allows multicasts to be transmitted in order and reliably at the
2668 * same time as unicasts are transmitted.
2669 */
2670 { &hf_eigrp_flags_condrecv,
2671 { "Conditional Receive", "eigrp.flags.condrecv",
2672 FT_BOOLEAN, 32, TFS(&tfs_set_notset), EIGRP_CR_FLAG,
2673 "Conditionally Received the next packet if address was in listed "
2674 "in the previous HELLO", HFILL }
2675 },
2676
2677 /*
2678 * Restart flag is set in the hello and the init update
2679 * packets during the nsf signaling period. A nsf-aware
2680 * router looks at the RS flag to detect if a peer is restarting
2681 * and maintain the adjacency. A restarting router looks at
2682 * this flag to determine if the peer is helping out with the restart.
2683 */
2684 { &hf_eigrp_flags_restart,
2685 { "Restart", "eigrp.flags.restart",
2686 FT_BOOLEAN, 32, TFS(&tfs_set_notset), EIGRP_RS_FLAG,
2687 "Restart flag - Set in the HELLO and the initial "
2688 "UPDATE packets during the nsf signaling period.", HFILL },
2689 },
2690
2691 /*
2692 * EOT bit. The End-of-Table flag marks the end of the start-up updates
2693 * sent to a new peer. A nsf restarting router looks at this flag to
2694 * determine if it has finished receiving the start-up updates from all
2695 * peers. A nsf-aware router waits for this flag before cleaning up
2696 * the stale routes from the restarting peer.
2697 */
2698 { &hf_eigrp_flags_eot,
2699 { "End Of Table", "eigrp.flags.eot",
2700 FT_BOOLEAN, 32, TFS(&tfs_set_notset), EIGRP_EOT_FLAG,
2701 "End-of-Table - Marks the end of the start-up UPDATES indicating the "
2702 "complete topology database has been sent to a new peer", HFILL }
2703 },
2704
2705 /**
2706 * TLV type definitions. Generic (protocol-independent) TLV types are
2707 * defined here. Protocol-specific ones are defined later
2708 *
2709 * +-----+------------------+
2710 * | | | |
2711 * | Type| Len | Vector |
2712 * | | | |
2713 * +-----+------------------+
2714 *
2715 * TLV type definitions. Generic (protocol-independent) TLV types are
2716 * defined here. Protocol-specific ones are defined elsewhere.
2717 *
2718 * EIGRP_PARAMETER 0x0001 parameter
2719 * EIGRP_AUTH 0x0002 authentication
2720 * EIGRP_SEQUENCE 0x0003 sequenced packet
2721 * EIGRP_SW_VERSION 0x0004 software version
2722 * EIGRP_NEXT_MCAST_SEQ 0x0005 multicast sequence
2723 * EIGRP_PEER_STUBINFO 0x0006 stub information
2724 * EIGRP_PEER_TERMINATION 0x0007 peer termination
2725 */
2726 { &hf_eigrp_tlv_type,
2727 { "Type", "eigrp.tlv_type",
2728 FT_UINT16, BASE_HEX, VALS(eigrp_tlv2string), 0x0,
2729 "TLV Type", HFILL }
2730 },
2731 { &hf_eigrp_tlv_len,
2732 { "Length", "eigrp.tlv.len",
2733 FT_UINT16, BASE_DEC, NULL, 0x0,
2734 "TLV Length", HFILL }
2735 },
2736
2737 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2738 * Parameters TLV
2739 */
2740 { &hf_eigrp_par_k1, { "K1", "eigrp.par.k1", FT_UINT8, BASE_DEC, NULL, 0x0,
2741 "Bandwidth/Throughput Coefficient", HFILL }},
2742 { &hf_eigrp_par_k2, { "K2", "eigrp.par.k2", FT_UINT8, BASE_DEC, NULL, 0x0,
2743 "Load Coefficient", HFILL }},
2744 { &hf_eigrp_par_k3, { "K3", "eigrp.par.k3", FT_UINT8, BASE_DEC, NULL, 0x0,
2745 "Delay/Latency Coefficient", HFILL }},
2746 { &hf_eigrp_par_k4, { "K4", "eigrp.par.k4", FT_UINT8, BASE_DEC, NULL, 0x0,
2747 "Reliability Coefficient", HFILL }},
2748 { &hf_eigrp_par_k5, { "K5", "eigrp.par.k5", FT_UINT8, BASE_DEC, NULL, 0x0,
2749 "Reliability Coefficient", HFILL }},
2750 { &hf_eigrp_par_k6, { "K6", "eigrp.par.k6", FT_UINT8, BASE_DEC, NULL, 0x0,
2751 "Extended Metric Coefficient", HFILL }},
2752 { &hf_eigrp_par_holdtime,
2753 { "Hold Time", "eigrp.par.holdtime", FT_UINT16, BASE_DEC, NULL, 0x0,
2754 "How long to ignore lost HELLO's", HFILL }
2755 },
2756
2757 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2758 * Authentication TLV
2759 */
2760 { &hf_eigrp_auth_type,
2761 { "Type", "eigrp.auth.type",
2762 FT_UINT16, BASE_DEC, VALS(eigrp_auth2string), 0x0,
2763 NULL, HFILL }
2764 },
2765 { &hf_eigrp_auth_len,
2766 { "Length", "eigrp.auth.length",
2767 FT_UINT16, BASE_DEC, NULL, 0x0,
2768 NULL, HFILL }
2769 },
2770 { &hf_eigrp_auth_keyid,
2771 { "Key ID", "eigrp.auth.keyid",
2772 FT_UINT32, BASE_DEC, NULL, 0x0,
2773 NULL, HFILL }
2774 },
2775 { &hf_eigrp_auth_keyseq,
2776 { "Key Sequence", "eigrp.auth.keyseq",
2777 FT_UINT32, BASE_DEC, NULL, 0x0,
2778 NULL, HFILL }
2779 },
2780 { &hf_eigrp_auth_digest,
2781 { "Digest", "eigrp.auth.digest",
2782 FT_BYTES, BASE_NONE, NULL, 0x0,
2783 NULL, HFILL }
2784 },
2785
2786 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2787 * Sequence TLV
2788 */
2789 { &hf_eigrp_seq_addrlen,
2790 { "Address length", "eigrp.seq.addrlen",
2791 FT_UINT8, BASE_DEC, NULL, 0x0,
2792 NULL, HFILL }
2793 },
2794 { &hf_eigrp_seq_ipv4addr,
2795 { "IP Address", "eigrp.seq.ipv4addr",
2796 FT_IPv4, BASE_NONE, NULL, 0x0,
2797 NULL, HFILL }
2798 },
2799 { &hf_eigrp_seq_ipv6addr,
2800 { "IPv6 Address", "eigrp.seq.ipv6addr",
2801 FT_IPv6, BASE_NONE, NULL, 0x0,
2802 NULL, HFILL }
2803 },
2804
2805 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2806 * Next Multicast Sequence
2807 */
2808 /*
2809 * This was added to the hello containing the sequence TLV so that the
2810 * hello packet could be more tightly bound to the multicast packet bearing
2811 * the CR bit that follows it. The sequence number of the impending multicast
2812 * is carried herein.
2813 */
2814 { &hf_eigrp_next_mcast_seq,
2815 { "Multicast Sequence", "eigrp.next_mcast_seq",
2816 FT_UINT32, BASE_DEC, NULL, 0x0,
2817 NULL, HFILL }
2818 },
2819
2820 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2821 * Peer Stub Information TLV
2822 */
2823 { &hf_eigrp_stub_flags,
2824 { "Stub Options", "eigrp.stub_options",
2825 FT_UINT16, BASE_HEX, NULL, 0x0,
2826 NULL, HFILL }
2827 },
2828
2829 /*
2830 * Define eigrp_stub_flags bits here
2831 */
2832 { &hf_eigrp_stub_flags_connected,
2833 { "Connected", "eigrp.stub_options.connected",
2834 FT_BOOLEAN, 16, TFS(&tfs_set_notset), EIGRP_PEER_ALLOWS_CONNECTED,
2835 NULL, HFILL }
2836 },
2837 { &hf_eigrp_stub_flags_static,
2838 { "Static", "eigrp.stub_options.static",
2839 FT_BOOLEAN, 16, TFS(&tfs_set_notset), EIGRP_PEER_ALLOWS_STATIC,
2840 NULL, HFILL }
2841 },
2842 { &hf_eigrp_stub_flags_summary,
2843 { "Summary", "eigrp.stub_options.summary",
2844 FT_BOOLEAN, 16, TFS(&tfs_set_notset), EIGRP_PEER_ALLOWS_SUMMARY,
2845 NULL, HFILL }
2846 },
2847 { &hf_eigrp_stub_flags_redist,
2848 { "Redistributed", "eigrp.stub_options.redist",
2849 FT_BOOLEAN, 16, TFS(&tfs_set_notset), EIGRP_PEER_ALLOWS_REDIST,
2850 NULL, HFILL }
2851 },
2852 { &hf_eigrp_stub_flags_leakmap,
2853 { "Leak-Map", "eigrp.stub_options.leakmap",
2854 FT_BOOLEAN, 16, TFS(&tfs_set_notset), EIGRP_PEER_ALLOWS_LEAKING,
2855 NULL, HFILL }
2856 },
2857 { &hf_eigrp_stub_flags_recvonly,
2858 { "Receive-Only", "eigrp.stub_options.recvonly",
2859 FT_BOOLEAN, 16, TFS(&tfs_set_notset), EIGRP_PEER_ALLOWS_RCVONLY,
2860 NULL, HFILL }
2861 },
2862
2863 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2864 * Peer Termination TLV
2865 */
2866 /* Place holder - this TLV has no options */
2867
2868 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2869 * EIGRP 3.0 Vector Header (deprecated)
2870 */
2871 /*
2872 * common header for all version 3 tlvs
2873 */
2874 { &hf_eigrp_tid,
2875 { "Topology", "eigrp.tid",
2876 FT_UINT16, BASE_DEC, NULL, 0x0,
2877 NULL, HFILL }
2878 },
2879 { &hf_eigrp_afi,
2880 { "AFI", "eigrp.afi",
2881 FT_UINT16, BASE_DEC, VALS(eigrp_afi2string), 0x0,
2882 NULL, HFILL }
2883 },
2884
2885 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2886 * EIGRP TLV 1.2 (legacy) and TLV 3.0 Metric (deprecated) definition
2887 */
2888 { &hf_eigrp_legacy_metric_delay,
2889 { "Scaled Delay", "eigrp.old_metric.delay",
2890 FT_UINT32, BASE_DEC, NULL, 0x0,
2891 "delay, in 39.1 nanosec interments", HFILL }
2892 },
2893 { &hf_eigrp_legacy_metric_bw,
2894 { "Scaled BW", "eigrp.old_metric.bw",
2895 FT_UINT32, BASE_DEC, NULL, 0x0,
2896 "bandwidth, in units of 1 Kbit/sec", HFILL }
2897 },
2898 { &hf_eigrp_legacy_metric_mtu,
2899 { "MTU", "eigrp.old_metric.mtu",
2900 FT_UINT24, BASE_DEC, NULL, 0x0,
2901 "MTU, in octets", HFILL }
2902 },
2903 { &hf_eigrp_legacy_metric_hopcount,
2904 { "Hop Count", "eigrp.old_metric.hopcount",
2905 FT_UINT8, BASE_DEC, NULL, 0x0,
2906 "Number of hops to destination", HFILL }
2907 },
2908 { &hf_eigrp_legacy_metric_rel,
2909 { "Reliability", "eigrp.old_metric.rel",
2910 FT_UINT8, BASE_DEC, NULL, 0x0,
2911 "percent packets successfully tx/rx", HFILL }
2912 },
2913 { &hf_eigrp_legacy_metric_load,
2914 { "Load", "eigrp.old_metric.load",
2915 FT_UINT8, BASE_DEC, NULL, 0x0,
2916 "percent of channel occupied", HFILL }
2917 },
2918 { &hf_eigrp_legacy_metric_intag,
2919 { "Route Tag", "eigrp.old_metric.intag",
2920 FT_UINT8, BASE_DEC, NULL, 0x0,
2921 "Internal Route Tag", HFILL }
2922 },
2923
2924 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2925 * EIGRP 3.0 TIDLIST TLV (only survivor in MTR)
2926 */
2927 { &hf_eigrp_tidlist_tid,
2928 { "TID List", "eigrp.tidlist",
2929 FT_UINT16, BASE_DEC, NULL, 0x0,
2930 NULL, HFILL }
2931 },
2932 { &hf_eigrp_tidlist_flags,
2933 { "TID List Flags", "eigrp.tidlist.flags",
2934 FT_UINT16, BASE_HEX, NULL, 0x0,
2935 NULL, HFILL }
2936 },
2937 { &hf_eigrp_tidlist_len,
2938 { "TID List Size", "eigrp.tidlist.len",
2939 FT_UINT16, BASE_DEC, NULL, 0x0,
2940 NULL, HFILL }
2941 },
2942 { &hf_eigrp_routerid,
2943 { "RouterID", "eigrp.routerid",
2944 FT_IPv4, BASE_NONE, NULL, 0x0,
2945 "Router ID of injecting router", HFILL }
2946 },
2947 { &hf_eigrp_legacy_metric_tag,
2948 { "Tag", "eigrp.old_metric.tag",
2949 FT_UINT32, BASE_DEC, NULL, 0x0,
2950 "route tag", HFILL }
2951 },
2952
2953 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2954 *
2955 * PDM opaque flag field definitions
2956 */
2957 { &hf_eigrp_metric_flags_srcwd,
2958 { "Source Withdraw", "eigrp.metric.flags.srcwd",
2959 FT_BOOLEAN, 8, TFS(&tfs_true_false), EIGRP_OPAQUE_SRCWD,
2960 "Route Source Withdraw", HFILL }
2961 },
2962 { &hf_eigrp_metric_flags_cd,
2963 { "Candidate Default", "eigrp.metric.flags.cd",
2964 FT_BOOLEAN, 8, TFS(&tfs_true_false), EIGRP_OPAQUE_CD,
2965 NULL, HFILL }
2966 },
2967 { &hf_eigrp_metric_flags_active,
2968 { "Route is Active", "eigrp.metric.flags.active",
2969 FT_BOOLEAN, 8, TFS(&tfs_true_false), EIGRP_OPAQUE_ACTIVE,
2970 "Route is currently in active state", HFILL }
2971 },
2972 { &hf_eigrp_metric_flags_repl,
2973 { "Route is Replicated", "eigrp.metric.flags.repl",
2974 FT_BOOLEAN, 8, TFS(&tfs_true_false), EIGRP_OPAQUE_REPL,
2975 "Route is replicated from different tableid", HFILL }
2976 },
2977
2978 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2979 * EIGRP TLV 1.2/3.0 ExtData Definitions
2980 */
2981 { &hf_eigrp_extdata_origrid,
2982 { "Originating RouterID", "eigrp.extdata.origrid",
2983 FT_IPv4, BASE_NONE, NULL, 0x0,
2984 "Router ID of redistributing router", HFILL }
2985 },
2986
2987 { &hf_eigrp_extdata_as,
2988 { "Originating A.S.", "eigrp.extdata.as",
2989 FT_UINT32, BASE_DEC, NULL, 0x0,
2990 "Autonomous System of redistributing protocol", HFILL }
2991 },
2992
2993 { &hf_eigrp_extdata_tag,
2994 { "Administrative Tag", "eigrp.extdata.tag",
2995 FT_UINT32, BASE_DEC, NULL, 0x0,
2996 "Administrative Route Tag", HFILL }
2997 },
2998 { &hf_eigrp_extdata_metric,
2999 { "External Metric", "eigrp.extdata.metric",
3000 FT_UINT32, BASE_DEC, NULL, 0x0,
3001 "Metric reported by redistributing protocol", HFILL }
3002 },
3003 { &hf_eigrp_extdata_reserved,
3004 { "Reserved", "eigrp.extdata.reserved",
3005 FT_UINT16, BASE_DEC, NULL, 0x0,
3006 NULL, HFILL }
3007 },
3008
3009 /* IPX ExtData Definitions */
3010 { &hf_eigrp_ipx_extdata_delay,
3011 { "External Delay", "eigrp.extdata.ipx_delay",
3012 FT_UINT16, BASE_DEC, NULL, 0x0,
3013 "Delay reported by redistributing protocol", HFILL }
3014 },
3015 { &hf_eigrp_ipx_extdata_metric,
3016 { "External Metric", "eigrp.extdata.ipx_metric",
3017 FT_UINT16, BASE_DEC, NULL, 0x0,
3018 "Delay reported by redistributing protocol", HFILL }
3019 },
3020
3021 { &hf_eigrp_extdata_proto,
3022 { "External Protocol ID", "eigrp.extdata.proto",
3023 FT_UINT8, BASE_DEC, VALS(eigrp_proto2string), 0x0,
3024 NULL, HFILL }
3025 },
3026
3027 { &hf_eigrp_extdata_flag_ext,
3028 { "Route is External", "eigrp.opaque.flag.ext",
3029 FT_BOOLEAN, 8, TFS(&tfs_true_false), EIGRP_OPAQUE_EXT,
3030 "External route", HFILL }
3031 },
3032 { &hf_eigrp_extdata_flag_cd,
3033 { "Route is Candidate Default", "eigrp.opaque.flag.cd",
3034 FT_BOOLEAN, 8, TFS(&tfs_true_false), EIGRP_OPAQUE_CD,
3035 "Candidate-Default route", HFILL }
3036 },
3037
3038 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
3039 * EIGRP TLV 2.0 "Wide" Metric format definition
3040 */
3041 /* Number of 16bit words in the metric section, used to determine the
3042 * start of the destination/attribute information.
3043 */
3044 { &hf_eigrp_metric_offset,
3045 { "Offset", "eigrp.metric.offset",
3046 FT_UINT8, BASE_DEC, NULL, 0x0,
3047 "Number of 16bit words to reach the start of the"
3048 "destination/attribute information", HFILL }
3049 },
3050
3051 /* Priority of the prefix when transmitting a group of destination
3052 * addresses to neighboring routers. A priority of zero indicates no
3053 * priority is set.
3054 */
3055 { &hf_eigrp_metric_priority,
3056 { "Priority", "eigrp.metric.priority",
3057 FT_UINT8, BASE_DEC, NULL, 0x0,
3058 "Priority of the prefix for ordering transmission", HFILL }
3059 },
3060
3061 /** The current error rate for the path. Measured as an error
3062 * percentage. A value of 255 indicates 100% reliability
3063 */
3064 { &hf_eigrp_metric_rel,
3065 { "Reliability", "eigrp.metric.reliability",
3066 FT_UINT8, BASE_DEC, NULL, 0x0,
3067 "percent packets successfully tx/rx", HFILL }
3068 },
3069
3070 /** The load utilization of the path to the destination. Measured as a
3071 * percentage of load. A value of 255 indicates 100% load.
3072 */
3073 { &hf_eigrp_metric_load,
3074 { "Load", "eigrp.metric.load",
3075 FT_UINT8, BASE_DEC, NULL, 0x0,
3076 "percent of channel occupied", HFILL }
3077 },
3078
3079 /** The minimum maximum transmission unit size for the path to the
3080 * destination. Not used in metric calculation, but available to
3081 * underlying protocols
3082 */
3083 { &hf_eigrp_metric_mtu,
3084 { "MTU", "eigrp.metric.mtu",
3085 FT_UINT24, BASE_DEC, NULL, 0x0,
3086 "MTU, in octets", HFILL }
3087 },
3088
3089 /** number of router traversals to the destination */
3090 { &hf_eigrp_metric_hopcount,
3091 { "Hop Count", "eigrp.metric.hopcount",
3092 FT_UINT8, BASE_DEC, NULL, 0x0,
3093 "Number of hops to destination", HFILL }
3094 },
3095
3096 /* Reserved - Transmitted as 0x0000 */
3097 { &hf_eigrp_metric_reserved,
3098 { "Reserved", "eigrp.metric.reserved",
3099 FT_UINT16, BASE_HEX, NULL, 0x0,
3100 NULL, HFILL }
3101 },
3102
3103 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
3104 * EIGRP TLV 2.0 Extended Metric Attributes
3105 */
3106 { &hf_eigrp_attr_opcode,
3107 { "Opcode", "eigrp.attr.opcode",
3108 FT_UINT8, BASE_DEC, VALS(eigrp_attr_opcode2string), 0x0,
3109 "Opcode - Operation code indicating the attribute type", HFILL }
3110 },
3111 { &hf_eigrp_attr_offset,
3112 { "Offset", "eigrp.attr.offset",
3113 FT_UINT8, BASE_DEC, NULL, 0x0,
3114 "Number of 2 byte words of data", HFILL }
3115 },
3116 { &hf_eigrp_attr_scaled,
3117 { "Legacy Metric", "eigrp.attr.scaled",
3118 FT_UINT16, BASE_DEC, NULL, 0x0,
3119 "Metric calculated from legacy TLVs", HFILL }
3120 },
3121 { &hf_eigrp_attr_tag,
3122 { "Tag", "eigrp.attr.tag",
3123 FT_UINT16, BASE_DEC, NULL, 0x0,
3124 "Tag assigned by admin for dest", HFILL }
3125 },
3126 { &hf_eigrp_attr_jitter,
3127 { "Jitter", "eigrp.attr.jitter",
3128 FT_UINT16, BASE_DEC, NULL, 0x0,
3129 "Variation in path delay", HFILL }
3130 },
3131 { &hf_eigrp_attr_qenergy,
3132 { "Q-Energy", "eigrp.attr.qenergy",
3133 FT_UINT16, BASE_DEC, NULL, 0x0,
3134 "Non-Active energy usage along path", HFILL }
3135 },
3136 { &hf_eigrp_attr_energy,
3137 { "Energy", "eigrp.attr.energy",
3138 FT_UINT16, BASE_DEC, NULL, 0x0,
3139 "Active energy usage along path", HFILL }
3140 },
3141
3142 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
3143 *
3144 * IPv4 specific address definitions
3145 */
3146 { &hf_eigrp_ipv4_nexthop,
3147 { "NextHop", "eigrp.ipv4.nexthop",
3148 FT_IPv4, BASE_NONE, NULL, 0x0,
3149 NULL, HFILL }
3150 },
3151 { &hf_eigrp_ipv4_prefixlen,
3152 { "Prefix Length", "eigrp.ipv4.prefixlen",
3153 FT_UINT8, BASE_DEC, NULL, 0x0,
3154 NULL, HFILL }
3155 },
3156
3157 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
3158 *
3159 * IPv6 specific address definitions
3160 */
3161 { &hf_eigrp_ipv6_nexthop,
3162 { "NextHop", "eigrp.ipv6.nexthop",
3163 FT_IPv6, BASE_NONE, NULL, 0x0,
3164 NULL, HFILL }
3165 },
3166
3167 { &hf_eigrp_ipv6_prefixlen,
3168 { "Prefix Length", "eigrp.ipv6.prefixlen",
3169 FT_UINT8, BASE_DEC, NULL, 0x0,
3170 NULL, HFILL }
3171 },
3172
3173 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
3174 *
3175 * IPX specific address definitions
3176 */
3177 { &hf_eigrp_ipx_nexthop_net,
3178 { "NextHop Net", "eigrp.ipx.nexthop_net",
3179 FT_IPXNET, BASE_NONE, NULL, 0x0,
3180 NULL, HFILL }
3181 },
3182 { &hf_eigrp_ipx_nexthop_host,
3183 { "NextHop Host", "eigrp.ipx.nexthop_host",
3184 FT_ETHER, BASE_NONE, NULL, 0x0,
3185 NULL, HFILL }
3186 },
3187 { &hf_eigrp_ipx_extdata_routerid,
3188 { "External RouterID", "eigrp.ipx.routerid",
3189 FT_ETHER, BASE_NONE, NULL, 0x0,
3190 "Router ID of redistributing router", HFILL }
3191 },
3192 { &hf_eigrp_ipx_dest,
3193 { "Destination", "eigrp.ipx.dest",
3194 FT_IPXNET, BASE_NONE, NULL, 0x0,
3195 NULL, HFILL }
3196 },
3197
3198 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
3199 *
3200 * AppleTalk specific address definitions
3201 */
3202 { &hf_eigrp_atalk_routerid,
3203 { "AppleTalk Router ID", "eigrp.atalk.routerid",
3204 FT_UINT32, BASE_DEC, NULL, 0x0,
3205 NULL, HFILL }
3206 },
3207
3208 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
3209 * Service Advertisement Framework definitions
3210 */
3211 { &hf_eigrp_saf_service,
3212 { "Service", "eigrp.saf.service",
3213 FT_UINT16, BASE_DEC, VALS(eigrp_saf_srv2string), 0x0,
3214 NULL, HFILL }
3215 },
3216 { &hf_eigrp_saf_subservice,
3217 { "Sub-Service", "eigrp.saf.subservice",
3218 FT_UINT16, BASE_DEC, NULL, 0x0,
3219 NULL, HFILL }
3220 },
3221 { &hf_eigrp_saf_guid,
3222 { "GUID", "eigrp.saf.guid",
3223 FT_GUID, BASE_NONE, NULL, 0x0,
3224 NULL, HFILL }
3225 },
3226 { &hf_eigrp_saf_data_type,
3227 { "Type", "eigrp.saf.data.type",
3228 FT_UINT16, BASE_HEX, VALS(eigrp_saf_type2string), 0x0,
3229 "SAF Message Data Type", HFILL }
3230 },
3231 { &hf_eigrp_saf_data_length,
3232 { "Length", "eigrp.saf.data.length",
3233 FT_UINT16, BASE_DEC, NULL, 0x0,
3234 NULL, HFILL }
3235 },
3236 { &hf_eigrp_saf_data_sequence,
3237 { "Sequence", "eigrp.saf.data.sequence",
3238 FT_UINT32, BASE_DEC, NULL, 0x0,
3239 NULL, HFILL }
3240 },
3241 { &hf_eigrp_saf_reachability_afi,
3242 { "AFI", "eigrp.saf.data.reachability.afi",
3243 FT_UINT16, BASE_DEC, VALS(eigrp_afi2string), 0x0,
3244 NULL, HFILL }
3245 },
3246 { &hf_eigrp_saf_reachability_port,
3247 { "Port", "eigrp.saf.data.reachability.port",
3248 FT_UINT16, BASE_DEC, NULL, 0x0,
3249 NULL, HFILL }
3250 },
3251 { &hf_eigrp_saf_reachability_protocol,
3252 { "Protocol", "eigrp.saf.data.reachability.protocol",
3253 FT_UINT16, BASE_DEC, NULL, 0x0,
3254 NULL, HFILL }
3255 },
3256 { &hf_eigrp_saf_reachability_addr_ipv4,
3257 { "IPv4 Addr", "eigrp.saf.data.reachability.addr_ipv4",
3258 FT_IPv4, BASE_NONE, NULL, 0x0,
3259 NULL, HFILL }
3260 },
3261 { &hf_eigrp_saf_reachability_addr_ipv6,
3262 { "IPv6 Addr", "eigrp.saf.data.reachability.addr_ipv6",
3263 FT_IPv6, BASE_NONE, NULL, 0x0,
3264 NULL, HFILL }
3265 },
3266 { &hf_eigrp_saf_reachability_addr_hex,
3267 { "Addr", "eigrp.saf.data.reachability.addr_hex",
3268 FT_BYTES, BASE_NONE, NULL, 0x0,
3269 NULL, HFILL }
3270 },
3271
3272 /* misc field used in a couple places */
3273 { &hf_eigrp_nullpad,
3274 { "Nullpad", "eigrp.nullpad",
3275 FT_BYTES, BASE_NONE, NULL, 0x0,
3276 NULL, HFILL }
3277 },
3278
3279 /* Generated from convert_proto_tree_add_text.pl */
3280 { &hf_eigrp_ipx_address, { "IPX Address", "eigrp.ipx_address", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3281 { &hf_eigrp_release, { "EIGRP Release", "eigrp.release_version", FT_UINT16, BASE_CUSTOM, CF_FUNC(eigrp_fmt_version), 0x0, NULL, HFILL }},
3282 { &hf_eigrp_tlv_version, { "EIGRP TLV version", "eigrp.tlv_version", FT_UINT16, BASE_CUSTOM, CF_FUNC(eigrp_fmt_version), 0x0, NULL, HFILL }},
3283 { &hf_eigrp_ipv4_destination, { "Destination", "eigrp.ipv4.destination", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3284 { &hf_eigrp_ipv6_destination, { "Destination", "eigrp.ipv6.destination", FT_IPv6, BASE_NONE, NULL, 0x0, NULL, HFILL }},
3285 { &hf_eigrp_appletalk_cable_range, { "AppleTalk Cable Range", "eigrp.appletalk_cable_range", FT_UINT32, BASE_CUSTOM, CF_FUNC(eigrp_fmt_cable_range), 0x0, NULL, HFILL }},
3286 { &hf_eigrp_nexthop_address, { "NextHop Address", "eigrp.nexthop_address", FT_UINT32, BASE_CUSTOM, CF_FUNC(eigrp_fmt_nexthop_address), 0x0, NULL, HFILL }},
3287 { &hf_eigrp_cable_range, { "Cable range", "eigrp.cable_range", FT_UINT32, BASE_CUSTOM, CF_FUNC(eigrp_fmt_cable_range), 0x0, NULL, HFILL }},
3288 { &hf_eigrp_metric_delay, { "Delay", "eigrp.metric.delay", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3289 { &hf_eigrp_metric_bandwidth, { "Bandwidth", "eigrp.metric.bandwidth", FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3290 { &hf_eigrp_checksum, { "Checksum", "eigrp.checksum", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3291 { &hf_eigrp_checksum_status, { "Checksum Status", "eigrp.checksum.status", FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0x0, NULL, HFILL }},
3292 { &hf_eigrp_metric_comm_type, { "Type", "eigrp.metric.comm_type", FT_UINT16, BASE_DEC, VALS(eigrp_metric_comm_type_vals), 0x0, NULL, HFILL }},
3293 { &hf_eigrp_extcomm_eigrp_flag, { "FLAG", "eigrp.extcomm.flag", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3294 { &hf_eigrp_extcomm_eigrp_tag, { "TAG", "eigrp.extcomm.tag", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3295 { &hf_eigrp_extcomm_eigrp_res, { "RES", "eigrp.extcomm.res", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3296 { &hf_eigrp_extcomm_eigrp_rid, { "RID", "eigrp.extcomm.rid", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3297 { &hf_eigrp_extcomm_eigrp_as, { "AS", "eigrp.extcomm.as", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3298 { &hf_eigrp_extcomm_eigrp_sdly, { "SDLY", "eigrp.extcomm.sdly", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3299 { &hf_eigrp_extcomm_eigrp_rel, { "RID", "eigrp.extcomm.rel", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3300 { &hf_eigrp_extcomm_eigrp_hop, { "AS", "eigrp.extcomm.hop", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3301 { &hf_eigrp_extcomm_eigrp_sbw, { "SDLY", "eigrp.extcomm.sbw", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3302 { &hf_eigrp_extcomm_eigrp_load, { "LOAD", "eigrp.extcomm.load", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3303 { &hf_eigrp_extcomm_eigrp_mtu, { "MTU", "eigrp.extcomm.mtu", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3304 { &hf_eigrp_extcomm_eigrp_xas, { "xAS", "eigrp.extcomm.xas", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3305 { &hf_eigrp_extcomm_eigrp_xrid, { "xRID", "eigrp.extcomm.xrid", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3306 { &hf_eigrp_extcomm_eigrp_xproto, { "xProto", "eigrp.extcomm.xproto", FT_UINT16, BASE_HEX, NULL, 0x0, NULL, HFILL }},
3307 { &hf_eigrp_extcomm_eigrp_xmetric, { "xMETRIC", "eigrp.extcomm.xmetric", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }},
3308 };
3309
3310 /* Setup protocol subtree array */
3311 static gint *ett[] = {
3312 /* header flag */
3313 &ett_eigrp,
3314 &ett_eigrp_flags,
3315
3316 /* tlv specific */
3317 &ett_eigrp_tlv,
3318 &ett_eigrp_tlv_metric,
3319 &ett_eigrp_tlv_attr,
3320 &ett_eigrp_tlv_extdata,
3321
3322 &ett_eigrp_tidlist,
3323 &ett_eigrp_stub_flags,
3324 &ett_eigrp_saf_reachability,
3325
3326 /* metric tlv specific */
3327 &ett_eigrp_metric_flags,
3328 &ett_eigrp_extdata_flags,
3329
3330 &ett_metric_comm_type
3331 };
3332
3333 static ei_register_info ei[] = {
3334 { &ei_eigrp_peer_termination, { "eigrp.peer_termination", PI_RESPONSE_CODE, PI_NOTE, "Peer Termination", EXPFILL }},
3335 { &ei_eigrp_auth_len, { "eigrp.auth.length.invalid", PI_MALFORMED, PI_WARN, "Invalid auth len", EXPFILL }},
3336 { &ei_eigrp_auth_type, { "eigrp.auth.type.invalid", PI_PROTOCOL, PI_WARN, "Invalid auth type", EXPFILL }},
3337 { &ei_eigrp_seq_addrlen, { "eigrp.seq.addrlen.invalid", PI_MALFORMED, PI_ERROR, "Invalid address length", EXPFILL }},
3338 { &ei_eigrp_peer_termination_graceful, { "eigrp.peer_termination_graceful", PI_RESPONSE_CODE, PI_NOTE, "Peer Termination (Graceful Shutdown)", EXPFILL }},
3339 { &ei_eigrp_prefixlen, { "eigrp.prefixlen.invalid", PI_MALFORMED, PI_WARN, "Invalid prefix length", EXPFILL }},
3340 { &ei_eigrp_unreachable, { "eigrp.unreachable", PI_RESPONSE_CODE, PI_NOTE, "Unreachable", EXPFILL }},
3341 { &ei_eigrp_tlv_type, { "eigrp.tlv_type.unknown", PI_PROTOCOL, PI_WARN, "Unknown TLV", EXPFILL }},
3342 { &ei_eigrp_afi, { "eigrp.afi.unknown", PI_PROTOCOL, PI_WARN, "Unknown AFI", EXPFILL }},
3343 { &ei_eigrp_checksum_bad, { "eigrp.checksum.bad", PI_CHECKSUM, PI_WARN, "Bad Checksum", EXPFILL }},
3344 { &ei_eigrp_tlv_len, { "eigrp.tlv.len.invalid", PI_MALFORMED, PI_ERROR, "Corrupt TLV (Length field less than 4)", EXPFILL }},
3345 { &ei_eigrp_tlv_trunc, { "eigrp.tlv.truncated", PI_MALFORMED, PI_ERROR, "Corrupt TLV (Truncated prematurely)", EXPFILL }},
3346 };
3347
3348 expert_module_t* expert_eigrp;
3349
3350 /* Register the protocol name and description */
3351 proto_eigrp = proto_register_protocol(
3352 "Enhanced Interior Gateway Routing Protocol", /* name */
3353 "EIGRP", /* short name */
3354 "eigrp" /* abbrev */
3355 );
3356
3357 /* Required function calls to register the header fields and subtrees used */
3358 proto_register_field_array(proto_eigrp, hf, array_length(hf));
3359 proto_register_subtree_array(ett, array_length(ett));
3360 expert_eigrp = expert_register_protocol(proto_eigrp);
3361 expert_register_field_array(expert_eigrp, ei, array_length(ei));
3362 }
3363
3364 /**
3365 *@fn void proto_reg_handoff_eigrp(void)
3366 *
3367 * @usage
3368 * This exact format is required because a script is used to find these
3369 * routines and create the code that calls these routines.
3370 *
3371 * @par
3372 * If this dissector uses sub-dissector registration add a registration routine.
3373 *
3374 * This form of the reg_handoff function is used if if you perform registration
3375 * functions which are dependent upon prefs. If this function is registered as
3376 * a prefs callback (see prefs_register_protocol above) this function is also
3377 * called by preferences whenever "Apply" is pressed;
3378 *
3379 * In that case, it should accommodate being called more than once.
3380 */
3381 void
proto_reg_handoff_eigrp(void)3382 proto_reg_handoff_eigrp(void)
3383 {
3384 dissector_handle_t eigrp_handle;
3385
3386 ipxsap_handle = find_dissector_add_dependency("ipxsap", proto_eigrp);
3387 media_type_table = find_dissector_table("media_type");
3388
3389 eigrp_handle = create_dissector_handle(dissect_eigrp, proto_eigrp);
3390
3391 dissector_add_uint("ip.proto", IP_PROTO_EIGRP, eigrp_handle);
3392 dissector_add_uint("ddp.type", DDP_EIGRP, eigrp_handle);
3393 dissector_add_uint("ipx.socket", IPX_SOCKET_EIGRP, eigrp_handle);
3394 }
3395
3396 /*
3397 * Editor modelines - https://www.wireshark.org/tools/modelines.html
3398 *
3399 * Local variables:
3400 * c-basic-offset: 4
3401 * tab-width: 8
3402 * indent-tabs-mode: nil
3403 * End:
3404 *
3405 * vi: set shiftwidth=4 tabstop=8 expandtab:
3406 * :indentSize=4:tabSize=8:noTabs=true:
3407 */
3408