1b0453382SBill Fenner /* 2b0453382SBill Fenner * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 3b0453382SBill Fenner * The Regents of the University of California. All rights reserved. 4b0453382SBill Fenner * 5b0453382SBill Fenner * Redistribution and use in source and binary forms, with or without 6b0453382SBill Fenner * modification, are permitted provided that: (1) source code distributions 7b0453382SBill Fenner * retain the above copyright notice and this paragraph in its entirety, (2) 8b0453382SBill Fenner * distributions including binary code include the above copyright notice and 9b0453382SBill Fenner * this paragraph in its entirety in the documentation or other materials 10b0453382SBill Fenner * provided with the distribution, and (3) all advertising materials mentioning 11b0453382SBill Fenner * features or use of this software display the following acknowledgement: 12b0453382SBill Fenner * ``This product includes software developed by the University of California, 13b0453382SBill Fenner * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14b0453382SBill Fenner * the University nor the names of its contributors may be used to endorse 15b0453382SBill Fenner * or promote products derived from this software without specific prior 16b0453382SBill Fenner * written permission. 17b0453382SBill Fenner * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18b0453382SBill Fenner * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19b0453382SBill Fenner * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20b0453382SBill Fenner */ 21b0453382SBill Fenner 223340d773SGleb Smirnoff /* \summary: Cisco HDLC printer */ 233340d773SGleb Smirnoff 24b0453382SBill Fenner #ifdef HAVE_CONFIG_H 25b0453382SBill Fenner #include "config.h" 26b0453382SBill Fenner #endif 27b0453382SBill Fenner 283340d773SGleb Smirnoff #include <netdissect-stdinc.h> 29b0453382SBill Fenner 303340d773SGleb Smirnoff #include "netdissect.h" 31b0453382SBill Fenner #include "addrtoname.h" 32685295f4SBill Fenner #include "ethertype.h" 33a90e161bSBill Fenner #include "extract.h" 34685295f4SBill Fenner #include "chdlc.h" 35b0453382SBill Fenner 363c602fabSXin LI static void chdlc_slarp_print(netdissect_options *, const u_char *, u_int); 37b0453382SBill Fenner 383c602fabSXin LI static const struct tok chdlc_cast_values[] = { 39b5bfcb5dSMax Laier { CHDLC_UNICAST, "unicast" }, 40b5bfcb5dSMax Laier { CHDLC_BCAST, "bcast" }, 41b5bfcb5dSMax Laier { 0, NULL} 42b5bfcb5dSMax Laier }; 43b5bfcb5dSMax Laier 44b5bfcb5dSMax Laier 45b0453382SBill Fenner /* Standard CHDLC printer */ 465b0fe478SBruce M Simpson u_int 473c602fabSXin LI chdlc_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p) 48b0453382SBill Fenner { 49*0bff6a5aSEd Maste return chdlc_print(ndo, p, h->len); 502ebc47dbSSam Leffler } 512ebc47dbSSam Leffler 522ebc47dbSSam Leffler u_int 538bdc5a62SPatrick Kelsey chdlc_print(netdissect_options *ndo, register const u_char *p, u_int length) 548bdc5a62SPatrick Kelsey { 552ebc47dbSSam Leffler u_int proto; 56*0bff6a5aSEd Maste const u_char *bp = p; 57a90e161bSBill Fenner 58*0bff6a5aSEd Maste if (length < CHDLC_HDRLEN) 59*0bff6a5aSEd Maste goto trunc; 60*0bff6a5aSEd Maste ND_TCHECK2(*p, CHDLC_HDRLEN); 61a90e161bSBill Fenner proto = EXTRACT_16BITS(&p[2]); 623c602fabSXin LI if (ndo->ndo_eflag) { 633c602fabSXin LI ND_PRINT((ndo, "%s, ethertype %s (0x%04x), length %u: ", 64b5bfcb5dSMax Laier tok2str(chdlc_cast_values, "0x%02x", p[0]), 65b5bfcb5dSMax Laier tok2str(ethertype_values, "Unknown", proto), 66b5bfcb5dSMax Laier proto, 673c602fabSXin LI length)); 68b0453382SBill Fenner } 69b0453382SBill Fenner 70b0453382SBill Fenner length -= CHDLC_HDRLEN; 71b5bfcb5dSMax Laier p += CHDLC_HDRLEN; 72b5bfcb5dSMax Laier 73b0453382SBill Fenner switch (proto) { 74b0453382SBill Fenner case ETHERTYPE_IP: 753c602fabSXin LI ip_print(ndo, p, length); 76b0453382SBill Fenner break; 77b0453382SBill Fenner case ETHERTYPE_IPV6: 783c602fabSXin LI ip6_print(ndo, p, length); 79b0453382SBill Fenner break; 80b0453382SBill Fenner case CHDLC_TYPE_SLARP: 813c602fabSXin LI chdlc_slarp_print(ndo, p, length); 82b0453382SBill Fenner break; 83b0453382SBill Fenner #if 0 84b0453382SBill Fenner case CHDLC_TYPE_CDP: 85b5bfcb5dSMax Laier chdlc_cdp_print(p, length); 86b0453382SBill Fenner break; 87b0453382SBill Fenner #endif 885b0fe478SBruce M Simpson case ETHERTYPE_MPLS: 895b0fe478SBruce M Simpson case ETHERTYPE_MPLS_MULTI: 903c602fabSXin LI mpls_print(ndo, p, length); 915b0fe478SBruce M Simpson break; 925b0fe478SBruce M Simpson case ETHERTYPE_ISO: 935b0fe478SBruce M Simpson /* is the fudge byte set ? lets verify by spotting ISO headers */ 94*0bff6a5aSEd Maste if (length < 2) 95*0bff6a5aSEd Maste goto trunc; 96*0bff6a5aSEd Maste ND_TCHECK_16BITS(p); 97b5bfcb5dSMax Laier if (*(p+1) == 0x81 || 98b5bfcb5dSMax Laier *(p+1) == 0x82 || 99b5bfcb5dSMax Laier *(p+1) == 0x83) 100*0bff6a5aSEd Maste isoclns_print(ndo, p + 1, length - 1); 1015b0fe478SBruce M Simpson else 102*0bff6a5aSEd Maste isoclns_print(ndo, p, length); 1035b0fe478SBruce M Simpson break; 1045b0fe478SBruce M Simpson default: 1053c602fabSXin LI if (!ndo->ndo_eflag) 1063c602fabSXin LI ND_PRINT((ndo, "unknown CHDLC protocol (0x%04x)", proto)); 1075b0fe478SBruce M Simpson break; 108b0453382SBill Fenner } 1095b0fe478SBruce M Simpson 1105b0fe478SBruce M Simpson return (CHDLC_HDRLEN); 111*0bff6a5aSEd Maste 112*0bff6a5aSEd Maste trunc: 113*0bff6a5aSEd Maste ND_PRINT((ndo, "[|chdlc]")); 114*0bff6a5aSEd Maste return ndo->ndo_snapend - bp; 115b0453382SBill Fenner } 116b0453382SBill Fenner 117f4d0c64aSSam Leffler /* 118f4d0c64aSSam Leffler * The fixed-length portion of a SLARP packet. 119f4d0c64aSSam Leffler */ 120b0453382SBill Fenner struct cisco_slarp { 1213c602fabSXin LI uint8_t code[4]; 122b0453382SBill Fenner #define SLARP_REQUEST 0 123b0453382SBill Fenner #define SLARP_REPLY 1 124b0453382SBill Fenner #define SLARP_KEEPALIVE 2 125b0453382SBill Fenner union { 126b0453382SBill Fenner struct { 1273c602fabSXin LI uint8_t addr[4]; 1283c602fabSXin LI uint8_t mask[4]; 129b0453382SBill Fenner } addr; 130b0453382SBill Fenner struct { 1313c602fabSXin LI uint8_t myseq[4]; 1323c602fabSXin LI uint8_t yourseq[4]; 1333c602fabSXin LI uint8_t rel[2]; 134b0453382SBill Fenner } keep; 135b0453382SBill Fenner } un; 136b0453382SBill Fenner }; 137b0453382SBill Fenner 138f4d0c64aSSam Leffler #define SLARP_MIN_LEN 14 139f4d0c64aSSam Leffler #define SLARP_MAX_LEN 18 140b0453382SBill Fenner 141b0453382SBill Fenner static void 1423c602fabSXin LI chdlc_slarp_print(netdissect_options *ndo, const u_char *cp, u_int length) 143b0453382SBill Fenner { 144a90e161bSBill Fenner const struct cisco_slarp *slarp; 145f4d0c64aSSam Leffler u_int sec,min,hrs,days; 146b0453382SBill Fenner 1473c602fabSXin LI ND_PRINT((ndo, "SLARP (length: %u), ",length)); 148f4d0c64aSSam Leffler if (length < SLARP_MIN_LEN) 1495b0fe478SBruce M Simpson goto trunc; 150b0453382SBill Fenner 151a90e161bSBill Fenner slarp = (const struct cisco_slarp *)cp; 1523c602fabSXin LI ND_TCHECK2(*slarp, SLARP_MIN_LEN); 1535b0fe478SBruce M Simpson switch (EXTRACT_32BITS(&slarp->code)) { 154b0453382SBill Fenner case SLARP_REQUEST: 1553c602fabSXin LI ND_PRINT((ndo, "request")); 156f4d0c64aSSam Leffler /* 157f4d0c64aSSam Leffler * At least according to William "Chops" Westfield's 158f4d0c64aSSam Leffler * message in 159f4d0c64aSSam Leffler * 160f4d0c64aSSam Leffler * http://www.nethelp.no/net/cisco-hdlc.txt 161f4d0c64aSSam Leffler * 162f4d0c64aSSam Leffler * the address and mask aren't used in requests - 163f4d0c64aSSam Leffler * they're just zero. 164f4d0c64aSSam Leffler */ 165b0453382SBill Fenner break; 166b0453382SBill Fenner case SLARP_REPLY: 1673c602fabSXin LI ND_PRINT((ndo, "reply %s/%s", 1683c602fabSXin LI ipaddr_string(ndo, &slarp->un.addr.addr), 1693c602fabSXin LI ipaddr_string(ndo, &slarp->un.addr.mask))); 170b0453382SBill Fenner break; 171b0453382SBill Fenner case SLARP_KEEPALIVE: 1723c602fabSXin LI ND_PRINT((ndo, "keepalive: mineseen=0x%08x, yourseen=0x%08x, reliability=0x%04x", 1735b0fe478SBruce M Simpson EXTRACT_32BITS(&slarp->un.keep.myseq), 174f4d0c64aSSam Leffler EXTRACT_32BITS(&slarp->un.keep.yourseq), 1753c602fabSXin LI EXTRACT_16BITS(&slarp->un.keep.rel))); 176f4d0c64aSSam Leffler 177f4d0c64aSSam Leffler if (length >= SLARP_MAX_LEN) { /* uptime-stamp is optional */ 178f4d0c64aSSam Leffler cp += SLARP_MIN_LEN; 1793c602fabSXin LI ND_TCHECK2(*cp, 4); 180f4d0c64aSSam Leffler sec = EXTRACT_32BITS(cp) / 1000; 181f4d0c64aSSam Leffler min = sec / 60; sec -= min * 60; 182f4d0c64aSSam Leffler hrs = min / 60; min -= hrs * 60; 183f4d0c64aSSam Leffler days = hrs / 24; hrs -= days * 24; 1843c602fabSXin LI ND_PRINT((ndo, ", link uptime=%ud%uh%um%us",days,hrs,min,sec)); 185f4d0c64aSSam Leffler } 186b0453382SBill Fenner break; 187b0453382SBill Fenner default: 1883c602fabSXin LI ND_PRINT((ndo, "0x%02x unknown", EXTRACT_32BITS(&slarp->code))); 1893c602fabSXin LI if (ndo->ndo_vflag <= 1) 1903c602fabSXin LI print_unknown_data(ndo,cp+4,"\n\t",length-4); 191b0453382SBill Fenner break; 192b0453382SBill Fenner } 193b0453382SBill Fenner 1943c602fabSXin LI if (SLARP_MAX_LEN < length && ndo->ndo_vflag) 1953c602fabSXin LI ND_PRINT((ndo, ", (trailing junk: %d bytes)", length - SLARP_MAX_LEN)); 1963c602fabSXin LI if (ndo->ndo_vflag > 1) 1973c602fabSXin LI print_unknown_data(ndo,cp+4,"\n\t",length-4); 1985b0fe478SBruce M Simpson return; 1995b0fe478SBruce M Simpson 2005b0fe478SBruce M Simpson trunc: 2013c602fabSXin LI ND_PRINT((ndo, "[|slarp]")); 202b0453382SBill Fenner } 2031de50e9fSSam Leffler 2041de50e9fSSam Leffler 2051de50e9fSSam Leffler /* 2061de50e9fSSam Leffler * Local Variables: 2071de50e9fSSam Leffler * c-style: whitesmith 2081de50e9fSSam Leffler * c-basic-offset: 8 2091de50e9fSSam Leffler * End: 2101de50e9fSSam Leffler */ 211