tcpdump/print-cip.c
guy c23f7b7dcf There's no link-layer header on Linux ARPHRD_ATM packets; there's
apparently (as per the previous version of this code) either an 802.2
LLC header (as per RFC 1483 and RFC 2225), or there's no header at all,
and just an IP packet.

As such, no link-layer header should be printed.

In addition, for packets with an LLC header, we should call the LLC
printer, rather than assuming that it's SNAP-encapsulated (RFC 1483
says they're not always SNAP-encapsulated) and printing the header
ourselves.  For packets without an LLC header, we should just call the
IP print routine.

This means that the LLC print routine may be called with null source and
destination MAC addresses; make it handle them.
2001-09-23 21:52:38 +00:00

132 lines
3.0 KiB
C

/*
* Marko Kiiskila carnil@cs.tut.fi
*
* Tampere University of Technology - Telecommunications Laboratory
*
* Permission to use, copy, modify and distribute this
* software and its documentation is hereby granted,
* provided that both the copyright notice and this
* permission notice appear in all copies of the software,
* derivative works or modified versions, and any portions
* thereof, that both notices appear in supporting
* documentation, and that the use of this software is
* acknowledged in any publications resulting from using
* the software.
*
* TUT ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
* CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR
* ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS
* SOFTWARE.
*
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header: /tcpdump/master/tcpdump/print-cip.c,v 1.16 2001-09-23 21:52:38 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <string.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <pcap.h>
#include "interface.h"
#include "addrtoname.h"
#include "ethertype.h"
#include "ether.h"
#define RFC1483LLC_LEN 8
static unsigned char rfcllc[] = {
0xaa, /* DSAP: non-ISO */
0xaa, /* SSAP: non-ISO */
0x03, /* Ctrl: Unnumbered Information Command PDU */
0x00, /* OUI: EtherType */
0x00,
0x00 };
static inline void
cip_print(register const u_char *bp, int length)
{
/*
* There is no MAC-layer header, so just print the length.
*/
printf("%d: ", length);
}
/*
* This is the top level routine of the printer. 'p' is the points
* to the raw header of the packet, 'tvp' is the timestamp,
* 'length' is the length of the packet off the wire, and 'caplen'
* is the number of bytes actually captured.
*/
void
cip_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
{
u_int caplen = h->caplen;
u_int length = h->len;
u_short extracted_ethertype;
++infodelay;
ts_print(&h->ts);
if (memcmp(rfcllc, p, sizeof(rfcllc))==0 && caplen < RFC1483LLC_LEN) {
printf("[|cip]");
goto out;
}
if (eflag)
cip_print(p, length);
/*
* Some printers want to get back at the ethernet addresses,
* and/or check that they're not walking off the end of the packet.
* Rather than pass them all the way down, we set these globals.
*/
packetp = p;
snapend = p + caplen;
if (memcmp(rfcllc, p, sizeof(rfcllc)) == 0) {
/*
* LLC header is present. Try to print it & higher layers.
*/
if (llc_print(p, length, caplen, NULL, NULL,
&extracted_ethertype) == 0) {
/* ether_type not known, print raw packet */
if (!eflag)
cip_print(p, length);
if (extracted_ethertype) {
printf("(LLC %s) ",
etherproto_string(htons(extracted_ethertype)));
}
if (!xflag && !qflag)
default_print(p, caplen);
}
} else {
/*
* LLC header is absent; treat it as just IP.
*/
ip_print(p, length);
}
if (xflag)
default_print(p, caplen);
out:
putchar('\n');
--infodelay;
if (infoprint)
info(0);
}