upnp: fix for compiler warnings and incorrect API.

This commit is contained in:
Marcelo Roberto Jimenez 2010-11-18 14:55:39 -02:00
parent 6bee05a517
commit d8a27bca96
4 changed files with 342 additions and 345 deletions

View File

@ -197,14 +197,20 @@ dnl ############################################################################
dnl # Release 1.6.10: dnl # Release 1.6.10:
dnl # "current:revision:age" dnl # "current:revision:age"
dnl # dnl #
dnl # - Code has changed in upnp
dnl # revision: 2 -> 3
dnl # - interface has changed in upnp
dnl # current: 4 -> 5
dnl # revision: 3 -> 0
dnl #
dnl #AC_SUBST([LT_VERSION_IXML], [2:5:0]) dnl #AC_SUBST([LT_VERSION_IXML], [2:5:0])
dnl #AC_SUBST([LT_VERSION_THREADUTIL], [5:2:2]) dnl #AC_SUBST([LT_VERSION_THREADUTIL], [5:2:2])
dnl #AC_SUBST([LT_VERSION_UPNP], [4:2:0]) dnl #AC_SUBST([LT_VERSION_UPNP], [5:0:0])
dnl # dnl #
############################################################################ ############################################################################
AC_SUBST([LT_VERSION_IXML], [2:5:0]) AC_SUBST([LT_VERSION_IXML], [2:5:0])
AC_SUBST([LT_VERSION_THREADUTIL], [5:2:2]) AC_SUBST([LT_VERSION_THREADUTIL], [5:2:2])
AC_SUBST([LT_VERSION_UPNP], [4:2:0]) AC_SUBST([LT_VERSION_UPNP], [5:0:0])
dnl ############################################################################ dnl ############################################################################
dnl # Repeating the algorithm to place it closer to the modificatin place: dnl # Repeating the algorithm to place it closer to the modificatin place:
dnl # - library code modified: revision++ dnl # - library code modified: revision++

View File

