]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/tcpdump/print-sl.c
This commit was generated by cvs2svn to compensate for changes in r56915,
[FreeBSD/FreeBSD.git] / contrib / tcpdump / print-sl.c
1 /*
2  * Copyright (c) 1989, 1990, 1991, 1993, 1994, 1995, 1996, 1997
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  * $FreeBSD$
22  */
23
24 #ifndef lint
25 static const char rcsid[] =
26     "@(#) $Header: /tcpdump/master/tcpdump/print-sl.c,v 1.46 1999/11/21 12:38:24 itojun Exp $ (LBL)";
27 #endif
28
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32
33 #ifdef HAVE_NET_SLIP_H
34 #include <sys/param.h>
35 #include <sys/time.h>
36 #include <sys/timeb.h>
37 #include <sys/file.h>
38 #include <sys/ioctl.h>
39 #include <sys/mbuf.h>
40 #include <sys/socket.h>
41
42 #if __STDC__
43 struct rtentry;
44 #endif
45 #include <net/if.h>
46
47 #include <netinet/in.h>
48 #include <netinet/in_systm.h>
49 #include <netinet/ip.h>
50 #include <net/ethernet.h>
51 #include <netinet/ip_var.h>
52 #include <netinet/udp.h>
53 #include <netinet/tcp.h>
54
55 #include <net/slcompress.h>
56 #include <net/slip.h>
57
58 #include <ctype.h>
59 #include <netdb.h>
60 #include <pcap.h>
61 #include <stdio.h>
62
63 #include "interface.h"
64 #include "addrtoname.h"
65 #include "extract.h"                    /* must come after interface.h */
66
67 static u_int lastlen[2][256];
68 static u_int lastconn = 255;
69
70 static void sliplink_print(const u_char *, const struct ip *, u_int);
71 static void compressed_sl_print(const u_char *, const struct ip *, u_int, int);
72
73 /* XXX BSD/OS 2.1 compatibility */
74 #if !defined(SLIP_HDRLEN) && defined(SLC_BPFHDR)
75 #define SLIP_HDRLEN SLC_BPFHDR
76 #define SLX_DIR 0
77 #define SLX_CHDR (SLC_BPFHDRLEN - 1)
78 #define CHDR_LEN (SLC_BPFHDR - SLC_BPFHDRLEN)
79 #endif
80
81 /* XXX needs more hacking to work right */
82
83 void
84 sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
85 {
86         register u_int caplen = h->caplen;
87         register u_int length = h->len;
88         register const struct ip *ip;
89
90         ts_print(&h->ts);
91
92         if (caplen < SLIP_HDRLEN) {
93                 printf("[|slip]");
94                 goto out;
95         }
96         /*
97          * Some printers want to get back at the link level addresses,
98          * and/or check that they're not walking off the end of the packet.
99          * Rather than pass them all the way down, we set these globals.
100          */
101         packetp = p;
102         snapend = p + caplen;
103
104         length -= SLIP_HDRLEN;
105
106         ip = (struct ip *)(p + SLIP_HDRLEN);
107
108         if (eflag)
109                 sliplink_print(p, ip, length);
110
111         switch (ip->ip_v) {
112         case 4:
113                 ip_print((u_char *)ip, length);
114                 break;
115 #ifdef INET6
116         case 6:
117                 ip6_print((u_char *)ip, length);
118                 break;
119 #endif
120         default:
121                 printf ("ip v%d", ip->ip_v);
122         }
123
124         if (xflag)
125                 default_print((u_char *)ip, caplen - SLIP_HDRLEN);
126  out:
127         putchar('\n');
128 }
129
130
131 void
132 sl_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
133 {
134         register u_int caplen = h->caplen;
135         register u_int length = h->len;
136         register const struct ip *ip;
137
138         ts_print(&h->ts);
139
140         if (caplen < SLIP_HDRLEN) {
141                 printf("[|slip]");
142                 goto out;
143         }
144         /*
145          * Some printers want to get back at the link level addresses,
146          * and/or check that they're not walking off the end of the packet.
147          * Rather than pass them all the way down, we set these globals.
148          */
149         packetp = p;
150         snapend = p + caplen;
151
152         length -= SLIP_HDRLEN;
153
154         ip = (struct ip *)(p + SLIP_HDRLEN);
155
156 #ifdef notdef
157         if (eflag)
158                 sliplink_print(p, ip, length);
159 #endif
160
161         ip_print((u_char *)ip, length);
162
163         if (xflag)
164                 default_print((u_char *)ip, caplen - SLIP_HDRLEN);
165  out:
166         putchar('\n');
167 }
168
169 static void
170 sliplink_print(register const u_char *p, register const struct ip *ip,
171                register u_int length)
172 {
173         int dir;
174         u_int hlen;
175
176         dir = p[SLX_DIR];
177         putchar(dir == SLIPDIR_IN ? 'I' : 'O');
178         putchar(' ');
179
180         if (nflag) {
181                 /* XXX just dump the header */
182                 register int i;
183
184                 for (i = SLX_CHDR; i < SLX_CHDR + CHDR_LEN - 1; ++i)
185                         printf("%02x.", p[i]);
186                 printf("%02x: ", p[SLX_CHDR + CHDR_LEN - 1]);
187                 return;
188         }
189         switch (p[SLX_CHDR] & 0xf0) {
190
191         case TYPE_IP:
192                 printf("ip %d: ", length + SLIP_HDRLEN);
193                 break;
194
195         case TYPE_UNCOMPRESSED_TCP:
196                 /*
197                  * The connection id is stored in the IP protocol field.
198                  * Get it from the link layer since sl_uncompress_tcp()
199                  * has restored the IP header copy to IPPROTO_TCP.
200                  */
201                 lastconn = ((struct ip *)&p[SLX_CHDR])->ip_p;
202                 hlen = ip->ip_hl;
203                 hlen += ((struct tcphdr *)&((int *)ip)[hlen])->th_off;
204                 lastlen[dir][lastconn] = length - (hlen << 2);
205                 printf("utcp %d: ", lastconn);
206                 break;
207
208         default:
209                 if (p[SLX_CHDR] & TYPE_COMPRESSED_TCP) {
210                         compressed_sl_print(&p[SLX_CHDR], ip,
211                             length, dir);
212                         printf(": ");
213                 } else
214                         printf("slip-%d!: ", p[SLX_CHDR]);
215         }
216 }
217
218 static const u_char *
219 print_sl_change(const char *str, register const u_char *cp)
220 {
221         register u_int i;
222
223         if ((i = *cp++) == 0) {
224                 i = EXTRACT_16BITS(cp);
225                 cp += 2;
226         }
227         printf(" %s%d", str, i);
228         return (cp);
229 }
230
231 static const u_char *
232 print_sl_winchange(register const u_char *cp)
233 {
234         register short i;
235
236         if ((i = *cp++) == 0) {
237                 i = EXTRACT_16BITS(cp);
238                 cp += 2;
239         }
240         if (i >= 0)
241                 printf(" W+%d", i);
242         else
243                 printf(" W%d", i);
244         return (cp);
245 }
246
247 static void
248 compressed_sl_print(const u_char *chdr, const struct ip *ip,
249                     u_int length, int dir)
250 {
251         register const u_char *cp = chdr;
252         register u_int flags, hlen;
253
254         flags = *cp++;
255         if (flags & NEW_C) {
256                 lastconn = *cp++;
257                 printf("ctcp %d", lastconn);
258         } else
259                 printf("ctcp *");
260
261         /* skip tcp checksum */
262         cp += 2;
263
264         switch (flags & SPECIALS_MASK) {
265         case SPECIAL_I:
266                 printf(" *SA+%d", lastlen[dir][lastconn]);
267                 break;
268
269         case SPECIAL_D:
270                 printf(" *S+%d", lastlen[dir][lastconn]);
271                 break;
272
273         default:
274                 if (flags & NEW_U)
275                         cp = print_sl_change("U=", cp);
276                 if (flags & NEW_W)
277                         cp = print_sl_winchange(cp);
278                 if (flags & NEW_A)
279                         cp = print_sl_change("A+", cp);
280                 if (flags & NEW_S)
281                         cp = print_sl_change("S+", cp);
282                 break;
283         }
284         if (flags & NEW_I)
285                 cp = print_sl_change("I+", cp);
286
287         /*
288          * 'hlen' is the length of the uncompressed TCP/IP header (in words).
289          * 'cp - chdr' is the length of the compressed header.
290          * 'length - hlen' is the amount of data in the packet.
291          */
292         hlen = ip->ip_hl;
293         hlen += ((struct tcphdr *)&((int32_t *)ip)[hlen])->th_off;
294         lastlen[dir][lastconn] = length - (hlen << 2);
295         printf(" %d (%d)", lastlen[dir][lastconn], cp - chdr);
296 }
297 #else
298 #include <sys/types.h>
299 #include <sys/time.h>
300
301 #include <pcap.h>
302 #include <stdio.h>
303
304 #include "interface.h"
305
306 void
307 sl_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
308 {
309
310         error("not configured for slip");
311         /* NOTREACHED */
312 }
313
314 void
315 sl_bsdos_if_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
316 {
317
318         error("not configured for slip");
319         /* NOTREACHED */
320 }
321 #endif