print-chdlc.c revision 56893
156893Sfenner/* maybe it should be merged into print-ppp.c */
256893Sfenner/*
356893Sfenner * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
456893Sfenner *	The Regents of the University of California.  All rights reserved.
556893Sfenner *
656893Sfenner * Redistribution and use in source and binary forms, with or without
756893Sfenner * modification, are permitted provided that: (1) source code distributions
856893Sfenner * retain the above copyright notice and this paragraph in its entirety, (2)
956893Sfenner * distributions including binary code include the above copyright notice and
1056893Sfenner * this paragraph in its entirety in the documentation or other materials
1156893Sfenner * provided with the distribution, and (3) all advertising materials mentioning
1256893Sfenner * features or use of this software display the following acknowledgement:
1356893Sfenner * ``This product includes software developed by the University of California,
1456893Sfenner * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1556893Sfenner * the University nor the names of its contributors may be used to endorse
1656893Sfenner * or promote products derived from this software without specific prior
1756893Sfenner * written permission.
1856893Sfenner * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1956893Sfenner * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
2056893Sfenner * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2156893Sfenner */
2256893Sfenner
2356893Sfenner#ifndef lint
2456893Sfennerstatic const char rcsid[] =
2556893Sfenner    "@(#) $Header: /tcpdump/master/tcpdump/print-chdlc.c,v 1.2 1999/11/21 09:36:49 fenner Exp $ (LBL)";
2656893Sfenner#endif
2756893Sfenner
2856893Sfenner#ifdef HAVE_CONFIG_H
2956893Sfenner#include "config.h"
3056893Sfenner#endif
3156893Sfenner
3256893Sfenner#include <sys/param.h>
3356893Sfenner#include <sys/time.h>
3456893Sfenner#include <sys/socket.h>
3556893Sfenner#include <sys/file.h>
3656893Sfenner#include <sys/ioctl.h>
3756893Sfenner
3856893Sfenner#if __STDC__
3956893Sfennerstruct mbuf;
4056893Sfennerstruct rtentry;
4156893Sfenner#endif
4256893Sfenner#include <net/if.h>
4356893Sfenner
4456893Sfenner#include <netinet/in.h>
4556893Sfenner#include <netinet/in_systm.h>
4656893Sfenner#include <netinet/ip.h>
4756893Sfenner#include <netinet/if_ether.h>
4856893Sfenner
4956893Sfenner#include <ctype.h>
5056893Sfenner#include <netdb.h>
5156893Sfenner#include <pcap.h>
5256893Sfenner#include <stdio.h>
5356893Sfenner#ifdef __bsdi__
5456893Sfenner#include <net/slcompress.h>
5556893Sfenner#include <net/if_ppp.h>
5656893Sfenner#endif
5756893Sfenner
5856893Sfenner#include "interface.h"
5956893Sfenner#include "addrtoname.h"
6056893Sfenner#include "ppp.h"
6156893Sfenner
6256893Sfenner/* XXX This goes somewhere else. */
6356893Sfenner#define CHDLC_HDRLEN 4
6456893Sfenner#define CHDLC_UNICAST	0x0f
6556893Sfenner#define CHDLC_BCAST	0x8f
6656893Sfenner#define CHDLC_TYPE_SLARP	0x8035
6756893Sfenner#define CHDLC_TYPE_CDP		0x2000
6856893Sfenner
6956893Sfennerstatic void chdlc_slarp_print(const u_char *, u_int);
7056893Sfenner
7156893Sfenner/* Standard CHDLC printer */
7256893Sfennervoid
7356893Sfennerchdlc_if_print(u_char *user, const struct pcap_pkthdr *h,
7456893Sfenner	     register const u_char *p)
7556893Sfenner{
7656893Sfenner	register u_int length = h->len;
7756893Sfenner	register u_int caplen = h->caplen;
7856893Sfenner	const struct ip *ip;
7956893Sfenner	u_int proto;
8056893Sfenner
8156893Sfenner	ts_print(&h->ts);
8256893Sfenner
8356893Sfenner	if (caplen < CHDLC_HDRLEN) {
8456893Sfenner		printf("[|chdlc]");
8556893Sfenner		goto out;
8656893Sfenner	}
8756893Sfenner
8856893Sfenner	/*
8956893Sfenner	 * Some printers want to get back at the link level addresses,
9056893Sfenner	 * and/or check that they're not walking off the end of the packet.
9156893Sfenner	 * Rather than pass them all the way down, we set these globals.
9256893Sfenner	 */
9356893Sfenner	proto = ntohs(*(u_short *)&p[2]);
9456893Sfenner	packetp = p;
9556893Sfenner	snapend = p + caplen;
9656893Sfenner
9756893Sfenner	if (eflag) {
9856893Sfenner		switch (p[0]) {
9956893Sfenner		case CHDLC_UNICAST:
10056893Sfenner			printf("unicast ");
10156893Sfenner			break;
10256893Sfenner		case CHDLC_BCAST:
10356893Sfenner			printf("bcast ");
10456893Sfenner			break;
10556893Sfenner		default:
10656893Sfenner			printf("0x%02x ", p[0]);
10756893Sfenner			break;
10856893Sfenner		}
10956893Sfenner		printf("%d %04x: ", length, proto);
11056893Sfenner	}
11156893Sfenner
11256893Sfenner	length -= CHDLC_HDRLEN;
11356893Sfenner	ip = (struct ip *)(p + CHDLC_HDRLEN);
11456893Sfenner	switch(proto) {
11556893Sfenner	case ETHERTYPE_IP:
11656893Sfenner		ip_print((const u_char *)ip, length);
11756893Sfenner		break;
11856893Sfenner#ifdef INET6
11956893Sfenner	case ETHERTYPE_IPV6:
12056893Sfenner		ip6_print((const u_char *)ip, length);
12156893Sfenner		break;
12256893Sfenner#endif
12356893Sfenner	case CHDLC_TYPE_SLARP:
12456893Sfenner		chdlc_slarp_print((const u_char *)ip, length);
12556893Sfenner		break;
12656893Sfenner#if 0
12756893Sfenner	case CHDLC_TYPE_CDP:
12856893Sfenner		chdlc_cdp_print((const u_char *)ip, length);
12956893Sfenner		break;
13056893Sfenner#endif
13156893Sfenner	}
13256893Sfenner	if (xflag)
13356893Sfenner		default_print((const u_char *)ip, caplen - CHDLC_HDRLEN);
13456893Sfennerout:
13556893Sfenner	putchar('\n');
13656893Sfenner}
13756893Sfenner
13856893Sfennerstruct cisco_slarp {
13956893Sfenner	long code;
14056893Sfenner#define SLARP_REQUEST	0
14156893Sfenner#define SLARP_REPLY	1
14256893Sfenner#define SLARP_KEEPALIVE	2
14356893Sfenner	union {
14456893Sfenner		struct {
14556893Sfenner			struct in_addr addr;
14656893Sfenner			struct in_addr mask;
14756893Sfenner			u_short unused[3];
14856893Sfenner		} addr;
14956893Sfenner		struct {
15056893Sfenner			long myseq;
15156893Sfenner			long yourseq;
15256893Sfenner			short rel;
15356893Sfenner			short t1;
15456893Sfenner			short t2;
15556893Sfenner		} keep;
15656893Sfenner	} un;
15756893Sfenner};
15856893Sfenner
15956893Sfenner#define SLARP_LEN	18
16056893Sfenner
16156893Sfennerstatic void
16256893Sfennerchdlc_slarp_print(const u_char *cp, u_int length)
16356893Sfenner{
16456893Sfenner	struct cisco_slarp *slarp;
16556893Sfenner
16656893Sfenner	if (length < SLARP_LEN) {
16756893Sfenner		printf("[|slarp]");
16856893Sfenner		return;
16956893Sfenner	}
17056893Sfenner
17156893Sfenner	slarp = (struct cisco_slarp *)cp;
17256893Sfenner	switch (ntohl(slarp->code)) {
17356893Sfenner	case SLARP_REQUEST:
17456893Sfenner		printf("slarp-request");
17556893Sfenner		break;
17656893Sfenner	case SLARP_REPLY:
17756893Sfenner		printf("slarp-reply %s/%s",
17856893Sfenner			ipaddr_string(&slarp->un.addr.addr),
17956893Sfenner			ipaddr_string(&slarp->un.addr.mask));
18056893Sfenner		break;
18156893Sfenner	case SLARP_KEEPALIVE:
18256893Sfenner		printf("slarp-keepalive my=0x%x your=0x%x ",
18356893Sfenner			(u_int32_t)ntohl(slarp->un.keep.myseq),
18456893Sfenner			(u_int32_t)ntohl(slarp->un.keep.yourseq));
18556893Sfenner		printf("reliability=0x%04x t1=%d.%d",
18656893Sfenner			ntohs(slarp->un.keep.rel), ntohs(slarp->un.keep.t1),
18756893Sfenner			ntohs(slarp->un.keep.t2));
18856893Sfenner		break;
18956893Sfenner	default:
19056893Sfenner		printf("slarp-0x%x unknown", (u_int32_t)ntohl(slarp->code));
19156893Sfenner		break;
19256893Sfenner	}
19356893Sfenner
19456893Sfenner	if (SLARP_LEN < length && vflag)
19556893Sfenner		printf("(trailing junk: %d bytes)", length - SLARP_LEN);
19656893Sfenner}
197