1*b636d99dSDavid van Moolenbroek /*
2*b636d99dSDavid van Moolenbroek * Copyright (c) 1998-2004 Hannes Gredler <hannes@tcpdump.org>
3*b636d99dSDavid van Moolenbroek * The TCPDUMP project
4*b636d99dSDavid van Moolenbroek *
5*b636d99dSDavid van Moolenbroek * Redistribution and use in source and binary forms, with or without
6*b636d99dSDavid van Moolenbroek * modification, are permitted provided that: (1) source code
7*b636d99dSDavid van Moolenbroek * distributions retain the above copyright notice and this paragraph
8*b636d99dSDavid van Moolenbroek * in its entirety, and (2) distributions including binary code include
9*b636d99dSDavid van Moolenbroek * the above copyright notice and this paragraph in its entirety in
10*b636d99dSDavid van Moolenbroek * the documentation or other materials provided with the distribution.
11*b636d99dSDavid van Moolenbroek * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
12*b636d99dSDavid van Moolenbroek * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
13*b636d99dSDavid van Moolenbroek * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
14*b636d99dSDavid van Moolenbroek * FOR A PARTICULAR PURPOSE.
15*b636d99dSDavid van Moolenbroek */
16*b636d99dSDavid van Moolenbroek
17*b636d99dSDavid van Moolenbroek #include <sys/cdefs.h>
18*b636d99dSDavid van Moolenbroek #ifndef lint
19*b636d99dSDavid van Moolenbroek __RCSID("$NetBSD: print-eigrp.c,v 1.6 2015/03/31 21:59:35 christos Exp $");
20*b636d99dSDavid van Moolenbroek #endif
21*b636d99dSDavid van Moolenbroek
22*b636d99dSDavid van Moolenbroek #define NETDISSECT_REWORKED
23*b636d99dSDavid van Moolenbroek #ifdef HAVE_CONFIG_H
24*b636d99dSDavid van Moolenbroek #include "config.h"
25*b636d99dSDavid van Moolenbroek #endif
26*b636d99dSDavid van Moolenbroek
27*b636d99dSDavid van Moolenbroek #include <tcpdump-stdinc.h>
28*b636d99dSDavid van Moolenbroek
29*b636d99dSDavid van Moolenbroek #include <string.h>
30*b636d99dSDavid van Moolenbroek
31*b636d99dSDavid van Moolenbroek #include "interface.h"
32*b636d99dSDavid van Moolenbroek #include "extract.h"
33*b636d99dSDavid van Moolenbroek #include "addrtoname.h"
34*b636d99dSDavid van Moolenbroek
35*b636d99dSDavid van Moolenbroek /*
36*b636d99dSDavid van Moolenbroek * packet format documented at
37*b636d99dSDavid van Moolenbroek * http://www.rhyshaden.com/eigrp.htm
38*b636d99dSDavid van Moolenbroek */
39*b636d99dSDavid van Moolenbroek
40*b636d99dSDavid van Moolenbroek struct eigrp_common_header {
41*b636d99dSDavid van Moolenbroek uint8_t version;
42*b636d99dSDavid van Moolenbroek uint8_t opcode;
43*b636d99dSDavid van Moolenbroek uint8_t checksum[2];
44*b636d99dSDavid van Moolenbroek uint8_t flags[4];
45*b636d99dSDavid van Moolenbroek uint8_t seq[4];
46*b636d99dSDavid van Moolenbroek uint8_t ack[4];
47*b636d99dSDavid van Moolenbroek uint8_t asn[4];
48*b636d99dSDavid van Moolenbroek };
49*b636d99dSDavid van Moolenbroek
50*b636d99dSDavid van Moolenbroek #define EIGRP_VERSION 2
51*b636d99dSDavid van Moolenbroek
52*b636d99dSDavid van Moolenbroek #define EIGRP_OPCODE_UPDATE 1
53*b636d99dSDavid van Moolenbroek #define EIGRP_OPCODE_QUERY 3
54*b636d99dSDavid van Moolenbroek #define EIGRP_OPCODE_REPLY 4
55*b636d99dSDavid van Moolenbroek #define EIGRP_OPCODE_HELLO 5
56*b636d99dSDavid van Moolenbroek #define EIGRP_OPCODE_IPXSAP 6
57*b636d99dSDavid van Moolenbroek #define EIGRP_OPCODE_PROBE 7
58*b636d99dSDavid van Moolenbroek
59*b636d99dSDavid van Moolenbroek static const struct tok eigrp_opcode_values[] = {
60*b636d99dSDavid van Moolenbroek { EIGRP_OPCODE_UPDATE, "Update" },
61*b636d99dSDavid van Moolenbroek { EIGRP_OPCODE_QUERY, "Query" },
62*b636d99dSDavid van Moolenbroek { EIGRP_OPCODE_REPLY, "Reply" },
63*b636d99dSDavid van Moolenbroek { EIGRP_OPCODE_HELLO, "Hello" },
64*b636d99dSDavid van Moolenbroek { EIGRP_OPCODE_IPXSAP, "IPX SAP" },
65*b636d99dSDavid van Moolenbroek { EIGRP_OPCODE_PROBE, "Probe" },
66*b636d99dSDavid van Moolenbroek { 0, NULL}
67*b636d99dSDavid van Moolenbroek };
68*b636d99dSDavid van Moolenbroek
69*b636d99dSDavid van Moolenbroek static const struct tok eigrp_common_header_flag_values[] = {
70*b636d99dSDavid van Moolenbroek { 0x01, "Init" },
71*b636d99dSDavid van Moolenbroek { 0x02, "Conditionally Received" },
72*b636d99dSDavid van Moolenbroek { 0, NULL}
73*b636d99dSDavid van Moolenbroek };
74*b636d99dSDavid van Moolenbroek
75*b636d99dSDavid van Moolenbroek struct eigrp_tlv_header {
76*b636d99dSDavid van Moolenbroek uint8_t type[2];
77*b636d99dSDavid van Moolenbroek uint8_t length[2];
78*b636d99dSDavid van Moolenbroek };
79*b636d99dSDavid van Moolenbroek
80*b636d99dSDavid van Moolenbroek #define EIGRP_TLV_GENERAL_PARM 0x0001
81*b636d99dSDavid van Moolenbroek #define EIGRP_TLV_AUTH 0x0002
82*b636d99dSDavid van Moolenbroek #define EIGRP_TLV_SEQ 0x0003
83*b636d99dSDavid van Moolenbroek #define EIGRP_TLV_SW_VERSION 0x0004
84*b636d99dSDavid van Moolenbroek #define EIGRP_TLV_MCAST_SEQ 0x0005
85*b636d99dSDavid van Moolenbroek #define EIGRP_TLV_IP_INT 0x0102
86*b636d99dSDavid van Moolenbroek #define EIGRP_TLV_IP_EXT 0x0103
87*b636d99dSDavid van Moolenbroek #define EIGRP_TLV_AT_INT 0x0202
88*b636d99dSDavid van Moolenbroek #define EIGRP_TLV_AT_EXT 0x0203
89*b636d99dSDavid van Moolenbroek #define EIGRP_TLV_AT_CABLE_SETUP 0x0204
90*b636d99dSDavid van Moolenbroek #define EIGRP_TLV_IPX_INT 0x0302
91*b636d99dSDavid van Moolenbroek #define EIGRP_TLV_IPX_EXT 0x0303
92*b636d99dSDavid van Moolenbroek
93*b636d99dSDavid van Moolenbroek static const struct tok eigrp_tlv_values[] = {
94*b636d99dSDavid van Moolenbroek { EIGRP_TLV_GENERAL_PARM, "General Parameters"},
95*b636d99dSDavid van Moolenbroek { EIGRP_TLV_AUTH, "Authentication"},
96*b636d99dSDavid van Moolenbroek { EIGRP_TLV_SEQ, "Sequence"},
97*b636d99dSDavid van Moolenbroek { EIGRP_TLV_SW_VERSION, "Software Version"},
98*b636d99dSDavid van Moolenbroek { EIGRP_TLV_MCAST_SEQ, "Next Multicast Sequence"},
99*b636d99dSDavid van Moolenbroek { EIGRP_TLV_IP_INT, "IP Internal routes"},
100*b636d99dSDavid van Moolenbroek { EIGRP_TLV_IP_EXT, "IP External routes"},
101*b636d99dSDavid van Moolenbroek { EIGRP_TLV_AT_INT, "AppleTalk Internal routes"},
102*b636d99dSDavid van Moolenbroek { EIGRP_TLV_AT_EXT, "AppleTalk External routes"},
103*b636d99dSDavid van Moolenbroek { EIGRP_TLV_AT_CABLE_SETUP, "AppleTalk Cable setup"},
104*b636d99dSDavid van Moolenbroek { EIGRP_TLV_IPX_INT, "IPX Internal routes"},
105*b636d99dSDavid van Moolenbroek { EIGRP_TLV_IPX_EXT, "IPX External routes"},
106*b636d99dSDavid van Moolenbroek { 0, NULL}
107*b636d99dSDavid van Moolenbroek };
108*b636d99dSDavid van Moolenbroek
109*b636d99dSDavid van Moolenbroek struct eigrp_tlv_general_parm_t {
110*b636d99dSDavid van Moolenbroek uint8_t k1;
111*b636d99dSDavid van Moolenbroek uint8_t k2;
112*b636d99dSDavid van Moolenbroek uint8_t k3;
113*b636d99dSDavid van Moolenbroek uint8_t k4;
114*b636d99dSDavid van Moolenbroek uint8_t k5;
115*b636d99dSDavid van Moolenbroek uint8_t res;
116*b636d99dSDavid van Moolenbroek uint8_t holdtime[2];
117*b636d99dSDavid van Moolenbroek };
118*b636d99dSDavid van Moolenbroek
119*b636d99dSDavid van Moolenbroek struct eigrp_tlv_sw_version_t {
120*b636d99dSDavid van Moolenbroek uint8_t ios_major;
121*b636d99dSDavid van Moolenbroek uint8_t ios_minor;
122*b636d99dSDavid van Moolenbroek uint8_t eigrp_major;
123*b636d99dSDavid van Moolenbroek uint8_t eigrp_minor;
124*b636d99dSDavid van Moolenbroek };
125*b636d99dSDavid van Moolenbroek
126*b636d99dSDavid van Moolenbroek struct eigrp_tlv_ip_int_t {
127*b636d99dSDavid van Moolenbroek uint8_t nexthop[4];
128*b636d99dSDavid van Moolenbroek uint8_t delay[4];
129*b636d99dSDavid van Moolenbroek uint8_t bandwidth[4];
130*b636d99dSDavid van Moolenbroek uint8_t mtu[3];
131*b636d99dSDavid van Moolenbroek uint8_t hopcount;
132*b636d99dSDavid van Moolenbroek uint8_t reliability;
133*b636d99dSDavid van Moolenbroek uint8_t load;
134*b636d99dSDavid van Moolenbroek uint8_t reserved[2];
135*b636d99dSDavid van Moolenbroek uint8_t plen;
136*b636d99dSDavid van Moolenbroek uint8_t destination; /* variable length [1-4] bytes encoding */
137*b636d99dSDavid van Moolenbroek };
138*b636d99dSDavid van Moolenbroek
139*b636d99dSDavid van Moolenbroek struct eigrp_tlv_ip_ext_t {
140*b636d99dSDavid van Moolenbroek uint8_t nexthop[4];
141*b636d99dSDavid van Moolenbroek uint8_t origin_router[4];
142*b636d99dSDavid van Moolenbroek uint8_t origin_as[4];
143*b636d99dSDavid van Moolenbroek uint8_t tag[4];
144*b636d99dSDavid van Moolenbroek uint8_t metric[4];
145*b636d99dSDavid van Moolenbroek uint8_t reserved[2];
146*b636d99dSDavid van Moolenbroek uint8_t proto_id;
147*b636d99dSDavid van Moolenbroek uint8_t flags;
148*b636d99dSDavid van Moolenbroek uint8_t delay[4];
149*b636d99dSDavid van Moolenbroek uint8_t bandwidth[4];
150*b636d99dSDavid van Moolenbroek uint8_t mtu[3];
151*b636d99dSDavid van Moolenbroek uint8_t hopcount;
152*b636d99dSDavid van Moolenbroek uint8_t reliability;
153*b636d99dSDavid van Moolenbroek uint8_t load;
154*b636d99dSDavid van Moolenbroek uint8_t reserved2[2];
155*b636d99dSDavid van Moolenbroek uint8_t plen;
156*b636d99dSDavid van Moolenbroek uint8_t destination; /* variable length [1-4] bytes encoding */
157*b636d99dSDavid van Moolenbroek };
158*b636d99dSDavid van Moolenbroek
159*b636d99dSDavid van Moolenbroek struct eigrp_tlv_at_cable_setup_t {
160*b636d99dSDavid van Moolenbroek uint8_t cable_start[2];
161*b636d99dSDavid van Moolenbroek uint8_t cable_end[2];
162*b636d99dSDavid van Moolenbroek uint8_t router_id[4];
163*b636d99dSDavid van Moolenbroek };
164*b636d99dSDavid van Moolenbroek
165*b636d99dSDavid van Moolenbroek struct eigrp_tlv_at_int_t {
166*b636d99dSDavid van Moolenbroek uint8_t nexthop[4];
167*b636d99dSDavid van Moolenbroek uint8_t delay[4];
168*b636d99dSDavid van Moolenbroek uint8_t bandwidth[4];
169*b636d99dSDavid van Moolenbroek uint8_t mtu[3];
170*b636d99dSDavid van Moolenbroek uint8_t hopcount;
171*b636d99dSDavid van Moolenbroek uint8_t reliability;
172*b636d99dSDavid van Moolenbroek uint8_t load;
173*b636d99dSDavid van Moolenbroek uint8_t reserved[2];
174*b636d99dSDavid van Moolenbroek uint8_t cable_start[2];
175*b636d99dSDavid van Moolenbroek uint8_t cable_end[2];
176*b636d99dSDavid van Moolenbroek };
177*b636d99dSDavid van Moolenbroek
178*b636d99dSDavid van Moolenbroek struct eigrp_tlv_at_ext_t {
179*b636d99dSDavid van Moolenbroek uint8_t nexthop[4];
180*b636d99dSDavid van Moolenbroek uint8_t origin_router[4];
181*b636d99dSDavid van Moolenbroek uint8_t origin_as[4];
182*b636d99dSDavid van Moolenbroek uint8_t tag[4];
183*b636d99dSDavid van Moolenbroek uint8_t proto_id;
184*b636d99dSDavid van Moolenbroek uint8_t flags;
185*b636d99dSDavid van Moolenbroek uint8_t metric[2];
186*b636d99dSDavid van Moolenbroek uint8_t delay[4];
187*b636d99dSDavid van Moolenbroek uint8_t bandwidth[4];
188*b636d99dSDavid van Moolenbroek uint8_t mtu[3];
189*b636d99dSDavid van Moolenbroek uint8_t hopcount;
190*b636d99dSDavid van Moolenbroek uint8_t reliability;
191*b636d99dSDavid van Moolenbroek uint8_t load;
192*b636d99dSDavid van Moolenbroek uint8_t reserved2[2];
193*b636d99dSDavid van Moolenbroek uint8_t cable_start[2];
194*b636d99dSDavid van Moolenbroek uint8_t cable_end[2];
195*b636d99dSDavid van Moolenbroek };
196*b636d99dSDavid van Moolenbroek
197*b636d99dSDavid van Moolenbroek static const struct tok eigrp_ext_proto_id_values[] = {
198*b636d99dSDavid van Moolenbroek { 0x01, "IGRP" },
199*b636d99dSDavid van Moolenbroek { 0x02, "EIGRP" },
200*b636d99dSDavid van Moolenbroek { 0x03, "Static" },
201*b636d99dSDavid van Moolenbroek { 0x04, "RIP" },
202*b636d99dSDavid van Moolenbroek { 0x05, "Hello" },
203*b636d99dSDavid van Moolenbroek { 0x06, "OSPF" },
204*b636d99dSDavid van Moolenbroek { 0x07, "IS-IS" },
205*b636d99dSDavid van Moolenbroek { 0x08, "EGP" },
206*b636d99dSDavid van Moolenbroek { 0x09, "BGP" },
207*b636d99dSDavid van Moolenbroek { 0x0a, "IDRP" },
208*b636d99dSDavid van Moolenbroek { 0x0b, "Connected" },
209*b636d99dSDavid van Moolenbroek { 0, NULL}
210*b636d99dSDavid van Moolenbroek };
211*b636d99dSDavid van Moolenbroek
212*b636d99dSDavid van Moolenbroek void
eigrp_print(netdissect_options * ndo,register const u_char * pptr,register u_int len)213*b636d99dSDavid van Moolenbroek eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int len)
214*b636d99dSDavid van Moolenbroek {
215*b636d99dSDavid van Moolenbroek const struct eigrp_common_header *eigrp_com_header;
216*b636d99dSDavid van Moolenbroek const struct eigrp_tlv_header *eigrp_tlv_header;
217*b636d99dSDavid van Moolenbroek const u_char *tptr,*tlv_tptr;
218*b636d99dSDavid van Moolenbroek u_int tlen,eigrp_tlv_len,eigrp_tlv_type,tlv_tlen, byte_length, bit_length;
219*b636d99dSDavid van Moolenbroek uint8_t prefix[4];
220*b636d99dSDavid van Moolenbroek
221*b636d99dSDavid van Moolenbroek union {
222*b636d99dSDavid van Moolenbroek const struct eigrp_tlv_general_parm_t *eigrp_tlv_general_parm;
223*b636d99dSDavid van Moolenbroek const struct eigrp_tlv_sw_version_t *eigrp_tlv_sw_version;
224*b636d99dSDavid van Moolenbroek const struct eigrp_tlv_ip_int_t *eigrp_tlv_ip_int;
225*b636d99dSDavid van Moolenbroek const struct eigrp_tlv_ip_ext_t *eigrp_tlv_ip_ext;
226*b636d99dSDavid van Moolenbroek const struct eigrp_tlv_at_cable_setup_t *eigrp_tlv_at_cable_setup;
227*b636d99dSDavid van Moolenbroek const struct eigrp_tlv_at_int_t *eigrp_tlv_at_int;
228*b636d99dSDavid van Moolenbroek const struct eigrp_tlv_at_ext_t *eigrp_tlv_at_ext;
229*b636d99dSDavid van Moolenbroek } tlv_ptr;
230*b636d99dSDavid van Moolenbroek
231*b636d99dSDavid van Moolenbroek tptr=pptr;
232*b636d99dSDavid van Moolenbroek eigrp_com_header = (const struct eigrp_common_header *)pptr;
233*b636d99dSDavid van Moolenbroek ND_TCHECK(*eigrp_com_header);
234*b636d99dSDavid van Moolenbroek
235*b636d99dSDavid van Moolenbroek /*
236*b636d99dSDavid van Moolenbroek * Sanity checking of the header.
237*b636d99dSDavid van Moolenbroek */
238*b636d99dSDavid van Moolenbroek if (eigrp_com_header->version != EIGRP_VERSION) {
239*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "EIGRP version %u packet not supported",eigrp_com_header->version));
240*b636d99dSDavid van Moolenbroek return;
241*b636d99dSDavid van Moolenbroek }
242*b636d99dSDavid van Moolenbroek
243*b636d99dSDavid van Moolenbroek /* in non-verbose mode just lets print the basic Message Type*/
244*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag < 1) {
245*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "EIGRP %s, length: %u",
246*b636d99dSDavid van Moolenbroek tok2str(eigrp_opcode_values, "unknown (%u)",eigrp_com_header->opcode),
247*b636d99dSDavid van Moolenbroek len));
248*b636d99dSDavid van Moolenbroek return;
249*b636d99dSDavid van Moolenbroek }
250*b636d99dSDavid van Moolenbroek
251*b636d99dSDavid van Moolenbroek /* ok they seem to want to know everything - lets fully decode it */
252*b636d99dSDavid van Moolenbroek
253*b636d99dSDavid van Moolenbroek tlen=len-sizeof(struct eigrp_common_header);
254*b636d99dSDavid van Moolenbroek
255*b636d99dSDavid van Moolenbroek /* FIXME print other header info */
256*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\tEIGRP v%u, opcode: %s (%u), chksum: 0x%04x, Flags: [%s]\n\tseq: 0x%08x, ack: 0x%08x, AS: %u, length: %u",
257*b636d99dSDavid van Moolenbroek eigrp_com_header->version,
258*b636d99dSDavid van Moolenbroek tok2str(eigrp_opcode_values, "unknown, type: %u",eigrp_com_header->opcode),
259*b636d99dSDavid van Moolenbroek eigrp_com_header->opcode,
260*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(&eigrp_com_header->checksum),
261*b636d99dSDavid van Moolenbroek tok2str(eigrp_common_header_flag_values,
262*b636d99dSDavid van Moolenbroek "none",
263*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&eigrp_com_header->flags)),
264*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&eigrp_com_header->seq),
265*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&eigrp_com_header->ack),
266*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&eigrp_com_header->asn),
267*b636d99dSDavid van Moolenbroek tlen));
268*b636d99dSDavid van Moolenbroek
269*b636d99dSDavid van Moolenbroek tptr+=sizeof(const struct eigrp_common_header);
270*b636d99dSDavid van Moolenbroek
271*b636d99dSDavid van Moolenbroek while(tlen>0) {
272*b636d99dSDavid van Moolenbroek /* did we capture enough for fully decoding the object header ? */
273*b636d99dSDavid van Moolenbroek ND_TCHECK2(*tptr, sizeof(struct eigrp_tlv_header));
274*b636d99dSDavid van Moolenbroek
275*b636d99dSDavid van Moolenbroek eigrp_tlv_header = (const struct eigrp_tlv_header *)tptr;
276*b636d99dSDavid van Moolenbroek eigrp_tlv_len=EXTRACT_16BITS(&eigrp_tlv_header->length);
277*b636d99dSDavid van Moolenbroek eigrp_tlv_type=EXTRACT_16BITS(&eigrp_tlv_header->type);
278*b636d99dSDavid van Moolenbroek
279*b636d99dSDavid van Moolenbroek
280*b636d99dSDavid van Moolenbroek if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header) ||
281*b636d99dSDavid van Moolenbroek eigrp_tlv_len > tlen) {
282*b636d99dSDavid van Moolenbroek print_unknown_data(ndo,tptr+sizeof(struct eigrp_tlv_header),"\n\t ",tlen);
283*b636d99dSDavid van Moolenbroek return;
284*b636d99dSDavid van Moolenbroek }
285*b636d99dSDavid van Moolenbroek
286*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t %s TLV (0x%04x), length: %u",
287*b636d99dSDavid van Moolenbroek tok2str(eigrp_tlv_values,
288*b636d99dSDavid van Moolenbroek "Unknown",
289*b636d99dSDavid van Moolenbroek eigrp_tlv_type),
290*b636d99dSDavid van Moolenbroek eigrp_tlv_type,
291*b636d99dSDavid van Moolenbroek eigrp_tlv_len));
292*b636d99dSDavid van Moolenbroek
293*b636d99dSDavid van Moolenbroek tlv_tptr=tptr+sizeof(struct eigrp_tlv_header);
294*b636d99dSDavid van Moolenbroek tlv_tlen=eigrp_tlv_len-sizeof(struct eigrp_tlv_header);
295*b636d99dSDavid van Moolenbroek
296*b636d99dSDavid van Moolenbroek /* did we capture enough for fully decoding the object ? */
297*b636d99dSDavid van Moolenbroek ND_TCHECK2(*tptr, eigrp_tlv_len);
298*b636d99dSDavid van Moolenbroek
299*b636d99dSDavid van Moolenbroek switch(eigrp_tlv_type) {
300*b636d99dSDavid van Moolenbroek
301*b636d99dSDavid van Moolenbroek case EIGRP_TLV_GENERAL_PARM:
302*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_general_parm = (const struct eigrp_tlv_general_parm_t *)tlv_tptr;
303*b636d99dSDavid van Moolenbroek
304*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t holdtime: %us, k1 %u, k2 %u, k3 %u, k4 %u, k5 %u",
305*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(tlv_ptr.eigrp_tlv_general_parm->holdtime),
306*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_general_parm->k1,
307*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_general_parm->k2,
308*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_general_parm->k3,
309*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_general_parm->k4,
310*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_general_parm->k5));
311*b636d99dSDavid van Moolenbroek break;
312*b636d99dSDavid van Moolenbroek
313*b636d99dSDavid van Moolenbroek case EIGRP_TLV_SW_VERSION:
314*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_sw_version = (const struct eigrp_tlv_sw_version_t *)tlv_tptr;
315*b636d99dSDavid van Moolenbroek
316*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t IOS version: %u.%u, EIGRP version %u.%u",
317*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_sw_version->ios_major,
318*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_sw_version->ios_minor,
319*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_sw_version->eigrp_major,
320*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_sw_version->eigrp_minor));
321*b636d99dSDavid van Moolenbroek break;
322*b636d99dSDavid van Moolenbroek
323*b636d99dSDavid van Moolenbroek case EIGRP_TLV_IP_INT:
324*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_ip_int = (const struct eigrp_tlv_ip_int_t *)tlv_tptr;
325*b636d99dSDavid van Moolenbroek
326*b636d99dSDavid van Moolenbroek bit_length = tlv_ptr.eigrp_tlv_ip_int->plen;
327*b636d99dSDavid van Moolenbroek if (bit_length > 32) {
328*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t illegal prefix length %u",bit_length));
329*b636d99dSDavid van Moolenbroek break;
330*b636d99dSDavid van Moolenbroek }
331*b636d99dSDavid van Moolenbroek byte_length = (bit_length + 7) / 8; /* variable length encoding */
332*b636d99dSDavid van Moolenbroek memset(prefix, 0, 4);
333*b636d99dSDavid van Moolenbroek memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_int->destination,byte_length);
334*b636d99dSDavid van Moolenbroek
335*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t IPv4 prefix: %15s/%u, nexthop: ",
336*b636d99dSDavid van Moolenbroek ipaddr_string(ndo, prefix),
337*b636d99dSDavid van Moolenbroek bit_length));
338*b636d99dSDavid van Moolenbroek if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->nexthop) == 0)
339*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "self"));
340*b636d99dSDavid van Moolenbroek else
341*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s",ipaddr_string(ndo, &tlv_ptr.eigrp_tlv_ip_int->nexthop)));
342*b636d99dSDavid van Moolenbroek
343*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
344*b636d99dSDavid van Moolenbroek (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->delay)/100),
345*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->bandwidth),
346*b636d99dSDavid van Moolenbroek EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_ip_int->mtu),
347*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_ip_int->hopcount,
348*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_ip_int->reliability,
349*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_ip_int->load));
350*b636d99dSDavid van Moolenbroek break;
351*b636d99dSDavid van Moolenbroek
352*b636d99dSDavid van Moolenbroek case EIGRP_TLV_IP_EXT:
353*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_ip_ext = (const struct eigrp_tlv_ip_ext_t *)tlv_tptr;
354*b636d99dSDavid van Moolenbroek
355*b636d99dSDavid van Moolenbroek bit_length = tlv_ptr.eigrp_tlv_ip_ext->plen;
356*b636d99dSDavid van Moolenbroek if (bit_length > 32) {
357*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t illegal prefix length %u",bit_length));
358*b636d99dSDavid van Moolenbroek break;
359*b636d99dSDavid van Moolenbroek }
360*b636d99dSDavid van Moolenbroek byte_length = (bit_length + 7) / 8; /* variable length encoding */
361*b636d99dSDavid van Moolenbroek memset(prefix, 0, 4);
362*b636d99dSDavid van Moolenbroek memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_ext->destination,byte_length);
363*b636d99dSDavid van Moolenbroek
364*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t IPv4 prefix: %15s/%u, nexthop: ",
365*b636d99dSDavid van Moolenbroek ipaddr_string(ndo, prefix),
366*b636d99dSDavid van Moolenbroek bit_length));
367*b636d99dSDavid van Moolenbroek if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->nexthop) == 0)
368*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "self"));
369*b636d99dSDavid van Moolenbroek else
370*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%s",ipaddr_string(ndo, &tlv_ptr.eigrp_tlv_ip_ext->nexthop)));
371*b636d99dSDavid van Moolenbroek
372*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t origin-router %s, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u",
373*b636d99dSDavid van Moolenbroek ipaddr_string(ndo, tlv_ptr.eigrp_tlv_ip_ext->origin_router),
374*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->origin_as),
375*b636d99dSDavid van Moolenbroek tok2str(eigrp_ext_proto_id_values,"unknown",tlv_ptr.eigrp_tlv_ip_ext->proto_id),
376*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_ip_ext->flags,
377*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->tag),
378*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->metric)));
379*b636d99dSDavid van Moolenbroek
380*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
381*b636d99dSDavid van Moolenbroek (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->delay)/100),
382*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->bandwidth),
383*b636d99dSDavid van Moolenbroek EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_ip_ext->mtu),
384*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_ip_ext->hopcount,
385*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_ip_ext->reliability,
386*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_ip_ext->load));
387*b636d99dSDavid van Moolenbroek break;
388*b636d99dSDavid van Moolenbroek
389*b636d99dSDavid van Moolenbroek case EIGRP_TLV_AT_CABLE_SETUP:
390*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_at_cable_setup = (const struct eigrp_tlv_at_cable_setup_t *)tlv_tptr;
391*b636d99dSDavid van Moolenbroek
392*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Cable-range: %u-%u, Router-ID %u",
393*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_start),
394*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_end),
395*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->router_id)));
396*b636d99dSDavid van Moolenbroek break;
397*b636d99dSDavid van Moolenbroek
398*b636d99dSDavid van Moolenbroek case EIGRP_TLV_AT_INT:
399*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_at_int = (const struct eigrp_tlv_at_int_t *)tlv_tptr;
400*b636d99dSDavid van Moolenbroek
401*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Cable-Range: %u-%u, nexthop: ",
402*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_start),
403*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_end)));
404*b636d99dSDavid van Moolenbroek
405*b636d99dSDavid van Moolenbroek if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop) == 0)
406*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "self"));
407*b636d99dSDavid van Moolenbroek else
408*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%u.%u",
409*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop),
410*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop[2])));
411*b636d99dSDavid van Moolenbroek
412*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
413*b636d99dSDavid van Moolenbroek (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->delay)/100),
414*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->bandwidth),
415*b636d99dSDavid van Moolenbroek EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_at_int->mtu),
416*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_at_int->hopcount,
417*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_at_int->reliability,
418*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_at_int->load));
419*b636d99dSDavid van Moolenbroek break;
420*b636d99dSDavid van Moolenbroek
421*b636d99dSDavid van Moolenbroek case EIGRP_TLV_AT_EXT:
422*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_at_ext = (const struct eigrp_tlv_at_ext_t *)tlv_tptr;
423*b636d99dSDavid van Moolenbroek
424*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t Cable-Range: %u-%u, nexthop: ",
425*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_start),
426*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_end)));
427*b636d99dSDavid van Moolenbroek
428*b636d99dSDavid van Moolenbroek if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop) == 0)
429*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "self"));
430*b636d99dSDavid van Moolenbroek else
431*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "%u.%u",
432*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop),
433*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop[2])));
434*b636d99dSDavid van Moolenbroek
435*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t origin-router %u, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u",
436*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->origin_router),
437*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->origin_as),
438*b636d99dSDavid van Moolenbroek tok2str(eigrp_ext_proto_id_values,"unknown",tlv_ptr.eigrp_tlv_at_ext->proto_id),
439*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_at_ext->flags,
440*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->tag),
441*b636d99dSDavid van Moolenbroek EXTRACT_16BITS(tlv_ptr.eigrp_tlv_at_ext->metric)));
442*b636d99dSDavid van Moolenbroek
443*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
444*b636d99dSDavid van Moolenbroek (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->delay)/100),
445*b636d99dSDavid van Moolenbroek EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->bandwidth),
446*b636d99dSDavid van Moolenbroek EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_at_ext->mtu),
447*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_at_ext->hopcount,
448*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_at_ext->reliability,
449*b636d99dSDavid van Moolenbroek tlv_ptr.eigrp_tlv_at_ext->load));
450*b636d99dSDavid van Moolenbroek break;
451*b636d99dSDavid van Moolenbroek
452*b636d99dSDavid van Moolenbroek /*
453*b636d99dSDavid van Moolenbroek * FIXME those are the defined TLVs that lack a decoder
454*b636d99dSDavid van Moolenbroek * you are welcome to contribute code ;-)
455*b636d99dSDavid van Moolenbroek */
456*b636d99dSDavid van Moolenbroek
457*b636d99dSDavid van Moolenbroek case EIGRP_TLV_AUTH:
458*b636d99dSDavid van Moolenbroek case EIGRP_TLV_SEQ:
459*b636d99dSDavid van Moolenbroek case EIGRP_TLV_MCAST_SEQ:
460*b636d99dSDavid van Moolenbroek case EIGRP_TLV_IPX_INT:
461*b636d99dSDavid van Moolenbroek case EIGRP_TLV_IPX_EXT:
462*b636d99dSDavid van Moolenbroek
463*b636d99dSDavid van Moolenbroek default:
464*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag <= 1)
465*b636d99dSDavid van Moolenbroek print_unknown_data(ndo,tlv_tptr,"\n\t ",tlv_tlen);
466*b636d99dSDavid van Moolenbroek break;
467*b636d99dSDavid van Moolenbroek }
468*b636d99dSDavid van Moolenbroek /* do we want to see an additionally hexdump ? */
469*b636d99dSDavid van Moolenbroek if (ndo->ndo_vflag > 1)
470*b636d99dSDavid van Moolenbroek print_unknown_data(ndo,tptr+sizeof(struct eigrp_tlv_header),"\n\t ",
471*b636d99dSDavid van Moolenbroek eigrp_tlv_len-sizeof(struct eigrp_tlv_header));
472*b636d99dSDavid van Moolenbroek
473*b636d99dSDavid van Moolenbroek tptr+=eigrp_tlv_len;
474*b636d99dSDavid van Moolenbroek tlen-=eigrp_tlv_len;
475*b636d99dSDavid van Moolenbroek }
476*b636d99dSDavid van Moolenbroek return;
477*b636d99dSDavid van Moolenbroek trunc:
478*b636d99dSDavid van Moolenbroek ND_PRINT((ndo, "\n\t\t packet exceeded snapshot"));
479*b636d99dSDavid van Moolenbroek }
480