30 #if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE)
34 #include <asm/types.h>
35 #include <linux/filter.h>
36 #include <linux/if_ether.h>
37 #include <linux/if_packet.h>
38 #include <netinet/in_systm.h>
44 #if defined (USE_LPF_RECEIVE) || defined (USE_LPF_HWADDR)
45 #include <sys/ioctl.h>
46 #include <sys/socket.h>
51 static unsigned char default_ib_bcast_addr[20] = {
52 0x00, 0xff, 0xff, 0xff,
53 0xff, 0x12, 0x40, 0x1b,
54 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x00,
56 0xff, 0xff, 0xff, 0xff
61 #if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE)
72 #ifdef USE_LPF_RECEIVE
88 struct sockaddr_ll ll;
89 struct sockaddr common;
101 protocol = ETH_P_ALL;
105 if ((sock = socket(PF_PACKET, type, htons((
short)protocol))) < 0) {
106 if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
107 errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
108 errno == EAFNOSUPPORT || errno == EINVAL) {
110 log_error (
"CONFIG_PACKET (Packet socket) %s",
111 "and CONFIG_FILTER");
112 log_error (
"(Socket Filtering) are enabled %s",
119 memset (&ifr, 0,
sizeof ifr);
120 strncpy (ifr.ifr_name, (
const char *)info -> ifp,
sizeof ifr.ifr_name);
121 ifr.ifr_name[IFNAMSIZ-1] =
'\0';
122 if (ioctl (sock, SIOCGIFINDEX, &ifr))
123 log_fatal (
"Failed to get interface index: %m");
126 memset (&sa, 0,
sizeof sa);
127 sa.ll.sll_family = AF_PACKET;
128 sa.ll.sll_protocol = htons(protocol);
129 sa.ll.sll_ifindex = ifr.ifr_ifindex;
130 if (bind (sock, &sa.common,
sizeof sa)) {
131 if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
132 errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
133 errno == EAFNOSUPPORT || errno == EINVAL) {
135 log_error (
"CONFIG_PACKET (Packet socket) %s",
136 "and CONFIG_FILTER");
137 log_error (
"(Socket Filtering) are enabled %s",
141 log_fatal (
"Bind socket to interface: %m");
155 #ifndef USE_LPF_RECEIVE
158 info -> wfdesc = info -> rfdesc;
161 log_info (
"Sending on LPF/%s/%s%s%s",
164 info -> hw_address.hlen - 1,
165 &info -> hw_address.hbuf [1]),
176 #ifndef USE_LPF_RECEIVE
179 close (info -> wfdesc);
183 log_info (
"Disabling output on LPF/%s/%s%s%s",
186 info -> hw_address.hlen - 1,
187 &info -> hw_address.hbuf [1]),
194 #ifdef USE_LPF_RECEIVE
197 extern struct sock_filter dhcp_bpf_filter [];
198 extern int dhcp_bpf_filter_len;
199 extern struct sock_filter dhcp_ib_bpf_filter [];
200 extern int dhcp_ib_bpf_filter_len;
202 #if defined(RELAY_PORT)
203 extern struct sock_filter dhcp_bpf_relay_filter [];
204 extern int dhcp_bpf_relay_filter_len;
207 #if defined (HAVE_TR_SUPPORT)
208 extern struct sock_filter dhcp_bpf_tr_filter [];
209 extern int dhcp_bpf_tr_filter_len;
221 #ifdef PACKET_AUXDATA
225 if (setsockopt(info->rfdesc, SOL_PACKET, PACKET_AUXDATA,
226 &val,
sizeof(val)) < 0) {
227 if (errno != ENOPROTOOPT) {
228 log_fatal (
"Failed to set auxiliary packet data: %m");
236 #if defined (HAVE_TR_SUPPORT)
238 lpf_tr_filter_setup (info);
241 lpf_gen_filter_setup (info);
244 log_info (
"Listening on LPF/%s/%s%s%s",
247 info -> hw_address.hlen - 1,
248 &info -> hw_address.hbuf [1]),
259 close (info -> rfdesc);
262 log_info (
"Disabling input on LPF/%s/%s%s%s",
265 info -> hw_address.hlen - 1,
266 &info -> hw_address.hbuf [1]),
272 static void lpf_gen_filter_setup (info)
277 memset(&
p, 0,
sizeof(
p));
281 p.len = dhcp_bpf_filter_len;
282 p.filter = dhcp_bpf_filter;
287 #if defined(RELAY_PORT)
293 p.len = dhcp_bpf_relay_filter_len;
294 p.filter = dhcp_bpf_relay_filter;
296 dhcp_bpf_relay_filter [10].k = ntohs (
relay_port);
301 if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &
p,
303 if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
304 errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
305 errno == EAFNOSUPPORT) {
307 log_error (
"CONFIG_PACKET (Packet socket) %s",
308 "and CONFIG_FILTER");
309 log_error (
"(Socket Filtering) are enabled %s",
313 log_fatal (
"Can't install packet filter program: %m");
317 #if defined (HAVE_TR_SUPPORT)
318 static void lpf_tr_filter_setup (info)
323 memset(&
p, 0,
sizeof(
p));
327 p.len = dhcp_bpf_tr_filter_len;
328 p.filter = dhcp_bpf_tr_filter;
337 if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &
p,
339 if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
340 errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
341 errno == EAFNOSUPPORT) {
343 log_error (
"CONFIG_PACKET (Packet socket) %s",
344 "and CONFIG_FILTER");
345 log_error (
"(Socket Filtering) are enabled %s",
349 log_fatal (
"Can't install packet filter program: %m");
356 ssize_t send_packet_ib(interface,
packet, raw, len, from, to, hto)
362 struct sockaddr_in *to;
366 double ih [1536 /
sizeof (double)];
367 unsigned char *buf = (
unsigned char *)ih;
372 struct sockaddr_ll sll;
373 struct sockaddr_storage ss;
377 to->sin_addr.s_addr, to->sin_port,
378 (
unsigned char *)raw, len);
379 memcpy (buf + ibufp, raw, len);
381 memset(&su, 0,
sizeof(su));
382 su.sll.sll_family = AF_PACKET;
385 if (!(su.sll.sll_ifindex = if_nametoindex(interface->name))) {
387 log_error (
"send_packet_ib: %m - failed to get if index");
392 su.sll.sll_halen =
sizeof(interface->bcast_addr);
393 memcpy(&su.sll.sll_addr, interface->bcast_addr, 20);
395 result = sendto(interface->wfdesc, buf, ibufp + len, 0,
404 ssize_t
send_packet (interface, packet, raw, len, from, to, hto)
406 struct packet *packet;
410 struct sockaddr_in *to;
413 unsigned hbufp = 0, ibufp = 0;
415 double ih [1536 /
sizeof (double)];
416 unsigned char *buf = (
unsigned char *)ih;
420 if (!strcmp (interface -> name,
"fallback"))
425 return send_packet_ib(interface, packet, raw, len, from,
429 if (hto == NULL && interface->anycast_mac_addr.
hlen)
430 hto = &interface->anycast_mac_addr;
435 memcpy (buf + fudge, (
unsigned char *)hh, hbufp);
436 ibufp = hbufp + fudge;
438 to -> sin_addr.s_addr, to -> sin_port,
439 (
unsigned char *)raw, len);
440 memcpy (buf + ibufp, raw, len);
441 result = write(interface->wfdesc, buf + fudge, ibufp + len - fudge);
448 #ifdef USE_LPF_RECEIVE
449 ssize_t receive_packet_ib (interface, buf, len, from, hfrom)
453 struct sockaddr_in *from;
458 unsigned char ibuf [1536];
462 length = read(interface->rfdesc, ibuf,
sizeof(ibuf));
468 (
unsigned)length, &paylen, 0);
480 memcpy(buf, &ibuf[bufix], paylen);
482 return (ssize_t)paylen;
489 struct sockaddr_in *from;
495 unsigned char ibuf [1536];
500 .iov_len =
sizeof ibuf,
502 #ifdef PACKET_AUXDATA
507 unsigned char cmsgbuf[CMSG_LEN(
sizeof(
struct tpacket_auxdata))];
508 struct msghdr msg = {
511 .msg_control = cmsgbuf,
512 .msg_controllen =
sizeof(cmsgbuf),
515 struct msghdr msg = {
524 return receive_packet_ib(interface, buf, len, from, hfrom);
527 length = recvmsg (interface->rfdesc, &msg, 0);
531 #ifdef PACKET_AUXDATA
550 struct cmsghdr *cmsg;
552 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
553 if (cmsg->cmsg_level == SOL_PACKET &&
554 cmsg->cmsg_type == PACKET_AUXDATA) {
555 struct tpacket_auxdata *aux = (
void *)CMSG_DATA(cmsg);
556 #ifdef VLAN_TCI_PRESENT
559 if (aux->tp_vlan_tci & 0x0fff)
563 csum_ready = ((aux->tp_status & TP_STATUS_CSUMNOTREADY)
587 (
unsigned)length, &paylen, csum_ready);
600 memcpy(buf, &ibuf[bufix], paylen);
632 log_fatal (
"Can't register I/O handle for \"%s\": %s",
633 fbi ->
name, isc_result_totext (status));
634 interface_dereference (&fbi,
MDL);
639 #if defined (USE_LPF_RECEIVE) || defined (USE_LPF_HWADDR)
641 get_ll (
struct ifaddrs *ifaddrs,
struct ifaddrs **ifa,
char *name)
643 for (*ifa = ifaddrs; *ifa != NULL; *ifa = (*ifa)->ifa_next) {
644 if ((*ifa)->ifa_addr == NULL)
647 if ((*ifa)->ifa_addr->sa_family != AF_PACKET)
650 if ((*ifa)->ifa_flags & IFF_LOOPBACK)
653 if (strcmp((*ifa)->ifa_name, name) == 0)
654 return (
struct sockaddr_ll *)(
void *)(*ifa)->ifa_addr;
661 ioctl_get_ll(
char *name)
665 struct sockaddr *sa = NULL;
666 struct sockaddr_ll *sll = NULL;
668 if (strlen(name) >=
sizeof(tmp.ifr_name)) {
669 log_fatal(
"Device name too long: \"%s\"", name);
672 sock = socket(AF_INET, SOCK_DGRAM, 0);
674 log_fatal(
"Can't create socket for \"%s\": %m", name);
677 memset(&tmp, 0,
sizeof(tmp));
678 strcpy(tmp.ifr_name, name);
679 if (ioctl(sock, SIOCGIFHWADDR, &tmp) < 0) {
680 log_fatal(
"Error getting hardware address for \"%s\": %m",
685 sa = &tmp.ifr_hwaddr;
687 sll =
dmalloc (
sizeof (
struct sockaddr_ll),
MDL);
689 log_fatal(
"Unable to allocate memory for link layer address");
690 memcpy(&sll->sll_hatype, &sa->sa_family, sizeof (sll->sll_hatype));
691 memcpy(sll->sll_addr, sa->sa_data, sizeof (sll->sll_addr));
692 switch (sll->sll_hatype) {
693 case ARPHRD_INFINIBAND:
711 log_fatal(
"Unsupported device type for \"%s\"",
720 char *name = info->
name;
721 struct ifaddrs *ifaddrs = NULL;
722 struct ifaddrs *ifa = NULL;
723 struct sockaddr_ll *sll = NULL;
724 int sll_allocated = 0;
729 if (getifaddrs(&ifaddrs) == -1)
732 if ((sll = get_ll(ifaddrs, &ifa, name)) == NULL) {
737 sll = ioctl_get_ll(name);
745 switch (sll->sll_hatype) {
749 memcpy(&hw->
hbuf[1], sll->sll_addr, 6);
752 #ifdef ARPHRD_IEEE802_TR
753 case ARPHRD_IEEE802_TR:
757 memcpy(&hw->
hbuf[1], sll->sll_addr, 6);
762 memcpy(&hw->
hbuf[1], sll->sll_addr, 6);
764 case ARPHRD_INFINIBAND:
771 if ((colon = strchr(dup,
':')) != NULL) {
773 if ((sll = get_ll(ifaddrs, &ifa, dup)) == NULL)
774 log_fatal(
"Error getting hardware address for \"%s\": %m", name);
780 if (ifa && (ifa->ifa_flags & IFF_BROADCAST)) {
781 struct sockaddr_ll *bll;
783 bll = (
struct sockaddr_ll *)ifa->ifa_broadaddr;
786 memcpy(&info->
bcast_addr, default_ib_bcast_addr,
796 #if defined(ARPHRD_PPP)
799 log_fatal(
"local_family != AF_INET6 for \"%s\"",
813 log_error(
"Unsupported device type %hu for \"%s\"",
814 sll->sll_hatype, name);
821 freeifaddrs(ifaddrs);
void if_register_send(struct interface_info *)
void try_hw_addr(struct interface_info *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 *)
log_fatal("no memory for uname information.")
void get_hw_addr(struct interface_info *info)
void maybe_setup_fallback(void)
void if_deregister_send(struct interface_info *)
isc_result_t get_hw_addr2(struct interface_info *info)
void assemble_hw_header(struct interface_info *, unsigned char *, unsigned *, struct hardware *)
int if_register_lpf(struct interface_info *)
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
#define HARDWARE_ADDR_LEN_IOCTL
int int log_info(const char *,...) __attribute__((__format__(__printf__
void * dmalloc(size_t, const char *, int)
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]
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 *)