40 #ifndef ZMQ_HAVE_WINDOWS 41 #include <sys/types.h> 42 #include <arpa/inet.h> 43 #include <netinet/tcp.h> 51 #ifdef ZMQ_HAVE_SOLARIS 52 #include <sys/sockio.h> 61 const int fd =
open_socket (AF_INET, SOCK_DGRAM, 0);
66 ifn.lifn_family = AF_INET;
68 int rc = ioctl (fd, SIOCGLIFNUM, (
char*) &ifn);
72 const size_t ifr_size =
sizeof (
struct lifreq) * ifn.lifn_count;
73 char *ifr = (
char*) malloc (ifr_size);
78 ifc.lifc_family = AF_INET;
80 ifc.lifc_len = ifr_size;
82 rc = ioctl (fd, SIOCGLIFCONF, (
char*) &ifc);
87 lifreq *ifrp = ifc.lifc_req;
88 for (
int n = 0; n < (
int) (ifc.lifc_len / sizeof (lifreq));
90 if (!strcmp (nic_, ifrp->lifr_name)) {
91 rc = ioctl (fd, SIOCGLIFADDR, (
char*) ifrp);
93 if (ifrp->lifr_addr.ss_family == AF_INET) {
97 address.ipv4 = *(sockaddr_in*) &ifrp->lifr_addr;
115 #elif defined ZMQ_HAVE_AIX || defined ZMQ_HAVE_HPUX || defined ZMQ_HAVE_ANDROID 116 #include <sys/ioctl.h> 120 #if defined ZMQ_HAVE_AIX || defined ZMQ_HAVE_HPUX 130 const int sd =
open_socket (ipv6_ ? AF_INET6 : AF_INET, SOCK_DGRAM, 0);
136 strncpy (ifr.ifr_name, nic_, sizeof (ifr.ifr_name) );
139 const int rc = ioctl (sd, SIOCGIFADDR, (caddr_t) &ifr,
sizeof (ifr) );
149 const int family = ifr.ifr_addr.sa_family;
150 if ((family == AF_INET || (ipv6_ && family == AF_INET6))
151 && !strcmp (nic_, ifr.ifr_name))
155 (family == AF_INET) ? sizeof (
struct sockaddr_in)
156 :
sizeof (
struct sockaddr_in6));
158 memcpy (&
address, &ifr.ifr_addr,
159 (family == AF_INET) ? sizeof (
struct sockaddr_in)
160 :
sizeof (
struct sockaddr_in6));
171 #elif ((defined ZMQ_HAVE_LINUX || defined ZMQ_HAVE_FREEBSD ||\ 172 defined ZMQ_HAVE_OSX || defined ZMQ_HAVE_OPENBSD ||\ 173 defined ZMQ_HAVE_QNXNTO || defined ZMQ_HAVE_NETBSD ||\ 174 defined ZMQ_HAVE_DRAGONFLY || defined ZMQ_HAVE_GNU)\ 175 && defined ZMQ_HAVE_IFADDRS) 185 const int rc = getifaddrs (&ifa);
191 for (ifaddrs *ifp = ifa; ifp != NULL; ifp = ifp->ifa_next) {
192 if (ifp->ifa_addr == NULL)
195 const int family = ifp->ifa_addr->sa_family;
196 if ((family == AF_INET || (ipv6_ && family == AF_INET6))
197 && !strcmp (nic_, ifp->ifa_name)) {
200 (family == AF_INET) ? sizeof (
struct sockaddr_in)
201 :
sizeof (
struct sockaddr_in6));
203 memcpy (&
address, ifp->ifa_addr,
204 (family == AF_INET) ? sizeof (
struct sockaddr_in)
205 :
sizeof (
struct sockaddr_in6));
240 sockaddr *out_addr = (sockaddr*) &ss;
246 sockaddr_in6 ip6_addr;
247 memset (&ip6_addr, 0,
sizeof (ip6_addr) );
248 ip6_addr.sin6_family = AF_INET6;
249 memcpy (&ip6_addr.sin6_addr, &in6addr_any, sizeof (in6addr_any) );
250 out_addrlen =
sizeof (ip6_addr);
251 memcpy (out_addr, &ip6_addr, out_addrlen);
254 sockaddr_in ip4_addr;
255 memset (&ip4_addr, 0,
sizeof (ip4_addr) );
256 ip4_addr.sin_family = AF_INET;
257 ip4_addr.sin_addr.s_addr = htonl (INADDR_ANY);
258 out_addrlen =
sizeof (ip4_addr);
259 memcpy (out_addr, &ip4_addr, out_addrlen);
262 if (strcmp (interface_,
"*") == 0) {
267 memcpy (&
address, out_addr, out_addrlen);
273 if (rc == 0 || errno != ENODEV)
277 #if defined ZMQ_HAVE_OPENVMS && defined __ia64 278 __addrinfo64 *res = NULL;
281 addrinfo *res = NULL;
284 memset (&req, 0,
sizeof (req) );
288 req.ai_family = ipv6_? AF_INET6: AF_INET;
291 req.ai_socktype = SOCK_STREAM;
295 req.ai_flags = AI_PASSIVE | AI_NUMERICHOST;
297 #if defined AI_V4MAPPED && !defined ZMQ_HAVE_FREEBSD && !defined ZMQ_HAVE_DRAGONFLY 303 if (req.ai_family == AF_INET6)
304 req.ai_flags |= AI_V4MAPPED;
309 rc = getaddrinfo (interface_, NULL, &req, &res);
321 memcpy (&
address, res->ai_addr, res->ai_addrlen);
332 #if defined ZMQ_HAVE_OPENVMS && defined __ia64 && __INITIAL_POINTER_SIZE == 64 337 memset (&req, 0,
sizeof (req) );
341 req.ai_family = ipv6_? AF_INET6: AF_INET;
345 req.ai_socktype = SOCK_STREAM;
347 #if defined AI_V4MAPPED && !defined ZMQ_HAVE_FREEBSD && !defined ZMQ_HAVE_DRAGONFLY 353 if (req.ai_family == AF_INET6)
354 req.ai_flags |= AI_V4MAPPED;
359 #if defined ZMQ_HAVE_OPENVMS && defined __ia64 && __INITIAL_POINTER_SIZE == 64 364 const int rc = getaddrinfo (hostname_, NULL, &req, &res);
382 memcpy (&
address, res->ai_addr, res->ai_addrlen);
403 if (sa->sa_family == AF_INET && sa_len >= (socklen_t) sizeof (
address.ipv4) )
406 if (sa->sa_family == AF_INET6 && sa_len >= (socklen_t) sizeof (
address.ipv6) )
418 const char *src_delimiter = strrchr (name_,
';');
420 std::string src_name (name_, src_delimiter - name_);
421 const int rc =
resolve (src_name.c_str (), local_, ipv6_,
true);
424 name_ = src_delimiter + 1;
430 const char *delimiter = strrchr (name_,
':');
437 std::string addr_str (name_, delimiter - name_);
438 std::string port_str (delimiter + 1);
441 if (addr_str.size () >= 2 && addr_str [0] ==
'[' &&
442 addr_str [addr_str.size () - 1] ==
']')
443 addr_str = addr_str.substr (1, addr_str.size () - 2);
447 std::size_t pos = addr_str.rfind(
"%");
448 uint32_t zone_id = 0;
449 if (pos != std::string::npos) {
450 std::string if_str = addr_str.substr(pos + 1);
451 addr_str = addr_str.substr(0, pos);
452 if (isalpha (if_str.at (0)))
453 #if !defined ZMQ_HAVE_WINDOWS_TARGET_XP 454 zone_id = if_nametoindex(if_str.c_str());
464 zone_id = (uint32_t) atoi (if_str.c_str ());
474 if (port_str ==
"*" || port_str ==
"0")
479 port = (uint16_t) atoi (port_str.c_str ());
488 if (local_ || is_src_)
505 if (
address.generic.sa_family == AF_INET6) {
506 address.ipv6.sin6_port = htons (port);
507 address.ipv6.sin6_scope_id = zone_id;
510 address.ipv4.sin_port = htons (port);
518 if (
address.generic.sa_family != AF_INET
519 &&
address.generic.sa_family != AF_INET6) {
526 char hbuf [NI_MAXHOST];
527 int rc = getnameinfo (
addr (),
addrlen (), hbuf,
sizeof (hbuf), NULL, 0, NI_NUMERICHOST);
533 if (
address.generic.sa_family == AF_INET6) {
535 s <<
"tcp://[" << hbuf <<
"]:" << ntohs (
address.ipv6.sin6_port);
540 s <<
"tcp://" << hbuf <<
":" << ntohs (
address.ipv4.sin_port);
553 if (
address.generic.sa_family == AF_INET6)
554 return (socklen_t)
sizeof (
address.ipv6);
556 return (socklen_t)
sizeof (
address.ipv4);
566 if (
address.generic.sa_family == AF_INET6)
577 #if defined ZMQ_HAVE_WINDOWS 583 return address.generic.sa_family;
601 std::string addr_str, mask_str;
602 const char *delimiter = strrchr (name_,
'/');
603 if (delimiter != NULL) {
604 addr_str.assign (name_, delimiter - name_);
605 mask_str.assign (delimiter + 1);
606 if (mask_str.empty ()) {
612 addr_str.assign (name_);
621 if (mask_str.empty ()) {
622 if (
address.generic.sa_family == AF_INET6)
631 const int mask = atoi (mask_str.c_str ());
634 (
address.generic.sa_family == AF_INET6 && mask > 128) ||
635 (
address.generic.sa_family != AF_INET6 && mask > 32)
648 if (
address.generic.sa_family != AF_INET
649 &&
address.generic.sa_family != AF_INET6) {
658 char hbuf [NI_MAXHOST];
659 int rc = getnameinfo (
addr (),
addrlen (), hbuf,
sizeof (hbuf), NULL, 0, NI_NUMERICHOST);
665 if (
address.generic.sa_family == AF_INET6) {
682 && ss_len >= (socklen_t)
sizeof (
struct sockaddr));
684 if (ss->sa_family !=
address.generic.sa_family)
689 const uint8_t *our_bytes, *their_bytes;
690 if (ss->sa_family == AF_INET6) {
691 zmq_assert (ss_len ==
sizeof (
struct sockaddr_in6));
692 their_bytes = (
const uint8_t *) &(((
const struct sockaddr_in6 *) ss)->sin6_addr);
693 our_bytes = (
const uint8_t *) &
address.ipv6.sin6_addr;
694 mask = sizeof (
struct in6_addr) * 8;
697 zmq_assert (ss_len ==
sizeof (
struct sockaddr_in));
698 their_bytes = (
const uint8_t *) &(((
const struct sockaddr_in *) ss)->sin_addr);
699 our_bytes = (
const uint8_t *) &
address.ipv4.sin_addr;
700 mask = sizeof (
struct in_addr) * 8;
705 const size_t full_bytes = mask / 8;
706 if (memcmp (our_bytes, their_bytes, full_bytes))
709 const uint8_t last_byte_bits = 0xffU << (8 - mask % 8);
710 if (last_byte_bits) {
711 if ((their_bytes [full_bytes] & last_byte_bits) != (our_bytes [full_bytes] & last_byte_bits))
virtual int to_string(std::string &addr_)
int to_string(std::string &addr_)
fd_t open_socket(int domain_, int type_, int protocol_)
int resolve_nic_name(const char *nic_, bool ipv6_, bool is_src_=false)
bool has_src_addr() const
socklen_t src_addrlen() const
int resolve(const char *name_, bool ipv6_)
int resolve_hostname(const char *hostname_, bool ipv6_, bool is_src_=false)
int resolve(const char *name_, bool local_, bool ipv6_, bool is_src_=false)
union zmq::tcp_address_t::@59 address
#define LIBZMQ_UNUSED(object)
bool match_address(const struct sockaddr *ss, const socklen_t ss_len) const
const sockaddr * addr() const
socklen_t addrlen() const
sa_family_t family() const
int resolve_interface(const char *interface_, bool ipv6_, bool is_src_=false)
union zmq::tcp_address_t::@60 source_address
const sockaddr * src_addr() const