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