-diff -up dhcp-4.2.2/client/dhclient.c.lpf-ib dhcp-4.2.2/client/dhclient.c
---- dhcp-4.2.2/client/dhclient.c.lpf-ib 2011-09-19 11:24:08.693775799 +0200
-+++ dhcp-4.2.2/client/dhclient.c 2011-09-19 11:24:08.703775541 +0200
-@@ -113,6 +113,8 @@ static int check_domain_name_list(const
+diff -up dhcp-4.2.4/client/dhclient.c.lpf-ib dhcp-4.2.4/client/dhclient.c
+--- dhcp-4.2.4/client/dhclient.c.lpf-ib 2012-07-18 21:08:48.100835005 +0200
++++ dhcp-4.2.4/client/dhclient.c 2012-07-18 21:08:48.111834856 +0200
+@@ -113,6 +113,8 @@ static int check_domain_name_list(const
static int check_option_values(struct universe *universe, unsigned int opt,
const char *ptr, size_t len);
int
main(int argc, char **argv) {
int fd;
-@@ -919,6 +921,14 @@ main(int argc, char **argv) {
+@@ -909,6 +911,14 @@ main(int argc, char **argv) {
}
srandom(seed + cur_time + (unsigned)getpid());
/* Start a configuration state machine for each interface. */
#ifdef DHCPv6
if (local_family == AF_INET6) {
-@@ -1195,6 +1205,29 @@ int find_subnet (struct subnet **sp,
+@@ -1185,6 +1195,29 @@ int find_subnet (struct subnet **sp,
return 0;
}
/* Individual States:
*
* Each routine is called from the dhclient_state_machine() in one of
-diff -up dhcp-4.2.2/common/bpf.c.lpf-ib dhcp-4.2.2/common/bpf.c
---- dhcp-4.2.2/common/bpf.c.lpf-ib 2011-09-19 11:24:08.694775773 +0200
-+++ dhcp-4.2.2/common/bpf.c 2011-09-19 11:24:08.704775516 +0200
+diff -up dhcp-4.2.4/common/bpf.c.lpf-ib dhcp-4.2.4/common/bpf.c
+--- dhcp-4.2.4/common/bpf.c.lpf-ib 2012-07-18 21:08:48.101834991 +0200
++++ dhcp-4.2.4/common/bpf.c 2012-07-18 21:08:48.111834856 +0200
@@ -198,11 +198,44 @@ struct bpf_insn dhcp_bpf_filter [] = {
BPF_STMT(BPF_RET+BPF_K, 0),
};
#if defined (HAVE_TR_SUPPORT)
struct bpf_insn dhcp_bpf_tr_filter [] = {
/* accept all token ring packets due to variable length header */
-diff -up dhcp-4.2.2/common/lpf.c.lpf-ib dhcp-4.2.2/common/lpf.c
---- dhcp-4.2.2/common/lpf.c.lpf-ib 2011-09-19 11:24:08.694775773 +0200
-+++ dhcp-4.2.2/common/lpf.c 2011-09-19 11:26:15.107109935 +0200
+diff -up dhcp-4.2.4/common/lpf.c.lpf-ib dhcp-4.2.4/common/lpf.c
+--- dhcp-4.2.4/common/lpf.c.lpf-ib 2012-07-18 21:08:48.101834991 +0200
++++ dhcp-4.2.4/common/lpf.c 2012-07-18 21:10:47.367210799 +0200
@@ -42,6 +42,7 @@
#include "includes/netinet/udp.h"
#include "includes/netinet/if_ether.h"
ssize_t send_packet (interface, packet, raw, len, from, to, hto)
struct interface_info *interface;
struct packet *packet;
-@@ -335,6 +420,11 @@ ssize_t send_packet (interface, packet,
+@@ -335,6 +420,11 @@ ssize_t send_packet (interface, packet,
return send_fallback (interface, packet, raw,
len, from, to, hto);
if (hto == NULL && interface->anycast_mac_addr.hlen)
hto = &interface->anycast_mac_addr;
-@@ -356,6 +446,42 @@ ssize_t send_packet (interface, packet,
+@@ -356,6 +446,42 @@ ssize_t send_packet (interface, packet,
#endif /* USE_LPF_SEND */
#ifdef USE_LPF_RECEIVE
ssize_t receive_packet (interface, buf, len, from, hfrom)
struct interface_info *interface;
unsigned char *buf;
-@@ -382,6 +508,10 @@ ssize_t receive_packet (interface, buf,
+@@ -382,6 +508,10 @@ ssize_t receive_packet (interface, buf,
};
struct cmsghdr *cmsg;
length = recvmsg (interface -> rfdesc, &msg, 0);
if (length <= 0)
return length;
-@@ -462,33 +592,44 @@ void maybe_setup_fallback ()
+@@ -461,11 +591,32 @@ void maybe_setup_fallback ()
+ }
}
- void
+-void
-get_hw_addr(const char *name, struct hardware *hw) {
-- int sock;
-- struct ifreq tmp;
-- struct sockaddr *sa;
-+get_hw_addr(struct interface_info *info)
++struct sockaddr_ll *
++get_ll (struct ifaddrs *ifaddrs, struct ifaddrs **ifa, char *name)
+{
-+ struct hardware *hw = &info->hw_address;
-+ char *name = info->name;
-+ struct ifaddrs *ifaddrs;
-+ struct ifaddrs *ifa;
-+ struct sockaddr_ll *sll = NULL;
-
-- if (strlen(name) >= sizeof(tmp.ifr_name)) {
-- log_fatal("Device name too long: \"%s\"", name);
-- }
-+ if (getifaddrs(&ifaddrs) == -1)
-+ log_fatal("Failed to get interfaces");
-
-- sock = socket(AF_INET, SOCK_DGRAM, 0);
-- if (sock < 0) {
-- log_fatal("Can't create socket for \"%s\": %m", name);
-+ for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
-+
-+ if (ifa->ifa_addr == NULL)
++ for (*ifa = ifaddrs; *ifa != NULL; *ifa = (*ifa)->ifa_next) {
++ if ((*ifa)->ifa_addr == NULL)
+ continue;
+
-+ if (ifa->ifa_addr->sa_family != AF_PACKET)
++ if ((*ifa)->ifa_addr->sa_family != AF_PACKET)
+ continue;
+
-+ if (ifa->ifa_flags & IFF_LOOPBACK)
++ if ((*ifa)->ifa_flags & IFF_LOOPBACK)
+ continue;
+
-+ if (strcmp(ifa->ifa_name, name) == 0) {
-+ sll = (struct sockaddr_ll *)(void *)ifa->ifa_addr;
-+ break;
-+ }
- }
++ if (strcmp((*ifa)->ifa_name, name) == 0)
++ return (struct sockaddr_ll *)(void *)(*ifa)->ifa_addr;
++ }
++ return NULL;
++}
++
++struct sockaddr_ll *
++ioctl_get_ll(char *name)
++{
+ int sock;
+ struct ifreq tmp;
+- struct sockaddr *sa;
++ struct sockaddr *sa = NULL;
++ struct sockaddr_ll *sll = NULL;
-- memset(&tmp, 0, sizeof(tmp));
-- strcpy(tmp.ifr_name, name);
-- if (ioctl(sock, SIOCGIFHWADDR, &tmp) < 0) {
+ if (strlen(name) >= sizeof(tmp.ifr_name)) {
+ log_fatal("Device name too long: \"%s\"", name);
+@@ -479,16 +630,44 @@ get_hw_addr(const char *name, struct har
+ memset(&tmp, 0, sizeof(tmp));
+ strcpy(tmp.ifr_name, name);
+ if (ioctl(sock, SIOCGIFHWADDR, &tmp) < 0) {
- log_fatal("Error getting hardware address for \"%s\": %m",
-- name);
-+ if (sll == NULL) {
-+ freeifaddrs(ifaddrs);
-+ log_fatal("Failed to get HW address for %s\n", name);
++ log_fatal("Error getting hardware address for \"%s\": %m",
+ name);
}
-- sa = &tmp.ifr_hwaddr;
+ sa = &tmp.ifr_hwaddr;
- switch (sa->sa_family) {
++ sll = dmalloc (sizeof (struct sockaddr_ll), MDL);
++ if (!sll)
++ log_fatal("Unable to allocate memory for link layer address");
++ memcpy(&sll->sll_hatype, &sa->sa_family, sizeof (sll->sll_hatype));
++ memcpy(sll->sll_addr, sa->sa_data, sizeof (sll->sll_addr));
++ return sll;
++}
++
++void
++get_hw_addr(struct interface_info *info)
++{
++ struct hardware *hw = &info->hw_address;
++ char *name = info->name;
++ struct ifaddrs *ifaddrs = NULL;
++ struct ifaddrs *ifa = NULL;
++ struct sockaddr_ll *sll = NULL;
++
++ if (getifaddrs(&ifaddrs) == -1)
++ log_fatal("Failed to get interfaces");
++
++ if ((sll = get_ll(ifaddrs, &ifa, name)) == NULL) {
++ /*
++ * We were unable to get link-layer address for name.
++ * Fall back to ioctl(SIOCGIFHWADDR).
++ */
++ sll = ioctl_get_ll(name);
++ }
++
+ switch (sll->sll_hatype) {
case ARPHRD_ETHER:
hw->hlen = 7;
break;
case ARPHRD_IEEE802:
#ifdef ARPHRD_IEEE802_TR
-@@ -496,18 +637,35 @@ get_hw_addr(const char *name, struct har
+@@ -496,18 +675,35 @@ get_hw_addr(const char *name, struct har
#endif /* ARPHRD_IEEE802_TR */
hw->hlen = 7;
hw->hbuf[0] = HTYPE_IEEE802;
if (local_family != AF_INET6)
- log_fatal("Unsupported device type %d for \"%s\"",
- sa->sa_family, name);
-+ log_fatal("Unsupported device type %ld for \"%s\"",
-+ (long int)sll->sll_family, name);
++ log_fatal("local_family != AF_INET6 for \"%s\"",
++ name);
hw->hlen = 0;
hw->hbuf[0] = HTYPE_RESERVED;
/* 0xdeadbeef should never occur on the wire,
-@@ -520,10 +678,11 @@ get_hw_addr(const char *name, struct har
+@@ -520,10 +716,11 @@ get_hw_addr(const char *name, struct har
break;
#endif
default:
-+ freeifaddrs(ifaddrs);
- log_fatal("Unsupported device type %ld for \"%s\"",
+- log_fatal("Unsupported device type %ld for \"%s\"",
- (long int)sa->sa_family, name);
-+ (long int)sll->sll_family, name);
++ freeifaddrs(ifaddrs);
++ log_fatal("Unsupported device type %h for \"%s\"",
++ sll->sll_hatype, name);
}
- close(sock);
+ freeifaddrs(ifaddrs);
}
#endif
-diff -up dhcp-4.2.2/common/socket.c.lpf-ib dhcp-4.2.2/common/socket.c
---- dhcp-4.2.2/common/socket.c.lpf-ib 2011-06-27 18:18:20.000000000 +0200
-+++ dhcp-4.2.2/common/socket.c 2011-09-19 11:24:08.705775490 +0200
-@@ -324,7 +324,7 @@ void if_register_send (info)
+diff -up dhcp-4.2.4/common/socket.c.lpf-ib dhcp-4.2.4/common/socket.c
+--- dhcp-4.2.4/common/socket.c.lpf-ib 2012-03-09 12:28:11.000000000 +0100
++++ dhcp-4.2.4/common/socket.c 2012-07-18 21:08:48.112834843 +0200
+@@ -325,7 +325,7 @@ void if_register_send (info)
info->wfdesc = if_register_socket(info, AF_INET, 0);
/* If this is a normal IPv4 address, get the hardware address. */
if (strcmp(info->name, "fallback") != 0)
#if defined (USE_SOCKET_FALLBACK)
/* Fallback only registers for send, but may need to receive as
well. */
-@@ -387,7 +387,7 @@ void if_register_receive (info)
+@@ -388,7 +388,7 @@ void if_register_receive (info)
#endif /* IP_PKTINFO... */
/* If this is a normal IPv4 address, get the hardware address. */
if (strcmp(info->name, "fallback") != 0)
if (!quiet_interface_discovery)
log_info ("Listening on Socket/%s%s%s",
-@@ -497,7 +497,7 @@ if_register6(struct interface_info *info
+@@ -498,7 +498,7 @@ if_register6(struct interface_info *info
if (req_multi)
if_register_multicast(info);
if (!quiet_interface_discovery) {
if (info->shared_network != NULL) {
-diff -up dhcp-4.2.2/includes/dhcpd.h.lpf-ib dhcp-4.2.2/includes/dhcpd.h
---- dhcp-4.2.2/includes/dhcpd.h.lpf-ib 2011-09-19 11:24:08.696775721 +0200
-+++ dhcp-4.2.2/includes/dhcpd.h 2011-09-19 11:24:08.707775438 +0200
+diff -up dhcp-4.2.4/includes/dhcpd.h.lpf-ib dhcp-4.2.4/includes/dhcpd.h
+--- dhcp-4.2.4/includes/dhcpd.h.lpf-ib 2012-07-18 21:08:48.102834978 +0200
++++ dhcp-4.2.4/includes/dhcpd.h 2012-07-18 21:08:48.114834815 +0200
@@ -1243,6 +1243,7 @@ struct interface_info {
struct shared_network *shared_network;
/* Networks connected to this interface. */
struct in_addr *addresses; /* Addresses associated with this
* interface.
*/
-@@ -2356,7 +2357,7 @@ void print_dns_status (int, struct dhcp_
+@@ -2360,7 +2361,7 @@ void print_dns_status (int, struct dhcp_
#endif
const char *print_time(TIME);
/* socket.c */
#if defined (USE_SOCKET_SEND) || defined (USE_SOCKET_RECEIVE) \
-diff -up dhcp-4.2.2/includes/dhcp.h.lpf-ib dhcp-4.2.2/includes/dhcp.h
---- dhcp-4.2.2/includes/dhcp.h.lpf-ib 2011-09-19 11:24:08.696775721 +0200
-+++ dhcp-4.2.2/includes/dhcp.h 2011-09-19 11:24:08.707775438 +0200
-@@ -79,6 +79,7 @@ struct dhcp_packet {
- #define HTYPE_ETHER 1 /* Ethernet 10Mbps */
- #define HTYPE_IEEE802 6 /* IEEE 802.2 Token Ring... */
- #define HTYPE_FDDI 8 /* FDDI... */
-+#define HTYPE_INFINIBAND 32 /* Infiniband IPoIB */
-
- #define HTYPE_RESERVED 0 /* RFC 5494 */
-