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.11 2003/06/03 16:01:01 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 #undef ICMP_MAXTYPE 36 #include <netinet/ip_icmp.h> 37 #include <netinet/ip_var.h> 38 #include <netinet/udp.h> 39 #include <netinet/tcpip.h> 40 41 42 #if !defined(lint) 43 static const char sccsid[] = "@(#)ipft_td.c 1.8 2/4/96 (C)1995 Darren Reed"; 44 static const char rcsid[] = "@(#)$Id: ipft_td.c,v 1.11 2003/06/03 16:01:01 darrenr Exp $"; 45 #endif 46 47 static int tcpd_open __P((char *)); 48 static int tcpd_close __P((void)); 49 static int tcpd_readip __P((char *, int, char **, int *)); 50 static int count_dots __P((char *)); 51 52 struct ipread tcpd = { tcpd_open, tcpd_close, tcpd_readip, 0 }; 53 54 static FILE *tfp = NULL; 55 static int tfd = -1; 56 57 58 static int tcpd_open(fname) 59 char *fname; 60 { 61 if (tfd != -1) 62 return tfd; 63 64 if (!strcmp(fname, "-")) { 65 tfd = 0; 66 tfp = stdin; 67 } else { 68 tfd = open(fname, O_RDONLY); 69 tfp = fdopen(tfd, "r"); 70 } 71 return tfd; 72 } 73 74 75 static int tcpd_close() 76 { 77 (void) fclose(tfp); 78 return close(tfd); 79 } 80 81 82 static int count_dots(str) 83 char *str; 84 { 85 int i = 0; 86 87 while (*str) 88 if (*str++ == '.') 89 i++; 90 return i; 91 } 92 93 94 static int tcpd_readip(buf, cnt, ifn, dir) 95 char *buf, **ifn; 96 int cnt, *dir; 97 { 98 struct tcpiphdr pkt; 99 ip_t *ip = (ip_t *)&pkt; 100 struct protoent *p; 101 char src[32], dst[32], misc[256], time[32], link1[32], link2[32]; 102 char lbuf[160], *s; 103 int n, slen, extra = 0; 104 105 if (!fgets(lbuf, sizeof(lbuf) - 1, tfp)) 106 return 0; 107 108 if ((s = strchr(lbuf, '\n'))) 109 *s = '\0'; 110 lbuf[sizeof(lbuf)-1] = '\0'; 111 112 bzero(&pkt, sizeof(pkt)); 113 114 if ((n = sscanf(lbuf, "%31s > %31s: %255s", src, dst, misc)) != 3) 115 if ((n = sscanf(lbuf, "%31s %31s > %31s: %255s", 116 time, src, dst, misc)) != 4) 117 if ((n = sscanf(lbuf, "%31s %31s: %31s > %31s: %255s", 118 link1, link2, src, dst, misc)) != 5) { 119 n = sscanf(lbuf, 120 "%31s %31s %31s: %31s > %31s: %255s", 121 time, link1, link2, src, dst, misc); 122 if (n != 6) 123 return -1; 124 } 125 126 if (count_dots(dst) == 4) { 127 s = strrchr(src, '.'); 128 *s++ = '\0'; 129 (void) inet_aton(src, &ip->ip_src); 130 pkt.ti_sport = htons(atoi(s)); 131 *--s = '.'; 132 s = strrchr(dst, '.'); 133 134 *s++ = '\0'; 135 (void) inet_aton(src, &ip->ip_dst); 136 pkt.ti_dport = htons(atoi(s)); 137 *--s = '.'; 138 139 } else { 140 (void) inet_aton(src, &ip->ip_src); 141 (void) inet_aton(src, &ip->ip_dst); 142 } 143 ip->ip_len = sizeof(ip_t); 144 IP_HL_A(ip, sizeof(ip_t)); 145 146 s = strtok(misc, " :"); 147 ip->ip_p = getproto(s); 148 149 switch (ip->ip_p) 150 { 151 case IPPROTO_TCP : 152 case IPPROTO_UDP : 153 s = strtok(NULL, " :"); 154 ip->ip_len += atoi(s); 155 if (ip->ip_p == IPPROTO_TCP) 156 extra = sizeof(struct tcphdr); 157 else if (ip->ip_p == IPPROTO_UDP) 158 extra = sizeof(struct udphdr); 159 break; 160 #ifdef IGMP 161 case IPPROTO_IGMP : 162 extra = sizeof(struct igmp); 163 break; 164 #endif 165 case IPPROTO_ICMP : 166 extra = sizeof(struct icmp); 167 break; 168 default : 169 break; 170 } 171 172 slen = IP_HL(ip) + extra + ip->ip_len; 173 return slen; 174 } 175