@ -1328,7 +1328,7 @@ EXPORT_SPEC int UpnpSetContentLength(
* length needs to be set. */ * length needs to be set. */
UpnpClient_Handle Hnd, UpnpClient_Handle Hnd,
/*! [in] Permissible content length */ /*! [in] Permissible content length */
int contentLength); size_t contentLength);
/*! /*!

View File

@ -157,7 +157,7 @@ char gIF_IPV6[65]/* INET6_ADDRSTRLEN*/ = { '\0' };
char gIF_IPV6_ULA_GUA[INET6_ADDRSTRLEN] = { '\0' }; char gIF_IPV6_ULA_GUA[INET6_ADDRSTRLEN] = { '\0' };
/*! Contains interface index. (extern'ed in upnp.h) */ /*! Contains interface index. (extern'ed in upnp.h) */
int gIF_INDEX = -1; unsigned gIF_INDEX = (unsigned)-1;
/*! local IPv4 port for the mini-server */ /*! local IPv4 port for the mini-server */
unsigned short LOCAL_PORT_V4; unsigned short LOCAL_PORT_V4;
@ -1007,6 +1007,7 @@ exit_function:
HandleUnlock(); HandleUnlock();
return retVal; return retVal;
bufferLen = bufferLen;
} }
#endif /* INCLUDE_DEVICE_APIS */ #endif /* INCLUDE_DEVICE_APIS */
@ -1408,44 +1409,39 @@ static int GetDescDocumentAndURL(
char aliasStr[LINE_SIZE]; char aliasStr[LINE_SIZE];
char *temp_str = NULL; char *temp_str = NULL;
FILE *fp = NULL; FILE *fp = NULL;
off_t fileLen; size_t fileLen;
size_t num_read; size_t num_read;
time_t last_modified; time_t last_modified;
struct stat file_info; struct stat file_info;
struct sockaddr_storage serverAddr; struct sockaddr_storage serverAddr;
int rc = UPNP_E_SUCCESS; int rc = UPNP_E_SUCCESS;
if (description == NULL) { if (description == NULL)
return UPNP_E_INVALID_PARAM; return UPNP_E_INVALID_PARAM;
}
/* non-URL description must have configuration specified */ /* non-URL description must have configuration specified */
if (descriptionType != UPNPREG_URL_DESC && !config_baseURL) { if (descriptionType != UPNPREG_URL_DESC && !config_baseURL)
return UPNP_E_INVALID_PARAM; return UPNP_E_INVALID_PARAM;
}
/* Get XML doc and last modified time */ /* Get XML doc and last modified time */
if (descriptionType == UPNPREG_URL_DESC) { if (descriptionType == UPNPREG_URL_DESC) {
retVal = UpnpDownloadXmlDoc(description, xmlDoc); retVal = UpnpDownloadXmlDoc(description, xmlDoc);
if (retVal != UPNP_E_SUCCESS) { if (retVal != UPNP_E_SUCCESS)
return retVal; return retVal;
}
last_modified = time(NULL); last_modified = time(NULL);
} else if (descriptionType == UPNPREG_FILENAME_DESC) { } else if (descriptionType == UPNPREG_FILENAME_DESC) {
retVal = stat( description, &file_info ); retVal = stat(description, &file_info);
if (retVal == -1) { if (retVal == -1)
return UPNP_E_FILE_NOT_FOUND; return UPNP_E_FILE_NOT_FOUND;
} fileLen = (size_t)file_info.st_size;
fileLen = file_info.st_size;
last_modified = file_info.st_mtime; last_modified = file_info.st_mtime;
fp = fopen(description, "rb"); fp = fopen(description, "rb");
if (fp == NULL) { if (fp == NULL)
return UPNP_E_FILE_NOT_FOUND; return UPNP_E_FILE_NOT_FOUND;
} membuf = (char *)malloc(fileLen + 1);
membuf = (char *)malloc((size_t) fileLen + 1);
if (membuf == NULL) { if (membuf == NULL) {
fclose(fp); fclose(fp);
return UPNP_E_OUTOF_MEMORY; return UPNP_E_OUTOF_MEMORY;
} }
num_read = fread(membuf, 1, (size_t) fileLen, fp); num_read = fread(membuf, 1, fileLen, fp);
if (num_read != fileLen) { if (num_read != fileLen) {
fclose(fp); fclose(fp);
free(membuf); free(membuf);
@ -1463,16 +1459,15 @@ static int GetDescDocumentAndURL(
} }
if (rc != IXML_SUCCESS && descriptionType != UPNPREG_URL_DESC) { if (rc != IXML_SUCCESS && descriptionType != UPNPREG_URL_DESC) {
if (rc == IXML_INSUFFICIENT_MEMORY) { if (rc == IXML_INSUFFICIENT_MEMORY)
return UPNP_E_OUTOF_MEMORY; return UPNP_E_OUTOF_MEMORY;
} else { else
return UPNP_E_INVALID_DESC; return UPNP_E_INVALID_DESC;
}
} }
/* Determine alias */ /* Determine alias */
if (config_baseURL) { if (config_baseURL) {
if (descriptionType == UPNPREG_BUF_DESC) { if (descriptionType == UPNPREG_BUF_DESC) {
strcpy( aliasStr, "description.xml" ); strcpy(aliasStr, "description.xml");
} else { } else {
/* URL or filename */ /* URL or filename */
retVal = GetNameForAlias(description, &temp_str); retVal = GetNameForAlias(description, &temp_str);
@ -1487,15 +1482,16 @@ static int GetDescDocumentAndURL(
} }
strcpy(aliasStr, temp_str); strcpy(aliasStr, temp_str);
} }
if(AddressFamily == AF_INET) { if (AddressFamily == AF_INET) {
get_server_addr((struct sockaddr *)&serverAddr); get_server_addr((struct sockaddr *)&serverAddr);
} else { } else {
get_server_addr6((struct sockaddr *)&serverAddr); get_server_addr6((struct sockaddr *)&serverAddr);
} }
/* config */ /* config */
retVal = configure_urlbase(*xmlDoc, (struct sockaddr *)&serverAddr, retVal =
aliasStr, last_modified, descURL); configure_urlbase(*xmlDoc, (struct sockaddr *)&serverAddr,
aliasStr, last_modified, descURL);
if (retVal != UPNP_E_SUCCESS) { if (retVal != UPNP_E_SUCCESS) {
ixmlDocument_free(*xmlDoc); ixmlDocument_free(*xmlDoc);
return retVal; return retVal;
@ -2973,324 +2969,327 @@ int UpnpDownloadXmlDoc(const char *url, IXML_Document **xmlDoc)
int UpnpGetIfInfo(const char *IfName) int UpnpGetIfInfo(const char *IfName)
{ {
#ifdef WIN32 #ifdef WIN32
/* ---------------------------------------------------- */ /* ---------------------------------------------------- */
/* WIN32 implementation will use the IpHlpAPI library. */ /* WIN32 implementation will use the IpHlpAPI library. */
/* ---------------------------------------------------- */ /* ---------------------------------------------------- */
PIP_ADAPTER_ADDRESSES adapts = NULL; PIP_ADAPTER_ADDRESSES adapts = NULL;
PIP_ADAPTER_ADDRESSES adapts_item; PIP_ADAPTER_ADDRESSES adapts_item;
PIP_ADAPTER_UNICAST_ADDRESS uni_addr; PIP_ADAPTER_UNICAST_ADDRESS uni_addr;
SOCKADDR* ip_addr; SOCKADDR *ip_addr;
struct in_addr v4_addr; struct in_addr v4_addr;
struct in6_addr v6_addr; struct in6_addr v6_addr;
ULONG adapts_sz = 0; ULONG adapts_sz = 0;
ULONG ret; ULONG ret;
int ifname_found = 0; int ifname_found = 0;
int valid_addr_found = 0; int valid_addr_found = 0;
/* Get Adapters addresses required size. */ /* Get Adapters addresses required size. */
ret = GetAdaptersAddresses(AF_UNSPEC, ret = GetAdaptersAddresses(AF_UNSPEC,
GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_DNS_SERVER, GAA_FLAG_SKIP_ANYCAST |
NULL, adapts, &adapts_sz ); GAA_FLAG_SKIP_DNS_SERVER, NULL, adapts,
if( ret != ERROR_BUFFER_OVERFLOW ) { &adapts_sz);
UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__, if (ret != ERROR_BUFFER_OVERFLOW) {
"GetAdaptersAddresses failed to find list of adapters\n" );
return UPNP_E_INIT;
}
/* Allocate enough memory. */
adapts = (PIP_ADAPTER_ADDRESSES)malloc( adapts_sz );
if( adapts == NULL ) {
return UPNP_E_OUTOF_MEMORY;
}
/* Do the call that will actually return the info. */
ret = GetAdaptersAddresses( AF_UNSPEC,
GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_DNS_SERVER,
NULL, adapts, &adapts_sz );
if( ret != ERROR_SUCCESS ) {
free( adapts );
UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
"GetAdaptersAddresses failed to find list of adapters\n" );
return UPNP_E_INIT;
}
/* Copy interface name, if it was provided. */
if( IfName != NULL ) {
if( strlen(IfName) > sizeof(gIF_NAME) )
return UPNP_E_INVALID_INTERFACE;
strncpy( gIF_NAME, IfName, sizeof(gIF_NAME) );
ifname_found = 1;
}
adapts_item = adapts;
while( adapts_item != NULL ) {
if( adapts_item->Flags & IP_ADAPTER_NO_MULTICAST ) {
continue;
}
if( ifname_found == 0 ) {
/* We have found a valid interface name. Keep it. */
strncpy( gIF_NAME, adapts_item->FriendlyName, sizeof(gIF_NAME) );
ifname_found = 1;
} else {
if( strncmp( gIF_NAME, adapts_item->FriendlyName, sizeof(gIF_NAME) ) != 0 ) {
/* This is not the interface we're looking for. */
continue;
}
}
/* Loop thru this adapter's unicast IP addresses. */
uni_addr = adapts_item->FirstUnicastAddress;
while( uni_addr ) {
ip_addr = uni_addr->Address.lpSockaddr;
switch( ip_addr->sa_family ) {
case AF_INET:
memcpy( &v4_addr, &((struct sockaddr_in *)ip_addr)->sin_addr, sizeof(v4_addr) );
valid_addr_found = 1;
break;
case AF_INET6:
/* Only keep IPv6 link-local addresses. */
if( IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)ip_addr)->sin6_addr) ) {
memcpy( &v6_addr, &((struct sockaddr_in6 *)ip_addr)->sin6_addr, sizeof(v6_addr) );
valid_addr_found = 1;
}
break;
default:
if( valid_addr_found == 0 ) {
/* Address is not IPv4 or IPv6 and no valid address has */
/* yet been found for this interface. Discard interface name. */
ifname_found = 0;
}
break;
}
/* Next address. */
uni_addr = uni_addr->Next;
}
if( valid_addr_found == 1 ) {
gIF_INDEX = adapts_item->IfIndex;
break;
}
/* Next adapter. */
adapts_item = adapts_item->Next;
}
/* Failed to find a valid interface, or valid address. */
if( ifname_found == 0 || valid_addr_found == 0 ) {
UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
"Failed to find an adapter with valid IP addresses for use.\n" );
return UPNP_E_INVALID_INTERFACE;
}
inet_ntop(AF_INET, &v4_addr, gIF_IPV4, sizeof(gIF_IPV4));
inet_ntop(AF_INET6, &v6_addr, gIF_IPV6, sizeof(gIF_IPV6));
#elif (defined(BSD) && BSD >= 199306) || defined(__FreeBSD_kernel__)
struct ifaddrs *ifap, *ifa;
struct in_addr v4_addr;
struct in6_addr v6_addr;
int ifname_found = 0;
int valid_addr_found = 0;
/* Copy interface name, if it was provided. */
if( IfName != NULL ) {
if( strlen(IfName) > sizeof(gIF_NAME) )
return UPNP_E_INVALID_INTERFACE;
strncpy( gIF_NAME, IfName, sizeof(gIF_NAME) );
ifname_found = 1;
}
/* Get system interface addresses. */
if( getifaddrs(&ifap) != 0 ) {
UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
"getifaddrs failed to find list of addresses\n" );
return UPNP_E_INIT;
}
/* cycle through available interfaces and their addresses. */
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next)
{
/* Skip LOOPBACK interfaces, DOWN interfaces and interfaces that */
/* don't support MULTICAST. */
if( ( ifa->ifa_flags & IFF_LOOPBACK )
|| ( !( ifa->ifa_flags & IFF_UP ) )
|| ( !( ifa->ifa_flags & IFF_MULTICAST ) ) ) {
continue;
}
if( ifname_found == 0 ) {
/* We have found a valid interface name. Keep it. */
strncpy( gIF_NAME, ifa->ifa_name, sizeof(gIF_NAME) );
ifname_found = 1;
} else {
if( strncmp( gIF_NAME, ifa->ifa_name, sizeof(gIF_NAME) ) != 0 ) {
/* This is not the interface we're looking for. */
continue;
}
}
/* Keep interface addresses for later. */
switch( ifa->ifa_addr->sa_family )
{
case AF_INET:
memcpy( &v4_addr, &((struct sockaddr_in *)(ifa->ifa_addr))->sin_addr, sizeof(v4_addr) );
valid_addr_found = 1;
break;
case AF_INET6:
/* Only keep IPv6 link-local addresses. */
if( IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)(ifa->ifa_addr))->sin6_addr) ) {
memcpy( &v6_addr, &((struct sockaddr_in6 *)(ifa->ifa_addr))->sin6_addr, sizeof(v6_addr) );
valid_addr_found = 1;
}
break;
default:
if( valid_addr_found == 0 ) {
/* Address is not IPv4 or IPv6 and no valid address has */
/* yet been found for this interface. Discard interface name. */
ifname_found = 0;
}
break;
}
}
freeifaddrs(ifap);
/* Failed to find a valid interface, or valid address. */
if( ifname_found == 0 || valid_addr_found == 0 ) {
UpnpPrintf( UPNP_CRITICAL, API, __FILE__, __LINE__,
"Failed to find an adapter with valid IP addresses for use.\n" );
return UPNP_E_INVALID_INTERFACE;
}
inet_ntop(AF_INET, &v4_addr, gIF_IPV4, sizeof(gIF_IPV4));
inet_ntop(AF_INET6, &v6_addr, gIF_IPV6, sizeof(gIF_IPV6));
gIF_INDEX = if_nametoindex(gIF_NAME);
#else
char szBuffer[MAX_INTERFACES * sizeof( struct ifreq )];
struct ifconf ifConf;
struct ifreq ifReq;
FILE* inet6_procfd;
int i;
int LocalSock;
struct in6_addr v6_addr;
int if_idx;
char addr6[8][5];
char buf[65]; /* INET6_ADDRSTRLEN */
int ifname_found = 0;
int valid_addr_found = 0;
/* Copy interface name, if it was provided. */
if( IfName != NULL ) {
if( strlen(IfName) > sizeof(gIF_NAME) )
return UPNP_E_INVALID_INTERFACE;
strncpy( gIF_NAME, IfName, sizeof(gIF_NAME) );
ifname_found = 1;
}
/* Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. */
if( ( LocalSock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ) ) < 0 ) {
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Can't create addrlist socket\n" );
return UPNP_E_INIT;
}
/* Get the interface configuration information... */
ifConf.ifc_len = sizeof szBuffer;
ifConf.ifc_ifcu.ifcu_buf = ( caddr_t ) szBuffer;
if( ioctl( LocalSock, SIOCGIFCONF, &ifConf ) < 0 ) {
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"DiscoverInterfaces: SIOCGIFCONF returned error\n" );
return UPNP_E_INIT;
}
/* Cycle through the list of interfaces looking for IP addresses. */
for( i = 0; i < ifConf.ifc_len ; ) {
struct ifreq *pifReq =
( struct ifreq * )( ( caddr_t ) ifConf.ifc_req + i );
i += sizeof *pifReq;
/* See if this is the sort of interface we want to deal with. */
strcpy( ifReq.ifr_name, pifReq->ifr_name );
if( ioctl( LocalSock, SIOCGIFFLAGS, &ifReq ) < 0 ) {
UpnpPrintf( UPNP_ALL, API, __FILE__, __LINE__,
"Can't get interface flags for %s:\n",
ifReq.ifr_name );
}
/* Skip LOOPBACK interfaces, DOWN interfaces and interfaces that */
/* don't support MULTICAST. */
if( ( ifReq.ifr_flags & IFF_LOOPBACK )
|| ( !( ifReq.ifr_flags & IFF_UP ) )
|| ( !( ifReq.ifr_flags & IFF_MULTICAST ) ) ) {
continue;
}
if( ifname_found == 0 ) {
/* We have found a valid interface name. Keep it. */
strncpy( gIF_NAME, pifReq->ifr_name, sizeof(gIF_NAME) );
ifname_found = 1;
} else {
if( strncmp( gIF_NAME, pifReq->ifr_name, sizeof(gIF_NAME) ) != 0 ) {
/* This is not the interface we're looking for. */
continue;
}
}
/* Check address family. */
if( pifReq->ifr_addr.sa_family == AF_INET ) {
/* Copy interface name, IPv4 address and interface index. */
strncpy( gIF_NAME, pifReq->ifr_name, sizeof(gIF_NAME) );
inet_ntop(AF_INET, &((struct sockaddr_in*)&pifReq->ifr_addr)->sin_addr, gIF_IPV4, sizeof(gIF_IPV4));
gIF_INDEX = if_nametoindex(gIF_NAME);
valid_addr_found = 1;
break;
} else {
/* Address is not IPv4 */
ifname_found = 0;
}
}
close( LocalSock );
/* Failed to find a valid interface, or valid address. */
if (ifname_found == 0 || valid_addr_found == 0) {
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__, UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
"Failed to find an adapter with valid IP addresses for use.\n"); "GetAdaptersAddresses failed to find list of adapters\n");
return UPNP_E_INIT;
}
/* Allocate enough memory. */
adapts = (PIP_ADAPTER_ADDRESSES) malloc(adapts_sz);
if (adapts == NULL) {
return UPNP_E_OUTOF_MEMORY;
}
/* Do the call that will actually return the info. */
ret = GetAdaptersAddresses(AF_UNSPEC,
GAA_FLAG_SKIP_ANYCAST |
GAA_FLAG_SKIP_DNS_SERVER, NULL, adapts,
&adapts_sz);
if (ret != ERROR_SUCCESS) {
free(adapts);
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
"GetAdaptersAddresses failed to find list of adapters\n");
return UPNP_E_INIT;
}
/* Copy interface name, if it was provided. */
if (IfName != NULL) {
if (strlen(IfName) > sizeof(gIF_NAME))
return UPNP_E_INVALID_INTERFACE;
strncpy(gIF_NAME, IfName, sizeof(gIF_NAME));
ifname_found = 1;
}
adapts_item = adapts;
while (adapts_item != NULL) {
if (adapts_item->Flags & IP_ADAPTER_NO_MULTICAST) {
continue;
}
if (ifname_found == 0) {
/* We have found a valid interface name. Keep it. */
strncpy(gIF_NAME, adapts_item->FriendlyName,
sizeof(gIF_NAME));
ifname_found = 1;
} else {
if (strncmp
(gIF_NAME, adapts_item->FriendlyName,
sizeof(gIF_NAME)) != 0) {
/* This is not the interface we're looking for. */
continue;
}
}
/* Loop thru this adapter's unicast IP addresses. */
uni_addr = adapts_item->FirstUnicastAddress;
while (uni_addr) {
ip_addr = uni_addr->Address.lpSockaddr;
switch (ip_addr->sa_family) {
case AF_INET:
memcpy(&v4_addr,
&((struct sockaddr_in *)ip_addr)->
sin_addr, sizeof(v4_addr));
valid_addr_found = 1;
break;
case AF_INET6:
/* Only keep IPv6 link-local addresses. */
if (IN6_IS_ADDR_LINKLOCAL
(&((struct sockaddr_in6 *)ip_addr)->
sin6_addr)) {
memcpy(&v6_addr,
&((struct sockaddr_in6 *)
ip_addr)->sin6_addr,
sizeof(v6_addr));
valid_addr_found = 1;
}
break;
default:
if (valid_addr_found == 0) {
/* Address is not IPv4 or IPv6 and no valid address has */
/* yet been found for this interface. Discard interface name. */
ifname_found = 0;
}
break;
}
/* Next address. */
uni_addr = uni_addr->Next;
}
if (valid_addr_found == 1) {
gIF_INDEX = adapts_item->IfIndex;
break;
}
/* Next adapter. */
adapts_item = adapts_item->Next;
}
/* Failed to find a valid interface, or valid address. */
if (ifname_found == 0 || valid_addr_found == 0) {
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
"Failed to find an adapter with valid IP addresses for use.\n");
return UPNP_E_INVALID_INTERFACE;
}
inet_ntop(AF_INET, &v4_addr, gIF_IPV4, sizeof(gIF_IPV4));
inet_ntop(AF_INET6, &v6_addr, gIF_IPV6, sizeof(gIF_IPV6));
#elif (defined(BSD) && BSD >= 199306) || defined(__FreeBSD_kernel__)
struct ifaddrs *ifap, *ifa;
struct in_addr v4_addr;
struct in6_addr v6_addr;
int ifname_found = 0;
int valid_addr_found = 0;
/* Copy interface name, if it was provided. */
if (IfName != NULL) {
if (strlen(IfName) > sizeof(gIF_NAME))
return UPNP_E_INVALID_INTERFACE;
strncpy(gIF_NAME, IfName, sizeof(gIF_NAME));
ifname_found = 1;
}
/* Get system interface addresses. */
if (getifaddrs(&ifap) != 0) {
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
"getifaddrs failed to find list of addresses\n");
return UPNP_E_INIT;
}
/* cycle through available interfaces and their addresses. */
for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) {
/* Skip LOOPBACK interfaces, DOWN interfaces and interfaces that */
/* don't support MULTICAST. */
if ((ifa->ifa_flags & IFF_LOOPBACK)
|| (!(ifa->ifa_flags & IFF_UP))
|| (!(ifa->ifa_flags & IFF_MULTICAST))) {
continue;
}
if (ifname_found == 0) {
/* We have found a valid interface name. Keep it. */
strncpy(gIF_NAME, ifa->ifa_name, sizeof(gIF_NAME));
ifname_found = 1;
} else {
if (strncmp(gIF_NAME, ifa->ifa_name, sizeof(gIF_NAME))
!= 0) {
/* This is not the interface we're looking for. */
continue;
}
}
/* Keep interface addresses for later. */
switch (ifa->ifa_addr->sa_family) {
case AF_INET:
memcpy(&v4_addr,
&((struct sockaddr_in *)(ifa->ifa_addr))->
sin_addr, sizeof(v4_addr));
valid_addr_found = 1;
break;
case AF_INET6:
/* Only keep IPv6 link-local addresses. */
if (IN6_IS_ADDR_LINKLOCAL
(&((struct sockaddr_in6 *)(ifa->ifa_addr))->
sin6_addr)) {
memcpy(&v6_addr,
&((struct sockaddr_in6 *)(ifa->
ifa_addr))->
sin6_addr, sizeof(v6_addr));
valid_addr_found = 1;
}
break;
default:
if (valid_addr_found == 0) {
/* Address is not IPv4 or IPv6 and no valid address has */
/* yet been found for this interface. Discard interface name. */
ifname_found = 0;
}
break;
}
}
freeifaddrs(ifap);
/* Failed to find a valid interface, or valid address. */
if (ifname_found == 0 || valid_addr_found == 0) {
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
"Failed to find an adapter with valid IP addresses for use.\n");
return UPNP_E_INVALID_INTERFACE;
}
inet_ntop(AF_INET, &v4_addr, gIF_IPV4, sizeof(gIF_IPV4));
inet_ntop(AF_INET6, &v6_addr, gIF_IPV6, sizeof(gIF_IPV6));
gIF_INDEX = if_nametoindex(gIF_NAME);
#else
char szBuffer[MAX_INTERFACES * sizeof(struct ifreq)];
struct ifconf ifConf;
struct ifreq ifReq;
FILE *inet6_procfd;
size_t i;
int LocalSock;
struct in6_addr v6_addr;
unsigned if_idx;
char addr6[8][5];
char buf[65]; /* INET6_ADDRSTRLEN */
int ifname_found = 0;
int valid_addr_found = 0;
/* Copy interface name, if it was provided. */
if (IfName != NULL) {
if (strlen(IfName) > sizeof(gIF_NAME))
return UPNP_E_INVALID_INTERFACE;
strncpy(gIF_NAME, IfName, sizeof(gIF_NAME));
ifname_found = 1;
}
/* Create an unbound datagram socket to do the SIOCGIFADDR ioctl on. */
if ((LocalSock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"Can't create addrlist socket\n");
return UPNP_E_INIT;
}
/* Get the interface configuration information... */
ifConf.ifc_len = sizeof szBuffer;
ifConf.ifc_ifcu.ifcu_buf = (caddr_t) szBuffer;
if (ioctl(LocalSock, SIOCGIFCONF, &ifConf) < 0) {
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"DiscoverInterfaces: SIOCGIFCONF returned error\n");
return UPNP_E_INIT;
}
/* Cycle through the list of interfaces looking for IP addresses. */
for (i = 0; i < (size_t)ifConf.ifc_len;) {
struct ifreq *pifReq =
(struct ifreq *)((caddr_t) ifConf.ifc_req + i);
i += sizeof *pifReq;
/* See if this is the sort of interface we want to deal with. */
strcpy(ifReq.ifr_name, pifReq->ifr_name);
if (ioctl(LocalSock, SIOCGIFFLAGS, &ifReq) < 0) {
UpnpPrintf(UPNP_ALL, API, __FILE__, __LINE__,
"Can't get interface flags for %s:\n",
ifReq.ifr_name);
}
/* Skip LOOPBACK interfaces, DOWN interfaces and interfaces that */
/* don't support MULTICAST. */
if ((ifReq.ifr_flags & IFF_LOOPBACK)
|| (!(ifReq.ifr_flags & IFF_UP))
|| (!(ifReq.ifr_flags & IFF_MULTICAST))) {
continue;
}
if (ifname_found == 0) {
/* We have found a valid interface name. Keep it. */
strncpy(gIF_NAME, pifReq->ifr_name, sizeof(gIF_NAME));
ifname_found = 1;
} else {
if (strncmp
(gIF_NAME, pifReq->ifr_name,
sizeof(gIF_NAME)) != 0) {
/* This is not the interface we're looking for. */
continue;
}
}
/* Check address family. */
if (pifReq->ifr_addr.sa_family == AF_INET) {
/* Copy interface name, IPv4 address and interface index. */
strncpy(gIF_NAME, pifReq->ifr_name, sizeof(gIF_NAME));
inet_ntop(AF_INET,
&((struct sockaddr_in *)&pifReq->ifr_addr)->
sin_addr, gIF_IPV4, sizeof(gIF_IPV4));
gIF_INDEX = if_nametoindex(gIF_NAME);
valid_addr_found = 1;
break;
} else {
/* Address is not IPv4 */
ifname_found = 0;
}
}
close(LocalSock);
/* Failed to find a valid interface, or valid address. */
if (ifname_found == 0 || valid_addr_found == 0) {
UpnpPrintf(UPNP_CRITICAL, API, __FILE__, __LINE__,
"Failed to find an adapter with valid IP addresses for use.\n");
return UPNP_E_INVALID_INTERFACE; return UPNP_E_INVALID_INTERFACE;
} }
/* Try to get the IPv6 address for the same interface */ /* Try to get the IPv6 address for the same interface */
/* from "/proc/net/if_inet6", if possible. */ /* from "/proc/net/if_inet6", if possible. */
inet6_procfd = fopen("/proc/net/if_inet6", "r"); inet6_procfd = fopen("/proc/net/if_inet6", "r");
if (inet6_procfd) { if (inet6_procfd) {
while (fscanf(inet6_procfd, while (fscanf(inet6_procfd,
"%4s%4s%4s%4s%4s%4s%4s%4s %02x %*02x %*02x %*02x %*20s\n", "%4s%4s%4s%4s%4s%4s%4s%4s %02x %*02x %*02x %*02x %*20s\n",
addr6[0],addr6[1],addr6[2],addr6[3], addr6[0], addr6[1], addr6[2], addr6[3],
addr6[4],addr6[5],addr6[6],addr6[7], &if_idx) != EOF) { addr6[4], addr6[5], addr6[6], addr6[7],
&if_idx) != EOF) {
/* Get same interface as IPv4 address retrieved. */ /* Get same interface as IPv4 address retrieved. */
if( gIF_INDEX == if_idx ) { if (gIF_INDEX == if_idx) {
snprintf(buf, sizeof(buf), "%s:%s:%s:%s:%s:%s:%s:%s", snprintf(buf, sizeof(buf),
addr6[0],addr6[1],addr6[2],addr6[3], "%s:%s:%s:%s:%s:%s:%s:%s", addr6[0],
addr6[4],addr6[5],addr6[6],addr6[7]); addr6[1], addr6[2], addr6[3], addr6[4],
addr6[5], addr6[6], addr6[7]);
/* Validate formed address and check for link-local. */ /* Validate formed address and check for link-local. */
if (inet_pton(AF_INET6, buf, &v6_addr) > 0) { if (inet_pton(AF_INET6, buf, &v6_addr) > 0) {
if (IN6_IS_ADDR_ULA(&v6_addr)) { if (IN6_IS_ADDR_ULA(&v6_addr)) {
/* Got valid IPv6 ula. */ /* Got valid IPv6 ula. */
strncpy(gIF_IPV6_ULA_GUA, buf, sizeof(gIF_IPV6_ULA_GUA)); strncpy(gIF_IPV6_ULA_GUA, buf,
} else if (IN6_IS_ADDR_GLOBAL(&v6_addr) && sizeof
strlen(gIF_IPV6_ULA_GUA) == 0) { (gIF_IPV6_ULA_GUA));
} else if (IN6_IS_ADDR_GLOBAL(&v6_addr)
&& strlen(gIF_IPV6_ULA_GUA)
== 0) {
/* got a GUA, should store it while no ULA is found */ /* got a GUA, should store it while no ULA is found */
strncpy(gIF_IPV6_ULA_GUA, buf, sizeof(gIF_IPV6_ULA_GUA)); strncpy(gIF_IPV6_ULA_GUA, buf,
} else if (IN6_IS_ADDR_LINKLOCAL(&v6_addr) && sizeof
strlen(gIF_IPV6) == 0) { (gIF_IPV6_ULA_GUA));
} else
if (IN6_IS_ADDR_LINKLOCAL(&v6_addr)
&& strlen(gIF_IPV6) == 0) {
/* got a Link local IPv6 address. */ /* got a Link local IPv6 address. */
strncpy(gIF_IPV6, buf, sizeof(gIF_IPV6)); strncpy(gIF_IPV6, buf,
sizeof(gIF_IPV6));
} }
} }
} }
@ -3298,10 +3297,9 @@ int UpnpGetIfInfo(const char *IfName)
fclose(inet6_procfd); fclose(inet6_procfd);
} }
#endif #endif
UpnpPrintf(UPNP_INFO, API, __FILE__, __LINE__,
UpnpPrintf( UPNP_INFO, API, __FILE__, __LINE__, "Interface name=%s, index=%d, v4=%s, v6=%s, ULA or GUA v6=%s\n",
"Interface name=%s, index=%d, v4=%s, v6=%s, ULA or GUA v6=%s\n", gIF_NAME, gIF_INDEX, gIF_IPV4, gIF_IPV6, gIF_IPV6_ULA_GUA);
gIF_NAME, gIF_INDEX, gIF_IPV4, gIF_IPV6, gIF_IPV6_ULA_GUA );
return UPNP_E_SUCCESS; return UPNP_E_SUCCESS;
} }
@ -3520,7 +3518,7 @@ int PrintHandleInfo(UpnpClient_Handle Hnd)
} }
int getlocalhostname(char *out, const int out_len) int getlocalhostname(char *out, size_t out_len)
{ {
int ret = UPNP_E_SUCCESS; int ret = UPNP_E_SUCCESS;
char tempstr[16]; char tempstr[16];
@ -3595,7 +3593,7 @@ int getlocalhostname(char *out, const int out_len)
struct ifconf ifConf; struct ifconf ifConf;
struct ifreq ifReq; struct ifreq ifReq;
int nResult; int nResult;
int i; long unsigned int i;
int LocalSock; int LocalSock;
struct sockaddr_in LocalAddr; struct sockaddr_in LocalAddr;
int j = 0; int j = 0;
@ -3624,7 +3622,7 @@ int getlocalhostname(char *out, const int out_len)
} }
/* Cycle through the list of interfaces looking for IP addresses. */ /* Cycle through the list of interfaces looking for IP addresses. */
for (i = 0; i < ifConf.ifc_len && j < DEFAULT_INTERFACE; ) { for (i = 0; i < (long unsigned int)ifConf.ifc_len && j < DEFAULT_INTERFACE; ) {
struct ifreq *pifReq = struct ifreq *pifReq =
(struct ifreq *)((caddr_t)ifConf.ifc_req + i); (struct ifreq *)((caddr_t)ifConf.ifc_req + i);
i += sizeof *pifReq; i += sizeof *pifReq;
@ -3952,10 +3950,7 @@ int UpnpVirtualDir_set_CloseCallback(VDCallback_Close callback)
return ret; return ret;
} }
int UpnpSetContentLength(UpnpClient_Handle Hnd, size_t contentLength)
int UpnpSetContentLength(
UpnpClient_Handle Hnd,
int contentLength)
{ {
int errCode = UPNP_E_SUCCESS; int errCode = UPNP_E_SUCCESS;
struct Handle_Info *HInfo = NULL; struct Handle_Info *HInfo = NULL;
@ -3969,25 +3964,21 @@ int UpnpSetContentLength(
HandleLock(); HandleLock();
errCode = GetHandleInfo(Hnd, &HInfo); errCode = GetHandleInfo(Hnd, &HInfo);
if (errCode != HND_DEVICE) { if (errCode != HND_DEVICE) {
errCode = UPNP_E_INVALID_HANDLE; errCode = UPNP_E_INVALID_HANDLE;
break; break;
} }
if (contentLength > MAX_SOAP_CONTENT_LENGTH) { if (contentLength > MAX_SOAP_CONTENT_LENGTH) {
errCode = UPNP_E_OUTOF_BOUNDS; errCode = UPNP_E_OUTOF_BOUNDS;
break; break;
} }
g_maxContentLength = contentLength; g_maxContentLength = contentLength;
} while(0); } while (0);
HandleUnlock(); HandleUnlock();
return errCode; return errCode;
} }
int UpnpSetMaxContentLength(size_t contentLength) int UpnpSetMaxContentLength(size_t contentLength)
{ {
int errCode = UPNP_E_SUCCESS; int errCode = UPNP_E_SUCCESS;

View File

@ -179,7 +179,7 @@ extern char gIF_IPV6[65];
extern char gIF_IPV6_ULA_GUA[INET6_ADDRSTRLEN]; extern char gIF_IPV6_ULA_GUA[INET6_ADDRSTRLEN];
extern int gIF_INDEX; extern unsigned gIF_INDEX;
extern unsigned short LOCAL_PORT_V4; extern unsigned short LOCAL_PORT_V4;
@ -292,7 +292,7 @@ int getlocalhostname(
/*! [out] IP address of the interface. */ /*! [out] IP address of the interface. */
char *out, char *out,
/*! [in] Length of the output buffer. */ /*! [in] Length of the output buffer. */
const int out_len); size_t out_len);
/*! /*!