11de50e9fSSam Leffler /* 2*0bff6a5aSEd Maste * Copyright (c) 1998-2004 Hannes Gredler <hannes@gredler.at> 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 173340d773SGleb Smirnoff /* \summary: Enhanced Interior Gateway Routing Protocol (EIGRP) printer */ 183340d773SGleb Smirnoff 191de50e9fSSam Leffler #ifdef HAVE_CONFIG_H 201de50e9fSSam Leffler #include "config.h" 211de50e9fSSam Leffler #endif 221de50e9fSSam Leffler 233340d773SGleb Smirnoff #include <netdissect-stdinc.h> 241de50e9fSSam Leffler 251de50e9fSSam Leffler #include <string.h> 261de50e9fSSam Leffler 273340d773SGleb Smirnoff #include "netdissect.h" 281de50e9fSSam Leffler #include "extract.h" 291de50e9fSSam Leffler #include "addrtoname.h" 301de50e9fSSam Leffler 311de50e9fSSam Leffler /* 321de50e9fSSam Leffler * packet format documented at 331de50e9fSSam Leffler * http://www.rhyshaden.com/eigrp.htm 34*0bff6a5aSEd Maste * RFC 7868 351de50e9fSSam Leffler */ 361de50e9fSSam Leffler 371de50e9fSSam Leffler struct eigrp_common_header { 383c602fabSXin LI uint8_t version; 393c602fabSXin LI uint8_t opcode; 403c602fabSXin LI uint8_t checksum[2]; 413c602fabSXin LI uint8_t flags[4]; 423c602fabSXin LI uint8_t seq[4]; 433c602fabSXin LI uint8_t ack[4]; 443c602fabSXin LI uint8_t asn[4]; 451de50e9fSSam Leffler }; 461de50e9fSSam Leffler 471de50e9fSSam Leffler #define EIGRP_VERSION 2 481de50e9fSSam Leffler 491de50e9fSSam Leffler #define EIGRP_OPCODE_UPDATE 1 501de50e9fSSam Leffler #define EIGRP_OPCODE_QUERY 3 511de50e9fSSam Leffler #define EIGRP_OPCODE_REPLY 4 521de50e9fSSam Leffler #define EIGRP_OPCODE_HELLO 5 531de50e9fSSam Leffler #define EIGRP_OPCODE_IPXSAP 6 541de50e9fSSam Leffler #define EIGRP_OPCODE_PROBE 7 551de50e9fSSam Leffler 561de50e9fSSam Leffler static const struct tok eigrp_opcode_values[] = { 571de50e9fSSam Leffler { EIGRP_OPCODE_UPDATE, "Update" }, 581de50e9fSSam Leffler { EIGRP_OPCODE_QUERY, "Query" }, 591de50e9fSSam Leffler { EIGRP_OPCODE_REPLY, "Reply" }, 601de50e9fSSam Leffler { EIGRP_OPCODE_HELLO, "Hello" }, 611de50e9fSSam Leffler { EIGRP_OPCODE_IPXSAP, "IPX SAP" }, 621de50e9fSSam Leffler { EIGRP_OPCODE_PROBE, "Probe" }, 631de50e9fSSam Leffler { 0, NULL} 641de50e9fSSam Leffler }; 651de50e9fSSam Leffler 661de50e9fSSam Leffler static const struct tok eigrp_common_header_flag_values[] = { 671de50e9fSSam Leffler { 0x01, "Init" }, 681de50e9fSSam Leffler { 0x02, "Conditionally Received" }, 691de50e9fSSam Leffler { 0, NULL} 701de50e9fSSam Leffler }; 711de50e9fSSam Leffler 721de50e9fSSam Leffler struct eigrp_tlv_header { 733c602fabSXin LI uint8_t type[2]; 743c602fabSXin LI uint8_t length[2]; 751de50e9fSSam Leffler }; 761de50e9fSSam Leffler 771de50e9fSSam Leffler #define EIGRP_TLV_GENERAL_PARM 0x0001 781de50e9fSSam Leffler #define EIGRP_TLV_AUTH 0x0002 791de50e9fSSam Leffler #define EIGRP_TLV_SEQ 0x0003 801de50e9fSSam Leffler #define EIGRP_TLV_SW_VERSION 0x0004 811de50e9fSSam Leffler #define EIGRP_TLV_MCAST_SEQ 0x0005 821de50e9fSSam Leffler #define EIGRP_TLV_IP_INT 0x0102 831de50e9fSSam Leffler #define EIGRP_TLV_IP_EXT 0x0103 841de50e9fSSam Leffler #define EIGRP_TLV_AT_INT 0x0202 851de50e9fSSam Leffler #define EIGRP_TLV_AT_EXT 0x0203 861de50e9fSSam Leffler #define EIGRP_TLV_AT_CABLE_SETUP 0x0204 871de50e9fSSam Leffler #define EIGRP_TLV_IPX_INT 0x0302 881de50e9fSSam Leffler #define EIGRP_TLV_IPX_EXT 0x0303 891de50e9fSSam Leffler 901de50e9fSSam Leffler static const struct tok eigrp_tlv_values[] = { 911de50e9fSSam Leffler { EIGRP_TLV_GENERAL_PARM, "General Parameters"}, 921de50e9fSSam Leffler { EIGRP_TLV_AUTH, "Authentication"}, 931de50e9fSSam Leffler { EIGRP_TLV_SEQ, "Sequence"}, 941de50e9fSSam Leffler { EIGRP_TLV_SW_VERSION, "Software Version"}, 951de50e9fSSam Leffler { EIGRP_TLV_MCAST_SEQ, "Next Multicast Sequence"}, 961de50e9fSSam Leffler { EIGRP_TLV_IP_INT, "IP Internal routes"}, 971de50e9fSSam Leffler { EIGRP_TLV_IP_EXT, "IP External routes"}, 981de50e9fSSam Leffler { EIGRP_TLV_AT_INT, "AppleTalk Internal routes"}, 991de50e9fSSam Leffler { EIGRP_TLV_AT_EXT, "AppleTalk External routes"}, 1001de50e9fSSam Leffler { EIGRP_TLV_AT_CABLE_SETUP, "AppleTalk Cable setup"}, 1011de50e9fSSam Leffler { EIGRP_TLV_IPX_INT, "IPX Internal routes"}, 1021de50e9fSSam Leffler { EIGRP_TLV_IPX_EXT, "IPX External routes"}, 1031de50e9fSSam Leffler { 0, NULL} 1041de50e9fSSam Leffler }; 1051de50e9fSSam Leffler 1061de50e9fSSam Leffler struct eigrp_tlv_general_parm_t { 1073c602fabSXin LI uint8_t k1; 1083c602fabSXin LI uint8_t k2; 1093c602fabSXin LI uint8_t k3; 1103c602fabSXin LI uint8_t k4; 1113c602fabSXin LI uint8_t k5; 1123c602fabSXin LI uint8_t res; 1133c602fabSXin LI uint8_t holdtime[2]; 1141de50e9fSSam Leffler }; 1151de50e9fSSam Leffler 1161de50e9fSSam Leffler struct eigrp_tlv_sw_version_t { 1173c602fabSXin LI uint8_t ios_major; 1183c602fabSXin LI uint8_t ios_minor; 1193c602fabSXin LI uint8_t eigrp_major; 1203c602fabSXin LI uint8_t eigrp_minor; 1211de50e9fSSam Leffler }; 1221de50e9fSSam Leffler 1231de50e9fSSam Leffler struct eigrp_tlv_ip_int_t { 1243c602fabSXin LI uint8_t nexthop[4]; 1253c602fabSXin LI uint8_t delay[4]; 1263c602fabSXin LI uint8_t bandwidth[4]; 1273c602fabSXin LI uint8_t mtu[3]; 1283c602fabSXin LI uint8_t hopcount; 1293c602fabSXin LI uint8_t reliability; 1303c602fabSXin LI uint8_t load; 1313c602fabSXin LI uint8_t reserved[2]; 1323c602fabSXin LI uint8_t plen; 1333c602fabSXin LI uint8_t destination; /* variable length [1-4] bytes encoding */ 1341de50e9fSSam Leffler }; 1351de50e9fSSam Leffler 1361de50e9fSSam Leffler struct eigrp_tlv_ip_ext_t { 1373c602fabSXin LI uint8_t nexthop[4]; 1383c602fabSXin LI uint8_t origin_router[4]; 1393c602fabSXin LI uint8_t origin_as[4]; 1403c602fabSXin LI uint8_t tag[4]; 1413c602fabSXin LI uint8_t metric[4]; 1423c602fabSXin LI uint8_t reserved[2]; 1433c602fabSXin LI uint8_t proto_id; 1443c602fabSXin LI uint8_t flags; 1453c602fabSXin LI uint8_t delay[4]; 1463c602fabSXin LI uint8_t bandwidth[4]; 1473c602fabSXin LI uint8_t mtu[3]; 1483c602fabSXin LI uint8_t hopcount; 1493c602fabSXin LI uint8_t reliability; 1503c602fabSXin LI uint8_t load; 1513c602fabSXin LI uint8_t reserved2[2]; 1523c602fabSXin LI uint8_t plen; 1533c602fabSXin LI uint8_t destination; /* variable length [1-4] bytes encoding */ 1541de50e9fSSam Leffler }; 1551de50e9fSSam Leffler 1561de50e9fSSam Leffler struct eigrp_tlv_at_cable_setup_t { 1573c602fabSXin LI uint8_t cable_start[2]; 1583c602fabSXin LI uint8_t cable_end[2]; 1593c602fabSXin LI uint8_t router_id[4]; 1601de50e9fSSam Leffler }; 1611de50e9fSSam Leffler 1621de50e9fSSam Leffler struct eigrp_tlv_at_int_t { 1633c602fabSXin LI uint8_t nexthop[4]; 1643c602fabSXin LI uint8_t delay[4]; 1653c602fabSXin LI uint8_t bandwidth[4]; 1663c602fabSXin LI uint8_t mtu[3]; 1673c602fabSXin LI uint8_t hopcount; 1683c602fabSXin LI uint8_t reliability; 1693c602fabSXin LI uint8_t load; 1703c602fabSXin LI uint8_t reserved[2]; 1713c602fabSXin LI uint8_t cable_start[2]; 1723c602fabSXin LI uint8_t cable_end[2]; 1731de50e9fSSam Leffler }; 1741de50e9fSSam Leffler 1751de50e9fSSam Leffler struct eigrp_tlv_at_ext_t { 1763c602fabSXin LI uint8_t nexthop[4]; 1773c602fabSXin LI uint8_t origin_router[4]; 1783c602fabSXin LI uint8_t origin_as[4]; 1793c602fabSXin LI uint8_t tag[4]; 1803c602fabSXin LI uint8_t proto_id; 1813c602fabSXin LI uint8_t flags; 1823c602fabSXin LI uint8_t metric[2]; 1833c602fabSXin LI uint8_t delay[4]; 1843c602fabSXin LI uint8_t bandwidth[4]; 1853c602fabSXin LI uint8_t mtu[3]; 1863c602fabSXin LI uint8_t hopcount; 1873c602fabSXin LI uint8_t reliability; 1883c602fabSXin LI uint8_t load; 1893c602fabSXin LI uint8_t reserved2[2]; 1903c602fabSXin LI uint8_t cable_start[2]; 1913c602fabSXin LI uint8_t cable_end[2]; 1921de50e9fSSam Leffler }; 1931de50e9fSSam Leffler 1941de50e9fSSam Leffler static const struct tok eigrp_ext_proto_id_values[] = { 1951de50e9fSSam Leffler { 0x01, "IGRP" }, 1961de50e9fSSam Leffler { 0x02, "EIGRP" }, 1971de50e9fSSam Leffler { 0x03, "Static" }, 1981de50e9fSSam Leffler { 0x04, "RIP" }, 1991de50e9fSSam Leffler { 0x05, "Hello" }, 2001de50e9fSSam Leffler { 0x06, "OSPF" }, 2011de50e9fSSam Leffler { 0x07, "IS-IS" }, 2021de50e9fSSam Leffler { 0x08, "EGP" }, 2031de50e9fSSam Leffler { 0x09, "BGP" }, 2041de50e9fSSam Leffler { 0x0a, "IDRP" }, 2051de50e9fSSam Leffler { 0x0b, "Connected" }, 2061de50e9fSSam Leffler { 0, NULL} 2071de50e9fSSam Leffler }; 2081de50e9fSSam Leffler 2091de50e9fSSam Leffler void 2108bdc5a62SPatrick Kelsey eigrp_print(netdissect_options *ndo, register const u_char *pptr, register u_int len) 2118bdc5a62SPatrick Kelsey { 2121de50e9fSSam Leffler const struct eigrp_common_header *eigrp_com_header; 2131de50e9fSSam Leffler const struct eigrp_tlv_header *eigrp_tlv_header; 2141de50e9fSSam Leffler const u_char *tptr,*tlv_tptr; 215f4d0c64aSSam Leffler u_int tlen,eigrp_tlv_len,eigrp_tlv_type,tlv_tlen, byte_length, bit_length; 2163c602fabSXin LI uint8_t prefix[4]; 2171de50e9fSSam Leffler 2181de50e9fSSam Leffler union { 2191de50e9fSSam Leffler const struct eigrp_tlv_general_parm_t *eigrp_tlv_general_parm; 2201de50e9fSSam Leffler const struct eigrp_tlv_sw_version_t *eigrp_tlv_sw_version; 2211de50e9fSSam Leffler const struct eigrp_tlv_ip_int_t *eigrp_tlv_ip_int; 2221de50e9fSSam Leffler const struct eigrp_tlv_ip_ext_t *eigrp_tlv_ip_ext; 2231de50e9fSSam Leffler const struct eigrp_tlv_at_cable_setup_t *eigrp_tlv_at_cable_setup; 2241de50e9fSSam Leffler const struct eigrp_tlv_at_int_t *eigrp_tlv_at_int; 2251de50e9fSSam Leffler const struct eigrp_tlv_at_ext_t *eigrp_tlv_at_ext; 2261de50e9fSSam Leffler } tlv_ptr; 2271de50e9fSSam Leffler 2281de50e9fSSam Leffler tptr=pptr; 2291de50e9fSSam Leffler eigrp_com_header = (const struct eigrp_common_header *)pptr; 2303c602fabSXin LI ND_TCHECK(*eigrp_com_header); 2311de50e9fSSam Leffler 2321de50e9fSSam Leffler /* 2331de50e9fSSam Leffler * Sanity checking of the header. 2341de50e9fSSam Leffler */ 2351de50e9fSSam Leffler if (eigrp_com_header->version != EIGRP_VERSION) { 2363c602fabSXin LI ND_PRINT((ndo, "EIGRP version %u packet not supported",eigrp_com_header->version)); 2371de50e9fSSam Leffler return; 2381de50e9fSSam Leffler } 2391de50e9fSSam Leffler 2401de50e9fSSam Leffler /* in non-verbose mode just lets print the basic Message Type*/ 2413c602fabSXin LI if (ndo->ndo_vflag < 1) { 2423c602fabSXin LI ND_PRINT((ndo, "EIGRP %s, length: %u", 2431de50e9fSSam Leffler tok2str(eigrp_opcode_values, "unknown (%u)",eigrp_com_header->opcode), 2443c602fabSXin LI len)); 2451de50e9fSSam Leffler return; 2461de50e9fSSam Leffler } 2471de50e9fSSam Leffler 2481de50e9fSSam Leffler /* ok they seem to want to know everything - lets fully decode it */ 2491de50e9fSSam Leffler 250*0bff6a5aSEd Maste if (len < sizeof(struct eigrp_common_header)) { 251*0bff6a5aSEd Maste ND_PRINT((ndo, "EIGRP %s, length: %u (too short, < %u)", 252*0bff6a5aSEd Maste tok2str(eigrp_opcode_values, "unknown (%u)",eigrp_com_header->opcode), 253*0bff6a5aSEd Maste len, (u_int) sizeof(struct eigrp_common_header))); 254*0bff6a5aSEd Maste return; 255*0bff6a5aSEd Maste } 2561de50e9fSSam Leffler tlen=len-sizeof(struct eigrp_common_header); 2571de50e9fSSam Leffler 2581de50e9fSSam Leffler /* FIXME print other header info */ 2593c602fabSXin LI 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", 2601de50e9fSSam Leffler eigrp_com_header->version, 2611de50e9fSSam Leffler tok2str(eigrp_opcode_values, "unknown, type: %u",eigrp_com_header->opcode), 2621de50e9fSSam Leffler eigrp_com_header->opcode, 2631de50e9fSSam Leffler EXTRACT_16BITS(&eigrp_com_header->checksum), 2641de50e9fSSam Leffler tok2str(eigrp_common_header_flag_values, 2651de50e9fSSam Leffler "none", 2661de50e9fSSam Leffler EXTRACT_32BITS(&eigrp_com_header->flags)), 2671de50e9fSSam Leffler EXTRACT_32BITS(&eigrp_com_header->seq), 2681de50e9fSSam Leffler EXTRACT_32BITS(&eigrp_com_header->ack), 2691de50e9fSSam Leffler EXTRACT_32BITS(&eigrp_com_header->asn), 2703c602fabSXin LI tlen)); 2711de50e9fSSam Leffler 2721de50e9fSSam Leffler tptr+=sizeof(const struct eigrp_common_header); 2731de50e9fSSam Leffler 2741de50e9fSSam Leffler while(tlen>0) { 2751de50e9fSSam Leffler /* did we capture enough for fully decoding the object header ? */ 2763c602fabSXin LI ND_TCHECK2(*tptr, sizeof(struct eigrp_tlv_header)); 2771de50e9fSSam Leffler 2781de50e9fSSam Leffler eigrp_tlv_header = (const struct eigrp_tlv_header *)tptr; 2791de50e9fSSam Leffler eigrp_tlv_len=EXTRACT_16BITS(&eigrp_tlv_header->length); 2801de50e9fSSam Leffler eigrp_tlv_type=EXTRACT_16BITS(&eigrp_tlv_header->type); 2811de50e9fSSam Leffler 2821de50e9fSSam Leffler 283f4d0c64aSSam Leffler if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header) || 284f4d0c64aSSam Leffler eigrp_tlv_len > tlen) { 2853c602fabSXin LI print_unknown_data(ndo,tptr+sizeof(struct eigrp_tlv_header),"\n\t ",tlen); 2861de50e9fSSam Leffler return; 2871de50e9fSSam Leffler } 2881de50e9fSSam Leffler 2893c602fabSXin LI ND_PRINT((ndo, "\n\t %s TLV (0x%04x), length: %u", 2901de50e9fSSam Leffler tok2str(eigrp_tlv_values, 2911de50e9fSSam Leffler "Unknown", 2921de50e9fSSam Leffler eigrp_tlv_type), 2931de50e9fSSam Leffler eigrp_tlv_type, 2943c602fabSXin LI eigrp_tlv_len)); 2951de50e9fSSam Leffler 296*0bff6a5aSEd Maste if (eigrp_tlv_len < sizeof(struct eigrp_tlv_header)) { 297*0bff6a5aSEd Maste ND_PRINT((ndo, " (too short, < %u)", 298*0bff6a5aSEd Maste (u_int) sizeof(struct eigrp_tlv_header))); 299*0bff6a5aSEd Maste break; 300*0bff6a5aSEd Maste } 3011de50e9fSSam Leffler tlv_tptr=tptr+sizeof(struct eigrp_tlv_header); 3021de50e9fSSam Leffler tlv_tlen=eigrp_tlv_len-sizeof(struct eigrp_tlv_header); 3031de50e9fSSam Leffler 3041de50e9fSSam Leffler /* did we capture enough for fully decoding the object ? */ 3053c602fabSXin LI ND_TCHECK2(*tptr, eigrp_tlv_len); 3061de50e9fSSam Leffler 3071de50e9fSSam Leffler switch(eigrp_tlv_type) { 3081de50e9fSSam Leffler 3091de50e9fSSam Leffler case EIGRP_TLV_GENERAL_PARM: 3101de50e9fSSam Leffler tlv_ptr.eigrp_tlv_general_parm = (const struct eigrp_tlv_general_parm_t *)tlv_tptr; 311*0bff6a5aSEd Maste if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_general_parm)) { 312*0bff6a5aSEd Maste ND_PRINT((ndo, " (too short, < %u)", 313*0bff6a5aSEd Maste (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_general_parm)))); 314*0bff6a5aSEd Maste break; 315*0bff6a5aSEd Maste } 3161de50e9fSSam Leffler 3173c602fabSXin LI ND_PRINT((ndo, "\n\t holdtime: %us, k1 %u, k2 %u, k3 %u, k4 %u, k5 %u", 3181de50e9fSSam Leffler EXTRACT_16BITS(tlv_ptr.eigrp_tlv_general_parm->holdtime), 3191de50e9fSSam Leffler tlv_ptr.eigrp_tlv_general_parm->k1, 3201de50e9fSSam Leffler tlv_ptr.eigrp_tlv_general_parm->k2, 3211de50e9fSSam Leffler tlv_ptr.eigrp_tlv_general_parm->k3, 3221de50e9fSSam Leffler tlv_ptr.eigrp_tlv_general_parm->k4, 3233c602fabSXin LI tlv_ptr.eigrp_tlv_general_parm->k5)); 3241de50e9fSSam Leffler break; 3251de50e9fSSam Leffler 3261de50e9fSSam Leffler case EIGRP_TLV_SW_VERSION: 3271de50e9fSSam Leffler tlv_ptr.eigrp_tlv_sw_version = (const struct eigrp_tlv_sw_version_t *)tlv_tptr; 328*0bff6a5aSEd Maste if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_sw_version)) { 329*0bff6a5aSEd Maste ND_PRINT((ndo, " (too short, < %u)", 330*0bff6a5aSEd Maste (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_sw_version)))); 331*0bff6a5aSEd Maste break; 332*0bff6a5aSEd Maste } 3331de50e9fSSam Leffler 3343c602fabSXin LI ND_PRINT((ndo, "\n\t IOS version: %u.%u, EIGRP version %u.%u", 3351de50e9fSSam Leffler tlv_ptr.eigrp_tlv_sw_version->ios_major, 3361de50e9fSSam Leffler tlv_ptr.eigrp_tlv_sw_version->ios_minor, 3371de50e9fSSam Leffler tlv_ptr.eigrp_tlv_sw_version->eigrp_major, 3383c602fabSXin LI tlv_ptr.eigrp_tlv_sw_version->eigrp_minor)); 3391de50e9fSSam Leffler break; 3401de50e9fSSam Leffler 3411de50e9fSSam Leffler case EIGRP_TLV_IP_INT: 3421de50e9fSSam Leffler tlv_ptr.eigrp_tlv_ip_int = (const struct eigrp_tlv_ip_int_t *)tlv_tptr; 343*0bff6a5aSEd Maste if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_ip_int)) { 344*0bff6a5aSEd Maste ND_PRINT((ndo, " (too short, < %u)", 345*0bff6a5aSEd Maste (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_ip_int)))); 346*0bff6a5aSEd Maste break; 347*0bff6a5aSEd Maste } 3481de50e9fSSam Leffler 3491de50e9fSSam Leffler bit_length = tlv_ptr.eigrp_tlv_ip_int->plen; 350f4d0c64aSSam Leffler if (bit_length > 32) { 3513c602fabSXin LI ND_PRINT((ndo, "\n\t illegal prefix length %u",bit_length)); 3521de50e9fSSam Leffler break; 3531de50e9fSSam Leffler } 3541de50e9fSSam Leffler byte_length = (bit_length + 7) / 8; /* variable length encoding */ 3551de50e9fSSam Leffler memset(prefix, 0, 4); 3561de50e9fSSam Leffler memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_int->destination,byte_length); 3571de50e9fSSam Leffler 3583c602fabSXin LI ND_PRINT((ndo, "\n\t IPv4 prefix: %15s/%u, nexthop: ", 3593c602fabSXin LI ipaddr_string(ndo, prefix), 3603c602fabSXin LI bit_length)); 3611de50e9fSSam Leffler if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->nexthop) == 0) 3623c602fabSXin LI ND_PRINT((ndo, "self")); 3631de50e9fSSam Leffler else 3643c602fabSXin LI ND_PRINT((ndo, "%s",ipaddr_string(ndo, &tlv_ptr.eigrp_tlv_ip_int->nexthop))); 3651de50e9fSSam Leffler 3663c602fabSXin LI ND_PRINT((ndo, "\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", 3671de50e9fSSam Leffler (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->delay)/100), 3681de50e9fSSam Leffler EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_int->bandwidth), 3691de50e9fSSam Leffler EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_ip_int->mtu), 3701de50e9fSSam Leffler tlv_ptr.eigrp_tlv_ip_int->hopcount, 3711de50e9fSSam Leffler tlv_ptr.eigrp_tlv_ip_int->reliability, 3723c602fabSXin LI tlv_ptr.eigrp_tlv_ip_int->load)); 3731de50e9fSSam Leffler break; 3741de50e9fSSam Leffler 3751de50e9fSSam Leffler case EIGRP_TLV_IP_EXT: 3761de50e9fSSam Leffler tlv_ptr.eigrp_tlv_ip_ext = (const struct eigrp_tlv_ip_ext_t *)tlv_tptr; 377*0bff6a5aSEd Maste if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_ip_ext)) { 378*0bff6a5aSEd Maste ND_PRINT((ndo, " (too short, < %u)", 379*0bff6a5aSEd Maste (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_ip_ext)))); 380*0bff6a5aSEd Maste break; 381*0bff6a5aSEd Maste } 3821de50e9fSSam Leffler 3831de50e9fSSam Leffler bit_length = tlv_ptr.eigrp_tlv_ip_ext->plen; 384f4d0c64aSSam Leffler if (bit_length > 32) { 3853c602fabSXin LI ND_PRINT((ndo, "\n\t illegal prefix length %u",bit_length)); 3861de50e9fSSam Leffler break; 3871de50e9fSSam Leffler } 3881de50e9fSSam Leffler byte_length = (bit_length + 7) / 8; /* variable length encoding */ 3891de50e9fSSam Leffler memset(prefix, 0, 4); 3901de50e9fSSam Leffler memcpy(prefix,&tlv_ptr.eigrp_tlv_ip_ext->destination,byte_length); 3911de50e9fSSam Leffler 3923c602fabSXin LI ND_PRINT((ndo, "\n\t IPv4 prefix: %15s/%u, nexthop: ", 3933c602fabSXin LI ipaddr_string(ndo, prefix), 3943c602fabSXin LI bit_length)); 3951de50e9fSSam Leffler if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->nexthop) == 0) 3963c602fabSXin LI ND_PRINT((ndo, "self")); 3971de50e9fSSam Leffler else 3983c602fabSXin LI ND_PRINT((ndo, "%s",ipaddr_string(ndo, &tlv_ptr.eigrp_tlv_ip_ext->nexthop))); 3991de50e9fSSam Leffler 4003c602fabSXin LI ND_PRINT((ndo, "\n\t origin-router %s, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u", 4013c602fabSXin LI ipaddr_string(ndo, tlv_ptr.eigrp_tlv_ip_ext->origin_router), 4021de50e9fSSam Leffler EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->origin_as), 4031de50e9fSSam Leffler tok2str(eigrp_ext_proto_id_values,"unknown",tlv_ptr.eigrp_tlv_ip_ext->proto_id), 4041de50e9fSSam Leffler tlv_ptr.eigrp_tlv_ip_ext->flags, 4051de50e9fSSam Leffler EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->tag), 4063c602fabSXin LI EXTRACT_32BITS(tlv_ptr.eigrp_tlv_ip_ext->metric))); 4071de50e9fSSam Leffler 4083c602fabSXin LI ND_PRINT((ndo, "\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", 4091de50e9fSSam Leffler (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->delay)/100), 4101de50e9fSSam Leffler EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_ip_ext->bandwidth), 4111de50e9fSSam Leffler EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_ip_ext->mtu), 4121de50e9fSSam Leffler tlv_ptr.eigrp_tlv_ip_ext->hopcount, 4131de50e9fSSam Leffler tlv_ptr.eigrp_tlv_ip_ext->reliability, 4143c602fabSXin LI tlv_ptr.eigrp_tlv_ip_ext->load)); 4151de50e9fSSam Leffler break; 4161de50e9fSSam Leffler 4171de50e9fSSam Leffler case EIGRP_TLV_AT_CABLE_SETUP: 4181de50e9fSSam Leffler tlv_ptr.eigrp_tlv_at_cable_setup = (const struct eigrp_tlv_at_cable_setup_t *)tlv_tptr; 419*0bff6a5aSEd Maste if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_cable_setup)) { 420*0bff6a5aSEd Maste ND_PRINT((ndo, " (too short, < %u)", 421*0bff6a5aSEd Maste (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_cable_setup)))); 422*0bff6a5aSEd Maste break; 423*0bff6a5aSEd Maste } 4241de50e9fSSam Leffler 4253c602fabSXin LI ND_PRINT((ndo, "\n\t Cable-range: %u-%u, Router-ID %u", 4261de50e9fSSam Leffler EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_start), 4271de50e9fSSam Leffler EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->cable_end), 4283c602fabSXin LI EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_cable_setup->router_id))); 4291de50e9fSSam Leffler break; 4301de50e9fSSam Leffler 4311de50e9fSSam Leffler case EIGRP_TLV_AT_INT: 4321de50e9fSSam Leffler tlv_ptr.eigrp_tlv_at_int = (const struct eigrp_tlv_at_int_t *)tlv_tptr; 433*0bff6a5aSEd Maste if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_int)) { 434*0bff6a5aSEd Maste ND_PRINT((ndo, " (too short, < %u)", 435*0bff6a5aSEd Maste (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_int)))); 436*0bff6a5aSEd Maste break; 437*0bff6a5aSEd Maste } 4381de50e9fSSam Leffler 4393c602fabSXin LI ND_PRINT((ndo, "\n\t Cable-Range: %u-%u, nexthop: ", 4401de50e9fSSam Leffler EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_start), 4413c602fabSXin LI EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->cable_end))); 4421de50e9fSSam Leffler 4431de50e9fSSam Leffler if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop) == 0) 4443c602fabSXin LI ND_PRINT((ndo, "self")); 4451de50e9fSSam Leffler else 4463c602fabSXin LI ND_PRINT((ndo, "%u.%u", 4471de50e9fSSam Leffler EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop), 4483c602fabSXin LI EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_int->nexthop[2]))); 4491de50e9fSSam Leffler 4503c602fabSXin LI ND_PRINT((ndo, "\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", 4511de50e9fSSam Leffler (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->delay)/100), 4521de50e9fSSam Leffler EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_int->bandwidth), 4531de50e9fSSam Leffler EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_at_int->mtu), 4541de50e9fSSam Leffler tlv_ptr.eigrp_tlv_at_int->hopcount, 4551de50e9fSSam Leffler tlv_ptr.eigrp_tlv_at_int->reliability, 4563c602fabSXin LI tlv_ptr.eigrp_tlv_at_int->load)); 4571de50e9fSSam Leffler break; 4581de50e9fSSam Leffler 4591de50e9fSSam Leffler case EIGRP_TLV_AT_EXT: 4601de50e9fSSam Leffler tlv_ptr.eigrp_tlv_at_ext = (const struct eigrp_tlv_at_ext_t *)tlv_tptr; 461*0bff6a5aSEd Maste if (tlv_tlen < sizeof(*tlv_ptr.eigrp_tlv_at_ext)) { 462*0bff6a5aSEd Maste ND_PRINT((ndo, " (too short, < %u)", 463*0bff6a5aSEd Maste (u_int) (sizeof(struct eigrp_tlv_header) + sizeof(*tlv_ptr.eigrp_tlv_at_ext)))); 464*0bff6a5aSEd Maste break; 465*0bff6a5aSEd Maste } 4661de50e9fSSam Leffler 4673c602fabSXin LI ND_PRINT((ndo, "\n\t Cable-Range: %u-%u, nexthop: ", 4681de50e9fSSam Leffler EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_start), 4693c602fabSXin LI EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->cable_end))); 4701de50e9fSSam Leffler 4711de50e9fSSam Leffler if (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop) == 0) 4723c602fabSXin LI ND_PRINT((ndo, "self")); 4731de50e9fSSam Leffler else 4743c602fabSXin LI ND_PRINT((ndo, "%u.%u", 4751de50e9fSSam Leffler EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop), 4763c602fabSXin LI EXTRACT_16BITS(&tlv_ptr.eigrp_tlv_at_ext->nexthop[2]))); 4771de50e9fSSam Leffler 4783c602fabSXin LI ND_PRINT((ndo, "\n\t origin-router %u, origin-as %u, origin-proto %s, flags [0x%02x], tag 0x%08x, metric %u", 4791de50e9fSSam Leffler EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->origin_router), 4801de50e9fSSam Leffler EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->origin_as), 4811de50e9fSSam Leffler tok2str(eigrp_ext_proto_id_values,"unknown",tlv_ptr.eigrp_tlv_at_ext->proto_id), 4821de50e9fSSam Leffler tlv_ptr.eigrp_tlv_at_ext->flags, 4831de50e9fSSam Leffler EXTRACT_32BITS(tlv_ptr.eigrp_tlv_at_ext->tag), 4843c602fabSXin LI EXTRACT_16BITS(tlv_ptr.eigrp_tlv_at_ext->metric))); 4851de50e9fSSam Leffler 4863c602fabSXin LI ND_PRINT((ndo, "\n\t delay %u ms, bandwidth %u Kbps, mtu %u, hop %u, reliability %u, load %u", 4871de50e9fSSam Leffler (EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->delay)/100), 4881de50e9fSSam Leffler EXTRACT_32BITS(&tlv_ptr.eigrp_tlv_at_ext->bandwidth), 4891de50e9fSSam Leffler EXTRACT_24BITS(&tlv_ptr.eigrp_tlv_at_ext->mtu), 4901de50e9fSSam Leffler tlv_ptr.eigrp_tlv_at_ext->hopcount, 4911de50e9fSSam Leffler tlv_ptr.eigrp_tlv_at_ext->reliability, 4923c602fabSXin LI tlv_ptr.eigrp_tlv_at_ext->load)); 4931de50e9fSSam Leffler break; 4941de50e9fSSam Leffler 4951de50e9fSSam Leffler /* 4961de50e9fSSam Leffler * FIXME those are the defined TLVs that lack a decoder 4971de50e9fSSam Leffler * you are welcome to contribute code ;-) 4981de50e9fSSam Leffler */ 4991de50e9fSSam Leffler 5001de50e9fSSam Leffler case EIGRP_TLV_AUTH: 5011de50e9fSSam Leffler case EIGRP_TLV_SEQ: 5021de50e9fSSam Leffler case EIGRP_TLV_MCAST_SEQ: 5031de50e9fSSam Leffler case EIGRP_TLV_IPX_INT: 5041de50e9fSSam Leffler case EIGRP_TLV_IPX_EXT: 5051de50e9fSSam Leffler 5061de50e9fSSam Leffler default: 5073c602fabSXin LI if (ndo->ndo_vflag <= 1) 5083c602fabSXin LI print_unknown_data(ndo,tlv_tptr,"\n\t ",tlv_tlen); 5091de50e9fSSam Leffler break; 5101de50e9fSSam Leffler } 5111de50e9fSSam Leffler /* do we want to see an additionally hexdump ? */ 5123c602fabSXin LI if (ndo->ndo_vflag > 1) 5133c602fabSXin LI print_unknown_data(ndo,tptr+sizeof(struct eigrp_tlv_header),"\n\t ", 5141de50e9fSSam Leffler eigrp_tlv_len-sizeof(struct eigrp_tlv_header)); 5151de50e9fSSam Leffler 5161de50e9fSSam Leffler tptr+=eigrp_tlv_len; 5171de50e9fSSam Leffler tlen-=eigrp_tlv_len; 5181de50e9fSSam Leffler } 5191de50e9fSSam Leffler return; 5201de50e9fSSam Leffler trunc: 5213c602fabSXin LI ND_PRINT((ndo, "\n\t\t packet exceeded snapshot")); 5221de50e9fSSam Leffler } 523