Add the DragonFly cvs id and perform general cleanups on cvs/rcs/sccs ids. Most
[dragonfly.git] / contrib / ipfilter / ipsend / snit.c
1 /*
2  * (C)opyright 1992-1998 Darren Reed. (from tcplog)
3  *
4  * See the IPFILTER.LICENCE file for details on licencing.
5  */
6
7 #include <stdio.h>
8 #include <netdb.h>
9 #include <ctype.h>
10 #include <signal.h>
11 #include <errno.h>
12 #include <sys/types.h>
13 #include <sys/time.h>
14 #include <sys/timeb.h>
15 #include <sys/socket.h>
16 #include <sys/file.h>
17 #include <sys/ioctl.h>
18 #include <net/nit.h>
19 #include <sys/fcntlcom.h>
20 #include <sys/dir.h>
21 #include <net/nit_if.h>
22 #include <net/nit_pf.h>
23 #include <net/nit_buf.h>
24 #include <net/packetfilt.h>
25 #include <sys/stropts.h>
26
27 #include <net/if.h>
28 #include <netinet/in.h>
29 #include <netinet/in_systm.h>
30 #include <netinet/ip.h>
31 #include <netinet/if_ether.h>
32 #include <netinet/ip_var.h>
33 #include <netinet/udp.h>
34 #include <netinet/udp_var.h>
35 #include <netinet/tcp.h>
36
37 #include "ipsend.h"
38
39 #if !defined(lint)
40 static const char sccsid[] = "@(#)snit.c        1.5 1/11/96 (C)1995 Darren Reed";
41 static const char rcsid[] = "@(#)$Id: snit.c,v 2.1.4.1 2001/06/26 10:43:22 darrenr Exp $";
42 #endif
43
44 #define CHUNKSIZE       8192
45 #define BUFSPACE        (4*CHUNKSIZE)
46
47 /*
48  * Be careful to only include those defined in the flags option for the
49  * interface are included in the header size.
50  */
51 #define BUFHDR_SIZE  (sizeof(struct nit_bufhdr))
52 #define NIT_HDRSIZE  (BUFHDR_SIZE)
53
54 static  int     timeout;
55
56
57 int     initdevice(device, sport, tout)
58 char    *device;
59 int     sport, tout;
60 {
61         struct  strioctl si;
62         struct  timeval to;
63         struct  ifreq ifr;
64         int     fd;
65
66         if ((fd = open("/dev/nit", O_RDWR)) < 0)
67             {
68                 perror("/dev/nit");
69                 exit(-1);
70             }
71
72         /*
73          * arrange to get messages from the NIT STREAM and use NIT_BUF option
74          */
75         ioctl(fd, I_SRDOPT, (char*)RMSGD);
76         ioctl(fd, I_PUSH, "nbuf");
77
78         /*
79          * set the timeout
80          */
81         timeout = tout;
82         si.ic_timout = 1;
83         to.tv_sec = 1;
84         to.tv_usec = 0;
85         si.ic_cmd = NIOCSTIME;
86         si.ic_len = sizeof(to);
87         si.ic_dp = (char*)&to;
88         if (ioctl(fd, I_STR, (char*)&si) == -1)
89             {
90                 perror("ioctl: NIT timeout");
91                 exit(-1);
92             }
93
94         /*
95          * request the interface
96          */
97         strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
98         ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = ' ';
99         si.ic_cmd = NIOCBIND;
100         si.ic_len = sizeof(ifr);
101         si.ic_dp = (char*)&ifr;
102         if (ioctl(fd, I_STR, (char*)&si) == -1)
103             {
104                 perror(ifr.ifr_name);
105                 exit(1);
106             }
107         return fd;
108 }
109
110
111 /*
112  * output an IP packet onto a fd opened for /dev/nit
113  */
114 int     sendip(fd, pkt, len)
115 int     fd, len;
116 char    *pkt;
117 {                       
118         struct  sockaddr sk, *sa = &sk;
119         struct  strbuf  cbuf, *cp = &cbuf, dbuf, *dp = &dbuf;
120
121         /*
122          * For ethernet, need at least 802.3 header and IP header.
123          */
124         if (len < (sizeof(sa->sa_data) + sizeof(struct ip)))
125                 return -1;
126         /*
127          * to avoid any output processing for IP, say we're not.
128          */
129         sa->sa_family = AF_UNSPEC;
130         bcopy(pkt, sa->sa_data, sizeof(sa->sa_data));
131         pkt += sizeof(sa->sa_data);
132         len -= sizeof(sa->sa_data);
133
134         /*
135          * construct NIT STREAMS messages, first control then data.
136          */
137         cp->len = sizeof(*sa);
138         cp->maxlen = sizeof(*sa);
139         cp->buf = (char *)sa;
140
141         dp->buf = pkt;
142         dp->len = len;
143         dp->maxlen = dp->len;
144
145         if (putmsg(fd, cp, dp, 0) == -1)
146             {
147                 perror("putmsg");
148                 return -1;
149             }
150
151         if (ioctl(fd, I_FLUSH, FLUSHW) == -1)
152             {
153                 perror("I_FLUSH");
154                 return -1;
155             }
156         return len;
157 }