31#if defined (USE_NIT_SEND) || defined (USE_NIT_RECEIVE)
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>
69int 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
175#if defined(RELAY_PORT)
176#error "Relay port is not yet supported for NIT"
184 struct packetfilt pf;
190 info -> rfdesc = if_register_nit (info);
195 if (ioctl (info -> rfdesc, NIOCSSNAP, &x) < 0)
196 log_fatal (
"Can't set NIT snap length on %s: %m", info -> name);
199 if (ioctl (info -> rfdesc, I_SRDOPT, RMSGN) != 0)
200 log_info (
"I_SRDOPT failed on %s: %m", info -> name);
204 if (ioctl (info -> rfdesc, I_PUSH,
"nbuf") < 0)
205 log_fatal (
"Can't push chunker onto NIT STREAM: %m");
210 if (ioctl (info -> rfdesc, NIOCSTIME, &t) < 0)
211 log_fatal (
"Can't set chunk timeout: %m");
216 if (ioctl (info -> rfdesc, NIOCSFLAGS, &x) < 0)
217 log_fatal (
"Can't set NIT flags on %s: %m", info -> name);
226 pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + 6;
227 pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT + ENF_CAND;
228 pf.Pf_Filter [pf.Pf_FilterLen++] = htons (
ETHERTYPE_IP);
229 pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT;
230 pf.Pf_Filter [pf.Pf_FilterLen++] = htons (IPPROTO_UDP);
231 pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + 11;
232 pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT + ENF_AND;
233 pf.Pf_Filter [pf.Pf_FilterLen++] = htons (0xFF);
234 pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_CAND;
235 pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + 18;
236 pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT + ENF_CAND;
237 pf.Pf_Filter [pf.Pf_FilterLen++] =
local_port;
240 sio.ic_cmd = NIOCSETF;
241 sio.ic_len =
sizeof pf;
242 sio.ic_dp = (
char *)&pf;
243 sio.ic_timout = INFTIM;
244 if (ioctl (info -> rfdesc, I_STR, &sio) < 0)
245 log_fatal (
"Can't set NIT filter on %s: %m", info -> name);
248 log_info (
"Listening on NIT/%s%s%s",
250 info -> hw_address.hlen - 1,
251 &info -> hw_address.hbuf [1]),
266 log_info (
"Disabling input on NIT/%s%s%s",
283 struct sockaddr_in *to;
286 unsigned hbufp, ibufp;
288 double ih [1536 /
sizeof (double)];
289 unsigned char *buf = (
unsigned char *)ih;
290 struct sockaddr *junk;
291 struct strbuf ctl, data;
292 struct sockaddr_in foo;
295 if (!strcmp (interface -> name,
"fallback"))
303 junk = (
struct sockaddr *)&hh [0];
304 hbufp = (((
unsigned char *)&junk -> sa_data [0]) -
305 (
unsigned char *)&hh[0]);
311 from.s_addr, to -> sin_addr.s_addr,
312 to -> sin_port, (
unsigned char *)raw, len);
315 memcpy (buf + ibufp, raw, len);
319 junk -> sa_len = hbufp - 2;
321 junk -> sa_family = AF_UNSPEC;
324 ctl.buf = (
char *)&hh [0];
325 ctl.maxlen = ctl.len = hbufp;
326 data.buf = (
char *)&ih [0];
327 data.maxlen = data.len = ibufp + len;
329 result = putmsg (interface -> wfdesc, &ctl, &data, 0);
336#ifdef USE_NIT_RECEIVE
341 struct sockaddr_in *from;
347 unsigned char ibuf [1536];
351 length = read (interface -> rfdesc, ibuf,
sizeof ibuf);
370 from, length, &paylen, 1);
383 memcpy(buf, &ibuf[bufix], paylen);
415 log_fatal (
"Can't register I/O handle for %s: %s",
416 fbi ->
name, isc_result_totext (status));
417 interface_dereference (&fbi,
MDL);
char * print_hw_addr(int htype, const int hlen, const unsigned char *data) const
void if_reinitialize_receive(struct interface_info *)
void maybe_setup_fallback(void)
int supports_multiple_interfaces(struct interface_info *)
void if_deregister_send(struct interface_info *)
void assemble_hw_header(struct interface_info *, unsigned char *, unsigned *, struct hardware *)
ssize_t decode_udp_ip_header(struct interface_info *, unsigned char *, unsigned, struct sockaddr_in *, unsigned, unsigned *, int)
void if_reinitialize_send(struct interface_info *)
isc_result_t fallback_discard(omapi_object_t *)
ssize_t send_packet(struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)
void assemble_udp_ip_header(struct interface_info *, unsigned char *, unsigned *, u_int32_t, u_int32_t, u_int32_t, unsigned char *, unsigned)
int can_receive_unicast_unconfigured(struct interface_info *)
ssize_t receive_packet(struct interface_info *, unsigned char *, size_t, struct sockaddr_in *, struct hardware *)
void if_register_receive(struct interface_info *)
ssize_t send_fallback(struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)
int can_unicast_without_arp(struct interface_info *)
void if_deregister_receive(struct interface_info *)
void if_register_fallback(struct interface_info *)
ssize_t decode_hw_header(struct interface_info *, unsigned char *, unsigned, struct hardware *)
void if_register_send(struct interface_info *)
int setup_fallback(struct interface_info **fp, const char *file, int line)
int quiet_interface_discovery
int if_readsocket(omapi_object_t *h)
isc_result_t omapi_register_io_object(omapi_object_t *, int(*)(omapi_object_t *), int(*)(omapi_object_t *), isc_result_t(*)(omapi_object_t *), isc_result_t(*)(omapi_object_t *), isc_result_t(*)(omapi_object_t *))
struct __omapi_object omapi_object_t
int log_error(const char *,...) __attribute__((__format__(__printf__
void log_fatal(const char *,...) __attribute__((__format__(__printf__
int int log_info(const char *,...) __attribute__((__format__(__printf__
u_int8_t hbuf[HARDWARE_ADDR_LEN+1]
struct hardware anycast_mac_addr
struct hardware hw_address