31 #if defined (USE_NIT_SEND) || defined (USE_NIT_RECEIVE)
32 #include <sys/ioctl.h>
37 #include <net/nit_if.h>
38 #include <net/nit_pf.h>
39 #include <net/nit_buf.h>
40 #include <sys/stropts.h>
41 #include <net/packetfilt.h>
43 #include <netinet/in_systm.h>
58 #ifdef USE_NIT_RECEIVE
69 int if_register_nit (info)
78 sock = open (
"/dev/nit", O_RDWR | O_CLOEXEC);
80 log_fatal (
"Can't open NIT device for %s: %m", info -> name);
83 sio.ic_cmd = NIOCBIND;
84 sio.ic_len =
sizeof *(info -> ifp);
85 sio.ic_dp = (
char *)(info -> ifp);
86 sio.ic_timout = INFTIM;
87 if (ioctl (sock, I_STR, &sio) < 0)
88 log_fatal (
"Can't attach interface %s to nit device: %m",
92 sio.ic_cmd = SIOCGIFADDR;
93 sio.ic_len =
sizeof ifr;
94 sio.ic_dp = (
char *)𝔦
95 sio.ic_timout = INFTIM;
96 if (ioctl (sock, I_STR, &sio) < 0)
97 log_fatal (
"Can't get physical layer address for %s: %m",
101 info -> hw_address.hlen = 7;
102 info -> hw_address.hbuf [0] = ARPHRD_ETHER;
103 memcpy (&info -> hw_address.hbuf [1],
104 ifr.ifr_ifru.ifru_addr.sa_data, 6);
106 if (ioctl (sock, I_PUSH,
"pf") < 0)
107 log_fatal (
"Can't push packet filter onto NIT for %s: %m",
120 #ifndef USE_NIT_RECEIVE
121 struct packetfilt pf;
124 info -> wfdesc = if_register_nit (info);
128 pf.Pf_Filter [0] = ENF_PUSHZERO;
131 sio.ic_cmd = NIOCSETF;
132 sio.ic_len =
sizeof pf;
133 sio.ic_dp = (
char *)&pf;
134 sio.ic_timout = INFTIM;
135 if (ioctl (info -> wfdesc, I_STR, &sio) < 0)
138 info -> wfdesc = info -> rfdesc;
143 info -> hw_address.hlen - 1,
144 &info -> hw_address.hbuf [1]),
155 #ifndef USE_NIT_RECEIVE
160 log_info (
"Disabling output on NIT/%s%s%s",
170 #ifdef USE_NIT_RECEIVE
180 struct packetfilt pf;
186 info -> rfdesc = if_register_nit (info);
191 if (ioctl (info -> rfdesc, NIOCSSNAP, &x) < 0)
192 log_fatal (
"Can't set NIT snap length on %s: %m", info -> name);
195 if (ioctl (info -> rfdesc, I_SRDOPT, RMSGN) != 0)
196 log_info (
"I_SRDOPT failed on %s: %m", info -> name);
200 if (ioctl (info -> rfdesc, I_PUSH,
"nbuf") < 0)
201 log_fatal (
"Can't push chunker onto NIT STREAM: %m");
206 if (ioctl (info -> rfdesc, NIOCSTIME, &t) < 0)
207 log_fatal (
"Can't set chunk timeout: %m");
212 if (ioctl (info -> rfdesc, NIOCSFLAGS, &x) < 0)
213 log_fatal (
"Can't set NIT flags on %s: %m", info -> name);
222 pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + 6;
223 pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT + ENF_CAND;
224 pf.Pf_Filter [pf.Pf_FilterLen++] = htons (
ETHERTYPE_IP);
225 pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT;
226 pf.Pf_Filter [pf.Pf_FilterLen++] = htons (IPPROTO_UDP);
227 pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + 11;
228 pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT + ENF_AND;
229 pf.Pf_Filter [pf.Pf_FilterLen++] = htons (0xFF);
230 pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_CAND;
231 pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + 18;
232 pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT + ENF_CAND;
233 pf.Pf_Filter [pf.Pf_FilterLen++] =
local_port;
236 sio.ic_cmd = NIOCSETF;
237 sio.ic_len =
sizeof pf;
238 sio.ic_dp = (
char *)&pf;
239 sio.ic_timout = INFTIM;
240 if (ioctl (info -> rfdesc, I_STR, &sio) < 0)
241 log_fatal (
"Can't set NIT filter on %s: %m", info -> name);
244 log_info (
"Listening on NIT/%s%s%s",
246 info -> hw_address.hlen - 1,
247 &info -> hw_address.hbuf [1]),
262 log_info (
"Disabling input on NIT/%s%s%s",
279 struct sockaddr_in *to;
282 unsigned hbufp, ibufp;
284 double ih [1536 /
sizeof (double)];
285 unsigned char *buf = (
unsigned char *)ih;
286 struct sockaddr *junk;
287 struct strbuf ctl, data;
288 struct sockaddr_in foo;
291 if (!strcmp (interface -> name,
"fallback"))
299 junk = (
struct sockaddr *)&hh [0];
300 hbufp = (((
unsigned char *)&junk -> sa_data [0]) -
301 (
unsigned char *)&hh[0]);
307 from.s_addr, to -> sin_addr.s_addr,
308 to -> sin_port, (
unsigned char *)raw, len);
311 memcpy (buf + ibufp, raw, len);
315 junk -> sa_len = hbufp - 2;
317 junk -> sa_family = AF_UNSPEC;
320 ctl.buf = (
char *)&hh [0];
321 ctl.maxlen = ctl.len = hbufp;
322 data.buf = (
char *)&ih [0];
323 data.maxlen = data.len = ibufp + len;
325 result = putmsg (interface -> wfdesc, &ctl, &data, 0);
332 #ifdef USE_NIT_RECEIVE
337 struct sockaddr_in *from;
343 unsigned char ibuf [1536];
347 length = read (interface -> rfdesc, ibuf,
sizeof ibuf);
366 from, length, &paylen, 1);
379 memcpy(buf, &ibuf[bufix], paylen);
410 if (status != ISC_R_SUCCESS)
411 log_fatal (
"Can't register I/O handle for %s: %s",
412 fbi ->
name, isc_result_totext (status));
413 interface_dereference (&fbi,
MDL);