print-ether.c revision 17680
117680Spst/* 217680Spst * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996 317680Spst * The Regents of the University of California. All rights reserved. 417680Spst * 517680Spst * Redistribution and use in source and binary forms, with or without 617680Spst * modification, are permitted provided that: (1) source code distributions 717680Spst * retain the above copyright notice and this paragraph in its entirety, (2) 817680Spst * distributions including binary code include the above copyright notice and 917680Spst * this paragraph in its entirety in the documentation or other materials 1017680Spst * provided with the distribution, and (3) all advertising materials mentioning 1117680Spst * features or use of this software display the following acknowledgement: 1217680Spst * ``This product includes software developed by the University of California, 1317680Spst * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 1417680Spst * the University nor the names of its contributors may be used to endorse 1517680Spst * or promote products derived from this software without specific prior 1617680Spst * written permission. 1717680Spst * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 1817680Spst * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 1917680Spst * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 2017680Spst */ 2117680Spst#ifndef lint 2217680Spststatic char rcsid[] = 2317680Spst "@(#) $Header: print-ether.c,v 1.42 96/07/23 14:17:23 leres Exp $ (LBL)"; 2417680Spst#endif 2517680Spst 2617680Spst#include <sys/param.h> 2717680Spst#include <sys/time.h> 2817680Spst#include <sys/socket.h> 2917680Spst 3017680Spst#if __STDC__ 3117680Spststruct mbuf; 3217680Spststruct rtentry; 3317680Spst#endif 3417680Spst#include <net/if.h> 3517680Spst 3617680Spst#include <netinet/in.h> 3717680Spst#include <netinet/if_ether.h> 3817680Spst#include <netinet/in_systm.h> 3917680Spst#include <netinet/ip.h> 4017680Spst#include <netinet/ip_var.h> 4117680Spst#include <netinet/udp.h> 4217680Spst#include <netinet/udp_var.h> 4317680Spst#include <netinet/tcp.h> 4417680Spst#include <netinet/tcpip.h> 4517680Spst 4617680Spst#include <stdio.h> 4717680Spst#include <pcap.h> 4817680Spst 4917680Spst#include "interface.h" 5017680Spst#include "addrtoname.h" 5117680Spst#include "ethertype.h" 5217680Spst 5317680Spstconst u_char *packetp; 5417680Spstconst u_char *snapend; 5517680Spst 5617680Spststatic inline void 5717680Spstether_print(register const u_char *bp, u_int length) 5817680Spst{ 5917680Spst register const struct ether_header *ep; 6017680Spst 6117680Spst ep = (const struct ether_header *)bp; 6217680Spst if (qflag) 6317680Spst (void)printf("%s %s %d: ", 6417680Spst etheraddr_string(ESRC(ep)), 6517680Spst etheraddr_string(EDST(ep)), 6617680Spst length); 6717680Spst else 6817680Spst (void)printf("%s %s %s %d: ", 6917680Spst etheraddr_string(ESRC(ep)), 7017680Spst etheraddr_string(EDST(ep)), 7117680Spst etherproto_string(ep->ether_type), 7217680Spst length); 7317680Spst} 7417680Spst 7517680Spst/* 7617680Spst * This is the top level routine of the printer. 'p' is the points 7717680Spst * to the ether header of the packet, 'tvp' is the timestamp, 7817680Spst * 'length' is the length of the packet off the wire, and 'caplen' 7917680Spst * is the number of bytes actually captured. 8017680Spst */ 8117680Spstvoid 8217680Spstether_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) 8317680Spst{ 8417680Spst u_int caplen = h->caplen; 8517680Spst u_int length = h->len; 8617680Spst struct ether_header *ep; 8717680Spst u_short ether_type; 8817680Spst extern u_short extracted_ethertype; 8917680Spst 9017680Spst ts_print(&h->ts); 9117680Spst 9217680Spst if (caplen < sizeof(struct ether_header)) { 9317680Spst printf("[|ether]"); 9417680Spst goto out; 9517680Spst } 9617680Spst 9717680Spst if (eflag) 9817680Spst ether_print(p, length); 9917680Spst 10017680Spst /* 10117680Spst * Some printers want to get back at the ethernet addresses, 10217680Spst * and/or check that they're not walking off the end of the packet. 10317680Spst * Rather than pass them all the way down, we set these globals. 10417680Spst */ 10517680Spst packetp = p; 10617680Spst snapend = p + caplen; 10717680Spst 10817680Spst length -= sizeof(struct ether_header); 10917680Spst caplen -= sizeof(struct ether_header); 11017680Spst ep = (struct ether_header *)p; 11117680Spst p += sizeof(struct ether_header); 11217680Spst 11317680Spst ether_type = ntohs(ep->ether_type); 11417680Spst 11517680Spst /* 11617680Spst * Is it (gag) an 802.3 encapsulation? 11717680Spst */ 11817680Spst extracted_ethertype = 0; 11917680Spst if (ether_type < ETHERMTU) { 12017680Spst /* Try to print the LLC-layer header & higher layers */ 12117680Spst if (llc_print(p, length, caplen, ESRC(ep), EDST(ep)) == 0) { 12217680Spst /* ether_type not known, print raw packet */ 12317680Spst if (!eflag) 12417680Spst ether_print((u_char *)ep, length); 12517680Spst if (extracted_ethertype) { 12617680Spst printf("(LLC %s) ", 12717680Spst etherproto_string(htons(extracted_ethertype))); 12817680Spst } 12917680Spst if (!xflag && !qflag) 13017680Spst default_print(p, caplen); 13117680Spst } 13217680Spst } else if (ether_encap_print(ether_type, p, length, caplen) == 0) { 13317680Spst /* ether_type not known, print raw packet */ 13417680Spst if (!eflag) 13517680Spst ether_print((u_char *)ep, length + sizeof(*ep)); 13617680Spst if (!xflag && !qflag) 13717680Spst default_print(p, caplen); 13817680Spst } 13917680Spst if (xflag) 14017680Spst default_print(p, caplen); 14117680Spst out: 14217680Spst putchar('\n'); 14317680Spst} 14417680Spst 14517680Spst/* 14617680Spst * Prints the packet encapsulated in an Ethernet data segment 14717680Spst * (or an equivalent encapsulation), given the Ethernet type code. 14817680Spst * 14917680Spst * Returns non-zero if it can do so, zero if the ethertype is unknown. 15017680Spst * 15117680Spst * Stuffs the ether type into a global for the benefit of lower layers 15217680Spst * that might want to know what it is. 15317680Spst */ 15417680Spst 15517680Spstu_short extracted_ethertype; 15617680Spst 15717680Spstint 15817680Spstether_encap_print(u_short ethertype, const u_char *p, 15917680Spst u_int length, u_int caplen) 16017680Spst{ 16117680Spst extracted_ethertype = ethertype; 16217680Spst 16317680Spst switch (ethertype) { 16417680Spst 16517680Spst case ETHERTYPE_IP: 16617680Spst ip_print(p, length); 16717680Spst return (1); 16817680Spst 16917680Spst case ETHERTYPE_ARP: 17017680Spst case ETHERTYPE_REVARP: 17117680Spst arp_print(p, length, caplen); 17217680Spst return (1); 17317680Spst 17417680Spst case ETHERTYPE_DN: 17517680Spst decnet_print(p, length, caplen); 17617680Spst return (1); 17717680Spst 17817680Spst case ETHERTYPE_ATALK: 17917680Spst if (vflag) 18017680Spst fputs("et1 ", stdout); 18117680Spst atalk_print(p, length); 18217680Spst return (1); 18317680Spst 18417680Spst case ETHERTYPE_AARP: 18517680Spst aarp_print(p, length); 18617680Spst return (1); 18717680Spst 18817680Spst case ETHERTYPE_LAT: 18917680Spst case ETHERTYPE_SCA: 19017680Spst case ETHERTYPE_MOPRC: 19117680Spst case ETHERTYPE_MOPDL: 19217680Spst /* default_print for now */ 19317680Spst default: 19417680Spst return (0); 19517680Spst } 19617680Spst} 197