From Jochen Bartl:
[obnox/wireshark/wip.git] / epan / dissectors / packet-eigrp.c
1 /* packet-eigrp.c
2  * Routines for EIGRP Stub Routing, Authentication and IPv6 TLV dissection
3  *
4  * Copyright 2009, Jochen Bartl <jochen.bartl@gmail.com>
5  *
6  * Routines for EIGRP dissection
7  * Copyright 2000, Paul Ionescu <paul@acorp.ro>
8  *
9  * $Id$
10  *
11  * Wireshark - Network traffic analyzer
12  * By Gerald Combs <gerald@wireshark.org>
13  * Copyright 1998 Gerald Combs
14  *
15  * This program is free software; you can redistribute it and/or
16  * modify it under the terms of the GNU General Public License
17  * as published by the Free Software Foundation; either version 2
18  * of the License, or (at your option) any later version.
19  *
20  * This program is distributed in the hope that it will be useful,
21  * but WITHOUT ANY WARRANTY; without even the implied warranty of
22  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  * GNU General Public License for more details.
24  *
25  * You should have received a copy of the GNU General Public License
26  * along with this program; if not, write to the Free Software
27  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
28  */
29
30 #ifdef HAVE_CONFIG_H
31 # include "config.h"
32 #endif
33
34 #include <glib.h>
35 #include <epan/packet.h>
36 #include <epan/addr_resolv.h>
37
38 #include <epan/atalk-utils.h>
39 #include <epan/addr_and_mask.h>
40 #include <epan/ipproto.h>
41 #include "packet-ipx.h"
42
43 /*
44  * See
45  *
46  *      http://www.rhyshaden.com/eigrp.htm
47  */
48
49 #define EIGRP_UPDATE    0x01
50 #define EIGRP_REQUEST   0x02
51 #define EIGRP_QUERY     0x03
52 #define EIGRP_REPLY     0x04
53 #define EIGRP_HELLO     0x05
54 #define EIGRP_SAP       0x06
55 #define EIGRP_SIA_QUERY 0x0a
56 #define EIGRP_SIA_REPLY 0x0b
57 #define EIGRP_HI        0x20  /* This value is for my own need to make a difference between Hello and Ack */
58 #define EIGRP_ACK       0x40  /* This value is for my own need to make a difference between Hello and Ack */
59
60 #define TLV_PAR         0x0001
61 #define TLV_AUTH        0x0002
62 #define TLV_SEQ         0x0003
63 #define TLV_SV          0x0004
64 #define TLV_NMS         0x0005
65 #define TLV_STUB        0x0006
66 #define TLV_IP_INT      0x0102
67 #define TLV_IP_EXT      0x0103
68 #define TLV_AT_INT      0x0202
69 #define TLV_AT_EXT      0x0203
70 #define TLV_AT_CBL      0x0204
71 #define TLV_IPX_INT     0x0302
72 #define TLV_IPX_EXT     0x0303
73 #define TLV_IP6_INT     0x0402
74 #define TLV_IP6_EXT     0x0403
75
76 #define EIGRP_FLAGS_INIT        0x00000001
77 #define EIGRP_FLAGS_CONDRECV    0x00000002
78
79 #define EIGRP_STUB_FLAGS_CONNECTED      0x0001
80 #define EIGRP_STUB_FLAGS_STATIC         0x0002
81 #define EIGRP_STUB_FLAGS_SUMMARY        0x0004
82 #define EIGRP_STUB_FLAGS_RECVONLY       0x0008
83 #define EIGRP_STUB_FLAGS_REDIST         0x0010
84 #define EIGRP_STUB_FLAGS_LEAKMAP        0x0020
85
86 #define EIGRP_IP_EXT_FLAGS_EXT          0x01
87 #define EIGRP_IP_EXT_FLAGS_DEFAULT      0x02
88
89 #define EIGRP_HEADER_LENGTH             20
90
91 static gint proto_eigrp = -1;
92
93 static gint hf_eigrp_version = -1;
94 static gint hf_eigrp_opcode = -1;
95 static gint hf_eigrp_checksum = -1;
96
97 static gint hf_eigrp_flags = -1; /* Flags Tree */
98 static gint hf_eigrp_flags_init = -1;
99 static gint hf_eigrp_flags_condrecv = -1;
100
101 static gint hf_eigrp_sequence = -1;
102 static gint hf_eigrp_acknowledge = -1;
103 static gint hf_eigrp_as = -1;
104 static gint hf_eigrp_tlv = -1;
105 static gint hf_eigrp_tlv_size = -1;
106
107 /* EIGRP Parameters TLV */
108 static gint hf_eigrp_par_k1 = -1;
109 static gint hf_eigrp_par_k2 = -1;
110 static gint hf_eigrp_par_k3 = -1;
111 static gint hf_eigrp_par_k4 = -1;
112 static gint hf_eigrp_par_k5 = -1;
113 static gint hf_eigrp_par_reserved = -1;
114 static gint hf_eigrp_par_holdtime = -1;
115
116 /* Authentication TLV */
117 static gint hf_eigrp_auth_type = -1;
118 static gint hf_eigrp_auth_keysize = -1;
119 static gint hf_eigrp_auth_keyid = -1;
120 static gint hf_eigrp_auth_nullpad = -1;
121 static gint hf_eigrp_auth_data = -1;
122
123 /* Sequence TLV */
124 static gint hf_eigrp_seq_addrlen = -1;
125 static gint hf_eigrp_seq_ipaddr = -1;
126 static gint hf_eigrp_seq_ip6addr = -1;
127
128 /* Software Version TLV */
129 static gint hf_eigrp_sv_ios = -1;
130 static gint hf_eigrp_sv_eigrp = -1;
131
132 /* Next multicast sequence TLV */
133 static gint hf_eigrp_nms = -1;
134
135 /* Stub routing TLV */
136 static gint hf_eigrp_stub_flags = -1; /* Stub Flags Tree */
137 static gint hf_eigrp_stub_flags_connected = -1;
138 static gint hf_eigrp_stub_flags_static = -1;
139 static gint hf_eigrp_stub_flags_summary = -1;
140 static gint hf_eigrp_stub_flags_recvonly = -1;
141 static gint hf_eigrp_stub_flags_redist = -1;
142 static gint hf_eigrp_stub_flags_leakmap = -1;
143
144 /* IP internal route TLV */
145 static gint hf_eigrp_ip_int_nexthop = -1;
146 static gint hf_eigrp_ip_int_delay = -1;
147 static gint hf_eigrp_ip_int_bandwidth = -1;
148 static gint hf_eigrp_ip_int_mtu = -1;
149 static gint hf_eigrp_ip_int_hopcount = -1;
150 static gint hf_eigrp_ip_int_reliability = -1;
151 static gint hf_eigrp_ip_int_load = -1;
152 static gint hf_eigrp_ip_int_reserved = -1;
153 static gint hf_eigrp_ip_int_prefixlen = -1;
154 static gint hf_eigrp_ip_int_dst = -1;
155
156 /* IP external route TLV */
157 static gint hf_eigrp_ip_ext_nexthop = -1;
158 static gint hf_eigrp_ip_ext_origrouter = -1;
159 static gint hf_eigrp_ip_ext_as = -1;
160 static gint hf_eigrp_ip_ext_tag = -1;
161 static gint hf_eigrp_ip_ext_metric = -1;
162 static gint hf_eigrp_ip_ext_reserved = -1;
163 static gint hf_eigrp_ip_ext_proto = -1;
164
165 static gint hf_eigrp_ip_ext_flags = -1; /* IP external route Flags Tree */
166 static gint hf_eigrp_ip_ext_flags_ext = -1;
167 static gint hf_eigrp_ip_ext_flags_default = -1;
168
169 static gint hf_eigrp_ip_ext_delay = -1;
170 static gint hf_eigrp_ip_ext_bandwidth = -1;
171 static gint hf_eigrp_ip_ext_mtu = -1;
172 static gint hf_eigrp_ip_ext_hopcount = -1;
173 static gint hf_eigrp_ip_ext_reliability = -1;
174 static gint hf_eigrp_ip_ext_load = -1;
175 static gint hf_eigrp_ip_ext_reserved2 = -1;
176 static gint hf_eigrp_ip_ext_prefixlen = -1;
177
178 /* IPX internal route TLV */
179 static gint hf_eigrp_ipx_int_delay = -1;
180 static gint hf_eigrp_ipx_int_bandwidth = -1;
181 static gint hf_eigrp_ipx_int_mtu = -1;
182 static gint hf_eigrp_ipx_int_hopcount = -1;
183 static gint hf_eigrp_ipx_int_reliability = -1;
184 static gint hf_eigrp_ipx_int_load = -1;
185 static gint hf_eigrp_ipx_int_reserved = -1;
186
187 /* IPX external route TLV */
188 static gint hf_eigrp_ipx_ext_as = -1;
189 static gint hf_eigrp_ipx_ext_tag = -1;
190 static gint hf_eigrp_ipx_ext_proto = -1;
191 static gint hf_eigrp_ipx_ext_reserved = -1;
192 static gint hf_eigrp_ipx_ext_metric = -1;
193 static gint hf_eigrp_ipx_ext_extdelay = -1;
194 static gint hf_eigrp_ipx_ext_delay = -1;
195 static gint hf_eigrp_ipx_ext_bandwidth = -1;
196 static gint hf_eigrp_ipx_ext_mtu = -1;
197 static gint hf_eigrp_ipx_ext_hopcount = -1;
198 static gint hf_eigrp_ipx_ext_reliability = -1;
199 static gint hf_eigrp_ipx_ext_load = -1;
200 static gint hf_eigrp_ipx_ext_reserved2 = -1;
201
202
203 /* AppleTalk cable configuration TLV */
204 static gint hf_eigrp_at_cbl_routerid = -1;
205
206 /* AppleTalk internal route TLV */
207 static gint hf_eigrp_at_int_delay = -1;
208 static gint hf_eigrp_at_int_bandwidth = -1;
209 static gint hf_eigrp_at_int_mtu = -1;
210 static gint hf_eigrp_at_int_hopcount = -1;
211 static gint hf_eigrp_at_int_reliability = -1;
212 static gint hf_eigrp_at_int_load = -1;
213 static gint hf_eigrp_at_int_reserved = -1;
214
215 /* AppleTalk external route TLV */
216 static gint hf_eigrp_at_ext_origrouter = -1;
217 static gint hf_eigrp_at_ext_as = -1;
218 static gint hf_eigrp_at_ext_tag = -1;
219 static gint hf_eigrp_at_ext_proto = -1;
220
221 static gint hf_eigrp_at_ext_flags = -1; /* AppleTalk external route Flags Tree */
222 static gint hf_eigrp_at_ext_flags_ext = -1;
223 static gint hf_eigrp_at_ext_flags_default = -1;
224
225 static gint hf_eigrp_at_ext_metric = -1;
226
227 static gint hf_eigrp_at_ext_delay = -1;
228 static gint hf_eigrp_at_ext_bandwidth = -1;
229 static gint hf_eigrp_at_ext_mtu = -1;
230 static gint hf_eigrp_at_ext_hopcount = -1;
231 static gint hf_eigrp_at_ext_reliability = -1;
232 static gint hf_eigrp_at_ext_load = -1;
233 static gint hf_eigrp_at_ext_reserved = -1;
234
235 /* IPv6 internal route TLV */
236 static gint hf_eigrp_ip6_int_nexthop = -1;
237 static gint hf_eigrp_ip6_int_delay = -1;
238 static gint hf_eigrp_ip6_int_bandwidth = -1;
239 static gint hf_eigrp_ip6_int_mtu = -1;
240 static gint hf_eigrp_ip6_int_hopcount = -1;
241 static gint hf_eigrp_ip6_int_reliability = -1;
242 static gint hf_eigrp_ip6_int_load = -1;
243 static gint hf_eigrp_ip6_int_reserved = -1;
244 static gint hf_eigrp_ip6_int_prefixlen = -1;
245
246 /* IPv6 external route TLV */
247 static gint hf_eigrp_ip6_ext_nexthop = -1;
248 static gint hf_eigrp_ip6_ext_origrouter = -1;
249 static gint hf_eigrp_ip6_ext_as = -1;
250 static gint hf_eigrp_ip6_ext_tag = -1;
251 static gint hf_eigrp_ip6_ext_metric = -1;
252 static gint hf_eigrp_ip6_ext_reserved = -1;
253 static gint hf_eigrp_ip6_ext_proto = -1;
254
255 static gint hf_eigrp_ip6_ext_flags = -1; /* IPv6 external route Flags Tree */
256 static gint hf_eigrp_ip6_ext_flags_ext = -1;
257 static gint hf_eigrp_ip6_ext_flags_default = -1;
258
259 static gint hf_eigrp_ip6_ext_delay = -1;
260 static gint hf_eigrp_ip6_ext_bandwidth = -1;
261 static gint hf_eigrp_ip6_ext_mtu = -1;
262 static gint hf_eigrp_ip6_ext_hopcount = -1;
263 static gint hf_eigrp_ip6_ext_reliability = -1;
264 static gint hf_eigrp_ip6_ext_load = -1;
265 static gint hf_eigrp_ip6_ext_reserved2 = -1;
266 static gint hf_eigrp_ip6_ext_prefixlen = -1;
267
268 static gint ett_eigrp = -1;
269 static gint ett_eigrp_flags = -1;
270 static gint ett_tlv = -1;
271 static gint ett_eigrp_stub_flags = -1;
272 static gint ett_eigrp_ip_ext_flags = -1;
273 static gint ett_eigrp_ip6_ext_flags = -1;
274 static gint ett_eigrp_at_ext_flags = -1;
275
276 static dissector_handle_t ipxsap_handle;
277
278
279 static const value_string eigrp_opcode_vals[] = {
280         { EIGRP_HELLO,          "Hello/Ack" },
281         { EIGRP_UPDATE,         "Update" },
282         { EIGRP_REPLY,          "Reply" },
283         { EIGRP_QUERY,          "Query" },
284         { EIGRP_REQUEST,        "Request" },
285         { EIGRP_SAP,            "IPX/SAP Update" },
286         { EIGRP_SIA_QUERY,      "SIA-Query" },
287         { EIGRP_SIA_REPLY,      "SIA-Reply" },
288         { EIGRP_HI,             "Hello" },
289         { EIGRP_ACK,            "Acknowledge" },
290         { 0,                            NULL }
291 };
292
293 static const value_string eigrp_tlv_vals[] = {
294         { TLV_PAR,     "EIGRP Parameters"},
295         { TLV_AUTH,    "Authentication data"},
296         { TLV_SEQ ,    "Sequence"},
297         { TLV_SV,      "Software Version"},
298         { TLV_NMS   ,  "Next multicast sequence"},
299         { TLV_STUB  ,  "Stub routing"},
300         { TLV_IP_INT,  "IP internal route"},
301         { TLV_IP_EXT,  "IP external route"},
302         { TLV_AT_INT,  "AppleTalk internal route"},
303         { TLV_AT_EXT,  "AppleTalk external route"},
304         { TLV_AT_CBL,  "AppleTalk cable configuration"},
305         { TLV_IPX_INT, "IPX internal route"},
306         { TLV_IPX_EXT, "IPX external route"},
307         { TLV_IP6_INT,  "IPv6 internal route"},
308         { TLV_IP6_EXT,  "IPv6 external route"},
309         { 0,            NULL}
310 };
311
312 static const value_string eigrp_pid_vals[] = {
313         { 1,    "IGRP"},
314         { 2,    "EIGRP"},
315         { 3,    "Static Route"},
316         { 4,    "RIP"},
317         { 5,    "Hello"},
318         { 6,    "OSPF"},
319         { 7,    "IS-IS"},
320         { 8,    "EGP"},
321         { 9,    "BGP"},
322         { 10,   "IDRP"},
323         { 11,   "Connected link"},
324         { 0,    NULL}
325 };
326
327 static const value_string eigrp_auth_type_vals[] = {
328         { 2,    "MD5"},
329         { 0,    NULL}
330 };
331
332 static void dissect_eigrp_par(tvbuff_t *tvb, proto_tree *tree, proto_item *ti);
333 static void dissect_eigrp_auth(tvbuff_t *tvb, proto_tree *tree, proto_item *ti);
334 static void dissect_eigrp_seq(tvbuff_t *tvb, proto_tree *tree);
335 static void dissect_eigrp_sv(tvbuff_t *tvb, proto_tree *tree, proto_item *ti);
336 static void dissect_eigrp_nms(tvbuff_t *tvb, proto_tree *tree, proto_item *ti);
337 static void dissect_eigrp_stub(tvbuff_t *tvb, proto_tree *tree);
338
339 static void dissect_eigrp_ip_int(tvbuff_t *tvb, proto_tree *tree, proto_item *ti);
340 static void dissect_eigrp_ip_ext(tvbuff_t *tvb, proto_tree *tree, proto_item *ti);
341
342 static void dissect_eigrp_ipx_int(tvbuff_t *tvb, proto_tree *tree, proto_item *ti);
343 static void dissect_eigrp_ipx_ext(tvbuff_t *tvb, proto_tree *tree, proto_item *ti);
344
345 static void dissect_eigrp_at_cbl(tvbuff_t *tvb, proto_tree *tree, proto_item *ti);
346 static void dissect_eigrp_at_int(tvbuff_t *tvb, proto_tree *tree, proto_item *ti);
347 static void dissect_eigrp_at_ext(tvbuff_t *tvb, proto_tree *tree, proto_item *ti);
348
349 static void dissect_eigrp_ip6_int(tvbuff_t *tvb, proto_tree *tree, proto_item *ti);
350 static void dissect_eigrp_ip6_ext(tvbuff_t *tvb, proto_tree *tree, proto_item *ti);
351
352
353 static void dissect_eigrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) {
354
355         proto_tree *eigrp_tree, *tlv_tree, *eigrp_flags_tree;
356         proto_item *ti;
357
358         guint opcode, opcode_tmp;
359         guint16 tlv;
360         guint32 ack, size, offset = EIGRP_HEADER_LENGTH;
361
362         col_set_str(pinfo->cinfo, COL_PROTOCOL, "EIGRP");
363         col_clear(pinfo->cinfo, COL_INFO);
364
365         opcode_tmp = opcode = tvb_get_guint8(tvb, 1);
366         ack = tvb_get_ntohl(tvb, 12);
367         if (opcode == EIGRP_HELLO) { if (ack == 0) opcode_tmp = EIGRP_HI; else opcode_tmp = EIGRP_ACK; }
368
369         col_add_str(pinfo->cinfo, COL_INFO,
370                         val_to_str(opcode_tmp, eigrp_opcode_vals, "Unknown (0x%04x)"));
371
372         if (tree) {
373
374                 ti = proto_tree_add_protocol_format(tree, proto_eigrp, tvb, 0, -1, "Cisco EIGRP");
375
376                 eigrp_tree = proto_item_add_subtree(ti, ett_eigrp);
377
378                 proto_tree_add_item(eigrp_tree, hf_eigrp_version, tvb, 0, 1, FALSE);
379                 proto_tree_add_item(eigrp_tree, hf_eigrp_opcode, tvb, 1, 1, FALSE);
380                 proto_tree_add_item(eigrp_tree, hf_eigrp_checksum, tvb, 2, 2, FALSE);
381
382 /* Decode the EIGRP Flags Field */
383
384                 ti = proto_tree_add_item(eigrp_tree, hf_eigrp_flags, tvb, 4, 4, FALSE);
385                 eigrp_flags_tree = proto_item_add_subtree(ti, ett_eigrp_flags);
386
387                 proto_tree_add_item(eigrp_flags_tree, hf_eigrp_flags_init, tvb, 4, 4, FALSE);
388                 proto_tree_add_item (eigrp_flags_tree, hf_eigrp_flags_condrecv, tvb, 4, 4, FALSE);
389
390 /* End Decode the EIGRP Flags Field */
391
392                 proto_tree_add_item(eigrp_tree, hf_eigrp_sequence, tvb, 8, 4, FALSE);
393                 proto_tree_add_item(eigrp_tree, hf_eigrp_acknowledge, tvb, 12, 4, FALSE);
394                 proto_tree_add_item(eigrp_tree, hf_eigrp_as, tvb, 16, 4, FALSE);
395
396                 if (opcode == EIGRP_SAP) {
397                         call_dissector(ipxsap_handle, tvb_new_subset(tvb, EIGRP_HEADER_LENGTH, -1, -1), pinfo, eigrp_tree);
398                         return;
399                 }
400
401                 while (tvb_reported_length_remaining(tvb, offset) > 0) {
402
403                         tlv = tvb_get_ntohs(tvb, offset);
404                         size =  tvb_get_ntohs(tvb, offset + 2);
405
406                         if (size == 0) {
407                                 proto_tree_add_text(eigrp_tree, tvb, offset, -1, "Unknown data (maybe authentication)");
408                                 return;
409                         }
410
411                         ti = proto_tree_add_text(eigrp_tree, tvb, offset,size,
412                                 "%s", val_to_str(tlv, eigrp_tlv_vals, "Unknown (0x%04x)"));
413
414                         tlv_tree = proto_item_add_subtree(ti, ett_tlv);
415                         proto_tree_add_item(tlv_tree, hf_eigrp_tlv, tvb, offset, 2, FALSE);
416                         proto_tree_add_item(tlv_tree, hf_eigrp_tlv_size, tvb, offset + 2, 2, FALSE);
417
418
419                         switch (tlv) {
420                                 case TLV_PAR:
421                                         dissect_eigrp_par(tvb_new_subset(tvb, offset + 4, size - 4, -1), tlv_tree, ti);
422                                         break;
423                                 case TLV_AUTH:
424                                         dissect_eigrp_auth(tvb_new_subset(tvb, offset + 4, size - 4, -1), tlv_tree, ti);
425                                         break;
426                                 case TLV_SEQ:
427                                         dissect_eigrp_seq(tvb_new_subset(tvb, offset + 4, size - 4, -1), tlv_tree);
428                                         break;
429                                 case TLV_SV:
430                                         dissect_eigrp_sv(tvb_new_subset(tvb, offset + 4, size - 4, -1), tlv_tree, ti);
431                                         break;
432                                 case TLV_NMS:
433                                         dissect_eigrp_nms(tvb_new_subset(tvb, offset + 4, size - 4, -1), tlv_tree, ti);
434                                         break;
435                                 case TLV_STUB:
436                                         dissect_eigrp_stub(tvb_new_subset(tvb, offset + 4, size - 4, -1), tlv_tree);
437                                         break;
438
439                                 case TLV_IP_INT:
440                                         dissect_eigrp_ip_int(tvb_new_subset(tvb, offset + 4, size - 4, -1), tlv_tree, ti);
441                                         break;
442                                 case TLV_IP_EXT:
443                                         dissect_eigrp_ip_ext(tvb_new_subset(tvb, offset + 4, size - 4, -1), tlv_tree, ti);
444                                         break;
445
446                                 case TLV_IPX_INT:
447                                         dissect_eigrp_ipx_int(tvb_new_subset(tvb, offset + 4, size - 4, -1), tlv_tree, ti);
448                                         break;
449                                 case TLV_IPX_EXT:
450                                         dissect_eigrp_ipx_ext(tvb_new_subset(tvb, offset + 4, size - 4, -1), tlv_tree, ti);
451                                         break;
452
453                                 case TLV_AT_CBL:
454                                         dissect_eigrp_at_cbl(tvb_new_subset(tvb, offset + 4, size - 4, -1), tlv_tree, ti);
455                                         break;
456                                 case TLV_AT_INT:
457                                         dissect_eigrp_at_int(tvb_new_subset(tvb, offset + 4, size - 4, -1), tlv_tree, ti);
458                                         break;
459                                 case TLV_AT_EXT:
460                                         dissect_eigrp_at_ext(tvb_new_subset(tvb, offset + 4, size - 4, -1), tlv_tree, ti);
461                                         break;                  
462
463                                 case TLV_IP6_INT:
464                                         dissect_eigrp_ip6_int(tvb_new_subset(tvb, offset + 4, size - 4, -1), tlv_tree, ti);
465                                         break;
466                                 case TLV_IP6_EXT:
467                                         dissect_eigrp_ip6_ext(tvb_new_subset(tvb, offset + 4, size - 4, -1), tlv_tree, ti);
468                                         break;
469                         }
470
471                         offset += size;
472                 }
473         }
474 }
475
476
477
478 static void dissect_eigrp_par(tvbuff_t *tvb, proto_tree *tree, proto_item *ti) {
479
480         int offset = 0;
481         guint8 k1, k2, k3, k4, k5;
482
483         k1 = tvb_get_guint8(tvb, 1);
484         proto_tree_add_item(tree, hf_eigrp_par_k1, tvb, offset, 1, FALSE);
485         offset += 1;
486         k2 = tvb_get_guint8(tvb, 1);
487         proto_tree_add_item(tree, hf_eigrp_par_k2, tvb, offset, 1, FALSE);
488         offset += 1;
489         k3 = tvb_get_guint8(tvb, 1);
490         proto_tree_add_item(tree, hf_eigrp_par_k3, tvb, offset, 1, FALSE);
491         offset += 1;
492         k4 = tvb_get_guint8(tvb, 1);
493         proto_tree_add_item(tree, hf_eigrp_par_k4, tvb, offset, 1, FALSE);
494         offset += 1;
495         k5 = tvb_get_guint8(tvb, 1);
496         proto_tree_add_item(tree, hf_eigrp_par_k5, tvb, offset, 1, FALSE);
497         offset += 1;
498         proto_tree_add_item(tree, hf_eigrp_par_reserved, tvb, offset, 1, FALSE);
499         offset += 1;
500         proto_tree_add_item(tree, hf_eigrp_par_holdtime, tvb, offset, 2, FALSE);
501
502         if (k1 == 255 && k2 == 255 && k3 == 255 && k4 == 255 && k5 == 255) {
503                 proto_item_append_text(ti, ": Goodbye Message");
504         }
505 }
506
507 static void dissect_eigrp_auth(tvbuff_t *tvb, proto_tree *tree, proto_item *ti) {
508
509         int offset = 0;
510         guint16 keysize;
511
512         keysize = tvb_get_ntohs(tvb, 2);
513
514         proto_tree_add_item(tree, hf_eigrp_auth_type, tvb, offset, 2, FALSE);
515         offset += 2;
516         proto_tree_add_item(tree, hf_eigrp_auth_keysize, tvb, offset, 2, FALSE);
517         offset += 2;
518         proto_tree_add_item(tree, hf_eigrp_auth_keyid, tvb, offset, 4, FALSE);
519         offset += 4;
520         proto_tree_add_item(tree, hf_eigrp_auth_nullpad, tvb, offset, 12, FALSE);
521         offset += 12;
522
523         switch (keysize) {
524                 /* Only MD5 is supported at the moment */
525                 case 16:
526                         proto_tree_add_item(tree, hf_eigrp_auth_data, tvb, offset, keysize, FALSE);
527                         break;
528                 default:
529                         /* nothing */
530                         proto_item_append_text(ti, "  [Invalid key size %u] Only 16/MD5 supported at the moment", keysize);
531                         ;
532         }
533 }
534
535 static void dissect_eigrp_seq(tvbuff_t *tvb, proto_tree *tree) {
536
537         int offset = 0;
538         guint8 addr_len;
539
540         addr_len = tvb_get_guint8(tvb, 0);
541
542         proto_tree_add_item(tree, hf_eigrp_seq_addrlen, tvb, offset, 1, FALSE);
543         offset += 1;
544
545         switch (addr_len) {
546                 /* IPv4 */
547                 case 4:
548                         proto_tree_add_item(tree, hf_eigrp_seq_ipaddr, tvb, offset, addr_len, FALSE);
549                         break;
550                 /* IPX */
551                 case 10:
552                         proto_tree_add_text(tree, tvb, offset, addr_len, "IPX Address = %08x.%04x.%04x.%04x",
553                                         tvb_get_ntohl(tvb, 1), tvb_get_ntohs(tvb, 5),
554                                         tvb_get_ntohs(tvb, 7), tvb_get_ntohs(tvb, 9));
555                         break;
556                 /* IPv6 */
557                 case 16:
558                         proto_tree_add_item(tree, hf_eigrp_seq_ip6addr, tvb, offset, addr_len, FALSE);
559                         break;
560                 default:
561                         /* nothing */
562                         ;
563         }
564 }
565
566 static void dissect_eigrp_sv(tvbuff_t *tvb, proto_tree *tree, proto_item *ti) {
567
568         int offset = 0;
569         guint8 ios_rel_major, ios_rel_minor;
570         guint8 eigrp_rel_major, eigrp_rel_minor;
571
572         ios_rel_major = tvb_get_guint8(tvb, 0);
573         ios_rel_minor = tvb_get_guint8(tvb, 1);
574         proto_tree_add_text(tree, tvb, offset, 2, "IOS release version: %u.%u",
575                              ios_rel_major, ios_rel_minor);
576         offset += 2;
577         proto_item_append_text(ti, ": IOS=%u.%u", ios_rel_major, ios_rel_minor);
578
579         eigrp_rel_major = tvb_get_guint8(tvb, 2);
580         eigrp_rel_minor = tvb_get_guint8(tvb, 3);
581         proto_tree_add_text(tree,tvb,offset, 2, "EIGRP release version: %u.%u",
582                              eigrp_rel_major, eigrp_rel_minor);
583         proto_item_append_text(ti, ", EIGRP=%u.%u",
584                                 eigrp_rel_major, eigrp_rel_minor);
585 }
586
587 static void dissect_eigrp_nms(tvbuff_t *tvb, proto_tree *tree, proto_item *ti) {
588
589         proto_tree_add_item(tree, hf_eigrp_nms, tvb, 0, 4, FALSE);
590         proto_item_append_text(ti, ": %u", tvb_get_ntohl(tvb, 0));
591 }
592
593 static void dissect_eigrp_stub(tvbuff_t *tvb, proto_tree *tree) {
594
595         proto_tree *eigrp_stub_flags_tree;
596         proto_item *ti;
597
598         ti = proto_tree_add_item(tree, hf_eigrp_stub_flags, tvb, 0, 2, FALSE);
599         eigrp_stub_flags_tree = proto_item_add_subtree(ti, ett_eigrp_stub_flags);
600
601         proto_tree_add_item(eigrp_stub_flags_tree, hf_eigrp_stub_flags_connected, tvb, 0, 2, FALSE);
602         proto_tree_add_item(eigrp_stub_flags_tree, hf_eigrp_stub_flags_static, tvb, 0, 2, FALSE);
603         proto_tree_add_item(eigrp_stub_flags_tree, hf_eigrp_stub_flags_summary, tvb, 0, 2, FALSE);
604         proto_tree_add_item(eigrp_stub_flags_tree, hf_eigrp_stub_flags_recvonly, tvb, 0, 2, FALSE);
605         proto_tree_add_item(eigrp_stub_flags_tree, hf_eigrp_stub_flags_redist, tvb, 0, 2, FALSE);
606         proto_tree_add_item(eigrp_stub_flags_tree, hf_eigrp_stub_flags_leakmap, tvb, 0, 2, FALSE);
607 }
608
609 static void dissect_eigrp_ip_int(tvbuff_t *tvb, proto_tree *tree, proto_item *ti) {
610
611         guint8 ip_addr[4], length;
612         int addr_len, offset = 0;
613         proto_item *prefixlenti;
614
615         tvb_memcpy(tvb, ip_addr, 0, 4);
616
617         proto_tree_add_item(tree, hf_eigrp_ip_int_nexthop, tvb, offset, 4, FALSE);
618         offset += 4;
619         proto_tree_add_item(tree, hf_eigrp_ip_int_delay, tvb, offset, 4, FALSE);
620         offset += 4;
621         proto_tree_add_item(tree, hf_eigrp_ip_int_bandwidth, tvb, offset, 4, FALSE);
622         offset += 4;
623         proto_tree_add_item(tree, hf_eigrp_ip_int_mtu, tvb, offset, 3, FALSE);
624         offset += 3;
625         proto_tree_add_item(tree, hf_eigrp_ip_int_hopcount, tvb, offset, 1, FALSE);
626         offset += 1;
627         proto_tree_add_item(tree, hf_eigrp_ip_int_reliability, tvb, offset, 1, FALSE);
628         offset += 1;
629         proto_tree_add_item(tree, hf_eigrp_ip_int_load, tvb, offset, 1, FALSE);
630         offset += 1;
631         proto_tree_add_item(tree, hf_eigrp_ip_int_reserved, tvb, offset, 2, FALSE);
632         offset += 2;
633
634         for (offset = 20; tvb_length_remaining(tvb, offset) > 0; offset += (1 + addr_len)) {
635                 length = tvb_get_guint8(tvb, offset);
636                 addr_len = ipv4_addr_and_mask(tvb, offset + 1, ip_addr, length);
637
638                 if (addr_len < 0) {
639                         prefixlenti = proto_tree_add_item(tree, hf_eigrp_ip_int_prefixlen, tvb, offset, 1, FALSE);
640                         proto_item_append_text(prefixlenti, " (invalid, must be <= 32)");
641                         proto_item_append_text(ti, "  [Invalid prefix length %u > 32]", length);
642                         addr_len = 4; /* assure we can exit the loop */
643                 } else {
644                         proto_tree_add_item(tree, hf_eigrp_ip_int_prefixlen, tvb, offset, 1, FALSE);
645                         offset += 1;
646                         proto_tree_add_text(tree, tvb, offset, addr_len, "Destination: %s", ip_to_str(ip_addr));
647                         proto_item_append_text (ti,"  %c   %s/%u%s", offset == 21 ? '=':',',
648                                 ip_to_str(ip_addr), length, ((tvb_get_ntohl(tvb, 4 )== 0xffffffff) ? " - Destination unreachable":""));
649                 }
650         }
651 }
652
653 static void dissect_eigrp_ip_ext(tvbuff_t *tvb, proto_tree *tree, proto_item *ti) {
654
655         guint8 ip_addr[4], length;
656         int addr_len, offset = 0;
657         proto_tree *eigrp_ip_ext_flags_tree;
658         proto_item *eigrp_ip_ext_ti, *prefixlenti;
659
660         eigrp_ip_ext_ti = ti;
661
662         tvb_memcpy(tvb, ip_addr, 0, 4);
663         proto_tree_add_item(tree, hf_eigrp_ip_ext_nexthop, tvb, offset, 4, FALSE);
664         offset += 4;
665         tvb_memcpy(tvb,ip_addr, 4, 4);
666         proto_tree_add_item(tree, hf_eigrp_ip_ext_origrouter, tvb, offset, 4, FALSE);
667         offset += 4;
668         proto_tree_add_item(tree, hf_eigrp_ip_ext_as, tvb, offset, 4, FALSE);
669         offset += 4;
670         proto_tree_add_item(tree, hf_eigrp_ip_ext_tag, tvb, offset, 4, FALSE);
671         offset += 4;
672         proto_tree_add_item(tree, hf_eigrp_ip_ext_metric, tvb, offset, 4, FALSE);
673         offset += 4;
674         proto_tree_add_item(tree, hf_eigrp_ip_ext_reserved, tvb, offset, 2, FALSE);
675         offset += 2;
676         proto_tree_add_item(tree, hf_eigrp_ip_ext_proto, tvb, offset, 1, FALSE);
677         offset += 1;
678
679 /* Decode the IP external route Flags Field */
680         ti = proto_tree_add_item(tree, hf_eigrp_ip_ext_flags, tvb, offset, 1, FALSE);
681         eigrp_ip_ext_flags_tree = proto_item_add_subtree(ti, ett_eigrp_ip_ext_flags);
682
683         proto_tree_add_item(eigrp_ip_ext_flags_tree, hf_eigrp_ip_ext_flags_ext, tvb, 0, 1, FALSE);
684         proto_tree_add_item(eigrp_ip_ext_flags_tree, hf_eigrp_ip_ext_flags_default, tvb, 0, 1, FALSE);
685         offset += 1;
686 /* End Decode the IP external route Flags Field */
687
688         proto_tree_add_item(tree, hf_eigrp_ip_ext_delay, tvb, offset, 4, FALSE);
689         offset += 4;
690         proto_tree_add_item(tree, hf_eigrp_ip_ext_bandwidth, tvb, offset, 4, FALSE);
691         offset += 4;
692         proto_tree_add_item(tree, hf_eigrp_ip_ext_mtu, tvb, offset, 3, FALSE);
693         offset += 3;
694         proto_tree_add_item(tree, hf_eigrp_ip_ext_hopcount, tvb, offset, 1, FALSE);
695         offset += 1;
696         proto_tree_add_item(tree, hf_eigrp_ip_ext_reliability, tvb, offset, 1, FALSE);
697         offset += 1;
698         proto_tree_add_item(tree, hf_eigrp_ip_ext_load, tvb, offset, 1, FALSE);
699         offset += 1;
700         proto_tree_add_item(tree, hf_eigrp_ip_ext_reserved2, tvb, offset, 2, FALSE);
701         offset += 2;
702
703         for (offset = 40; tvb_length_remaining(tvb, offset) > 0; offset += (1 + addr_len)) {
704                 length = tvb_get_guint8(tvb, offset);
705                 addr_len = ipv4_addr_and_mask(tvb, offset + 1, ip_addr, length);
706
707                 if (addr_len < 0) {
708                         prefixlenti = proto_tree_add_item(tree, hf_eigrp_ip_ext_prefixlen, tvb, offset, 1, FALSE);
709                         proto_item_append_text(prefixlenti, " (invalid, must be <= 32)");
710                         proto_item_append_text(ti,"  [Invalid prefix length %u > 32]", length);
711                         addr_len = 4; /* assure we can exit the loop */
712                 } else {
713                         proto_tree_add_item(tree, hf_eigrp_ip_ext_prefixlen, tvb, offset, 1, FALSE);
714                         offset += 1;
715                         proto_tree_add_text(tree, tvb, offset, addr_len, "Destination = %s", ip_to_str(ip_addr));
716                         proto_item_append_text(eigrp_ip_ext_ti, "  %c   %s/%u%s", offset == 41 ? '=':',',
717                                 ip_to_str(ip_addr), length, ((tvb_get_ntohl(tvb, 24) == 0xffffffff) ? " - Destination unreachable":""));
718                 }
719         }
720 }
721
722
723
724 static void dissect_eigrp_ipx_int(tvbuff_t *tvb, proto_tree *tree, proto_item *ti) {
725
726         int offset = 0;
727
728         proto_tree_add_text(tree, tvb, offset, 4, "Next Hop Address = %08x", tvb_get_ntohl(tvb, 4));
729         offset += 4;
730         proto_tree_add_text(tree, tvb, offset, 6, "Next Hop ID      = %04x:%04x:%04x", tvb_get_ntohs(tvb, 4), tvb_get_ntohs(tvb, 6), tvb_get_ntohs(tvb, 8));
731         offset += 6;
732         proto_tree_add_item(tree, hf_eigrp_ipx_int_delay, tvb, offset, 4, FALSE);
733         offset += 4;
734         proto_tree_add_item(tree, hf_eigrp_ipx_int_bandwidth, tvb, offset, 4, FALSE);
735         offset += 4;
736         proto_tree_add_item(tree, hf_eigrp_ipx_int_mtu, tvb, offset, 3, FALSE);
737         offset += 3;
738         proto_tree_add_item(tree, hf_eigrp_ipx_int_hopcount, tvb, offset, 1, FALSE);
739         offset += 1;
740         proto_tree_add_item(tree, hf_eigrp_ipx_int_reliability, tvb, offset, 1, FALSE);
741         offset += 1;
742         proto_tree_add_item(tree, hf_eigrp_ipx_int_load, tvb, offset, 1, FALSE);
743         offset += 1;
744         proto_tree_add_item(tree, hf_eigrp_ipx_int_reserved, tvb, offset, 2, FALSE);
745         offset += 2;
746         proto_tree_add_text(tree, tvb, offset, 4, "Destination Address =  %08x", tvb_get_ntohl(tvb, 26));
747         proto_item_append_text(ti, "  =   %08x%s", tvb_get_ntohl(tvb, 26), ((tvb_get_ntohl(tvb, 10) == 0xffffffff) ? " - Destination unreachable":""));
748 }
749
750 static void dissect_eigrp_ipx_ext(tvbuff_t *tvb, proto_tree *tree, proto_item *ti) {
751
752         int offset = 0;
753
754         proto_tree_add_text(tree, tvb, offset, 4, "Next Hop Address = %08x", tvb_get_ntohl(tvb, 4));
755         offset += 4;
756         proto_tree_add_text(tree, tvb, offset, 6, "Next Hop ID      = %04x:%04x:%04x", tvb_get_ntohs(tvb, 4), tvb_get_ntohs(tvb, 6), tvb_get_ntohs(tvb, 8));
757         offset += 6;
758
759         proto_tree_add_text(tree, tvb, offset, 6, "Originating router ID = %04x:%04x:%04x", tvb_get_ntohs(tvb, 10), tvb_get_ntohs(tvb, 12), tvb_get_ntohs(tvb, 14));
760         offset += 6;
761         proto_tree_add_item(tree, hf_eigrp_ipx_ext_as, tvb, offset, 4, FALSE);
762         offset += 4;
763         proto_tree_add_item(tree, hf_eigrp_ipx_ext_tag, tvb, offset, 4, FALSE);
764         offset += 4;
765         proto_tree_add_item(tree, hf_eigrp_ipx_ext_proto, tvb, offset, 1, FALSE);
766         offset += 1;
767         proto_tree_add_item(tree, hf_eigrp_ipx_ext_reserved, tvb, offset, 1, FALSE);
768         offset += 1;
769         proto_tree_add_item(tree, hf_eigrp_ipx_ext_metric, tvb, offset, 2, FALSE);
770         offset += 2;
771         proto_tree_add_item(tree, hf_eigrp_ipx_ext_extdelay, tvb, offset, 2, FALSE);
772         offset += 2;
773
774         proto_tree_add_item(tree, hf_eigrp_ipx_ext_delay, tvb, offset, 4, FALSE);
775         offset += 4;
776         proto_tree_add_item(tree, hf_eigrp_ipx_ext_bandwidth, tvb, offset, 4, FALSE);
777         offset += 4;
778         proto_tree_add_item(tree, hf_eigrp_ipx_ext_mtu, tvb, offset, 3, FALSE);
779         offset += 3;
780         proto_tree_add_item(tree, hf_eigrp_ipx_ext_hopcount, tvb, offset, 1, FALSE);
781         offset += 1;
782         proto_tree_add_item(tree, hf_eigrp_ipx_ext_reliability, tvb, offset, 1, FALSE);
783         offset += 1;
784         proto_tree_add_item(tree, hf_eigrp_ipx_ext_load, tvb, offset, 1, FALSE);
785         offset += 1;
786         proto_tree_add_item(tree, hf_eigrp_ipx_ext_reserved2, tvb, offset, 2, FALSE);
787         offset += 2;
788         proto_tree_add_text(tree, tvb, offset, 4, "Destination Address =  %08x", tvb_get_ntohl(tvb, 46));
789         proto_item_append_text(ti, "  =   %08x%s", tvb_get_ntohl(tvb, 46), ((tvb_get_ntohl(tvb, 30) == 0xffffffff) ? " - Destination unreachable":""));
790 }
791
792
793
794 static void dissect_eigrp_at_cbl(tvbuff_t *tvb, proto_tree *tree, proto_item *ti) {
795
796         proto_tree_add_text(tree, tvb, 0, 4, "AppleTalk Cable Range = %u-%u", tvb_get_ntohs(tvb, 0), tvb_get_ntohs(tvb, 2));
797         proto_tree_add_item(tree, hf_eigrp_at_cbl_routerid, tvb, 4, 4, FALSE);
798         proto_item_append_text(ti, ": Cable range= %u-%u, Router ID= %u", tvb_get_ntohs(tvb, 0), tvb_get_ntohs(tvb, 2), tvb_get_ntohl(tvb, 4));
799
800 }
801
802 static void dissect_eigrp_at_int(tvbuff_t *tvb, proto_tree *tree, proto_item *ti) {
803
804         int offset = 0;
805
806         proto_tree_add_text(tree, tvb, offset, 4, "Next Hop Address = %u.%u", tvb_get_ntohs(tvb, 0), tvb_get_ntohs(tvb, 2));
807         offset += 4;
808
809         proto_tree_add_item(tree, hf_eigrp_at_int_delay, tvb, offset, 4, FALSE);
810         offset += 4;
811         proto_tree_add_item(tree, hf_eigrp_at_int_bandwidth, tvb, offset, 4, FALSE);
812         offset += 4;
813         proto_tree_add_item(tree, hf_eigrp_at_int_mtu, tvb, offset, 3, FALSE);
814         offset += 3;
815         proto_tree_add_item(tree, hf_eigrp_at_int_hopcount, tvb, offset, 1, FALSE);
816         offset += 1;
817         proto_tree_add_item(tree, hf_eigrp_at_int_reliability, tvb, offset, 1, FALSE);
818         offset += 1;
819         proto_tree_add_item(tree, hf_eigrp_at_int_load, tvb, offset, 1, FALSE);
820         offset += 1;
821         proto_tree_add_item(tree, hf_eigrp_at_int_reserved, tvb, offset, 2, FALSE);
822         offset += 2;
823         proto_tree_add_text(tree,tvb,offset,4,"Cable range = %u-%u",tvb_get_ntohs(tvb,20),tvb_get_ntohs(tvb,22));
824
825         proto_item_append_text(ti, ": %u-%u", tvb_get_ntohs(tvb, 20), tvb_get_ntohs(tvb, 22));
826 }
827
828 static void dissect_eigrp_at_ext(tvbuff_t *tvb, proto_tree *tree, proto_item *ti) {
829
830         int offset = 0;
831         proto_tree *eigrp_at_ext_flags_tree;
832
833         proto_tree_add_text(tree, tvb, offset, 4, "Next Hop Address = %u.%u", tvb_get_ntohs(tvb, 0), tvb_get_ntohs(tvb, 2));
834         offset += 4;
835         proto_tree_add_item(tree, hf_eigrp_at_ext_origrouter, tvb, offset, 4, FALSE);
836         offset += 4;
837         proto_tree_add_item(tree, hf_eigrp_at_ext_as, tvb, offset, 4, FALSE);
838         offset += 4;
839         proto_tree_add_item(tree, hf_eigrp_at_ext_tag, tvb, offset, 4, FALSE);
840         offset += 4;
841         proto_tree_add_item(tree, hf_eigrp_at_ext_proto, tvb, offset, 1, FALSE);
842         offset += 1;
843
844 /* Decode the AppleTalk external route Flags Field */
845         ti = proto_tree_add_item(tree, hf_eigrp_at_ext_flags, tvb, offset, 1, FALSE);
846         eigrp_at_ext_flags_tree = proto_item_add_subtree(ti, ett_eigrp_at_ext_flags);
847
848         proto_tree_add_item(eigrp_at_ext_flags_tree, hf_eigrp_at_ext_flags_ext, tvb, 0, 1, FALSE);
849         proto_tree_add_item(eigrp_at_ext_flags_tree, hf_eigrp_at_ext_flags_default, tvb, 0, 1, FALSE);
850         offset += 1;
851 /* End Decode the AppleTalk external route Flags Field */
852
853         proto_tree_add_item(tree, hf_eigrp_at_ext_metric, tvb, offset, 2, FALSE);
854         offset += 2;
855
856         proto_tree_add_item(tree, hf_eigrp_at_ext_delay, tvb, offset, 4, FALSE);
857         offset += 4;
858         proto_tree_add_item(tree, hf_eigrp_at_ext_bandwidth, tvb, offset, 4, FALSE);
859         offset += 4;
860         proto_tree_add_item(tree, hf_eigrp_at_ext_mtu, tvb, offset, 3, FALSE);
861         offset += 3;
862         proto_tree_add_item(tree, hf_eigrp_at_ext_hopcount, tvb, offset, 1, FALSE);
863         offset += 1;
864         proto_tree_add_item(tree, hf_eigrp_at_ext_reliability, tvb, offset, 1, FALSE);
865         offset += 1;
866         proto_tree_add_item(tree, hf_eigrp_at_ext_load, tvb, offset, 1, FALSE);
867         offset += 1;
868         proto_tree_add_item(tree, hf_eigrp_at_ext_reserved, tvb, offset, 2, FALSE);
869         offset += 2;
870         proto_tree_add_text(tree, tvb, offset, 4, "Cable range = %u-%u", tvb_get_ntohs(tvb, 36), tvb_get_ntohs(tvb, 38));
871
872         proto_item_append_text(ti, ": %u-%u", tvb_get_ntohs(tvb, 36), tvb_get_ntohs(tvb, 38));
873 }
874
875 static void dissect_eigrp_ip6_int(tvbuff_t *tvb, proto_tree *tree, proto_item *ti) {
876
877         guint8 length;
878         int addr_len, offset = 0;
879         struct e_in6_addr addr;
880         proto_item *prefixlenti;
881
882         proto_tree_add_item(tree, hf_eigrp_ip6_int_nexthop, tvb, offset, 16, FALSE);
883         offset += 16;
884         proto_tree_add_item(tree, hf_eigrp_ip6_int_delay, tvb, offset, 4, FALSE);
885         offset += 4;
886         proto_tree_add_item(tree, hf_eigrp_ip6_int_bandwidth, tvb, offset, 4, FALSE);
887         offset += 4;
888         proto_tree_add_item(tree, hf_eigrp_ip6_int_mtu, tvb, offset, 3, FALSE);
889         offset += 3;
890         proto_tree_add_item(tree, hf_eigrp_ip6_int_hopcount, tvb, offset, 1, FALSE);
891         offset += 1;
892         proto_tree_add_item(tree, hf_eigrp_ip6_int_reliability, tvb, offset, 1, FALSE);
893         offset += 1;
894         proto_tree_add_item(tree, hf_eigrp_ip6_int_load, tvb, offset, 1, FALSE);
895         offset += 1;
896         proto_tree_add_item(tree, hf_eigrp_ip6_int_reserved, tvb, offset, 2, FALSE);
897         offset += 2;
898
899         for (offset = 32; tvb_length_remaining(tvb, offset) > 0; offset += (1 + addr_len)) {
900                 length = tvb_get_guint8(tvb, offset);
901                 addr_len = ipv6_addr_and_mask(tvb, offset + 1, &addr, length);
902
903                 if (addr_len < 0) {
904                         prefixlenti = proto_tree_add_item(tree, hf_eigrp_ip6_int_prefixlen, tvb, offset, 1, FALSE);
905                         proto_item_append_text(prefixlenti, " (invalid, must be <= 128)");
906                         proto_item_append_text(ti, "  [Invalid prefix length %u > 128]", length);
907                         addr_len = 16; /* assure we can exit the loop */
908                 } else {
909                         proto_tree_add_item(tree, hf_eigrp_ip6_int_prefixlen, tvb, offset, 1, FALSE);
910                         offset += 1;
911                         proto_tree_add_text(tree, tvb, offset, addr_len, "Destination: %s", ip6_to_str(&addr));
912                         proto_item_append_text(ti, "  %c   %s/%u%s", offset == 33 ? '=':',',
913                                 ip6_to_str(&addr), length, ((tvb_get_ntohl(tvb, 16) == 0xffffffff) ? " - Destination unreachable":""));
914                 }
915         }
916 }
917
918 static void dissect_eigrp_ip6_ext(tvbuff_t *tvb, proto_tree *tree, proto_item *ti) {
919
920         guint8 length;
921         int addr_len, offset = 0;
922         struct e_in6_addr addr;
923         proto_tree *eigrp_ip6_ext_flags_tree;
924         proto_item *eigrp_ip6_ext_ti, *prefixlenti;
925
926         eigrp_ip6_ext_ti = ti;
927
928         proto_tree_add_item(tree, hf_eigrp_ip6_ext_nexthop, tvb, offset, 16, FALSE);
929         offset += 16;
930         proto_tree_add_item(tree, hf_eigrp_ip6_ext_origrouter, tvb, offset, 4, FALSE);
931         offset += 4;
932         proto_tree_add_item(tree, hf_eigrp_ip6_ext_as, tvb, offset, 4, FALSE);
933         offset += 4;
934         proto_tree_add_item(tree, hf_eigrp_ip6_ext_tag, tvb, offset, 4, FALSE);
935         offset += 4;
936         proto_tree_add_item(tree, hf_eigrp_ip6_ext_metric, tvb, offset, 4, FALSE);
937         offset += 4;
938         proto_tree_add_item(tree, hf_eigrp_ip6_ext_reserved, tvb, offset, 2, FALSE);
939         offset += 2;
940         proto_tree_add_item(tree, hf_eigrp_ip6_ext_proto, tvb, offset, 1, FALSE);
941         offset += 1;
942
943 /* Decode the IPv6 external route Flags Field */
944         ti = proto_tree_add_item(tree, hf_eigrp_ip6_ext_flags, tvb, offset, 1, FALSE);
945         eigrp_ip6_ext_flags_tree = proto_item_add_subtree(ti, ett_eigrp_ip6_ext_flags);
946
947         proto_tree_add_item(eigrp_ip6_ext_flags_tree, hf_eigrp_ip6_ext_flags_ext, tvb, 0, 1, FALSE);
948         proto_tree_add_item(eigrp_ip6_ext_flags_tree, hf_eigrp_ip6_ext_flags_default, tvb, 0, 1, FALSE);
949         offset += 1;
950 /* End Decode the IPv6 external route Flags Field */
951
952         proto_tree_add_item(tree, hf_eigrp_ip6_ext_delay, tvb, offset, 4, FALSE);
953         offset += 4;
954         proto_tree_add_item(tree, hf_eigrp_ip6_ext_bandwidth, tvb, offset, 4, FALSE);
955         offset += 4;
956         proto_tree_add_item(tree, hf_eigrp_ip6_ext_mtu, tvb, offset, 3, FALSE);
957         offset += 3;
958         proto_tree_add_item(tree, hf_eigrp_ip6_ext_hopcount, tvb, offset, 1, FALSE);
959         offset += 1;
960         proto_tree_add_item(tree, hf_eigrp_ip6_ext_reliability, tvb, offset, 1, FALSE);
961         offset += 1;
962         proto_tree_add_item(tree, hf_eigrp_ip6_ext_load, tvb, offset, 1, FALSE);
963         offset += 1;
964         proto_tree_add_item(tree, hf_eigrp_ip6_ext_reserved2, tvb, offset, 2, FALSE);
965         offset += 2;
966
967         for (offset = 52; tvb_length_remaining(tvb, offset) > 0; offset += (1 + addr_len))
968         {
969                 length = tvb_get_guint8(tvb, offset);
970                 addr_len = ipv6_addr_and_mask(tvb, offset + 1, &addr, length);
971
972                 if (addr_len < 0) {
973                         prefixlenti = proto_tree_add_item(tree, hf_eigrp_ip6_int_prefixlen, tvb, offset, 1, FALSE);
974                         proto_item_append_text(prefixlenti, " (invalid, must be <= 128)");
975                         proto_item_append_text(ti, "  [Invalid prefix length %u > 128]", length);
976                         addr_len = 16; /* assure we can exit the loop */
977                 } else {
978                         proto_tree_add_item(tree, hf_eigrp_ip6_int_prefixlen, tvb, offset, 1, FALSE);
979                         offset += 1;
980                         proto_tree_add_text(tree, tvb, offset, addr_len, "Destination: %s", ip6_to_str(&addr));
981                         proto_item_append_text(eigrp_ip6_ext_ti, "  %c   %s/%u%s", offset == 53 ? '=':',',
982                                 ip6_to_str(&addr), length, ((tvb_get_ntohl(tvb, 36) == 0xffffffff) ? " - Destination unreachable":""));
983                 }
984         }
985 }
986
987
988 void proto_register_eigrp(void) {
989
990   static hf_register_info hf[] = {
991    { &hf_eigrp_version,
992     { "Version", "eigrp.version",
993      FT_UINT8, BASE_DEC, NULL, 0x0,
994      NULL, HFILL }
995      }, 
996    { &hf_eigrp_opcode,
997     { "Opcode", "eigrp.opcode",
998      FT_UINT8, BASE_DEC, VALS(eigrp_opcode_vals), 0x0,
999      "Opcode number", HFILL }
1000      },
1001    { &hf_eigrp_checksum,
1002     { "Checksum", "eigrp.checksum",
1003      FT_UINT16, BASE_HEX, NULL, 0x0,
1004      NULL, HFILL }
1005      },
1006    { &hf_eigrp_flags,
1007     { "Flags", "eigrp.flags",
1008      FT_UINT32, BASE_HEX, NULL, 0x0,
1009      NULL, HFILL }
1010      },
1011    { &hf_eigrp_flags_init,
1012     { "Init", "eigrp.flags.init",
1013      FT_BOOLEAN, 32, NULL, EIGRP_FLAGS_INIT,
1014      NULL, HFILL }
1015      },
1016    { &hf_eigrp_flags_condrecv,
1017     { "Conditional Receive", "eigrp.flags.condrecv",
1018      FT_BOOLEAN, 32, NULL, EIGRP_FLAGS_CONDRECV,
1019      NULL, HFILL }
1020      },
1021    { &hf_eigrp_sequence,
1022     { "Sequence", "eigrp.seq",
1023      FT_UINT32, BASE_DEC, NULL, 0x0,
1024      NULL, HFILL }
1025      },
1026    { &hf_eigrp_acknowledge,
1027     { "Acknowledge", "eigrp.ack",
1028      FT_UINT32, BASE_DEC, NULL, 0x0,
1029      NULL, HFILL }
1030      },
1031    { &hf_eigrp_as,
1032     { "Autonomous System", "eigrp.as",
1033       FT_UINT16, BASE_DEC, NULL, 0x0,
1034      "Autonomous System number", HFILL }
1035     },
1036    { &hf_eigrp_tlv,
1037     { "Type",           "eigrp.tlv",
1038       FT_UINT16, BASE_DEC, VALS(eigrp_tlv_vals), 0x0,
1039      "Type/Length/Value", HFILL }
1040     },
1041    { &hf_eigrp_tlv_size,
1042     { "Size", "eigrp.tlv.size",
1043       FT_UINT16, BASE_DEC, NULL, 0x0,
1044      "TLV size", HFILL }
1045     },
1046 /* EIGRP Parameters TLV */
1047    { &hf_eigrp_par_k1,
1048     { "K1", "eigrp.par.k1",
1049      FT_UINT8, BASE_DEC, NULL, 0x0,
1050      NULL, HFILL }
1051     }, 
1052    { &hf_eigrp_par_k2,
1053     { "K2", "eigrp.par.k2",
1054      FT_UINT8, BASE_DEC, NULL, 0x0,
1055      NULL, HFILL }
1056     }, 
1057    { &hf_eigrp_par_k3,
1058     { "K3", "eigrp.par.k3",
1059      FT_UINT8, BASE_DEC, NULL, 0x0,
1060      NULL, HFILL }
1061     }, 
1062    { &hf_eigrp_par_k4,
1063     { "K4", "eigrp.par.k4",
1064      FT_UINT8, BASE_DEC, NULL, 0x0,
1065      NULL, HFILL }
1066     }, 
1067    { &hf_eigrp_par_k5,
1068     { "K5", "eigrp.par.k5",
1069      FT_UINT8, BASE_DEC, NULL, 0x0,
1070      NULL, HFILL }
1071     }, 
1072    { &hf_eigrp_par_reserved,
1073     { "Reserved", "eigrp.par.reserved",
1074      FT_UINT8, BASE_DEC, NULL, 0x0,
1075      NULL, HFILL }
1076     }, 
1077    { &hf_eigrp_par_holdtime,
1078     { "Hold Time", "eigrp.par.holdtime",
1079      FT_UINT16, BASE_DEC, NULL, 0x0,
1080      NULL, HFILL }
1081      },
1082 /* Authentication TLV */
1083    { &hf_eigrp_auth_type,
1084     { "Authentication Type", "eigrp.auth.type",
1085      FT_UINT16, BASE_DEC, VALS(eigrp_auth_type_vals), 0x0,
1086      NULL, HFILL }
1087     },
1088    { &hf_eigrp_auth_keysize,
1089     { "Key size", "eigrp.auth.keysize",
1090      FT_UINT16, BASE_DEC, NULL, 0x0,
1091      NULL, HFILL }
1092     },
1093    { &hf_eigrp_auth_keyid,
1094     { "Key ID", "eigrp.auth.keyid",
1095      FT_UINT32, BASE_DEC, NULL, 0x0,
1096      NULL, HFILL }
1097     },
1098    { &hf_eigrp_auth_nullpad,
1099     { "Nullpad", "eigrp.auth.nullapd",
1100      FT_STRING, BASE_NONE, NULL, 0x0,
1101      NULL, HFILL }
1102     },
1103    { &hf_eigrp_auth_data,
1104     { "Data", "eigrp.auth.data",
1105      FT_STRING, BASE_NONE, NULL, 0x0,
1106      NULL, HFILL }
1107     },
1108 /* Sequence TLV */
1109    { &hf_eigrp_seq_addrlen,
1110     { "Address length", "eigrp.seq.addrlen",
1111      FT_UINT8, BASE_DEC, NULL, 0x0,
1112      NULL, HFILL }
1113     }, 
1114    { &hf_eigrp_seq_ipaddr,
1115     { "IP Address", "eigrp.seq.ipaddr",
1116      FT_IPv4, BASE_NONE, NULL, 0x0,
1117      NULL, HFILL }
1118     }, 
1119    { &hf_eigrp_seq_ip6addr,
1120     { "IPv6 Address", "eigrp.seq.ip6addr",
1121      FT_IPv6, BASE_NONE, NULL, 0x0,
1122      NULL, HFILL }
1123     }, 
1124 /* Software Version TLV */
1125    { &hf_eigrp_sv_ios,
1126     { "IOS release version", "eigrp.sv.ios",
1127      FT_STRING, BASE_NONE, NULL, 0x0,
1128      NULL, HFILL }
1129     }, 
1130    { &hf_eigrp_sv_eigrp,
1131     { "EIGRP release version", "eigrp.sv.eigrp",
1132      FT_STRING, BASE_NONE, NULL, 0x0,
1133      NULL, HFILL }
1134     }, 
1135 /* Next multicast sequence TLV */
1136    { &hf_eigrp_nms,
1137     { "Next Multicast Sequence", "eigrp.nms",
1138      FT_UINT32, BASE_DEC, NULL, 0x0,
1139      NULL, HFILL }
1140      },
1141 /* Stub routing TLV */
1142    { &hf_eigrp_stub_flags,
1143     { "Stub Flags", "eigrp.stub_flags",
1144      FT_UINT16, BASE_HEX, NULL, 0x0,
1145      NULL, HFILL }
1146      },
1147    { &hf_eigrp_stub_flags_connected,
1148     { "Connected", "eigrp.stub_flags.connected",
1149      FT_BOOLEAN, 16, NULL, EIGRP_STUB_FLAGS_CONNECTED,
1150      NULL, HFILL }
1151      },
1152    { &hf_eigrp_stub_flags_static,
1153     { "Static", "eigrp.stub_flags.static",
1154      FT_BOOLEAN, 16, NULL, EIGRP_STUB_FLAGS_STATIC,
1155      NULL, HFILL }
1156      },
1157    { &hf_eigrp_stub_flags_summary,
1158     { "Summary", "eigrp.stub_flags.summary",
1159      FT_BOOLEAN, 16, NULL, EIGRP_STUB_FLAGS_SUMMARY,
1160      NULL, HFILL }
1161      },
1162    { &hf_eigrp_stub_flags_recvonly,
1163     { "Receive-Only", "eigrp.stub_flags.recvonly",
1164      FT_BOOLEAN, 16, NULL, EIGRP_STUB_FLAGS_RECVONLY,
1165      NULL, HFILL }
1166      },
1167    { &hf_eigrp_stub_flags_redist,
1168     { "Redistributed", "eigrp.stub_flags.redist",
1169      FT_BOOLEAN, 16, NULL, EIGRP_STUB_FLAGS_REDIST,
1170      NULL, HFILL }
1171      },
1172    { &hf_eigrp_stub_flags_leakmap,
1173     { "Leak-Map", "eigrp.stub_flags.leakmap",
1174      FT_BOOLEAN, 16, NULL, EIGRP_STUB_FLAGS_LEAKMAP,
1175      NULL, HFILL }
1176      },
1177 /* IP internal route TLV */
1178    { &hf_eigrp_ip_int_nexthop,
1179     { "Next Hop", "eigrp.ip_int.nexthop",
1180      FT_IPv4, BASE_NONE, NULL, 0x0,
1181      NULL, HFILL }
1182     }, 
1183    { &hf_eigrp_ip_int_delay,
1184     { "Delay", "eigrp.ip_int.delay",
1185      FT_UINT32, BASE_DEC, NULL, 0x0,
1186      NULL, HFILL }
1187     }, 
1188    { &hf_eigrp_ip_int_bandwidth,
1189     { "Bandwidth", "eigrp.ip_int.bandwidth",
1190      FT_UINT32, BASE_DEC, NULL, 0x0,
1191      NULL, HFILL }
1192     }, 
1193    { &hf_eigrp_ip_int_mtu,
1194     { "MTU", "eigrp.ip_int.mtu",
1195      FT_UINT24, BASE_DEC, NULL, 0x0,
1196      NULL, HFILL }
1197     }, 
1198    { &hf_eigrp_ip_int_hopcount,
1199     { "Hop Count", "eigrp.ip_int.hopcount",
1200      FT_UINT8, BASE_DEC, NULL, 0x0,
1201      NULL, HFILL }
1202     }, 
1203    { &hf_eigrp_ip_int_reliability,
1204     { "Reliability", "eigrp.ip_int.reliability",
1205      FT_UINT8, BASE_DEC, NULL, 0x0,
1206      NULL, HFILL }
1207     }, 
1208    { &hf_eigrp_ip_int_load,
1209     { "Load", "eigrp.ip_int.load",
1210      FT_UINT8, BASE_DEC, NULL, 0x0,
1211      NULL, HFILL }
1212     }, 
1213    { &hf_eigrp_ip_int_reserved,
1214     { "Reserved", "eigrp.ip_int.reserved",
1215      FT_UINT16, BASE_DEC, NULL, 0x0,
1216      NULL, HFILL }
1217     }, 
1218    { &hf_eigrp_ip_int_prefixlen,
1219     { "Prefix Length", "eigrp.ip_int.prefixlen",
1220      FT_UINT8, BASE_DEC, NULL, 0x0,
1221      NULL, HFILL }
1222     }, 
1223    { &hf_eigrp_ip_int_dst,
1224     { "Destination", "eigrp.ip_int.dst",
1225      FT_STRING, BASE_NONE, NULL, 0x0,
1226      NULL, HFILL }
1227     }, 
1228 /* IP external route TLV */
1229    { &hf_eigrp_ip_ext_nexthop,
1230     { "Next Hop", "eigrp.ip_ext.nexthop",
1231      FT_IPv4, BASE_NONE, NULL, 0x0,
1232      NULL, HFILL }
1233     },
1234    { &hf_eigrp_ip_ext_origrouter,
1235     { "Originating router", "eigrp.ip_ext.origrouter",
1236      FT_IPv4, BASE_NONE, NULL, 0x0,
1237      NULL, HFILL }
1238     },
1239    { &hf_eigrp_ip_ext_as,
1240     { "Originating A.S.", "eigrp.ip_ext.as",
1241      FT_UINT32, BASE_DEC, NULL, 0x0,
1242      NULL, HFILL }
1243     }, 
1244    { &hf_eigrp_ip_ext_tag,
1245     { "Arbitrary tag", "eigrp.ip_ext.tag",
1246      FT_UINT32, BASE_DEC, NULL, 0x0,
1247      NULL, HFILL }
1248     }, 
1249    { &hf_eigrp_ip_ext_metric,
1250     { "External protocol metric", "eigrp.ip_ext.metric",
1251      FT_UINT32, BASE_DEC, NULL, 0x0,
1252      NULL, HFILL }
1253     }, 
1254    { &hf_eigrp_ip_ext_reserved,
1255     { "Reserved", "eigrp.ip_ext.reserved",
1256      FT_UINT16, BASE_DEC, NULL, 0x0,
1257      NULL, HFILL }
1258     }, 
1259    { &hf_eigrp_ip_ext_proto,
1260     { "External protocol ID", "eigrp.ip_ext.proto",
1261      FT_UINT8, BASE_DEC, VALS(eigrp_pid_vals), 0x0,
1262      NULL, HFILL }
1263     }, 
1264    { &hf_eigrp_ip_ext_flags,
1265     { "Flags", "eigrp.ip_ext.flags",
1266      FT_UINT8, BASE_HEX, NULL, 0x0,
1267      NULL, HFILL }
1268      },
1269    { &hf_eigrp_ip_ext_flags_ext,
1270     { "External Route", "eigrp.ip_ext.flags.ext",
1271      FT_BOOLEAN, 8, NULL, EIGRP_IP_EXT_FLAGS_EXT,
1272      NULL, HFILL }
1273      },
1274    { &hf_eigrp_ip_ext_flags_default,
1275     { "Candidate Default Route", "eigrp.ip_ext.flags.default",
1276      FT_BOOLEAN, 8, NULL, EIGRP_IP_EXT_FLAGS_DEFAULT,
1277      NULL, HFILL }
1278      },
1279    { &hf_eigrp_ip_ext_delay,
1280     { "Delay", "eigrp.ip_ext.delay",
1281      FT_UINT32, BASE_DEC, NULL, 0x0,
1282      NULL, HFILL }
1283     }, 
1284    { &hf_eigrp_ip_ext_bandwidth,
1285     { "Bandwidth", "eigrp.ip_ext.bandwidth",
1286      FT_UINT32, BASE_DEC, NULL, 0x0,
1287      NULL, HFILL }
1288     }, 
1289    { &hf_eigrp_ip_ext_mtu,
1290     { "MTU", "eigrp.ip_ext.mtu",
1291      FT_UINT24, BASE_DEC, NULL, 0x0,
1292      NULL, HFILL }
1293     }, 
1294    { &hf_eigrp_ip_ext_hopcount,
1295     { "Hop Count", "eigrp.ip_ext.hopcount",
1296      FT_UINT8, BASE_DEC, NULL, 0x0,
1297      NULL, HFILL }
1298     }, 
1299    { &hf_eigrp_ip_ext_reliability,
1300     { "Reliability", "eigrp.ip_ext.reliability",
1301      FT_UINT8, BASE_DEC, NULL, 0x0,
1302      NULL, HFILL }
1303     }, 
1304    { &hf_eigrp_ip_ext_load,
1305     { "Load", "eigrp.ip_ext.load",
1306      FT_UINT8, BASE_DEC, NULL, 0x0,
1307      NULL, HFILL }
1308     }, 
1309    { &hf_eigrp_ip_ext_reserved2,
1310     { "Reserved", "eigrp.ip_ext.reserved2",
1311      FT_UINT16, BASE_DEC, NULL, 0x0,
1312      NULL, HFILL }
1313     }, 
1314    { &hf_eigrp_ip_ext_prefixlen,
1315     { "Prefix Length", "eigrp.ip_ext.prefixlen",
1316      FT_UINT8, BASE_DEC, NULL, 0x0,
1317      NULL, HFILL }
1318     }, 
1319 /* IPX internal route TLV */
1320    { &hf_eigrp_ipx_int_delay,
1321     { "Delay", "eigrp.ipx_int.delay",
1322      FT_UINT32, BASE_DEC, NULL, 0x0,
1323      NULL, HFILL }
1324     }, 
1325    { &hf_eigrp_ipx_int_bandwidth,
1326     { "Bandwidth", "eigrp.ipx_int.bandwidth",
1327      FT_UINT32, BASE_DEC, NULL, 0x0,
1328      NULL, HFILL }
1329     }, 
1330    { &hf_eigrp_ipx_int_mtu,
1331     { "MTU", "eigrp.ipx_int.mtu",
1332      FT_UINT24, BASE_DEC, NULL, 0x0,
1333      NULL, HFILL }
1334     }, 
1335    { &hf_eigrp_ipx_int_hopcount,
1336     { "Hop Count", "eigrp.ipx_int.hopcount",
1337      FT_UINT8, BASE_DEC, NULL, 0x0,
1338      NULL, HFILL }
1339     }, 
1340    { &hf_eigrp_ipx_int_reliability,
1341     { "Reliability", "eigrp.ipx_int.reliability",
1342      FT_UINT8, BASE_DEC, NULL, 0x0,
1343      NULL, HFILL }
1344     }, 
1345    { &hf_eigrp_ipx_int_load,
1346     { "Load", "eigrp.ipx_int.load",
1347      FT_UINT8, BASE_DEC, NULL, 0x0,
1348      NULL, HFILL }
1349     }, 
1350    { &hf_eigrp_ipx_int_reserved,
1351     { "Reserved", "eigrp.ipx_int.reserved",
1352      FT_UINT16, BASE_DEC, NULL, 0x0,
1353      NULL, HFILL }
1354     }, 
1355 /* IPX external route TLV */
1356    { &hf_eigrp_ipx_ext_as,
1357     { "Originating A.S.", "eigrp.ipx_ext.as",
1358      FT_UINT32, BASE_DEC, NULL, 0x0,
1359      NULL, HFILL }
1360     }, 
1361    { &hf_eigrp_ipx_ext_tag,
1362     { "Arbitrary tag", "eigrp.ipx_ext.tag",
1363      FT_UINT32, BASE_DEC, NULL, 0x0,
1364      NULL, HFILL }
1365     }, 
1366    { &hf_eigrp_ipx_ext_proto,
1367     { "External protocol ID", "eigrp.ipx_ext.proto",
1368      FT_UINT8, BASE_DEC, VALS(eigrp_pid_vals), 0x0,
1369      NULL, HFILL }
1370     }, 
1371    { &hf_eigrp_ipx_ext_reserved,
1372     { "Reserved", "eigrp.ipx_ext.reserved",
1373      FT_UINT8, BASE_DEC, NULL, 0x0,
1374      NULL, HFILL }
1375     }, 
1376    { &hf_eigrp_ipx_ext_metric,
1377     { "External protocol metric", "eigrp.ipx_ext.metric",
1378      FT_UINT16, BASE_DEC, NULL, 0x0,
1379      NULL, HFILL }
1380     }, 
1381    { &hf_eigrp_ipx_ext_extdelay,
1382     { "External protocol delay", "eigrp.ipx_ext.extdelay",
1383      FT_UINT16, BASE_DEC, NULL, 0x0,
1384      NULL, HFILL }
1385     }, 
1386    { &hf_eigrp_ipx_ext_delay,
1387     { "Delay", "eigrp.ipx_ext.delay",
1388      FT_UINT32, BASE_DEC, NULL, 0x0,
1389      NULL, HFILL }
1390     }, 
1391    { &hf_eigrp_ipx_ext_bandwidth,
1392     { "Bandwidth", "eigrp.ipx_ext.bandwidth",
1393      FT_UINT32, BASE_DEC, NULL, 0x0,
1394      NULL, HFILL }
1395     }, 
1396    { &hf_eigrp_ipx_ext_mtu,
1397     { "MTU", "eigrp.ipx_ext.mtu",
1398      FT_UINT24, BASE_DEC, NULL, 0x0,
1399      NULL, HFILL }
1400     }, 
1401    { &hf_eigrp_ipx_ext_hopcount,
1402     { "Hop Count", "eigrp.ipx_ext.hopcount",
1403      FT_UINT8, BASE_DEC, NULL, 0x0,
1404      NULL, HFILL }
1405     }, 
1406    { &hf_eigrp_ipx_ext_reliability,
1407     { "Reliability", "eigrp.ipx_ext.reliability",
1408      FT_UINT8, BASE_DEC, NULL, 0x0,
1409      NULL, HFILL }
1410     }, 
1411    { &hf_eigrp_ipx_ext_load,
1412     { "Load", "eigrp.ipx_ext.load",
1413      FT_UINT8, BASE_DEC, NULL, 0x0,
1414      NULL, HFILL }
1415     }, 
1416    { &hf_eigrp_ipx_ext_reserved2,
1417     { "Reserved", "eigrp.ipx_ext.reserved2",
1418      FT_UINT16, BASE_DEC, NULL, 0x0,
1419      NULL, HFILL }
1420     }, 
1421 /* AppleTalk cable configuration TLV */
1422    { &hf_eigrp_at_cbl_routerid,
1423     { "AppleTalk Router ID", "eigrp.at_cbl.routerid",
1424      FT_UINT32, BASE_DEC, NULL, 0x0,
1425      NULL, HFILL }
1426     },
1427 /* AppleTalk internal route TLV */
1428    { &hf_eigrp_at_int_delay,
1429     { "Delay", "eigrp.at_int.delay",
1430      FT_UINT32, BASE_DEC, NULL, 0x0,
1431      NULL, HFILL }
1432     }, 
1433    { &hf_eigrp_at_int_bandwidth,
1434     { "Bandwidth", "eigrp.at_int.bandwidth",
1435      FT_UINT32, BASE_DEC, NULL, 0x0,
1436      NULL, HFILL }
1437     }, 
1438    { &hf_eigrp_at_int_mtu,
1439     { "MTU", "eigrp.at_int.mtu",
1440      FT_UINT24, BASE_DEC, NULL, 0x0,
1441      NULL, HFILL }
1442     }, 
1443    { &hf_eigrp_at_int_hopcount,
1444     { "Hop Count", "eigrp.at_int.hopcount",
1445      FT_UINT8, BASE_DEC, NULL, 0x0,
1446      NULL, HFILL }
1447     }, 
1448    { &hf_eigrp_at_int_reliability,
1449     { "Reliability", "eigrp.at_int.reliability",
1450      FT_UINT8, BASE_DEC, NULL, 0x0,
1451      NULL, HFILL }
1452     }, 
1453    { &hf_eigrp_at_int_load,
1454     { "Load", "eigrp.at_int.load",
1455      FT_UINT8, BASE_DEC, NULL, 0x0,
1456      NULL, HFILL }
1457     }, 
1458    { &hf_eigrp_at_int_reserved,
1459     { "Reserved", "eigrp.at_int.reserved",
1460      FT_UINT16, BASE_DEC, NULL, 0x0,
1461      NULL, HFILL }
1462     }, 
1463 /* AppleTalk external route TLV */
1464    { &hf_eigrp_at_ext_origrouter,
1465     { "Originating router", "eigrp.at_ext.origrouter",
1466      FT_UINT32, BASE_DEC, NULL, 0x0,
1467      NULL, HFILL }
1468     },
1469    { &hf_eigrp_at_ext_as,
1470     { "Originating A.S.", "eigrp.at_ext.as",
1471      FT_UINT32, BASE_DEC, NULL, 0x0,
1472      NULL, HFILL }
1473     }, 
1474    { &hf_eigrp_at_ext_tag,
1475     { "Arbitrary tag", "eigrp.at_ext.tag",
1476      FT_UINT32, BASE_DEC, NULL, 0x0,
1477      NULL, HFILL }
1478     }, 
1479    { &hf_eigrp_at_ext_proto,
1480     { "External protocol ID", "eigrp.at_ext.proto",
1481      FT_UINT8, BASE_DEC, VALS(eigrp_pid_vals), 0x0,
1482      NULL, HFILL }
1483     }, 
1484    { &hf_eigrp_at_ext_flags,
1485     { "Flags", "eigrp.at_ext.flags",
1486      FT_UINT8, BASE_HEX, NULL, 0x0,
1487      NULL, HFILL }
1488      },
1489    { &hf_eigrp_at_ext_flags_ext,
1490     { "External Route", "eigrp.at_ext.flags.ext",
1491      FT_BOOLEAN, 8, NULL, EIGRP_IP_EXT_FLAGS_EXT,
1492      NULL, HFILL }
1493      },
1494    { &hf_eigrp_at_ext_flags_default,
1495     { "Candidate Default Route", "eigrp.at_ext.flags.default",
1496      FT_BOOLEAN, 8, NULL, EIGRP_IP_EXT_FLAGS_DEFAULT,
1497      NULL, HFILL }
1498      },
1499    { &hf_eigrp_at_ext_metric,
1500     { "External protocol metric", "eigrp.at_ext.metric",
1501      FT_UINT16, BASE_DEC, NULL, 0x0,
1502      NULL, HFILL }
1503     }, 
1504    { &hf_eigrp_at_ext_delay,
1505     { "Delay", "eigrp.at_ext.delay",
1506      FT_UINT32, BASE_DEC, NULL, 0x0,
1507      NULL, HFILL }
1508     }, 
1509    { &hf_eigrp_at_ext_bandwidth,
1510     { "Bandwidth", "eigrp.at_ext.bandwidth",
1511      FT_UINT32, BASE_DEC, NULL, 0x0,
1512      NULL, HFILL }
1513     }, 
1514    { &hf_eigrp_at_ext_mtu,
1515     { "MTU", "eigrp.at_ext.mtu",
1516      FT_UINT24, BASE_DEC, NULL, 0x0,
1517      NULL, HFILL }
1518     }, 
1519    { &hf_eigrp_at_ext_hopcount,
1520     { "Hop Count", "eigrp.at_ext.hopcount",
1521      FT_UINT8, BASE_DEC, NULL, 0x0,
1522      NULL, HFILL }
1523     }, 
1524    { &hf_eigrp_at_ext_reliability,
1525     { "Reliability", "eigrp.at_ext.reliability",
1526      FT_UINT8, BASE_DEC, NULL, 0x0,
1527      NULL, HFILL }
1528     }, 
1529    { &hf_eigrp_at_ext_load,
1530     { "Load", "eigrp.at_ext.load",
1531      FT_UINT8, BASE_DEC, NULL, 0x0,
1532      NULL, HFILL }
1533     }, 
1534    { &hf_eigrp_at_ext_reserved,
1535     { "Reserved", "eigrp.at_ext.reserved",
1536      FT_UINT16, BASE_DEC, NULL, 0x0,
1537      NULL, HFILL }
1538     }, 
1539 /* IPv6 internal route TLV */
1540    { &hf_eigrp_ip6_int_nexthop,
1541     { "Next Hop", "eigrp.ip6_int.nexthop",
1542      FT_IPv6, BASE_NONE, NULL, 0x0,
1543      NULL, HFILL }
1544     },
1545    { &hf_eigrp_ip6_int_delay,
1546     { "Delay", "eigrp.ip6_int.delay",
1547      FT_UINT32, BASE_DEC, NULL, 0x0,
1548      NULL, HFILL }
1549     }, 
1550    { &hf_eigrp_ip6_int_bandwidth,
1551     { "Bandwidth", "eigrp.ip6_int.bandwidth",
1552      FT_UINT32, BASE_DEC, NULL, 0x0,
1553      NULL, HFILL }
1554     }, 
1555    { &hf_eigrp_ip6_int_mtu,
1556     { "MTU", "eigrp.ip6_int.mtu",
1557      FT_UINT24, BASE_DEC, NULL, 0x0,
1558      NULL, HFILL }
1559     }, 
1560    { &hf_eigrp_ip6_int_hopcount,
1561     { "Hop Count", "eigrp.ip6_int.hopcount",
1562      FT_UINT8, BASE_DEC, NULL, 0x0,
1563      NULL, HFILL }
1564     }, 
1565    { &hf_eigrp_ip6_int_reliability,
1566     { "Reliability", "eigrp.ip6_int.reliability",
1567      FT_UINT8, BASE_DEC, NULL, 0x0,
1568      NULL, HFILL }
1569     }, 
1570    { &hf_eigrp_ip6_int_load,
1571     { "Load", "eigrp.ip6_int.load",
1572      FT_UINT8, BASE_DEC, NULL, 0x0,
1573      NULL, HFILL }
1574     }, 
1575    { &hf_eigrp_ip6_int_reserved,
1576     { "Reserved", "eigrp.ip6_int.reserved",
1577      FT_UINT16, BASE_DEC, NULL, 0x0,
1578      NULL, HFILL }
1579     }, 
1580    { &hf_eigrp_ip6_int_prefixlen,
1581     { "Prefix Length", "eigrp.ip6_int.prefixlen",
1582      FT_UINT8, BASE_DEC, NULL, 0x0,
1583      NULL, HFILL }
1584     }, 
1585 /* IPv6 external route TLV */
1586    { &hf_eigrp_ip6_ext_nexthop,
1587     { "Next Hop", "eigrp.ip6_ext.nexthop",
1588      FT_IPv6, BASE_NONE, NULL, 0x0,
1589      NULL, HFILL }
1590     },
1591    { &hf_eigrp_ip6_ext_origrouter,
1592     { "Originating router", "eigrp.ip6_ext.origrouter",
1593      FT_IPv4, BASE_NONE, NULL, 0x0,
1594      NULL, HFILL }
1595     },
1596    { &hf_eigrp_ip6_ext_as,
1597     { "Originating A.S.", "eigrp.ip6_ext.as",
1598      FT_UINT32, BASE_DEC, NULL, 0x0,
1599      NULL, HFILL }
1600     }, 
1601    { &hf_eigrp_ip6_ext_tag,
1602     { "Arbitrary tag", "eigrp.ip6_ext.tag",
1603      FT_UINT32, BASE_DEC, NULL, 0x0,
1604      NULL, HFILL }
1605     }, 
1606    { &hf_eigrp_ip6_ext_metric,
1607     { "External protocol metric", "eigrp.ip6_ext.metric",
1608      FT_UINT32, BASE_DEC, NULL, 0x0,
1609      NULL, HFILL }
1610     }, 
1611    { &hf_eigrp_ip6_ext_reserved,
1612     { "Reserved", "eigrp.ip6_ext.reserved",
1613      FT_UINT16, BASE_DEC, NULL, 0x0,
1614      NULL, HFILL }
1615     }, 
1616    { &hf_eigrp_ip6_ext_proto,
1617     { "External protocol ID", "eigrp.ip6_ext.proto",
1618      FT_UINT8, BASE_DEC, VALS(eigrp_pid_vals), 0x0,
1619      NULL, HFILL }
1620     }, 
1621    { &hf_eigrp_ip6_ext_flags,
1622     { "Flags", "eigrp.ip6_ext.flags",
1623      FT_UINT8, BASE_HEX, NULL, 0x0,
1624      NULL, HFILL }
1625      },
1626    { &hf_eigrp_ip6_ext_flags_ext,
1627     { "External Route", "eigrp.ip6_ext.flags.ext",
1628      FT_BOOLEAN, 8, NULL, EIGRP_IP_EXT_FLAGS_EXT,
1629      NULL, HFILL }
1630      },
1631    { &hf_eigrp_ip6_ext_flags_default,
1632     { "Candidate Default Route", "eigrp.ip6_ext.flags.default",
1633      FT_BOOLEAN, 8, NULL, EIGRP_IP_EXT_FLAGS_DEFAULT,
1634      NULL, HFILL }
1635      },
1636    { &hf_eigrp_ip6_ext_delay,
1637     { "Delay", "eigrp.ip6_ext.delay",
1638      FT_UINT32, BASE_DEC, NULL, 0x0,
1639      NULL, HFILL }
1640     }, 
1641    { &hf_eigrp_ip6_ext_bandwidth,
1642     { "Bandwidth", "eigrp.ip6_ext.bandwidth",
1643      FT_UINT32, BASE_DEC, NULL, 0x0,
1644      NULL, HFILL }
1645     }, 
1646    { &hf_eigrp_ip6_ext_mtu,
1647     { "MTU", "eigrp.ip6_ext.mtu",
1648      FT_UINT24, BASE_DEC, NULL, 0x0,
1649      NULL, HFILL }
1650     }, 
1651    { &hf_eigrp_ip6_ext_hopcount,
1652     { "Hop Count", "eigrp.ip6_ext.hopcount",
1653      FT_UINT8, BASE_DEC, NULL, 0x0,
1654      NULL, HFILL }
1655     }, 
1656    { &hf_eigrp_ip6_ext_reliability,
1657     { "Reliability", "eigrp.ip6_ext.reliability",
1658      FT_UINT8, BASE_DEC, NULL, 0x0,
1659      NULL, HFILL }
1660     }, 
1661    { &hf_eigrp_ip6_ext_load,
1662     { "Load", "eigrp.ip6_ext.load",
1663      FT_UINT8, BASE_DEC, NULL, 0x0,
1664      NULL, HFILL }
1665     }, 
1666    { &hf_eigrp_ip6_ext_reserved2,
1667     { "Reserved", "eigrp.ip6_ext.reserved2",
1668      FT_UINT16, BASE_DEC, NULL, 0x0,
1669      NULL, HFILL }
1670     }, 
1671    { &hf_eigrp_ip6_ext_prefixlen,
1672     { "Prefix Length", "eigrp.ip6_ext.prefixlen",
1673      FT_UINT8, BASE_DEC, NULL, 0x0,
1674      NULL, HFILL }
1675     } 
1676         };
1677
1678         static gint *ett[] = {
1679                 &ett_eigrp,
1680                 &ett_eigrp_flags,
1681                 &ett_tlv,
1682                 &ett_eigrp_stub_flags,
1683                 &ett_eigrp_ip_ext_flags,
1684                 &ett_eigrp_ip6_ext_flags,
1685                 &ett_eigrp_at_ext_flags
1686         };
1687
1688         proto_eigrp = proto_register_protocol("Enhanced Interior Gateway Routing Protocol", "EIGRP", "eigrp");
1689         proto_register_field_array(proto_eigrp, hf, array_length(hf));
1690         proto_register_subtree_array(ett, array_length(ett));
1691 }
1692
1693 void proto_reg_handoff_eigrp(void) {
1694
1695         dissector_handle_t eigrp_handle;
1696
1697         ipxsap_handle = find_dissector("ipxsap");
1698         eigrp_handle = create_dissector_handle(dissect_eigrp, proto_eigrp);
1699         dissector_add("ip.proto", IP_PROTO_EIGRP, eigrp_handle);
1700         dissector_add("ddp.type", DDP_EIGRP, eigrp_handle);
1701         dissector_add("ipx.socket", IPX_SOCKET_EIGRP, eigrp_handle);
1702 }