2000-12-21 18:43:19 +08:00
|
|
|
/*
|
|
|
|
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
|
|
|
|
* The Regents of the University of California. All rights reserved.
|
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that: (1) source code distributions
|
|
|
|
* retain the above copyright notice and this paragraph in its entirety, (2)
|
|
|
|
* distributions including binary code include the above copyright notice and
|
|
|
|
* this paragraph in its entirety in the documentation or other materials
|
|
|
|
* provided with the distribution, and (3) all advertising materials mentioning
|
|
|
|
* features or use of this software display the following acknowledgement:
|
|
|
|
* ``This product includes software developed by the University of California,
|
|
|
|
* Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
|
|
|
|
* the University nor the names of its contributors may be used to endorse
|
|
|
|
* or promote products derived from this software without specific prior
|
|
|
|
* written permission.
|
|
|
|
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
|
|
|
|
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
|
|
|
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
*/
|
2003-11-16 17:36:07 +08:00
|
|
|
#ifndef lint
|
|
|
|
static const char rcsid[] _U_ =
|
2005-11-13 20:12:41 +08:00
|
|
|
"@(#) $Header: /tcpdump/master/tcpdump/print-sll.c,v 1.19 2005-11-13 12:12:43 guy Exp $ (LBL)";
|
2003-11-16 17:36:07 +08:00
|
|
|
#endif
|
2000-12-21 18:43:19 +08:00
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
#include "config.h"
|
|
|
|
#endif
|
|
|
|
|
2002-08-01 16:52:55 +08:00
|
|
|
#include <tcpdump-stdinc.h>
|
2000-12-21 18:43:19 +08:00
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <pcap.h>
|
|
|
|
|
|
|
|
#include "interface.h"
|
|
|
|
#include "addrtoname.h"
|
|
|
|
#include "ethertype.h"
|
2004-10-28 08:34:29 +08:00
|
|
|
#include "extract.h"
|
2000-12-21 18:43:19 +08:00
|
|
|
|
|
|
|
#include "ether.h"
|
|
|
|
#include "sll.h"
|
|
|
|
|
2004-10-28 08:34:29 +08:00
|
|
|
const struct tok sll_pkttype_values[] = {
|
|
|
|
{ LINUX_SLL_HOST, "In" },
|
|
|
|
{ LINUX_SLL_BROADCAST, "B" },
|
|
|
|
{ LINUX_SLL_MULTICAST, "M" },
|
|
|
|
{ LINUX_SLL_OTHERHOST, "P" },
|
|
|
|
{ LINUX_SLL_OUTGOING, "Out" },
|
|
|
|
{ 0, NULL}
|
|
|
|
};
|
|
|
|
|
2000-12-21 18:43:19 +08:00
|
|
|
static inline void
|
2000-12-24 04:49:34 +08:00
|
|
|
sll_print(register const struct sll_header *sllp, u_int length)
|
2000-12-21 18:43:19 +08:00
|
|
|
{
|
2005-04-26 08:16:28 +08:00
|
|
|
u_short ether_type;
|
|
|
|
|
2004-10-28 08:34:29 +08:00
|
|
|
printf("%3s ",tok2str(sll_pkttype_values,"?",EXTRACT_16BITS(&sllp->sll_pkttype)));
|
2000-12-21 18:43:19 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* XXX - check the link-layer address type value?
|
|
|
|
* For now, we just assume 6 means Ethernet.
|
|
|
|
* XXX - print others as strings of hex?
|
|
|
|
*/
|
2004-10-28 08:34:29 +08:00
|
|
|
if (EXTRACT_16BITS(&sllp->sll_halen) == 6)
|
2000-12-21 18:43:19 +08:00
|
|
|
(void)printf("%s ", etheraddr_string(sllp->sll_addr));
|
|
|
|
|
2005-04-26 08:16:28 +08:00
|
|
|
if (!qflag) {
|
|
|
|
ether_type = EXTRACT_16BITS(&sllp->sll_protocol);
|
|
|
|
|
|
|
|
if (ether_type <= ETHERMTU) {
|
|
|
|
/*
|
|
|
|
* Not an Ethernet type; what type is it?
|
|
|
|
*/
|
|
|
|
switch (ether_type) {
|
|
|
|
|
|
|
|
case LINUX_SLL_P_802_3:
|
|
|
|
/*
|
|
|
|
* Ethernet_802.3 IPX frame.
|
|
|
|
*/
|
|
|
|
(void)printf("802.3");
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LINUX_SLL_P_802_2:
|
|
|
|
/*
|
|
|
|
* 802.2.
|
|
|
|
*/
|
|
|
|
(void)printf("802.3");
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
/*
|
|
|
|
* What is it?
|
|
|
|
*/
|
|
|
|
(void)printf("ethertype Unknown (0x%04x)",
|
|
|
|
ether_type);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
(void)printf("ethertype %s (0x%04x)",
|
|
|
|
tok2str(ethertype_values, "Unknown", ether_type),
|
|
|
|
ether_type);
|
|
|
|
}
|
|
|
|
(void)printf(", length %u: ", length);
|
|
|
|
}
|
2000-12-21 18:43:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2002-09-06 05:25:34 +08:00
|
|
|
* This is the top level routine of the printer. 'p' points to the
|
|
|
|
* Linux "cooked capture" header of the packet, 'h->ts' is the timestamp,
|
2004-03-18 07:24:35 +08:00
|
|
|
* 'h->len' is the length of the packet off the wire, and 'h->caplen'
|
2000-12-21 18:43:19 +08:00
|
|
|
* is the number of bytes actually captured.
|
|
|
|
*/
|
2002-12-19 17:39:10 +08:00
|
|
|
u_int
|
|
|
|
sll_if_print(const struct pcap_pkthdr *h, const u_char *p)
|
2000-12-21 18:43:19 +08:00
|
|
|
{
|
|
|
|
u_int caplen = h->caplen;
|
|
|
|
u_int length = h->len;
|
|
|
|
register const struct sll_header *sllp;
|
|
|
|
u_short ether_type;
|
|
|
|
u_short extracted_ethertype;
|
|
|
|
|
|
|
|
if (caplen < SLL_HDR_LEN) {
|
|
|
|
/*
|
|
|
|
* XXX - this "can't happen" because "pcap-linux.c" always
|
|
|
|
* adds this many bytes of header to every packet in a
|
|
|
|
* cooked socket capture.
|
|
|
|
*/
|
|
|
|
printf("[|sll]");
|
2002-12-19 17:39:10 +08:00
|
|
|
return (caplen);
|
2000-12-21 18:43:19 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
sllp = (const struct sll_header *)p;
|
|
|
|
|
|
|
|
if (eflag)
|
2000-12-24 04:49:34 +08:00
|
|
|
sll_print(sllp, length);
|
2000-12-21 18:43:19 +08:00
|
|
|
|
Add a new routine "default_print_packet()", which takes a pointer to the
beginning of the raw packet data, the captured length of the raw packet
data, and the length of the link-layer header, and:
if "-e" was specified, prints all the raw packet data;
if "-e" was not specified, prints all the raw packet data past
the link-layer header, if there is any.
Use that routine in all the "xxx_if_print()" routines if "-x" was
specified.
Make "arcnet_encap_print()" static - it's not used outside
"print-arcnet.c".
Add missing info printing code to "atm_if_print()".
Print the packet data in "lane_if_print()", not in "lane_print()", as
"lane_print()" can be called from other "xxx_if_print()" routines, and
those routines will also print the packet data if "-x" was specified -
no need to print it twice.
2002-12-18 17:41:13 +08:00
|
|
|
/*
|
|
|
|
* Go past the cooked-mode header.
|
|
|
|
*/
|
2000-12-21 18:43:19 +08:00
|
|
|
length -= SLL_HDR_LEN;
|
|
|
|
caplen -= SLL_HDR_LEN;
|
|
|
|
p += SLL_HDR_LEN;
|
|
|
|
|
|
|
|
ether_type = ntohs(sllp->sll_protocol);
|
|
|
|
|
|
|
|
/*
|
Put the LINUX_SLL_P_ definitions back, and check for at least some of
them in "print-sll.c" - as a cooked-mode capture may be reading from
non-Ethernet, non-802.x devices, it may well see some
ETH_P_/LINUX_SLL_P_ types that don't mean "this is an 802.2 LLC frame".
We currently assume that the ETH_P_ values won't change in the kernel,
so we don't have to explicitly map them.
In various link-layer packet printers, if we don't handle the next layer
up of packet type, and are printing the link-layer header, use the
correct pointer to that header (i.e., if we've stepped "p" past the
link-layer header, don't use "p", use a pointer to the beginning of the
packet), and use the correct length (i.e., if we've subtracted the
length of the link-layer header, add it back in, so that we always print
the full packet length).
2000-12-23 06:45:09 +08:00
|
|
|
* Is it (gag) an 802.3 encapsulation, or some non-Ethernet
|
|
|
|
* packet type?
|
2000-12-21 18:43:19 +08:00
|
|
|
*/
|
|
|
|
if (ether_type <= ETHERMTU) {
|
Put the LINUX_SLL_P_ definitions back, and check for at least some of
them in "print-sll.c" - as a cooked-mode capture may be reading from
non-Ethernet, non-802.x devices, it may well see some
ETH_P_/LINUX_SLL_P_ types that don't mean "this is an 802.2 LLC frame".
We currently assume that the ETH_P_ values won't change in the kernel,
so we don't have to explicitly map them.
In various link-layer packet printers, if we don't handle the next layer
up of packet type, and are printing the link-layer header, use the
correct pointer to that header (i.e., if we've stepped "p" past the
link-layer header, don't use "p", use a pointer to the beginning of the
packet), and use the correct length (i.e., if we've subtracted the
length of the link-layer header, add it back in, so that we always print
the full packet length).
2000-12-23 06:45:09 +08:00
|
|
|
/*
|
|
|
|
* Yes - what type is it?
|
|
|
|
*/
|
|
|
|
switch (ether_type) {
|
|
|
|
|
2001-01-15 08:33:59 +08:00
|
|
|
case LINUX_SLL_P_802_3:
|
|
|
|
/*
|
|
|
|
* Ethernet_802.3 IPX frame.
|
|
|
|
*/
|
|
|
|
ipx_print(p, length);
|
|
|
|
break;
|
|
|
|
|
Put the LINUX_SLL_P_ definitions back, and check for at least some of
them in "print-sll.c" - as a cooked-mode capture may be reading from
non-Ethernet, non-802.x devices, it may well see some
ETH_P_/LINUX_SLL_P_ types that don't mean "this is an 802.2 LLC frame".
We currently assume that the ETH_P_ values won't change in the kernel,
so we don't have to explicitly map them.
In various link-layer packet printers, if we don't handle the next layer
up of packet type, and are printing the link-layer header, use the
correct pointer to that header (i.e., if we've stepped "p" past the
link-layer header, don't use "p", use a pointer to the beginning of the
packet), and use the correct length (i.e., if we've subtracted the
length of the link-layer header, add it back in, so that we always print
the full packet length).
2000-12-23 06:45:09 +08:00
|
|
|
case LINUX_SLL_P_802_2:
|
|
|
|
/*
|
|
|
|
* 802.2.
|
|
|
|
* Try to print the LLC-layer header & higher layers.
|
|
|
|
*/
|
2002-12-18 16:53:18 +08:00
|
|
|
if (llc_print(p, length, caplen, NULL, NULL,
|
|
|
|
&extracted_ethertype) == 0)
|
Put the LINUX_SLL_P_ definitions back, and check for at least some of
them in "print-sll.c" - as a cooked-mode capture may be reading from
non-Ethernet, non-802.x devices, it may well see some
ETH_P_/LINUX_SLL_P_ types that don't mean "this is an 802.2 LLC frame".
We currently assume that the ETH_P_ values won't change in the kernel,
so we don't have to explicitly map them.
In various link-layer packet printers, if we don't handle the next layer
up of packet type, and are printing the link-layer header, use the
correct pointer to that header (i.e., if we've stepped "p" past the
link-layer header, don't use "p", use a pointer to the beginning of the
packet), and use the correct length (i.e., if we've subtracted the
length of the link-layer header, add it back in, so that we always print
the full packet length).
2000-12-23 06:45:09 +08:00
|
|
|
goto unknown; /* unknown LLC type */
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2005-11-13 20:12:41 +08:00
|
|
|
extracted_ethertype = 0;
|
|
|
|
/*FALLTHROUGH*/
|
|
|
|
|
Put the LINUX_SLL_P_ definitions back, and check for at least some of
them in "print-sll.c" - as a cooked-mode capture may be reading from
non-Ethernet, non-802.x devices, it may well see some
ETH_P_/LINUX_SLL_P_ types that don't mean "this is an 802.2 LLC frame".
We currently assume that the ETH_P_ values won't change in the kernel,
so we don't have to explicitly map them.
In various link-layer packet printers, if we don't handle the next layer
up of packet type, and are printing the link-layer header, use the
correct pointer to that header (i.e., if we've stepped "p" past the
link-layer header, don't use "p", use a pointer to the beginning of the
packet), and use the correct length (i.e., if we've subtracted the
length of the link-layer header, add it back in, so that we always print
the full packet length).
2000-12-23 06:45:09 +08:00
|
|
|
unknown:
|
2000-12-21 18:43:19 +08:00
|
|
|
/* ether_type not known, print raw packet */
|
|
|
|
if (!eflag)
|
2000-12-24 04:49:34 +08:00
|
|
|
sll_print(sllp, length + SLL_HDR_LEN);
|
2000-12-21 18:43:19 +08:00
|
|
|
if (extracted_ethertype) {
|
|
|
|
printf("(LLC %s) ",
|
|
|
|
etherproto_string(htons(extracted_ethertype)));
|
|
|
|
}
|
2005-07-07 09:22:15 +08:00
|
|
|
if (!suppress_default_print)
|
2000-12-21 18:43:19 +08:00
|
|
|
default_print(p, caplen);
|
Put the LINUX_SLL_P_ definitions back, and check for at least some of
them in "print-sll.c" - as a cooked-mode capture may be reading from
non-Ethernet, non-802.x devices, it may well see some
ETH_P_/LINUX_SLL_P_ types that don't mean "this is an 802.2 LLC frame".
We currently assume that the ETH_P_ values won't change in the kernel,
so we don't have to explicitly map them.
In various link-layer packet printers, if we don't handle the next layer
up of packet type, and are printing the link-layer header, use the
correct pointer to that header (i.e., if we've stepped "p" past the
link-layer header, don't use "p", use a pointer to the beginning of the
packet), and use the correct length (i.e., if we've subtracted the
length of the link-layer header, add it back in, so that we always print
the full packet length).
2000-12-23 06:45:09 +08:00
|
|
|
break;
|
2000-12-21 18:43:19 +08:00
|
|
|
}
|
|
|
|
} else if (ether_encap_print(ether_type, p, length, caplen,
|
|
|
|
&extracted_ethertype) == 0) {
|
|
|
|
/* ether_type not known, print raw packet */
|
|
|
|
if (!eflag)
|
2000-12-24 04:49:34 +08:00
|
|
|
sll_print(sllp, length + SLL_HDR_LEN);
|
2005-07-07 09:22:15 +08:00
|
|
|
if (!suppress_default_print)
|
2000-12-21 18:43:19 +08:00
|
|
|
default_print(p, caplen);
|
|
|
|
}
|
2002-12-19 17:39:10 +08:00
|
|
|
|
|
|
|
return (SLL_HDR_LEN);
|
2000-12-21 18:43:19 +08:00
|
|
|
}
|