Diff for /embedaddon/quagga/lib/sockunion.c between versions 1.1 and 1.1.1.4

version 1.1, 2012/02/21 17:26:12 version 1.1.1.4, 2016/11/02 10:09:11
Line 27 Line 27
 #include "memory.h"  #include "memory.h"
 #include "str.h"  #include "str.h"
 #include "log.h"  #include "log.h"
   #include "jhash.h"
   
 #ifndef HAVE_INET_ATON  #ifndef HAVE_INET_ATON
 int  int
Line 116  inet_ntop (int family, const void *addrptr, char *strp Line 117  inet_ntop (int family, const void *addrptr, char *strp
 #endif /* ! HAVE_INET_NTOP */  #endif /* ! HAVE_INET_NTOP */
   
 const char *  const char *
inet_sutop (union sockunion *su, char *str)inet_sutop (const union sockunion *su, char *str)
 {  {
   switch (su->sa.sa_family)    switch (su->sa.sa_family)
     {      {
Line 163  str2sockunion (const char *str, union sockunion *su) Line 164  str2sockunion (const char *str, union sockunion *su)
 }  }
   
 const char *  const char *
sockunion2str (union sockunion *su, char *buf, size_t len)sockunion2str (const union sockunion *su, char *buf, size_t len)
 {  {
  if  (su->sa.sa_family == AF_INET)  switch (sockunion_family(su))
    return inet_ntop (AF_INET, &su->sin.sin_addr, buf, len);    {
     case AF_UNSPEC:
       snprintf (buf, len, "(unspec)");
       return buf;
     case AF_INET:
       return inet_ntop (AF_INET, &su->sin.sin_addr, buf, len);
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
  else if (su->sa.sa_family == AF_INET6)    case AF_INET6:
    return inet_ntop (AF_INET6, &su->sin6.sin6_addr, buf, len);      return inet_ntop (AF_INET6, &su->sin6.sin6_addr, buf, len);
 #endif /* HAVE_IPV6 */  #endif /* HAVE_IPV6 */
  return NULL;    }
   snprintf (buf, len, "(af %d)", sockunion_family(su));
   return buf;
 }  }
   
 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 247  sockunion_normalise_mapped (union sockunion *su) Line 215  sockunion_normalise_mapped (union sockunion *su)
   
 /* Return socket of sockunion. */  /* Return socket of sockunion. */
 int  int
sockunion_socket (union sockunion *su)sockunion_socket (const union sockunion *su)
 {  {
   int sock;    int sock;
   
Line 277  sockunion_accept (int sock, union sockunion *su) Line 245  sockunion_accept (int sock, union sockunion *su)
   
 /* Return sizeof union sockunion.  */  /* Return sizeof union sockunion.  */
 static int  static int
sockunion_sizeof (union sockunion *su)sockunion_sizeof (const union sockunion *su)
 {  {
   int ret;    int ret;
   
Line 297  sockunion_sizeof (union sockunion *su) Line 265  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 (const 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 325  sockunion_log (union sockunion *su) Line 290  sockunion_log (union sockunion *su)
    0 : connect success     0 : connect success
    1 : connect is in progress */     1 : connect is in progress */
 enum connect_result  enum connect_result
sockunion_connect (int fd, union sockunion *peersu, unsigned short port,sockunion_connect (int fd, const union sockunion *peersu, unsigned short port,
                   unsigned int ifindex)                   ifindex_t ifindex)
 {  {
   int ret;    int ret;
   int val;    int val;
Line 347  sockunion_connect (int fd, union sockunion *peersu, un Line 312  sockunion_connect (int fd, union sockunion *peersu, un
         {          {
 #ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID  #ifdef HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID
           /* su.sin6.sin6_scope_id = ifindex; */            /* su.sin6.sin6_scope_id = ifindex; */
 #ifdef MUSICA  
           su.sin6.sin6_scope_id = ifindex;   
 #endif  
 #endif /* HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID */  #endif /* HAVE_STRUCT_SOCKADDR_IN6_SIN6_SCOPE_ID */
 #ifndef MUSICA  
           SET_IN6_LINKLOCAL_IFINDEX (su.sin6.sin6_addr, ifindex);            SET_IN6_LINKLOCAL_IFINDEX (su.sin6.sin6_addr, ifindex);
 #endif  
         }          }
 #endif /* KAME */  #endif /* KAME */
       break;        break;
Line 379  sockunion_connect (int fd, union sockunion *peersu, un Line 339  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 385  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 435  sockunion_bind (int sock, union sockunion *su, unsigne Line 397  sockunion_bind (int sock, union sockunion *su, unsigne
 #endif /* SIN6_LEN */  #endif /* SIN6_LEN */
       if (su_addr == NULL)        if (su_addr == NULL)
         {          {
#if defined(LINUX_IPV6) || defined(NRL)#ifdef LINUX_IPV6
           memset (&su->sin6.sin6_addr, 0, sizeof (struct in6_addr));            memset (&su->sin6.sin6_addr, 0, sizeof (struct in6_addr));
 #else  #else
           su->sin6.sin6_addr = in6addr_any;            su->sin6.sin6_addr = in6addr_any;
Line 567  sockopt_minttl (int family, int sock, int minttl) Line 529  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 (const union sockunion *su1, const union sockunion *su2)
 {  {
   int ret = 0;    int ret = 0;
   
Line 595  sockunion_same (union sockunion *su1, union sockunion  Line 581  sockunion_same (union sockunion *su1, union sockunion 
     return 0;      return 0;
 }  }
   
   unsigned int
   sockunion_hash (const union sockunion *su)
   {
     switch (sockunion_family(su))
       {
       case AF_INET:
         return jhash_1word(su->sin.sin_addr.s_addr, 0);
   #ifdef HAVE_IPV6
       case AF_INET6:
         return jhash2(su->sin6.sin6_addr.s6_addr32, ZEBRA_NUM_OF(su->sin6.sin6_addr.s6_addr32), 0);
   #endif /* HAVE_IPV6 */
       }
     return 0;
   }
   
   size_t
   family2addrsize(int family)
   {
     switch (family)
       {
       case AF_INET:
         return sizeof(struct in_addr);
   #ifdef HAVE_IPV6
       case AF_INET6:
         return sizeof(struct in6_addr);
   #endif /* HAVE_IPV6 */
       }
     return 0;
   }
   
   size_t
   sockunion_get_addrlen(const union sockunion *su)
   {
     return family2addrsize(sockunion_family(su));
   }
   
   const u_char *
   sockunion_get_addr(const union sockunion *su)
   {
     switch (sockunion_family(su))
       {
       case AF_INET:
         return (const u_char *) &su->sin.sin_addr.s_addr;
   #ifdef HAVE_IPV6
       case AF_INET6:
         return (const u_char *) &su->sin6.sin6_addr;
   #endif /* HAVE_IPV6 */
       }
     return NULL;
   }
   
   void
   sockunion_set(union sockunion *su, int family, const u_char *addr, size_t bytes)
   {
     if (family2addrsize(family) != bytes)
       return;
   
     sockunion_family(su) = family;
     switch (family)
       {
       case AF_INET:
         memcpy(&su->sin.sin_addr.s_addr, addr, bytes);
         break;
   #ifdef HAVE_IPV6
       case AF_INET6:
         memcpy(&su->sin6.sin6_addr, addr, bytes);
         break;
   #endif /* HAVE_IPV6 */
       }
   }
   
 /* After TCP connection is established.  Get local address and port. */  /* After TCP connection is established.  Get local address and port. */
 union sockunion *  union sockunion *
 sockunion_getsockname (int fd)  sockunion_getsockname (int fd)
Line 688  sockunion_getpeername (int fd) Line 745  sockunion_getpeername (int fd)
   
 /* Print sockunion structure */  /* Print sockunion structure */
 static void __attribute__ ((unused))  static void __attribute__ ((unused))
sockunion_print (union sockunion *su)sockunion_print (const union sockunion *su)
 {  {
   if (su == NULL)    if (su == NULL)
     return;      return;
Line 727  sockunion_print (union sockunion *su) Line 784  sockunion_print (union sockunion *su)
   
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
 static int  static int
in6addr_cmp (struct in6_addr *addr1, struct in6_addr *addr2)in6addr_cmp (const struct in6_addr *addr1, const struct in6_addr *addr2)
 {  {
   unsigned int i;    unsigned int i;
   u_char *p1, *p2;    u_char *p1, *p2;
Line 747  in6addr_cmp (struct in6_addr *addr1, struct in6_addr * Line 804  in6addr_cmp (struct in6_addr *addr1, struct in6_addr *
 #endif /* HAVE_IPV6 */  #endif /* HAVE_IPV6 */
   
 int  int
sockunion_cmp (union sockunion *su1, union sockunion *su2)sockunion_cmp (const union sockunion *su1, const union sockunion *su2)
 {  {
   if (su1->sa.sa_family > su2->sa.sa_family)    if (su1->sa.sa_family > su2->sa.sa_family)
     return 1;      return 1;
Line 756  sockunion_cmp (union sockunion *su1, union sockunion * Line 813  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;
Line 772  sockunion_cmp (union sockunion *su1, union sockunion * Line 829  sockunion_cmp (union sockunion *su1, union sockunion *
   
 /* Duplicate sockunion. */  /* Duplicate sockunion. */
 union sockunion *  union sockunion *
sockunion_dup (union sockunion *su)sockunion_dup (const union sockunion *su)
 {  {
   union sockunion *dup = XCALLOC (MTYPE_SOCKUNION, sizeof (union sockunion));    union sockunion *dup = XCALLOC (MTYPE_SOCKUNION, sizeof (union sockunion));
   memcpy (dup, su, sizeof (union sockunion));    memcpy (dup, su, sizeof (union sockunion));

Removed from v.1.1  
changed lines
  Added in v.1.1.1.4


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>