1 /* $OpenBSD: print-ether.c,v 1.30 2015/11/16 00:16:39 mmcc 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 struct mbuf; 28 struct rtentry; 29 #include <net/if.h> 30 31 #include <netinet/in.h> 32 #include <netinet/if_ether.h> 33 #include <netinet/ip.h> 34 #include <netinet/ip_var.h> 35 #include <netinet/udp.h> 36 #include <netinet/udp_var.h> 37 #include <netinet/tcp.h> 38 39 #include <stdio.h> 40 #include <pcap.h> 41 42 #ifdef INET6 43 #include <netinet/ip6.h> 44 #endif 45 46 #include "interface.h" 47 #include "addrtoname.h" 48 #include "ethertype.h" 49 #include "extract.h" 50 51 const u_char *packetp; 52 const u_char *snapend; 53 54 void ether_macctl(const u_char *, u_int); 55 56 void 57 ether_print(const u_char *bp, u_int length) 58 { 59 const struct ether_header *ep; 60 61 ep = (const struct ether_header *)bp; 62 if (qflag) { 63 TCHECK2(*ep, 12); 64 (void)printf("%s %s %d: ", 65 etheraddr_string(ESRC(ep)), 66 etheraddr_string(EDST(ep)), 67 length); 68 } else { 69 TCHECK2(*ep, 14); 70 (void)printf("%s %s %s %d: ", 71 etheraddr_string(ESRC(ep)), 72 etheraddr_string(EDST(ep)), 73 etherproto_string(ep->ether_type), 74 length); 75 } 76 return; 77 trunc: 78 printf("[|ether] "); 79 } 80 81 u_short extracted_ethertype; 82 83 /* 84 * This is the top level routine of the printer. 'p' is the points 85 * to the ether header of the packet, 'tvp' is the timestamp, 86 * 'length' is the length of the packet off the wire, and 'caplen' 87 * is the number of bytes actually captured. 88 */ 89 void 90 ether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) 91 { 92 u_int caplen = h->caplen; 93 u_int length = h->len; 94 struct ether_header *ep; 95 u_short ether_type; 96 97 ts_print(&h->ts); 98 99 if (caplen < sizeof(struct ether_header)) { 100 printf("[|ether]"); 101 goto out; 102 } 103 104 /* 105 * Some printers want to get back at the ethernet addresses, 106 * and/or check that they're not walking off the end of the packet. 107 * Rather than pass them all the way down, we set these globals. 108 */ 109 packetp = p; 110 snapend = p + caplen; 111 112 if (eflag) 113 ether_print(p, length); 114 115 length -= sizeof(struct ether_header); 116 caplen -= sizeof(struct ether_header); 117 ep = (struct ether_header *)p; 118 p += sizeof(struct ether_header); 119 120 ether_type = ntohs(ep->ether_type); 121 122 /* 123 * Is it (gag) an 802.3 encapsulation? 124 */ 125 extracted_ethertype = 0; 126 if (ether_type <= ETHERMTU) { 127 /* Try to print the LLC-layer header & higher layers */ 128 if (llc_print(p, length, caplen, ESRC(ep), EDST(ep)) == 0) { 129 /* ether_type not known, print raw packet */ 130 if (!eflag) 131 ether_print((u_char *)ep, length); 132 if (extracted_ethertype) { 133 printf("(LLC %s) ", 134 etherproto_string(htons(extracted_ethertype))); 135 } 136 if (!xflag && !qflag) { 137 if (eflag) 138 default_print(packetp, 139 snapend - packetp); 140 else 141 default_print(p, caplen); 142 } 143 } 144 } else if (ether_encap_print(ether_type, p, length, caplen) == 0) { 145 /* ether_type not known, print raw packet */ 146 if (!eflag) 147 ether_print((u_char *)ep, length + sizeof(*ep)); 148 if (!xflag && !qflag) { 149 if (eflag) 150 default_print(packetp, snapend - packetp); 151 else 152 default_print(p, caplen); 153 } 154 } 155 if (xflag) { 156 if (eflag) 157 default_print(packetp, snapend - packetp); 158 else 159 default_print(p, caplen); 160 } 161 out: 162 putchar('\n'); 163 } 164 165 /* 166 * Prints the packet encapsulated in an Ethernet data segment 167 * (or an equivalent encapsulation), given the Ethernet type code. 168 * 169 * Returns non-zero if it can do so, zero if the ethertype is unknown. 170 * 171 * Stuffs the ether type into a global for the benefit of lower layers 172 * that might want to know what it is. 173 */ 174 175 int 176 ether_encap_print(u_short ethertype, const u_char *p, 177 u_int length, u_int caplen) 178 { 179 recurse: 180 extracted_ethertype = ethertype; 181 182 switch (ethertype) { 183 184 case ETHERTYPE_IP: 185 ip_print(p, length); 186 return (1); 187 188 #ifdef INET6 189 case ETHERTYPE_IPV6: 190 ip6_print(p, length); 191 return (1); 192 #endif /*INET6*/ 193 194 case ETHERTYPE_ARP: 195 case ETHERTYPE_REVARP: 196 arp_print(p, length, caplen); 197 return (1); 198 199 case ETHERTYPE_DN: 200 decnet_print(p, length, caplen); 201 return (1); 202 203 case ETHERTYPE_ATALK: 204 if (vflag) 205 fputs("et1 ", stdout); 206 atalk_print_llap(p, length); 207 return (1); 208 209 case ETHERTYPE_AARP: 210 aarp_print(p, length); 211 return (1); 212 213 case ETHERTYPE_8021Q: 214 printf("802.1Q "); 215 case ETHERTYPE_QINQ: 216 if (ethertype == ETHERTYPE_QINQ) 217 printf("QinQ s"); 218 printf("vid %d pri %d%s", 219 ntohs(*(unsigned short*)p)&0xFFF, 220 ntohs(*(unsigned short*)p)>>13, 221 (ntohs(*(unsigned short*)p)&0x1000) ? " cfi " : " "); 222 ethertype = ntohs(*(unsigned short*)(p+2)); 223 p += 4; 224 length -= 4; 225 caplen -= 4; 226 if (ethertype > ETHERMTU) 227 goto recurse; 228 229 extracted_ethertype = 0; 230 231 if (llc_print(p, length, caplen, p-18, p-12) == 0) { 232 /* ether_type not known, print raw packet */ 233 if (!eflag) 234 ether_print(p-18, length+4); 235 if (extracted_ethertype) { 236 printf("(LLC %s) ", 237 etherproto_string(htons(extracted_ethertype))); 238 } 239 if (!xflag && !qflag) 240 default_print(p-18, caplen+4); 241 } 242 return (1); 243 244 #ifdef PPP 245 case ETHERTYPE_PPPOEDISC: 246 case ETHERTYPE_PPPOE: 247 pppoe_if_print(ethertype, p, length, caplen); 248 return (1); 249 #endif 250 251 case ETHERTYPE_FLOWCONTROL: 252 ether_macctl(p, length); 253 return (1); 254 255 case ETHERTYPE_MPLS: 256 case ETHERTYPE_MPLS_MCAST: 257 mpls_print(p, length); 258 return (1); 259 260 case ETHERTYPE_LLDP: 261 lldp_print(p, length); 262 return (1); 263 264 case ETHERTYPE_SLOW: 265 slow_print(p, length); 266 return (1); 267 268 case ETHERTYPE_LAT: 269 case ETHERTYPE_SCA: 270 case ETHERTYPE_MOPRC: 271 case ETHERTYPE_MOPDL: 272 /* default_print for now */ 273 default: 274 return (0); 275 } 276 } 277 278 void 279 ether_macctl(const u_char *p, u_int length) 280 { 281 printf("MACCTL"); 282 283 if (length < 2) 284 goto trunc; 285 if (EXTRACT_16BITS(p) == 0x0001) { 286 u_int plen; 287 288 printf(" PAUSE"); 289 290 length -= 2; 291 p += 2; 292 if (length < 2) 293 goto trunc; 294 plen = 512 * EXTRACT_16BITS(p); 295 printf(" quanta %u", plen); 296 } else { 297 printf(" unknown-opcode(0x%04x)", EXTRACT_16BITS(p)); 298 } 299 return; 300 301 trunc: 302 printf("[|MACCTL]"); 303 } 304