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