30 #if defined (USE_UPF_SEND) || defined (USE_UPF_RECEIVE) 31 #include <sys/ioctl.h> 34 #include <net/pfilt.h> 35 #include <netinet/in_systm.h> 50 #ifdef USE_UPF_RECEIVE 61 int if_register_upf (info)
72 sprintf(filename,
"/dev/pf/pfilt%d", b);
74 sock = open (filename, O_RDWR | O_CLOEXEC, 0);
87 if (ioctl (sock, EIOCSETIF, info -> ifp) < 0)
88 log_fatal (
"Can't attach interface %s to upf device %s: %m",
89 info -> name, filename);
92 if (ioctl (sock, EIOCDEVP, ¶m) < 0)
93 log_fatal (
"Can't get interface %s hardware address: %m",
97 if (param.end_dev_type != ENDT_10MB)
98 log_fatal (
"Invalid device type on network interface %s: %d",
99 info -> name, param.end_dev_type);
101 if (param.end_addr_len != 6)
102 log_fatal (
"Invalid hardware address length on %s: %d",
103 info -> name, param.end_addr_len);
105 info -> hw_address.hlen = 7;
106 info -> hw_address.hbuf [0] = ARPHRD_ETHER;
107 memcpy (&info -> hw_address.hbuf [1], param.end_addr, 6);
119 #ifndef USE_UPF_RECEIVE 120 info -> wfdesc = if_register_upf (info, interface);
122 info -> wfdesc = info -> rfdesc;
125 log_info (
"Sending on UPF/%s/%s%s%s",
128 info -> hw_address.hlen - 1,
129 &info -> hw_address.hbuf [1]),
138 #ifndef USE_UPF_RECEIVE 139 close (info -> wfdesc);
143 log_info (
"Disabling output on UPF/%s/%s%s%s",
146 info -> hw_address.hlen - 1,
147 &info -> hw_address.hbuf [1]),
154 #ifdef USE_UPF_RECEIVE 169 info -> rfdesc = if_register_upf (info);
172 if (ioctl(info -> rfdesc, EIOCALLOWCOPYALL, &flag) < 0)
173 log_fatal (
"Can't set ALLOWCOPYALL: %m");
176 flag = (ENHOLDSIG | ENBATCH | ENTSTAMP | ENPROMISC |
177 ENNONEXCL | ENCOPYALL);
178 if (ioctl (info -> rfdesc, EIOCMBIC, &flag) < 0)
179 log_fatal (
"Can't clear pfilt bits: %m");
182 bits = ENBATCH | ENCOPYALL;
183 if (ioctl (info -> rfdesc, EIOCMBIS, &bits) < 0)
184 log_fatal (
"Can't set ENBATCH|ENCOPYALL: %m");
191 pf.enf_FilterLen = 0;
193 pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHWORD + 6;
194 pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHLIT + ENF_CAND;
195 pf.enf_Filter [pf.enf_FilterLen++] = htons (
ETHERTYPE_IP);
196 pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHLIT;
197 pf.enf_Filter [pf.enf_FilterLen++] = htons (IPPROTO_UDP);
198 pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHWORD + 11;
199 pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHLIT + ENF_AND;
200 pf.enf_Filter [pf.enf_FilterLen++] = htons (0xFF);
201 pf.enf_Filter [pf.enf_FilterLen++] = ENF_CAND;
202 pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHWORD + 18;
203 pf.enf_Filter [pf.enf_FilterLen++] = ENF_PUSHLIT + ENF_CAND;
204 pf.enf_Filter [pf.enf_FilterLen++] =
local_port;
206 if (ioctl (info -> rfdesc, EIOCSETF, &pf) < 0)
207 log_fatal (
"Can't install packet filter program: %m");
209 log_info (
"Listening on UPF/%s/%s%s%s",
212 info -> hw_address.hlen - 1,
213 &info -> hw_address.hbuf [1]),
222 close (info -> rfdesc);
225 log_info (
"Disabling input on UPF/%s/%s%s%s",
228 info -> hw_address.hlen - 1,
229 &info -> hw_address.hbuf [1]),
243 struct sockaddr_in *to;
246 unsigned hbufp = 0, ibufp = 0;
249 struct iovec iov [3];
253 if (!strcmp (interface -> name,
"fallback"))
257 if (hto == NULL && interface->anycast_mac_addr.
hlen)
258 hto = &interface->anycast_mac_addr;
263 (
unsigned char *)ip, &ibufp, from.s_addr,
264 to -> sin_addr.s_addr, to -> sin_port,
265 (
unsigned char *)raw, len);
268 iov [0].iov_base = ((
char *)hw);
269 iov [0].iov_len = hbufp;
270 iov [1].iov_base = ((
char *)ip);
271 iov [1].iov_len = ibufp;
272 iov [2].iov_base = (
char *)raw;
273 iov [2].iov_len = len;
275 result = writev(interface -> wfdesc, iov, 3);
282 #ifdef USE_UPF_RECEIVE 287 struct sockaddr_in *from;
293 unsigned char ibuf [1500 +
sizeof (
struct enstamp)];
297 length = read (interface -> rfdesc, ibuf,
sizeof ibuf);
301 bufix =
sizeof (
struct enstamp);
317 from, length, &paylen, 1);
330 memcpy (buf, &ibuf[bufix], paylen);
361 if (status != ISC_R_SUCCESS)
362 log_fatal (
"Can't register I/O handle for %s: %s",
363 fbi ->
name, isc_result_totext (status));
364 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 *)
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 *)
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 *)