print-ether.c revision 172686
1296853Sdes/* 276259Sgreen * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000 3126274Sdes * The Regents of the University of California. All rights reserved. 476259Sgreen * 5126274Sdes * Redistribution and use in source and binary forms, with or without 6126274Sdes * modification, are permitted provided that: (1) source code distributions 7126274Sdes * retain the above copyright notice and this paragraph in its entirety, (2) 876259Sgreen * distributions including binary code include the above copyright notice and 9126274Sdes * this paragraph in its entirety in the documentation or other materials 10126274Sdes * provided with the distribution, and (3) all advertising materials mentioning 11126274Sdes * features or use of this software display the following acknowledgement: 12126274Sdes * ``This product includes software developed by the University of California, 13126274Sdes * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 14126274Sdes * the University nor the names of its contributors may be used to endorse 15126274Sdes * or promote products derived from this software without specific prior 1676259Sgreen * written permission. 1776259Sgreen * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1876259Sgreen * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1976259Sgreen * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20295367Sdes * 21162852Sdes * $FreeBSD: head/contrib/tcpdump/print-ether.c 172686 2007-10-16 02:31:48Z mlaier $ 22162852Sdes */ 23162852Sdes#ifndef lint 24162852Sdesstatic const char rcsid[] _U_ = 25162852Sdes "@(#) $Header: /tcpdump/master/tcpdump/print-ether.c,v 1.95.2.6 2006/02/20 18:15:03 hannes Exp $ (LBL)"; 26162852Sdes#endif 27162852Sdes 28162852Sdes#ifdef HAVE_CONFIG_H 29181111Sdes#include "config.h" 30181111Sdes#endif 31181111Sdes 3276259Sgreen#include <tcpdump-stdinc.h> 33181111Sdes 34162852Sdes#include <stdio.h> 35162852Sdes#include <pcap.h> 36162852Sdes 37162852Sdes#include "interface.h" 38162852Sdes#include "addrtoname.h" 39204917Sdes#include "ethertype.h" 40204917Sdes 41204917Sdes#include "ether.h" 42255767Sdes 43255767Sdesconst struct tok ethertype_values[] = { 44255767Sdes { ETHERTYPE_IP, "IPv4" }, 45146998Sdes { ETHERTYPE_MPLS, "MPLS unicast" }, 46146998Sdes { ETHERTYPE_MPLS_MULTI, "MPLS multicast" }, 47146998Sdes { ETHERTYPE_IPV6, "IPv6" }, 48146998Sdes { ETHERTYPE_8021Q, "802.1Q" }, 49146998Sdes { ETHERTYPE_VMAN, "VMAN" }, 50295367Sdes { ETHERTYPE_PUP, "PUP" }, 51162852Sdes { ETHERTYPE_ARP, "ARP"}, 52162852Sdes { ETHERTYPE_REVARP, "Reverse ARP"}, 53162852Sdes { ETHERTYPE_NS, "NS" }, 54162852Sdes { ETHERTYPE_SPRITE, "Sprite" }, 55162852Sdes { ETHERTYPE_TRAIL, "Trail" }, 56162852Sdes { ETHERTYPE_MOPDL, "MOP DL" }, 57146998Sdes { ETHERTYPE_MOPRC, "MOP RC" }, 58181111Sdes { ETHERTYPE_DN, "DN" }, 59181111Sdes { ETHERTYPE_LAT, "LAT" }, 60181111Sdes { ETHERTYPE_SCA, "SCA" }, 61181111Sdes { ETHERTYPE_LANBRIDGE, "Lanbridge" }, 6276259Sgreen { ETHERTYPE_DECDNS, "DEC DNS" }, 6376259Sgreen { ETHERTYPE_DECDTS, "DEC DTS" }, 6476259Sgreen { ETHERTYPE_VEXP, "VEXP" }, 6592555Sdes { ETHERTYPE_VPROD, "VPROD" }, 6676259Sgreen { ETHERTYPE_ATALK, "Appletalk" }, 6776259Sgreen { ETHERTYPE_AARP, "Appletalk ARP" }, 68295367Sdes { ETHERTYPE_IPX, "IPX" }, 69295367Sdes { ETHERTYPE_PPP, "PPP" }, 7076259Sgreen { ETHERTYPE_SLOW, "Slow Protocols" }, 7176259Sgreen { ETHERTYPE_PPPOED, "PPPoE D" }, 7276259Sgreen { ETHERTYPE_PPPOES, "PPPoE S" }, 73204917Sdes { ETHERTYPE_EAPOL, "EAPOL" }, 74294693Sdes { ETHERTYPE_JUMBO, "Jumbo" }, 75204917Sdes { ETHERTYPE_LOOPBACK, "Loopback" }, 76126274Sdes { ETHERTYPE_ISO, "OSI" }, 77126274Sdes { ETHERTYPE_GRE_ISO, "GRE-OSI" }, 78126274Sdes { 0, NULL} 79126274Sdes}; 80126274Sdes 81126274Sdesstatic inline void 82126274Sdesether_hdr_print(register const u_char *bp, u_int length) 83126274Sdes{ 84126274Sdes register const struct ether_header *ep; 85255767Sdes ep = (const struct ether_header *)bp; 86255767Sdes 87255767Sdes (void)printf("%s > %s", 88126274Sdes etheraddr_string(ESRC(ep)), 89128456Sdes etheraddr_string(EDST(ep))); 90126274Sdes 91204917Sdes if (!qflag) { 92204917Sdes if (ntohs(ep->ether_type) <= ETHERMTU) 93204917Sdes (void)printf(", 802.3"); 94295367Sdes else 95255767Sdes (void)printf(", ethertype %s (0x%04x)", 96255767Sdes tok2str(ethertype_values,"Unknown", ntohs(ep->ether_type)), 97204917Sdes ntohs(ep->ether_type)); 98204917Sdes } else { 99204917Sdes if (ntohs(ep->ether_type) <= ETHERMTU) 100262566Sdes (void)printf(", 802.3"); 101262566Sdes else 102262566Sdes (void)printf(", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", ntohs(ep->ether_type))); 103137015Sdes } 104137015Sdes 105137015Sdes (void)printf(", length %u: ", length); 106137015Sdes} 107137015Sdes 108137015Sdesvoid 109204917Sdesether_print(const u_char *p, u_int length, u_int caplen) 110204917Sdes{ 111204917Sdes struct ether_header *ep; 112204917Sdes u_short ether_type; 113204917Sdes u_short extracted_ether_type; 114204917Sdes 115126274Sdes if (caplen < ETHER_HDRLEN) { 116126274Sdes printf("[|ether]"); 117126274Sdes return; 11898937Sdes } 11998937Sdes 120126274Sdes if (eflag) 121126274Sdes ether_hdr_print(p, length); 12276259Sgreen 123137015Sdes length -= ETHER_HDRLEN; 124204917Sdes caplen -= ETHER_HDRLEN; 125204917Sdes ep = (struct ether_header *)p; 126204917Sdes p += ETHER_HDRLEN; 127204917Sdes 128204917Sdes ether_type = ntohs(ep->ether_type); 129204917Sdes 130204917Sdes /* 131204917Sdes * Is it (gag) an 802.3 encapsulation? 132204917Sdes */ 133113908Sdes if (ether_type <= ETHERMTU) { 134204917Sdes /* Try to print the LLC-layer header & higher layers */ 135137015Sdes if (llc_print(p, length, caplen, ESRC(ep), EDST(ep), 136137015Sdes &extracted_ether_type) == 0) { 137126274Sdes /* ether_type not known, print raw packet */ 138262566Sdes if (!eflag) 139262566Sdes ether_hdr_print((u_char *)ep, length + ETHER_HDRLEN); 140262566Sdes 141262566Sdes if (!suppress_default_print) 142262566Sdes default_print(p, caplen); 143262566Sdes } 144262566Sdes } else if (ether_encap_print(ether_type, p, length, caplen, 145262566Sdes &extracted_ether_type) == 0) { 146262566Sdes /* ether_type not known, print raw packet */ 147262566Sdes if (!eflag) 148262566Sdes ether_hdr_print((u_char *)ep, length + ETHER_HDRLEN); 149262566Sdes 150262566Sdes if (!suppress_default_print) 151262566Sdes default_print(p, caplen); 152262566Sdes } 153262566Sdes} 154262566Sdes 155262566Sdes/* 156262566Sdes * This is the top level routine of the printer. 'p' points 157295367Sdes * to the ether header of the packet, 'h->ts' is the timestamp, 158262566Sdes * 'h->len' is the length of the packet off the wire, and 'h->caplen' 159295367Sdes * is the number of bytes actually captured. 160262566Sdes */ 161262566Sdesu_int 162262566Sdesether_if_print(const struct pcap_pkthdr *h, const u_char *p) 163262566Sdes{ 164262566Sdes ether_print(p, h->len, h->caplen); 165262566Sdes 166262566Sdes return (ETHER_HDRLEN); 167126274Sdes} 168126274Sdes 169126274Sdes/* 170126274Sdes * Prints the packet encapsulated in an Ethernet data segment 171204917Sdes * (or an equivalent encapsulation), given the Ethernet type code. 172126274Sdes * 173126274Sdes * Returns non-zero if it can do so, zero if the ethertype is unknown. 174204917Sdes * 175204917Sdes * The Ethernet type code is passed through a pointer; if it was 176204917Sdes * ETHERTYPE_8021Q, it gets updated to be the Ethernet type of 177204917Sdes * the 802.1Q payload, for the benefit of lower layers that might 178204917Sdes * want to know what it is. 179126274Sdes */ 180204917Sdes 181204917Sdesint 182204917Sdesether_encap_print(u_short ether_type, const u_char *p, 183204917Sdes u_int length, u_int caplen, u_short *extracted_ether_type) 184204917Sdes{ 185204917Sdes recurse: 186204917Sdes *extracted_ether_type = ether_type; 187204917Sdes 188204917Sdes switch (ether_type) { 189204917Sdes 190204917Sdes case ETHERTYPE_IP: 191204917Sdes ip_print(gndo, p, length); 192204917Sdes return (1); 193204917Sdes 194204917Sdes#ifdef INET6 195221420Sdes case ETHERTYPE_IPV6: 196204917Sdes ip6_print(p, length); 197204917Sdes return (1); 198204917Sdes#endif /*INET6*/ 199204917Sdes 200215116Sdes case ETHERTYPE_ARP: 201215116Sdes case ETHERTYPE_REVARP: 202204917Sdes arp_print(gndo, p, length, caplen); 203204917Sdes return (1); 204204917Sdes 205204917Sdes case ETHERTYPE_DN: 206255767Sdes decnet_print(p, length, caplen); 207204917Sdes return (1); 208295367Sdes 209204917Sdes case ETHERTYPE_ATALK: 210204917Sdes if (vflag) 211204917Sdes fputs("et1 ", stdout); 212204917Sdes atalk_print(p, length); 213204917Sdes return (1); 214204917Sdes 215204917Sdes case ETHERTYPE_AARP: 216126274Sdes aarp_print(p, length); 217126274Sdes return (1); 218204917Sdes 219126274Sdes case ETHERTYPE_IPX: 220181111Sdes printf("(NOV-ETHII) "); 22192555Sdes ipx_print(p, length); 222137015Sdes return (1); 223137015Sdes 224146998Sdes case ETHERTYPE_8021Q: 225137015Sdes if (eflag) 226146998Sdes printf("vlan %u, p %u%s, ", 227146998Sdes ntohs(*(u_int16_t *)p) & 0xfff, 228137015Sdes ntohs(*(u_int16_t *)p) >> 13, 229137015Sdes (ntohs(*(u_int16_t *)p) & 0x1000) ? ", CFI" : ""); 230137015Sdes 231137015Sdes ether_type = ntohs(*(u_int16_t *)(p + 2)); 232181111Sdes p += 4; 233137015Sdes length -= 4; 234137015Sdes caplen -= 4; 235137015Sdes 236137015Sdes if (ether_type > ETHERMTU) { 237146998Sdes if (eflag) 238137015Sdes printf("ethertype %s, ", 239255767Sdes tok2str(ethertype_values,"0x%04x", ether_type)); 240137015Sdes goto recurse; 241146998Sdes } 242137015Sdes 243137015Sdes *extracted_ether_type = 0; 244137015Sdes 245126274Sdes if (llc_print(p, length, caplen, p - 18, p - 12, 246126274Sdes extracted_ether_type) == 0) { 247192595Sdes ether_hdr_print(p - 18, length + 4); 248192595Sdes 249192595Sdes if (!suppress_default_print) { 250192595Sdes default_print(p - 18, caplen + 4); 251192595Sdes } 252192595Sdes } 253192595Sdes 254192595Sdes 255192595Sdes return (1); 256295367Sdes 257295367Sdes case ETHERTYPE_JUMBO: 258295367Sdes ether_type = ntohs(*(u_int16_t *)(p)); 259192595Sdes p += 2; 260192595Sdes length -= 2; 261192595Sdes caplen -= 2; 262192595Sdes 263221420Sdes if (ether_type > ETHERMTU) { 264192595Sdes if (eflag) 265204917Sdes printf("ethertype %s, ", 266192595Sdes tok2str(ethertype_values,"0x%04x", ether_type)); 267192595Sdes goto recurse; 268192595Sdes } 269295367Sdes 270192595Sdes *extracted_ether_type = 0; 271192595Sdes 272192595Sdes if (llc_print(p, length, caplen, p - 16, p - 10, 273192595Sdes extracted_ether_type) == 0) { 274192595Sdes ether_hdr_print(p - 16, length + 2); 275192595Sdes 276192595Sdes if (!suppress_default_print) { 277192595Sdes default_print(p - 16, caplen + 2); 278192595Sdes } 279192595Sdes } 280126274Sdes 281126274Sdes return (1); 282126274Sdes 283126274Sdes case ETHERTYPE_ISO: 284126274Sdes isoclns_print(p+1, length-1, length-1); 285126274Sdes return(1); 286126274Sdes 287126274Sdes case ETHERTYPE_PPPOED: 288126274Sdes case ETHERTYPE_PPPOES: 289126274Sdes case ETHERTYPE_PPPOED2: 290126274Sdes case ETHERTYPE_PPPOES2: 291126274Sdes pppoe_print(p, length); 292221420Sdes return (1); 293126274Sdes 294126274Sdes case ETHERTYPE_EAPOL: 295126274Sdes eap_print(gndo, p, length); 296126274Sdes return (1); 297126274Sdes 298126274Sdes case ETHERTYPE_PPP: 299126274Sdes if (length) { 300126274Sdes printf(": "); 301126274Sdes ppp_print(p, length); 302126274Sdes } 303126274Sdes return (1); 304126274Sdes 305126274Sdes case ETHERTYPE_SLOW: 306126274Sdes slow_print(p, length); 307126274Sdes return (1); 308126274Sdes 309126274Sdes case ETHERTYPE_LOOPBACK: 310126274Sdes return (1); 311126274Sdes 312126274Sdes case ETHERTYPE_MPLS: 313126274Sdes case ETHERTYPE_MPLS_MULTI: 314126274Sdes mpls_print(p, length); 315162852Sdes return (1); 316126274Sdes 317126274Sdes case ETHERTYPE_LAT: 318126274Sdes case ETHERTYPE_SCA: 319126274Sdes case ETHERTYPE_MOPRC: 320126274Sdes case ETHERTYPE_MOPDL: 321126274Sdes /* default_print for now */ 322126274Sdes default: 323126274Sdes return (0); 324126274Sdes } 325126274Sdes} 326126274Sdes 327126274Sdes 328126274Sdes/* 329126274Sdes * Local Variables: 330126274Sdes * c-style: whitesmith 331126274Sdes * c-basic-offset: 8 332255767Sdes * End: 333126274Sdes */ 334126274Sdes 335126274Sdes