print-chdlc.c revision 162017
156893Sfenner/*
256893Sfenner * Copyright (c) 1990, 1991, 1993, 1994, 1995, 1996, 1997
356893Sfenner *	The Regents of the University of California.  All rights reserved.
456893Sfenner *
556893Sfenner * Redistribution and use in source and binary forms, with or without
656893Sfenner * modification, are permitted provided that: (1) source code distributions
756893Sfenner * retain the above copyright notice and this paragraph in its entirety, (2)
856893Sfenner * distributions including binary code include the above copyright notice and
956893Sfenner * this paragraph in its entirety in the documentation or other materials
1056893Sfenner * provided with the distribution, and (3) all advertising materials mentioning
1156893Sfenner * features or use of this software display the following acknowledgement:
1256893Sfenner * ``This product includes software developed by the University of California,
1356893Sfenner * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
1456893Sfenner * the University nor the names of its contributors may be used to endorse
1556893Sfenner * or promote products derived from this software without specific prior
1656893Sfenner * written permission.
1756893Sfenner * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
1856893Sfenner * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
1956893Sfenner * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
2056893Sfenner */
2156893Sfenner
2256893Sfenner#ifndef lint
23127668Sbmsstatic const char rcsid[] _U_ =
24162017Ssam    "@(#) $Header: /tcpdump/master/tcpdump/print-chdlc.c,v 1.32.2.8 2005/08/23 10:29:42 hannes Exp $ (LBL)";
2556893Sfenner#endif
2656893Sfenner
2756893Sfenner#ifdef HAVE_CONFIG_H
2856893Sfenner#include "config.h"
2956893Sfenner#endif
3056893Sfenner
31127668Sbms#include <tcpdump-stdinc.h>
3256893Sfenner
3356893Sfenner#include <pcap.h>
3456893Sfenner#include <stdio.h>
3556893Sfenner
3656893Sfenner#include "interface.h"
3756893Sfenner#include "addrtoname.h"
3875115Sfenner#include "ethertype.h"
3998524Sfenner#include "extract.h"
4056893Sfenner#include "ppp.h"
4175115Sfenner#include "chdlc.h"
4256893Sfenner
4356893Sfennerstatic void chdlc_slarp_print(const u_char *, u_int);
4456893Sfenner
4556893Sfenner/* Standard CHDLC printer */
46127668Sbmsu_int
47127668Sbmschdlc_if_print(const struct pcap_pkthdr *h, register const u_char *p)
4856893Sfenner{
4956893Sfenner	register u_int length = h->len;
5056893Sfenner	register u_int caplen = h->caplen;
5198524Sfenner
5298524Sfenner	if (caplen < CHDLC_HDRLEN) {
5398524Sfenner		printf("[|chdlc]");
54127668Sbms		return (caplen);
5598524Sfenner	}
56162017Ssam        return (chdlc_print(p,length));
57162017Ssam}
5898524Sfenner
59162017Ssamu_int
60162017Ssamchdlc_print(register const u_char *p, u_int length) {
61162017Ssam	u_int proto;
62162017Ssam	const struct ip *ip;
63162017Ssam
6498524Sfenner	proto = EXTRACT_16BITS(&p[2]);
6556893Sfenner	if (eflag) {
6656893Sfenner		switch (p[0]) {
6756893Sfenner		case CHDLC_UNICAST:
6856893Sfenner			printf("unicast ");
6956893Sfenner			break;
7056893Sfenner		case CHDLC_BCAST:
7156893Sfenner			printf("bcast ");
7256893Sfenner			break;
7356893Sfenner		default:
7456893Sfenner			printf("0x%02x ", p[0]);
7556893Sfenner			break;
7656893Sfenner		}
7756893Sfenner		printf("%d %04x: ", length, proto);
7856893Sfenner	}
7956893Sfenner
8056893Sfenner	length -= CHDLC_HDRLEN;
8198524Sfenner	ip = (const struct ip *)(p + CHDLC_HDRLEN);
8275115Sfenner	switch (proto) {
8356893Sfenner	case ETHERTYPE_IP:
84146773Ssam		ip_print(gndo, (const u_char *)ip, length);
8556893Sfenner		break;
8656893Sfenner#ifdef INET6
8756893Sfenner	case ETHERTYPE_IPV6:
8856893Sfenner		ip6_print((const u_char *)ip, length);
8956893Sfenner		break;
9056893Sfenner#endif
9156893Sfenner	case CHDLC_TYPE_SLARP:
9256893Sfenner		chdlc_slarp_print((const u_char *)ip, length);
9356893Sfenner		break;
9456893Sfenner#if 0
9556893Sfenner	case CHDLC_TYPE_CDP:
9656893Sfenner		chdlc_cdp_print((const u_char *)ip, length);
9756893Sfenner		break;
9856893Sfenner#endif
99127668Sbms        case ETHERTYPE_MPLS:
100127668Sbms        case ETHERTYPE_MPLS_MULTI:
101127668Sbms                mpls_print((const u_char *)(ip), length);
102127668Sbms		break;
103127668Sbms        case ETHERTYPE_ISO:
104127668Sbms                /* is the fudge byte set ? lets verify by spotting ISO headers */
105127668Sbms                if (*(p+CHDLC_HDRLEN+1) == 0x81 ||
106127668Sbms                    *(p+CHDLC_HDRLEN+1) == 0x82 ||
107127668Sbms                    *(p+CHDLC_HDRLEN+1) == 0x83)
108127668Sbms                    isoclns_print(p+CHDLC_HDRLEN+1, length-1, length-1);
109127668Sbms                else
110127668Sbms                    isoclns_print(p+CHDLC_HDRLEN, length, length);
111127668Sbms                break;
112127668Sbms	default:
113127668Sbms                printf("unknown CHDLC protocol (0x%04x)", proto);
114127668Sbms                break;
11556893Sfenner	}
116127668Sbms
117127668Sbms	return (CHDLC_HDRLEN);
11856893Sfenner}
11956893Sfenner
120147899Ssam/*
121147899Ssam * The fixed-length portion of a SLARP packet.
122147899Ssam */
12356893Sfennerstruct cisco_slarp {
124147899Ssam	u_int8_t code[4];
12556893Sfenner#define SLARP_REQUEST	0
12656893Sfenner#define SLARP_REPLY	1
12756893Sfenner#define SLARP_KEEPALIVE	2
12856893Sfenner	union {
12956893Sfenner		struct {
130147899Ssam			u_int8_t addr[4];
131147899Ssam			u_int8_t mask[4];
13256893Sfenner		} addr;
13356893Sfenner		struct {
134147899Ssam			u_int8_t myseq[4];
135147899Ssam			u_int8_t yourseq[4];
136147899Ssam			u_int8_t rel[2];
13756893Sfenner		} keep;
13856893Sfenner	} un;
13956893Sfenner};
14056893Sfenner
141147899Ssam#define SLARP_MIN_LEN	14
142147899Ssam#define SLARP_MAX_LEN	18
14356893Sfenner
14456893Sfennerstatic void
14556893Sfennerchdlc_slarp_print(const u_char *cp, u_int length)
14656893Sfenner{
14798524Sfenner	const struct cisco_slarp *slarp;
148147899Ssam        u_int sec,min,hrs,days;
14956893Sfenner
150147899Ssam        printf("SLARP (length: %u), ",length);
151147899Ssam	if (length < SLARP_MIN_LEN)
152127668Sbms		goto trunc;
15356893Sfenner
15498524Sfenner	slarp = (const struct cisco_slarp *)cp;
155147899Ssam	TCHECK2(*slarp, SLARP_MIN_LEN);
156127668Sbms	switch (EXTRACT_32BITS(&slarp->code)) {
15756893Sfenner	case SLARP_REQUEST:
158127668Sbms		printf("request");
159147899Ssam		/*
160147899Ssam		 * At least according to William "Chops" Westfield's
161147899Ssam		 * message in
162147899Ssam		 *
163147899Ssam		 *	http://www.nethelp.no/net/cisco-hdlc.txt
164147899Ssam		 *
165147899Ssam		 * the address and mask aren't used in requests -
166147899Ssam		 * they're just zero.
167147899Ssam		 */
16856893Sfenner		break;
16956893Sfenner	case SLARP_REPLY:
170127668Sbms		printf("reply %s/%s",
17156893Sfenner			ipaddr_string(&slarp->un.addr.addr),
17256893Sfenner			ipaddr_string(&slarp->un.addr.mask));
17356893Sfenner		break;
17456893Sfenner	case SLARP_KEEPALIVE:
175147899Ssam		printf("keepalive: mineseen=0x%08x, yourseen=0x%08x, reliability=0x%04x",
176147899Ssam                       EXTRACT_32BITS(&slarp->un.keep.myseq),
177147899Ssam                       EXTRACT_32BITS(&slarp->un.keep.yourseq),
178147899Ssam                       EXTRACT_16BITS(&slarp->un.keep.rel));
179147899Ssam
180147899Ssam                if (length >= SLARP_MAX_LEN) { /* uptime-stamp is optional */
181147899Ssam                        cp += SLARP_MIN_LEN;
182147899Ssam                        if (!TTEST2(*cp, 4))
183147899Ssam                                goto trunc;
184147899Ssam                        sec = EXTRACT_32BITS(cp) / 1000;
185147899Ssam                        min = sec / 60; sec -= min * 60;
186147899Ssam                        hrs = min / 60; min -= hrs * 60;
187147899Ssam                        days = hrs / 24; hrs -= days * 24;
188147899Ssam                        printf(", link uptime=%ud%uh%um%us",days,hrs,min,sec);
189147899Ssam                }
19056893Sfenner		break;
19156893Sfenner	default:
192127668Sbms		printf("0x%02x unknown", EXTRACT_32BITS(&slarp->code));
193127668Sbms                if (vflag <= 1)
194127668Sbms                    print_unknown_data(cp+4,"\n\t",length-4);
19556893Sfenner		break;
19656893Sfenner	}
19756893Sfenner
198147899Ssam	if (SLARP_MAX_LEN < length && vflag)
199147899Ssam		printf(", (trailing junk: %d bytes)", length - SLARP_MAX_LEN);
200127668Sbms        if (vflag > 1)
201127668Sbms            print_unknown_data(cp+4,"\n\t",length-4);
202127668Sbms	return;
203127668Sbms
204127668Sbmstrunc:
205127668Sbms	printf("[|slarp]");
20656893Sfenner}
207146773Ssam
208146773Ssam
209146773Ssam/*
210146773Ssam * Local Variables:
211146773Ssam * c-style: whitesmith
212146773Ssam * c-basic-offset: 8
213146773Ssam * End:
214146773Ssam */
215