| version 1.1, 2012/02/21 17:26:12 | version 1.1.1.3, 2013/07/21 23:54:39 | 
| Line 177  sockunion2str (union sockunion *su, char *buf, size_t | Line 177  sockunion2str (union sockunion *su, char *buf, size_t | 
 | union sockunion * | union sockunion * | 
 | sockunion_str2su (const char *str) | sockunion_str2su (const char *str) | 
 | { | { | 
| int ret; | union sockunion *su = XCALLOC (MTYPE_SOCKUNION, sizeof (union sockunion)); | 
| union sockunion *su; |  | 
|  | if (!str2sockunion (str, su)) | 
| su = XCALLOC (MTYPE_SOCKUNION, sizeof (union sockunion)); | return su; | 
|  |  | 
| ret = inet_pton (AF_INET, str, &su->sin.sin_addr); |  | 
| if (ret > 0)                  /* Valid IPv4 address format. */ |  | 
| { |  | 
| su->sin.sin_family = AF_INET; |  | 
| #ifdef HAVE_STRUCT_SOCKADDR_IN_SIN_LEN |  | 
| su->sin.sin_len = sizeof(struct sockaddr_in); |  | 
| #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ |  | 
| return su; |  | 
| } |  | 
| #ifdef HAVE_IPV6 |  | 
| ret = inet_pton (AF_INET6, str, &su->sin6.sin6_addr); |  | 
| if (ret > 0)                  /* Valid IPv6 address format. */ |  | 
| { |  | 
| su->sin6.sin6_family = AF_INET6; |  | 
| #ifdef SIN6_LEN |  | 
| su->sin6.sin6_len = sizeof(struct sockaddr_in6); |  | 
| #endif /* SIN6_LEN */ |  | 
| return su; |  | 
| } |  | 
| #endif /* HAVE_IPV6 */ |  | 
|  |  | 
 | XFREE (MTYPE_SOCKUNION, su); | XFREE (MTYPE_SOCKUNION, su); | 
 | return NULL; | return NULL; | 
 | } | } | 
 |  |  | 
 | char * |  | 
 | sockunion_su2str (union sockunion *su) |  | 
 | { |  | 
 | char str[SU_ADDRSTRLEN]; |  | 
 |  |  | 
 | switch (su->sa.sa_family) |  | 
 | { |  | 
 | case AF_INET: |  | 
 | inet_ntop (AF_INET, &su->sin.sin_addr, str, sizeof (str)); |  | 
 | break; |  | 
 | #ifdef HAVE_IPV6 |  | 
 | case AF_INET6: |  | 
 | inet_ntop (AF_INET6, &su->sin6.sin6_addr, str, sizeof (str)); |  | 
 | break; |  | 
 | #endif /* HAVE_IPV6 */ |  | 
 | } |  | 
 | return XSTRDUP (MTYPE_TMP, str); |  | 
 | } |  | 
 |  |  | 
 | /* Convert IPv4 compatible IPv6 address to IPv4 address. */ | /* Convert IPv4 compatible IPv6 address to IPv4 address. */ | 
 | static void | static void | 
 | sockunion_normalise_mapped (union sockunion *su) | sockunion_normalise_mapped (union sockunion *su) | 
| Line 297  sockunion_sizeof (union sockunion *su) | Line 257  sockunion_sizeof (union sockunion *su) | 
 | } | } | 
 |  |  | 
 | /* return sockunion structure : this function should be revised. */ | /* return sockunion structure : this function should be revised. */ | 
