14edb46e9SPaul Traina /* 2699fc314SBill Fenner * Copyright (c) 1989, 1990, 1991, 1993, 1994, 1995, 1996, 1997 34edb46e9SPaul Traina * The Regents of the University of California. All rights reserved. 44edb46e9SPaul Traina * 54edb46e9SPaul Traina * Redistribution and use in source and binary forms, with or without 64edb46e9SPaul Traina * modification, are permitted provided that: (1) source code distributions 74edb46e9SPaul Traina * retain the above copyright notice and this paragraph in its entirety, (2) 84edb46e9SPaul Traina * distributions including binary code include the above copyright notice and 94edb46e9SPaul Traina * this paragraph in its entirety in the documentation or other materials 104edb46e9SPaul Traina * provided with the distribution, and (3) all advertising materials mentioning 114edb46e9SPaul Traina * features or use of this software display the following acknowledgement: 124edb46e9SPaul Traina * ``This product includes software developed by the University of California, 134edb46e9SPaul Traina * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of 144edb46e9SPaul Traina * the University nor the names of its contributors may be used to endorse 154edb46e9SPaul Traina * or promote products derived from this software without specific prior 164edb46e9SPaul Traina * written permission. 174edb46e9SPaul Traina * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED 184edb46e9SPaul Traina * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF 194edb46e9SPaul Traina * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 20a88113a8SBill Fenner * 21a88113a8SBill Fenner * $FreeBSD$ 224edb46e9SPaul Traina */ 234edb46e9SPaul Traina 244edb46e9SPaul Traina #ifndef lint 252ebf6c05SBill Fenner static const char rcsid[] = 26a88113a8SBill Fenner "@(#) $Header: /tcpdump/master/tcpdump/print-sl.c,v 1.46 1999/11/21 12:38:24 itojun Exp $ (LBL)"; 27a88113a8SBill Fenner #endif 28a88113a8SBill Fenner 29a88113a8SBill Fenner #ifdef HAVE_CONFIG_H 30a88113a8SBill Fenner #include "config.h" 314edb46e9SPaul Traina #endif 324edb46e9SPaul Traina 334edb46e9SPaul Traina #ifdef HAVE_NET_SLIP_H 344edb46e9SPaul Traina #include <sys/param.h> 354edb46e9SPaul Traina #include <sys/time.h> 364edb46e9SPaul Traina #include <sys/timeb.h> 374edb46e9SPaul Traina #include <sys/file.h> 384edb46e9SPaul Traina #include <sys/ioctl.h> 394edb46e9SPaul Traina #include <sys/mbuf.h> 404edb46e9SPaul Traina #include <sys/socket.h> 414edb46e9SPaul Traina 424edb46e9SPaul Traina #if __STDC__ 434edb46e9SPaul Traina struct rtentry; 444edb46e9SPaul Traina #endif 454edb46e9SPaul Traina #include <net/if.h> 464edb46e9SPaul Traina 474edb46e9SPaul Traina #include <netinet/in.h> 484edb46e9SPaul Traina #include <netinet/in_systm.h> 494edb46e9SPaul Traina #include <netinet/ip.h> 50ee3e7633SGarrett Wollman #include <net/ethernet.h> 514edb46e9SPaul Traina #include <netinet/ip_var.h> 524edb46e9SPaul Traina #include <netinet/udp.h> 534edb46e9SPaul Traina #include <netinet/tcp.h> 544edb46e9SPaul Traina 554edb46e9SPaul Traina #include <net/slcompress.h> 564edb46e9SPaul Traina #include <net/slip.h> 574edb46e9SPaul Traina 584edb46e9SPaul Traina #include <ctype.h> 594edb46e9SPaul Traina #include <netdb.h> 604edb46e9SPaul Traina #include <pcap.h> 614edb46e9SPaul Traina #include <stdio.h> 624edb46e9SPaul Traina 634edb46e9SPaul Traina #include "interface.h" 644edb46e9SPaul Traina #include "addrtoname.h" 654edb46e9SPaul Traina #include "extract.h" /* must come after interface.h */ 664edb46e9SPaul Traina 674edb46e9SPaul Traina static u_int lastlen[2][256]; 684edb46e9SPaul Traina static u_int lastconn = 255; 694edb46e9SPaul Traina 704edb46e9SPaul Traina static void sliplink_print(const u_char *, const struct ip *, u_int); 714edb46e9SPaul Traina static void compressed_sl_print(const u_char *, const struct ip *, u_int, int); 724edb46e9SPaul Traina 734edb46e9SPaul Traina /* XXX BSD/OS 2.1 compatibility */ 744edb46e9SPaul Traina #if !defined(SLIP_HDRLEN) && defined(SLC_BPFHDR) 754edb46e9SPaul Traina #define SLIP_HDRLEN SLC_BPFHDR 764edb46e9SPaul Traina #define SLX_DIR 0 774edb46e9SPaul Traina #define SLX_CHDR (SLC_BPFHDRLEN - 1) 784edb46e9SPaul Traina #define CHDR_LEN (SLC_BPFHDR - SLC_BPFHDRLEN) 794edb46e9SPaul Traina #endif 804edb46e9SPaul Traina 81699fc314SBill Fenner /* XXX needs more hacking to work right */ 82699fc314SBill Fenner 834edb46e9SPaul Traina void 844edb46e9SPaul Traina sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) 854edb46e9SPaul Traina { 864edb46e9SPaul Traina register u_int caplen = h->caplen; 874edb46e9SPaul Traina register u_int length = h->len; 884edb46e9SPaul Traina register const struct ip *ip; 894edb46e9SPaul Traina 904edb46e9SPaul Traina ts_print(&h->ts); 914edb46e9SPaul Traina 924edb46e9SPaul Traina if (caplen < SLIP_HDRLEN) { 934edb46e9SPaul Traina printf("[|slip]"); 944edb46e9SPaul Traina goto out; 954edb46e9SPaul Traina } 964edb46e9SPaul Traina /* 974edb46e9SPaul Traina * Some printers want to get back at the link level addresses, 984edb46e9SPaul Traina * and/or check that they're not walking off the end of the packet. 994edb46e9SPaul Traina * Rather than pass them all the way down, we set these globals. 1004edb46e9SPaul Traina */ 1014edb46e9SPaul Traina packetp = p; 1024edb46e9SPaul Traina snapend = p + caplen; 1034edb46e9SPaul Traina 1044edb46e9SPaul Traina length -= SLIP_HDRLEN; 1054edb46e9SPaul Traina 1064edb46e9SPaul Traina ip = (struct ip *)(p + SLIP_HDRLEN); 1074edb46e9SPaul Traina 1084edb46e9SPaul Traina if (eflag) 1094edb46e9SPaul Traina sliplink_print(p, ip, length); 1104edb46e9SPaul Traina 111a88113a8SBill Fenner switch (ip->ip_v) { 112a88113a8SBill Fenner case 4: 1134edb46e9SPaul Traina ip_print((u_char *)ip, length); 114a88113a8SBill Fenner break; 115a88113a8SBill Fenner #ifdef INET6 116a88113a8SBill Fenner case 6: 117a88113a8SBill Fenner ip6_print((u_char *)ip, length); 118a88113a8SBill Fenner break; 119a88113a8SBill Fenner #endif 120a88113a8SBill Fenner default: 121a88113a8SBill Fenner printf ("ip v%d", ip->ip_v); 122a88113a8SBill Fenner } 1234edb46e9SPaul Traina 1244edb46e9SPaul Traina if (xflag) 1254edb46e9SPaul Traina default_print((u_char *)ip, caplen - SLIP_HDRLEN); 1264edb46e9SPaul Traina out: 1274edb46e9SPaul Traina putchar('\n'); 1284edb46e9SPaul Traina } 1294edb46e9SPaul Traina 130699fc314SBill Fenner 131699fc314SBill Fenner void 132699fc314SBill Fenner sl_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) 133699fc314SBill Fenner { 134699fc314SBill Fenner register u_int caplen = h->caplen; 135699fc314SBill Fenner register u_int length = h->len; 136699fc314SBill Fenner register const struct ip *ip; 137699fc314SBill Fenner 138699fc314SBill Fenner ts_print(&h->ts); 139699fc314SBill Fenner 140699fc314SBill Fenner if (caplen < SLIP_HDRLEN) { 141699fc314SBill Fenner printf("[|slip]"); 142699fc314SBill Fenner goto out; 143699fc314SBill Fenner } 144699fc314SBill Fenner /* 145699fc314SBill Fenner * Some printers want to get back at the link level addresses, 146699fc314SBill Fenner * and/or check that they're not walking off the end of the packet. 147699fc314SBill Fenner * Rather than pass them all the way down, we set these globals. 148699fc314SBill Fenner */ 149699fc314SBill Fenner packetp = p; 150699fc314SBill Fenner snapend = p + caplen; 151699fc314SBill Fenner 152699fc314SBill Fenner length -= SLIP_HDRLEN; 153699fc314SBill Fenner 154699fc314SBill Fenner ip = (struct ip *)(p + SLIP_HDRLEN); 155699fc314SBill Fenner 156699fc314SBill Fenner #ifdef notdef 157699fc314SBill Fenner if (eflag) 158699fc314SBill Fenner sliplink_print(p, ip, length); 159699fc314SBill Fenner #endif 160699fc314SBill Fenner 161699fc314SBill Fenner ip_print((u_char *)ip, length); 162699fc314SBill Fenner 163699fc314SBill Fenner if (xflag) 164699fc314SBill Fenner default_print((u_char *)ip, caplen - SLIP_HDRLEN); 165699fc314SBill Fenner out: 166699fc314SBill Fenner putchar('\n'); 167699fc314SBill Fenner } 168699fc314SBill Fenner 1694edb46e9SPaul Traina static void 1704edb46e9SPaul Traina sliplink_print(register const u_char *p, register const struct ip *ip, 1714edb46e9SPaul Traina register u_int length) 1724edb46e9SPaul Traina { 1734edb46e9SPaul Traina int dir; 1744edb46e9SPaul Traina u_int hlen; 1754edb46e9SPaul Traina 1764edb46e9SPaul Traina dir = p[SLX_DIR]; 1774edb46e9SPaul Traina putchar(dir == SLIPDIR_IN ? 'I' : 'O'); 1784edb46e9SPaul Traina putchar(' '); 1794edb46e9SPaul Traina 1804edb46e9SPaul Traina if (nflag) { 1814edb46e9SPaul Traina /* XXX just dump the header */ 1824edb46e9SPaul Traina register int i; 1834edb46e9SPaul Traina 1844edb46e9SPaul Traina for (i = SLX_CHDR; i < SLX_CHDR + CHDR_LEN - 1; ++i) 1854edb46e9SPaul Traina printf("%02x.", p[i]); 1864edb46e9SPaul Traina printf("%02x: ", p[SLX_CHDR + CHDR_LEN - 1]); 1874edb46e9SPaul Traina return; 1884edb46e9SPaul Traina } 1894edb46e9SPaul Traina switch (p[SLX_CHDR] & 0xf0) { 1904edb46e9SPaul Traina 1914edb46e9SPaul Traina case TYPE_IP: 1924edb46e9SPaul Traina printf("ip %d: ", length + SLIP_HDRLEN); 1934edb46e9SPaul Traina break; 1944edb46e9SPaul Traina 1954edb46e9SPaul Traina case TYPE_UNCOMPRESSED_TCP: 1964edb46e9SPaul Traina /* 1972ebf6c05SBill Fenner * The connection id is stored in the IP protocol field. 1984edb46e9SPaul Traina * Get it from the link layer since sl_uncompress_tcp() 1994edb46e9SPaul Traina * has restored the IP header copy to IPPROTO_TCP. 2004edb46e9SPaul Traina */ 2014edb46e9SPaul Traina lastconn = ((struct ip *)&p[SLX_CHDR])->ip_p; 2024edb46e9SPaul Traina hlen = ip->ip_hl; 2034edb46e9SPaul Traina hlen += ((struct tcphdr *)&((int *)ip)[hlen])->th_off; 2044edb46e9SPaul Traina lastlen[dir][lastconn] = length - (hlen << 2); 2054edb46e9SPaul Traina printf("utcp %d: ", lastconn); 2064edb46e9SPaul Traina break; 2074edb46e9SPaul Traina 2084edb46e9SPaul Traina default: 2094edb46e9SPaul Traina if (p[SLX_CHDR] & TYPE_COMPRESSED_TCP) { 2104edb46e9SPaul Traina compressed_sl_print(&p[SLX_CHDR], ip, 2114edb46e9SPaul Traina length, dir); 2124edb46e9SPaul Traina printf(": "); 2134edb46e9SPaul Traina } else 2144edb46e9SPaul Traina printf("slip-%d!: ", p[SLX_CHDR]); 2154edb46e9SPaul Traina } 2164edb46e9SPaul Traina } 2174edb46e9SPaul Traina 2184edb46e9SPaul Traina static const u_char * 2194edb46e9SPaul Traina print_sl_change(const char *str, register const u_char *cp) 2204edb46e9SPaul Traina { 2214edb46e9SPaul Traina register u_int i; 2224edb46e9SPaul Traina 2234edb46e9SPaul Traina if ((i = *cp++) == 0) { 2244edb46e9SPaul Traina i = EXTRACT_16BITS(cp); 2254edb46e9SPaul Traina cp += 2; 2264edb46e9SPaul Traina } 2274edb46e9SPaul Traina printf(" %s%d", str, i); 2284edb46e9SPaul Traina return (cp); 2294edb46e9SPaul Traina } 2304edb46e9SPaul Traina 2314edb46e9SPaul Traina static const u_char * 2324edb46e9SPaul Traina print_sl_winchange(register const u_char *cp) 2334edb46e9SPaul Traina { 2344edb46e9SPaul Traina register short i; 2354edb46e9SPaul Traina 2364edb46e9SPaul Traina if ((i = *cp++) == 0) { 2374edb46e9SPaul Traina i = EXTRACT_16BITS(cp); 2384edb46e9SPaul Traina cp += 2; 2394edb46e9SPaul Traina } 2404edb46e9SPaul Traina if (i >= 0) 2414edb46e9SPaul Traina printf(" W+%d", i); 2424edb46e9SPaul Traina else 2434edb46e9SPaul Traina printf(" W%d", i); 2444edb46e9SPaul Traina return (cp); 2454edb46e9SPaul Traina } 2464edb46e9SPaul Traina 2474edb46e9SPaul Traina static void 2484edb46e9SPaul Traina compressed_sl_print(const u_char *chdr, const struct ip *ip, 2494edb46e9SPaul Traina u_int length, int dir) 2504edb46e9SPaul Traina { 2514edb46e9SPaul Traina register const u_char *cp = chdr; 2524edb46e9SPaul Traina register u_int flags, hlen; 2534edb46e9SPaul Traina 2544edb46e9SPaul Traina flags = *cp++; 2554edb46e9SPaul Traina if (flags & NEW_C) { 2564edb46e9SPaul Traina lastconn = *cp++; 2574edb46e9SPaul Traina printf("ctcp %d", lastconn); 2584edb46e9SPaul Traina } else 2594edb46e9SPaul Traina printf("ctcp *"); 2604edb46e9SPaul Traina 2614edb46e9SPaul Traina /* skip tcp checksum */ 2624edb46e9SPaul Traina cp += 2; 2634edb46e9SPaul Traina 2644edb46e9SPaul Traina switch (flags & SPECIALS_MASK) { 2654edb46e9SPaul Traina case SPECIAL_I: 2664edb46e9SPaul Traina printf(" *SA+%d", lastlen[dir][lastconn]); 2674edb46e9SPaul Traina break; 2684edb46e9SPaul Traina 2694edb46e9SPaul Traina case SPECIAL_D: 2704edb46e9SPaul Traina printf(" *S+%d", lastlen[dir][lastconn]); 2714edb46e9SPaul Traina break; 2724edb46e9SPaul Traina 2734edb46e9SPaul Traina default: 2744edb46e9SPaul Traina if (flags & NEW_U) 2754edb46e9SPaul Traina cp = print_sl_change("U=", cp); 2764edb46e9SPaul Traina if (flags & NEW_W) 2774edb46e9SPaul Traina cp = print_sl_winchange(cp); 2784edb46e9SPaul Traina if (flags & NEW_A) 2794edb46e9SPaul Traina cp = print_sl_change("A+", cp); 2804edb46e9SPaul Traina if (flags & NEW_S) 2814edb46e9SPaul Traina cp = print_sl_change("S+", cp); 2824edb46e9SPaul Traina break; 2834edb46e9SPaul Traina } 2844edb46e9SPaul Traina if (flags & NEW_I) 2854edb46e9SPaul Traina cp = print_sl_change("I+", cp); 2864edb46e9SPaul Traina 2874edb46e9SPaul Traina /* 2884edb46e9SPaul Traina * 'hlen' is the length of the uncompressed TCP/IP header (in words). 2894edb46e9SPaul Traina * 'cp - chdr' is the length of the compressed header. 2904edb46e9SPaul Traina * 'length - hlen' is the amount of data in the packet. 2914edb46e9SPaul Traina */ 2924edb46e9SPaul Traina hlen = ip->ip_hl; 2934edb46e9SPaul Traina hlen += ((struct tcphdr *)&((int32_t *)ip)[hlen])->th_off; 2944edb46e9SPaul Traina lastlen[dir][lastconn] = length - (hlen << 2); 2954edb46e9SPaul Traina printf(" %d (%d)", lastlen[dir][lastconn], cp - chdr); 2964edb46e9SPaul Traina } 2974edb46e9SPaul Traina #else 2984edb46e9SPaul Traina #include <sys/types.h> 2994edb46e9SPaul Traina #include <sys/time.h> 3004edb46e9SPaul Traina 3012ebf6c05SBill Fenner #include <pcap.h> 3024edb46e9SPaul Traina #include <stdio.h> 3034edb46e9SPaul Traina 3044edb46e9SPaul Traina #include "interface.h" 305699fc314SBill Fenner 3064edb46e9SPaul Traina void 3074edb46e9SPaul Traina sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) 3084edb46e9SPaul Traina { 3094edb46e9SPaul Traina 3104edb46e9SPaul Traina error("not configured for slip"); 3114edb46e9SPaul Traina /* NOTREACHED */ 3124edb46e9SPaul Traina } 313699fc314SBill Fenner 314699fc314SBill Fenner void 315699fc314SBill Fenner sl_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) 316699fc314SBill Fenner { 317699fc314SBill Fenner 318699fc314SBill Fenner error("not configured for slip"); 319699fc314SBill Fenner /* NOTREACHED */ 320699fc314SBill Fenner } 3214edb46e9SPaul Traina #endif 322