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 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);
414 if (status != ISC_R_SUCCESS)
415 log_fatal (
"Can't register I/O handle for %s: %s",
416 fbi ->
name, isc_result_totext (status));
417 interface_dereference (&fbi,
MDL);
void if_register_send(struct interface_info *)
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 *))
void assemble_udp_ip_header(struct interface_info *, unsigned char *, unsigned *, u_int32_t, u_int32_t, u_int32_t, unsigned char *, unsigned)
int if_readsocket(omapi_object_t *h)
void if_reinitialize_send(struct interface_info *)
char * print_hw_addr(int htype, const int hlen, const unsigned char *data) const
ssize_t decode_udp_ip_header(struct interface_info *, unsigned char *, unsigned, struct sockaddr_in *, unsigned, unsigned *, int)
int can_receive_unicast_unconfigured(struct interface_info *)
int setup_fallback(struct interface_info **fp, const char *file, int line)
int log_error(const char *,...) __attribute__((__format__(__printf__
void if_deregister_receive(struct interface_info *)
void maybe_setup_fallback(void)
void if_deregister_send(struct interface_info *)
void log_fatal(const char *,...) __attribute__((__format__(__printf__
void assemble_hw_header(struct interface_info *, unsigned char *, unsigned *, struct hardware *)
ssize_t send_packet(struct interface_info *, struct packet *, struct dhcp_packet *, size_t, struct in_addr, struct sockaddr_in *, struct hardware *)
struct hardware hw_address
int int log_info(const char *,...) __attribute__((__format__(__printf__
int quiet_interface_discovery
void if_register_fallback(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 supports_multiple_interfaces(struct interface_info *)
u_int8_t hbuf[HARDWARE_ADDR_LEN+1]
struct hardware anycast_mac_addr
ssize_t receive_packet(struct interface_info *, unsigned char *, size_t, struct sockaddr_in *, struct hardware *)
ssize_t decode_hw_header(struct interface_info *, unsigned char *, unsigned, struct hardware *)
void if_reinitialize_receive(struct interface_info *)
int can_unicast_without_arp(struct interface_info *)
void if_register_receive(struct interface_info *)
isc_result_t fallback_discard(omapi_object_t *)