1 /* $OpenBSD: print-ether.c,v 1.39 2021/12/01 18:28:46 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that: (1) source code distributions 9 * retain the above copyright notice and this paragraph in its entirety, (2) 10 * distributions including binary code include the above copyright notice and 11 * this paragraph in its entirety in the documentation or other materials 12 * provided with the distribution, and (3) all advertising materials mentioning 13 * features or use of this software display the following acknowledgement: 14 * ``This product includes software developed by the University of California, 15 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 16 * the University nor the names of its contributors may be used to endorse 17 * or promote products derived from this software without specific prior 18 * written permission. 19 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 20 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 21 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 22 */ 23 24 #include <sys/time.h> 25 #include <sys/socket.h> 26 27 #include <net/if.h> 28 29 #include <netinet/in.h> 30 #include <netinet/if_ether.h> 31 #include <netinet/ip.h> 32 #include <netinet/ip6.h> 33 #include <netinet/ip_var.h> 34 #include <netinet/udp.h> 35 #include <netinet/udp_var.h> 36 #include <netinet/tcp.h> 37 38 #include <stdio.h> 39 #include <pcap.h> 40 41 42 #include "interface.h" 43 #include "addrtoname.h" 44 #include "ethertype.h" 45 #include "extract.h" 46 47 const u_char *packetp; 48 const u_char *snapend; 49 50 void ether_macctl(const u_char *, u_int); 51 void ether_pbb_print(const u_char *, u_int, u_int); 52 53 void 54 ether_print(const u_char *bp, u_int length) 55 { 56 const struct ether_header *ep; 57 58 ep = (const struct ether_header *)bp; 59 if (qflag) { 60 TCHECK2(*ep, 12); 61 printf("%s %s %d: ", 62 etheraddr_string(ESRC(ep)), 63 etheraddr_string(EDST(ep)), 64 length); 65 } else { 66 TCHECK2(*ep, 14); 67 printf("%s %s %s %d: ", 68 etheraddr_string(ESRC(ep)), 69 etheraddr_string(EDST(ep)), 70 etherproto_string(ep->ether_type), 71 length); 72 } 73 return; 74 trunc: 75 printf("[|ether] "); 76 } 77 78 u_short extracted_ethertype; 79 80 /* 81 * This is the top level routine of the printer. 'p' is the points 82 * to the ether header of the packet, 'tvp' is the timestamp, 83 * 'length' is the length of the packet off the wire, and 'caplen' 84 * is the number of bytes actually captured. 85 */ 86 void 87 ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) 88 { 89 ts_print(&h->ts); 90 91 /* 92 * Some printers want to get back at the ethernet addresses, 93 * and/or check that they're not walking off the end of the packet. 94 * Rather than pass them all the way down, we set these globals. 95 */ 96 snapend = p + h->caplen; 97 98 ether_tryprint(p, h->len, 1); 99 } 100 101 void 102 ether_tryprint(const u_char *p, u_int length, int first_header) 103 { 104 struct ether_header *ep; 105 u_int caplen = snapend - p; 106 u_short ether_type; 107 108 if (caplen < sizeof(struct ether_header)) { 109 printf("[|ether]"); 110 goto out; 111 } 112 113 if (eflag) 114 ether_print(p, length); 115 116 packetp = p; 117 length -= sizeof(struct ether_header); 118 caplen -= sizeof(struct ether_header); 119 ep = (struct ether_header *)p; 120 p += sizeof(struct ether_header); 121 122 ether_type = ntohs(ep->ether_type); 123 124 /* 125 * Is it (gag) an 802.3 encapsulation? 126 */ 127 extracted_ethertype = 0; 128 if (ether_type <= ETHERMTU) { 129 /* Try to print the LLC-layer header & higher layers */ 130 if (llc_print(p, length, caplen, ESRC(ep), EDST(ep)) == 0) { 131 /* ether_type not known, print raw packet */ 132 if (!eflag) 133 ether_print((u_char *)ep, length); 134 if (extracted_ethertype) { 135 printf("(LLC %s) ", 136 etherproto_string(htons(extracted_ethertype))); 137 } 138 if (!xflag && !qflag) { 139 if (eflag) 140 default_print(packetp, 141 snapend - packetp); 142 else 143 default_print(p, caplen); 144 } 145 } 146 } else if (ether_encap_print(ether_type, p, length, caplen) == 0) { 147 /* ether_type not known, print raw packet */ 148 if (!eflag) 149 ether_print((u_char *)ep, length + sizeof(*ep)); 150 if (!xflag && !qflag) { 151 if (eflag) 152 default_print(packetp, snapend - packetp); 153 else 154 default_print(p, caplen); 155 } 156 } 157 if (xflag && first_header) { 158 if (eflag) 159 default_print(packetp, snapend - packetp); 160 else 161 default_print(p, caplen); 162 } 163 out: 164 if (first_header) 165 putchar('\n'); 166 } 167 168 void 169 ether_pbb_print(const u_char *bp, u_int length, u_int caplen) 170 { 171 uint32_t itag; 172 uint8_t pri, res; 173 174 if (caplen < sizeof(itag)) 175 goto trunc; 176 177 itag = EXTRACT_32BITS(bp); 178 179 bp += sizeof(itag); 180 length -= sizeof(itag); 181 caplen -= sizeof(itag); 182 183 pri = itag >> 29; 184 if (pri <= 1) 185 pri = !pri; 186 187 res = (itag >> 24) & 0x7; 188 189 printf("802.1Q ivid %u pri %u ", itag & 0xffffff, pri); 190 if (itag & (1 << 28)) 191 printf("dei "); 192 if (itag & (1 << 27)) 193 printf("uca "); 194 if (res) 195 printf("res %u! ", res); 196 197 ether_tryprint(bp, length, 0); 198 199 return; 200 201 trunc: 202 printf("[|pbb] "); 203 } 204 205 /* 206 * Prints the packet encapsulated in an Ethernet data segment 207 * (or an equivalent encapsulation), given the Ethernet type code. 208 * 209 * Returns non-zero if it can do so, zero if the ethertype is unknown. 210 * 211 * Stuffs the ether type into a global for the benefit of lower layers 212 * that might want to know what it is. 213 */ 214 215 int 216 ether_encap_print(u_short ethertype, const u_char *p, 217 u_int length, u_int caplen) 218 { 219 uint16_t vlan, pri, vid; 220 recurse: 221 extracted_ethertype = ethertype; 222 223 switch (ethertype) { 224 225 case ETHERTYPE_IP: 226 ip_print(p, length); 227 return (1); 228 229 case ETHERTYPE_IPV6: 230 ip6_print(p, length); 231 return (1); 232 233 case ETHERTYPE_ARP: 234 case ETHERTYPE_REVARP: 235 arp_print(p, length, caplen); 236 return (1); 237 238 case ETHERTYPE_DN: 239 decnet_print(p, length, caplen); 240 return (1); 241 242 case ETHERTYPE_ATALK: 243 if (vflag) 244 printf("et1 "); 245 atalk_print_llap(p, length); 246 return (1); 247 248 case ETHERTYPE_AARP: 249 aarp_print(p, length); 250 return (1); 251 252 case ETHERTYPE_8021Q: 253 printf("802.1Q "); 254 case ETHERTYPE_QINQ: 255 if (ethertype == ETHERTYPE_QINQ) 256 printf("QinQ s"); 257 258 /* XXX caplen check */ 259 260 vlan = ntohs(*(unsigned short*)p); 261 vid = vlan & 0xfff; 262 pri = vlan >> 13; 263 if (pri <= 1) 264 pri = !pri; 265 266 printf("vid %d pri %d%s", vid, pri, 267 vlan & 0x1000 ? " dei " : " "); 268 ethertype = ntohs(*(unsigned short*)(p+2)); 269 p += 4; 270 length -= 4; 271 caplen -= 4; 272 if (ethertype > ETHERMTU) 273 goto recurse; 274 275 extracted_ethertype = 0; 276 277 if (llc_print(p, length, caplen, p-18, p-12) == 0) { 278 /* ether_type not known, print raw packet */ 279 if (!eflag) 280 ether_print(p-18, length+4); 281 if (extracted_ethertype) { 282 printf("(LLC %s) ", 283 etherproto_string(htons(extracted_ethertype))); 284 } 285 if (!xflag && !qflag) 286 default_print(p-18, caplen+4); 287 } 288 return (1); 289 290 #ifndef ETHERTYPE_NSH 291 #define ETHERTYPE_NSH 0x894f 292 #endif 293 case ETHERTYPE_NSH: 294 nsh_print(p, length); 295 return (1); 296 297 #ifndef ETHERTYPE_PBB 298 #define ETHERTYPE_PBB 0x88e7 299 #endif 300 case ETHERTYPE_PBB: 301 ether_pbb_print(p, length, caplen); 302 return (1); 303 304 #ifndef ETHERTYPE_NHRP 305 #define ETHERTYPE_NHRP 0x2001 306 #endif 307 case ETHERTYPE_NHRP: 308 nhrp_print(p, length); 309 return (1); 310 311 #ifdef PPP 312 case ETHERTYPE_PPPOEDISC: 313 case ETHERTYPE_PPPOE: 314 pppoe_if_print(ethertype, p, length, caplen); 315 return (1); 316 #endif 317 318 case ETHERTYPE_FLOWCONTROL: 319 ether_macctl(p, length); 320 return (1); 321 322 case ETHERTYPE_MPLS: 323 case ETHERTYPE_MPLS_MCAST: 324 mpls_print(p, length); 325 return (1); 326 327 case ETHERTYPE_LLDP: 328 lldp_print(p, length); 329 return (1); 330 331 case ETHERTYPE_SLOW: 332 slow_print(p, length); 333 return (1); 334 335 case ETHERTYPE_LAT: 336 case ETHERTYPE_SCA: 337 case ETHERTYPE_MOPRC: 338 case ETHERTYPE_MOPDL: 339 /* default_print for now */ 340 default: 341 return (0); 342 } 343 } 344 345 void 346 ether_macctl(const u_char *p, u_int length) 347 { 348 printf("MACCTL"); 349 350 if (length < 2) 351 goto trunc; 352 if (EXTRACT_16BITS(p) == 0x0001) { 353 u_int plen; 354 355 printf(" PAUSE"); 356 357 length -= 2; 358 p += 2; 359 if (length < 2) 360 goto trunc; 361 plen = 512 * EXTRACT_16BITS(p); 362 printf(" quanta %u", plen); 363 } else { 364 printf(" unknown-opcode(0x%04x)", EXTRACT_16BITS(p)); 365 } 366 return; 367 368 trunc: 369 printf("[|MACCTL]"); 370 } 371