1 /* 2 * Copyright (c) 1988, 1989, 1990, 1991, 1992, 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 #ifndef lint 22 static const char rcsid[] = 23 "@(#) $Header: /tcpdump/master/tcpdump/print-sll.c,v 1.6.4.1 2002/06/01 23:51:16 guy Exp $ (LBL)"; 24 #endif 25 26 #ifdef HAVE_CONFIG_H 27 #include "config.h" 28 #endif 29 30 #include <sys/param.h> 31 #include <sys/time.h> 32 #include <sys/socket.h> 33 34 #include <netinet/in.h> 35 36 #include <stdio.h> 37 #include <string.h> 38 #include <pcap.h> 39 40 #include "interface.h" 41 #include "addrtoname.h" 42 #include "ethertype.h" 43 44 #include "ether.h" 45 #include "sll.h" 46 47 static inline void 48 sll_print(register const struct sll_header *sllp, u_int length) 49 { 50 u_short halen; 51 52 switch (ntohs(sllp->sll_pkttype)) { 53 54 case LINUX_SLL_HOST: 55 (void)printf("< "); 56 break; 57 58 case LINUX_SLL_BROADCAST: 59 (void)printf("B "); 60 break; 61 62 case LINUX_SLL_MULTICAST: 63 (void)printf("M "); 64 break; 65 66 case LINUX_SLL_OTHERHOST: 67 (void)printf("P "); 68 break; 69 70 case LINUX_SLL_OUTGOING: 71 (void)printf("> "); 72 break; 73 74 default: 75 (void)printf("? "); 76 break; 77 } 78 79 /* 80 * XXX - check the link-layer address type value? 81 * For now, we just assume 6 means Ethernet. 82 * XXX - print others as strings of hex? 83 */ 84 halen = ntohs(sllp->sll_halen); 85 if (halen == 6) 86 (void)printf("%s ", etheraddr_string(sllp->sll_addr)); 87 88 if (!qflag) 89 (void)printf("%s ", etherproto_string(sllp->sll_protocol)); 90 (void)printf("%d: ", length); 91 } 92 93 /* 94 * This is the top level routine of the printer. 'p' is the points 95 * to the ether header of the packet, 'h->tv' is the timestamp, 96 * 'h->length' is the length of the packet off the wire, and 'h->caplen' 97 * is the number of bytes actually captured. 98 */ 99 void 100 sll_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) 101 { 102 u_int caplen = h->caplen; 103 u_int length = h->len; 104 register const struct sll_header *sllp; 105 u_short pkttype; 106 struct ether_header ehdr; 107 u_short ether_type; 108 u_short extracted_ethertype; 109 110 ++infodelay; 111 ts_print(&h->ts); 112 113 if (caplen < SLL_HDR_LEN) { 114 /* 115 * XXX - this "can't happen" because "pcap-linux.c" always 116 * adds this many bytes of header to every packet in a 117 * cooked socket capture. 118 */ 119 printf("[|sll]"); 120 goto out; 121 } 122 123 sllp = (const struct sll_header *)p; 124 125 /* 126 * Fake up an Ethernet header for the benefit of printers that 127 * insist on "packetp" pointing to an Ethernet header. 128 */ 129 pkttype = ntohs(sllp->sll_pkttype); 130 131 /* The source address is in the packet header */ 132 memcpy(ehdr.ether_shost, sllp->sll_addr, ETHER_ADDR_LEN); 133 134 if (pkttype != LINUX_SLL_OUTGOING) { 135 /* 136 * We received this packet. 137 * 138 * We don't know the destination address, so 139 * we fake it - all 0's except that the 140 * bottommost bit of the bottommost octet 141 * is set for a unicast packet, all 0's except 142 * that the bottommost bit of the uppermost 143 * octet is set for a multicast packet, all 144 * 1's for a broadcast packet. 145 */ 146 if (pkttype == LINUX_SLL_BROADCAST) 147 memset(ehdr.ether_dhost, 0xFF, ETHER_ADDR_LEN); 148 else { 149 memset(ehdr.ether_dhost, 0, ETHER_ADDR_LEN); 150 if (pkttype == LINUX_SLL_MULTICAST) 151 ehdr.ether_dhost[0] = 1; 152 else 153 ehdr.ether_dhost[ETHER_ADDR_LEN-1] = 1; 154 } 155 } else { 156 /* 157 * We sent this packet; we don't know whether it's 158 * broadcast, multicast, or unicast, so just make 159 * the destination address all 0's. 160 */ 161 memset(ehdr.ether_dhost, 0, ETHER_ADDR_LEN); 162 } 163 164 if (eflag) 165 sll_print(sllp, length); 166 167 /* 168 * Some printers want to get back at the ethernet addresses, 169 * and/or check that they're not walking off the end of the packet. 170 * Rather than pass them all the way down, we set these globals. 171 */ 172 snapend = p + caplen; 173 /* 174 * Actually, the only printers that use packetp are print-arp.c 175 * and print-bootp.c, and they assume that packetp points to an 176 * Ethernet header. The right thing to do is to fix them to know 177 * which link type is in use when they excavate. XXX 178 */ 179 packetp = (u_char *)&ehdr; 180 181 length -= SLL_HDR_LEN; 182 caplen -= SLL_HDR_LEN; 183 p += SLL_HDR_LEN; 184 185 ether_type = ntohs(sllp->sll_protocol); 186 187 /* 188 * Is it (gag) an 802.3 encapsulation, or some non-Ethernet 189 * packet type? 190 */ 191 extracted_ethertype = 0; 192 if (ether_type <= ETHERMTU) { 193 /* 194 * Yes - what type is it? 195 */ 196 switch (ether_type) { 197 198 case LINUX_SLL_P_802_3: 199 /* 200 * Ethernet_802.3 IPX frame. 201 */ 202 ipx_print(p, length); 203 break; 204 205 case LINUX_SLL_P_802_2: 206 /* 207 * 802.2. 208 * Try to print the LLC-layer header & higher layers. 209 */ 210 if (llc_print(p, length, caplen, ESRC(&ehdr), 211 EDST(&ehdr), &extracted_ethertype) == 0) 212 goto unknown; /* unknown LLC type */ 213 break; 214 215 default: 216 unknown: 217 /* ether_type not known, print raw packet */ 218 if (!eflag) 219 sll_print(sllp, length + SLL_HDR_LEN); 220 if (extracted_ethertype) { 221 printf("(LLC %s) ", 222 etherproto_string(htons(extracted_ethertype))); 223 } 224 if (!xflag && !qflag) 225 default_print(p, caplen); 226 break; 227 } 228 } else if (ether_encap_print(ether_type, p, length, caplen, 229 &extracted_ethertype) == 0) { 230 /* ether_type not known, print raw packet */ 231 if (!eflag) 232 sll_print(sllp, length + SLL_HDR_LEN); 233 if (!xflag && !qflag) 234 default_print(p, caplen); 235 } 236 if (xflag) 237 default_print(p, caplen); 238 out: 239 putchar('\n'); 240 --infodelay; 241 if (infoprint) 242 info(0); 243 } 244