exutils.c

来自「mediastreamer2是开源的网络传输媒体流的库」· C语言 代码 · 共 1,770 行 · 第 1/4 页

C
1,770
字号
            OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO4, NULL,                                    "ERROR alloca failed\r\n"));            return OSIP_NOMEM;          }        if (!GetIpAddrTable (ipt, &size_of_iptable, TRUE))          {            /* look for the best public interface */            for (pos = 0; pos < ipt->dwNumEntries && *netmask == NULL; ++pos)              {                /* index is */                struct in_addr addr;                struct in_addr mask;                ifrow->dwIndex = ipt->table[pos].dwIndex;                if (GetIfEntry (ifrow) == NO_ERROR)                  {                    switch (ifrow->dwType)                      {                        case MIB_IF_TYPE_LOOPBACK:                          /*    break; */                        case MIB_IF_TYPE_ETHERNET:                        default:                          addr.s_addr = ipt->table[pos].dwAddr;                          mask.s_addr = ipt->table[pos].dwMask;                          if (ipt->table[pos].dwIndex == WIN32_interface)                            {                              *servername = NULL;       /* no name on win32? */                              *serverip = osip_strdup (inet_ntoa (addr));                              *netmask = osip_strdup (inet_ntoa (mask));                              OSIP_TRACE (osip_trace                                          (__FILE__, __LINE__, OSIP_INFO4, NULL,                                           "Interface ethernet: %s/%s\r\n",                                           *serverip, *netmask));                              break;                            }                      }                  }              }          }      }  }  if (*serverip == NULL || *netmask == NULL)    {      OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_WARNING, NULL,                              "ERROR No network interface found\r\n"));      return OSIP_NO_NETWORK;    }  return OSIP_SUCCESS;}inteXosip_guess_ip_for_via (int family, char *address, int size){  SOCKET sock;  SOCKADDR_STORAGE local_addr;  int local_addr_len;  struct addrinfo *addrf;  address[0] = '\0';  sock = socket (family, SOCK_DGRAM, 0);  if (family == AF_INET)    {      getaddrinfo (eXosip.ipv4_for_gateway, NULL, NULL, &addrf);  } else if (family == AF_INET6)    {      getaddrinfo (eXosip.ipv6_for_gateway, NULL, NULL, &addrf);    }  if (addrf == NULL)    {      closesocket (sock);      snprintf (address, size, (family == AF_INET) ? "127.0.0.1" : "::1");      return OSIP_NO_NETWORK;    }  if (WSAIoctl      (sock, SIO_ROUTING_INTERFACE_QUERY, addrf->ai_addr, addrf->ai_addrlen,       &local_addr, sizeof (local_addr), &local_addr_len, NULL, NULL) != 0)    {      closesocket (sock);      freeaddrinfo (addrf);      snprintf (address, size, (family == AF_INET) ? "127.0.0.1" : "::1");      return OSIP_NO_NETWORK;    }  closesocket (sock);  freeaddrinfo (addrf);  if (getnameinfo ((const struct sockaddr *) &local_addr,                   local_addr_len, address, size, NULL, 0, NI_NUMERICHOST))    {      snprintf (address, size, (family == AF_INET) ? "127.0.0.1" : "::1");      return OSIP_NO_NETWORK;    }  return OSIP_SUCCESS;}#else /* sun, *BSD, linux, and other? */#include <sys/types.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <sys/ioctl.h>#include <net/if.h>#include <unistd.h>#include <sys/param.h>#include <stdio.h>static int _eXosip_default_gateway_ipv4 (char *address, int size);static int _eXosip_default_gateway_ipv6 (char *address, int size);#ifdef HAVE_GETIFADDRS#include <ifaddrs.h>static int_eXosip_default_gateway_with_getifaddrs (int type, char *address, int size){  struct ifaddrs *ifp;  struct ifaddrs *ifpstart;  int ret = -1;  if (getifaddrs (&ifpstart) < 0)    {      return OSIP_NO_NETWORK;    }  for (ifp = ifpstart; ifp != NULL; ifp = ifp->ifa_next)    {      if (ifp->ifa_addr && ifp->ifa_addr->sa_family == type          && (ifp->ifa_flags & IFF_RUNNING) && !(ifp->ifa_flags & IFF_LOOPBACK))        {          getnameinfo (ifp->ifa_addr,                       (type == AF_INET6) ?                       sizeof (struct sockaddr_in6) : sizeof (struct sockaddr_in),                       address, size, NULL, 0, NI_NUMERICHOST);          if (strchr (address, '%') == NULL)            {                   /*avoid ipv6 link-local addresses */              OSIP_TRACE (osip_trace                          (__FILE__, __LINE__, OSIP_INFO2, NULL,                           "_eXosip_default_gateway_with_getifaddrs(): found %s\n",                           address));              ret = 0;              break;            }        }    }  freeifaddrs (ifpstart);  return ret;}#endifinteXosip_guess_ip_for_via (int family, char *address, int size){  int err;  if (family == AF_INET6)    {      err = _eXosip_default_gateway_ipv6 (address, size);  } else    {      err = _eXosip_default_gateway_ipv4 (address, size);    }#ifdef HAVE_GETIFADDRS  if (err < 0)    err = _eXosip_default_gateway_with_getifaddrs (family, address, size);#endif  return err;}/* This is a portable way to find the default gateway. * The ip of the default interface is returned. */static int_eXosip_default_gateway_ipv4 (char *address, int size){#ifdef __APPLE_CC__  int len;#else  unsigned int len;#endif  int sock_rt, on = 1;  struct sockaddr_in iface_out;  struct sockaddr_in remote;  memset (&remote, 0, sizeof (struct sockaddr_in));  remote.sin_family = AF_INET;  remote.sin_addr.s_addr = inet_addr (eXosip.ipv4_for_gateway);  remote.sin_port = htons (11111);  memset (&iface_out, 0, sizeof (iface_out));  sock_rt = socket (AF_INET, SOCK_DGRAM, 0);  if (setsockopt (sock_rt, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) == -1)    {      perror ("DEBUG: [get_output_if] setsockopt(SOL_SOCKET, SO_BROADCAST");      close (sock_rt);      snprintf (address, size, "127.0.0.1");      return OSIP_NO_NETWORK;    }  if (connect      (sock_rt, (struct sockaddr *) &remote, sizeof (struct sockaddr_in)) == -1)    {      perror ("DEBUG: [get_output_if] connect");      close (sock_rt);      snprintf (address, size, "127.0.0.1");      return OSIP_NO_NETWORK;    }  len = sizeof (iface_out);  if (getsockname (sock_rt, (struct sockaddr *) &iface_out, &len) == -1)    {      perror ("DEBUG: [get_output_if] getsockname");      close (sock_rt);      snprintf (address, size, "127.0.0.1");      return OSIP_NO_NETWORK;    }  close (sock_rt);  if (iface_out.sin_addr.s_addr == 0)    {                           /* what is this case?? */      snprintf (address, size, "127.0.0.1");      return OSIP_NO_NETWORK;    }  osip_strncpy (address, inet_ntoa (iface_out.sin_addr), size - 1);  return OSIP_SUCCESS;}/* This is a portable way to find the default gateway. * The ip of the default interface is returned. */static int_eXosip_default_gateway_ipv6 (char *address, int size){#ifdef __APPLE_CC__  int len;#else  unsigned int len;#endif  int sock_rt, on = 1;  struct sockaddr_in6 iface_out;  struct sockaddr_in6 remote;  memset (&remote, 0, sizeof (struct sockaddr_in6));  remote.sin6_family = AF_INET6;  inet_pton (AF_INET6, eXosip.ipv6_for_gateway, &remote.sin6_addr);  remote.sin6_port = htons (11111);  memset (&iface_out, 0, sizeof (iface_out));  sock_rt = socket (AF_INET6, SOCK_DGRAM, 0);  /*default to ipv6 local loopback in case something goes wrong: */  strncpy (address, "::1", size);  if (setsockopt (sock_rt, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) == -1)    {      perror ("DEBUG: [get_output_if] setsockopt(SOL_SOCKET, SO_BROADCAST");      close (sock_rt);      return OSIP_NO_NETWORK;    }  if (connect      (sock_rt, (struct sockaddr *) &remote, sizeof (struct sockaddr_in6)) == -1)    {      perror ("DEBUG: [get_output_if] connect");      close (sock_rt);      return OSIP_NO_NETWORK;    }  len = sizeof (iface_out);  if (getsockname (sock_rt, (struct sockaddr *) &iface_out, &len) == -1)    {      perror ("DEBUG: [get_output_if] getsockname");      close (sock_rt);      return OSIP_NO_NETWORK;    }  close (sock_rt);  if (iface_out.sin6_addr.s6_addr == 0)    {                           /* what is this case?? */      return OSIP_NO_NETWORK;    }  inet_ntop (AF_INET6, (const void *) &iface_out.sin6_addr, address, size - 1);  return OSIP_SUCCESS;}#endifchar *strdup_printf (const char *fmt, ...){  /* Guess we need no more than 100 bytes. */  int n, size = 100;  char *p;  va_list ap;  if ((p = osip_malloc (size)) == NULL)    return NULL;  while (1)    {      /* Try to print in the allocated space. */      va_start (ap, fmt);#ifdef WIN32      n = _vsnprintf (p, size, fmt, ap);#else      n = vsnprintf (p, size, fmt, ap);#endif      va_end (ap);      /* If that worked, return the string. */      if (n > -1 && n < size)        return p;      /* Else try again with more space. */      if (n > -1)               /* glibc 2.1 */        size = n + 1;           /* precisely what is needed */      else                      /* glibc 2.0 */        size *= 2;              /* twice the old size */      if ((p = realloc (p, size)) == NULL)        return NULL;    }}#if !defined(USE_GETHOSTBYNAME)inteXosip_get_addrinfo (struct addrinfo **addrinfo, const char *hostname,                     int service, int protocol){  struct addrinfo hints;  int error;  char portbuf[10];  if (hostname == NULL)    return OSIP_BADPARAMETER;  if (service != -1)            /* -1 for SRV record */    {      int i;      for (i = 0; i < MAX_EXOSIP_DNS_ENTRY; i++)        {          if (eXosip.dns_entries[i].host[0] != '\0'              && 0 == osip_strcasecmp (eXosip.dns_entries[i].host, hostname))            {              /* update entry */              if (eXosip.dns_entries[i].ip[0] != '\0')                {                  hostname = eXosip.dns_entries[i].ip;                  OSIP_TRACE (osip_trace                              (__FILE__, __LINE__, OSIP_INFO1, NULL,                               "eXosip option set: dns cache used:%s -> %s\n",                               eXosip.dns_entries[i].host,                               eXosip.dns_entries[i].ip));                }            }        }    }  if (service != -1)            /* -1 for SRV record */    snprintf (portbuf, sizeof (portbuf), "%i", service);  memset (&hints, 0, sizeof (hints));  hints.ai_flags = 0;  if (ipv6_enable)    hints.ai_family = PF_INET6;  else    hints.ai_family = PF_INET;  /* ipv4 only support */  if (protocol == IPPROTO_UDP)    hints.ai_socktype = SOCK_DGRAM;  else    hints.ai_socktype = SOCK_STREAM;  hints.ai_protocol = protocol; /* IPPROTO_UDP or IPPROTO_TCP */  if (service == -1)            /* -1 for SRV record */    {      error = getaddrinfo (hostname, "sip", &hints, addrinfo);      OSIP_TRACE (osip_trace                  (__FILE__, __LINE__, OSIP_INFO2, NULL,                   "SRV resolution with udp-sip-%s\n", hostname));  } else    {      error = getaddrinfo (hostname, portbuf, &hints, addrinfo);      OSIP_TRACE (osip_trace                  (__FILE__, __LINE__, OSIP_INFO2, NULL,                   "DNS resolution with %s:%i\n", hostname, service));    }  if (error || *addrinfo == NULL)    {      OSIP_TRACE (osip_trace                  (__FILE__, __LINE__, OSIP_INFO2, NULL,                   "getaddrinfo failure. %s:%s (%d)\n", hostname, portbuf, error));      return OSIP_UNKNOWN_HOST;  } else    {      struct addrinfo *elem;      char tmp[INET6_ADDRSTRLEN];      char porttmp[10];      OSIP_TRACE (osip_trace                  (__FILE__, __LINE__, OSIP_INFO2, NULL,                   "getaddrinfo returned the following addresses:\n"));      for (elem = *addrinfo; elem != NULL; elem = elem->ai_next)        {          getnameinfo (elem->ai_addr, elem->ai_addrlen, tmp, sizeof (tmp), porttmp,                       sizeof (porttmp), NI_NUMERICHOST | NI_NUMERICSERV);          OSIP_TRACE (osip_trace                      (__FILE__, __LINE__, OSIP_INFO2, NULL, "%s port %s\n", tmp,                       porttmp));        }    }

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?