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