Merge from vendor branch NTPD:
[dragonfly.git] / contrib / ipfilter / ipft_ef.c
1 /*
2  * Copyright (C) 1993-2001 by Darren Reed.
3  *
4  * See the IPFILTER.LICENCE file for details on licencing.
5  */
6
7 /*
8                                             icmp type
9  lnth proto         source     destination   src port   dst port
10
11 etherfind -n
12
13    60  tcp   128.250.20.20  128.250.133.13       2419     telnet
14
15 etherfind -n -t
16
17  0.32    91   04    131.170.1.10  128.250.133.13
18  0.33   566  udp  128.250.37.155   128.250.133.3        901        901
19 */
20 #if defined(__sgi) && (IRIX > 602)
21 # include <sys/ptimers.h>
22 #endif
23 #include <stdio.h>
24 #include <string.h>
25 #if !defined(__SVR4) && !defined(__GNUC__)
26 #include <strings.h>
27 #endif
28 #include <sys/types.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <stddef.h>
32 #include <sys/socket.h>
33 #include <sys/ioctl.h>
34 #include <sys/param.h>
35 #include <sys/time.h>
36 #include <netinet/in.h>
37 #include <arpa/inet.h>
38 #include <netinet/in_systm.h>
39 #ifndef linux
40 #include <netinet/ip_var.h>
41 #endif
42 #include <netinet/ip.h>
43 #include <netinet/tcp.h>
44 #include <netinet/udp.h>
45 #include <netinet/ip_icmp.h>
46 #include <net/if.h>
47 #include <netdb.h>
48 #include "ip_compat.h"
49 #include <netinet/tcpip.h>
50 #include "ipf.h"
51 #include "ipt.h"
52
53 #if !defined(lint)
54 static const char sccsid[] = "@(#)ipft_ef.c     1.6 2/4/96 (C)1995 Darren Reed";
55 static const char rcsid[] = "@(#)$Id: ipft_ef.c,v 2.2.2.5 2003/05/19 12:02:35 darrenr Exp $";
56 #endif
57
58 static  int     etherf_open __P((char *));
59 static  int     etherf_close __P((void));
60 static  int     etherf_readip __P((char *, int, char **, int *));
61
62 struct  ipread  etherf = { etherf_open, etherf_close, etherf_readip };
63
64 static  FILE    *efp = NULL;
65 static  int     efd = -1;
66
67
68 static  int     etherf_open(fname)
69 char    *fname;
70 {
71         if (efd != -1)
72                 return efd;
73
74         if (!strcmp(fname, "-")) {
75                 efd = 0;
76                 efp = stdin;
77         } else {
78                 efd = open(fname, O_RDONLY);
79                 efp = fdopen(efd, "r");
80         }
81         return efd;
82 }
83
84
85 static  int     etherf_close()
86 {
87         return close(efd);
88 }
89
90
91 static  int     etherf_readip(buf, cnt, ifn, dir)
92 char    *buf, **ifn;
93 int     cnt, *dir;
94 {
95         struct  tcpiphdr pkt;
96         ip_t    *ip = (ip_t *)&pkt;
97         struct  protoent *p = NULL;
98         char    src[16], dst[16], sprt[16], dprt[16];
99         char    lbuf[128], len[8], prot[8], time[8], *s;
100         int     slen, extra = 0, i;
101
102         if (!fgets(lbuf, sizeof(lbuf) - 1, efp))
103                 return 0;
104
105         if ((s = strchr(lbuf, '\n')))
106                 *s = '\0';
107         lbuf[sizeof(lbuf)-1] = '\0';
108
109         bzero(&pkt, sizeof(pkt));
110
111         if (sscanf(lbuf, "%7s %7s %15s %15s %15s %15s", len, prot, src, dst,
112                    sprt, dprt) != 6)
113                 if (sscanf(lbuf, "%7s %7s %7s %15s %15s %15s %15s", time,
114                            len, prot, src, dst, sprt, dprt) != 7)
115                         return -1;
116
117         ip->ip_p = atoi(prot);
118         if (ip->ip_p == 0) {
119                 if (!(p = getprotobyname(prot)))
120                         return -1;
121                 ip->ip_p = p->p_proto;
122         }
123
124         switch (ip->ip_p) {
125         case IPPROTO_TCP :
126         case IPPROTO_UDP :
127                 s = strtok(NULL, " :");
128                 ip->ip_len += atoi(s);
129                 if (p->p_proto == IPPROTO_TCP)
130                         extra = sizeof(struct tcphdr);
131                 else if (p->p_proto == IPPROTO_UDP)
132                         extra = sizeof(struct udphdr);
133                 break;
134 #ifdef  IGMP
135         case IPPROTO_IGMP :
136                 extra = sizeof(struct igmp);
137                 break;
138 #endif
139         case IPPROTO_ICMP :
140                 extra = sizeof(struct icmp);
141                 break;
142         default :
143                 break;
144         }
145
146         (void) inet_aton(src, &ip->ip_src);
147         (void) inet_aton(dst, &ip->ip_dst);
148         ip->ip_len = atoi(len);
149         ip->ip_hl = sizeof(ip_t);
150
151         slen = ip->ip_hl + extra;
152         i = MIN(cnt, slen);
153         bcopy((char *)&pkt, buf, i);
154         return i;
155 }