print-chdlc.c revision 56893
1/* maybe it should be merged into print-ppp.c */
2/*
3 * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
4 *	The Regents of the University of California.  All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that: (1) source code distributions
8 * retain the above copyright notice and this paragraph in its entirety, (2)
9 * distributions including binary code include the above copyright notice and
10 * this paragraph in its entirety in the documentation or other materials
11 * provided with the distribution, and (3) all advertising materials mentioning
12 * features or use of this software display the following acknowledgement:
13 * ``This product includes software developed by the University of California,
14 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
15 * the University nor the names of its contributors may be used to endorse
16 * or promote products derived from this software without specific prior
17 * written permission.
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21 */
22
23#ifndef lint
24static const char rcsid[] =
25    "@(#) $Header: /tcpdump/master/tcpdump/print-chdlc.c,v 1.2 1999/11/21 09:36:49 fenner Exp $ (LBL)";
26#endif
27
28#ifdef HAVE_CONFIG_H
29#include "config.h"
30#endif
31
32#include <sys/param.h>
33#include <sys/time.h>
34#include <sys/socket.h>
35#include <sys/file.h>
36#include <sys/ioctl.h>
37
38#if __STDC__
39struct mbuf;
40struct rtentry;
41#endif
42#include <net/if.h>
43
44#include <netinet/in.h>
45#include <netinet/in_systm.h>
46#include <netinet/ip.h>
47#include <netinet/if_ether.h>
48
49#include <ctype.h>
50#include <netdb.h>
51#include <pcap.h>
52#include <stdio.h>
53#ifdef __bsdi__
54#include <net/slcompress.h>
55#include <net/if_ppp.h>
56#endif
57
58#include "interface.h"
59#include "addrtoname.h"
60#include "ppp.h"
61
62/* XXX This goes somewhere else. */
63#define CHDLC_HDRLEN 4
64#define CHDLC_UNICAST	0x0f
65#define CHDLC_BCAST	0x8f
66#define CHDLC_TYPE_SLARP	0x8035
67#define CHDLC_TYPE_CDP		0x2000
68
69static void chdlc_slarp_print(const u_char *, u_int);
70
71/* Standard CHDLC printer */
72void
73chdlc_if_print(u_char *user, const struct pcap_pkthdr *h,
74	     register const u_char *p)
75{
76	register u_int length = h->len;
77	register u_int caplen = h->caplen;
78	const struct ip *ip;
79	u_int proto;
80
81	ts_print(&h->ts);
82
83	if (caplen < CHDLC_HDRLEN) {
84		printf("[|chdlc]");
85		goto out;
86	}
87
88	/*
89	 * Some printers want to get back at the link level addresses,
90	 * and/or check that they're not walking off the end of the packet.
91	 * Rather than pass them all the way down, we set these globals.
92	 */
93	proto = ntohs(*(u_short *)&p[2]);
94	packetp = p;
95	snapend = p + caplen;
96
97	if (eflag) {
98		switch (p[0]) {
99		case CHDLC_UNICAST:
100			printf("unicast ");
101			break;
102		case CHDLC_BCAST:
103			printf("bcast ");
104			break;
105		default:
106			printf("0x%02x ", p[0]);
107			break;
108		}
109		printf("%d %04x: ", length, proto);
110	}
111
112	length -= CHDLC_HDRLEN;
113	ip = (struct ip *)(p + CHDLC_HDRLEN);
114	switch(proto) {
115	case ETHERTYPE_IP:
116		ip_print((const u_char *)ip, length);
117		break;
118#ifdef INET6
119	case ETHERTYPE_IPV6:
120		ip6_print((const u_char *)ip, length);
121		break;
122#endif
123	case CHDLC_TYPE_SLARP:
124		chdlc_slarp_print((const u_char *)ip, length);
125		break;
126#if 0
127	case CHDLC_TYPE_CDP:
128		chdlc_cdp_print((const u_char *)ip, length);
129		break;
130#endif
131	}
132	if (xflag)
133		default_print((const u_char *)ip, caplen - CHDLC_HDRLEN);
134out:
135	putchar('\n');
136}
137
138struct cisco_slarp {
139	long code;
140#define SLARP_REQUEST	0
141#define SLARP_REPLY	1
142#define SLARP_KEEPALIVE	2
143	union {
144		struct {
145			struct in_addr addr;
146			struct in_addr mask;
147			u_short unused[3];
148		} addr;
149		struct {
150			long myseq;
151			long yourseq;
152			short rel;
153			short t1;
154			short t2;
155		} keep;
156	} un;
157};
158
159#define SLARP_LEN	18
160
161static void
162chdlc_slarp_print(const u_char *cp, u_int length)
163{
164	struct cisco_slarp *slarp;
165
166	if (length < SLARP_LEN) {
167		printf("[|slarp]");
168		return;
169	}
170
171	slarp = (struct cisco_slarp *)cp;
172	switch (ntohl(slarp->code)) {
173	case SLARP_REQUEST:
174		printf("slarp-request");
175		break;
176	case SLARP_REPLY:
177		printf("slarp-reply %s/%s",
178			ipaddr_string(&slarp->un.addr.addr),
179			ipaddr_string(&slarp->un.addr.mask));
180		break;
181	case SLARP_KEEPALIVE:
182		printf("slarp-keepalive my=0x%x your=0x%x ",
183			(u_int32_t)ntohl(slarp->un.keep.myseq),
184			(u_int32_t)ntohl(slarp->un.keep.yourseq));
185		printf("reliability=0x%04x t1=%d.%d",
186			ntohs(slarp->un.keep.rel), ntohs(slarp->un.keep.t1),
187			ntohs(slarp->un.keep.t2));
188		break;
189	default:
190		printf("slarp-0x%x unknown", (u_int32_t)ntohl(slarp->code));
191		break;
192	}
193
194	if (SLARP_LEN < length && vflag)
195		printf("(trailing junk: %d bytes)", length - SLARP_LEN);
196}
197