📄 exutils.c
字号:
*serverip = NULL; *netmask = NULL; /* First, try to get the interface where we should listen */ { DWORD size_of_iptable = 0; PMIB_IPADDRTABLE ipt; PMIB_IFROW ifrow; if (GetIpAddrTable (NULL, &size_of_iptable, TRUE) == ERROR_INSUFFICIENT_BUFFER) { ifrow = (PMIB_IFROW) _alloca (sizeof (MIB_IFROW)); ipt = (PMIB_IPADDRTABLE) _alloca (size_of_iptable); if (ifrow == NULL || ipt == NULL) { /* not very usefull to continue */ OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO4, NULL, "ERROR alloca failed\r\n")); return -1; } 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 -1; } return 0;}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 -1; } 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 -1; } 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 -1; } return 0;}#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_ipv6_with_getifaddrs(char *address, int size){ struct ifaddrs *ifp; struct ifaddrs *ifpstart; int ret=-1; if (getifaddrs (&ifpstart) < 0){ return -1; } for (ifp=ifpstart; ifp != NULL; ifp = ifp->ifa_next) { if (ifp->ifa_addr && ifp->ifa_addr->sa_family==AF_INET6 && (ifp->ifa_flags & IFF_RUNNING) && !(ifp->ifa_flags & IFF_LOOPBACK) ) { getnameinfo(ifp->ifa_addr,sizeof(struct sockaddr_in6),address,size,NULL,0,NI_NUMERICHOST); if (strchr(address,'%')==NULL){ /*avoid link-local addresses */ OSIP_TRACE (osip_trace(__FILE__, __LINE__, OSIP_INFO2, NULL,"_eXosip_default_gateway_ipv6_with_getifaddrs(): found %s\n",address)); ret=0; break; } } } freeifaddrs (ifpstart); return ret;}#endifinteXosip_guess_ip_for_via (int family, char *address, int size){ if (family == AF_INET6) { int err; err=_eXosip_default_gateway_ipv6 (address, size);#ifdef HAVE_GETIFADDRS if (err<0) err=_eXosip_default_gateway_ipv6_with_getifaddrs(address,size);#endif return err; }else { return _eXosip_default_gateway_ipv4 (address, size); }}/* 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 -1; } 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 -1; } 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 -1; } close (sock_rt); if (iface_out.sin_addr.s_addr == 0) { /* what is this case?? */ snprintf(address, size, "127.0.0.1"); return -1; } osip_strncpy (address, inet_ntoa (iface_out.sin_addr), size - 1); return 0;}/* 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 -1; } if (connect (sock_rt, (struct sockaddr *) &remote, sizeof (struct sockaddr_in6)) == -1) { perror ("DEBUG: [get_output_if] connect"); close (sock_rt); return -1; } len = sizeof (iface_out); if (getsockname (sock_rt, (struct sockaddr *) &iface_out, &len) == -1) { perror ("DEBUG: [get_output_if] getsockname"); close (sock_rt); return -1; } close (sock_rt); if (iface_out.sin6_addr.s6_addr == 0) { /* what is this case?? */ return -1; } inet_ntop (AF_INET6, (const void *) &iface_out.sin6_addr, address, size - 1); return 0;}#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 -1; 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -