xref: /dragonfly/contrib/tcpdump/print-eigrp.c (revision ed775ee7)
141c99275SPeter Avalos /*
2411677aeSAaron LI  * Copyright (c) 1998-2004  Hannes Gredler <hannes@gredler.at>
341c99275SPeter Avalos  *      The TCPDUMP project
441c99275SPeter Avalos  *
541c99275SPeter Avalos  * Redistribution and use in source and binary forms, with or without
641c99275SPeter Avalos  * modification, are permitted provided that: (1) source code
741c99275SPeter Avalos  * distributions retain the above copyright notice and this paragraph
841c99275SPeter Avalos  * in its entirety, and (2) distributions including binary code include
941c99275SPeter Avalos  * the above copyright notice and this paragraph in its entirety in
1041c99275SPeter Avalos  * the documentation or other materials provided with the distribution.
1141c99275SPeter Avalos  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
1241c99275SPeter Avalos  * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
1341c99275SPeter Avalos  * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
1441c99275SPeter Avalos  * FOR A PARTICULAR PURPOSE.
1541c99275SPeter Avalos  */
1641c99275SPeter Avalos 
17411677aeSAaron LI /* \summary: Enhanced Interior Gateway Routing Protocol (EIGRP) printer */
1841c99275SPeter Avalos 
19*ed775ee7SAntonio Huete Jimenez /*
20*ed775ee7SAntonio Huete Jimenez  * specification:
21*ed775ee7SAntonio Huete Jimenez  *
22*ed775ee7SAntonio Huete Jimenez  * https://web.archive.org/web/20190722221712/https://www.rhyshaden.com/eigrp.htm
23*ed775ee7SAntonio Huete Jimenez  * RFC 7868
24*ed775ee7SAntonio Huete Jimenez  */
25*ed775ee7SAntonio Huete Jimenez 
2641c99275SPeter Avalos #ifdef HAVE_CONFIG_H
27*ed775ee7SAntonio Huete Jimenez #include <config.h>
2841c99275SPeter Avalos #endif
2941c99275SPeter Avalos 
30*ed775ee7SAntonio Huete Jimenez #include "netdissect-stdinc.h"
3141c99275SPeter Avalos 
3241c99275SPeter Avalos #include <string.h>
3341c99275SPeter Avalos 
34411677aeSAaron LI #include "netdissect.h"
3541c99275SPeter Avalos #include "extract.h"
3641c99275SPeter Avalos #include "addrtoname.h"
3741c99275SPeter Avalos 
3841c99275SPeter Avalos 
3941c99275SPeter Avalos struct eigrp_common_header {
40*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  version;
41*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  opcode;
42*ed775ee7SAntonio Huete Jimenez     nd_uint16_t checksum;
43*ed775ee7SAntonio Huete Jimenez     nd_uint32_t flags;
44*ed775ee7SAntonio Huete Jimenez     nd_uint32_t seq;
45*ed775ee7SAntonio Huete Jimenez     nd_uint32_t ack;
46*ed775ee7SAntonio Huete Jimenez     nd_uint16_t vrid;
47*ed775ee7SAntonio Huete Jimenez     nd_uint16_t asn;
4841c99275SPeter Avalos };
4941c99275SPeter Avalos 
5041c99275SPeter Avalos #define	EIGRP_VERSION                        2
5141c99275SPeter Avalos 
5241c99275SPeter Avalos #define	EIGRP_OPCODE_UPDATE                  1
5341c99275SPeter Avalos #define	EIGRP_OPCODE_QUERY                   3
5441c99275SPeter Avalos #define	EIGRP_OPCODE_REPLY                   4
5541c99275SPeter Avalos #define	EIGRP_OPCODE_HELLO                   5
5641c99275SPeter Avalos #define	EIGRP_OPCODE_IPXSAP                  6
5741c99275SPeter Avalos #define	EIGRP_OPCODE_PROBE                   7
5841c99275SPeter Avalos 
5941c99275SPeter Avalos static const struct tok eigrp_opcode_values[] = {
6041c99275SPeter Avalos     { EIGRP_OPCODE_UPDATE, "Update" },
6141c99275SPeter Avalos     { EIGRP_OPCODE_QUERY, "Query" },
6241c99275SPeter Avalos     { EIGRP_OPCODE_REPLY, "Reply" },
6341c99275SPeter Avalos     { EIGRP_OPCODE_HELLO, "Hello" },
6441c99275SPeter Avalos     { EIGRP_OPCODE_IPXSAP, "IPX SAP" },
6541c99275SPeter Avalos     { EIGRP_OPCODE_PROBE, "Probe" },
6641c99275SPeter Avalos     { 0, NULL}
6741c99275SPeter Avalos };
6841c99275SPeter Avalos 
6941c99275SPeter Avalos static const struct tok eigrp_common_header_flag_values[] = {
7041c99275SPeter Avalos     { 0x01, "Init" },
7141c99275SPeter Avalos     { 0x02, "Conditionally Received" },
72*ed775ee7SAntonio Huete Jimenez     { 0x04, "Restart" },
73*ed775ee7SAntonio Huete Jimenez     { 0x08, "End-of-Table" },
7441c99275SPeter Avalos     { 0, NULL}
7541c99275SPeter Avalos };
7641c99275SPeter Avalos 
7741c99275SPeter Avalos struct eigrp_tlv_header {
78*ed775ee7SAntonio Huete Jimenez     nd_uint16_t type;
79*ed775ee7SAntonio Huete Jimenez     nd_uint16_t length;
8041c99275SPeter Avalos };
8141c99275SPeter Avalos 
8241c99275SPeter Avalos #define EIGRP_TLV_GENERAL_PARM   0x0001
8341c99275SPeter Avalos #define EIGRP_TLV_AUTH           0x0002
8441c99275SPeter Avalos #define EIGRP_TLV_SEQ            0x0003
8541c99275SPeter Avalos #define EIGRP_TLV_SW_VERSION     0x0004
8641c99275SPeter Avalos #define EIGRP_TLV_MCAST_SEQ      0x0005
8741c99275SPeter Avalos #define EIGRP_TLV_IP_INT         0x0102
8841c99275SPeter Avalos #define EIGRP_TLV_IP_EXT         0x0103
8941c99275SPeter Avalos #define EIGRP_TLV_AT_INT         0x0202
9041c99275SPeter Avalos #define EIGRP_TLV_AT_EXT         0x0203
9141c99275SPeter Avalos #define EIGRP_TLV_AT_CABLE_SETUP 0x0204
9241c99275SPeter Avalos #define EIGRP_TLV_IPX_INT        0x0302
9341c99275SPeter Avalos #define EIGRP_TLV_IPX_EXT        0x0303
9441c99275SPeter Avalos 
9541c99275SPeter Avalos static const struct tok eigrp_tlv_values[] = {
9641c99275SPeter Avalos     { EIGRP_TLV_GENERAL_PARM, "General Parameters"},
9741c99275SPeter Avalos     { EIGRP_TLV_AUTH, "Authentication"},
9841c99275SPeter Avalos     { EIGRP_TLV_SEQ, "Sequence"},
9941c99275SPeter Avalos     { EIGRP_TLV_SW_VERSION, "Software Version"},
10041c99275SPeter Avalos     { EIGRP_TLV_MCAST_SEQ, "Next Multicast Sequence"},
10141c99275SPeter Avalos     { EIGRP_TLV_IP_INT, "IP Internal routes"},
10241c99275SPeter Avalos     { EIGRP_TLV_IP_EXT, "IP External routes"},
10341c99275SPeter Avalos     { EIGRP_TLV_AT_INT, "AppleTalk Internal routes"},
10441c99275SPeter Avalos     { EIGRP_TLV_AT_EXT, "AppleTalk External routes"},
10541c99275SPeter Avalos     { EIGRP_TLV_AT_CABLE_SETUP, "AppleTalk Cable setup"},
10641c99275SPeter Avalos     { EIGRP_TLV_IPX_INT, "IPX Internal routes"},
10741c99275SPeter Avalos     { EIGRP_TLV_IPX_EXT, "IPX External routes"},
10841c99275SPeter Avalos     { 0, NULL}
10941c99275SPeter Avalos };
11041c99275SPeter Avalos 
11141c99275SPeter Avalos struct eigrp_tlv_general_parm_t {
112*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  k1;
113*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  k2;
114*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  k3;
115*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  k4;
116*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  k5;
117*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  res;
118*ed775ee7SAntonio Huete Jimenez     nd_uint16_t holdtime;
11941c99275SPeter Avalos };
12041c99275SPeter Avalos 
12141c99275SPeter Avalos struct eigrp_tlv_sw_version_t {
122*ed775ee7SAntonio Huete Jimenez     nd_uint8_t ios_major;
123*ed775ee7SAntonio Huete Jimenez     nd_uint8_t ios_minor;
124*ed775ee7SAntonio Huete Jimenez     nd_uint8_t eigrp_major;
125*ed775ee7SAntonio Huete Jimenez     nd_uint8_t eigrp_minor;
12641c99275SPeter Avalos };
12741c99275SPeter Avalos 
12841c99275SPeter Avalos struct eigrp_tlv_ip_int_t {
129*ed775ee7SAntonio Huete Jimenez     nd_ipv4     nexthop;
130*ed775ee7SAntonio Huete Jimenez     nd_uint32_t delay;
131*ed775ee7SAntonio Huete Jimenez     nd_uint32_t bandwidth;
132*ed775ee7SAntonio Huete Jimenez     nd_uint24_t mtu;
133*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  hopcount;
134*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  reliability;
135*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  load;
136*ed775ee7SAntonio Huete Jimenez     nd_byte     reserved[2];
137*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  plen;
138*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  destination; /* variable length [1-4] bytes encoding */
13941c99275SPeter Avalos };
14041c99275SPeter Avalos 
14141c99275SPeter Avalos struct eigrp_tlv_ip_ext_t {
142*ed775ee7SAntonio Huete Jimenez     nd_ipv4     nexthop;
143*ed775ee7SAntonio Huete Jimenez     nd_ipv4     origin_router;
144*ed775ee7SAntonio Huete Jimenez     nd_uint32_t origin_as;
145*ed775ee7SAntonio Huete Jimenez     nd_uint32_t tag;
146*ed775ee7SAntonio Huete Jimenez     nd_uint32_t metric;
147*ed775ee7SAntonio Huete Jimenez     nd_byte     reserved[2];
148*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  proto_id;
149*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  flags;
150*ed775ee7SAntonio Huete Jimenez     nd_uint32_t delay;
151*ed775ee7SAntonio Huete Jimenez     nd_uint32_t bandwidth;
152*ed775ee7SAntonio Huete Jimenez     nd_uint24_t mtu;
153*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  hopcount;
154*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  reliability;
155*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  load;
156*ed775ee7SAntonio Huete Jimenez     nd_byte     reserved2[2];
157*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  plen;
158*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  destination; /* variable length [1-4] bytes encoding */
15941c99275SPeter Avalos };
16041c99275SPeter Avalos 
16141c99275SPeter Avalos struct eigrp_tlv_at_cable_setup_t {
162*ed775ee7SAntonio Huete Jimenez     nd_uint16_t cable_start;
163*ed775ee7SAntonio Huete Jimenez     nd_uint16_t cable_end;
164*ed775ee7SAntonio Huete Jimenez     nd_uint32_t router_id;
16541c99275SPeter Avalos };
16641c99275SPeter Avalos 
16741c99275SPeter Avalos struct eigrp_tlv_at_int_t {
168*ed775ee7SAntonio Huete Jimenez     nd_byte     nexthop[4];
169*ed775ee7SAntonio Huete Jimenez     nd_uint32_t delay;
170*ed775ee7SAntonio Huete Jimenez     nd_uint32_t bandwidth;
171*ed775ee7SAntonio Huete Jimenez     nd_uint24_t mtu;
172*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  hopcount;
173*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  reliability;
174*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  load;
175*ed775ee7SAntonio Huete Jimenez     nd_byte     reserved[2];
176*ed775ee7SAntonio Huete Jimenez     nd_uint16_t cable_start;
177*ed775ee7SAntonio Huete Jimenez     nd_uint16_t cable_end;
17841c99275SPeter Avalos };
17941c99275SPeter Avalos 
18041c99275SPeter Avalos struct eigrp_tlv_at_ext_t {
181*ed775ee7SAntonio Huete Jimenez     nd_byte     nexthop[4];
182*ed775ee7SAntonio Huete Jimenez     nd_uint32_t origin_router;
183*ed775ee7SAntonio Huete Jimenez     nd_uint32_t origin_as;
184*ed775ee7SAntonio Huete Jimenez     nd_uint32_t tag;
185*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  proto_id;
186*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  flags;
187*ed775ee7SAntonio Huete Jimenez     nd_uint16_t metric;
188*ed775ee7SAntonio Huete Jimenez     nd_uint32_t delay;
189*ed775ee7SAntonio Huete Jimenez     nd_uint32_t bandwidth;
190*ed775ee7SAntonio Huete Jimenez     nd_uint24_t mtu;
191*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  hopcount;
192*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  reliability;
193*ed775ee7SAntonio Huete Jimenez     nd_uint8_t  load;
194*ed775ee7SAntonio Huete Jimenez     nd_byte     reserved2[2];
195*ed775ee7SAntonio Huete Jimenez     nd_uint16_t cable_start;
196*ed775ee7SAntonio Huete Jimenez     nd_uint16_t cable_end;
19741c99275SPeter Avalos };
19841c99275SPeter Avalos 
19941c99275SPeter Avalos static const struct tok eigrp_ext_proto_id_values[] = {
20041c99275SPeter Avalos     { 0x01, "IGRP" },
20141c99275SPeter Avalos     { 0x02, "EIGRP" },
20241c99275SPeter Avalos     { 0x03, "Static" },
20341c99275SPeter Avalos     { 0x04, "RIP" },
20441c99275SPeter Avalos     { 0x05, "Hello" },
20541c99275SPeter Avalos     { 0x06, "OSPF" },
20641c99275SPeter Avalos     { 0x07, "IS-IS" },
20741c99275SPeter Avalos     { 0x08, "EGP" },
20841c99275SPeter Avalos     { 0x09, "BGP" },
20941c99275SPeter Avalos     { 0x0a, "IDRP" },
21041c99275SPeter Avalos     { 0x0b, "Connected" },
21141c99275SPeter Avalos     { 0, NULL}
21241c99275SPeter Avalos };
21341c99275SPeter Avalos 
21441c99275SPeter Avalos void
eigrp_print(netdissect_options * ndo,const u_char * pptr,u_int len)215*ed775ee7SAntonio Huete Jimenez eigrp_print(netdissect_options *ndo, const u_char *pptr, u_int len)
216411677aeSAaron LI {
21741c99275SPeter Avalos     const struct eigrp_common_header *eigrp_com_header;
21841c99275SPeter Avalos     const struct eigrp_tlv_header *eigrp_tlv_header;
21941c99275SPeter Avalos     const u_char *tptr,*tlv_tptr;
22041c99275SPeter Avalos     u_int tlen,eigrp_tlv_len,eigrp_tlv_type,tlv_tlen, byte_length, bit_length;
221411677aeSAaron LI     uint8_t prefix[4];
22241c99275SPeter Avalos 
22341c99275SPeter Avalos     union {
22441c99275SPeter Avalos         const struct eigrp_tlv_general_parm_t *eigrp_tlv_general_parm;
22541c99275SPeter Avalos         const struct eigrp_tlv_sw_version_t *eigrp_tlv_sw_version;
22641c99275SPeter Avalos         const struct eigrp_tlv_ip_int_t *eigrp_tlv_ip_int;
22741c99275SPeter Avalos         const struct eigrp_tlv_ip_ext_t *eigrp_tlv_ip_ext;
22841c99275SPeter Avalos         const struct eigrp_tlv_at_cable_setup_t *eigrp_tlv_at_cable_setup;
22941c99275SPeter Avalos         const struct eigrp_tlv_at_int_t *eigrp_tlv_at_int;
23041c99275SPeter Avalos         const struct eigrp_tlv_at_ext_t *eigrp_tlv_at_ext;
23141c99275SPeter Avalos     } tlv_ptr;
23241c99275SPeter Avalos 
233*ed775ee7SAntonio Huete Jimenez     ndo->ndo_protocol = "eigrp";
23441c99275SPeter Avalos     tptr=pptr;
23541c99275SPeter Avalos     eigrp_com_header = (const struct eigrp_common_header *)pptr;
236*ed775ee7SAntonio Huete Jimenez     ND_TCHECK_SIZE(eigrp_com_header);
23741c99275SPeter Avalos 
23841c99275SPeter Avalos     /*
23941c99275SPeter Avalos      * Sanity checking of the header.
24041c99275SPeter Avalos      */
241*ed775ee7SAntonio Huete Jimenez     if (GET_U_1(eigrp_com_header->version) != EIGRP_VERSION) {
242*ed775ee7SAntonio Huete Jimenez         ND_PRINT("EIGRP version %u packet not supported",
243*ed775ee7SAntonio Huete Jimenez                  GET_U_1(eigrp_com_header->version));
24441c99275SPeter Avalos         return;
24541c99275SPeter Avalos     }
24641c99275SPeter Avalos 
24741c99275SPeter Avalos     /* in non-verbose mode just lets print the basic Message Type*/
248411677aeSAaron LI     if (ndo->ndo_vflag < 1) {
249*ed775ee7SAntonio Huete Jimenez         ND_PRINT("EIGRP %s, length: %u",
250*ed775ee7SAntonio Huete Jimenez                tok2str(eigrp_opcode_values, "unknown (%u)",GET_U_1(eigrp_com_header->opcode)),
251*ed775ee7SAntonio Huete Jimenez                len);
25241c99275SPeter Avalos         return;
25341c99275SPeter Avalos     }
25441c99275SPeter Avalos 
25541c99275SPeter Avalos     /* ok they seem to want to know everything - lets fully decode it */
25641c99275SPeter Avalos 
257411677aeSAaron LI     if (len < sizeof(struct eigrp_common_header)) {
258*ed775ee7SAntonio Huete Jimenez         ND_PRINT("EIGRP %s, length: %u (too short, < %zu)",
259*ed775ee7SAntonio Huete Jimenez                tok2str(eigrp_opcode_values, "unknown (%u)",GET_U_1(eigrp_com_header->opcode)),
260*ed775ee7SAntonio Huete Jimenez                len, sizeof(struct eigrp_common_header));
261411677aeSAaron LI         return;
262411677aeSAaron LI     }
26341c99275SPeter Avalos     tlen=len-sizeof(struct eigrp_common_header);
26441c99275SPeter Avalos 
265*ed775ee7SAntonio Huete Jimenez     ND_PRINT("\n\tEIGRP v%u, opcode: %s (%u), chksum: 0x%04x, Flags: [%s]"
266*ed775ee7SAntonio Huete Jimenez              "\n\tseq: 0x%08x, ack: 0x%08x, VRID: %u, AS: %u, length: %u",
267*ed775ee7SAntonio Huete Jimenez            GET_U_1(eigrp_com_header->version),
268*ed775ee7SAntonio Huete Jimenez            tok2str(eigrp_opcode_values, "unknown, type: %u",GET_U_1(eigrp_com_header->opcode)),
269*ed775ee7SAntonio Huete Jimenez            GET_U_1(eigrp_com_header->opcode),
270*ed775ee7SAntonio Huete Jimenez            GET_BE_U_2(eigrp_com_header->checksum),
271*ed775ee7SAntonio Huete Jimenez            bittok2str(eigrp_common_header_flag_values,
27241c99275SPeter Avalos                    "none",
273*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_4(eigrp_com_header->flags)),
274*ed775ee7SAntonio Huete Jimenez            GET_BE_U_4(eigrp_com_header->seq),
275*ed775ee7SAntonio Huete Jimenez            GET_BE_U_4(eigrp_com_header->ack),
276*ed775ee7SAntonio Huete Jimenez            GET_BE_U_2(eigrp_com_header->vrid),
277*ed775ee7SAntonio Huete Jimenez            GET_BE_U_2(eigrp_com_header->asn),
278*ed775ee7SAntonio Huete Jimenez            tlen);
27941c99275SPeter Avalos 
280*ed775ee7SAntonio Huete Jimenez     tptr+=sizeof(struct eigrp_common_header);
28141c99275SPeter Avalos 
28241c99275SPeter Avalos     while(tlen>0) {
28341c99275SPeter Avalos         /* did we capture enough for fully decoding the object header ? */
284*ed775ee7SAntonio Huete Jimenez         ND_TCHECK_LEN(tptr, sizeof(struct eigrp_tlv_header));
28541c99275SPeter Avalos 
28641c99275SPeter Avalos         eigrp_tlv_header = (const struct eigrp_tlv_header *)tptr;
287*ed775ee7SAntonio Huete Jimenez         eigrp_tlv_len=GET_BE_U_2(eigrp_tlv_header->length);
288*ed775ee7SAntonio Huete Jimenez         eigrp_tlv_type=GET_BE_U_2(eigrp_tlv_header->type);
28941c99275SPeter Avalos 
29041c99275SPeter Avalos 
29141c99275SPeter Avalos         if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header) ||
29241c99275SPeter Avalos             eigrp_tlv_len > tlen) {
293411677aeSAaron LI             print_unknown_data(ndo,tptr+sizeof(struct eigrp_tlv_header),"\n\t    ",tlen);
29441c99275SPeter Avalos             return;
29541c99275SPeter Avalos         }
29641c99275SPeter Avalos 
297*ed775ee7SAntonio Huete Jimenez         ND_PRINT("\n\t  %s TLV (0x%04x), length: %u",
29841c99275SPeter Avalos                tok2str(eigrp_tlv_values,
29941c99275SPeter Avalos                        "Unknown",
30041c99275SPeter Avalos                        eigrp_tlv_type),
30141c99275SPeter Avalos                eigrp_tlv_type,
302*ed775ee7SAntonio Huete Jimenez                eigrp_tlv_len);
30341c99275SPeter Avalos 
304411677aeSAaron LI         if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header)) {
305*ed775ee7SAntonio Huete Jimenez                 ND_PRINT(" (too short, < %zu)",
306*ed775ee7SAntonio Huete Jimenez                          sizeof(struct eigrp_tlv_header));
307411677aeSAaron LI                 break;
308411677aeSAaron LI         }
30941c99275SPeter Avalos         tlv_tptr=tptr+sizeof(struct eigrp_tlv_header);
31041c99275SPeter Avalos         tlv_tlen=eigrp_tlv_len-sizeof(struct eigrp_tlv_header);
31141c99275SPeter Avalos 
31241c99275SPeter Avalos         /* did we capture enough for fully decoding the object ? */
313*ed775ee7SAntonio Huete Jimenez         ND_TCHECK_LEN(tptr, eigrp_tlv_len);
31441c99275SPeter Avalos 
31541c99275SPeter Avalos         switch(eigrp_tlv_type) {
31641c99275SPeter Avalos 
31741c99275SPeter Avalos         case EIGRP_TLV_GENERAL_PARM:
31841c99275SPeter Avalos             tlv_ptr.eigrp_tlv_general_parm = (const struct eigrp_tlv_general_parm_t *)tlv_tptr;
319411677aeSAaron LI             if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_general_parm)) {
320*ed775ee7SAntonio Huete Jimenez                 ND_PRINT(" (too short, < %zu)",
321*ed775ee7SAntonio Huete Jimenez         		 sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_general_parm));
322411677aeSAaron LI                 break;
323411677aeSAaron LI             }
32441c99275SPeter Avalos 
325*ed775ee7SAntonio Huete Jimenez             ND_PRINT("\n\t    holdtime: %us, k1 %u, k2 %u, k3 %u, k4 %u, k5 %u",
326*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_2(tlv_ptr.eigrp_tlv_general_parm->holdtime),
327*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_general_parm->k1),
328*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_general_parm->k2),
329*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_general_parm->k3),
330*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_general_parm->k4),
331*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_general_parm->k5));
33241c99275SPeter Avalos             break;
33341c99275SPeter Avalos 
33441c99275SPeter Avalos         case EIGRP_TLV_SW_VERSION:
33541c99275SPeter Avalos             tlv_ptr.eigrp_tlv_sw_version = (const struct eigrp_tlv_sw_version_t *)tlv_tptr;
336411677aeSAaron LI             if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_sw_version)) {
337*ed775ee7SAntonio Huete Jimenez                 ND_PRINT(" (too short, < %zu)",
338*ed775ee7SAntonio Huete Jimenez                          sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_sw_version));
339411677aeSAaron LI                 break;
340411677aeSAaron LI             }
34141c99275SPeter Avalos 
342*ed775ee7SAntonio Huete Jimenez             ND_PRINT("\n\t    IOS version: %u.%u, EIGRP version %u.%u",
343*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_sw_version->ios_major),
344*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_sw_version->ios_minor),
345*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_sw_version->eigrp_major),
346*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_sw_version->eigrp_minor));
34741c99275SPeter Avalos             break;
34841c99275SPeter Avalos 
34941c99275SPeter Avalos         case EIGRP_TLV_IP_INT:
35041c99275SPeter Avalos             tlv_ptr.eigrp_tlv_ip_int = (const struct eigrp_tlv_ip_int_t *)tlv_tptr;
351411677aeSAaron LI             if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_ip_int)) {
352*ed775ee7SAntonio Huete Jimenez                 ND_PRINT(" (too short, < %zu)",
353*ed775ee7SAntonio Huete Jimenez                          sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_ip_int));
354411677aeSAaron LI                 break;
355411677aeSAaron LI             }
35641c99275SPeter Avalos 
357*ed775ee7SAntonio Huete Jimenez             bit_length = GET_U_1(tlv_ptr.eigrp_tlv_ip_int->plen);
35841c99275SPeter Avalos             if (bit_length > 32) {
359*ed775ee7SAntonio Huete Jimenez                 ND_PRINT("\n\t    illegal prefix length %u",bit_length);
36041c99275SPeter Avalos                 break;
36141c99275SPeter Avalos             }
36241c99275SPeter Avalos             byte_length = (bit_length + 7) / 8; /* variable length encoding */
36341c99275SPeter Avalos             memset(prefix, 0, 4);
364*ed775ee7SAntonio Huete Jimenez             GET_CPY_BYTES(prefix, tlv_ptr.eigrp_tlv_ip_int->destination, byte_length);
36541c99275SPeter Avalos 
366*ed775ee7SAntonio Huete Jimenez             ND_PRINT("\n\t    IPv4 prefix: %15s/%u, nexthop: ",
367*ed775ee7SAntonio Huete Jimenez                    ipaddr_string(ndo, prefix),	/* local buffer, not packet data; don't use GET_IPADDR_STRING() */
368*ed775ee7SAntonio Huete Jimenez                    bit_length);
369*ed775ee7SAntonio Huete Jimenez             if (GET_BE_U_4(tlv_ptr.eigrp_tlv_ip_int->nexthop) == 0)
370*ed775ee7SAntonio Huete Jimenez                 ND_PRINT("self");
37141c99275SPeter Avalos             else
372*ed775ee7SAntonio Huete Jimenez                 ND_PRINT("%s",
373*ed775ee7SAntonio Huete Jimenez                          GET_IPADDR_STRING(tlv_ptr.eigrp_tlv_ip_int->nexthop));
37441c99275SPeter Avalos 
375*ed775ee7SAntonio Huete Jimenez             ND_PRINT("\n\t      delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
376*ed775ee7SAntonio Huete Jimenez                    (GET_BE_U_4(tlv_ptr.eigrp_tlv_ip_int->delay)/100),
377*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_4(tlv_ptr.eigrp_tlv_ip_int->bandwidth),
378*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_3(tlv_ptr.eigrp_tlv_ip_int->mtu),
379*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_ip_int->hopcount),
380*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_ip_int->reliability),
381*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_ip_int->load));
38241c99275SPeter Avalos             break;
38341c99275SPeter Avalos 
38441c99275SPeter Avalos         case EIGRP_TLV_IP_EXT:
38541c99275SPeter Avalos             tlv_ptr.eigrp_tlv_ip_ext = (const struct eigrp_tlv_ip_ext_t *)tlv_tptr;
386411677aeSAaron LI             if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_ip_ext)) {
387*ed775ee7SAntonio Huete Jimenez                 ND_PRINT(" (too short, < %zu)",
388*ed775ee7SAntonio Huete Jimenez                          sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_ip_ext));
389411677aeSAaron LI                 break;
390411677aeSAaron LI             }
39141c99275SPeter Avalos 
392*ed775ee7SAntonio Huete Jimenez             bit_length = GET_U_1(tlv_ptr.eigrp_tlv_ip_ext->plen);
39341c99275SPeter Avalos             if (bit_length > 32) {
394*ed775ee7SAntonio Huete Jimenez                 ND_PRINT("\n\t    illegal prefix length %u",bit_length);
39541c99275SPeter Avalos                 break;
39641c99275SPeter Avalos             }
39741c99275SPeter Avalos             byte_length = (bit_length + 7) / 8; /* variable length encoding */
39841c99275SPeter Avalos             memset(prefix, 0, 4);
399*ed775ee7SAntonio Huete Jimenez             GET_CPY_BYTES(prefix, tlv_ptr.eigrp_tlv_ip_ext->destination, byte_length);
40041c99275SPeter Avalos 
401*ed775ee7SAntonio Huete Jimenez             ND_PRINT("\n\t    IPv4 prefix: %15s/%u, nexthop: ",
402*ed775ee7SAntonio Huete Jimenez                    ipaddr_string(ndo, prefix),	/* local buffer, not packet data; don't use GET_IPADDR_STRING() */
403*ed775ee7SAntonio Huete Jimenez                    bit_length);
404*ed775ee7SAntonio Huete Jimenez             if (GET_BE_U_4(tlv_ptr.eigrp_tlv_ip_ext->nexthop) == 0)
405*ed775ee7SAntonio Huete Jimenez                 ND_PRINT("self");
40641c99275SPeter Avalos             else
407*ed775ee7SAntonio Huete Jimenez                 ND_PRINT("%s",
408*ed775ee7SAntonio Huete Jimenez                          GET_IPADDR_STRING(tlv_ptr.eigrp_tlv_ip_ext->nexthop));
40941c99275SPeter Avalos 
410*ed775ee7SAntonio Huete Jimenez             ND_PRINT("\n\t      origin-router %s, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u",
411*ed775ee7SAntonio Huete Jimenez                    GET_IPADDR_STRING(tlv_ptr.eigrp_tlv_ip_ext->origin_router),
412*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_4(tlv_ptr.eigrp_tlv_ip_ext->origin_as),
413*ed775ee7SAntonio Huete Jimenez                    tok2str(eigrp_ext_proto_id_values,"unknown",GET_U_1(tlv_ptr.eigrp_tlv_ip_ext->proto_id)),
414*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_ip_ext->flags),
415*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_4(tlv_ptr.eigrp_tlv_ip_ext->tag),
416*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_4(tlv_ptr.eigrp_tlv_ip_ext->metric));
41741c99275SPeter Avalos 
418*ed775ee7SAntonio Huete Jimenez             ND_PRINT("\n\t      delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
419*ed775ee7SAntonio Huete Jimenez                    (GET_BE_U_4(tlv_ptr.eigrp_tlv_ip_ext->delay)/100),
420*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_4(tlv_ptr.eigrp_tlv_ip_ext->bandwidth),
421*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_3(tlv_ptr.eigrp_tlv_ip_ext->mtu),
422*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_ip_ext->hopcount),
423*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_ip_ext->reliability),
424*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_ip_ext->load));
42541c99275SPeter Avalos             break;
42641c99275SPeter Avalos 
42741c99275SPeter Avalos         case EIGRP_TLV_AT_CABLE_SETUP:
42841c99275SPeter Avalos             tlv_ptr.eigrp_tlv_at_cable_setup = (const struct eigrp_tlv_at_cable_setup_t *)tlv_tptr;
429411677aeSAaron LI             if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_cable_setup)) {
430*ed775ee7SAntonio Huete Jimenez                 ND_PRINT(" (too short, < %zu)",
431*ed775ee7SAntonio Huete Jimenez                          sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_cable_setup));
432411677aeSAaron LI                 break;
433411677aeSAaron LI             }
43441c99275SPeter Avalos 
435*ed775ee7SAntonio Huete Jimenez             ND_PRINT("\n\t    Cable-range: %u-%u, Router-ID %u",
436*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_2(tlv_ptr.eigrp_tlv_at_cable_setup->cable_start),
437*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_2(tlv_ptr.eigrp_tlv_at_cable_setup->cable_end),
438*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_4(tlv_ptr.eigrp_tlv_at_cable_setup->router_id));
43941c99275SPeter Avalos             break;
44041c99275SPeter Avalos 
44141c99275SPeter Avalos         case EIGRP_TLV_AT_INT:
44241c99275SPeter Avalos             tlv_ptr.eigrp_tlv_at_int = (const struct eigrp_tlv_at_int_t *)tlv_tptr;
443411677aeSAaron LI             if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_int)) {
444*ed775ee7SAntonio Huete Jimenez                 ND_PRINT(" (too short, < %zu)",
445*ed775ee7SAntonio Huete Jimenez                          sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_int));
446411677aeSAaron LI                 break;
447411677aeSAaron LI             }
44841c99275SPeter Avalos 
449*ed775ee7SAntonio Huete Jimenez             ND_PRINT("\n\t     Cable-Range: %u-%u, nexthop: ",
450*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_2(tlv_ptr.eigrp_tlv_at_int->cable_start),
451*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_2(tlv_ptr.eigrp_tlv_at_int->cable_end));
45241c99275SPeter Avalos 
453*ed775ee7SAntonio Huete Jimenez             if (GET_BE_U_4(tlv_ptr.eigrp_tlv_at_int->nexthop) == 0)
454*ed775ee7SAntonio Huete Jimenez                 ND_PRINT("self");
45541c99275SPeter Avalos             else
456*ed775ee7SAntonio Huete Jimenez                 ND_PRINT("%u.%u",
457*ed775ee7SAntonio Huete Jimenez                        GET_BE_U_2(&tlv_ptr.eigrp_tlv_at_int->nexthop[0]),
458*ed775ee7SAntonio Huete Jimenez                        GET_BE_U_2(&tlv_ptr.eigrp_tlv_at_int->nexthop[2]));
45941c99275SPeter Avalos 
460*ed775ee7SAntonio Huete Jimenez             ND_PRINT("\n\t      delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
461*ed775ee7SAntonio Huete Jimenez                    (GET_BE_U_4(tlv_ptr.eigrp_tlv_at_int->delay)/100),
462*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_4(tlv_ptr.eigrp_tlv_at_int->bandwidth),
463*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_3(tlv_ptr.eigrp_tlv_at_int->mtu),
464*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_at_int->hopcount),
465*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_at_int->reliability),
466*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_at_int->load));
46741c99275SPeter Avalos             break;
46841c99275SPeter Avalos 
46941c99275SPeter Avalos         case EIGRP_TLV_AT_EXT:
47041c99275SPeter Avalos             tlv_ptr.eigrp_tlv_at_ext = (const struct eigrp_tlv_at_ext_t *)tlv_tptr;
471411677aeSAaron LI             if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_ext)) {
472*ed775ee7SAntonio Huete Jimenez                 ND_PRINT(" (too short, < %zu)",
473*ed775ee7SAntonio Huete Jimenez                          sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_ext));
474411677aeSAaron LI                 break;
475411677aeSAaron LI             }
47641c99275SPeter Avalos 
477*ed775ee7SAntonio Huete Jimenez             ND_PRINT("\n\t     Cable-Range: %u-%u, nexthop: ",
478*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_2(tlv_ptr.eigrp_tlv_at_ext->cable_start),
479*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_2(tlv_ptr.eigrp_tlv_at_ext->cable_end));
48041c99275SPeter Avalos 
481*ed775ee7SAntonio Huete Jimenez             if (GET_BE_U_4(tlv_ptr.eigrp_tlv_at_ext->nexthop) == 0)
482*ed775ee7SAntonio Huete Jimenez                 ND_PRINT("self");
48341c99275SPeter Avalos             else
484*ed775ee7SAntonio Huete Jimenez                 ND_PRINT("%u.%u",
485*ed775ee7SAntonio Huete Jimenez                        GET_BE_U_2(&tlv_ptr.eigrp_tlv_at_ext->nexthop[0]),
486*ed775ee7SAntonio Huete Jimenez                        GET_BE_U_2(&tlv_ptr.eigrp_tlv_at_ext->nexthop[2]));
48741c99275SPeter Avalos 
488*ed775ee7SAntonio Huete Jimenez             ND_PRINT("\n\t      origin-router %u, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u",
489*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_4(tlv_ptr.eigrp_tlv_at_ext->origin_router),
490*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_4(tlv_ptr.eigrp_tlv_at_ext->origin_as),
491*ed775ee7SAntonio Huete Jimenez                    tok2str(eigrp_ext_proto_id_values,"unknown",GET_U_1(tlv_ptr.eigrp_tlv_at_ext->proto_id)),
492*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_at_ext->flags),
493*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_4(tlv_ptr.eigrp_tlv_at_ext->tag),
494*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_2(tlv_ptr.eigrp_tlv_at_ext->metric));
49541c99275SPeter Avalos 
496*ed775ee7SAntonio Huete Jimenez             ND_PRINT("\n\t      delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
497*ed775ee7SAntonio Huete Jimenez                    (GET_BE_U_4(tlv_ptr.eigrp_tlv_at_ext->delay)/100),
498*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_4(tlv_ptr.eigrp_tlv_at_ext->bandwidth),
499*ed775ee7SAntonio Huete Jimenez                    GET_BE_U_3(tlv_ptr.eigrp_tlv_at_ext->mtu),
500*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_at_ext->hopcount),
501*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_at_ext->reliability),
502*ed775ee7SAntonio Huete Jimenez                    GET_U_1(tlv_ptr.eigrp_tlv_at_ext->load));
50341c99275SPeter Avalos             break;
50441c99275SPeter Avalos 
50541c99275SPeter Avalos             /*
50641c99275SPeter Avalos              * FIXME those are the defined TLVs that lack a decoder
50741c99275SPeter Avalos              * you are welcome to contribute code ;-)
50841c99275SPeter Avalos              */
50941c99275SPeter Avalos 
51041c99275SPeter Avalos         case EIGRP_TLV_AUTH:
51141c99275SPeter Avalos         case EIGRP_TLV_SEQ:
51241c99275SPeter Avalos         case EIGRP_TLV_MCAST_SEQ:
51341c99275SPeter Avalos         case EIGRP_TLV_IPX_INT:
51441c99275SPeter Avalos         case EIGRP_TLV_IPX_EXT:
51541c99275SPeter Avalos 
51641c99275SPeter Avalos         default:
517411677aeSAaron LI             if (ndo->ndo_vflag <= 1)
518411677aeSAaron LI                 print_unknown_data(ndo,tlv_tptr,"\n\t    ",tlv_tlen);
51941c99275SPeter Avalos             break;
52041c99275SPeter Avalos         }
52141c99275SPeter Avalos         /* do we want to see an additionally hexdump ? */
522411677aeSAaron LI         if (ndo->ndo_vflag > 1)
523411677aeSAaron LI             print_unknown_data(ndo,tptr+sizeof(struct eigrp_tlv_header),"\n\t    ",
52441c99275SPeter Avalos                                eigrp_tlv_len-sizeof(struct eigrp_tlv_header));
52541c99275SPeter Avalos 
52641c99275SPeter Avalos         tptr+=eigrp_tlv_len;
52741c99275SPeter Avalos         tlen-=eigrp_tlv_len;
52841c99275SPeter Avalos     }
52941c99275SPeter Avalos     return;
53041c99275SPeter Avalos trunc:
531*ed775ee7SAntonio Huete Jimenez     nd_print_trunc(ndo);
53241c99275SPeter Avalos }
533