1/*	$FreeBSD: stable/11/contrib/ipfilter/ipsend/sdlpi.c 344833 2019-03-06 02:37:25Z cy $	*/
2
3/*
4 * (C)opyright 1992-1998 Darren Reed. (from tcplog)
5 *
6 * See the IPFILTER.LICENCE file for details on licencing.
7 *
8 */
9
10#include <stdio.h>
11#include <netdb.h>
12#include <ctype.h>
13#include <fcntl.h>
14#include <signal.h>
15#include <errno.h>
16#include <sys/types.h>
17#include <sys/time.h>
18#include <sys/timeb.h>
19#include <sys/socket.h>
20#include <sys/file.h>
21#include <sys/ioctl.h>
22#include <sys/stropts.h>
23
24#ifdef sun
25# include <sys/pfmod.h>
26# include <sys/bufmod.h>
27#endif
28# include <sys/dlpi.h>
29
30#include <net/if.h>
31#include <netinet/in.h>
32#include <netinet/in_systm.h>
33#include <netinet/ip.h>
34#include <netinet/if_ether.h>
35#include <netinet/ip_var.h>
36#include <netinet/udp.h>
37#include <netinet/udp_var.h>
38#include <netinet/tcp.h>
39
40#include "ipsend.h"
41
42#if !defined(lint)
43static const char sccsid[] = "@(#)sdlpi.c	1.3 10/30/95 (C)1995 Darren Reed";
44static const char rcsid[] = "@(#)$Id$";
45#endif
46
47#define	CHUNKSIZE	8192
48#define BUFSPACE	(4*CHUNKSIZE)
49
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 */
55int	initdevice(device, tout)
56	char	*device;
57	int	tout;
58{
59	char	devname[16], *s, buf[256];
60	int	i, fd;
61
62	(void) strcpy(devname, "/dev/");
63	(void) strncat(devname, device, sizeof(devname) - strlen(devname));
64
65	s = devname + 5;
66	while (*s && !ISDIGIT(*s))
67		s++;
68	if (!*s)
69	    {
70		fprintf(stderr, "bad device name %s\n", devname);
71		exit(-1);
72	    }
73	i = atoi(s);
74	*s = '\0';
75	/*
76	 * For writing
77	 */
78	if ((fd = open(devname, O_RDWR)) < 0)
79	    {
80		fprintf(stderr, "O_RDWR(1) ");
81		perror(devname);
82		exit(-1);
83	    }
84
85	if (dlattachreq(fd, i) == -1)
86	    {
87		fprintf(stderr, "dlattachreq: DLPI error\n");
88		exit(-1);
89	    }
90	else if (dlokack(fd, buf) == -1)
91	    {
92		fprintf(stderr, "dlokack(attach): DLPI error\n");
93		exit(-1);
94	    }
95#ifdef DL_HP_RAWDLS
96	if (dlpromisconreq(fd, DL_PROMISC_SAP) < 0)
97	    {
98		fprintf(stderr, "dlpromisconreq: DL_PROMISC_PHYS error\n");
99		exit(-1);
100	    }
101	else if (dlokack(fd, buf) < 0)
102	    {
103		fprintf(stderr, "dlokack(promisc): DLPI error\n");
104		exit(-1);
105	    }
106	/* 22 is INSAP as per the HP-UX DLPI Programmer's Guide */
107
108	dlbindreq(fd, 22, 1, DL_HP_RAWDLS, 0, 0);
109#else
110	dlbindreq(fd, ETHERTYPE_IP, 0, DL_CLDLS, 0, 0);
111#endif
112	dlbindack(fd, buf);
113	/*
114	 * write full headers
115	 */
116#ifdef DLIOCRAW /* we require RAW DLPI mode, which is a Sun extension */
117	if (strioctl(fd, DLIOCRAW, -1, 0, NULL) == -1)
118	    {
119		fprintf(stderr, "DLIOCRAW error\n");
120		exit(-1);
121	    }
122#endif
123	return fd;
124}
125
126
127/*
128 * output an IP packet onto a fd opened for /dev/nit
129 */
130int	sendip(fd, pkt, len)
131	int	fd, len;
132	char	*pkt;
133{
134	struct strbuf dbuf, *dp = &dbuf, *cp = NULL;
135	int pri = 0;
136#ifdef DL_HP_RAWDLS
137	struct strbuf cbuf;
138	dl_hp_rawdata_req_t raw;
139
140	cp = &cbuf;
141	raw.dl_primitive = DL_HP_RAWDATA_REQ;
142	cp->len = sizeof(raw);
143	cp->buf = (char *)&raw;
144	cp->maxlen = cp->len;
145	pri = MSG_HIPRI;
146#endif
147	/*
148	 * construct NIT STREAMS messages, first control then data.
149	 */
150	dp->buf = pkt;
151	dp->len = len;
152	dp->maxlen = dp->len;
153
154	if (putmsg(fd, cp, dp, pri) == -1)
155	    {
156		perror("putmsg");
157		return -1;
158	    }
159	if (ioctl(fd, I_FLUSH, FLUSHW) == -1)
160	    {
161		perror("I_FLUSHW");
162		return -1;
163	    }
164	return len;
165}
166
167