6#if defined(__SUNPRO_CC) || defined (__sun__)
10#include <sys/socket.h>
11#include <netinet/in.h>
31#define RESIPROCATE_SUBSYSTEM resip::Subsystem::DNS
34#define MAXHOSTNAMELEN 256
48 names.push_back(host);
52 struct hostent* result=0;
57 struct hostent hostbuf;
59 ret = gethostbyname_r( host.
c_str(), &hostbuf, buffer,
sizeof(buffer), &result, &herrno);
61#elif defined(__QNX__) || defined(__SUNPRO_CC)
62 struct hostent hostbuf;
64 result = gethostbyname_r( host.
c_str(), &hostbuf, buffer,
sizeof(buffer), &herrno );
65#elif defined(__APPLE__)
68 result = gethostbyname( host.
c_str() );
75 if (ret != 0 || result == 0)
81 msg =
"host not found: ";
84 msg =
"no data found for: ";
87 msg =
"no recovery lookup up: ";
95 DebugLog (<<
"DNS lookup of " << host <<
" resulted in " << msg);
96 throw Exception(
"no dns resolution:" + msg, __FILE__, __LINE__);
103 for (
char** pptr = result->h_addr_list; *pptr != 0; pptr++)
105 inet_ntop(result->h_addrtype, (u_int32_t*)(*pptr), str,
sizeof(str));
106 names.push_back(str);
109 StackLog (<<
"DNS lookup of " << host <<
": canonical name: " << result->h_name
129 static const Data localHostName = lookupLocalHostName();
130 return localHostName;
134DnsUtil::lookupLocalHostName()
141 if (gethostname(buffer,
sizeof(buffer)-1) == -1)
150 CritLog( <<
"could not find local hostname because network not initialized:" <<
strError(err) );
156 throw Exception(
"could not find local hostname",__FILE__,__LINE__);
159 struct addrinfo* result=0;
160 struct addrinfo hints;
161 memset(&hints, 0,
sizeof(hints));
162 hints.ai_flags |= AI_CANONNAME;
163 hints.ai_family |= AF_UNSPEC;
164 int res = getaddrinfo(buffer, 0, &hints, &result);
168 if (strchr(result->ai_canonname,
'.') != 0)
170 snprintf(buffer,
sizeof(buffer),
"%s", result->ai_canonname);
174 InfoLog( <<
"local hostname does not contain a domain part " << buffer);
176 freeaddrinfo(result);
180 InfoLog (<<
"Couldn't determine local hostname. Error was: " << gai_strerror(res) <<
". Returning empty string");
193 return lhn.
substr(dpos+1);
197#if defined( __APPLE__ ) || defined( WIN32 ) || defined(__SUNPRO_CC) || defined(__sun__) || defined( __ANDROID__ )
198 throw Exception(
"Could not find domainname in local hostname",__FILE__,__LINE__);
200 DebugLog( <<
"No domain portion in hostname <" << lhn <<
">, so using getdomainname");
205 if (
int e = getdomainname(buffer,
sizeof(buffer)-1) == -1)
210 CritLog(<<
"Couldn't find domainname: " << strerror(err));
214 DebugLog (<<
"Found local domain name " << buffer);
229 WarningLog( <<
"No interfaces matching " << myInterface <<
" were found" );
230 throw Exception(
"No interfaces matching", __FILE__, __LINE__);
234 InfoLog (<<
"Local IP address for " << myInterface <<
" is " << ifs.
begin()->second);
235 return ifs.begin()->second;
243 inet_ntop(AF_INET, &addr, str,
sizeof(str));
252 inet_ntop(AF_INET6, &addr, str,
sizeof(str));
261 if (addr.sa_family == AF_INET6)
263 const struct sockaddr_in6* addr6 =
reinterpret_cast<const sockaddr_in6*
>(&addr);
269 const struct sockaddr_in* addr4 =
reinterpret_cast<const sockaddr_in*
>(&addr);
295 const char* first = ipAddress.
data();
296 const char* end = first + ipAddress.
size();
300 const char* last=first;
304 while(last != end && *last >=
'0' && *last <=
'9' && last - first <= 3)
335 if(*(first+1)>
'5' || (*(first+1)==
'5' && *(first+2)>
'5'))
353 if(last != end && *last ==
'.')
388 if (ipAddress.
empty())
394 if (!isxdigit(
static_cast< unsigned char >(*ipAddress.
data())) &&
395 *ipAddress.
data() !=
':')
400 switch (ipAddress.
size())
405 return (*(ipAddress.
data()+1) ==
':' ||
406 *(ipAddress.
data()+0) ==
':');
408 return (*(ipAddress.
data()+2) ==
':' ||
409 *(ipAddress.
data()+1) ==
':' ||
410 *(ipAddress.
data()+0) ==
':');
412 return (*(ipAddress.
data()+3) ==
':' ||
413 *(ipAddress.
data()+2) ==
':' ||
414 *(ipAddress.
data()+1) ==
':' ||
415 *(ipAddress.
data()+0) ==
':');
418 return (*(ipAddress.
data()+4) ==
':' ||
419 *(ipAddress.
data()+3) ==
':' ||
420 *(ipAddress.
data()+2) ==
':' ||
421 *(ipAddress.
data()+1) ==
':' ||
422 *(ipAddress.
data()+0) ==
':');
436 InfoLog(<< ipV6Address <<
" is not a well formed IPV6 address");
459std::list<std::pair<Data,Data> >
462 std::list<std::pair<Data,Data> > results;
468 int s = socket( AF_INET, SOCK_DGRAM, 0 );
470 const int len = 100 *
sizeof(
struct ifreq);
477 int e = ioctl(s,SIOCGIFCONF,&ifc);
479 int tl = ifc.ifc_len;
482 while ( (tl > 0) && ( count < maxRet) )
484 struct ifreq* ifr = (
struct ifreq *)ptr;
488#if defined(__NetBSD__) || defined(__APPLE__)
489 int si =
sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len;
491 int si =
sizeof(ifr->ifr_name) +
sizeof(ifr->ifr_ifru);
497 char* name = ifr->ifr_name;
502 e = ioctl(s,SIOCGIFADDR,&ifr2);
506 DebugLog (<<
"Ignoring interface " << name <<
" as there is no valid address" );
509 struct sockaddr a = ifr2.ifr_addr;
512 e = ioctl(s,SIOCGIFFLAGS,&ifr2);
516 DebugLog (<<
"Ignoring interface " << name <<
" as there is no valid flags" );
519 short flags = ifr2.ifr_flags;
524 struct ifmediareq media;
525 e = ioctl(s,SIOCGIFMEDIA,&media);
526 int status = media.ifm_status;
527 int active = media.ifm_active;
528 DebugLog (<<
"Media status=" << hex << status
529 <<
" active=" << hex << active << dec );
535 e = ioctl(s,SIOCGIFPHYS,&ifr2);
536 int phys= ifr2.ifr_phys;
537 DebugLog (<<
"Phys=" << hex << phys << dec );
540 DebugLog (<<
"Considering: " << name <<
" -> " << ip
541 <<
" flags=0x" << hex <<
flags << dec );
543 if ( (
flags & IFF_UP) == 0 )
545 DebugLog (<<
" ignore because: interface is not up");
549 if ( (
flags & IFF_LOOPBACK) != 0 )
551 DebugLog (<<
" ignore because: interface is loopback");
555 if ( (
flags & IFF_RUNNING) == 0 )
557 DebugLog (<<
" ignore because: interface is not running");
561 if ( ( (name[0]<
'A') || (name[0]>
'z') )
562#
if defined(__MACH__) && defined(__GNU__)
567 DebugLog (<<
" ignore because: name looks bogus");
575 results.push_back(std::make_pair(
Data(name), ip));
584 return WinCompat::getInterfaces(matching);
586 catch(WinCompat::Exception& e)
588 DebugLog (<<
" WinCompat::getInterfaces throws " << e.getMessage());
600const Data DnsUtil::UInt8ToStr[]={
601 "0.",
"1.",
"2.",
"3.",
"4.",
"5.",
"6.",
"7.",
602 "8.",
"9.",
"10.",
"11.",
"12.",
"13.",
"14.",
"15.",
603 "16.",
"17.",
"18.",
"19.",
"20.",
"21.",
"22.",
"23.",
604 "24.",
"25.",
"26.",
"27.",
"28.",
"29.",
"30.",
"31.",
605 "32.",
"33.",
"34.",
"35.",
"36.",
"37.",
"38.",
"39.",
606 "40.",
"41.",
"42.",
"43.",
"44.",
"45.",
"46.",
"47.",
607 "48.",
"49.",
"50.",
"51.",
"52.",
"53.",
"54.",
"55.",
608 "56.",
"57.",
"58.",
"59.",
"60.",
"61.",
"62.",
"63.",
609 "64.",
"65.",
"66.",
"67.",
"68.",
"69.",
"70.",
"71.",
610 "72.",
"73.",
"74.",
"75.",
"76.",
"77.",
"78.",
"79.",
611 "80.",
"81.",
"82.",
"83.",
"84.",
"85.",
"86.",
"87.",
612 "88.",
"89.",
"90.",
"91.",
"92.",
"93.",
"94.",
"95.",
613 "96.",
"97.",
"98.",
"99.",
"100.",
"101.",
"102.",
"103.",
614"104.",
"105.",
"106.",
"107.",
"108.",
"109.",
"110.",
"111.",
615"112.",
"113.",
"114.",
"115.",
"116.",
"117.",
"118.",
"119.",
616"120.",
"121.",
"122.",
"123.",
"124.",
"125.",
"126.",
"127.",
617"128.",
"129.",
"130.",
"131.",
"132.",
"133.",
"134.",
"135.",
618"136.",
"137.",
"138.",
"139.",
"140.",
"141.",
"142.",
"143.",
619"144.",
"145.",
"146.",
"147.",
"148.",
"149.",
"150.",
"151.",
620"152.",
"153.",
"154.",
"155.",
"156.",
"157.",
"158.",
"159.",
621"160.",
"161.",
"162.",
"163.",
"164.",
"165.",
"166.",
"167.",
622"168.",
"169.",
"170.",
"171.",
"172.",
"173.",
"174.",
"175.",
623"176.",
"177.",
"178.",
"179.",
"180.",
"181.",
"182.",
"183.",
624"184.",
"185.",
"186.",
"187.",
"188.",
"189.",
"190.",
"191.",
625"192.",
"193.",
"194.",
"195.",
"196.",
"197.",
"198.",
"199.",
626"200.",
"201.",
"202.",
"203.",
"204.",
"205.",
"206.",
"207.",
627"208.",
"209.",
"210.",
"211.",
"212.",
"213.",
"214.",
"215.",
628"216.",
"217.",
"218.",
"219.",
"220.",
"221.",
"222.",
"223.",
629"224.",
"225.",
"226.",
"227.",
"228.",
"229.",
"230.",
"231.",
630"232.",
"233.",
"234.",
"235.",
"236.",
"237.",
"238.",
"239.",
631"240.",
"241.",
"242.",
"243.",
"244.",
"245.",
"246.",
"247.",
632"248.",
"249.",
"250.",
"251.",
"252.",
"253.",
"254.",
"255."
636#if !(defined(WIN32) || defined(__CYGWIN__))
650 dest.
append(UInt8ToStr[bytes[0]].data(), UInt8ToStr[bytes[0]].size());
651 dest.
append(UInt8ToStr[bytes[1]].data(), UInt8ToStr[bytes[1]].size());
652 dest.
append(UInt8ToStr[bytes[2]].data(), UInt8ToStr[bytes[2]].size());
653 dest.
append(UInt8ToStr[bytes[3]].data(), UInt8ToStr[bytes[3]].size()-1);
659 return ::inet_ntop(af, src, dst, size);
665 return ::inet_pton(af, src, dst);
672#define NS_IN6ADDRSZ 16
674const char* inet_ntop4(
const u_char *src,
char *dst,
size_t size);
676const char * inet_ntop6(
const u_char *src,
char *dst,
size_t size);
697 return (inet_ntop4((
const u_char *)src, dst, size));
700 return (inet_ntop6((
const u_char *)src, dst, size));
703 errno = EAFNOSUPPORT;
710static const char fmt[] =
"%u.%u.%u.%u";
712inet_ntop4(
const u_char *src,
char *dst,
size_t size)
714 if (snprintf(dst, size, fmt, src[0], src[1], src[2], src[3]) < 0)
733inet_ntop6(
const u_char *src,
char *dst,
size_t size)
742 char tmp[
sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
743 struct {
int base, len; } best, cur;
752 memset(words,
'\0',
sizeof words);
754 words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
760 cur.base = i, cur.len = 1;
764 if (cur.base != -1) {
765 if (best.base == -1 || cur.len > best.len)
771 if (cur.base != -1) {
772 if (best.base == -1 || cur.len > best.len)
775 if (best.base != -1 && best.len < 2)
784 if (best.base != -1 && i >= best.base &&
785 i < (best.base + best.len)) {
794 if (i == 6 && best.base == 0 &&
795 (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
796 if (!inet_ntop4(src+12, tp,
sizeof tmp - (tp - tmp)))
801 tp += snprintf(tp,
sizeof(tmp) - (tp - tmp),
"%x", words[i]);
804 if (best.base != -1 && (best.base + best.len) ==
812 if ((
size_t)(tp - tmp) > size) {
816 memcpy(dst, tmp, (
size_t)(tp - tmp));
820static int inet_pton6(
const char *src, u_char *dst);
823static int inet_pton4(
const char *src, u_char *dst);
847 errno = EAFNOSUPPORT;
863static const char digits[] =
"0123456789";
867 int saw_digit, octets, ch;
873 while ((ch = *src++) !=
'\0') {
876 if ((pch = strchr(digits, ch)) != NULL) {
877 u_int newVal = u_int(*tp * 10 + (pch - digits));
887 }
else if (ch ==
'.' && saw_digit) {
917static const char xdigits_l[] =
"0123456789abcdef",
918 xdigits_u[] =
"0123456789ABCDEF";
923 const char *xdigits, *curtok;
937 while ((ch = *src++) !=
'\0') {
940 if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
941 pch = strchr((xdigits = xdigits_u), ch);
944 val |= (pch - xdigits);
960 *tp++ = (u_char) (val >> 8) & 0xff;
961 *tp++ = (u_char) val & 0xff;
977 *tp++ = (u_char) (val >> 8) & 0xff;
978 *tp++ = (u_char) val & 0xff;
980 if (colonp != NULL) {
985 const int n = int(tp - colonp);
988 for (i = 1; i <= n; i++) {
989 endp[- i] = colonp[n - i];
#define WarningLog(args_)
#define resip_assert(x)
This file needs to work for both C and C++ code.
Handles cross-platform sockets compatibility.
#define WSANOTINITIALISED
static const struct nv flags[]
static int inet_pton6(const char *src, u_char *dst)
static int inet_pton4(const char *src, u_char *dst)
An alternative to std::string, encapsulates an arbitrary buffer of bytes.
static const Data Empty
Constant that represents a zero-length data.
const char * c_str() const
Returns a null-terminated string representing.
@ Borrow
The Data instance is borrowing the memory from the passed in buffer.
Data & append(const char *str, size_type len)
Appends the specified number of bytes to the end of this Data.
Data substr(size_type first, size_type count=Data::npos) const
Copies a portion of this Data into a new Data.
bool empty() const noexcept
Checks whether the Data is empty.
size_type size() const noexcept
Returns the number of bytes in this Data.
size_type find(const Data &match, size_type start=0) const
Finds a specified sequence of bytes in this Data.
static const size_type npos
Represents an impossible position; returned to indicate failure to find.
const char * begin() const noexcept
Returns a pointer to the beginning of the buffer used by the Data.
Data & clear()
Clears the contents of this Data.
const char * data() const noexcept
Returns a pointer to the contents of this Data.
static bool isIpV6Address(const Data &ipAddress)
static Data canonicalizeIpV6Address(const Data &ipV6Address)
Converts the printable form of an IPv6 address into consistent format so that string comparisons will...
static Data getLocalDomainName()
static std::list< std::pair< Data, Data > > getInterfaces(const Data &matchingInterface=Data::Empty)
static bool isIpAddress(const Data &ipAddress)
static const Data & getLocalHostName()
static int inet_pton(const Data &printableIp, struct in_addr &dst)
Convert from the presentation format of the IPv4 address to struct in_addr.
static Data inet_ntop(const struct in_addr &addr)
Converts from the network format to presentation format.
static bool isIpV4Address(const Data &ipAddress)
static std::list< Data > lookupARecords(const Data &host)
Used to synchronously query A records - only for test code usage.
static Data getLocalIpAddress(const Data &defaultInterface=Data::Empty)
Gets the IP address of "the" local interface.
This file is used to handle compatibility fixes/tweaks so reSIProcate can function on multiple platfo...
dcm! – add UnusedChecking(_enum) below;
InserterClass< T > Inserter(const T &t)
Templatized function to construct an instance of InserterClass for a container to be inserted.
void initNetwork()
set up network - does nothing in unix but needed for windows
std::string strError(int err)