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. 204edb46e9SPaul Traina */ 214edb46e9SPaul Traina 224edb46e9SPaul Traina #ifndef lint 232ebf6c05SBill Fenner static const char rcsid[] = 24699fc314SBill Fenner "@(#) $Header: print-sl.c,v 1.42 97/06/12 14:21:35 leres Exp $ (LBL)"; 254edb46e9SPaul Traina #endif 264edb46e9SPaul Traina 274edb46e9SPaul Traina #ifdef HAVE_NET_SLIP_H 284edb46e9SPaul Traina #include <sys/param.h> 294edb46e9SPaul Traina #include <sys/time.h> 304edb46e9SPaul Traina #include <sys/timeb.h> 314edb46e9SPaul Traina #include <sys/file.h> 324edb46e9SPaul Traina #include <sys/ioctl.h> 334edb46e9SPaul Traina #include <sys/mbuf.h> 344edb46e9SPaul Traina #include <sys/socket.h> 354edb46e9SPaul Traina 364edb46e9SPaul Traina #if __STDC__ 374edb46e9SPaul Traina struct rtentry; 384edb46e9SPaul Traina #endif 394edb46e9SPaul Traina #include <net/if.h> 404edb46e9SPaul Traina 414edb46e9SPaul Traina #include <netinet/in.h> 424edb46e9SPaul Traina #include <netinet/in_systm.h> 434edb46e9SPaul Traina #include <netinet/ip.h> 44ee3e7633SGarrett Wollman #include <net/ethernet.h> 454edb46e9SPaul Traina #include <netinet/ip_var.h> 464edb46e9SPaul Traina #include <netinet/udp.h> 474edb46e9SPaul Traina #include <netinet/udp_var.h> 484edb46e9SPaul Traina #include <netinet/tcp.h> 494edb46e9SPaul Traina #include <netinet/tcpip.h> 504edb46e9SPaul Traina 514edb46e9SPaul Traina #include <net/slcompress.h> 524edb46e9SPaul Traina #include <net/slip.h> 534edb46e9SPaul Traina 544edb46e9SPaul Traina #include <ctype.h> 554edb46e9SPaul Traina #include <netdb.h> 564edb46e9SPaul Traina #include <pcap.h> 574edb46e9SPaul Traina #include <stdio.h> 584edb46e9SPaul Traina 594edb46e9SPaul Traina #include "interface.h" 604edb46e9SPaul Traina #include "addrtoname.h" 614edb46e9SPaul Traina #include "extract.h" /* must come after interface.h */ 624edb46e9SPaul Traina 634edb46e9SPaul Traina static u_int lastlen[2][256]; 644edb46e9SPaul Traina static u_int lastconn = 255; 654edb46e9SPaul Traina 664edb46e9SPaul Traina static void sliplink_print(const u_char *, const struct ip *, u_int); 674edb46e9SPaul Traina static void compressed_sl_print(const u_char *, const struct ip *, u_int, int); 684edb46e9SPaul Traina 694edb46e9SPaul Traina /* XXX BSD/OS 2.1 compatibility */ 704edb46e9SPaul Traina #if !defined(SLIP_HDRLEN) && defined(SLC_BPFHDR) 714edb46e9SPaul Traina #define SLIP_HDRLEN SLC_BPFHDR 724edb46e9SPaul Traina #define SLX_DIR 0 734edb46e9SPaul Traina #define SLX_CHDR (SLC_BPFHDRLEN - 1) 744edb46e9SPaul Traina #define CHDR_LEN (SLC_BPFHDR - SLC_BPFHDRLEN) 754edb46e9SPaul Traina #endif 764edb46e9SPaul Traina 77699fc314SBill Fenner /* XXX needs more hacking to work right */ 78699fc314SBill Fenner 794edb46e9SPaul Traina void 804edb46e9SPaul Traina sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) 814edb46e9SPaul Traina { 824edb46e9SPaul Traina register u_int caplen = h->caplen; 834edb46e9SPaul Traina register u_int length = h->len; 844edb46e9SPaul Traina register const struct ip *ip; 854edb46e9SPaul Traina 864edb46e9SPaul Traina ts_print(&h->ts); 874edb46e9SPaul Traina 884edb46e9SPaul Traina if (caplen < SLIP_HDRLEN) { 894edb46e9SPaul Traina printf("[|slip]"); 904edb46e9SPaul Traina goto out; 914edb46e9SPaul Traina } 924edb46e9SPaul Traina /* 934edb46e9SPaul Traina * Some printers want to get back at the link level addresses, 944edb46e9SPaul Traina * and/or check that they're not walking off the end of the packet. 954edb46e9SPaul Traina * Rather than pass them all the way down, we set these globals. 964edb46e9SPaul Traina */ 974edb46e9SPaul Traina packetp = p; 984edb46e9SPaul Traina snapend = p + caplen; 994edb46e9SPaul Traina 1004edb46e9SPaul Traina length -= SLIP_HDRLEN; 1014edb46e9SPaul Traina 1024edb46e9SPaul Traina ip = (struct ip *)(p + SLIP_HDRLEN); 1034edb46e9SPaul Traina 1044edb46e9SPaul Traina if (eflag) 1054edb46e9SPaul Traina sliplink_print(p, ip, length); 1064edb46e9SPaul Traina 1074edb46e9SPaul Traina ip_print((u_char *)ip, length); 1084edb46e9SPaul Traina 1094edb46e9SPaul Traina if (xflag) 1104edb46e9SPaul Traina default_print((u_char *)ip, caplen - SLIP_HDRLEN); 1114edb46e9SPaul Traina out: 1124edb46e9SPaul Traina putchar('\n'); 1134edb46e9SPaul Traina } 1144edb46e9SPaul Traina 115699fc314SBill Fenner 116699fc314SBill Fenner void 117699fc314SBill Fenner sl_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) 118699fc314SBill Fenner { 119699fc314SBill Fenner register u_int caplen = h->caplen; 120699fc314SBill Fenner register u_int length = h->len; 121699fc314SBill Fenner register const struct ip *ip; 122699fc314SBill Fenner 123699fc314SBill Fenner ts_print(&h->ts); 124699fc314SBill Fenner 125699fc314SBill Fenner if (caplen < SLIP_HDRLEN) { 126699fc314SBill Fenner printf("[|slip]"); 127699fc314SBill Fenner goto out; 128699fc314SBill Fenner } 129699fc314SBill Fenner /* 130699fc314SBill Fenner * Some printers want to get back at the link level addresses, 131699fc314SBill Fenner * and/or check that they're not walking off the end of the packet. 132699fc314SBill Fenner * Rather than pass them all the way down, we set these globals. 133699fc314SBill Fenner */ 134699fc314SBill Fenner packetp = p; 135699fc314SBill Fenner snapend = p + caplen; 136699fc314SBill Fenner 137699fc314SBill Fenner length -= SLIP_HDRLEN; 138699fc314SBill Fenner 139699fc314SBill Fenner ip = (struct ip *)(p + SLIP_HDRLEN); 140699fc314SBill Fenner 141699fc314SBill Fenner #ifdef notdef 142699fc314SBill Fenner if (eflag) 143699fc314SBill Fenner sliplink_print(p, ip, length); 144699fc314SBill Fenner #endif 145699fc314SBill Fenner 146699fc314SBill Fenner ip_print((u_char *)ip, length); 147699fc314SBill Fenner 148699fc314SBill Fenner if (xflag) 149699fc314SBill Fenner default_print((u_char *)ip, caplen - SLIP_HDRLEN); 150699fc314SBill Fenner out: 151699fc314SBill Fenner putchar('\n'); 152699fc314SBill Fenner } 153699fc314SBill Fenner 1544edb46e9SPaul Traina static void 1554edb46e9SPaul Traina sliplink_print(register const u_char *p, register const struct ip *ip, 1564edb46e9SPaul Traina register u_int length) 1574edb46e9SPaul Traina { 1584edb46e9SPaul Traina int dir; 1594edb46e9SPaul Traina u_int hlen; 1604edb46e9SPaul Traina 1614edb46e9SPaul Traina dir = p[SLX_DIR]; 1624edb46e9SPaul Traina putchar(dir == SLIPDIR_IN ? 'I' : 'O'); 1634edb46e9SPaul Traina putchar(' '); 1644edb46e9SPaul Traina 1654edb46e9SPaul Traina if (nflag) { 1664edb46e9SPaul Traina /* XXX just dump the header */ 1674edb46e9SPaul Traina register int i; 1684edb46e9SPaul Traina 1694edb46e9SPaul Traina for (i = SLX_CHDR; i < SLX_CHDR + CHDR_LEN - 1; ++i) 1704edb46e9SPaul Traina printf("%02x.", p[i]); 1714edb46e9SPaul Traina printf("%02x: ", p[SLX_CHDR + CHDR_LEN - 1]); 1724edb46e9SPaul Traina return; 1734edb46e9SPaul Traina } 1744edb46e9SPaul Traina switch (p[SLX_CHDR] & 0xf0) { 1754edb46e9SPaul Traina 1764edb46e9SPaul Traina case TYPE_IP: 1774edb46e9SPaul Traina printf("ip %d: ", length + SLIP_HDRLEN); 1784edb46e9SPaul Traina break; 1794edb46e9SPaul Traina 1804edb46e9SPaul Traina case TYPE_UNCOMPRESSED_TCP: 1814edb46e9SPaul Traina /* 1822ebf6c05SBill Fenner * The connection id is stored in the IP protocol field. 1834edb46e9SPaul Traina * Get it from the link layer since sl_uncompress_tcp() 1844edb46e9SPaul Traina * has restored the IP header copy to IPPROTO_TCP. 1854edb46e9SPaul Traina */ 1864edb46e9SPaul Traina lastconn = ((struct ip *)&p[SLX_CHDR])->ip_p; 1874edb46e9SPaul Traina hlen = ip->ip_hl; 1884edb46e9SPaul Traina hlen += ((struct tcphdr *)&((int *)ip)[hlen])->th_off; 1894edb46e9SPaul Traina lastlen[dir][lastconn] = length - (hlen << 2); 1904edb46e9SPaul Traina printf("utcp %d: ", lastconn); 1914edb46e9SPaul Traina break; 1924edb46e9SPaul Traina 1934edb46e9SPaul Traina default: 1944edb46e9SPaul Traina if (p[SLX_CHDR] & TYPE_COMPRESSED_TCP) { 1954edb46e9SPaul Traina compressed_sl_print(&p[SLX_CHDR], ip, 1964edb46e9SPaul Traina length, dir); 1974edb46e9SPaul Traina printf(": "); 1984edb46e9SPaul Traina } else 1994edb46e9SPaul Traina printf("slip-%d!: ", p[SLX_CHDR]); 2004edb46e9SPaul Traina } 2014edb46e9SPaul Traina } 2024edb46e9SPaul Traina 2034edb46e9SPaul Traina static const u_char * 2044edb46e9SPaul Traina print_sl_change(const char *str, register const u_char *cp) 2054edb46e9SPaul Traina { 2064edb46e9SPaul Traina register u_int i; 2074edb46e9SPaul Traina 2084edb46e9SPaul Traina if ((i = *cp++) == 0) { 2094edb46e9SPaul Traina i = EXTRACT_16BITS(cp); 2104edb46e9SPaul Traina cp += 2; 2114edb46e9SPaul Traina } 2124edb46e9SPaul Traina printf(" %s%d", str, i); 2134edb46e9SPaul Traina return (cp); 2144edb46e9SPaul Traina } 2154edb46e9SPaul Traina 2164edb46e9SPaul Traina static const u_char * 2174edb46e9SPaul Traina print_sl_winchange(register const u_char *cp) 2184edb46e9SPaul Traina { 2194edb46e9SPaul Traina register short i; 2204edb46e9SPaul Traina 2214edb46e9SPaul Traina if ((i = *cp++) == 0) { 2224edb46e9SPaul Traina i = EXTRACT_16BITS(cp); 2234edb46e9SPaul Traina cp += 2; 2244edb46e9SPaul Traina } 2254edb46e9SPaul Traina if (i >= 0) 2264edb46e9SPaul Traina printf(" W+%d", i); 2274edb46e9SPaul Traina else 2284edb46e9SPaul Traina printf(" W%d", i); 2294edb46e9SPaul Traina return (cp); 2304edb46e9SPaul Traina } 2314edb46e9SPaul Traina 2324edb46e9SPaul Traina static void 2334edb46e9SPaul Traina compressed_sl_print(const u_char *chdr, const struct ip *ip, 2344edb46e9SPaul Traina u_int length, int dir) 2354edb46e9SPaul Traina { 2364edb46e9SPaul Traina register const u_char *cp = chdr; 2374edb46e9SPaul Traina register u_int flags, hlen; 2384edb46e9SPaul Traina 2394edb46e9SPaul Traina flags = *cp++; 2404edb46e9SPaul Traina if (flags & NEW_C) { 2414edb46e9SPaul Traina lastconn = *cp++; 2424edb46e9SPaul Traina printf("ctcp %d", lastconn); 2434edb46e9SPaul Traina } else 2444edb46e9SPaul Traina printf("ctcp *"); 2454edb46e9SPaul Traina 2464edb46e9SPaul Traina /* skip tcp checksum */ 2474edb46e9SPaul Traina cp += 2; 2484edb46e9SPaul Traina 2494edb46e9SPaul Traina switch (flags & SPECIALS_MASK) { 2504edb46e9SPaul Traina case SPECIAL_I: 2514edb46e9SPaul Traina printf(" *SA+%d", lastlen[dir][lastconn]); 2524edb46e9SPaul Traina break; 2534edb46e9SPaul Traina 2544edb46e9SPaul Traina case SPECIAL_D: 2554edb46e9SPaul Traina printf(" *S+%d", lastlen[dir][lastconn]); 2564edb46e9SPaul Traina break; 2574edb46e9SPaul Traina 2584edb46e9SPaul Traina default: 2594edb46e9SPaul Traina if (flags & NEW_U) 2604edb46e9SPaul Traina cp = print_sl_change("U=", cp); 2614edb46e9SPaul Traina if (flags & NEW_W) 2624edb46e9SPaul Traina cp = print_sl_winchange(cp); 2634edb46e9SPaul Traina if (flags & NEW_A) 2644edb46e9SPaul Traina cp = print_sl_change("A+", cp); 2654edb46e9SPaul Traina if (flags & NEW_S) 2664edb46e9SPaul Traina cp = print_sl_change("S+", cp); 2674edb46e9SPaul Traina break; 2684edb46e9SPaul Traina } 2694edb46e9SPaul Traina if (flags & NEW_I) 2704edb46e9SPaul Traina cp = print_sl_change("I+", cp); 2714edb46e9SPaul Traina 2724edb46e9SPaul Traina /* 2734edb46e9SPaul Traina * 'hlen' is the length of the uncompressed TCP/IP header (in words). 2744edb46e9SPaul Traina * 'cp - chdr' is the length of the compressed header. 2754edb46e9SPaul Traina * 'length - hlen' is the amount of data in the packet. 2764edb46e9SPaul Traina */ 2774edb46e9SPaul Traina hlen = ip->ip_hl; 2784edb46e9SPaul Traina hlen += ((struct tcphdr *)&((int32_t *)ip)[hlen])->th_off; 2794edb46e9SPaul Traina lastlen[dir][lastconn] = length - (hlen << 2); 2804edb46e9SPaul Traina printf(" %d (%d)", lastlen[dir][lastconn], cp - chdr); 2814edb46e9SPaul Traina } 2824edb46e9SPaul Traina #else 2834edb46e9SPaul Traina #include <sys/types.h> 2844edb46e9SPaul Traina #include <sys/time.h> 2854edb46e9SPaul Traina 2862ebf6c05SBill Fenner #include <pcap.h> 2874edb46e9SPaul Traina #include <stdio.h> 2884edb46e9SPaul Traina 2894edb46e9SPaul Traina #include "interface.h" 290699fc314SBill Fenner 2914edb46e9SPaul Traina void 2924edb46e9SPaul Traina sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) 2934edb46e9SPaul Traina { 2944edb46e9SPaul Traina 2954edb46e9SPaul Traina error("not configured for slip"); 2964edb46e9SPaul Traina /* NOTREACHED */ 2974edb46e9SPaul Traina } 298699fc314SBill Fenner 299699fc314SBill Fenner void 300699fc314SBill Fenner sl_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p) 301699fc314SBill Fenner { 302699fc314SBill Fenner 303699fc314SBill Fenner error("not configured for slip"); 304699fc314SBill Fenner /* NOTREACHED */ 305699fc314SBill Fenner } 3064edb46e9SPaul Traina #endif 307