Coverage Report

Created: 2026-07-12 07:10

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