xref: /freebsd/sbin/ipf/ipsend/snit.c (revision 51e16cb8fc536913f490ac6bc9c17e92ebd0411b)
141edb306SCy Schubert 
241edb306SCy Schubert /*
341edb306SCy Schubert  * (C)opyright 1992-1998 Darren Reed. (from tcplog)
441edb306SCy Schubert  *
541edb306SCy Schubert  * See the IPFILTER.LICENCE file for details on licencing.
641edb306SCy Schubert  *
741edb306SCy Schubert  */
841edb306SCy Schubert 
941edb306SCy Schubert #include <stdio.h>
1041edb306SCy Schubert #include <netdb.h>
1141edb306SCy Schubert #include <ctype.h>
1241edb306SCy Schubert #include <signal.h>
1341edb306SCy Schubert #include <errno.h>
1441edb306SCy Schubert #include <sys/types.h>
1541edb306SCy Schubert #include <sys/time.h>
1641edb306SCy Schubert #include <sys/timeb.h>
1741edb306SCy Schubert #include <sys/socket.h>
1841edb306SCy Schubert #include <sys/file.h>
1941edb306SCy Schubert #include <sys/ioctl.h>
2041edb306SCy Schubert #include <net/nit.h>
2141edb306SCy Schubert #include <sys/fcntlcom.h>
2241edb306SCy Schubert #include <sys/dir.h>
2341edb306SCy Schubert #include <net/nit_if.h>
2441edb306SCy Schubert #include <net/nit_pf.h>
2541edb306SCy Schubert #include <net/nit_buf.h>
2641edb306SCy Schubert #include <net/packetfilt.h>
2741edb306SCy Schubert #include <sys/stropts.h>
2841edb306SCy Schubert 
2941edb306SCy Schubert #include <net/if.h>
3041edb306SCy Schubert #include <netinet/in.h>
3141edb306SCy Schubert #include <netinet/in_systm.h>
3241edb306SCy Schubert #include <netinet/ip.h>
3341edb306SCy Schubert #include <netinet/if_ether.h>
3441edb306SCy Schubert #include <netinet/ip_var.h>
3541edb306SCy Schubert #include <netinet/udp.h>
3641edb306SCy Schubert #include <netinet/udp_var.h>
3741edb306SCy Schubert #include <netinet/tcp.h>
3841edb306SCy Schubert 
3941edb306SCy Schubert #include "ipsend.h"
4041edb306SCy Schubert 
4141edb306SCy Schubert 
4241edb306SCy Schubert #define	CHUNKSIZE	8192
4341edb306SCy Schubert #define BUFSPACE	(4*CHUNKSIZE)
4441edb306SCy Schubert 
4541edb306SCy Schubert /*
4641edb306SCy Schubert  * Be careful to only include those defined in the flags option for the
4741edb306SCy Schubert  * interface are included in the header size.
4841edb306SCy Schubert  */
4941edb306SCy Schubert #define BUFHDR_SIZE  (sizeof(struct nit_bufhdr))
5041edb306SCy Schubert #define NIT_HDRSIZE  (BUFHDR_SIZE)
5141edb306SCy Schubert 
5241edb306SCy Schubert static	int	timeout;
5341edb306SCy Schubert 
5441edb306SCy Schubert 
55efeb8bffSCy Schubert int
initdevice(char * device,int tout)56efeb8bffSCy Schubert initdevice(char *device, int tout)
5741edb306SCy Schubert {
5841edb306SCy Schubert 	struct	strioctl si;
5941edb306SCy Schubert 	struct	timeval to;
6041edb306SCy Schubert 	struct	ifreq ifr;
6141edb306SCy Schubert 	int	fd;
6241edb306SCy Schubert 
6341edb306SCy Schubert 	if ((fd = open("/dev/nit", O_RDWR)) < 0)
6441edb306SCy Schubert 	    {
6541edb306SCy Schubert 		perror("/dev/nit");
6641edb306SCy Schubert 		exit(-1);
6741edb306SCy Schubert 	    }
6841edb306SCy Schubert 
6941edb306SCy Schubert 	/*
7041edb306SCy Schubert 	 * arrange to get messages from the NIT STREAM and use NIT_BUF option
7141edb306SCy Schubert 	 */
7241edb306SCy Schubert 	ioctl(fd, I_SRDOPT, (char*)RMSGD);
7341edb306SCy Schubert 	ioctl(fd, I_PUSH, "nbuf");
7441edb306SCy Schubert 
7541edb306SCy Schubert 	/*
7641edb306SCy Schubert 	 * set the timeout
7741edb306SCy Schubert 	 */
7841edb306SCy Schubert 	timeout = tout;
7941edb306SCy Schubert 	si.ic_timout = 1;
8041edb306SCy Schubert 	to.tv_sec = 1;
8141edb306SCy Schubert 	to.tv_usec = 0;
8241edb306SCy Schubert 	si.ic_cmd = NIOCSTIME;
8341edb306SCy Schubert 	si.ic_len = sizeof(to);
8441edb306SCy Schubert 	si.ic_dp = (char*)&to;
8541edb306SCy Schubert 	if (ioctl(fd, I_STR, (char*)&si) == -1)
8641edb306SCy Schubert 	    {
8741edb306SCy Schubert 		perror("ioctl: NIT timeout");
8841edb306SCy Schubert 		exit(-1);
8941edb306SCy Schubert 	    }
9041edb306SCy Schubert 
9141edb306SCy Schubert 	/*
9241edb306SCy Schubert 	 * request the interface
9341edb306SCy Schubert 	 */
9441edb306SCy Schubert 	strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
9541edb306SCy Schubert 	ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = ' ';
9641edb306SCy Schubert 	si.ic_cmd = NIOCBIND;
9741edb306SCy Schubert 	si.ic_len = sizeof(ifr);
9841edb306SCy Schubert 	si.ic_dp = (char*)&ifr;
9941edb306SCy Schubert 	if (ioctl(fd, I_STR, (char*)&si) == -1)
10041edb306SCy Schubert 	    {
10141edb306SCy Schubert 		perror(ifr.ifr_name);
10241edb306SCy Schubert 		exit(1);
10341edb306SCy Schubert 	    }
104*2582ae57SCy Schubert 	return (fd);
10541edb306SCy Schubert }
10641edb306SCy Schubert 
10741edb306SCy Schubert 
10841edb306SCy Schubert /*
10941edb306SCy Schubert  * output an IP packet onto a fd opened for /dev/nit
11041edb306SCy Schubert  */
111efeb8bffSCy Schubert int
112efeb8bffSCy Schubert sendip(int fd, char *pkt, int len)
11341edb306SCy Schubert 	int	fd, len;
11441edb306SCy Schubert 	char	*pkt;
11541edb306SCy Schubert {
11641edb306SCy Schubert 	struct	sockaddr sk, *sa = &sk;
11741edb306SCy Schubert 	struct	strbuf	cbuf, *cp = &cbuf, dbuf, *dp = &dbuf;
11841edb306SCy Schubert 
11941edb306SCy Schubert 	/*
12041edb306SCy Schubert 	 * For ethernet, need at least 802.3 header and IP header.
12141edb306SCy Schubert 	 */
12241edb306SCy Schubert 	if (len < (sizeof(sa->sa_data) + sizeof(struct ip)))
123*2582ae57SCy Schubert 		return (-1);
12441edb306SCy Schubert 	/*
12541edb306SCy Schubert 	 * to avoid any output processing for IP, say we're not.
12641edb306SCy Schubert 	 */
12741edb306SCy Schubert 	sa->sa_family = AF_UNSPEC;
12841edb306SCy Schubert 	bcopy(pkt, sa->sa_data, sizeof(sa->sa_data));
12941edb306SCy Schubert 	pkt += sizeof(sa->sa_data);
13041edb306SCy Schubert 	len -= sizeof(sa->sa_data);
13141edb306SCy Schubert 
13241edb306SCy Schubert 	/*
13341edb306SCy Schubert 	 * construct NIT STREAMS messages, first control then data.
13441edb306SCy Schubert 	 */
13541edb306SCy Schubert 	cp->len = sizeof(*sa);
13641edb306SCy Schubert 	cp->maxlen = sizeof(*sa);
13741edb306SCy Schubert 	cp->buf = (char *)sa;
13841edb306SCy Schubert 
13941edb306SCy Schubert 	dp->buf = pkt;
14041edb306SCy Schubert 	dp->len = len;
14141edb306SCy Schubert 	dp->maxlen = dp->len;
14241edb306SCy Schubert 
14341edb306SCy Schubert 	if (putmsg(fd, cp, dp, 0) == -1)
14441edb306SCy Schubert 	    {
14541edb306SCy Schubert 		perror("putmsg");
146*2582ae57SCy Schubert 		return (-1);
14741edb306SCy Schubert 	    }
14841edb306SCy Schubert 
14941edb306SCy Schubert 	if (ioctl(fd, I_FLUSH, FLUSHW) == -1)
15041edb306SCy Schubert 	    {
15141edb306SCy Schubert 		perror("I_FLUSH");
152*2582ae57SCy Schubert 		return (-1);
15341edb306SCy Schubert 	    }
154*2582ae57SCy Schubert 	return (len);
15541edb306SCy Schubert }
156