1 /* 2 * Copyright (c) 1990 The Regents of the University of California. 3 * 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.16 91/04/19 10:46:47 mccanne Exp $ (LBL)"; 25 #endif 26 27 #ifdef CSLIP 28 #include <stdio.h> 29 #include <netdb.h> 30 #include <ctype.h> 31 #include <signal.h> 32 #include <errno.h> 33 #include <sys/param.h> 34 #include <sys/types.h> 35 #include <sys/time.h> 36 /*#include <sys/timeb.h>*/ 37 #include <sys/socket.h> 38 #include <sys/file.h> 39 #include <sys/mbuf.h> 40 #include <sys/ioctl.h> 41 42 #include <net/if.h> 43 #include <netinet/in.h> 44 #include <netinet/in_systm.h> 45 #include <netinet/ip.h> 46 #include <netinet/if_ether.h> 47 #include <netinet/ip_var.h> 48 #include <netinet/udp.h> 49 #include <netinet/udp_var.h> 50 #include <netinet/tcp.h> 51 #include <netinet/tcpip.h> 52 53 #include <net/slcompress.h> 54 #include <net/slip.h> 55 #include <net/bpf.h> 56 57 #include "interface.h" 58 #include "addrtoname.h" 59 60 static int lastlen[2][256]; 61 static int lastconn = 255; 62 63 static void compressed_sl_print(); 64 65 void 66 sl_if_print(p, tvp, length, caplen) 67 u_char *p; 68 struct timeval *tvp; 69 int length; 70 int caplen; 71 { 72 struct ip *ip; 73 74 if (tflag > 0) { 75 int i = (tvp->tv_sec + thiszone) % 86400; 76 (void)printf(timestamp_fmt, 77 i / 3600, (i % 3600) / 60, i % 60, 78 tvp->tv_usec / timestamp_scale); 79 } else if (tflag < 0) 80 printf("%d.%06d ", tvp->tv_sec, tvp->tv_usec); 81 82 if (caplen < SLIP_HDRLEN) { 83 printf("[|slip]"); 84 goto out; 85 } 86 /* 87 * Some printers want to get back at the link level addresses, 88 * and/or check that they're not walking off the end of the packet. 89 * Rather than pass them all the way down, we set these globals. 90 */ 91 packetp = (u_char *)p; 92 snapend = (u_char *)p + caplen; 93 94 length -= SLIP_HDRLEN; 95 96 ip = (struct ip *)(p + SLIP_HDRLEN); 97 98 if (eflag) 99 sliplink_print(p, ip, length); 100 101 ip_print(ip, length); 102 103 if (xflag) 104 default_print((u_short *)ip, caplen - SLIP_HDRLEN); 105 out: 106 putchar('\n'); 107 } 108 109 sliplink_print(p, ip, length) 110 u_char *p; 111 struct ip *ip; 112 int length; 113 { 114 int dir; 115 int hlen; 116 117 dir = p[SLX_DIR]; 118 putchar(dir == SLIPDIR_IN ? 'I' : 'O'); 119 putchar(' '); 120 121 if (nflag) { 122 /* XXX just dump the header */ 123 int i; 124 125 for (i = 0; i < 15; ++i) 126 printf("%02x.", p[SLX_CHDR + i]); 127 printf("%02x: ", p[SLX_CHDR + 15]); 128 return; 129 } 130 switch (p[SLX_CHDR] & 0xf0) { 131 132 case TYPE_IP: 133 printf("ip %d: ", length + SLIP_HDRLEN); 134 break; 135 136 case TYPE_UNCOMPRESSED_TCP: 137 /* 138 * The connection id is stode in the IP protcol field. 139 */ 140 lastconn = ip->ip_p; 141 hlen = ip->ip_hl; 142 hlen += ((struct tcphdr *)&((int *)ip)[hlen])->th_off; 143 lastlen[dir][lastconn] = length - (hlen << 2); 144 printf("utcp %d: ", lastconn); 145 break; 146 147 default: 148 if (p[SLX_CHDR] & TYPE_COMPRESSED_TCP) { 149 compressed_sl_print(&p[SLX_CHDR], ip, length, dir); 150 printf(": "); 151 } else 152 printf("slip-%d!: ", p[SLX_CHDR]); 153 } 154 } 155 156 static u_char * 157 print_sl_change(str, cp) 158 char *str; 159 register u_char *cp; 160 { 161 register u_int i; 162 163 if ((i = *cp++) == 0) { 164 i = (cp[0] << 8) | cp[1]; 165 cp += 2; 166 } 167 printf(" %s%d", str, i); 168 return (cp); 169 } 170 171 static u_char * 172 print_sl_winchange(cp) 173 register u_char *cp; 174 { 175 register short i; 176 177 if ((i = *cp++) == 0) { 178 i = (cp[0] << 8) | cp[1]; 179 cp += 2; 180 } 181 if (i >= 0) 182 printf(" W+%d", i); 183 else 184 printf(" W%d", i); 185 return (cp); 186 } 187 188 static void 189 compressed_sl_print(chdr, ip, length, dir) 190 u_char *chdr; 191 int length; 192 struct ip *ip; 193 int dir; 194 { 195 register u_char *cp = chdr; 196 register u_int flags; 197 int 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 longs). 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 *)&((long *)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 <stdio.h> 244 void 245 sl_if_print() 246 { 247 void error(); 248 249 error("not configured for slip"); 250 /* NOTREACHED */ 251 } 252 #endif 253