xref: /freebsd/contrib/tcpdump/print-eigrp.c (revision 1de50e9f417616cf647a842762944a2301cb1415)
11de50e9fSSam Leffler /*
21de50e9fSSam Leffler  * Copyright (c) 1998-2004  Hannes Gredler <hannes@tcpdump.org>
31de50e9fSSam Leffler  *      The TCPDUMP project
41de50e9fSSam Leffler  *
51de50e9fSSam Leffler  * Redistribution and use in source and binary forms, with or without
61de50e9fSSam Leffler  * modification, are permitted provided that: (1) source code
71de50e9fSSam Leffler  * distributions retain the above copyright notice and this paragraph
81de50e9fSSam Leffler  * in its entirety, and (2) distributions including binary code include
91de50e9fSSam Leffler  * the above copyright notice and this paragraph in its entirety in
101de50e9fSSam Leffler  * the documentation or other materials provided with the distribution.
111de50e9fSSam Leffler  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND
121de50e9fSSam Leffler  * WITHOUT ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, WITHOUT
131de50e9fSSam Leffler  * LIMITATION, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
141de50e9fSSam Leffler  * FOR A PARTICULAR PURPOSE.
151de50e9fSSam Leffler  */
161de50e9fSSam Leffler 
171de50e9fSSam Leffler #ifndef lint
181de50e9fSSam Leffler static const char rcsid[] _U_ =
191de50e9fSSam Leffler     "@(#) $Header: /tcpdump/master/tcpdump/print-eigrp.c,v 1.5 2004/05/12 22:22:40 hannes Exp $";
201de50e9fSSam Leffler #endif
211de50e9fSSam Leffler 
221de50e9fSSam Leffler #ifdef HAVE_CONFIG_H
231de50e9fSSam Leffler #include "config.h"
241de50e9fSSam Leffler #endif
251de50e9fSSam Leffler 
261de50e9fSSam Leffler #include <tcpdump-stdinc.h>
271de50e9fSSam Leffler 
281de50e9fSSam Leffler #include <stdio.h>
291de50e9fSSam Leffler #include <stdlib.h>
301de50e9fSSam Leffler #include <string.h>
311de50e9fSSam Leffler 
321de50e9fSSam Leffler #include "interface.h"
331de50e9fSSam Leffler #include "extract.h"
341de50e9fSSam Leffler #include "addrtoname.h"
351de50e9fSSam Leffler 
361de50e9fSSam Leffler /*
371de50e9fSSam Leffler  * packet format documented at
381de50e9fSSam Leffler  * http://www.rhyshaden.com/eigrp.htm
391de50e9fSSam Leffler  */
401de50e9fSSam Leffler 
411de50e9fSSam Leffler struct eigrp_common_header {
421de50e9fSSam Leffler     u_int8_t version;
431de50e9fSSam Leffler     u_int8_t opcode;
441de50e9fSSam Leffler     u_int8_t checksum[2];
451de50e9fSSam Leffler     u_int8_t flags[4];
461de50e9fSSam Leffler     u_int8_t seq[4];
471de50e9fSSam Leffler     u_int8_t ack[4];
481de50e9fSSam Leffler     u_int8_t asn[4];
491de50e9fSSam Leffler };
501de50e9fSSam Leffler 
511de50e9fSSam Leffler #define	EIGRP_VERSION                        2
521de50e9fSSam Leffler 
531de50e9fSSam Leffler #define	EIGRP_OPCODE_UPDATE                  1
541de50e9fSSam Leffler #define	EIGRP_OPCODE_QUERY                   3
551de50e9fSSam Leffler #define	EIGRP_OPCODE_REPLY                   4
561de50e9fSSam Leffler #define	EIGRP_OPCODE_HELLO                   5
571de50e9fSSam Leffler #define	EIGRP_OPCODE_IPXSAP                  6
581de50e9fSSam Leffler #define	EIGRP_OPCODE_PROBE                   7
591de50e9fSSam Leffler 
601de50e9fSSam Leffler static const struct tok eigrp_opcode_values[] = {
611de50e9fSSam Leffler     { EIGRP_OPCODE_UPDATE, "Update" },
621de50e9fSSam Leffler     { EIGRP_OPCODE_QUERY, "Query" },
631de50e9fSSam Leffler     { EIGRP_OPCODE_REPLY, "Reply" },
641de50e9fSSam Leffler     { EIGRP_OPCODE_HELLO, "Hello" },
651de50e9fSSam Leffler     { EIGRP_OPCODE_IPXSAP, "IPX SAP" },
661de50e9fSSam Leffler     { EIGRP_OPCODE_PROBE, "Probe" },
671de50e9fSSam Leffler     { 0, NULL}
681de50e9fSSam Leffler };
691de50e9fSSam Leffler 
701de50e9fSSam Leffler static const struct tok eigrp_common_header_flag_values[] = {
711de50e9fSSam Leffler     { 0x01, "Init" },
721de50e9fSSam Leffler     { 0x02, "Conditionally Received" },
731de50e9fSSam Leffler     { 0, NULL}
741de50e9fSSam Leffler };
751de50e9fSSam Leffler 
761de50e9fSSam Leffler struct eigrp_tlv_header {
771de50e9fSSam Leffler     u_int8_t type[2];
781de50e9fSSam Leffler     u_int8_t length[2];
791de50e9fSSam Leffler };
801de50e9fSSam Leffler 
811de50e9fSSam Leffler #define EIGRP_TLV_GENERAL_PARM   0x0001
821de50e9fSSam Leffler #define EIGRP_TLV_AUTH           0x0002
831de50e9fSSam Leffler #define EIGRP_TLV_SEQ            0x0003
841de50e9fSSam Leffler #define EIGRP_TLV_SW_VERSION     0x0004
851de50e9fSSam Leffler #define EIGRP_TLV_MCAST_SEQ      0x0005
861de50e9fSSam Leffler #define EIGRP_TLV_IP_INT         0x0102
871de50e9fSSam Leffler #define EIGRP_TLV_IP_EXT         0x0103
881de50e9fSSam Leffler #define EIGRP_TLV_AT_INT         0x0202
891de50e9fSSam Leffler #define EIGRP_TLV_AT_EXT         0x0203
901de50e9fSSam Leffler #define EIGRP_TLV_AT_CABLE_SETUP 0x0204
911de50e9fSSam Leffler #define EIGRP_TLV_IPX_INT        0x0302
921de50e9fSSam Leffler #define EIGRP_TLV_IPX_EXT        0x0303
931de50e9fSSam Leffler 
941de50e9fSSam Leffler static const struct tok eigrp_tlv_values[] = {
951de50e9fSSam Leffler     { EIGRP_TLV_GENERAL_PARM, "General Parameters"},
961de50e9fSSam Leffler     { EIGRP_TLV_AUTH, "Authentication"},
971de50e9fSSam Leffler     { EIGRP_TLV_SEQ, "Sequence"},
981de50e9fSSam Leffler     { EIGRP_TLV_SW_VERSION, "Software Version"},
991de50e9fSSam Leffler     { EIGRP_TLV_MCAST_SEQ, "Next Multicast Sequence"},
1001de50e9fSSam Leffler     { EIGRP_TLV_IP_INT, "IP Internal routes"},
1011de50e9fSSam Leffler     { EIGRP_TLV_IP_EXT, "IP External routes"},
1021de50e9fSSam Leffler     { EIGRP_TLV_AT_INT, "AppleTalk Internal routes"},
1031de50e9fSSam Leffler     { EIGRP_TLV_AT_EXT, "AppleTalk External routes"},
1041de50e9fSSam Leffler     { EIGRP_TLV_AT_CABLE_SETUP, "AppleTalk Cable setup"},
1051de50e9fSSam Leffler     { EIGRP_TLV_IPX_INT, "IPX Internal routes"},
1061de50e9fSSam Leffler     { EIGRP_TLV_IPX_EXT, "IPX External routes"},
1071de50e9fSSam Leffler     { 0, NULL}
1081de50e9fSSam Leffler };
1091de50e9fSSam Leffler 
1101de50e9fSSam Leffler struct eigrp_tlv_general_parm_t {
1111de50e9fSSam Leffler     u_int8_t k1;
1121de50e9fSSam Leffler     u_int8_t k2;
1131de50e9fSSam Leffler     u_int8_t k3;
1141de50e9fSSam Leffler     u_int8_t k4;
1151de50e9fSSam Leffler     u_int8_t k5;
1161de50e9fSSam Leffler     u_int8_t res;
1171de50e9fSSam Leffler     u_int8_t holdtime[2];
1181de50e9fSSam Leffler };
1191de50e9fSSam Leffler 
1201de50e9fSSam Leffler struct eigrp_tlv_sw_version_t {
1211de50e9fSSam Leffler     u_int8_t ios_major;
1221de50e9fSSam Leffler     u_int8_t ios_minor;
1231de50e9fSSam Leffler     u_int8_t eigrp_major;
1241de50e9fSSam Leffler     u_int8_t eigrp_minor;
1251de50e9fSSam Leffler };
1261de50e9fSSam Leffler 
1271de50e9fSSam Leffler struct eigrp_tlv_ip_int_t {
1281de50e9fSSam Leffler     u_int8_t nexthop[4];
1291de50e9fSSam Leffler     u_int8_t delay[4];
1301de50e9fSSam Leffler     u_int8_t bandwidth[4];
1311de50e9fSSam Leffler     u_int8_t mtu[3];
1321de50e9fSSam Leffler     u_int8_t hopcount;
1331de50e9fSSam Leffler     u_int8_t reliability;
1341de50e9fSSam Leffler     u_int8_t load;
1351de50e9fSSam Leffler     u_int8_t reserved[2];
1361de50e9fSSam Leffler     u_int8_t plen;
1371de50e9fSSam Leffler     u_int8_t destination; /* variable length [1-4] bytes encoding */
1381de50e9fSSam Leffler };
1391de50e9fSSam Leffler 
1401de50e9fSSam Leffler struct eigrp_tlv_ip_ext_t {
1411de50e9fSSam Leffler     u_int8_t nexthop[4];
1421de50e9fSSam Leffler     u_int8_t origin_router[4];
1431de50e9fSSam Leffler     u_int8_t origin_as[4];
1441de50e9fSSam Leffler     u_int8_t tag[4];
1451de50e9fSSam Leffler     u_int8_t metric[4];
1461de50e9fSSam Leffler     u_int8_t reserved[2];
1471de50e9fSSam Leffler     u_int8_t proto_id;
1481de50e9fSSam Leffler     u_int8_t flags;
1491de50e9fSSam Leffler     u_int8_t delay[4];
1501de50e9fSSam Leffler     u_int8_t bandwidth[4];
1511de50e9fSSam Leffler     u_int8_t mtu[3];
1521de50e9fSSam Leffler     u_int8_t hopcount;
1531de50e9fSSam Leffler     u_int8_t reliability;
1541de50e9fSSam Leffler     u_int8_t load;
1551de50e9fSSam Leffler     u_int8_t reserved2[2];
1561de50e9fSSam Leffler     u_int8_t plen;
1571de50e9fSSam Leffler     u_int8_t destination; /* variable length [1-4] bytes encoding */
1581de50e9fSSam Leffler };
1591de50e9fSSam Leffler 
1601de50e9fSSam Leffler struct eigrp_tlv_at_cable_setup_t {
1611de50e9fSSam Leffler     u_int8_t cable_start[2];
1621de50e9fSSam Leffler     u_int8_t cable_end[2];
1631de50e9fSSam Leffler     u_int8_t router_id[4];
1641de50e9fSSam Leffler };
1651de50e9fSSam Leffler 
1661de50e9fSSam Leffler struct eigrp_tlv_at_int_t {
1671de50e9fSSam Leffler     u_int8_t nexthop[4];
1681de50e9fSSam Leffler     u_int8_t delay[4];
1691de50e9fSSam Leffler     u_int8_t bandwidth[4];
1701de50e9fSSam Leffler     u_int8_t mtu[3];
1711de50e9fSSam Leffler     u_int8_t hopcount;
1721de50e9fSSam Leffler     u_int8_t reliability;
1731de50e9fSSam Leffler     u_int8_t load;
1741de50e9fSSam Leffler     u_int8_t reserved[2];
1751de50e9fSSam Leffler     u_int8_t cable_start[2];
1761de50e9fSSam Leffler     u_int8_t cable_end[2];
1771de50e9fSSam Leffler };
1781de50e9fSSam Leffler 
1791de50e9fSSam Leffler struct eigrp_tlv_at_ext_t {
1801de50e9fSSam Leffler     u_int8_t nexthop[4];
1811de50e9fSSam Leffler     u_int8_t origin_router[4];
1821de50e9fSSam Leffler     u_int8_t origin_as[4];
1831de50e9fSSam Leffler     u_int8_t tag[4];
1841de50e9fSSam Leffler     u_int8_t proto_id;
1851de50e9fSSam Leffler     u_int8_t flags;
1861de50e9fSSam Leffler     u_int8_t metric[2];
1871de50e9fSSam Leffler     u_int8_t delay[4];
1881de50e9fSSam Leffler     u_int8_t bandwidth[4];
1891de50e9fSSam Leffler     u_int8_t mtu[3];
1901de50e9fSSam Leffler     u_int8_t hopcount;
1911de50e9fSSam Leffler     u_int8_t reliability;
1921de50e9fSSam Leffler     u_int8_t load;
1931de50e9fSSam Leffler     u_int8_t reserved2[2];
1941de50e9fSSam Leffler     u_int8_t cable_start[2];
1951de50e9fSSam Leffler     u_int8_t cable_end[2];
1961de50e9fSSam Leffler };
1971de50e9fSSam Leffler 
1981de50e9fSSam Leffler static const struct tok eigrp_ext_proto_id_values[] = {
1991de50e9fSSam Leffler     { 0x01, "IGRP" },
2001de50e9fSSam Leffler     { 0x02, "EIGRP" },
2011de50e9fSSam Leffler     { 0x03, "Static" },
2021de50e9fSSam Leffler     { 0x04, "RIP" },
2031de50e9fSSam Leffler     { 0x05, "Hello" },
2041de50e9fSSam Leffler     { 0x06, "OSPF" },
2051de50e9fSSam Leffler     { 0x07, "IS-IS" },
2061de50e9fSSam Leffler     { 0x08, "EGP" },
2071de50e9fSSam Leffler     { 0x09, "BGP" },
2081de50e9fSSam Leffler     { 0x0a, "IDRP" },
2091de50e9fSSam Leffler     { 0x0b, "Connected" },
2101de50e9fSSam Leffler     { 0, NULL}
2111de50e9fSSam Leffler };
2121de50e9fSSam Leffler 
2131de50e9fSSam Leffler void
2141de50e9fSSam Leffler eigrp_print(register const u_char *pptr, register u_int len) {
2151de50e9fSSam Leffler 
2161de50e9fSSam Leffler     const struct eigrp_common_header *eigrp_com_header;
2171de50e9fSSam Leffler     const struct eigrp_tlv_header *eigrp_tlv_header;
2181de50e9fSSam Leffler     const u_char *tptr,*tlv_tptr;
2191de50e9fSSam Leffler     int tlen,eigrp_tlv_len,eigrp_tlv_type,tlv_tlen,byte_length, bit_length;
2201de50e9fSSam Leffler     u_int8_t prefix[4];
2211de50e9fSSam Leffler 
2221de50e9fSSam Leffler     union {
2231de50e9fSSam Leffler         const struct eigrp_tlv_general_parm_t *eigrp_tlv_general_parm;
2241de50e9fSSam Leffler         const struct eigrp_tlv_sw_version_t *eigrp_tlv_sw_version;
2251de50e9fSSam Leffler         const struct eigrp_tlv_ip_int_t *eigrp_tlv_ip_int;
2261de50e9fSSam Leffler         const struct eigrp_tlv_ip_ext_t *eigrp_tlv_ip_ext;
2271de50e9fSSam Leffler         const struct eigrp_tlv_at_cable_setup_t *eigrp_tlv_at_cable_setup;
2281de50e9fSSam Leffler         const struct eigrp_tlv_at_int_t *eigrp_tlv_at_int;
2291de50e9fSSam Leffler         const struct eigrp_tlv_at_ext_t *eigrp_tlv_at_ext;
2301de50e9fSSam Leffler     } tlv_ptr;
2311de50e9fSSam Leffler 
2321de50e9fSSam Leffler     tptr=pptr;
2331de50e9fSSam Leffler     eigrp_com_header = (const struct eigrp_common_header *)pptr;
2341de50e9fSSam Leffler     TCHECK(*eigrp_com_header);
2351de50e9fSSam Leffler 
2361de50e9fSSam Leffler     /*
2371de50e9fSSam Leffler      * Sanity checking of the header.
2381de50e9fSSam Leffler      */
2391de50e9fSSam Leffler     if (eigrp_com_header->version != EIGRP_VERSION) {
2401de50e9fSSam Leffler 	printf("EIGRP version %u packet not supported",eigrp_com_header->version);
2411de50e9fSSam Leffler 	return;
2421de50e9fSSam Leffler     }
2431de50e9fSSam Leffler 
2441de50e9fSSam Leffler     /* in non-verbose mode just lets print the basic Message Type*/
2451de50e9fSSam Leffler     if (vflag < 1) {
2461de50e9fSSam Leffler         printf("EIGRP %s, length: %u",
2471de50e9fSSam Leffler                tok2str(eigrp_opcode_values, "unknown (%u)",eigrp_com_header->opcode),
2481de50e9fSSam Leffler                len);
2491de50e9fSSam Leffler         return;
2501de50e9fSSam Leffler     }
2511de50e9fSSam Leffler 
2521de50e9fSSam Leffler     /* ok they seem to want to know everything - lets fully decode it */
2531de50e9fSSam Leffler 
2541de50e9fSSam Leffler     tlen=len-sizeof(struct eigrp_common_header);
2551de50e9fSSam Leffler 
2561de50e9fSSam Leffler     /* FIXME print other header info */
2571de50e9fSSam Leffler     printf("\n\tEIGRP v%u, opcode: %s (%u), chksum: 0x%04x, Flags: [%s]\n\tseq: 0x%08x, ack: 0x%08x, AS: %u, length: %u",
2581de50e9fSSam Leffler            eigrp_com_header->version,
2591de50e9fSSam Leffler            tok2str(eigrp_opcode_values, "unknown, type: %u",eigrp_com_header->opcode),
2601de50e9fSSam Leffler            eigrp_com_header->opcode,
2611de50e9fSSam Leffler            EXTRACT_16BITS(&eigrp_com_header->checksum),
2621de50e9fSSam Leffler            tok2str(eigrp_common_header_flag_values,
2631de50e9fSSam Leffler                    "none",
2641de50e9fSSam Leffler                    EXTRACT_32BITS(&eigrp_com_header->flags)),
2651de50e9fSSam Leffler            EXTRACT_32BITS(&eigrp_com_header->seq),
2661de50e9fSSam Leffler            EXTRACT_32BITS(&eigrp_com_header->ack),
2671de50e9fSSam Leffler            EXTRACT_32BITS(&eigrp_com_header->asn),
2681de50e9fSSam Leffler            tlen);
2691de50e9fSSam Leffler 
2701de50e9fSSam Leffler     tptr+=sizeof(const struct eigrp_common_header);
2711de50e9fSSam Leffler 
2721de50e9fSSam Leffler     while(tlen>0) {
2731de50e9fSSam Leffler         /* did we capture enough for fully decoding the object header ? */
2741de50e9fSSam Leffler         if (!TTEST2(*tptr, sizeof(struct eigrp_tlv_header)))
2751de50e9fSSam Leffler             goto trunc;
2761de50e9fSSam Leffler 
2771de50e9fSSam Leffler         eigrp_tlv_header = (const struct eigrp_tlv_header *)tptr;
2781de50e9fSSam Leffler         eigrp_tlv_len=EXTRACT_16BITS(&eigrp_tlv_header->length);
2791de50e9fSSam Leffler         eigrp_tlv_type=EXTRACT_16BITS(&eigrp_tlv_header->type);
2801de50e9fSSam Leffler 
2811de50e9fSSam Leffler 
2821de50e9fSSam Leffler         if (eigrp_tlv_len == 0 || eigrp_tlv_len > tlen) {
2831de50e9fSSam Leffler             print_unknown_data(tptr+sizeof(sizeof(struct eigrp_tlv_header)),"\n\t    ",tlen);
2841de50e9fSSam Leffler             return;
2851de50e9fSSam Leffler         }
2861de50e9fSSam Leffler 
2871de50e9fSSam Leffler         printf("\n\t  %s TLV (0x%04x), length: %u",
2881de50e9fSSam Leffler                tok2str(eigrp_tlv_values,
2891de50e9fSSam Leffler                        "Unknown",
2901de50e9fSSam Leffler                        eigrp_tlv_type),
2911de50e9fSSam Leffler                eigrp_tlv_type,
2921de50e9fSSam Leffler                eigrp_tlv_len);
2931de50e9fSSam Leffler 
2941de50e9fSSam Leffler         tlv_tptr=tptr+sizeof(struct eigrp_tlv_header);
2951de50e9fSSam Leffler         tlv_tlen=eigrp_tlv_len-sizeof(struct eigrp_tlv_header);
2961de50e9fSSam Leffler 
2971de50e9fSSam Leffler         /* did we capture enough for fully decoding the object ? */
2981de50e9fSSam Leffler         if (!TTEST2(*tptr, eigrp_tlv_len))
2991de50e9fSSam Leffler             goto trunc;
3001de50e9fSSam Leffler 
3011de50e9fSSam Leffler         switch(eigrp_tlv_type) {
3021de50e9fSSam Leffler 
3031de50e9fSSam Leffler         case EIGRP_TLV_GENERAL_PARM:
3041de50e9fSSam Leffler             tlv_ptr.eigrp_tlv_general_parm = (const struct eigrp_tlv_general_parm_t *)tlv_tptr;
3051de50e9fSSam Leffler 
3061de50e9fSSam Leffler             printf("\n\t    holdtime: %us, k1 %u, k2 %u, k3 %u, k4 %u, k5 %u",
3071de50e9fSSam Leffler                    EXTRACT_16BITS(tlv_ptr.eigrp_tlv_general_parm->holdtime),
3081de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_general_parm->k1,
3091de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_general_parm->k2,
3101de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_general_parm->k3,
3111de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_general_parm->k4,
3121de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_general_parm->k5);
3131de50e9fSSam Leffler             break;
3141de50e9fSSam Leffler 
3151de50e9fSSam Leffler         case EIGRP_TLV_SW_VERSION:
3161de50e9fSSam Leffler             tlv_ptr.eigrp_tlv_sw_version = (const struct eigrp_tlv_sw_version_t *)tlv_tptr;
3171de50e9fSSam Leffler 
3181de50e9fSSam Leffler             printf("\n\t    IOS version: %u.%u, EIGRP version %u.%u",
3191de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_sw_version->ios_major,
3201de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_sw_version->ios_minor,
3211de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_sw_version->eigrp_major,
3221de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_sw_version->eigrp_minor);
3231de50e9fSSam Leffler             break;
3241de50e9fSSam Leffler 
3251de50e9fSSam Leffler         case EIGRP_TLV_IP_INT:
3261de50e9fSSam Leffler             tlv_ptr.eigrp_tlv_ip_int = (const struct eigrp_tlv_ip_int_t *)tlv_tptr;
3271de50e9fSSam Leffler 
3281de50e9fSSam Leffler             bit_length = tlv_ptr.eigrp_tlv_ip_int->plen;
3291de50e9fSSam Leffler             if (bit_length < 0 || bit_length > 32) {
3301de50e9fSSam Leffler                 printf("\n\t    illegal prefix length %u",bit_length);
3311de50e9fSSam Leffler                 break;
3321de50e9fSSam Leffler             }
3331de50e9fSSam Leffler             byte_length = (bit_length + 7) / 8; /* variable length encoding */
3341de50e9fSSam Leffler             memset(prefix, 0, 4);
3351de50e9fSSam Leffler             memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_int->destination,byte_length);
3361de50e9fSSam Leffler 
3371de50e9fSSam Leffler             printf("\n\t    IPv4 prefix: %15s/%u, nexthop: ",
3381de50e9fSSam Leffler                    ipaddr_string(prefix),
3391de50e9fSSam Leffler                    bit_length);
3401de50e9fSSam Leffler             if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->nexthop) == 0)
3411de50e9fSSam Leffler                 printf("self");
3421de50e9fSSam Leffler             else
3431de50e9fSSam Leffler                 printf("%s",ipaddr_string(EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->nexthop)));
3441de50e9fSSam Leffler 
3451de50e9fSSam Leffler             printf("\n\t      delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
3461de50e9fSSam Leffler                    (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->delay)/100),
3471de50e9fSSam Leffler                    EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->bandwidth),
3481de50e9fSSam Leffler                    EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_ip_int->mtu),
3491de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_ip_int->hopcount,
3501de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_ip_int->reliability,
3511de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_ip_int->load);
3521de50e9fSSam Leffler             break;
3531de50e9fSSam Leffler 
3541de50e9fSSam Leffler         case EIGRP_TLV_IP_EXT:
3551de50e9fSSam Leffler             tlv_ptr.eigrp_tlv_ip_ext = (const struct eigrp_tlv_ip_ext_t *)tlv_tptr;
3561de50e9fSSam Leffler 
3571de50e9fSSam Leffler             bit_length = tlv_ptr.eigrp_tlv_ip_ext->plen;
3581de50e9fSSam Leffler             if (bit_length < 0 || bit_length > 32) {
3591de50e9fSSam Leffler                 printf("\n\t    illegal prefix length %u",bit_length);
3601de50e9fSSam Leffler                 break;
3611de50e9fSSam Leffler             }
3621de50e9fSSam Leffler             byte_length = (bit_length + 7) / 8; /* variable length encoding */
3631de50e9fSSam Leffler             memset(prefix, 0, 4);
3641de50e9fSSam Leffler             memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_ext->destination,byte_length);
3651de50e9fSSam Leffler 
3661de50e9fSSam Leffler             printf("\n\t    IPv4 prefix: %15s/%u, nexthop: ",
3671de50e9fSSam Leffler                    ipaddr_string(prefix),
3681de50e9fSSam Leffler                    bit_length);
3691de50e9fSSam Leffler             if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->nexthop) == 0)
3701de50e9fSSam Leffler                 printf("self");
3711de50e9fSSam Leffler             else
3721de50e9fSSam Leffler                 printf("%s",ipaddr_string(EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->nexthop)));
3731de50e9fSSam Leffler 
3741de50e9fSSam Leffler             printf("\n\t      origin-router %s, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u",
3751de50e9fSSam Leffler                    ipaddr_string(tlv_ptr.eigrp_tlv_ip_ext->origin_router),
3761de50e9fSSam Leffler                    EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->origin_as),
3771de50e9fSSam Leffler                    tok2str(eigrp_ext_proto_id_values,"unknown",tlv_ptr.eigrp_tlv_ip_ext->proto_id),
3781de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_ip_ext->flags,
3791de50e9fSSam Leffler                    EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->tag),
3801de50e9fSSam Leffler                    EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->metric));
3811de50e9fSSam Leffler 
3821de50e9fSSam Leffler             printf("\n\t      delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
3831de50e9fSSam Leffler                    (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->delay)/100),
3841de50e9fSSam Leffler                    EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->bandwidth),
3851de50e9fSSam Leffler                    EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_ip_ext->mtu),
3861de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_ip_ext->hopcount,
3871de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_ip_ext->reliability,
3881de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_ip_ext->load);
3891de50e9fSSam Leffler             break;
3901de50e9fSSam Leffler 
3911de50e9fSSam Leffler         case EIGRP_TLV_AT_CABLE_SETUP:
3921de50e9fSSam Leffler             tlv_ptr.eigrp_tlv_at_cable_setup = (const struct eigrp_tlv_at_cable_setup_t *)tlv_tptr;
3931de50e9fSSam Leffler 
3941de50e9fSSam Leffler             printf("\n\t    Cable-range: %u-%u, Router-ID %u",
3951de50e9fSSam Leffler                    EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_start),
3961de50e9fSSam Leffler                    EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_end),
3971de50e9fSSam Leffler                    EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->router_id));
3981de50e9fSSam Leffler             break;
3991de50e9fSSam Leffler 
4001de50e9fSSam Leffler         case EIGRP_TLV_AT_INT:
4011de50e9fSSam Leffler             tlv_ptr.eigrp_tlv_at_int = (const struct eigrp_tlv_at_int_t *)tlv_tptr;
4021de50e9fSSam Leffler 
4031de50e9fSSam Leffler             printf("\n\t     Cable-Range: %u-%u, nexthop: ",
4041de50e9fSSam Leffler                    EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_start),
4051de50e9fSSam Leffler                    EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_end));
4061de50e9fSSam Leffler 
4071de50e9fSSam Leffler             if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop) == 0)
4081de50e9fSSam Leffler                 printf("self");
4091de50e9fSSam Leffler             else
4101de50e9fSSam Leffler                 printf("%u.%u",
4111de50e9fSSam Leffler                        EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop),
4121de50e9fSSam Leffler                        EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop[2]));
4131de50e9fSSam Leffler 
4141de50e9fSSam Leffler             printf("\n\t      delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
4151de50e9fSSam Leffler                    (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->delay)/100),
4161de50e9fSSam Leffler                    EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->bandwidth),
4171de50e9fSSam Leffler                    EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_at_int->mtu),
4181de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_at_int->hopcount,
4191de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_at_int->reliability,
4201de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_at_int->load);
4211de50e9fSSam Leffler             break;
4221de50e9fSSam Leffler 
4231de50e9fSSam Leffler         case EIGRP_TLV_AT_EXT:
4241de50e9fSSam Leffler             tlv_ptr.eigrp_tlv_at_ext = (const struct eigrp_tlv_at_ext_t *)tlv_tptr;
4251de50e9fSSam Leffler 
4261de50e9fSSam Leffler             printf("\n\t     Cable-Range: %u-%u, nexthop: ",
4271de50e9fSSam Leffler                    EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_start),
4281de50e9fSSam Leffler                    EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_end));
4291de50e9fSSam Leffler 
4301de50e9fSSam Leffler             if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop) == 0)
4311de50e9fSSam Leffler                 printf("self");
4321de50e9fSSam Leffler             else
4331de50e9fSSam Leffler                 printf("%u.%u",
4341de50e9fSSam Leffler                        EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop),
4351de50e9fSSam Leffler                        EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop[2]));
4361de50e9fSSam Leffler 
4371de50e9fSSam Leffler             printf("\n\t      origin-router %u, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u",
4381de50e9fSSam Leffler                    EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->origin_router),
4391de50e9fSSam Leffler                    EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->origin_as),
4401de50e9fSSam Leffler                    tok2str(eigrp_ext_proto_id_values,"unknown",tlv_ptr.eigrp_tlv_at_ext->proto_id),
4411de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_at_ext->flags,
4421de50e9fSSam Leffler                    EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->tag),
4431de50e9fSSam Leffler                    EXTRACT_16BITS(tlv_ptr.eigrp_tlv_at_ext->metric));
4441de50e9fSSam Leffler 
4451de50e9fSSam Leffler             printf("\n\t      delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u",
4461de50e9fSSam Leffler                    (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->delay)/100),
4471de50e9fSSam Leffler                    EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->bandwidth),
4481de50e9fSSam Leffler                    EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_at_ext->mtu),
4491de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_at_ext->hopcount,
4501de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_at_ext->reliability,
4511de50e9fSSam Leffler                    tlv_ptr.eigrp_tlv_at_ext->load);
4521de50e9fSSam Leffler             break;
4531de50e9fSSam Leffler 
4541de50e9fSSam Leffler             /*
4551de50e9fSSam Leffler              * FIXME those are the defined TLVs that lack a decoder
4561de50e9fSSam Leffler              * you are welcome to contribute code ;-)
4571de50e9fSSam Leffler              */
4581de50e9fSSam Leffler 
4591de50e9fSSam Leffler         case EIGRP_TLV_AUTH:
4601de50e9fSSam Leffler         case EIGRP_TLV_SEQ:
4611de50e9fSSam Leffler         case EIGRP_TLV_MCAST_SEQ:
4621de50e9fSSam Leffler         case EIGRP_TLV_IPX_INT:
4631de50e9fSSam Leffler         case EIGRP_TLV_IPX_EXT:
4641de50e9fSSam Leffler 
4651de50e9fSSam Leffler         default:
4661de50e9fSSam Leffler             if (vflag <= 1)
4671de50e9fSSam Leffler                 print_unknown_data(tlv_tptr,"\n\t    ",tlv_tlen);
4681de50e9fSSam Leffler             break;
4691de50e9fSSam Leffler         }
4701de50e9fSSam Leffler         /* do we want to see an additionally hexdump ? */
4711de50e9fSSam Leffler         if (vflag > 1)
4721de50e9fSSam Leffler             print_unknown_data(tptr+sizeof(sizeof(struct eigrp_tlv_header)),"\n\t    ",
4731de50e9fSSam Leffler                                eigrp_tlv_len-sizeof(struct eigrp_tlv_header));
4741de50e9fSSam Leffler 
4751de50e9fSSam Leffler         tptr+=eigrp_tlv_len;
4761de50e9fSSam Leffler         tlen-=eigrp_tlv_len;
4771de50e9fSSam Leffler     }
4781de50e9fSSam Leffler     return;
4791de50e9fSSam Leffler trunc:
4801de50e9fSSam Leffler     printf("\n\t\t packet exceeded snapshot");
4811de50e9fSSam Leffler }
482