aboutsummaryrefslogtreecommitdiff
path: root/common/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/socket.c')
-rw-r--r--common/socket.c85
1 files changed, 53 insertions, 32 deletions
diff --git a/common/socket.c b/common/socket.c
index a48404b..f95665c 100644
--- a/common/socket.c
+++ b/common/socket.c
@@ -3,7 +3,7 @@
BSD socket interface code... */
/*
- * Copyright (c) 2004-2011 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2004-2012 by Internet Systems Consortium, Inc. ("ISC")
* Copyright (c) 1995-2003 by Internet Software Consortium
*
* Permission to use, copy, modify, and distribute this software for any
@@ -51,6 +51,7 @@
#include <net/if.h>
#include <sys/sockio.h>
#include <net/if_dl.h>
+#include <sys/dlpi.h>
#endif
#ifdef USE_SOCKET_FALLBACK
@@ -765,7 +766,7 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
struct sockaddr_in *from;
struct hardware *hfrom;
{
-#if !defined(USE_V4_PKTINFO)
+#if !(defined(IP_PKTINFO) && defined(IP_RECVPKTINFO) && defined(USE_V4_PKTINFO))
SOCKLEN_T flen = sizeof *from;
#endif
int result;
@@ -788,7 +789,6 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
struct cmsghdr *cmsg;
struct in_pktinfo *pktinfo;
unsigned int ifindex;
- int found_pktinfo;
/*
* If necessary allocate space for the control message header.
@@ -831,7 +831,7 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
* We set up some space for a "control message". We have
* previously asked the kernel to give us packet
* information (when we initialized the interface), so we
- * should get the destination address from that.
+ * should get the interface index from that.
*/
m.msg_control = control_buf;
m.msg_controllen = control_buf_len;
@@ -842,12 +842,8 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
/*
* If we did read successfully, then we need to loop
* through the control messages we received and
- * find the one with our destination address.
- *
- * We also keep a flag to see if we found it. If we
- * didn't, then we consider this to be an error.
+ * find the one with our inteface index.
*/
- found_pktinfo = 0;
cmsg = CMSG_FIRSTHDR(&m);
while (cmsg != NULL) {
if ((cmsg->cmsg_level == IPPROTO_IP) &&
@@ -861,18 +857,21 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
* the discover code.
*/
memcpy(hfrom->hbuf, &ifindex, sizeof(ifindex));
- found_pktinfo = 1;
+ return (result);
}
cmsg = CMSG_NXTHDR(&m, cmsg);
}
- if (!found_pktinfo) {
- result = -1;
- errno = EIO;
- }
+
+ /*
+ * We didn't find the necessary control message
+ * flag it as an error
+ */
+ result = -1;
+ errno = EIO;
}
#else
- result = recvfrom (interface -> rfdesc, (char *)buf, len, 0,
- (struct sockaddr *)from, &flen);
+ result = recvfrom(interface -> rfdesc, (char *)buf, len, 0,
+ (struct sockaddr *)from, &flen);
#endif /* IP_PKTINFO ... */
#ifdef IGNORE_HOSTUNREACH
} while (result < 0 &&
@@ -880,7 +879,7 @@ ssize_t receive_packet (interface, buf, len, from, hfrom)
errno == ECONNREFUSED) &&
retry++ < 10);
#endif
- return result;
+ return (result);
}
#endif /* USE_SOCKET_RECEIVE */
@@ -897,7 +896,6 @@ receive_packet6(struct interface_info *interface,
int result;
struct cmsghdr *cmsg;
struct in6_pktinfo *pktinfo;
- int found_pktinfo;
/*
* If necessary allocate space for the control message header.
@@ -952,11 +950,7 @@ receive_packet6(struct interface_info *interface,
* If we did read successfully, then we need to loop
* through the control messages we received and
* find the one with our destination address.
- *
- * We also keep a flag to see if we found it. If we
- * didn't, then we consider this to be an error.
*/
- found_pktinfo = 0;
cmsg = CMSG_FIRSTHDR(&m);
while (cmsg != NULL) {
if ((cmsg->cmsg_level == IPPROTO_IPV6) &&
@@ -964,17 +958,21 @@ receive_packet6(struct interface_info *interface,
pktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg);
*to_addr = pktinfo->ipi6_addr;
*if_idx = pktinfo->ipi6_ifindex;
- found_pktinfo = 1;
+
+ return (result);
}
cmsg = CMSG_NXTHDR(&m, cmsg);
}
- if (!found_pktinfo) {
- result = -1;
- errno = EIO;
- }
+
+ /*
+ * We didn't find the necessary control message
+ * flag is as an error
+ */
+ result = -1;
+ errno = EIO;
}
- return result;
+ return (result);
}
#endif /* DHCPv6 */
@@ -1002,6 +1000,9 @@ isc_result_t fallback_discard (object)
log_error ("fallback_discard: %m");
return ISC_R_UNEXPECTED;
}
+#else
+ /* ignore the fact that status value is never used */
+ IGNORE_UNUSED(status);
#endif
return ISC_R_SUCCESS;
}
@@ -1070,7 +1071,7 @@ void maybe_setup_fallback ()
void
get_hw_addr(const char *name, struct hardware *hw) {
struct sockaddr_dl *dladdrp;
- int rv, sock, i;
+ int sock, i;
struct lifreq lifr;
memset(&lifr, 0, sizeof (lifr));
@@ -1104,7 +1105,8 @@ get_hw_addr(const char *name, struct hardware *hw) {
hw->hlen = sizeof (hw->hbuf);
srandom((long)gethrtime());
- for (i = 0; i < hw->hlen; ++i) {
+ hw->hbuf[0] = HTYPE_IPMP;
+ for (i = 1; i < hw->hlen; ++i) {
hw->hbuf[i] = random() % 256;
}
@@ -1117,8 +1119,27 @@ get_hw_addr(const char *name, struct hardware *hw) {
log_fatal("Couldn't get interface hardware address for %s: %m",
name);
dladdrp = (struct sockaddr_dl *)&lifr.lifr_addr;
- hw->hlen = dladdrp->sdl_alen;
- memcpy(hw->hbuf, LLADDR(dladdrp), hw->hlen);
+ hw->hlen = dladdrp->sdl_alen+1;
+ switch (dladdrp->sdl_type) {
+ case DL_CSMACD: /* IEEE 802.3 */
+ case DL_ETHER:
+ hw->hbuf[0] = HTYPE_ETHER;
+ break;
+ case DL_TPR:
+ hw->hbuf[0] = HTYPE_IEEE802;
+ break;
+ case DL_FDDI:
+ hw->hbuf[0] = HTYPE_FDDI;
+ break;
+ case DL_IB:
+ hw->hbuf[0] = HTYPE_INFINIBAND;
+ break;
+ default:
+ log_fatal("%s: unsupported DLPI MAC type %lu", name,
+ (unsigned long)dladdrp->sdl_type);
+ }
+
+ memcpy(hw->hbuf+1, LLADDR(dladdrp), hw->hlen-1);
if (sock != -1)
(void) close(sock);