version 1.1, 2012/02/21 22:30:18
|
version 1.1.1.1, 2012/10/09 09:06:54
|
Line 3
|
Line 3
|
BSD socket interface code... */ |
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 |
* Copyright (c) 1995-2003 by Internet Software Consortium |
* |
* |
* Permission to use, copy, modify, and distribute this software for any |
* Permission to use, copy, modify, and distribute this software for any |
Line 52
|
Line 52
|
#include <net/if.h> |
#include <net/if.h> |
#include <sys/sockio.h> |
#include <sys/sockio.h> |
#include <net/if_dl.h> |
#include <net/if_dl.h> |
|
#include <sys/dlpi.h> |
#endif |
#endif |
|
|
#ifdef USE_SOCKET_FALLBACK |
#ifdef USE_SOCKET_FALLBACK |
Line 759 ssize_t receive_packet (interface, buf, len, from, hfr
|
Line 760 ssize_t receive_packet (interface, buf, len, from, hfr
|
struct sockaddr_in *from; |
struct sockaddr_in *from; |
struct hardware *hfrom; |
struct hardware *hfrom; |
{ |
{ |
#if !defined(USE_V4_PKTINFO) | #if !(defined(IP_PKTINFO) && defined(IP_RECVPKTINFO) && defined(USE_V4_PKTINFO)) |
SOCKLEN_T flen = sizeof *from; |
SOCKLEN_T flen = sizeof *from; |
#endif |
#endif |
int result; |
int result; |
Line 782 ssize_t receive_packet (interface, buf, len, from, hfr
|
Line 783 ssize_t receive_packet (interface, buf, len, from, hfr
|
struct cmsghdr *cmsg; |
struct cmsghdr *cmsg; |
struct in_pktinfo *pktinfo; |
struct in_pktinfo *pktinfo; |
unsigned int ifindex; |
unsigned int ifindex; |
int found_pktinfo; |
|
|
|
/* |
/* |
* If necessary allocate space for the control message header. |
* If necessary allocate space for the control message header. |
Line 825 ssize_t receive_packet (interface, buf, len, from, hfr
|
Line 825 ssize_t receive_packet (interface, buf, len, from, hfr
|
* We set up some space for a "control message". We have |
* We set up some space for a "control message". We have |
* previously asked the kernel to give us packet |
* previously asked the kernel to give us packet |
* information (when we initialized the interface), so we |
* 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_control = control_buf; |
m.msg_controllen = control_buf_len; |
m.msg_controllen = control_buf_len; |
Line 836 ssize_t receive_packet (interface, buf, len, from, hfr
|
Line 836 ssize_t receive_packet (interface, buf, len, from, hfr
|
/* |
/* |
* If we did read successfully, then we need to loop |
* If we did read successfully, then we need to loop |
* through the control messages we received and |
* through the control messages we received and |
* find the one with our destination address. | * find the one with our inteface index. |
* | |
* 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); |
cmsg = CMSG_FIRSTHDR(&m); |
while (cmsg != NULL) { |
while (cmsg != NULL) { |
if ((cmsg->cmsg_level == IPPROTO_IP) && |
if ((cmsg->cmsg_level == IPPROTO_IP) && |
Line 855 ssize_t receive_packet (interface, buf, len, from, hfr
|
Line 851 ssize_t receive_packet (interface, buf, len, from, hfr
|
* the discover code. |
* the discover code. |
*/ |
*/ |
memcpy(hfrom->hbuf, &ifindex, sizeof(ifindex)); |
memcpy(hfrom->hbuf, &ifindex, sizeof(ifindex)); |
found_pktinfo = 1; | return (result); |
} |
} |
cmsg = CMSG_NXTHDR(&m, cmsg); |
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 |
#else |
result = recvfrom (interface -> rfdesc, (char *)buf, len, 0, | result = recvfrom(interface -> rfdesc, (char *)buf, len, 0, |
(struct sockaddr *)from, &flen); | (struct sockaddr *)from, &flen); |
#endif /* IP_PKTINFO ... */ |
#endif /* IP_PKTINFO ... */ |
#ifdef IGNORE_HOSTUNREACH |
#ifdef IGNORE_HOSTUNREACH |
} while (result < 0 && |
} while (result < 0 && |
Line 874 ssize_t receive_packet (interface, buf, len, from, hfr
|
Line 873 ssize_t receive_packet (interface, buf, len, from, hfr
|
errno == ECONNREFUSED) && |
errno == ECONNREFUSED) && |
retry++ < 10); |
retry++ < 10); |
#endif |
#endif |
return result; | return (result); |
} |
} |
|
|
#endif /* USE_SOCKET_RECEIVE */ |
#endif /* USE_SOCKET_RECEIVE */ |
Line 891 receive_packet6(struct interface_info *interface,
|
Line 890 receive_packet6(struct interface_info *interface,
|
int result; |
int result; |
struct cmsghdr *cmsg; |
struct cmsghdr *cmsg; |
struct in6_pktinfo *pktinfo; |
struct in6_pktinfo *pktinfo; |
int found_pktinfo; |
|
|
|
/* |
/* |
* If necessary allocate space for the control message header. |
* If necessary allocate space for the control message header. |
Line 946 receive_packet6(struct interface_info *interface,
|
Line 944 receive_packet6(struct interface_info *interface,
|
* If we did read successfully, then we need to loop |
* If we did read successfully, then we need to loop |
* through the control messages we received and |
* through the control messages we received and |
* find the one with our destination address. |
* 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); |
cmsg = CMSG_FIRSTHDR(&m); |
while (cmsg != NULL) { |
while (cmsg != NULL) { |
if ((cmsg->cmsg_level == IPPROTO_IPV6) && |
if ((cmsg->cmsg_level == IPPROTO_IPV6) && |
Line 958 receive_packet6(struct interface_info *interface,
|
Line 952 receive_packet6(struct interface_info *interface,
|
pktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg); |
pktinfo = (struct in6_pktinfo *)CMSG_DATA(cmsg); |
*to_addr = pktinfo->ipi6_addr; |
*to_addr = pktinfo->ipi6_addr; |
*if_idx = pktinfo->ipi6_ifindex; |
*if_idx = pktinfo->ipi6_ifindex; |
found_pktinfo = 1; | |
| return (result); |
} |
} |
cmsg = CMSG_NXTHDR(&m, cmsg); |
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 */ |
#endif /* DHCPv6 */ |
|
|
Line 996 isc_result_t fallback_discard (object)
|
Line 994 isc_result_t fallback_discard (object)
|
log_error ("fallback_discard: %m"); |
log_error ("fallback_discard: %m"); |
return ISC_R_UNEXPECTED; |
return ISC_R_UNEXPECTED; |
} |
} |
|
#else |
|
/* ignore the fact that status value is never used */ |
|
IGNORE_UNUSED(status); |
#endif |
#endif |
return ISC_R_SUCCESS; |
return ISC_R_SUCCESS; |
} |
} |
Line 1064 void maybe_setup_fallback ()
|
Line 1065 void maybe_setup_fallback ()
|
void |
void |
get_hw_addr(const char *name, struct hardware *hw) { |
get_hw_addr(const char *name, struct hardware *hw) { |
struct sockaddr_dl *dladdrp; |
struct sockaddr_dl *dladdrp; |
int rv, sock, i; | int sock, i; |
struct lifreq lifr; |
struct lifreq lifr; |
|
|
memset(&lifr, 0, sizeof (lifr)); |
memset(&lifr, 0, sizeof (lifr)); |
Line 1098 get_hw_addr(const char *name, struct hardware *hw) {
|
Line 1099 get_hw_addr(const char *name, struct hardware *hw) {
|
hw->hlen = sizeof (hw->hbuf); |
hw->hlen = sizeof (hw->hbuf); |
srandom((long)gethrtime()); |
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; |
hw->hbuf[i] = random() % 256; |
} |
} |
|
|
Line 1111 get_hw_addr(const char *name, struct hardware *hw) {
|
Line 1113 get_hw_addr(const char *name, struct hardware *hw) {
|
log_fatal("Couldn't get interface hardware address for %s: %m", |
log_fatal("Couldn't get interface hardware address for %s: %m", |
name); |
name); |
dladdrp = (struct sockaddr_dl *)&lifr.lifr_addr; |
dladdrp = (struct sockaddr_dl *)&lifr.lifr_addr; |
hw->hlen = dladdrp->sdl_alen; | hw->hlen = dladdrp->sdl_alen+1; |
memcpy(hw->hbuf, LLADDR(dladdrp), hw->hlen); | 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) |
if (sock != -1) |
(void) close(sock); |
(void) close(sock); |