1 /* 2 * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that: (1) source code distributions 7 * retain the above copyright notice and this paragraph in its entirety, (2) 8 * distributions including binary code include the above copyright notice and 9 * this paragraph in its entirety in the documentation or other materials 10 * provided with the distribution, and (3) all advertising materials mentioning 11 * features or use of this software display the following acknowledgement: 12 * ``This product includes software developed by the University of California, 13 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14 * the University nor the names of its contributors may be used to endorse 15 * or promote products derived from this software without specific prior 16 * written permission. 17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 18 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20 */ 21 22 #define NETDISSECT_REWORKED 23 #ifdef HAVE_CONFIG_H 24 #include "config.h" 25 #endif 26 27 #include <tcpdump-stdinc.h> 28 29 #include "interface.h" 30 #include "addrtoname.h" 31 #include "ethertype.h" 32 #include "extract.h" 33 #include "chdlc.h" 34 35 static void chdlc_slarp_print(netdissect_options *, const u_char *, u_int); 36 37 static const struct tok chdlc_cast_values[] = { 38 { CHDLC_UNICAST, "unicast" }, 39 { CHDLC_BCAST, "bcast" }, 40 { 0, NULL} 41 }; 42 43 44 /* Standard CHDLC printer */ 45 u_int 46 chdlc_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, register const u_char *p) 47 { 48 register u_int length = h->len; 49 register u_int caplen = h->caplen; 50 51 if (caplen < CHDLC_HDRLEN) { 52 ND_PRINT((ndo, "[|chdlc]")); 53 return (caplen); 54 } 55 return (chdlc_print(ndo, p,length)); 56 } 57 58 u_int 59 chdlc_print(netdissect_options *ndo, register const u_char *p, u_int length) 60 { 61 u_int proto; 62 63 proto = EXTRACT_16BITS(&p[2]); 64 if (ndo->ndo_eflag) { 65 ND_PRINT((ndo, "%s, ethertype %s (0x%04x), length %u: ", 66 tok2str(chdlc_cast_values, "0x%02x", p[0]), 67 tok2str(ethertype_values, "Unknown", proto), 68 proto, 69 length)); 70 } 71 72 length -= CHDLC_HDRLEN; 73 p += CHDLC_HDRLEN; 74 75 switch (proto) { 76 case ETHERTYPE_IP: 77 ip_print(ndo, p, length); 78 break; 79 case ETHERTYPE_IPV6: 80 ip6_print(ndo, p, length); 81 break; 82 case CHDLC_TYPE_SLARP: 83 chdlc_slarp_print(ndo, p, length); 84 break; 85 #if 0 86 case CHDLC_TYPE_CDP: 87 chdlc_cdp_print(p, length); 88 break; 89 #endif 90 case ETHERTYPE_MPLS: 91 case ETHERTYPE_MPLS_MULTI: 92 mpls_print(ndo, p, length); 93 break; 94 case ETHERTYPE_ISO: 95 /* is the fudge byte set ? lets verify by spotting ISO headers */ 96 if (*(p+1) == 0x81 || 97 *(p+1) == 0x82 || 98 *(p+1) == 0x83) 99 isoclns_print(ndo, p + 1, length - 1, length - 1); 100 else 101 isoclns_print(ndo, p, length, length); 102 break; 103 default: 104 if (!ndo->ndo_eflag) 105 ND_PRINT((ndo, "unknown CHDLC protocol (0x%04x)", proto)); 106 break; 107 } 108 109 return (CHDLC_HDRLEN); 110 } 111 112 /* 113 * The fixed-length portion of a SLARP packet. 114 */ 115 struct cisco_slarp { 116 uint8_t code[4]; 117 #define SLARP_REQUEST 0 118 #define SLARP_REPLY 1 119 #define SLARP_KEEPALIVE 2 120 union { 121 struct { 122 uint8_t addr[4]; 123 uint8_t mask[4]; 124 } addr; 125 struct { 126 uint8_t myseq[4]; 127 uint8_t yourseq[4]; 128 uint8_t rel[2]; 129 } keep; 130 } un; 131 }; 132 133 #define SLARP_MIN_LEN 14 134 #define SLARP_MAX_LEN 18 135 136 static void 137 chdlc_slarp_print(netdissect_options *ndo, const u_char *cp, u_int length) 138 { 139 const struct cisco_slarp *slarp; 140 u_int sec,min,hrs,days; 141 142 ND_PRINT((ndo, "SLARP (length: %u), ",length)); 143 if (length < SLARP_MIN_LEN) 144 goto trunc; 145 146 slarp = (const struct cisco_slarp *)cp; 147 ND_TCHECK2(*slarp, SLARP_MIN_LEN); 148 switch (EXTRACT_32BITS(&slarp->code)) { 149 case SLARP_REQUEST: 150 ND_PRINT((ndo, "request")); 151 /* 152 * At least according to William "Chops" Westfield's 153 * message in 154 * 155 * http://www.nethelp.no/net/cisco-hdlc.txt 156 * 157 * the address and mask aren't used in requests - 158 * they're just zero. 159 */ 160 break; 161 case SLARP_REPLY: 162 ND_PRINT((ndo, "reply %s/%s", 163 ipaddr_string(ndo, &slarp->un.addr.addr), 164 ipaddr_string(ndo, &slarp->un.addr.mask))); 165 break; 166 case SLARP_KEEPALIVE: 167 ND_PRINT((ndo, "keepalive: mineseen=0x%08x, yourseen=0x%08x, reliability=0x%04x", 168 EXTRACT_32BITS(&slarp->un.keep.myseq), 169 EXTRACT_32BITS(&slarp->un.keep.yourseq), 170 EXTRACT_16BITS(&slarp->un.keep.rel))); 171 172 if (length >= SLARP_MAX_LEN) { /* uptime-stamp is optional */ 173 cp += SLARP_MIN_LEN; 174 ND_TCHECK2(*cp, 4); 175 sec = EXTRACT_32BITS(cp) / 1000; 176 min = sec / 60; sec -= min * 60; 177 hrs = min / 60; min -= hrs * 60; 178 days = hrs / 24; hrs -= days * 24; 179 ND_PRINT((ndo, ", link uptime=%ud%uh%um%us",days,hrs,min,sec)); 180 } 181 break; 182 default: 183 ND_PRINT((ndo, "0x%02x unknown", EXTRACT_32BITS(&slarp->code))); 184 if (ndo->ndo_vflag <= 1) 185 print_unknown_data(ndo,cp+4,"\n\t",length-4); 186 break; 187 } 188 189 if (SLARP_MAX_LEN < length && ndo->ndo_vflag) 190 ND_PRINT((ndo, ", (trailing junk: %d bytes)", length - SLARP_MAX_LEN)); 191 if (ndo->ndo_vflag > 1) 192 print_unknown_data(ndo,cp+4,"\n\t",length-4); 193 return; 194 195 trunc: 196 ND_PRINT((ndo, "[|slarp]")); 197 } 198 199 200 /* 201 * Local Variables: 202 * c-style: whitesmith 203 * c-basic-offset: 8 204 * End: 205 */ 206