32 #if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE) 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> 48 #include <sys/socket.h> 53 static unsigned char default_ib_bcast_addr[20] = {
54 0x00, 0xff, 0xff, 0xff,
55 0xff, 0x12, 0x40, 0x1b,
56 0x00, 0x00, 0x00, 0x00,
57 0x00, 0x00, 0x00, 0x00,
58 0xff, 0xff, 0xff, 0xff
63 #if defined (USE_LPF_SEND) || defined (USE_LPF_RECEIVE) 74 #ifdef USE_LPF_RECEIVE 90 struct sockaddr_ll ll;
91 struct sockaddr common;
103 protocol = ETH_P_ALL;
107 if ((sock = socket(PF_PACKET, type, htons((
short)protocol))) < 0) {
108 if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
109 errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
110 errno == EAFNOSUPPORT || errno == EINVAL) {
112 log_error (
"CONFIG_PACKET (Packet socket) %s",
113 "and CONFIG_FILTER");
114 log_error (
"(Socket Filtering) are enabled %s",
121 memset (&ifr, 0,
sizeof ifr);
122 strncpy (ifr.ifr_name, (
const char *)info -> ifp,
sizeof ifr.ifr_name);
123 ifr.ifr_name[IFNAMSIZ-1] =
'\0';
124 if (ioctl (sock, SIOCGIFINDEX, &ifr))
125 log_fatal (
"Failed to get interface index: %m");
128 memset (&sa, 0,
sizeof sa);
129 sa.ll.sll_family = AF_PACKET;
130 sa.ll.sll_protocol = htons(protocol);
131 sa.ll.sll_ifindex = ifr.ifr_ifindex;
132 if (bind (sock, &sa.common,
sizeof sa)) {
133 if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
134 errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
135 errno == EAFNOSUPPORT || errno == EINVAL) {
137 log_error (
"CONFIG_PACKET (Packet socket) %s",
138 "and CONFIG_FILTER");
139 log_error (
"(Socket Filtering) are enabled %s",
143 log_fatal (
"Bind socket to interface: %m");
157 #ifndef USE_LPF_RECEIVE 160 info -> wfdesc = info -> rfdesc;
163 log_info (
"Sending on LPF/%s/%s%s%s",
166 info -> hw_address.hlen - 1,
167 &info -> hw_address.hbuf [1]),
178 #ifndef USE_LPF_RECEIVE 181 close (info -> wfdesc);
185 log_info (
"Disabling output on LPF/%s/%s%s%s",
188 info -> hw_address.hlen - 1,
189 &info -> hw_address.hbuf [1]),
196 #ifdef USE_LPF_RECEIVE 199 extern struct sock_filter dhcp_bpf_filter [];
200 extern int dhcp_bpf_filter_len;
201 extern struct sock_filter dhcp_ib_bpf_filter [];
202 extern int dhcp_ib_bpf_filter_len;
204 #if defined (HAVE_TR_SUPPORT) 205 extern struct sock_filter dhcp_bpf_tr_filter [];
206 extern int dhcp_bpf_tr_filter_len;
218 #ifdef PACKET_AUXDATA 222 if (setsockopt(info->rfdesc, SOL_PACKET, PACKET_AUXDATA,
223 &val,
sizeof(val)) < 0) {
224 if (errno != ENOPROTOOPT) {
225 log_fatal (
"Failed to set auxiliary packet data: %m");
233 #if defined (HAVE_TR_SUPPORT) 235 lpf_tr_filter_setup (info);
238 lpf_gen_filter_setup (info);
241 log_info (
"Listening on LPF/%s/%s%s%s",
244 info -> hw_address.hlen - 1,
245 &info -> hw_address.hbuf [1]),
256 close (info -> rfdesc);
259 log_info (
"Disabling input on LPF/%s/%s%s%s",
262 info -> hw_address.hlen - 1,
263 &info -> hw_address.hbuf [1]),
269 static void lpf_gen_filter_setup (info)
274 memset(&p, 0,
sizeof(p));
278 p.len = dhcp_ib_bpf_filter_len;
279 p.filter = dhcp_ib_bpf_filter;
286 dhcp_ib_bpf_filter[6].k = ntohs ((
short)
local_port);
290 p.len = dhcp_bpf_filter_len;
291 p.filter = dhcp_bpf_filter;
296 dhcp_bpf_filter [8].k = ntohs ((
short)
local_port);
299 if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
301 if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
302 errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
303 errno == EAFNOSUPPORT) {
305 log_error (
"CONFIG_PACKET (Packet socket) %s",
306 "and CONFIG_FILTER");
307 log_error (
"(Socket Filtering) are enabled %s",
311 log_fatal (
"Can't install packet filter program: %m");
315 #if defined (HAVE_TR_SUPPORT) 316 static void lpf_tr_filter_setup (info)
321 memset(&p, 0,
sizeof(p));
325 p.len = dhcp_bpf_tr_filter_len;
326 p.filter = dhcp_bpf_tr_filter;
335 if (setsockopt (info -> rfdesc, SOL_SOCKET, SO_ATTACH_FILTER, &p,
337 if (errno == ENOPROTOOPT || errno == EPROTONOSUPPORT ||
338 errno == ESOCKTNOSUPPORT || errno == EPFNOSUPPORT ||
339 errno == EAFNOSUPPORT) {
341 log_error (
"CONFIG_PACKET (Packet socket) %s",
342 "and CONFIG_FILTER");
343 log_error (
"(Socket Filtering) are enabled %s",
347 log_fatal (
"Can't install packet filter program: %m");
354 ssize_t send_packet_ib(interface,
packet, raw, len, from, to, hto)
360 struct sockaddr_in *to;
364 double ih [1536 /
sizeof (double)];
365 unsigned char *buf = (
unsigned char *)ih;
370 struct sockaddr_ll sll;
371 struct sockaddr_storage ss;
375 to->sin_addr.s_addr, to->sin_port,
376 (
unsigned char *)raw, len);
377 memcpy (buf + ibufp, raw, len);
379 memset(&su, 0,
sizeof(su));
380 su.sll.sll_family = AF_PACKET;
383 if (!(su.sll.sll_ifindex = if_nametoindex(interface->name))) {
385 log_error (
"send_packet_ib: %m - failed to get if index");
390 su.sll.sll_halen =
sizeof(interface->bcast_addr);
391 memcpy(&su.sll.sll_addr, interface->bcast_addr, 20);
393 result = sendto(interface->wfdesc, buf, ibufp + len, 0,
402 ssize_t
send_packet (interface, packet, raw, len, from, to, hto)
404 struct packet *packet;
408 struct sockaddr_in *to;
411 unsigned hbufp = 0, ibufp = 0;
413 double ih [1536 /
sizeof (double)];
414 unsigned char *buf = (
unsigned char *)ih;
418 if (!strcmp (interface -> name,
"fallback"))
423 return send_packet_ib(interface, packet, raw, len, from,
427 if (hto == NULL && interface->anycast_mac_addr.
hlen)
428 hto = &interface->anycast_mac_addr;
433 memcpy (buf + fudge, (
unsigned char *)hh, hbufp);
434 ibufp = hbufp + fudge;
436 to -> sin_addr.s_addr, to -> sin_port,
437 (
unsigned char *)raw, len);
438 memcpy (buf + ibufp, raw, len);
439 result = write(interface->wfdesc, buf + fudge, ibufp + len - fudge);
446 #ifdef USE_LPF_RECEIVE 447 ssize_t receive_packet_ib (interface, buf, len, from, hfrom)
451 struct sockaddr_in *from;
456 unsigned char ibuf [1536];
460 length = read(interface->rfdesc, ibuf,
sizeof(ibuf));
466 (
unsigned)length, &paylen, 0);
478 memcpy(buf, &ibuf[bufix], paylen);
480 return (ssize_t)paylen;
487 struct sockaddr_in *from;
493 unsigned char ibuf [1536];
498 .iov_len =
sizeof ibuf,
500 #ifdef PACKET_AUXDATA 505 unsigned char cmsgbuf[CMSG_LEN(
sizeof(
struct tpacket_auxdata))];
506 struct msghdr msg = {
509 .msg_control = cmsgbuf,
510 .msg_controllen =
sizeof(cmsgbuf),
513 struct msghdr msg = {
522 return receive_packet_ib(interface, buf, len, from, hfrom);
525 length = recvmsg (interface->rfdesc, &msg, 0);
529 #ifdef PACKET_AUXDATA 548 struct cmsghdr *cmsg;
550 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
551 if (cmsg->cmsg_level == SOL_PACKET &&
552 cmsg->cmsg_type == PACKET_AUXDATA) {
553 struct tpacket_auxdata *aux = (
void *)CMSG_DATA(cmsg);
556 #ifdef VLAN_TCI_PRESENT 558 if (aux->tp_vlan_tci & 0x0fff)
562 csum_ready = ((aux->tp_status & TP_STATUS_CSUMNOTREADY)
586 (
unsigned)length, &paylen, csum_ready);
599 memcpy(buf, &ibuf[bufix], paylen);
630 if (status != ISC_R_SUCCESS)
631 log_fatal (
"Can't register I/O handle for \"%s\": %s",
632 fbi ->
name, isc_result_totext (status));
633 interface_dereference (&fbi,
MDL);
638 #if defined (USE_LPF_RECEIVE) || defined (USE_LPF_HWADDR) 640 get_ll (
struct ifaddrs *ifaddrs,
struct ifaddrs **ifa,
char *name)
642 for (*ifa = ifaddrs; *ifa != NULL; *ifa = (*ifa)->ifa_next) {
643 if ((*ifa)->ifa_addr == NULL)
646 if ((*ifa)->ifa_addr->sa_family != AF_PACKET)
649 if ((*ifa)->ifa_flags & IFF_LOOPBACK)
652 if (strcmp((*ifa)->ifa_name, name) == 0)
653 return (
struct sockaddr_ll *)(
void *)(*ifa)->ifa_addr;
660 ioctl_get_ll(
char *name)
664 struct sockaddr *sa = NULL;
665 struct sockaddr_ll *sll = NULL;
667 if (strlen(name) >=
sizeof(tmp.ifr_name)) {
668 log_fatal(
"Device name too long: \"%s\"", name);
671 sock = socket(AF_INET, SOCK_DGRAM, 0);
673 log_fatal(
"Can't create socket for \"%s\": %m", name);
676 memset(&tmp, 0,
sizeof(tmp));
677 strcpy(tmp.ifr_name, name);
678 if (ioctl(sock, SIOCGIFHWADDR, &tmp) < 0) {
679 log_fatal(
"Error getting hardware address for \"%s\": %m",
684 sa = &tmp.ifr_hwaddr;
686 sll =
dmalloc (
sizeof (
struct sockaddr_ll),
MDL);
688 log_fatal(
"Unable to allocate memory for link layer address");
689 memcpy(&sll->sll_hatype, &sa->sa_family, sizeof (sll->sll_hatype));
690 memcpy(sll->sll_addr, sa->sa_data, sizeof (sll->sll_addr));
691 switch (sll->sll_hatype) {
692 case ARPHRD_INFINIBAND:
705 char *name = info->
name;
706 struct ifaddrs *ifaddrs = NULL;
707 struct ifaddrs *ifa = NULL;
708 struct sockaddr_ll *sll = NULL;
709 int sll_allocated = 0;
713 if (getifaddrs(&ifaddrs) == -1)
716 if ((sll = get_ll(ifaddrs, &ifa, name)) == NULL) {
721 sll = ioctl_get_ll(name);
729 switch (sll->sll_hatype) {
733 memcpy(&hw->
hbuf[1], sll->sll_addr, 6);
736 #ifdef ARPHRD_IEEE802_TR 737 case ARPHRD_IEEE802_TR:
741 memcpy(&hw->
hbuf[1], sll->sll_addr, 6);
746 memcpy(&hw->
hbuf[1], sll->sll_addr, 6);
748 case ARPHRD_INFINIBAND:
755 if ((colon = strchr(dup,
':')) != NULL) {
757 if ((sll = get_ll(ifaddrs, &ifa, dup)) == NULL)
758 log_fatal(
"Error getting hardware address for \"%s\": %m", name);
764 if (ifa && (ifa->ifa_flags & IFF_BROADCAST)) {
765 struct sockaddr_ll *bll;
767 bll = (
struct sockaddr_ll *)ifa->ifa_broadaddr;
770 memcpy(&info->
bcast_addr, default_ib_bcast_addr,
780 #if defined(ARPHRD_PPP) 783 log_fatal(
"local_family != AF_INET6 for \"%s\"",
797 freeifaddrs(ifaddrs);
798 log_fatal(
"Unsupported device type %hu for \"%s\"",
799 sll->sll_hatype, name);
804 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
#define HARDWARE_ADDR_LEN_IOCTL
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]
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 *)