tcpdump  4.99.1
About: tcpdump is a tool for network monitoring and data acquisition.
  Fossies Dox: tcpdump-4.99.1.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

print-sll.c
Go to the documentation of this file.
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 
22 /* \summary: Linux cooked sockets capture printer */
23 
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27 
28 #ifdef HAVE_NET_IF_H
29 #include <net/if.h>
30 #endif
31 
32 #include "netdissect-stdinc.h"
33 
34 #define ND_LONGJMP_FROM_TCHECK
35 #include "netdissect.h"
36 #include "addrtoname.h"
37 #include "ethertype.h"
38 #include "extract.h"
39 
40 /*
41  * For captures on Linux cooked sockets, we construct a fake header
42  * that includes:
43  *
44  * a 2-byte "packet type" which is one of:
45  *
46  * LINUX_SLL_HOST packet was sent to us
47  * LINUX_SLL_BROADCAST packet was broadcast
48  * LINUX_SLL_MULTICAST packet was multicast
49  * LINUX_SLL_OTHERHOST packet was sent to somebody else
50  * LINUX_SLL_OUTGOING packet was sent *by* us;
51  *
52  * a 2-byte Ethernet protocol field;
53  *
54  * a 2-byte link-layer type;
55  *
56  * a 2-byte link-layer address length;
57  *
58  * an 8-byte source link-layer address, whose actual length is
59  * specified by the previous value.
60  *
61  * All fields except for the link-layer address are in network byte order.
62  *
63  * DO NOT change the layout of this structure, or change any of the
64  * LINUX_SLL_ values below. If you must change the link-layer header
65  * for a "cooked" Linux capture, introduce a new DLT_ type (ask
66  * "tcpdump-workers@lists.tcpdump.org" for one, so that you don't give it
67  * a value that collides with a value already being used), and use the
68  * new header in captures of that type, so that programs that can
69  * handle DLT_LINUX_SLL captures will continue to handle them correctly
70  * without any change, and so that capture files with different headers
71  * can be told apart and programs that read them can dissect the
72  * packets in them.
73  *
74  * This structure, and the #defines below, must be the same in the
75  * libpcap and tcpdump versions of "sll.h".
76  */
77 
78 /*
79  * A DLT_LINUX_SLL fake link-layer header.
80  */
81 #define SLL_HDR_LEN 16 /* total header length */
82 #define SLL_ADDRLEN 8 /* length of address field */
83 
84 struct sll_header {
85  nd_uint16_t sll_pkttype; /* packet type */
86  nd_uint16_t sll_hatype; /* link-layer address type */
87  nd_uint16_t sll_halen; /* link-layer address length */
88  nd_byte sll_addr[SLL_ADDRLEN]; /* link-layer address */
89  nd_uint16_t sll_protocol; /* protocol */
90 };
91 
92 /*
93  * A DLT_LINUX_SLL2 fake link-layer header.
94  */
95 #define SLL2_HDR_LEN 20 /* total header length */
96 
97 struct sll2_header {
98  nd_uint16_t sll2_protocol; /* protocol */
99  nd_uint16_t sll2_reserved_mbz; /* reserved - must be zero */
100  nd_uint32_t sll2_if_index; /* 1-based interface index */
101  nd_uint16_t sll2_hatype; /* link-layer address type */
102  nd_uint8_t sll2_pkttype; /* packet type */
103  nd_uint8_t sll2_halen; /* link-layer address length */
104  nd_byte sll2_addr[SLL_ADDRLEN]; /* link-layer address */
105 };
106 
107 /*
108  * The LINUX_SLL_ values for "sll_pkttype"; these correspond to the
109  * PACKET_ values on Linux, but are defined here so that they're
110  * available even on systems other than Linux, and so that they
111  * don't change even if the PACKET_ values change.
112  */
113 #define LINUX_SLL_HOST 0
114 #define LINUX_SLL_BROADCAST 1
115 #define LINUX_SLL_MULTICAST 2
116 #define LINUX_SLL_OTHERHOST 3
117 #define LINUX_SLL_OUTGOING 4
118 
119 /*
120  * The LINUX_SLL_ values for "sll_protocol"; these correspond to the
121  * ETH_P_ values on Linux, but are defined here so that they're
122  * available even on systems other than Linux. We assume, for now,
123  * that the ETH_P_ values won't change in Linux; if they do, then:
124  *
125  * if we don't translate them in "pcap-linux.c", capture files
126  * won't necessarily be readable if captured on a system that
127  * defines ETH_P_ values that don't match these values;
128  *
129  * if we do translate them in "pcap-linux.c", that makes life
130  * unpleasant for the BPF code generator, as the values you test
131  * for in the kernel aren't the values that you test for when
132  * reading a capture file, so the fixup code run on BPF programs
133  * handed to the kernel ends up having to do more work.
134  *
135  * Add other values here as necessary, for handling packet types that
136  * might show up on non-Ethernet, non-802.x networks. (Not all the ones
137  * in the Linux "if_ether.h" will, I suspect, actually show up in
138  * captures.)
139  */
140 #define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */
141 #define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */
142 
143 static const struct tok sll_pkttype_values[] = {
144  { LINUX_SLL_HOST, "In" },
145  { LINUX_SLL_BROADCAST, "B" },
146  { LINUX_SLL_MULTICAST, "M" },
147  { LINUX_SLL_OTHERHOST, "P" },
148  { LINUX_SLL_OUTGOING, "Out" },
149  { 0, NULL}
150 };
151 
152 static void
153 sll_print(netdissect_options *ndo, const struct sll_header *sllp, u_int length)
154 {
155  u_short ether_type;
156 
157  ndo->ndo_protocol = "sll";
158  ND_PRINT("%3s ",
160 
161  /*
162  * XXX - check the link-layer address type value?
163  * For now, we just assume 6 means Ethernet.
164  * XXX - print others as strings of hex?
165  */
166  if (GET_BE_U_2(sllp->sll_halen) == MAC_ADDR_LEN)
167  ND_PRINT("%s ", GET_ETHERADDR_STRING(sllp->sll_addr));
168 
169  if (!ndo->ndo_qflag) {
170  ether_type = GET_BE_U_2(sllp->sll_protocol);
171 
172  if (ether_type <= MAX_ETHERNET_LENGTH_VAL) {
173  /*
174  * Not an Ethernet type; what type is it?
175  */
176  switch (ether_type) {
177 
178  case LINUX_SLL_P_802_3:
179  /*
180  * Ethernet_802.3 IPX frame.
181  */
182  ND_PRINT("802.3");
183  break;
184 
185  case LINUX_SLL_P_802_2:
186  /*
187  * 802.2.
188  */
189  ND_PRINT("802.2");
190  break;
191 
192  default:
193  /*
194  * What is it?
195  */
196  ND_PRINT("ethertype Unknown (0x%04x)",
197  ether_type);
198  break;
199  }
200  } else {
201  ND_PRINT("ethertype %s (0x%04x)",
202  tok2str(ethertype_values, "Unknown", ether_type),
203  ether_type);
204  }
205  ND_PRINT(", length %u: ", length);
206  }
207 }
208 
209 /*
210  * This is the top level routine of the printer. 'p' points to the
211  * Linux "cooked capture" header of the packet, 'h->ts' is the timestamp,
212  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
213  * is the number of bytes actually captured.
214  */
215 void
216 sll_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
217 {
218  u_int caplen = h->caplen;
219  u_int length = h->len;
220  const struct sll_header *sllp;
221  u_short hatype;
222  u_short ether_type;
223  int llc_hdrlen;
224  u_int hdrlen;
225 
226  ndo->ndo_protocol = "sll";
228 
229  sllp = (const struct sll_header *)p;
230 
231  if (ndo->ndo_eflag)
232  sll_print(ndo, sllp, length);
233 
234  /*
235  * Go past the cooked-mode header.
236  */
237  length -= SLL_HDR_LEN;
238  caplen -= SLL_HDR_LEN;
239  p += SLL_HDR_LEN;
240  hdrlen = SLL_HDR_LEN;
241 
242  hatype = GET_BE_U_2(sllp->sll_hatype);
243  switch (hatype) {
244 
245  case 803:
246  /*
247  * This is an packet with a radiotap header;
248  * just dissect the payload as such.
249  */
250  ndo->ndo_ll_hdr_len += SLL_HDR_LEN;
251  ndo->ndo_ll_hdr_len += ieee802_11_radio_print(ndo, p, length, caplen);
252  return;
253  }
254  ether_type = GET_BE_U_2(sllp->sll_protocol);
255 
256 recurse:
257  /*
258  * Is it (gag) an 802.3 encapsulation, or some non-Ethernet
259  * packet type?
260  */
261  if (ether_type <= MAX_ETHERNET_LENGTH_VAL) {
262  /*
263  * Yes - what type is it?
264  */
265  switch (ether_type) {
266 
267  case LINUX_SLL_P_802_3:
268  /*
269  * Ethernet_802.3 IPX frame.
270  */
271  ipx_print(ndo, p, length);
272  break;
273 
274  case LINUX_SLL_P_802_2:
275  /*
276  * 802.2.
277  * Try to print the LLC-layer header & higher layers.
278  */
279  llc_hdrlen = llc_print(ndo, p, length, caplen, NULL, NULL);
280  if (llc_hdrlen < 0)
281  goto unknown; /* unknown LLC type */
282  hdrlen += llc_hdrlen;
283  break;
284 
285  default:
286  /*FALLTHROUGH*/
287 
288  unknown:
289  /* packet type not known, print raw packet */
290  if (!ndo->ndo_suppress_default_print)
291  ND_DEFAULTPRINT(p, caplen);
292  break;
293  }
294  } else if (ether_type == ETHERTYPE_8021Q) {
295  /*
296  * Print VLAN information, and then go back and process
297  * the enclosed type field.
298  */
299  if (caplen < 4) {
300  ndo->ndo_protocol = "vlan";
301  nd_print_trunc(ndo);
302  ndo->ndo_ll_hdr_len += hdrlen + caplen;
303  return;
304  }
305  if (ndo->ndo_eflag) {
306  uint16_t tag = GET_BE_U_2(p);
307 
308  ND_PRINT("%s, ", ieee8021q_tci_string(tag));
309  }
310 
311  ether_type = GET_BE_U_2(p + 2);
312  if (ether_type <= MAX_ETHERNET_LENGTH_VAL)
313  ether_type = LINUX_SLL_P_802_2;
314  if (!ndo->ndo_qflag) {
315  ND_PRINT("ethertype %s, ",
316  tok2str(ethertype_values, "Unknown", ether_type));
317  }
318  p += 4;
319  length -= 4;
320  caplen -= 4;
321  hdrlen += 4;
322  goto recurse;
323  } else {
324  if (ethertype_print(ndo, ether_type, p, length, caplen, NULL, NULL) == 0) {
325  /* ether_type not known, print raw packet */
326  if (!ndo->ndo_eflag)
327  sll_print(ndo, sllp, length + SLL_HDR_LEN);
328  if (!ndo->ndo_suppress_default_print)
329  ND_DEFAULTPRINT(p, caplen);
330  }
331  }
332 
333  ndo->ndo_ll_hdr_len += hdrlen;
334 }
335 
336 static void
337 sll2_print(netdissect_options *ndo, const struct sll2_header *sllp, u_int length)
338 {
339  u_short ether_type;
340 
341  ndo->ndo_protocol = "sll2";
342  ND_PRINT("ifindex %u ", GET_BE_U_4(sllp->sll2_if_index));
343 
344  /*
345  * XXX - check the link-layer address type value?
346  * For now, we just assume 6 means Ethernet.
347  * XXX - print others as strings of hex?
348  */
349  if (GET_U_1(sllp->sll2_halen) == MAC_ADDR_LEN)
350  ND_PRINT("%s ", GET_ETHERADDR_STRING(sllp->sll2_addr));
351 
352  if (!ndo->ndo_qflag) {
353  ether_type = GET_BE_U_2(sllp->sll2_protocol);
354 
355  if (ether_type <= MAX_ETHERNET_LENGTH_VAL) {
356  /*
357  * Not an Ethernet type; what type is it?
358  */
359  switch (ether_type) {
360 
361  case LINUX_SLL_P_802_3:
362  /*
363  * Ethernet_802.3 IPX frame.
364  */
365  ND_PRINT("802.3");
366  break;
367 
368  case LINUX_SLL_P_802_2:
369  /*
370  * 802.2.
371  */
372  ND_PRINT("802.2");
373  break;
374 
375  default:
376  /*
377  * What is it?
378  */
379  ND_PRINT("ethertype Unknown (0x%04x)",
380  ether_type);
381  break;
382  }
383  } else {
384  ND_PRINT("ethertype %s (0x%04x)",
385  tok2str(ethertype_values, "Unknown", ether_type),
386  ether_type);
387  }
388  ND_PRINT(", length %u: ", length);
389  }
390 }
391 
392 /*
393  * This is the top level routine of the printer. 'p' points to the
394  * Linux "cooked capture" header of the packet, 'h->ts' is the timestamp,
395  * 'h->len' is the length of the packet off the wire, and 'h->caplen'
396  * is the number of bytes actually captured.
397  */
398 void
399 sll2_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
400 {
401  u_int caplen = h->caplen;
402  u_int length = h->len;
403  const struct sll2_header *sllp;
404  u_short hatype;
405  u_short ether_type;
406  int llc_hdrlen;
407  u_int hdrlen;
408 #ifdef HAVE_NET_IF_H
409  uint32_t if_index;
410  char ifname[IF_NAMESIZE];
411 #endif
412 
413  ndo->ndo_protocol = "sll2";
415 
416  sllp = (const struct sll2_header *)p;
417 #ifdef HAVE_NET_IF_H
418  if_index = GET_BE_U_4(sllp->sll2_if_index);
419  if (!if_indextoname(if_index, ifname))
420  strncpy(ifname, "?", 2);
421  ND_PRINT("%-5s ", ifname);
422 #endif
423 
424  ND_PRINT("%-3s ",
426 
427  if (ndo->ndo_eflag)
428  sll2_print(ndo, sllp, length);
429 
430  /*
431  * Go past the cooked-mode header.
432  */
433  length -= SLL2_HDR_LEN;
434  caplen -= SLL2_HDR_LEN;
435  p += SLL2_HDR_LEN;
436  hdrlen = SLL2_HDR_LEN;
437 
438  hatype = GET_BE_U_2(sllp->sll2_hatype);
439  switch (hatype) {
440 
441  case 803:
442  /*
443  * This is an packet with a radiotap header;
444  * just dissect the payload as such.
445  */
447  ndo->ndo_ll_hdr_len += ieee802_11_radio_print(ndo, p, length, caplen);
448  return;
449  }
450  ether_type = GET_BE_U_2(sllp->sll2_protocol);
451 
452 recurse:
453  /*
454  * Is it (gag) an 802.3 encapsulation, or some non-Ethernet
455  * packet type?
456  */
457  if (ether_type <= MAX_ETHERNET_LENGTH_VAL) {
458  /*
459  * Yes - what type is it?
460  */
461  switch (ether_type) {
462 
463  case LINUX_SLL_P_802_3:
464  /*
465  * Ethernet_802.3 IPX frame.
466  */
467  ipx_print(ndo, p, length);
468  break;
469 
470  case LINUX_SLL_P_802_2:
471  /*
472  * 802.2.
473  * Try to print the LLC-layer header & higher layers.
474  */
475  llc_hdrlen = llc_print(ndo, p, length, caplen, NULL, NULL);
476  if (llc_hdrlen < 0)
477  goto unknown; /* unknown LLC type */
478  hdrlen += llc_hdrlen;
479  break;
480 
481  default:
482  /*FALLTHROUGH*/
483 
484  unknown:
485  /* packet type not known, print raw packet */
486  if (!ndo->ndo_suppress_default_print)
487  ND_DEFAULTPRINT(p, caplen);
488  break;
489  }
490  } else if (ether_type == ETHERTYPE_8021Q) {
491  /*
492  * Print VLAN information, and then go back and process
493  * the enclosed type field.
494  */
495  if (caplen < 4) {
496  ndo->ndo_protocol = "vlan";
497  nd_print_trunc(ndo);
498  ndo->ndo_ll_hdr_len += hdrlen + caplen;
499  return;
500  }
501  if (ndo->ndo_eflag) {
502  uint16_t tag = GET_BE_U_2(p);
503 
504  ND_PRINT("%s, ", ieee8021q_tci_string(tag));
505  }
506 
507  ether_type = GET_BE_U_2(p + 2);
508  if (ether_type <= MAX_ETHERNET_LENGTH_VAL)
509  ether_type = LINUX_SLL_P_802_2;
510  if (!ndo->ndo_qflag) {
511  ND_PRINT("ethertype %s, ",
512  tok2str(ethertype_values, "Unknown", ether_type));
513  }
514  p += 4;
515  length -= 4;
516  caplen -= 4;
517  hdrlen += 4;
518  goto recurse;
519  } else {
520  if (ethertype_print(ndo, ether_type, p, length, caplen, NULL, NULL) == 0) {
521  /* ether_type not known, print raw packet */
522  if (!ndo->ndo_eflag)
523  sll2_print(ndo, sllp, length + SLL2_HDR_LEN);
524  if (!ndo->ndo_suppress_default_print)
525  ND_DEFAULTPRINT(p, caplen);
526  }
527  }
528 
529  ndo->ndo_ll_hdr_len += hdrlen;
530 }
const char * ieee8021q_tci_string(const uint16_t tci)
Definition: addrtoname.c:1325
#define GET_ETHERADDR_STRING(p)
Definition: addrtoname.h:117
#define MAX_ETHERNET_LENGTH_VAL
Definition: ethertype.h:27
#define ETHERTYPE_8021Q
Definition: ethertype.h:112
const struct tok ethertype_values[]
Definition: print-ether.c:52
#define GET_BE_U_4(p)
Definition: extract.h:877
#define GET_BE_U_2(p)
Definition: extract.h:875
#define GET_U_1(p)
Definition: extract.h:872
unsigned char nd_uint16_t[2]
Definition: netdissect.h:47
#define ND_TCHECK_LEN(p, l)
Definition: netdissect.h:368
const char * tok2str(const struct tok *, const char *, u_int)
Definition: util-print.c:485
int ethertype_print(netdissect_options *, u_short, const u_char *, u_int, u_int, const struct lladdr_info *, const struct lladdr_info *)
Definition: print-ether.c:522
#define MAC_ADDR_LEN
Definition: netdissect.h:102
#define ND_DEFAULTPRINT(ap, length)
Definition: netdissect.h:386
unsigned char nd_byte
Definition: netdissect.h:108
int llc_print(netdissect_options *, const u_char *, u_int, u_int, const struct lladdr_info *, const struct lladdr_info *)
Definition: print-llc.c:150
u_int ieee802_11_radio_print(netdissect_options *, const u_char *, u_int, u_int)
void nd_print_trunc(netdissect_options *)
Definition: util-print.c:409
#define ND_PRINT(...)
Definition: netdissect.h:385
void ipx_print(netdissect_options *, const u_char *, u_int)
Definition: print-ipx.c:73
unsigned char nd_uint32_t[4]
Definition: netdissect.h:49
unsigned char nd_uint8_t[1]
Definition: netdissect.h:46
static void sll_print(netdissect_options *ndo, const struct sll_header *sllp, u_int length)
Definition: print-sll.c:153
#define LINUX_SLL_P_802_3
Definition: print-sll.c:140
#define SLL2_HDR_LEN
Definition: print-sll.c:95
static const struct tok sll_pkttype_values[]
Definition: print-sll.c:143
#define LINUX_SLL_OTHERHOST
Definition: print-sll.c:116
#define SLL_ADDRLEN
Definition: print-sll.c:82
#define LINUX_SLL_MULTICAST
Definition: print-sll.c:115
#define LINUX_SLL_OUTGOING
Definition: print-sll.c:117
void sll_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
Definition: print-sll.c:216
#define LINUX_SLL_BROADCAST
Definition: print-sll.c:114
static void sll2_print(netdissect_options *ndo, const struct sll2_header *sllp, u_int length)
Definition: print-sll.c:337
#define SLL_HDR_LEN
Definition: print-sll.c:81
#define LINUX_SLL_P_802_2
Definition: print-sll.c:141
#define LINUX_SLL_HOST
Definition: print-sll.c:113
void sll2_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, const u_char *p)
Definition: print-sll.c:399
int ndo_suppress_default_print
Definition: netdissect.h:222
const char * ndo_protocol
Definition: netdissect.h:218
nd_uint16_t sll2_hatype
Definition: print-sll.c:101
nd_uint16_t sll2_reserved_mbz
Definition: print-sll.c:99
nd_uint8_t sll2_pkttype
Definition: print-sll.c:102
nd_uint32_t sll2_if_index
Definition: print-sll.c:100
nd_uint8_t sll2_halen
Definition: print-sll.c:103
nd_uint16_t sll2_protocol
Definition: print-sll.c:98
nd_byte sll2_addr[8]
Definition: print-sll.c:104
nd_uint16_t sll_hatype
Definition: print-sll.c:86
nd_uint16_t sll_protocol
Definition: print-sll.c:89
nd_byte sll_addr[8]
Definition: print-sll.c:88
nd_uint16_t sll_halen
Definition: print-sll.c:87
nd_uint16_t sll_pkttype
Definition: print-sll.c:85