home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / tcpdumpb.zip / print-sl.c < prev    next >
C/C++ Source or Header  |  1996-07-16  |  6KB  |  257 lines

  1. /*
  2.  * Copyright (c) 1989, 1990, 1991, 1993, 1994, 1995, 1996
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that: (1) source code distributions
  7.  * retain the above copyright notice and this paragraph in its entirety, (2)
  8.  * distributions including binary code include the above copyright notice and
  9.  * this paragraph in its entirety in the documentation or other materials
  10.  * provided with the distribution, and (3) all advertising materials mentioning
  11.  * features or use of this software display the following acknowledgement:
  12.  * ``This product includes software developed by the University of California,
  13.  * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
  14.  * the University nor the names of its contributors may be used to endorse
  15.  * or promote products derived from this software without specific prior
  16.  * written permission.
  17.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
  18.  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
  19.  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  20.  */
  21.  
  22. #ifndef lint
  23. static  char rcsid[] =
  24.     "@(#)$Header: print-sl.c,v 1.38 96/07/15 18:23:25 leres Exp $ (LBL)";
  25. #endif
  26.  
  27. #ifdef HAVE_NET_SLIP_H
  28. #include <sys/param.h>
  29. #include <sys/time.h>
  30. #include <sys/timeb.h>
  31. #include <sys/file.h>
  32. #include <sys/ioctl.h>
  33. #include <sys/mbuf.h>
  34. #include <sys/socket.h>
  35.  
  36. #if __STDC__
  37. struct rtentry;
  38. #endif
  39. #include <net/if.h>
  40.  
  41. #include <netinet/in.h>
  42. #include <netinet/in_systm.h>
  43. #include <netinet/ip.h>
  44. #include <netinet/if_ether.h>
  45. #include <netinet/ip_var.h>
  46. #include <netinet/udp.h>
  47. #include <netinet/udp_var.h>
  48. #include <netinet/tcp.h>
  49. #include <netinet/tcpip.h>
  50.  
  51. #include <net/slcompress.h>
  52. #include <net/slip.h>
  53.  
  54. #include <ctype.h>
  55. #include <netdb.h>
  56. #include <pcap.h>
  57. #include <signal.h>
  58. #include <stdio.h>
  59.  
  60. #include "interface.h"
  61. #include "addrtoname.h"
  62. #include "extract.h"            /* must come after interface.h */
  63.  
  64. static u_int lastlen[2][256];
  65. static u_int lastconn = 255;
  66.  
  67. static void sliplink_print(const u_char *, const struct ip *, u_int);
  68. static void compressed_sl_print(const u_char *, const struct ip *, u_int, int);
  69.  
  70. /* XXX BSD/OS 2.1 compatibility */
  71. #if !defined(SLIP_HDRLEN) && defined(SLC_BPFHDR)
  72. #define SLIP_HDRLEN SLC_BPFHDR
  73. #define SLX_DIR 0
  74. #define SLX_CHDR (SLC_BPFHDRLEN - 1)
  75. #define CHDR_LEN (SLC_BPFHDR - SLC_BPFHDRLEN)
  76. #endif
  77.  
  78. void
  79. sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
  80. {
  81.     register u_int caplen = h->caplen;
  82.     register u_int length = h->len;
  83.     register const struct ip *ip;
  84.  
  85.     ts_print(&h->ts);
  86.  
  87.     if (caplen < SLIP_HDRLEN) {
  88.         printf("[|slip]");
  89.         goto out;
  90.     }
  91.     /*
  92.      * Some printers want to get back at the link level addresses,
  93.      * and/or check that they're not walking off the end of the packet.
  94.      * Rather than pass them all the way down, we set these globals.
  95.      */
  96.     packetp = p;
  97.     snapend = p + caplen;
  98.  
  99.     length -= SLIP_HDRLEN;
  100.  
  101.     ip = (struct ip *)(p + SLIP_HDRLEN);
  102.  
  103.     if (eflag)
  104.         sliplink_print(p, ip, length);
  105.  
  106.     ip_print((u_char *)ip, length);
  107.  
  108.     if (xflag)
  109.         default_print((u_char *)ip, caplen - SLIP_HDRLEN);
  110.  out:
  111.     putchar('\n');
  112. }
  113.  
  114. static void
  115. sliplink_print(register const u_char *p, register const struct ip *ip,
  116.            register u_int length)
  117. {
  118.     int dir;
  119.     u_int hlen;
  120.  
  121.     dir = p[SLX_DIR];
  122.     putchar(dir == SLIPDIR_IN ? 'I' : 'O');
  123.     putchar(' ');
  124.  
  125.     if (nflag) {
  126.         /* XXX just dump the header */
  127.         register int i;
  128.  
  129.         for (i = SLX_CHDR; i < SLX_CHDR + CHDR_LEN - 1; ++i)
  130.             printf("%02x.", p[i]);
  131.         printf("%02x: ", p[SLX_CHDR + CHDR_LEN - 1]);
  132.         return;
  133.     }
  134.     switch (p[SLX_CHDR] & 0xf0) {
  135.  
  136.     case TYPE_IP:
  137.         printf("ip %d: ", length + SLIP_HDRLEN);
  138.         break;
  139.  
  140.     case TYPE_UNCOMPRESSED_TCP:
  141.         /*
  142.          * The connection id is stored in the IP protcol field.
  143.          * Get it from the link layer since sl_uncompress_tcp()
  144.          * has restored the IP header copy to IPPROTO_TCP.
  145.          */
  146.         lastconn = ((struct ip *)&p[SLX_CHDR])->ip_p;
  147.         hlen = ip->ip_hl;
  148.         hlen += ((struct tcphdr *)&((int *)ip)[hlen])->th_off;
  149.         lastlen[dir][lastconn] = length - (hlen << 2);
  150.         printf("utcp %d: ", lastconn);
  151.         break;
  152.  
  153.     default:
  154.         if (p[SLX_CHDR] & TYPE_COMPRESSED_TCP) {
  155.             compressed_sl_print(&p[SLX_CHDR], ip,
  156.                 length, dir);
  157.             printf(": ");
  158.         } else
  159.             printf("slip-%d!: ", p[SLX_CHDR]);
  160.     }
  161. }
  162.  
  163. static const u_char *
  164. print_sl_change(const char *str, register const u_char *cp)
  165. {
  166.     register u_int i;
  167.  
  168.     if ((i = *cp++) == 0) {
  169.         i = EXTRACT_16BITS(cp);
  170.         cp += 2;
  171.     }
  172.     printf(" %s%d", str, i);
  173.     return (cp);
  174. }
  175.  
  176. static const u_char *
  177. print_sl_winchange(register const u_char *cp)
  178. {
  179.     register short i;
  180.  
  181.     if ((i = *cp++) == 0) {
  182.         i = EXTRACT_16BITS(cp);
  183.         cp += 2;
  184.     }
  185.     if (i >= 0)
  186.         printf(" W+%d", i);
  187.     else
  188.         printf(" W%d", i);
  189.     return (cp);
  190. }
  191.  
  192. static void
  193. compressed_sl_print(const u_char *chdr, const struct ip *ip,
  194.             u_int length, int dir)
  195. {
  196.     register const u_char *cp = chdr;
  197.     register u_int flags, hlen;
  198.  
  199.     flags = *cp++;
  200.     if (flags & NEW_C) {
  201.         lastconn = *cp++;
  202.         printf("ctcp %d", lastconn);
  203.     } else
  204.         printf("ctcp *");
  205.  
  206.     /* skip tcp checksum */
  207.     cp += 2;
  208.  
  209.     switch (flags & SPECIALS_MASK) {
  210.     case SPECIAL_I:
  211.         printf(" *SA+%d", lastlen[dir][lastconn]);
  212.         break;
  213.  
  214.     case SPECIAL_D:
  215.         printf(" *S+%d", lastlen[dir][lastconn]);
  216.         break;
  217.  
  218.     default:
  219.         if (flags & NEW_U)
  220.             cp = print_sl_change("U=", cp);
  221.         if (flags & NEW_W)
  222.             cp = print_sl_winchange(cp);
  223.         if (flags & NEW_A)
  224.             cp = print_sl_change("A+", cp);
  225.         if (flags & NEW_S)
  226.             cp = print_sl_change("S+", cp);
  227.         break;
  228.     }
  229.     if (flags & NEW_I)
  230.         cp = print_sl_change("I+", cp);
  231.  
  232.     /*
  233.      * 'hlen' is the length of the uncompressed TCP/IP header (in words).
  234.      * 'cp - chdr' is the length of the compressed header.
  235.      * 'length - hlen' is the amount of data in the packet.
  236.      */
  237.     hlen = ip->ip_hl;
  238.     hlen += ((struct tcphdr *)&((int32_t *)ip)[hlen])->th_off;
  239.     lastlen[dir][lastconn] = length - (hlen << 2);
  240.     printf(" %d (%d)", lastlen[dir][lastconn], cp - chdr);
  241. }
  242. #else
  243. #include <sys/types.h>
  244. #include <sys/time.h>
  245.  
  246. #include <stdio.h>
  247.  
  248. #include "interface.h"
  249. void
  250. sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
  251. {
  252.  
  253.     error("not configured for slip");
  254.     /* NOTREACHED */
  255. }
  256. #endif
  257.