print-cip.c revision 98524
156893Sfenner/*
256893Sfenner * Marko Kiiskila carnil@cs.tut.fi
356893Sfenner *
456893Sfenner * Tampere University of Technology - Telecommunications Laboratory
556893Sfenner *
656893Sfenner * Permission to use, copy, modify and distribute this
756893Sfenner * software and its documentation is hereby granted,
856893Sfenner * provided that both the copyright notice and this
956893Sfenner * permission notice appear in all copies of the software,
1056893Sfenner * derivative works or modified versions, and any portions
1156893Sfenner * thereof, that both notices appear in supporting
1256893Sfenner * documentation, and that the use of this software is
1356893Sfenner * acknowledged in any publications resulting from using
1456893Sfenner * the software.
1556893Sfenner *
1656893Sfenner * TUT ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
1756893Sfenner * CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR
1856893Sfenner * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS
1956893Sfenner * SOFTWARE.
2056893Sfenner *
2156893Sfenner */
2256893Sfenner
2356893Sfenner#ifndef lint
2456893Sfennerstatic const char rcsid[] =
2598524Sfenner    "@(#) $Header: /tcpdump/master/tcpdump/print-cip.c,v 1.16 2001/09/23 21:52:38 guy Exp $ (LBL)";
2656893Sfenner#endif
2756893Sfenner
2856893Sfenner#ifdef HAVE_CONFIG_H
2956893Sfenner#include "config.h"
3056893Sfenner#endif
3156893Sfenner
3298524Sfenner#include <string.h>
3398524Sfenner
3456893Sfenner#include <sys/param.h>
3556893Sfenner#include <sys/time.h>
3656893Sfenner#include <sys/types.h>
3756893Sfenner#include <sys/socket.h>
3856893Sfenner
3956893Sfenner
4056893Sfenner#include <netinet/in.h>
4156893Sfenner
4256893Sfenner#include <stdio.h>
4356893Sfenner#include <pcap.h>
4456893Sfenner
4556893Sfenner#include "interface.h"
4656893Sfenner#include "addrtoname.h"
4775115Sfenner#include "ethertype.h"
4875115Sfenner#include "ether.h"
4956893Sfenner
5075115Sfenner#define RFC1483LLC_LEN	8
5156893Sfenner
5256893Sfennerstatic unsigned char rfcllc[] = {
5375115Sfenner	0xaa,	/* DSAP: non-ISO */
5475115Sfenner	0xaa,	/* SSAP: non-ISO */
5575115Sfenner	0x03,	/* Ctrl: Unnumbered Information Command PDU */
5675115Sfenner	0x00,	/* OUI: EtherType */
5775115Sfenner	0x00,
5875115Sfenner	0x00 };
5956893Sfenner
6056893Sfennerstatic inline void
6156893Sfennercip_print(register const u_char *bp, int length)
6256893Sfenner{
6398524Sfenner	/*
6498524Sfenner	 * There is no MAC-layer header, so just print the length.
6598524Sfenner	 */
6698524Sfenner	printf("%d: ", length);
6756893Sfenner}
6856893Sfenner
6956893Sfenner/*
7056893Sfenner * This is the top level routine of the printer.  'p' is the points
7156893Sfenner * to the raw header of the packet, 'tvp' is the timestamp,
7256893Sfenner * 'length' is the length of the packet off the wire, and 'caplen'
7356893Sfenner * is the number of bytes actually captured.
7456893Sfenner */
7556893Sfennervoid
7656893Sfennercip_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
7756893Sfenner{
7898524Sfenner	u_int caplen = h->caplen;
7998524Sfenner	u_int length = h->len;
8056893Sfenner	u_short extracted_ethertype;
8156893Sfenner
8298524Sfenner	++infodelay;
8356893Sfenner	ts_print(&h->ts);
8456893Sfenner
8556893Sfenner	if (memcmp(rfcllc, p, sizeof(rfcllc))==0 && caplen < RFC1483LLC_LEN) {
8656893Sfenner		printf("[|cip]");
8756893Sfenner		goto out;
8856893Sfenner	}
8956893Sfenner
9056893Sfenner	if (eflag)
9175115Sfenner		cip_print(p, length);
9256893Sfenner
9356893Sfenner	/*
9456893Sfenner	 * Some printers want to get back at the ethernet addresses,
9556893Sfenner	 * and/or check that they're not walking off the end of the packet.
9656893Sfenner	 * Rather than pass them all the way down, we set these globals.
9756893Sfenner	 */
9856893Sfenner	packetp = p;
9956893Sfenner	snapend = p + caplen;
10056893Sfenner
10198524Sfenner	if (memcmp(rfcllc, p, sizeof(rfcllc)) == 0) {
10298524Sfenner		/*
10398524Sfenner		 * LLC header is present.  Try to print it & higher layers.
10498524Sfenner		 */
10575115Sfenner		if (llc_print(p, length, caplen, NULL, NULL,
10698524Sfenner		    &extracted_ethertype) == 0) {
10756893Sfenner			/* ether_type not known, print raw packet */
10856893Sfenner			if (!eflag)
10998524Sfenner				cip_print(p, length);
11056893Sfenner			if (extracted_ethertype) {
11156893Sfenner				printf("(LLC %s) ",
11256893Sfenner			       etherproto_string(htons(extracted_ethertype)));
11356893Sfenner			}
11456893Sfenner			if (!xflag && !qflag)
11556893Sfenner				default_print(p, caplen);
11656893Sfenner		}
11798524Sfenner	} else {
11898524Sfenner		/*
11998524Sfenner		 * LLC header is absent; treat it as just IP.
12098524Sfenner		 */
12198524Sfenner		ip_print(p, length);
12256893Sfenner	}
12398524Sfenner
12456893Sfenner	if (xflag)
12556893Sfenner		default_print(p, caplen);
12656893Sfenner out:
12756893Sfenner	putchar('\n');
12898524Sfenner	--infodelay;
12998524Sfenner	if (infoprint)
13098524Sfenner		info(0);
13156893Sfenner}
132