| static char * | static const char * | 
| sockunion_log (union sockunion *su) | sockunion_log (union sockunion *su, char *buf, size_t len) | 
 | { | { | 
 | static char buf[SU_ADDRSTRLEN]; |  | 
 |  |  | 
 | switch (su->sa.sa_family) | switch (su->sa.sa_family) | 
 | { | { | 
 | case AF_INET: | case AF_INET: | 
| snprintf (buf, SU_ADDRSTRLEN, "%s", inet_ntoa (su->sin.sin_addr)); | return inet_ntop(AF_INET, &su->sin.sin_addr, buf, len); | 
| break; |  | 
 | #ifdef HAVE_IPV6 | #ifdef HAVE_IPV6 | 
 | case AF_INET6: | case AF_INET6: | 
| snprintf (buf, SU_ADDRSTRLEN, "%s", | return inet_ntop(AF_INET6, &(su->sin6.sin6_addr), buf, len); | 
| inet_ntop (AF_INET6, &(su->sin6.sin6_addr), buf, SU_ADDRSTRLEN)); |  | 
 | break; | break; | 
 | #endif /* HAVE_IPV6 */ | #endif /* HAVE_IPV6 */ | 
 |  |  | 
 | default: | default: | 
| snprintf (buf, SU_ADDRSTRLEN, "af_unknown %d ", su->sa.sa_family); | snprintf (buf, len, "af_unknown %d ", su->sa.sa_family); | 
| break; | return buf; | 
 | } | } | 
 | return (XSTRDUP (MTYPE_TMP, buf)); |  | 
 | } | } | 
 |  |  | 
 | /* sockunion_connect returns | /* sockunion_connect returns | 
| Line 379  sockunion_connect (int fd, union sockunion *peersu, un | Line 336  sockunion_connect (int fd, union sockunion *peersu, un | 
 | { | { | 
 | if (errno != EINPROGRESS) | if (errno != EINPROGRESS) | 
 | { | { | 
 |  | char str[SU_ADDRSTRLEN]; | 
 | zlog_info ("can't connect to %s fd %d : %s", | zlog_info ("can't connect to %s fd %d : %s", | 
| sockunion_log (&su), fd, safe_strerror (errno)); | sockunion_log (&su, str, sizeof str), | 
|  | fd, safe_strerror (errno)); | 
 | return connect_error; | return connect_error; | 
 | } | } | 
 | } | } | 
| Line 423  sockunion_bind (int sock, union sockunion *su, unsigne | Line 382  sockunion_bind (int sock, union sockunion *su, unsigne | 
 | su->sin.sin_len = size; | su->sin.sin_len = size; | 
 | #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ | #endif /* HAVE_STRUCT_SOCKADDR_IN_SIN_LEN */ | 
 | if (su_addr == NULL) | if (su_addr == NULL) | 
| su->sin.sin_addr.s_addr = htonl (INADDR_ANY); | sockunion2ip (su) = htonl (INADDR_ANY); | 
 | } | } | 
 | #ifdef HAVE_IPV6 | #ifdef HAVE_IPV6 | 
 | else if (su->sa.sa_family == AF_INET6) | else if (su->sa.sa_family == AF_INET6) | 
| Line 567  sockopt_minttl (int family, int sock, int minttl) | Line 526  sockopt_minttl (int family, int sock, int minttl) | 
 | return -1; | return -1; | 
 | } | } | 
 |  |  | 
 |  | int | 
 |  | sockopt_v6only (int family, int sock) | 
 |  | { | 
 |  | int ret, on = 1; | 
 |  |  | 
 |  | #ifdef HAVE_IPV6 | 
 |  | #ifdef IPV6_V6ONLY | 
 |  | if (family == AF_INET6) | 
 |  | { | 
 |  | ret = setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, | 
 |  | (void *) &on, sizeof (int)); | 
 |  | if (ret < 0) | 
 |  | { | 
 |  | zlog (NULL, LOG_WARNING, "can't set sockopt IPV6_V6ONLY " | 
 |  | "to socket %d", sock); | 
 |  | return -1; | 
 |  | } | 
 |  | return 0; | 
 |  | } | 
 |  | #endif /* IPV6_V6ONLY */ | 
 |  | #endif /* HAVE_IPV6 */ | 
 |  | return 0; | 
 |  | } | 
 |  |  | 
 | /* If same family and same prefix return 1. */ | /* If same family and same prefix return 1. */ | 
 | int | int | 
 | sockunion_same (union sockunion *su1, union sockunion *su2) | sockunion_same (union sockunion *su1, union sockunion *su2) | 
| Line 756  sockunion_cmp (union sockunion *su1, union sockunion * | Line 739  sockunion_cmp (union sockunion *su1, union sockunion * | 
 |  |  | 
 | if (su1->sa.sa_family == AF_INET) | if (su1->sa.sa_family == AF_INET) | 
 | { | { | 
| if (ntohl (su1->sin.sin_addr.s_addr) == ntohl (su2->sin.sin_addr.s_addr)) | if (ntohl (sockunion2ip (su1)) == ntohl (sockunion2ip (su2))) | 
 | return 0; | return 0; | 
| if (ntohl (su1->sin.sin_addr.s_addr) > ntohl (su2->sin.sin_addr.s_addr)) | if (ntohl (sockunion2ip (su1)) > ntohl (sockunion2ip (su2))) | 
 | return 1; | return 1; | 
 | else | else | 
 | return -1; | return -1; |