1 /* 2 * Copyright (C) 1993-2001 by Darren Reed. 3 * 4 * See the IPFILTER.LICENCE file for details on licencing. 5 * 6 * $Id: ipft_td.c,v 1.15 2004/01/08 13:34:31 darrenr Exp $ 7 */ 8 9 /* 10 tcpdump -n 11 12 00:05:47.816843 128.231.76.76.3291 > 224.2.252.231.36573: udp 36 (encap) 13 14 tcpdump -nq 15 16 00:33:48.410771 192.73.213.11.1463 > 224.2.248.153.59360: udp 31 (encap) 17 18 tcpdump -nqt 19 20 128.250.133.13.23 > 128.250.20.20.2419: tcp 27 21 22 tcpdump -nqtt 23 24 123456789.1234567 128.250.133.13.23 > 128.250.20.20.2419: tcp 27 25 26 tcpdump -nqte 27 28 8:0:20:f:65:f7 0:0:c:1:8a:c5 81: 128.250.133.13.23 > 128.250.20.20.2419: tcp 27 29 30 */ 31 32 #include "ipf.h" 33 #include "ipt.h" 34 35 #ifndef linux 36 #include <netinet/ip_var.h> 37 #endif 38 #include <netinet/tcpip.h> 39 40 41 #if !defined(lint) 42 static const char sccsid[] = "@(#)ipft_td.c 1.8 2/4/96 (C)1995 Darren Reed"; 43 static const char rcsid[] = "@(#)$Id: ipft_td.c,v 1.15 2004/01/08 13:34:31 darrenr Exp $"; 44 #endif 45 46 static int tcpd_open __P((char *)); 47 static int tcpd_close __P((void)); 48 static int tcpd_readip __P((char *, int, char **, int *)); 49 static int count_dots __P((char *)); 50 51 struct ipread tcpd = { tcpd_open, tcpd_close, tcpd_readip, 0 }; 52 53 static FILE *tfp = NULL; 54 static int tfd = -1; 55 56 57 static int tcpd_open(fname) 58 char *fname; 59 { 60 if (tfd != -1) 61 return tfd; 62 63 if (!strcmp(fname, "-")) { 64 tfd = 0; 65 tfp = stdin; 66 } else { 67 tfd = open(fname, O_RDONLY); 68 tfp = fdopen(tfd, "r"); 69 } 70 return tfd; 71 } 72 73 74 static int tcpd_close() 75 { 76 (void) fclose(tfp); 77 return close(tfd); 78 } 79 80 81 static int count_dots(str) 82 char *str; 83 { 84 int i = 0; 85 86 while (*str) 87 if (*str++ == '.') 88 i++; 89 return i; 90 } 91 92 93 static int tcpd_readip(buf, cnt, ifn, dir) 94 char *buf, **ifn; 95 int cnt, *dir; 96 { 97 struct tcpiphdr pkt; 98 ip_t *ip = (ip_t *)&pkt; 99 char src[32], dst[32], misc[256], time[32], link1[32], link2[32]; 100 char lbuf[160], *s; 101 int n, slen, extra = 0; 102 103 if (!fgets(lbuf, sizeof(lbuf) - 1, tfp)) 104 return 0; 105 106 if ((s = strchr(lbuf, '\n'))) 107 *s = '\0'; 108 lbuf[sizeof(lbuf)-1] = '\0'; 109 110 bzero(&pkt, sizeof(pkt)); 111 112 if ((n = sscanf(lbuf, "%31s > %31s: %255s", src, dst, misc)) != 3) 113 if ((n = sscanf(lbuf, "%31s %31s > %31s: %255s", 114 time, src, dst, misc)) != 4) 115 if ((n = sscanf(lbuf, "%31s %31s: %31s > %31s: %255s", 116 link1, link2, src, dst, misc)) != 5) { 117 n = sscanf(lbuf, 118 "%31s %31s %31s: %31s > %31s: %255s", 119 time, link1, link2, src, dst, misc); 120 if (n != 6) 121 return -1; 122 } 123 124 if (count_dots(dst) == 4) { 125 s = strrchr(src, '.'); 126 *s++ = '\0'; 127 (void) inet_aton(src, &ip->ip_src); 128 pkt.ti_sport = htons(atoi(s)); 129 *--s = '.'; 130 s = strrchr(dst, '.'); 131 132 *s++ = '\0'; 133 (void) inet_aton(src, &ip->ip_dst); 134 pkt.ti_dport = htons(atoi(s)); 135 *--s = '.'; 136 137 } else { 138 (void) inet_aton(src, &ip->ip_src); 139 (void) inet_aton(src, &ip->ip_dst); 140 } 141 ip->ip_len = sizeof(ip_t); 142 IP_HL_A(ip, sizeof(ip_t)); 143 144 s = strtok(misc, " :"); 145 ip->ip_p = getproto(s); 146 147 switch (ip->ip_p) 148 { 149 case IPPROTO_TCP : 150 case IPPROTO_UDP : 151 s = strtok(NULL, " :"); 152 ip->ip_len += atoi(s); 153 if (ip->ip_p == IPPROTO_TCP) 154 extra = sizeof(struct tcphdr); 155 else if (ip->ip_p == IPPROTO_UDP) 156 extra = sizeof(struct udphdr); 157 break; 158 #ifdef IGMP 159 case IPPROTO_IGMP : 160 extra = sizeof(struct igmp); 161 break; 162 #endif 163 case IPPROTO_ICMP : 164 extra = sizeof(struct icmp); 165 break; 166 default : 167 break; 168 } 169 170 slen = IP_HL(ip) + extra + ip->ip_len; 171 return slen; 172 } 173