upgrade to miniupnp-20071213

This commit is contained in:
Charles Kerr
2007-12-20 20:18:22 +00:00
parent 45155fdc04
commit cf30fac9cf
8 changed files with 252 additions and 84 deletions
+1 -1
View File
@@ -87,7 +87,7 @@ tr_upnpPulse( tr_upnp * handle, int port, int isEnabled )
{
struct UPNPDev * devlist;
errno = 0;
devlist = upnpDiscover( 2000, NULL );
devlist = upnpDiscover( 2000, NULL, NULL );
if( devlist == NULL ) {
tr_err( KEY "upnpDiscover returned NULL (errno %d - %s)", errno, strerror(errno) );
}
+1 -1
View File
@@ -1,3 +1,3 @@
MiniUPnP is written by Thomas Bernard.
Its homepage is http://miniupnp.free.fr/
This code is from the miniupnpc-20071103 snapshot
This code is from the miniupnpc-20071213 snapshot
+10 -5
View File
@@ -1,4 +1,4 @@
/* $Id: minisoap.c,v 1.11 2007/05/19 13:13:08 nanard Exp $ */
/* $Id: minisoap.c,v 1.12 2007/12/13 17:09:03 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas Bernard
* Copyright (c) 2005 Thomas Bernard
@@ -62,13 +62,18 @@ int soapPostSubmit(int fd,
char headerbuf[1024];
int headerssize;
bodysize = (int)strlen(body);
/* We are not using keep-alive HTTP connections.
* HTTP/1.1 needs the header Connection: close to do that.
* This is the default with HTTP/1.0 */
headerssize = snprintf(headerbuf, sizeof(headerbuf),
"POST %s HTTP/1.1\r\n"
"HOST: %s:%d\r\n"
"Content-length: %d\r\n"
/* "POST %s HTTP/1.1\r\n"*/
"POST %s HTTP/1.0\r\n"
"Host: %s:%d\r\n"
"User-Agent: POSIX, UPnP/1.0, miniUPnPc/1.0\r\n"
"Content-Length: %d\r\n"
"Content-Type: text/xml\r\n"
"SOAPAction: \"%s\"\r\n"
"Connection: Close\r\n"
/* "Connection: Close\r\n" */
"\r\n",
url, host, port, bodysize, action);
return httpWrite(fd, body, bodysize, headerbuf, headerssize);
+35 -12
View File
@@ -1,4 +1,4 @@
/* $Id: minissdpc.c,v 1.3 2007/09/01 23:34:12 nanard Exp $ */
/* $Id: minissdpc.c,v 1.4 2007/12/19 14:56:58 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas BERNARD
* copyright (c) 2005-2007 Thomas Bernard
@@ -16,16 +16,23 @@
#include "minissdpc.h"
#include "miniupnpc.h"
#define DECODELENGTH(n, p) n = 0; \
do { n = (n << 7) | (*p & 0x7f); } \
while(*(p++)&0x80);
#define CODELENGTH(n, p) do { *p = (n & 0x7f) | ((n > 0x7f) ? 0x80 : 0); \
p++; n >>= 7; } while(n);
struct UPNPDev *
getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath)
{
struct UPNPDev * tmp;
struct UPNPDev * devlist = NULL;
unsigned char buffer[512];
unsigned char buffer[2048];
ssize_t n;
unsigned char * p;
unsigned char * url;
unsigned int i;
unsigned int urlsize, stsize;
unsigned int urlsize, stsize, usnsize, l;
int s;
struct sockaddr_un addr;
@@ -46,37 +53,53 @@ getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath)
}
stsize = strlen(devtype);
buffer[0] = 1;
buffer[1] = stsize;
memcpy(buffer + 2, devtype, (int)buffer[1]);
if(write(s, buffer, (int)buffer[1] + 2) < 0)
p = buffer + 1;
l = stsize; CODELENGTH(l, p);
memcpy(p, devtype, stsize);
p += stsize;
if(write(s, buffer, p - buffer) < 0)
{
/*syslog(LOG_ERR, "write(): %m");*/
perror("write()");
perror("minissdpc.c: write()");
close(s);
return NULL;
}
n = read(s, buffer, sizeof(buffer));
if(n<=0)
{
perror("minissdpc.c: read()");
close(s);
return NULL;
}
p = buffer + 1;
for(i = 0; i < buffer[0]; i++)
{
urlsize = *(p++);
stsize = p[urlsize];
if(p+2>=buffer+sizeof(buffer))
break;
DECODELENGTH(urlsize, p);
if(p+urlsize+2>=buffer+sizeof(buffer))
break;
url = p;
p += urlsize;
DECODELENGTH(stsize, p);
if(p+stsize+2>=buffer+sizeof(buffer))
break;
tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize);
tmp->pNext = devlist;
tmp->descURL = tmp->buffer;
tmp->st = tmp->buffer + 1 + urlsize;
memcpy(tmp->buffer, p, urlsize);
memcpy(tmp->buffer, url, urlsize);
tmp->buffer[urlsize] = '\0';
p += urlsize;
p++;
memcpy(tmp->buffer + urlsize + 1, p, stsize);
p += stsize;
tmp->buffer[urlsize+1+stsize] = '\0';
devlist = tmp;
/* added for compatibility with recent versions of MiniSSDPd
* >= 2007/12/19 */
DECODELENGTH(usnsize, p);
p += usnsize;
if(p>buffer + sizeof(buffer))
break;
}
close(s);
return devlist;
+29 -9
View File
@@ -1,4 +1,4 @@
/* $Id: miniupnpc.c,v 1.45 2007/10/16 15:23:44 nanard Exp $ */
/* $Id: miniupnpc.c,v 1.49 2007/12/19 14:58:54 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas BERNARD
* copyright (c) 2005-2007 Thomas Bernard
@@ -128,7 +128,7 @@ getContentLengthAndHeaderLength(char * p, int n,
/* simpleUPnPcommand :
* not so simple !
* */
* TODO: return some error codes */
int simpleUPnPcommand(int s, const char * url, const char * service,
const char * action, struct UPNParg * args,
char * buffer, int * bufsize)
@@ -147,7 +147,7 @@ int simpleUPnPcommand(int s, const char * url, const char * service,
snprintf(soapact, sizeof(soapact), "%s#%s", service, action);
if(args==NULL)
{
soapbodylen = snprintf(soapbody, sizeof(soapbody),
/*soapbodylen = snprintf(soapbody, sizeof(soapbody),
"<?xml version=\"1.0\"?>\r\n"
"<SOAP-ENV:Envelope "
"xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" "
@@ -155,7 +155,17 @@ int simpleUPnPcommand(int s, const char * url, const char * service,
"<SOAP-ENV:Body>"
"<m:%s xmlns:m=\"%s\"/>"
"</SOAP-ENV:Body></SOAP-ENV:Envelope>"
"\r\n", action, service);
"\r\n", action, service);*/
soapbodylen = snprintf(soapbody, sizeof(soapbody),
"<?xml version=\"1.0\"?>\r\n"
"<s:Envelope "
"xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\" "
"s:encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
"<s:Body>"
"<m:%s xmlns:m=\"%s\">"
"</m:%s>"
"</s:Body></s:Envelope>"
"\r\n", action, service, action);
}
else
{
@@ -316,7 +326,8 @@ parseMSEARCHReply(const char * reply, int size,
* no devices was found.
* It is up to the caller to free the chained list
* delay is in millisecond (poll) */
struct UPNPDev * upnpDiscover(int delay, const char * multicastif)
struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
const char * minissdpdsock)
{
struct UPNPDev * tmp;
struct UPNPDev * devlist = 0;
@@ -343,9 +354,17 @@ struct UPNPDev * upnpDiscover(int delay, const char * multicastif)
#ifndef WIN32
/* first try to get infos from minissdpd ! */
devlist = getDevicesFromMiniSSDPD(deviceList[0], "/var/run/minissdpd.sock");
if(devlist)
return devlist;
if(!minissdpdsock)
minissdpdsock = "/var/run/minissdpd.sock";
while(!devlist && deviceList[deviceIndex]) {
devlist = getDevicesFromMiniSSDPD(deviceList[deviceIndex],
minissdpdsock);
/* We return what we have found if it was not only a rootdevice */
if(devlist && !strstr(deviceList[deviceIndex], "rootdevice"))
return devlist;
deviceIndex++;
}
deviceIndex = 0;
#endif
/* fallback to direct discovery */
#ifdef WIN32
@@ -574,7 +593,8 @@ int ReceiveData(int socket, char * data, int length, int timeout)
FD_SET(socket, &socketSet);
timeval.tv_sec = timeout / 1000;
timeval.tv_usec = (timeout % 1000) * 1000;
n = select(0, &socketSet, NULL, NULL, &timeval);
/*n = select(0, &socketSet, NULL, NULL, &timeval);*/
n = select(FD_SETSIZE, &socketSet, NULL, NULL, &timeval);
if(n < 0)
{
PRINT_SOCKET_ERROR("select");
+21 -5
View File
@@ -1,4 +1,4 @@
/* $Id: miniupnpc.h,v 1.15 2007/10/16 15:07:32 nanard Exp $ */
/* $Id: miniupnpc.h,v 1.17 2007/12/19 14:58:54 nanard Exp $ */
/* Project: miniupnp
* http://miniupnp.free.fr/
* Author: Thomas Bernard
@@ -15,6 +15,7 @@
extern "C" {
#endif
/* Structures definitions : */
struct UPNParg { const char * elt; const char * val; };
int simpleUPnPcommand(int, const char *, const char *,
@@ -28,17 +29,32 @@ struct UPNPDev {
char buffer[2];
};
/* discover UPnP devices on the network */
LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif);
/* free returned list from above function */
/* upnpDiscover()
* discover UPnP devices on the network.
* The discovered devices are returned as a chained list.
* It is up to the caller to free the list with freeUPNPDevlist().
* delay (in millisecond) is the maximum time for waiting any device
* response.
* If available, device list will be obtained from MiniSSDPd.
* Default path for minissdpd socket will be used if minissdpdsock argument
* is NULL.
* If multicastif is not NULL, it will be used instead of the default
* multicast interface for sending SSDP discover packets. */
LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
const char * minissdpdsock);
/* freeUPNPDevlist()
* free list returned by upnpDiscover() */
LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist);
/* parserootdesc() :
* parse root XML description of a UPnP device and fill the IGDdatas
* structure. */
LIBSPEC void parserootdesc(const char *, int, struct IGDdatas *);
/* structure used to get fast access to urls
* controlURL: controlURL of the WANIPConnection
* ipcondescURL: url of the description of the WANIPConnection
* controlURL_CIF: controlURL of the WANCOmmonInterfaceConfig
* controlURL_CIF: controlURL of the WANCommonInterfaceConfig
*/
struct UPNPUrls {
char * controlURL;
+99 -43
View File
@@ -1,4 +1,4 @@
/* $Id: upnpcommands.c,v 1.16 2007/08/03 14:11:42 nanard Exp $ */
/* $Id: upnpcommands.c,v 1.18 2007/12/19 14:56:14 nanard Exp $ */
/* Project : miniupnp
* Author : Thomas Bernard
* Copyright (c) 2005 Thomas Bernard
@@ -224,16 +224,27 @@ void UPNP_GetLinkLayerMaxBitRates(const char * controlURL, const char * servicet
/* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
* if the third arg is not null the value is copied to it.
* at least 16 bytes must be available */
void UPNP_GetExternalIPAddress(const char * controlURL, const char * servicetype, char * extIpAdd)
* at least 16 bytes must be available
*
* Return values :
* 0 : SUCCESS
* NON ZERO : ERROR Either an UPnP error code or an unknown error.
*
* 402 Invalid Args - See UPnP Device Architecture section on Control.
* 501 Action Failed - See UPnP Device Architecture section on Control.
*/
int UPNP_GetExternalIPAddress(const char * controlURL,
const char * servicetype,
char * extIpAdd)
{
struct NameValueParserData pdata;
char buffer[4096];
int bufsize = 4096;
char * p;
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
if(!extIpAdd)
return;
if(!extIpAdd || !controlURL || !servicetype)
return UPNPCOMMAND_INVALID_ARGS;
simpleUPnPcommand(-1, controlURL, servicetype, "GetExternalIPAddress", 0, buffer, &bufsize);
/*fd = simpleUPnPcommand(fd, controlURL, data.servicetype, "GetExternalIPAddress", 0, buffer, &bufsize);*/
@@ -241,14 +252,21 @@ void UPNP_GetExternalIPAddress(const char * controlURL, const char * servicetype
ParseNameValue(buffer, bufsize, &pdata);
/*printf("external ip = %s\n", GetValueFromNameValueList(&pdata, "NewExternalIPAddress") );*/
p = GetValueFromNameValueList(&pdata, "NewExternalIPAddress");
if(p){
if(p) {
strncpy(extIpAdd, p, 16 );
extIpAdd[15] = '\0';
}else
ret = UPNPCOMMAND_SUCCESS;
} else
extIpAdd[0] = '\0';
p = GetValueFromNameValueList(&pdata, "errorCode");
if(p) {
ret = UPNPCOMMAND_UNKNOWN_ERROR;
sscanf(p, "%d", &ret);
}
ClearNameValueList(&pdata);
return ret;
}
int
@@ -266,8 +284,8 @@ UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
const char * resVal;
int ret;
if(!inPort || !inClient)
return 0;
if(!inPort || !inClient || !proto || !extPort)
return UPNPCOMMAND_INVALID_ARGS;
AddPortMappingArgs = calloc(9, sizeof(struct UPNParg));
AddPortMappingArgs[0].elt = "NewRemoteHost";
@@ -292,24 +310,32 @@ UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
/*puts(buffer);*/
ParseNameValue(buffer, bufsize, &pdata);
resVal = GetValueFromNameValueList(&pdata, "errorCode");
ret = resVal?0:1;
/* Do something with resVal if not null ! */
/*printf("AddPortMapping errorCode = '%s'\n", resVal); */
if(resVal) {
/*printf("AddPortMapping errorCode = '%s'\n", resVal); */
ret = UPNPCOMMAND_UNKNOWN_ERROR;
sscanf(resVal, "%d", &ret);
} else {
ret = UPNPCOMMAND_SUCCESS;
}
ClearNameValueList(&pdata);
free(AddPortMappingArgs);
return ret;
}
void UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
const char * extPort, const char * proto)
int
UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
const char * extPort, const char * proto)
{
/*struct NameValueParserData pdata;*/
struct UPNParg * DeletePortMappingArgs;
char buffer[4096];
int bufsize = 4096;
struct NameValueParserData pdata;
const char * resVal;
int ret;
if(!extPort)
return;
if(!extPort || !proto)
return UPNPCOMMAND_INVALID_ARGS;
DeletePortMappingArgs = calloc(4, sizeof(struct UPNParg));
DeletePortMappingArgs[0].elt = "NewRemoteHost";
@@ -321,7 +347,17 @@ void UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
"DeletePortMapping",
DeletePortMappingArgs, buffer, &bufsize);
/*DisplayNameValueList(buffer, bufsize);*/
ParseNameValue(buffer, bufsize, &pdata);
resVal = GetValueFromNameValueList(&pdata, "errorCode");
if(resVal) {
ret = UPNPCOMMAND_UNKNOWN_ERROR;
sscanf(resVal, "%d", &ret);
} else {
ret = UPNPCOMMAND_SUCCESS;
}
ClearNameValueList(&pdata);
free(DeletePortMappingArgs);
return ret;
}
int UPNP_GetGenericPortMappingEntry(const char * controlURL,
@@ -341,7 +377,9 @@ int UPNP_GetGenericPortMappingEntry(const char * controlURL,
char buffer[4096];
int bufsize = 4096;
char * p;
int r = -1;
int r = UPNPCOMMAND_UNKNOWN_ERROR;
if(!index)
return UPNPCOMMAND_INVALID_ARGS;
intClient[0] = '\0';
intPort[0] = '\0';
GetPortMappingArgs = calloc(2, sizeof(struct UPNParg));
@@ -362,7 +400,7 @@ int UPNP_GetGenericPortMappingEntry(const char * controlURL,
{
strncpy(extPort, p, 6);
extPort[5] = '\0';
r = 0;
r = UPNPCOMMAND_SUCCESS;
}
p = GetValueFromNameValueList(&pdata, "NewProtocol");
if(p && protocol)
@@ -401,35 +439,50 @@ int UPNP_GetGenericPortMappingEntry(const char * controlURL,
strncpy(duration, p, 16);
duration[15] = '\0';
}
p = GetValueFromNameValueList(&pdata, "errorCode");
if(p) {
r = UPNPCOMMAND_UNKNOWN_ERROR;
sscanf(p, "%d", &r);
}
ClearNameValueList(&pdata);
free(GetPortMappingArgs);
return r;
}
void UPNP_GetPortMappingNumberOfEntries(const char * controlURL, const char * servicetype, unsigned int * numEntries)
int UPNP_GetPortMappingNumberOfEntries(const char * controlURL, const char * servicetype, unsigned int * numEntries)
{
struct NameValueParserData pdata;
char buffer[4096];
int bufsize = 4096;
char* p;
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
simpleUPnPcommand(-1, controlURL, servicetype, "GetPortMappingNumberOfEntries", 0, buffer, &bufsize);
#ifndef NDEBUG
DisplayNameValueList(buffer, bufsize);
#endif
ParseNameValue(buffer, bufsize, &pdata);
p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries");
if(numEntries && p)
{
sscanf(p,"%u",numEntries);
if(numEntries && p) {
*numEntries = 0;
sscanf(p, "%u", numEntries);
ret = UPNPCOMMAND_SUCCESS;
}
p = GetValueFromNameValueList(&pdata, "errorCode");
if(p) {
ret = UPNPCOMMAND_UNKNOWN_ERROR;
sscanf(p, "%d", &ret);
}
ClearNameValueList(&pdata);
return ret;
}
/* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping
* the result is returned in the intClient and intPort strings
* please provide 16 and 6 bytes of data */
void
int
UPNP_GetSpecificPortMappingEntry(const char * controlURL,
const char * servicetype,
const char * extPort,
@@ -442,9 +495,10 @@ UPNP_GetSpecificPortMappingEntry(const char * controlURL,
char buffer[4096];
int bufsize = 4096;
char * p;
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
if(!intPort && !intClient && !extPort)
return;
if(!intPort || !intClient || !extPort || !proto)
return UPNPCOMMAND_INVALID_ARGS;
GetPortMappingArgs = calloc(4, sizeof(struct UPNParg));
GetPortMappingArgs[0].elt = "NewRemoteHost";
@@ -458,29 +512,31 @@ UPNP_GetSpecificPortMappingEntry(const char * controlURL,
/*fd = simpleUPnPcommand(fd, controlURL, data.servicetype, "GetSpecificPortMappingEntry", AddPortMappingArgs, buffer, &bufsize); */
/*DisplayNameValueList(buffer, bufsize);*/
ParseNameValue(buffer, bufsize, &pdata);
p = GetValueFromNameValueList(&pdata, "NewInternalClient");
if(intClient)
{
if(p){
strncpy(intClient, p, 16);
intClient[15] = '\0';
}else
intClient[0] = '\0';
}
p = GetValueFromNameValueList(&pdata, "NewInternalClient");
if(p) {
strncpy(intClient, p, 16);
intClient[15] = '\0';
ret = UPNPCOMMAND_SUCCESS;
} else
intClient[0] = '\0';
p = GetValueFromNameValueList(&pdata, "NewInternalPort");
if(intPort)
{
if(p){
strncpy(intPort, p, 6);
intPort[5] = '\0';
}else
intPort[0] = '\0';
if(p) {
strncpy(intPort, p, 6);
intPort[5] = '\0';
} else
intPort[0] = '\0';
p = GetValueFromNameValueList(&pdata, "errorCode");
if(p) {
ret = UPNPCOMMAND_UNKNOWN_ERROR;
sscanf(p, "%d", &ret);
}
ClearNameValueList(&pdata);
free(GetPortMappingArgs);
return ret;
}
+56 -8
View File
@@ -1,4 +1,4 @@
/* $Id: upnpcommands.h,v 1.10 2007/01/29 20:27:24 nanard Exp $ */
/* $Id: upnpcommands.h,v 1.12 2007/12/19 14:56:15 nanard Exp $ */
/* Miniupnp project : http://miniupnp.free.fr/
* Author : Thomas Bernard
* Copyright (c) 2005-2006 Thomas Bernard
@@ -10,6 +10,11 @@
#include "upnpreplyparse.h"
#include "declspec.h"
/* MiniUPnPc return codes : */
#define UPNPCOMMAND_SUCCESS (0)
#define UPNPCOMMAND_UNKNOWN_ERROR (-1)
#define UPNPCOMMAND_INVALID_ARGS (-2)
#ifdef __cplusplus
extern "C" {
#endif
@@ -43,8 +48,16 @@ UPNP_GetConnectionTypeInfo(const char * controlURL,
/* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
* if the third arg is not null the value is copied to it.
* at least 16 bytes must be available */
LIBSPEC void
* at least 16 bytes must be available
*
* Return values :
* 0 : SUCCESS
* NON ZERO : ERROR Either an UPnP error code or an unknown error.
*
* possible UPnP Errors :
* 402 Invalid Args - See UPnP Device Architecture section on Control.
* 501 Action Failed - See UPnP Device Architecture section on Control. */
LIBSPEC int
UPNP_GetExternalIPAddress(const char * controlURL,
const char * servicetype,
char * extIpAdd);
@@ -55,8 +68,29 @@ UPNP_GetLinkLayerMaxBitRates(const char* controlURL,
unsigned int * bitrateDown,
unsigned int * bitrateUp);
/* Returns zero if unable to add the port mapping, otherwise non-zero
* to indicate success */
/* UPNP_AddPortMapping()
*
* Return values :
* 0 : SUCCESS
* NON ZERO : ERROR. Either an UPnP error code or an unknown error.
*
* List of possible UPnP errors for AddPortMapping :
* errorCode errorDescription (short) - Description (long)
* 402 Invalid Args - See UPnP Device Architecture section on Control.
* 501 Action Failed - See UPnP Device Architecture section on Control.
* 715 WildCardNotPermittedInSrcIP - The source IP address cannot be
* wild-carded
* 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded
* 718 ConflictInMappingEntry - The port mapping entry specified conflicts
* with a mapping assigned previously to another client
* 724 SamePortValuesRequired - Internal and External port values
* must be the same
* 725 OnlyPermanentLeasesSupported - The NAT implementation only supports
* permanent lease times on port mappings
* 726 RemoteHostOnlySupportsWildcard - RemoteHost must be a wildcard
* and cannot be a specific IP address or DNS name
* 727 ExternalPortOnlySupportsWildcard - ExternalPort must be a wildcard and
* cannot be a specific port value */
LIBSPEC int
UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
const char * extPort,
@@ -65,17 +99,25 @@ UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
const char * desc,
const char * proto);
LIBSPEC void
/* UPNP_DeletePortMapping()
* Return Values :
* 0 : SUCCESS
* NON ZERO : error. Either an UPnP error code or an undefined error.
*
* List of possible UPnP errors for DeletePortMapping :
* 402 Invalid Args - See UPnP Device Architecture section on Control.
* 714 NoSuchEntryInArray - The specified value does not exist in the array */
LIBSPEC int
UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
const char * extPort, const char * proto);
LIBSPEC void
LIBSPEC int
UPNP_GetPortMappingNumberOfEntries(const char* controlURL, const char* servicetype, unsigned int * num);
/* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping
* the result is returned in the intClient and intPort strings
* please provide 16 and 6 bytes of data */
LIBSPEC void
LIBSPEC int
UPNP_GetSpecificPortMappingEntry(const char * controlURL,
const char * servicetype,
const char * extPort,
@@ -83,6 +125,12 @@ UPNP_GetSpecificPortMappingEntry(const char * controlURL,
char * intClient,
char * intPort);
/* UPNP_GetGenericPortMappingEntry()
*
* Possible UPNP Error codes :
* 402 Invalid Args - See UPnP Device Architecture section on Control.
* 713 SpecifiedArrayIndexInvalid - The specified array index is out of bounds
*/
LIBSPEC int
UPNP_GetGenericPortMappingEntry(const char * controlURL,
const char * servicetype,