print-cip.c revision 98524
1/*
2 * Marko Kiiskila carnil@cs.tut.fi
3 *
4 * Tampere University of Technology - Telecommunications Laboratory
5 *
6 * Permission to use, copy, modify and distribute this
7 * software and its documentation is hereby granted,
8 * provided that both the copyright notice and this
9 * permission notice appear in all copies of the software,
10 * derivative works or modified versions, and any portions
11 * thereof, that both notices appear in supporting
12 * documentation, and that the use of this software is
13 * acknowledged in any publications resulting from using
14 * the software.
15 *
16 * TUT ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
17 * CONDITION AND DISCLAIMS ANY LIABILITY OF ANY KIND FOR
18 * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS
19 * SOFTWARE.
20 *
21 */
22
23#ifndef lint
24static const char rcsid[] =
25    "@(#) $Header: /tcpdump/master/tcpdump/print-cip.c,v 1.16 2001/09/23 21:52:38 guy Exp $ (LBL)";
26#endif
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <string.h>
33
34#include <sys/param.h>
35#include <sys/time.h>
36#include <sys/types.h>
37#include <sys/socket.h>
38
39
40#include <netinet/in.h>
41
42#include <stdio.h>
43#include <pcap.h>
44
45#include "interface.h"
46#include "addrtoname.h"
47#include "ethertype.h"
48#include "ether.h"
49
50#define RFC1483LLC_LEN	8
51
52static unsigned char rfcllc[] = {
53	0xaa,	/* DSAP: non-ISO */
54	0xaa,	/* SSAP: non-ISO */
55	0x03,	/* Ctrl: Unnumbered Information Command PDU */
56	0x00,	/* OUI: EtherType */
57	0x00,
58	0x00 };
59
60static inline void
61cip_print(register const u_char *bp, int length)
62{
63	/*
64	 * There is no MAC-layer header, so just print the length.
65	 */
66	printf("%d: ", length);
67}
68
69/*
70 * This is the top level routine of the printer.  'p' is the points
71 * to the raw header of the packet, 'tvp' is the timestamp,
72 * 'length' is the length of the packet off the wire, and 'caplen'
73 * is the number of bytes actually captured.
74 */
75void
76cip_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
77{
78	u_int caplen = h->caplen;
79	u_int length = h->len;
80	u_short extracted_ethertype;
81
82	++infodelay;
83	ts_print(&h->ts);
84
85	if (memcmp(rfcllc, p, sizeof(rfcllc))==0 && caplen < RFC1483LLC_LEN) {
86		printf("[|cip]");
87		goto out;
88	}
89
90	if (eflag)
91		cip_print(p, length);
92
93	/*
94	 * Some printers want to get back at the ethernet addresses,
95	 * and/or check that they're not walking off the end of the packet.
96	 * Rather than pass them all the way down, we set these globals.
97	 */
98	packetp = p;
99	snapend = p + caplen;
100
101	if (memcmp(rfcllc, p, sizeof(rfcllc)) == 0) {
102		/*
103		 * LLC header is present.  Try to print it & higher layers.
104		 */
105		if (llc_print(p, length, caplen, NULL, NULL,
106		    &extracted_ethertype) == 0) {
107			/* ether_type not known, print raw packet */
108			if (!eflag)
109				cip_print(p, length);
110			if (extracted_ethertype) {
111				printf("(LLC %s) ",
112			       etherproto_string(htons(extracted_ethertype)));
113			}
114			if (!xflag && !qflag)
115				default_print(p, caplen);
116		}
117	} else {
118		/*
119		 * LLC header is absent; treat it as just IP.
120		 */
121		ip_print(p, length);
122	}
123
124	if (xflag)
125		default_print(p, caplen);
126 out:
127	putchar('\n');
128	--infodelay;
129	if (infoprint)
130		info(0);
131}
132