30#if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE)
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)
46#include <sys/socket.h>
51static 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)
88 struct sockaddr_ll ll;
89 struct sockaddr common;
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
161 log_info (
"Sending on LPF/%s/%s%s%s",
176#ifndef USE_LPF_RECEIVE
183 log_info (
"Disabling output on LPF/%s/%s%s%s",
194#ifdef USE_LPF_RECEIVE
197extern struct sock_filter dhcp_bpf_filter [];
198extern int dhcp_bpf_filter_len;
199extern struct sock_filter dhcp_ib_bpf_filter [];
200extern int dhcp_ib_bpf_filter_len;
202#if defined(RELAY_PORT)
203extern struct sock_filter dhcp_bpf_relay_filter [];
204extern int dhcp_bpf_relay_filter_len;
207#if defined (HAVE_TR_SUPPORT)
208extern struct sock_filter dhcp_bpf_tr_filter [];
209extern int dhcp_bpf_tr_filter_len;
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",
262 log_info (
"Disabling input on LPF/%s/%s%s%s",
272static void lpf_gen_filter_setup (info)
277 memset(&p, 0,
sizeof(p));
280 p.len = dhcp_ib_bpf_filter_len;
281 p.filter = dhcp_ib_bpf_filter;
293 p.len = dhcp_bpf_filter_len;
294 p.filter = dhcp_bpf_filter;
299#if defined(RELAY_PORT)
305 p.len = dhcp_bpf_relay_filter_len;
306 p.filter = dhcp_bpf_relay_filter;
308 dhcp_bpf_relay_filter [10].k = ntohs (
relay_port);
315 if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
317 if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
318 errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
319 errno == EAFNOSUPPORT) {
321 log_error (
"CONFIG_PACKET (Packet socket) %s",
322 "and CONFIG_FILTER");
323 log_error (
"(Socket Filtering) are enabled %s",
327 log_fatal (
"Can't install packet filter program: %m");
331#if defined (HAVE_TR_SUPPORT)
332static void lpf_tr_filter_setup (info)
337 memset(&p, 0,
sizeof(p));
341 p.len = dhcp_bpf_tr_filter_len;
342 p.filter = dhcp_bpf_tr_filter;
351 if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
353 if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
354 errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
355 errno == EAFNOSUPPORT) {
357 log_error (
"CONFIG_PACKET (Packet socket) %s",
358 "and CONFIG_FILTER");
359 log_error (
"(Socket Filtering) are enabled %s",
363 log_fatal (
"Can't install packet filter program: %m");
370ssize_t send_packet_ib(interface,
packet, raw, len, from, to, hto)
376 struct sockaddr_in *to;
380 double ih [1536 /
sizeof (double)];
381 unsigned char *buf = (
unsigned char *)ih;
386 struct sockaddr_ll sll;
387 struct sockaddr_storage ss;
391 to->sin_addr.s_addr, to->sin_port,
392 (
unsigned char *)raw, len);
393 memcpy (buf + ibufp, raw, len);
395 memset(&su, 0,
sizeof(su));
396 su.sll.sll_family = AF_PACKET;
399 if (!(su.sll.sll_ifindex = if_nametoindex(interface->
name))) {
401 log_error (
"send_packet_ib: %m - failed to get if index");
406 su.sll.sll_halen =
sizeof(interface->
bcast_addr);
407 memcpy(&su.sll.sll_addr, interface->
bcast_addr, 20);
409 result = sendto(interface->
wfdesc, buf, ibufp + len, 0,
424 struct sockaddr_in *to;
427 unsigned hbufp = 0, ibufp = 0;
429 double ih [1536 /
sizeof (double)];
430 unsigned char *buf = (
unsigned char *)ih;
434 if (!strcmp (interface -> name,
"fallback"))
439 return send_packet_ib(interface,
packet, raw, len, from,
449 memcpy (buf + fudge, (
unsigned char *)hh, hbufp);
450 ibufp = hbufp + fudge;
452 to -> sin_addr.s_addr, to -> sin_port,
453 (
unsigned char *)raw, len);
454 memcpy (buf + ibufp, raw, len);
455 result = write(interface->
wfdesc, buf + fudge, ibufp + len - fudge);
462#ifdef USE_LPF_RECEIVE
463ssize_t receive_packet_ib (interface, buf, len, from, hfrom)
467 struct sockaddr_in *from;
472 unsigned char ibuf [1536];
476 length = read(interface->
rfdesc, ibuf,
sizeof(ibuf));
482 (
unsigned)length, &paylen, 0);
494 memcpy(buf, &ibuf[bufix], paylen);
496 return (ssize_t)paylen;
503 struct sockaddr_in *from;
509 unsigned char ibuf [1536];
514 .iov_len =
sizeof ibuf,
521 unsigned char cmsgbuf[CMSG_LEN(
sizeof(
struct tpacket_auxdata))];
522 struct msghdr msg = {
525 .msg_control = cmsgbuf,
526 .msg_controllen =
sizeof(cmsgbuf),
529 struct msghdr msg = {
538 return receive_packet_ib(interface, buf, len, from, hfrom);
541 length = recvmsg (interface->
rfdesc, &msg, 0);
564 struct cmsghdr *cmsg;
566 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
567 if (cmsg->cmsg_level == SOL_PACKET &&
568 cmsg->cmsg_type == PACKET_AUXDATA) {
569 struct tpacket_auxdata *aux = (
void *)CMSG_DATA(cmsg);
570#ifdef VLAN_TCI_PRESENT
573 if (aux->tp_vlan_tci & 0x0fff)
577 csum_ready = ((aux->tp_status & TP_STATUS_CSUMNOTREADY)
601 (
unsigned)length, &paylen, csum_ready);
614 memcpy(buf, &ibuf[bufix], paylen);
646 log_fatal (
"Can't register I/O handle for \"%s\": %s",
647 fbi ->
name, isc_result_totext (status));
648 interface_dereference (&fbi,
MDL);
653#if defined (USE_LPF_RECEIVE) || defined (USE_LPF_HWADDR)
655get_ll (
struct ifaddrs *ifaddrs,
struct ifaddrs **ifa,
char *name)
657 for (*ifa = ifaddrs; *ifa != NULL; *ifa = (*ifa)->ifa_next) {
658 if ((*ifa)->ifa_addr == NULL)
661 if ((*ifa)->ifa_addr->sa_family != AF_PACKET)
664 if ((*ifa)->ifa_flags & IFF_LOOPBACK)
667 if (strcmp((*ifa)->ifa_name, name) == 0)
668 return (
struct sockaddr_ll *)(
void *)(*ifa)->ifa_addr;
675ioctl_get_ll(
char *name)
679 struct sockaddr *sa = NULL;
680 struct sockaddr_ll *sll = NULL;
682 if (strlen(name) >=
sizeof(tmp.ifr_name)) {
683 log_fatal(
"Device name too long: \"%s\"", name);
686 sock = socket(AF_INET, SOCK_DGRAM, 0);
688 log_fatal(
"Can't create socket for \"%s\": %m", name);
691 memset(&tmp, 0,
sizeof(tmp));
692 strcpy(tmp.ifr_name, name);
693 if (ioctl(sock, SIOCGIFHWADDR, &tmp) < 0) {
694 log_fatal(
"Error getting hardware address for \"%s\": %m",
699 sa = &tmp.ifr_hwaddr;
701 sll =
dmalloc (
sizeof (
struct sockaddr_ll),
MDL);
703 log_fatal(
"Unable to allocate memory for link layer address");
704 memcpy(&sll->sll_hatype, &sa->sa_family, sizeof (sll->sll_hatype));
705 memcpy(sll->sll_addr, sa->sa_data, sizeof (sll->sll_addr));
706 switch (sll->sll_hatype) {
707 case ARPHRD_INFINIBAND:
725 log_fatal(
"Unsupported device type for \"%s\"",
734 char *name = info->
name;
735 struct ifaddrs *ifaddrs = NULL;
736 struct ifaddrs *ifa = NULL;
737 struct sockaddr_ll *sll = NULL;
738 int sll_allocated = 0;
743 if (getifaddrs(&ifaddrs) == -1)
746 if ((sll = get_ll(ifaddrs, &ifa, name)) == NULL) {
751 sll = ioctl_get_ll(name);
759 switch (sll->sll_hatype) {
763 memcpy(&hw->
hbuf[1], sll->sll_addr, 6);
766#ifdef ARPHRD_IEEE802_TR
767 case ARPHRD_IEEE802_TR:
771 memcpy(&hw->
hbuf[1], sll->sll_addr, 6);
776 memcpy(&hw->
hbuf[1], sll->sll_addr, 6);
778 case ARPHRD_INFINIBAND:
785 if ((colon = strchr(dup,
':')) != NULL) {
787 if ((sll = get_ll(ifaddrs, &ifa, dup)) == NULL)
788 log_fatal(
"Error getting hardware address for \"%s\": %m", name);
794 if (ifa && (ifa->ifa_flags & IFF_BROADCAST)) {
795 struct sockaddr_ll *bll;
797 bll = (
struct sockaddr_ll *)ifa->ifa_broadaddr;
800 memcpy(&info->
bcast_addr, default_ib_bcast_addr,
810#if defined(ARPHRD_PPP)
813 log_fatal(
"local_family != AF_INET6 for \"%s\"",
827 log_error(
"Unsupported device type %hu for \"%s\"",
828 sll->sll_hatype, name);
829 result = ISC_R_NOTFOUND;
835 freeifaddrs(ifaddrs);
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 *)
#define HARDWARE_ADDR_LEN_IOCTL
void assemble_hw_header(struct interface_info *, unsigned char *, unsigned *, struct hardware *)
void try_hw_addr(struct interface_info *info)
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 if_register_lpf(struct interface_info *)
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 get_hw_addr(struct interface_info *info)
void if_register_receive(struct interface_info *)
isc_result_t get_hw_addr2(struct interface_info *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
void * dmalloc(size_t, const char *, int)
void dfree(void *, const char *, int)
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