Add support for IGD2 AddAnyPortMapping and DeletePortMappingRange
Added python bindings for both AddAnyPortMapping and DeletePortMappingRange
This commit is contained in:
parent
be9584d156
commit
b9362f32a7
|
@ -265,6 +265,42 @@ Py_END_ALLOW_THREADS
|
|||
}
|
||||
}
|
||||
|
||||
/* AddAnyPortMapping(externalPort, protocol, internalHost, internalPort, desc,
|
||||
* remoteHost)
|
||||
* protocol is 'UDP' or 'TCP' */
|
||||
static PyObject *
|
||||
UPnP_addanyportmapping(UPnPObject *self, PyObject *args)
|
||||
{
|
||||
char extPort[6];
|
||||
unsigned short ePort;
|
||||
char inPort[6];
|
||||
unsigned short iPort;
|
||||
char reservedPort[6];
|
||||
const char * proto;
|
||||
const char * host;
|
||||
const char * desc;
|
||||
const char * remoteHost;
|
||||
const char * leaseDuration = "0";
|
||||
int r;
|
||||
if (!PyArg_ParseTuple(args, "HssHss", &ePort, &proto, &host, &iPort, &desc, &remoteHost))
|
||||
return NULL;
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
sprintf(extPort, "%hu", ePort);
|
||||
sprintf(inPort, "%hu", iPort);
|
||||
r = UPNP_AddAnyPortMapping(self->urls.controlURL, self->data.first.servicetype,
|
||||
extPort, inPort, host, desc, proto,
|
||||
remoteHost, leaseDuration, reservedPort);
|
||||
Py_END_ALLOW_THREADS
|
||||
if(r==UPNPCOMMAND_SUCCESS) {
|
||||
return Py_BuildValue("i", atoi(reservedPort));
|
||||
} else {
|
||||
/* TODO: have our own exception type ! */
|
||||
PyErr_SetString(PyExc_Exception, strupnperror(r));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* DeletePortMapping(extPort, proto, removeHost='')
|
||||
* proto = 'UDP', 'TCP' */
|
||||
static PyObject *
|
||||
|
@ -291,6 +327,37 @@ Py_END_ALLOW_THREADS
|
|||
}
|
||||
}
|
||||
|
||||
/* DeletePortMappingRange(extPort, proto, removeHost='')
|
||||
* proto = 'UDP', 'TCP' */
|
||||
static PyObject *
|
||||
UPnP_deleteportmappingrange(UPnPObject *self, PyObject *args)
|
||||
{
|
||||
char extPortStart[6];
|
||||
unsigned short ePortStart;
|
||||
char extPortEnd[6];
|
||||
unsigned short ePortEnd;
|
||||
const char * proto;
|
||||
unsigned char manage;
|
||||
char manageStr[1];
|
||||
int r;
|
||||
if(!PyArg_ParseTuple(args, "HHsb", &ePortStart, &ePortEnd, &proto, &manage))
|
||||
return NULL;
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
sprintf(extPortStart, "%hu", ePortStart);
|
||||
sprintf(extPortEnd, "%hu", ePortEnd);
|
||||
sprintf(manageStr, "%hhu", manage);
|
||||
r = UPNP_DeletePortMappingRange(self->urls.controlURL, self->data.first.servicetype,
|
||||
extPortStart, extPortEnd, proto, manageStr);
|
||||
Py_END_ALLOW_THREADS
|
||||
if(r==UPNPCOMMAND_SUCCESS) {
|
||||
Py_RETURN_TRUE;
|
||||
} else {
|
||||
/* TODO: have our own exception type ! */
|
||||
PyErr_SetString(PyExc_Exception, strupnperror(r));
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
UPnP_getportmappingnumberofentries(UPnPObject *self)
|
||||
{
|
||||
|
@ -429,9 +496,15 @@ static PyMethodDef UPnP_methods[] = {
|
|||
{"addportmapping", (PyCFunction)UPnP_addportmapping, METH_VARARGS,
|
||||
"add a port mapping"
|
||||
},
|
||||
{"addanyportmapping", (PyCFunction)UPnP_addanyportmapping, METH_VARARGS,
|
||||
"add a port mapping, IGD to select alternative if necessary"
|
||||
},
|
||||
{"deleteportmapping", (PyCFunction)UPnP_deleteportmapping, METH_VARARGS,
|
||||
"delete a port mapping"
|
||||
},
|
||||
{"deleteportmappingrange", (PyCFunction)UPnP_deleteportmappingrange, METH_VARARGS,
|
||||
"delete a range of port mappings"
|
||||
},
|
||||
{"getportmappingnumberofentries", (PyCFunction)UPnP_getportmappingnumberofentries, METH_NOARGS,
|
||||
"-- non standard --"
|
||||
},
|
||||
|
|
|
@ -230,10 +230,12 @@ static void SetRedirectAndTest(struct UPNPUrls * urls,
|
|||
const char * proto,
|
||||
const char * leaseDuration,
|
||||
const char * description,
|
||||
int addAny)
|
||||
{
|
||||
char externalIPAddress[40];
|
||||
char intClient[40];
|
||||
char intPort[6];
|
||||
char reservedPort[6];
|
||||
char duration[16];
|
||||
int r;
|
||||
|
||||
|
@ -257,12 +259,23 @@ static void SetRedirectAndTest(struct UPNPUrls * urls,
|
|||
else
|
||||
printf("GetExternalIPAddress failed.\n");
|
||||
|
||||
r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype,
|
||||
eport, iport, iaddr, description,
|
||||
proto, 0, leaseDuration);
|
||||
if(r!=UPNPCOMMAND_SUCCESS)
|
||||
printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
|
||||
eport, iport, iaddr, r, strupnperror(r));
|
||||
if (addAny) {
|
||||
r = UPNP_AddAnyPortMapping(urls->controlURL, data->first.servicetype,
|
||||
eport, iport, iaddr, description,
|
||||
proto, 0, leaseDuration, reservedPort);
|
||||
if(r==UPNPCOMMAND_SUCCESS)
|
||||
eport = reservedPort;
|
||||
else
|
||||
printf("AddAnyPortMapping(%s, %s, %s) failed with code %d (%s)\n",
|
||||
eport, iport, iaddr, r, strupnperror(r));
|
||||
} else {
|
||||
r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype,
|
||||
eport, iport, iaddr, description,
|
||||
proto, 0, leaseDuration);
|
||||
if(r!=UPNPCOMMAND_SUCCESS)
|
||||
printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
|
||||
eport, iport, iaddr, r, strupnperror(r));
|
||||
}
|
||||
|
||||
r = UPNP_GetSpecificPortMappingEntry(urls->controlURL,
|
||||
data->first.servicetype,
|
||||
|
@ -302,6 +315,32 @@ RemoveRedirect(struct UPNPUrls * urls,
|
|||
printf("UPNP_DeletePortMapping() returned : %d\n", r);
|
||||
}
|
||||
|
||||
static void
|
||||
RemoveRedirectRange(struct UPNPUrls * urls,
|
||||
struct IGDdatas * data,
|
||||
const char * ePortStart, char const * ePortEnd,
|
||||
const char * proto, const char * manage)
|
||||
{
|
||||
int r;
|
||||
|
||||
if (!manage)
|
||||
manage = "0";
|
||||
|
||||
if(!proto || !ePortStart || !ePortEnd)
|
||||
{
|
||||
fprintf(stderr, "invalid arguments\n");
|
||||
return;
|
||||
}
|
||||
proto = protofix(proto);
|
||||
if(!proto)
|
||||
{
|
||||
fprintf(stderr, "protocol invalid\n");
|
||||
return;
|
||||
}
|
||||
r = UPNP_DeletePortMappingRange(urls->controlURL, data->first.servicetype, ePortStart, ePortEnd, proto, manage);
|
||||
printf("UPNP_DeletePortMappingRange() returned : %d\n", r);
|
||||
}
|
||||
|
||||
/* IGD:2, functions for service WANIPv6FirewallControl:1 */
|
||||
static void GetFirewallStatus(struct UPNPUrls * urls, struct IGDdatas * data)
|
||||
{
|
||||
|
@ -550,6 +589,8 @@ int main(int argc, char ** argv)
|
|||
fprintf(stderr, " \t%s [options] -s\n\t\tGet Connection status\n", argv[0]);
|
||||
fprintf(stderr, " \t%s [options] -l\n\t\tList redirections\n", argv[0]);
|
||||
fprintf(stderr, " \t%s [options] -L\n\t\tList redirections (using GetListOfPortMappings (for IGD:2 only)\n", argv[0]);
|
||||
fprintf(stderr, " \t%s [options] -n ip port external_port protocol [duration]\n\t\tAdd (any) port redirection allowing IGD to use alternative external_port (for IGD:2 only)\n", argv[0]);
|
||||
fprintf(stderr, " \t%s [options] -N external_port_start external_port_end protocol [manage]\n\t\tDelete range of port redirections (for IGD:2 only)\n", argv[0]);
|
||||
fprintf(stderr, " \t%s [options] -r port1 protocol1 [port2 protocol2] [...]\n\t\tAdd all redirections to the current host\n", argv[0]);
|
||||
fprintf(stderr, " \t%s [options] -A remote_ip remote_port internal_ip internal_port protocol lease_time\n\t\tAdd Pinhole (for IGD:2 only)\n", argv[0]);
|
||||
fprintf(stderr, " \t%s [options] -U uniqueID new_lease_time\n\t\tUpdate Pinhole (for IGD:2 only)\n", argv[0]);
|
||||
|
@ -631,10 +672,10 @@ int main(int argc, char ** argv)
|
|||
break;
|
||||
case 'a':
|
||||
SetRedirectAndTest(&urls, &data,
|
||||
commandargv[0], commandargv[1],
|
||||
commandargv[2], commandargv[3],
|
||||
(commandargc > 4)?commandargv[4]:"0",
|
||||
description);
|
||||
commandargv[0], commandargv[1],
|
||||
commandargv[2], commandargv[3],
|
||||
(commandargc > 4)?commandargv[4]:"0",
|
||||
description, 0);
|
||||
break;
|
||||
case 'd':
|
||||
for(i=0; i<commandargc; i+=2)
|
||||
|
@ -642,6 +683,20 @@ int main(int argc, char ** argv)
|
|||
RemoveRedirect(&urls, &data, commandargv[i], commandargv[i+1]);
|
||||
}
|
||||
break;
|
||||
case 'n': /* aNy */
|
||||
SetRedirectAndTest(&urls, &data,
|
||||
commandargv[0], commandargv[1],
|
||||
commandargv[2], commandargv[3],
|
||||
(commandargc > 4)?commandargv[4]:"0",
|
||||
description, 1);
|
||||
break;
|
||||
case 'N':
|
||||
if (commandargc < 3)
|
||||
fprintf(stderr, "too few arguments\n");
|
||||
|
||||
RemoveRedirectRange(&urls, &data, commandargv[0], commandargv[1], commandargv[2],
|
||||
commandargc > 3 ? commandargv[3] : NULL);
|
||||
break;
|
||||
case 's':
|
||||
GetConnectionStatus(&urls, &data);
|
||||
break;
|
||||
|
@ -650,9 +705,9 @@ int main(int argc, char ** argv)
|
|||
{
|
||||
/*printf("port %s protocol %s\n", argv[i], argv[i+1]);*/
|
||||
SetRedirectAndTest(&urls, &data,
|
||||
lanaddr, commandargv[i],
|
||||
commandargv[i], commandargv[i+1], "0",
|
||||
description);
|
||||
lanaddr, commandargv[i],
|
||||
commandargv[i], commandargv[i+1], "0",
|
||||
description, 0);
|
||||
}
|
||||
break;
|
||||
case 'A':
|
||||
|
|
|
@ -394,6 +394,73 @@ UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
|
|||
return ret;
|
||||
}
|
||||
|
||||
LIBSPEC int
|
||||
UPNP_AddAnyPortMapping(const char * controlURL, const char * servicetype,
|
||||
const char * extPort,
|
||||
const char * inPort,
|
||||
const char * inClient,
|
||||
const char * desc,
|
||||
const char * proto,
|
||||
const char * remoteHost,
|
||||
const char * leaseDuration,
|
||||
char * reservedPort)
|
||||
{
|
||||
struct UPNParg * AddPortMappingArgs;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
struct NameValueParserData pdata;
|
||||
const char * resVal;
|
||||
int ret;
|
||||
|
||||
if(!inPort || !inClient || !proto || !extPort)
|
||||
return UPNPCOMMAND_INVALID_ARGS;
|
||||
|
||||
AddPortMappingArgs = calloc(9, sizeof(struct UPNParg));
|
||||
AddPortMappingArgs[0].elt = "NewRemoteHost";
|
||||
AddPortMappingArgs[0].val = remoteHost;
|
||||
AddPortMappingArgs[1].elt = "NewExternalPort";
|
||||
AddPortMappingArgs[1].val = extPort;
|
||||
AddPortMappingArgs[2].elt = "NewProtocol";
|
||||
AddPortMappingArgs[2].val = proto;
|
||||
AddPortMappingArgs[3].elt = "NewInternalPort";
|
||||
AddPortMappingArgs[3].val = inPort;
|
||||
AddPortMappingArgs[4].elt = "NewInternalClient";
|
||||
AddPortMappingArgs[4].val = inClient;
|
||||
AddPortMappingArgs[5].elt = "NewEnabled";
|
||||
AddPortMappingArgs[5].val = "1";
|
||||
AddPortMappingArgs[6].elt = "NewPortMappingDescription";
|
||||
AddPortMappingArgs[6].val = desc?desc:"libminiupnpc";
|
||||
AddPortMappingArgs[7].elt = "NewLeaseDuration";
|
||||
AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0";
|
||||
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"AddAnyPortMapping", AddPortMappingArgs,
|
||||
&bufsize))) {
|
||||
free(AddPortMappingArgs);
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
}
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
free(buffer); buffer = NULL;
|
||||
resVal = GetValueFromNameValueList(&pdata, "errorCode");
|
||||
if(resVal) {
|
||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
sscanf(resVal, "%d", &ret);
|
||||
} else {
|
||||
char *p;
|
||||
|
||||
p = GetValueFromNameValueList(&pdata, "NewReservedPort");
|
||||
if(p) {
|
||||
strncpy(reservedPort, p, 6);
|
||||
reservedPort[5] = '\0';
|
||||
ret = UPNPCOMMAND_SUCCESS;
|
||||
} else {
|
||||
ret = UPNPCOMMAND_INVALID_RESPONSE;
|
||||
}
|
||||
}
|
||||
ClearNameValueList(&pdata);
|
||||
free(AddPortMappingArgs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LIBSPEC int
|
||||
UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
|
||||
const char * extPort, const char * proto,
|
||||
|
@ -438,6 +505,52 @@ UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
|
|||
return ret;
|
||||
}
|
||||
|
||||
LIBSPEC int
|
||||
UPNP_DeletePortMappingRange(const char * controlURL, const char * servicetype,
|
||||
const char * extPortStart, const char * extPortEnd,
|
||||
const char * proto,
|
||||
const char * manage)
|
||||
{
|
||||
struct UPNParg * DeletePortMappingArgs;
|
||||
char * buffer;
|
||||
int bufsize;
|
||||
struct NameValueParserData pdata;
|
||||
const char * resVal;
|
||||
int ret;
|
||||
|
||||
if(!extPortStart || !extPortEnd || !proto || !manage)
|
||||
return UPNPCOMMAND_INVALID_ARGS;
|
||||
|
||||
DeletePortMappingArgs = calloc(5, sizeof(struct UPNParg));
|
||||
DeletePortMappingArgs[0].elt = "NewStartPort";
|
||||
DeletePortMappingArgs[0].val = extPortStart;
|
||||
DeletePortMappingArgs[1].elt = "NewEndPort";
|
||||
DeletePortMappingArgs[1].val = extPortEnd;
|
||||
DeletePortMappingArgs[2].elt = "NewProtocol";
|
||||
DeletePortMappingArgs[2].val = proto;
|
||||
DeletePortMappingArgs[3].elt = "NewManage";
|
||||
DeletePortMappingArgs[3].val = manage;
|
||||
|
||||
if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
|
||||
"DeletePortMappingRange",
|
||||
DeletePortMappingArgs, &bufsize))) {
|
||||
free(DeletePortMappingArgs);
|
||||
return UPNPCOMMAND_HTTP_ERROR;
|
||||
}
|
||||
ParseNameValue(buffer, bufsize, &pdata);
|
||||
free(buffer); buffer = NULL;
|
||||
resVal = GetValueFromNameValueList(&pdata, "errorCode");
|
||||
if(resVal) {
|
||||
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
||||
sscanf(resVal, "%d", &ret);
|
||||
} else {
|
||||
ret = UPNPCOMMAND_SUCCESS;
|
||||
}
|
||||
ClearNameValueList(&pdata);
|
||||
free(DeletePortMappingArgs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LIBSPEC int
|
||||
UPNP_GetGenericPortMappingEntry(const char * controlURL,
|
||||
const char * servicetype,
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#define UPNPCOMMAND_UNKNOWN_ERROR (-1)
|
||||
#define UPNPCOMMAND_INVALID_ARGS (-2)
|
||||
#define UPNPCOMMAND_HTTP_ERROR (-3)
|
||||
#define UPNPCOMMAND_INVALID_RESPONSE (-4)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -131,6 +132,40 @@ UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
|
|||
const char * remoteHost,
|
||||
const char * leaseDuration);
|
||||
|
||||
/* UPNP_AddAnyPortMapping()
|
||||
* if desc is NULL, it will be defaulted to "libminiupnpc"
|
||||
* remoteHost is usually NULL because IGD don't support it.
|
||||
*
|
||||
* 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.
|
||||
* 606 Action not authorized - The action requested REQUIRES authorization and
|
||||
* the sender was not authorized.
|
||||
* 715 WildCardNotPermittedInSrcIP - The source IP address cannot be
|
||||
* wild-carded
|
||||
* 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded
|
||||
* 728 NoPortMapsAvailable - There are not enough free ports available to
|
||||
* complete port mapping.
|
||||
* 729 ConflictWithOtherMechanisms - Attempted port mapping is not allowed
|
||||
* due to conflict with other mechanisms.
|
||||
* 732 WildCardNotPermittedInIntPort - The internal port cannot be wild-carded
|
||||
*/
|
||||
LIBSPEC int
|
||||
UPNP_AddAnyPortMapping(const char * controlURL, const char * servicetype,
|
||||
const char * extPort,
|
||||
const char * inPort,
|
||||
const char * inClient,
|
||||
const char * desc,
|
||||
const char * proto,
|
||||
const char * remoteHost,
|
||||
const char * leaseDuration,
|
||||
char * reservedPort);
|
||||
|
||||
/* UPNP_DeletePortMapping()
|
||||
* Use same argument values as what was used for AddPortMapping().
|
||||
* remoteHost is usually NULL because IGD don't support it.
|
||||
|
@ -148,6 +183,25 @@ UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
|
|||
const char * extPort, const char * proto,
|
||||
const char * remoteHost);
|
||||
|
||||
/* UPNP_DeletePortRangeMapping()
|
||||
* Use same argument values as what was used for AddPortMapping().
|
||||
* remoteHost is usually NULL because IGD don't support it.
|
||||
* Return Values :
|
||||
* 0 : SUCCESS
|
||||
* NON ZERO : error. Either an UPnP error code or an undefined error.
|
||||
*
|
||||
* List of possible UPnP errors for DeletePortMapping :
|
||||
* 606 Action not authorized - The action requested REQUIRES authorization
|
||||
* and the sender was not authorized.
|
||||
* 730 PortMappingNotFound - This error message is returned if no port
|
||||
* mapping is found in the specified range.
|
||||
* 733 InconsistentParameters - NewStartPort and NewEndPort values are not consistent. */
|
||||
LIBSPEC int
|
||||
UPNP_DeletePortMappingRange(const char * controlURL, const char * servicetype,
|
||||
const char * extPortStart, const char * extPortEnd,
|
||||
const char * proto,
|
||||
const char * manage);
|
||||
|
||||
/* UPNP_GetPortMappingNumberOfEntries()
|
||||
* not supported by all routers */
|
||||
LIBSPEC int
|
||||
|
|
|
@ -24,6 +24,9 @@ const char * strupnperror(int err)
|
|||
case UPNPCOMMAND_INVALID_ARGS:
|
||||
s = "Miniupnpc Invalid Arguments";
|
||||
break;
|
||||
case UPNPCOMMAND_INVALID_RESPONSE:
|
||||
s = "Miniupnpc Invalid response";
|
||||
break;
|
||||
case UPNPDISCOVER_SOCKET_ERROR:
|
||||
s = "Miniupnpc Socket error";
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue