print-chdlc.c revision 98524
1118611Snjl/* maybe it should be merged into print-ppp.c */
2118611Snjl/*
3118611Snjl * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
4118611Snjl *	The Regents of the University of California.  All rights reserved.
5118611Snjl *
6118611Snjl * Redistribution and use in source and binary forms, with or without
7118611Snjl * modification, are permitted provided that: (1) source code distributions
8118611Snjl * retain the above copyright notice and this paragraph in its entirety, (2)
9118611Snjl * distributions including binary code include the above copyright notice and
10118611Snjl * this paragraph in its entirety in the documentation or other materials
11118611Snjl * provided with the distribution, and (3) all advertising materials mentioning
12193529Sjkim * features or use of this software display the following acknowledgement:
13118611Snjl * ``This product includes software developed by the University of California,
14118611Snjl * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
15118611Snjl * the University nor the names of its contributors may be used to endorse
16118611Snjl * or promote products derived from this software without specific prior
17118611Snjl * written permission.
18118611Snjl * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
19118611Snjl * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
20118611Snjl * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
21118611Snjl */
22118611Snjl
23118611Snjl#ifndef lint
24118611Snjlstatic const char rcsid[] =
25118611Snjl    "@(#) $Header: /tcpdump/master/tcpdump/print-chdlc.c,v 1.13 2001/09/17 21:57:57 fenner Exp $ (LBL)";
26118611Snjl#endif
27118611Snjl
28118611Snjl#ifdef HAVE_CONFIG_H
29118611Snjl#include "config.h"
30118611Snjl#endif
31118611Snjl
32118611Snjl#include <sys/param.h>
33118611Snjl#include <sys/time.h>
34118611Snjl
35118611Snjl#include <netinet/in.h>
36118611Snjl
37118611Snjl#include <ctype.h>
38118611Snjl#include <netdb.h>
39118611Snjl#include <pcap.h>
40118611Snjl#include <stdio.h>
41118611Snjl
42118611Snjl#include "interface.h"
43118611Snjl#include "addrtoname.h"
44118611Snjl#include "ethertype.h"
45118611Snjl#include "extract.h"
46118611Snjl#include "ppp.h"
47118611Snjl#include "chdlc.h"
48118611Snjl
49118611Snjlstatic void chdlc_slarp_print(const u_char *, u_int);
50118611Snjl
51118611Snjl/* Standard CHDLC printer */
52118611Snjlvoid
53118611Snjlchdlc_if_print(u_char *user, const struct pcap_pkthdr *h,
54118611Snjl	     register const u_char *p)
55118611Snjl{
56118611Snjl	register u_int length = h->len;
57118611Snjl	register u_int caplen = h->caplen;
58118611Snjl
59118611Snjl	++infodelay;
60118611Snjl	ts_print(&h->ts);
61118611Snjl
62118611Snjl	/*
63118611Snjl	 * Some printers want to get back at the link level addresses,
64118611Snjl	 * and/or check that they're not walking off the end of the packet.
65118611Snjl	 * Rather than pass them all the way down, we set these globals.
66118611Snjl	 */
67118611Snjl	packetp = p;
68118611Snjl	snapend = p + caplen;
69118611Snjl
70118611Snjl	chdlc_print(p, length, caplen);
71118611Snjl
72118611Snjl	putchar('\n');
73118611Snjl	--infodelay;
74118611Snjl	if (infoprint)
75118611Snjl		info(0);
76118611Snjl}
77118611Snjl
78118611Snjlvoid
79118611Snjlchdlc_print(register const u_char *p, u_int length, u_int caplen)
80118611Snjl{
81118611Snjl	const struct ip *ip;
82118611Snjl	u_int proto;
83118611Snjl
84118611Snjl	if (caplen < CHDLC_HDRLEN) {
85118611Snjl		printf("[|chdlc]");
86118611Snjl		return;
87118611Snjl	}
88118611Snjl
89118611Snjl	proto = EXTRACT_16BITS(&p[2]);
90118611Snjl	if (eflag) {
91118611Snjl		switch (p[0]) {
92118611Snjl		case CHDLC_UNICAST:
93118611Snjl			printf("unicast ");
94118611Snjl			break;
95118611Snjl		case CHDLC_BCAST:
96118611Snjl			printf("bcast ");
97118611Snjl			break;
98118611Snjl		default:
99118611Snjl			printf("0x%02x ", p[0]);
100118611Snjl			break;
101118611Snjl		}
102118611Snjl		printf("%d %04x: ", length, proto);
103118611Snjl	}
104118611Snjl
105118611Snjl	length -= CHDLC_HDRLEN;
106118611Snjl	ip = (const struct ip *)(p + CHDLC_HDRLEN);
107118611Snjl	switch (proto) {
108118611Snjl	case ETHERTYPE_IP:
109118611Snjl		ip_print((const u_char *)ip, length);
110118611Snjl		break;
111118611Snjl#ifdef INET6
112118611Snjl	case ETHERTYPE_IPV6:
113118611Snjl		ip6_print((const u_char *)ip, length);
114118611Snjl		break;
115118611Snjl#endif
116118611Snjl	case CHDLC_TYPE_SLARP:
117118611Snjl		chdlc_slarp_print((const u_char *)ip, length);
118151937Sjkim		break;
119118611Snjl#if 0
120118611Snjl	case CHDLC_TYPE_CDP:
121118611Snjl		chdlc_cdp_print((const u_char *)ip, length);
122118611Snjl		break;
123118611Snjl#endif
124151937Sjkim	}
125118611Snjl	if (xflag)
126151937Sjkim		default_print((const u_char *)ip, caplen - CHDLC_HDRLEN);
127151937Sjkim}
128151937Sjkim
129151937Sjkimstruct cisco_slarp {
130151937Sjkim	u_int32_t code;
131151937Sjkim#define SLARP_REQUEST	0
132151937Sjkim#define SLARP_REPLY	1
133151937Sjkim#define SLARP_KEEPALIVE	2
134151937Sjkim	union {
135151937Sjkim		struct {
136151937Sjkim			struct in_addr addr;
137151937Sjkim			struct in_addr mask;
138151937Sjkim			u_int16_t unused[3];
139151937Sjkim		} addr;
140151937Sjkim		struct {
141151937Sjkim			u_int32_t myseq;
142151937Sjkim			u_int32_t yourseq;
143151937Sjkim			u_int16_t rel;
144151937Sjkim			u_int16_t t1;
145151937Sjkim			u_int16_t t2;
146151937Sjkim		} keep;
147151937Sjkim	} un;
148151937Sjkim};
149151937Sjkim
150151937Sjkim#define SLARP_LEN	18
151151937Sjkim
152151937Sjkimstatic void
153151937Sjkimchdlc_slarp_print(const u_char *cp, u_int length)
154151937Sjkim{
155151937Sjkim	const struct cisco_slarp *slarp;
156151937Sjkim
157151937Sjkim	if (length < SLARP_LEN) {
158151937Sjkim		printf("[|slarp]");
159151937Sjkim		return;
160151937Sjkim	}
161151937Sjkim
162151937Sjkim	slarp = (const struct cisco_slarp *)cp;
163151937Sjkim	switch (ntohl(slarp->code)) {
164118611Snjl	case SLARP_REQUEST:
165118611Snjl		printf("slarp-request");
166118611Snjl		break;
167118611Snjl	case SLARP_REPLY:
168151937Sjkim		printf("slarp-reply %s/%s",
169151937Sjkim			ipaddr_string(&slarp->un.addr.addr),
170151937Sjkim			ipaddr_string(&slarp->un.addr.mask));
171151937Sjkim		break;
172118611Snjl	case SLARP_KEEPALIVE:
173151937Sjkim		printf("slarp-keepalive my=0x%x your=0x%x ",
174118611Snjl			(u_int32_t)ntohl(slarp->un.keep.myseq),
175138287Smarks			(u_int32_t)ntohl(slarp->un.keep.yourseq));
176151937Sjkim		printf("reliability=0x%04x t1=%d.%d",
177118611Snjl			ntohs(slarp->un.keep.rel), ntohs(slarp->un.keep.t1),
178118611Snjl			ntohs(slarp->un.keep.t2));
179118611Snjl		break;
180151937Sjkim	default:
181118611Snjl		printf("slarp-0x%x unknown", (u_int32_t)ntohl(slarp->code));
182151937Sjkim		break;
183151937Sjkim	}
184118611Snjl
185118611Snjl	if (SLARP_LEN < length && vflag)
186118611Snjl		printf("(trailing junk: %d bytes)", length - SLARP_LEN);
187118611Snjl}
188151937Sjkim