print-sll.c revision 1.7 1 1.1 christos /*
2 1.1 christos * Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
3 1.1 christos * The Regents of the University of California. All rights reserved.
4 1.1 christos *
5 1.1 christos * Redistribution and use in source and binary forms, with or without
6 1.1 christos * modification, are permitted provided that: (1) source code distributions
7 1.1 christos * retain the above copyright notice and this paragraph in its entirety, (2)
8 1.1 christos * distributions including binary code include the above copyright notice and
9 1.1 christos * this paragraph in its entirety in the documentation or other materials
10 1.1 christos * provided with the distribution, and (3) all advertising materials mentioning
11 1.1 christos * features or use of this software display the following acknowledgement:
12 1.1 christos * ``This product includes software developed by the University of California,
13 1.1 christos * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
14 1.1 christos * the University nor the names of its contributors may be used to endorse
15 1.1 christos * or promote products derived from this software without specific prior
16 1.1 christos * written permission.
17 1.1 christos * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
18 1.1 christos * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
19 1.1 christos * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
20 1.1 christos */
21 1.5 christos
22 1.2 christos #include <sys/cdefs.h>
23 1.1 christos #ifndef lint
24 1.7 christos __RCSID("$NetBSD: print-sll.c,v 1.7 2017/01/24 23:29:14 christos Exp $");
25 1.1 christos #endif
26 1.1 christos
27 1.1 christos #ifdef HAVE_CONFIG_H
28 1.1 christos #include "config.h"
29 1.1 christos #endif
30 1.1 christos
31 1.7 christos #include <netdissect-stdinc.h>
32 1.1 christos
33 1.7 christos #include "netdissect.h"
34 1.1 christos #include "addrtoname.h"
35 1.1 christos #include "ethertype.h"
36 1.1 christos #include "extract.h"
37 1.1 christos
38 1.1 christos #include "ether.h"
39 1.5 christos
40 1.5 christos /*
41 1.5 christos * For captures on Linux cooked sockets, we construct a fake header
42 1.5 christos * that includes:
43 1.5 christos *
44 1.5 christos * a 2-byte "packet type" which is one of:
45 1.5 christos *
46 1.5 christos * LINUX_SLL_HOST packet was sent to us
47 1.5 christos * LINUX_SLL_BROADCAST packet was broadcast
48 1.5 christos * LINUX_SLL_MULTICAST packet was multicast
49 1.5 christos * LINUX_SLL_OTHERHOST packet was sent to somebody else
50 1.5 christos * LINUX_SLL_OUTGOING packet was sent *by* us;
51 1.5 christos *
52 1.5 christos * a 2-byte Ethernet protocol field;
53 1.5 christos *
54 1.5 christos * a 2-byte link-layer type;
55 1.5 christos *
56 1.5 christos * a 2-byte link-layer address length;
57 1.5 christos *
58 1.5 christos * an 8-byte source link-layer address, whose actual length is
59 1.5 christos * specified by the previous value.
60 1.5 christos *
61 1.5 christos * All fields except for the link-layer address are in network byte order.
62 1.5 christos *
63 1.5 christos * DO NOT change the layout of this structure, or change any of the
64 1.5 christos * LINUX_SLL_ values below. If you must change the link-layer header
65 1.5 christos * for a "cooked" Linux capture, introduce a new DLT_ type (ask
66 1.5 christos * "tcpdump-workers (at) lists.tcpdump.org" for one, so that you don't give it
67 1.5 christos * a value that collides with a value already being used), and use the
68 1.5 christos * new header in captures of that type, so that programs that can
69 1.5 christos * handle DLT_LINUX_SLL captures will continue to handle them correctly
70 1.5 christos * without any change, and so that capture files with different headers
71 1.5 christos * can be told apart and programs that read them can dissect the
72 1.5 christos * packets in them.
73 1.5 christos *
74 1.5 christos * This structure, and the #defines below, must be the same in the
75 1.5 christos * libpcap and tcpdump versions of "sll.h".
76 1.5 christos */
77 1.5 christos
78 1.5 christos /*
79 1.5 christos * A DLT_LINUX_SLL fake link-layer header.
80 1.5 christos */
81 1.5 christos #define SLL_HDR_LEN 16 /* total header length */
82 1.5 christos #define SLL_ADDRLEN 8 /* length of address field */
83 1.5 christos
84 1.5 christos struct sll_header {
85 1.5 christos uint16_t sll_pkttype; /* packet type */
86 1.5 christos uint16_t sll_hatype; /* link-layer address type */
87 1.5 christos uint16_t sll_halen; /* link-layer address length */
88 1.5 christos uint8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
89 1.5 christos uint16_t sll_protocol; /* protocol */
90 1.5 christos };
91 1.5 christos
92 1.5 christos /*
93 1.5 christos * The LINUX_SLL_ values for "sll_pkttype"; these correspond to the
94 1.5 christos * PACKET_ values on Linux, but are defined here so that they're
95 1.5 christos * available even on systems other than Linux, and so that they
96 1.5 christos * don't change even if the PACKET_ values change.
97 1.5 christos */
98 1.5 christos #define LINUX_SLL_HOST 0
99 1.5 christos #define LINUX_SLL_BROADCAST 1
100 1.5 christos #define LINUX_SLL_MULTICAST 2
101 1.5 christos #define LINUX_SLL_OTHERHOST 3
102 1.5 christos #define LINUX_SLL_OUTGOING 4
103 1.5 christos
104 1.5 christos /*
105 1.5 christos * The LINUX_SLL_ values for "sll_protocol"; these correspond to the
106 1.5 christos * ETH_P_ values on Linux, but are defined here so that they're
107 1.5 christos * available even on systems other than Linux. We assume, for now,
108 1.5 christos * that the ETH_P_ values won't change in Linux; if they do, then:
109 1.5 christos *
110 1.5 christos * if we don't translate them in "pcap-linux.c", capture files
111 1.5 christos * won't necessarily be readable if captured on a system that
112 1.5 christos * defines ETH_P_ values that don't match these values;
113 1.5 christos *
114 1.5 christos * if we do translate them in "pcap-linux.c", that makes life
115 1.5 christos * unpleasant for the BPF code generator, as the values you test
116 1.5 christos * for in the kernel aren't the values that you test for when
117 1.5 christos * reading a capture file, so the fixup code run on BPF programs
118 1.5 christos * handed to the kernel ends up having to do more work.
119 1.5 christos *
120 1.5 christos * Add other values here as necessary, for handling packet types that
121 1.5 christos * might show up on non-Ethernet, non-802.x networks. (Not all the ones
122 1.5 christos * in the Linux "if_ether.h" will, I suspect, actually show up in
123 1.5 christos * captures.)
124 1.5 christos */
125 1.5 christos #define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */
126 1.5 christos #define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */
127 1.1 christos
128 1.4 christos static const struct tok sll_pkttype_values[] = {
129 1.1 christos { LINUX_SLL_HOST, "In" },
130 1.1 christos { LINUX_SLL_BROADCAST, "B" },
131 1.1 christos { LINUX_SLL_MULTICAST, "M" },
132 1.1 christos { LINUX_SLL_OTHERHOST, "P" },
133 1.1 christos { LINUX_SLL_OUTGOING, "Out" },
134 1.1 christos { 0, NULL}
135 1.1 christos };
136 1.1 christos
137 1.1 christos static inline void
138 1.5 christos sll_print(netdissect_options *ndo, register const struct sll_header *sllp, u_int length)
139 1.1 christos {
140 1.1 christos u_short ether_type;
141 1.1 christos
142 1.5 christos ND_PRINT((ndo, "%3s ",tok2str(sll_pkttype_values,"?",EXTRACT_16BITS(&sllp->sll_pkttype))));
143 1.1 christos
144 1.1 christos /*
145 1.1 christos * XXX - check the link-layer address type value?
146 1.1 christos * For now, we just assume 6 means Ethernet.
147 1.1 christos * XXX - print others as strings of hex?
148 1.1 christos */
149 1.1 christos if (EXTRACT_16BITS(&sllp->sll_halen) == 6)
150 1.5 christos ND_PRINT((ndo, "%s ", etheraddr_string(ndo, sllp->sll_addr)));
151 1.1 christos
152 1.5 christos if (!ndo->ndo_qflag) {
153 1.1 christos ether_type = EXTRACT_16BITS(&sllp->sll_protocol);
154 1.5 christos
155 1.1 christos if (ether_type <= ETHERMTU) {
156 1.1 christos /*
157 1.1 christos * Not an Ethernet type; what type is it?
158 1.1 christos */
159 1.1 christos switch (ether_type) {
160 1.1 christos
161 1.1 christos case LINUX_SLL_P_802_3:
162 1.1 christos /*
163 1.1 christos * Ethernet_802.3 IPX frame.
164 1.1 christos */
165 1.5 christos ND_PRINT((ndo, "802.3"));
166 1.1 christos break;
167 1.1 christos
168 1.1 christos case LINUX_SLL_P_802_2:
169 1.1 christos /*
170 1.1 christos * 802.2.
171 1.1 christos */
172 1.5 christos ND_PRINT((ndo, "802.2"));
173 1.1 christos break;
174 1.1 christos
175 1.1 christos default:
176 1.1 christos /*
177 1.1 christos * What is it?
178 1.1 christos */
179 1.5 christos ND_PRINT((ndo, "ethertype Unknown (0x%04x)",
180 1.5 christos ether_type));
181 1.1 christos break;
182 1.1 christos }
183 1.1 christos } else {
184 1.5 christos ND_PRINT((ndo, "ethertype %s (0x%04x)",
185 1.1 christos tok2str(ethertype_values, "Unknown", ether_type),
186 1.5 christos ether_type));
187 1.1 christos }
188 1.5 christos ND_PRINT((ndo, ", length %u: ", length));
189 1.1 christos }
190 1.1 christos }
191 1.1 christos
192 1.1 christos /*
193 1.1 christos * This is the top level routine of the printer. 'p' points to the
194 1.1 christos * Linux "cooked capture" header of the packet, 'h->ts' is the timestamp,
195 1.1 christos * 'h->len' is the length of the packet off the wire, and 'h->caplen'
196 1.1 christos * is the number of bytes actually captured.
197 1.1 christos */
198 1.1 christos u_int
199 1.5 christos sll_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
200 1.1 christos {
201 1.1 christos u_int caplen = h->caplen;
202 1.1 christos u_int length = h->len;
203 1.1 christos register const struct sll_header *sllp;
204 1.1 christos u_short ether_type;
205 1.7 christos int llc_hdrlen;
206 1.7 christos u_int hdrlen;
207 1.1 christos
208 1.1 christos if (caplen < SLL_HDR_LEN) {
209 1.1 christos /*
210 1.1 christos * XXX - this "can't happen" because "pcap-linux.c" always
211 1.1 christos * adds this many bytes of header to every packet in a
212 1.1 christos * cooked socket capture.
213 1.1 christos */
214 1.5 christos ND_PRINT((ndo, "[|sll]"));
215 1.1 christos return (caplen);
216 1.1 christos }
217 1.1 christos
218 1.1 christos sllp = (const struct sll_header *)p;
219 1.1 christos
220 1.5 christos if (ndo->ndo_eflag)
221 1.5 christos sll_print(ndo, sllp, length);
222 1.1 christos
223 1.1 christos /*
224 1.1 christos * Go past the cooked-mode header.
225 1.1 christos */
226 1.1 christos length -= SLL_HDR_LEN;
227 1.1 christos caplen -= SLL_HDR_LEN;
228 1.1 christos p += SLL_HDR_LEN;
229 1.7 christos hdrlen = SLL_HDR_LEN;
230 1.1 christos
231 1.1 christos ether_type = EXTRACT_16BITS(&sllp->sll_protocol);
232 1.1 christos
233 1.1 christos recurse:
234 1.1 christos /*
235 1.1 christos * Is it (gag) an 802.3 encapsulation, or some non-Ethernet
236 1.1 christos * packet type?
237 1.1 christos */
238 1.1 christos if (ether_type <= ETHERMTU) {
239 1.1 christos /*
240 1.1 christos * Yes - what type is it?
241 1.1 christos */
242 1.1 christos switch (ether_type) {
243 1.1 christos
244 1.1 christos case LINUX_SLL_P_802_3:
245 1.1 christos /*
246 1.1 christos * Ethernet_802.3 IPX frame.
247 1.1 christos */
248 1.5 christos ipx_print(ndo, p, length);
249 1.1 christos break;
250 1.1 christos
251 1.1 christos case LINUX_SLL_P_802_2:
252 1.1 christos /*
253 1.1 christos * 802.2.
254 1.1 christos * Try to print the LLC-layer header & higher layers.
255 1.1 christos */
256 1.7 christos llc_hdrlen = llc_print(ndo, p, length, caplen, NULL, NULL);
257 1.7 christos if (llc_hdrlen < 0)
258 1.1 christos goto unknown; /* unknown LLC type */
259 1.7 christos hdrlen += llc_hdrlen;
260 1.1 christos break;
261 1.1 christos
262 1.1 christos default:
263 1.1 christos /*FALLTHROUGH*/
264 1.1 christos
265 1.1 christos unknown:
266 1.7 christos /* packet type not known, print raw packet */
267 1.5 christos if (!ndo->ndo_suppress_default_print)
268 1.5 christos ND_DEFAULTPRINT(p, caplen);
269 1.1 christos break;
270 1.1 christos }
271 1.1 christos } else if (ether_type == ETHERTYPE_8021Q) {
272 1.1 christos /*
273 1.1 christos * Print VLAN information, and then go back and process
274 1.1 christos * the enclosed type field.
275 1.1 christos */
276 1.7 christos if (caplen < 4) {
277 1.7 christos ND_PRINT((ndo, "[|vlan]"));
278 1.7 christos return (hdrlen + caplen);
279 1.7 christos }
280 1.7 christos if (length < 4) {
281 1.5 christos ND_PRINT((ndo, "[|vlan]"));
282 1.7 christos return (hdrlen + length);
283 1.1 christos }
284 1.5 christos if (ndo->ndo_eflag) {
285 1.5 christos uint16_t tag = EXTRACT_16BITS(p);
286 1.1 christos
287 1.6 christos ND_PRINT((ndo, "%s, ", ieee8021q_tci_string(tag)));
288 1.1 christos }
289 1.1 christos
290 1.1 christos ether_type = EXTRACT_16BITS(p + 2);
291 1.1 christos if (ether_type <= ETHERMTU)
292 1.1 christos ether_type = LINUX_SLL_P_802_2;
293 1.5 christos if (!ndo->ndo_qflag) {
294 1.5 christos ND_PRINT((ndo, "ethertype %s, ",
295 1.5 christos tok2str(ethertype_values, "Unknown", ether_type)));
296 1.1 christos }
297 1.1 christos p += 4;
298 1.1 christos length -= 4;
299 1.1 christos caplen -= 4;
300 1.7 christos hdrlen += 4;
301 1.1 christos goto recurse;
302 1.1 christos } else {
303 1.5 christos if (ethertype_print(ndo, ether_type, p, length, caplen) == 0) {
304 1.1 christos /* ether_type not known, print raw packet */
305 1.5 christos if (!ndo->ndo_eflag)
306 1.5 christos sll_print(ndo, sllp, length + SLL_HDR_LEN);
307 1.5 christos if (!ndo->ndo_suppress_default_print)
308 1.5 christos ND_DEFAULTPRINT(p, caplen);
309 1.1 christos }
310 1.1 christos }
311 1.1 christos
312 1.7 christos return (hdrlen);
313 1.1 christos }
314