31 #if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE) 32 #include <sys/socket.h> 36 #include <asm/types.h> 37 #include <linux/filter.h> 38 #include <linux/if_ether.h> 39 #include <linux/if_packet.h> 40 #include <netinet/in_systm.h> 46 #if defined (USE_LPF_RECEIVE) || defined (USE_LPF_HWADDR) 47 #include <sys/ioctl.h> 52 static unsigned char default_ib_bcast_addr[20] = {
53 0x00, 0xff, 0xff, 0xff,
54 0xff, 0x12, 0x40, 0x1b,
55 0x00, 0x00, 0x00, 0x00,
56 0x00, 0x00, 0x00, 0x00,
57 0xff, 0xff, 0xff, 0xff
62 #if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE) 66 #ifndef PACKET_AUXDATA 67 #define PACKET_AUXDATA 8 69 struct tpacket_auxdata
86 #ifdef USE_LPF_RECEIVE 102 struct sockaddr_ll ll;
103 struct sockaddr common;
117 protocol = ETH_P_ALL;
120 if ((sock = socket(PF_PACKET, type, htons((
short)protocol))) < 0) {
121 if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
122 errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
123 errno == EAFNOSUPPORT || errno == EINVAL) {
125 log_error (
"CONFIG_PACKET (Packet socket) %s",
126 "and CONFIG_FILTER");
127 log_error (
"(Socket Filtering) are enabled %s",
134 memset (&ifr, 0,
sizeof ifr);
135 strncpy (ifr.ifr_name, (
const char *)info -> ifp,
sizeof ifr.ifr_name);
136 ifr.ifr_name[IFNAMSIZ-1] =
'\0';
137 if (ioctl (sock, SIOCGIFINDEX, &ifr))
138 log_fatal (
"Failed to get interface index: %m");
141 memset (&sa, 0,
sizeof sa);
142 sa.ll.sll_family = AF_PACKET;
143 sa.ll.sll_protocol = htons(protocol);
144 sa.ll.sll_ifindex = ifr.ifr_ifindex;
145 if (bind (sock, &sa.common,
sizeof sa)) {
146 if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
147 errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
148 errno == EAFNOSUPPORT || errno == EINVAL) {
150 log_error (
"CONFIG_PACKET (Packet socket) %s",
151 "and CONFIG_FILTER");
152 log_error (
"(Socket Filtering) are enabled %s",
156 log_fatal (
"Bind socket to interface: %m");
171 #ifndef USE_LPF_RECEIVE 181 log_info (
"Sending on LPF/%s/%s%s%s",
200 #ifndef USE_LPF_RECEIVE 207 log_info (
"Disabling output on LPF/%s/%s%s%s",
218 #ifdef USE_LPF_RECEIVE 221 extern struct sock_filter dhcp_bpf_filter [];
222 extern int dhcp_bpf_filter_len;
223 extern struct sock_filter dhcp_ib_bpf_filter [];
224 extern int dhcp_ib_bpf_filter_len;
226 #if defined (HAVE_TR_SUPPORT) 227 extern struct sock_filter dhcp_bpf_tr_filter [];
228 extern int dhcp_bpf_tr_filter_len;
244 if (setsockopt (info ->
rfdesc, SOL_PACKET, PACKET_AUXDATA,
245 &val,
sizeof val) < 0) {
246 if (errno != ENOPROTOOPT)
247 log_fatal (
"Failed to set auxiliary packet data: %m");
253 #if defined (HAVE_TR_SUPPORT) 255 lpf_tr_filter_setup (info);
258 lpf_gen_filter_setup (info);
261 log_info (
"Listening on LPF/%s/%s%s%s",
283 log_info (
"Disabling input on LPF/%s/%s%s%s",
293 static void lpf_gen_filter_setup (info)
298 memset(&p, 0,
sizeof(p));
302 p.len = dhcp_ib_bpf_filter_len;
303 p.filter = dhcp_ib_bpf_filter;
310 dhcp_ib_bpf_filter[6].k = ntohs ((
short)
local_port);
314 p.len = dhcp_bpf_filter_len;
315 p.filter = dhcp_bpf_filter;
320 dhcp_bpf_filter [8].k = ntohs ((
short)
local_port);
323 if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
325 if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
326 errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
327 errno == EAFNOSUPPORT) {
329 log_error (
"CONFIG_PACKET (Packet socket) %s",
330 "and CONFIG_FILTER");
331 log_error (
"(Socket Filtering) are enabled %s",
335 log_fatal (
"Can't install packet filter program: %m");
339 #if defined (HAVE_TR_SUPPORT) 340 static void lpf_tr_filter_setup (info)
345 memset(&p, 0,
sizeof(p));
349 p.len = dhcp_bpf_tr_filter_len;
350 p.filter = dhcp_bpf_tr_filter;
359 if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
361 if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
362 errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
363 errno == EAFNOSUPPORT) {
365 log_error (
"CONFIG_PACKET (Packet socket) %s",
366 "and CONFIG_FILTER");
367 log_error (
"(Socket Filtering) are enabled %s",
371 log_fatal (
"Can't install packet filter program: %m");
378 ssize_t send_packet_ib(interface,
packet, raw, len, from, to, hto)
384 struct sockaddr_in *to;
388 double ih [1536 /
sizeof (double)];
389 unsigned char *buf = (
unsigned char *)ih;
394 struct sockaddr_ll sll;
395 struct sockaddr_storage ss;
399 to->sin_addr.s_addr, to->sin_port,
400 (
unsigned char *)raw, len);
401 memcpy (buf + ibufp, raw, len);
403 memset(&su, 0,
sizeof(su));
404 su.sll.sll_family = AF_PACKET;
407 if (!(su.sll.sll_ifindex = if_nametoindex(interface->
name))) {
409 log_error (
"send_packet_ib: %m - failed to get if index");
414 su.sll.sll_halen =
sizeof(interface->
bcast_addr);
415 memcpy(&su.sll.sll_addr, interface->
bcast_addr, 20);
417 result = sendto(interface->
wfdesc, buf, ibufp + len, 0,
426 ssize_t
send_packet (interface, packet, raw, len, from, to, hto)
428 struct packet *packet;
432 struct sockaddr_in *to;
435 unsigned hbufp = 0, ibufp = 0;
437 double ih [1536 /
sizeof (double)];
438 unsigned char *buf = (
unsigned char *)ih;
442 if (!strcmp (interface -> name,
"fallback"))
447 return send_packet_ib(interface, packet, raw, len, from,
457 memcpy (buf + fudge, (
unsigned char *)hh, hbufp);
458 ibufp = hbufp + fudge;
460 to -> sin_addr.s_addr, to -> sin_port,
461 (
unsigned char *)raw, len);
462 memcpy (buf + ibufp, raw, len);
464 result = write (interface -> wfdesc, buf + fudge, ibufp + len - fudge);
471 #ifdef USE_LPF_RECEIVE 472 ssize_t receive_packet_ib (interface, buf, len, from, hfrom)
476 struct sockaddr_in *from;
481 unsigned char ibuf [1536];
485 length = read(interface->
rfdesc, ibuf,
sizeof(ibuf));
491 (
unsigned)length, &paylen, 0);
503 memcpy(buf, &ibuf[bufix], paylen);
505 return (ssize_t)paylen;
512 struct sockaddr_in *from;
518 unsigned char ibuf [1536];
521 unsigned char cmsgbuf[CMSG_LEN(
sizeof(
struct tpacket_auxdata))];
524 .iov_len =
sizeof ibuf,
526 struct msghdr msg = {
529 .msg_control = cmsgbuf,
530 .msg_controllen =
sizeof(cmsgbuf),
532 struct cmsghdr *cmsg;
535 return receive_packet_ib(interface, buf, len, from, hfrom);
538 length = recvmsg (interface -> rfdesc, &msg, 0);
542 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
543 if (cmsg->cmsg_level == SOL_PACKET &&
544 cmsg->cmsg_type == PACKET_AUXDATA) {
545 struct tpacket_auxdata *aux = (
void *)CMSG_DATA(cmsg);
546 nocsum = aux->tp_status & TP_STATUS_CSUMNOTREADY;
566 (
unsigned)length, &paylen, nocsum);
579 memcpy(buf, &ibuf[bufix], paylen);
610 if (status != ISC_R_SUCCESS)
611 log_fatal (
"Can't register I/O handle for \"%s\": %s",
612 fbi ->
name, isc_result_totext (status));
613 interface_dereference (&fbi,
MDL);
618 #if defined (USE_LPF_RECEIVE) || defined (USE_LPF_HWADDR) 620 get_ll (
struct ifaddrs *ifaddrs,
struct ifaddrs **ifa,
char *name)
622 for (*ifa = ifaddrs; *ifa != NULL; *ifa = (*ifa)->ifa_next) {
623 if ((*ifa)->ifa_addr == NULL)
626 if ((*ifa)->ifa_addr->sa_family != AF_PACKET)
629 if ((*ifa)->ifa_flags & IFF_LOOPBACK)
632 if (strcmp((*ifa)->ifa_name, name) == 0)
633 return (
struct sockaddr_ll *)(
void *)(*ifa)->ifa_addr;
640 ioctl_get_ll(
char *name)
644 struct sockaddr *sa = NULL;
645 struct sockaddr_ll *sll = NULL;
647 if (strlen(name) >=
sizeof(tmp.ifr_name)) {
648 log_fatal(
"Device name too long: \"%s\"", name);
651 sock = socket(AF_INET, SOCK_DGRAM, 0);
653 log_fatal(
"Can't create socket for \"%s\": %m", name);
656 memset(&tmp, 0,
sizeof(tmp));
657 strcpy(tmp.ifr_name, name);
658 if (ioctl(sock, SIOCGIFHWADDR, &tmp) < 0) {
659 log_fatal(
"Error getting hardware address for \"%s\": %m",
664 sa = &tmp.ifr_hwaddr;
666 sll =
dmalloc (
sizeof (
struct sockaddr_ll),
MDL);
668 log_fatal(
"Unable to allocate memory for link layer address");
669 memcpy(&sll->sll_hatype, &sa->sa_family, sizeof (sll->sll_hatype));
670 memcpy(sll->sll_addr, sa->sa_data, sizeof (sll->sll_addr));
671 switch (sll->sll_hatype) {
672 case ARPHRD_INFINIBAND:
686 char *name = info->
name;
687 struct ifaddrs *ifaddrs = NULL;
688 struct ifaddrs *ifa = NULL;
689 struct sockaddr_ll *sll = NULL;
690 int sll_allocated = 0;
694 if (getifaddrs(&ifaddrs) == -1)
697 if ((sll = get_ll(ifaddrs, &ifa, name)) == NULL) {
702 sll = ioctl_get_ll(name);
710 switch (sll->sll_hatype) {
714 memcpy(&hw->
hbuf[1], sll->sll_addr, 6);
717 #ifdef ARPHRD_IEEE802_TR 718 case ARPHRD_IEEE802_TR:
722 memcpy(&hw->
hbuf[1], sll->sll_addr, 6);
727 memcpy(&hw->
hbuf[1], sll->sll_addr, 6);
729 case ARPHRD_INFINIBAND:
736 if ((colon = strchr(dup,
':')) != NULL) {
738 if ((sll = get_ll(ifaddrs, &ifa, dup)) == NULL)
739 log_fatal(
"Error getting hardware address for \"%s\": %m", name);
745 if (ifa && (ifa->ifa_flags & IFF_BROADCAST)) {
746 struct sockaddr_ll *bll;
748 bll = (
struct sockaddr_ll *)ifa->ifa_broadaddr;
751 memcpy(&info->
bcast_addr, default_ib_bcast_addr,
757 memcpy(&hw->
hbuf[1], &sll->sll_addr[sll->sll_halen - 8], 8);
759 #if defined(ARPHRD_PPP) 762 log_fatal(
"local_family != AF_INET6 for \"%s\"",
776 freeifaddrs(ifaddrs);
777 log_fatal(
"Unsupported device type %hu for \"%s\"",
778 sll->sll_hatype, name);
783 freeifaddrs(ifaddrs);
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 *)
void * dmalloc(unsigned, const char *, int)
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 get_hw_addr(struct interface_info *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 *)
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 *)
void dfree(void *, const char *, int)
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 *)