xref: /netbsd-src/external/bsd/ipf/dist/ipsend/snit.c (revision 13885a665959c62f13a82b3caedf986eaa17aa31)
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*)&ifr;
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