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