Allow user to explicitly specify local (source) port
See https://github.com/miniupnp/miniupnp/issues/119 - Replace the sameport parameter to the upnpDiscover* functions - Added constants UPNP_LOCAL_PORT_ANY(0) & UPNP_LOCAL_PORT_SAME(1). The value "1" was chosen for presumed backwards compatability with the previous "sameport" parameter (assuming usesr would have set to 1 if they wanted same port) - Can be specified with "-z" to the test programs "upnpc" & "pymoduletest.py"
This commit is contained in:
parent
f11b8b2a0d
commit
94a5af0c15
|
@ -25,13 +25,16 @@ through the miniupnpc API. The name of the C functions are matching
|
|||
the UPnP methods names. ie: GetGenericPortMappingEntry is
|
||||
UPNP_GetGenericPortMappingEntry.
|
||||
.SH "API FUNCTIONS"
|
||||
.IP "struct UPNPDev * upnpDiscover(int delay, const char * multicastif, const char * minissdpdsock, int sameport, int ipv6, int * error);"
|
||||
.IP "struct UPNPDev * upnpDiscover(int delay, const char * multicastif, const char * minissdpdsock, int localport, int ipv6, int * error);"
|
||||
execute the discovery process.
|
||||
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.
|
||||
If sameport is not null, SSDP packets will be sent from the source port 1900 (same as destination port) otherwise system assign a source port.
|
||||
If localport is set to UPNP_LOCAL_PORT_SAME(1) SSDP packets will be sent
|
||||
from the source port 1900 (same as destination port), if set to
|
||||
UPNP_LOCAL_PORT_ANY(0) system assign a source port, any other value will
|
||||
be attempted as the source port.
|
||||
If ipv6 is not 0, IPv6 is used instead of IPv4 for the discovery process.
|
||||
.IP "void freeUPNPDevlist(struct UPNPDev * devlist);"
|
||||
free the list returned by upnpDiscover().
|
||||
|
|
|
@ -344,7 +344,7 @@ parseMSEARCHReply(const char * reply, int size,
|
|||
MINIUPNP_LIBSPEC struct UPNPDev *
|
||||
upnpDiscoverDevices(const char * const deviceTypes[],
|
||||
int delay, const char * multicastif,
|
||||
const char * minissdpdsock, int sameport,
|
||||
const char * minissdpdsock, int localport,
|
||||
int ipv6,
|
||||
int * error)
|
||||
{
|
||||
|
@ -376,6 +376,8 @@ upnpDiscoverDevices(const char * const deviceTypes[],
|
|||
#endif
|
||||
int linklocal = 1;
|
||||
|
||||
if(localport==UPNP_LOCAL_PORT_SAME)
|
||||
localport = PORT;
|
||||
if(error)
|
||||
*error = UPNPDISCOVER_UNKNOWN_ERROR;
|
||||
#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
|
||||
|
@ -411,14 +413,14 @@ upnpDiscoverDevices(const char * const deviceTypes[],
|
|||
if(ipv6) {
|
||||
struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_r;
|
||||
p->sin6_family = AF_INET6;
|
||||
if(sameport)
|
||||
p->sin6_port = htons(PORT);
|
||||
if(localport)
|
||||
p->sin6_port = htons(localport);
|
||||
p->sin6_addr = in6addr_any; /* in6addr_any is not available with MinGW32 3.4.2 */
|
||||
} else {
|
||||
struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_r;
|
||||
p->sin_family = AF_INET;
|
||||
if(sameport)
|
||||
p->sin_port = htons(PORT);
|
||||
if(localport)
|
||||
p->sin_port = htons(localport);
|
||||
p->sin_addr.s_addr = INADDR_ANY;
|
||||
}
|
||||
#ifdef _WIN32
|
||||
|
@ -715,7 +717,7 @@ error:
|
|||
/* upnpDiscover() Discover IGD device */
|
||||
MINIUPNP_LIBSPEC struct UPNPDev *
|
||||
upnpDiscover(int delay, const char * multicastif,
|
||||
const char * minissdpdsock, int sameport,
|
||||
const char * minissdpdsock, int localport,
|
||||
int ipv6,
|
||||
int * error)
|
||||
{
|
||||
|
@ -732,14 +734,14 @@ upnpDiscover(int delay, const char * multicastif,
|
|||
0
|
||||
};
|
||||
return upnpDiscoverDevices(deviceList,
|
||||
delay, multicastif, minissdpdsock, sameport,
|
||||
delay, multicastif, minissdpdsock, localport,
|
||||
ipv6, error);
|
||||
}
|
||||
|
||||
/* upnpDiscoverAll() Discover all UPnP devices */
|
||||
MINIUPNP_LIBSPEC struct UPNPDev *
|
||||
upnpDiscoverAll(int delay, const char * multicastif,
|
||||
const char * minissdpdsock, int sameport,
|
||||
const char * minissdpdsock, int localport,
|
||||
int ipv6,
|
||||
int * error)
|
||||
{
|
||||
|
@ -749,14 +751,14 @@ upnpDiscoverAll(int delay, const char * multicastif,
|
|||
0
|
||||
};
|
||||
return upnpDiscoverDevices(deviceList,
|
||||
delay, multicastif, minissdpdsock, sameport,
|
||||
delay, multicastif, minissdpdsock, localport,
|
||||
ipv6, error);
|
||||
}
|
||||
|
||||
/* upnpDiscoverDevice() Discover a specific device */
|
||||
MINIUPNP_LIBSPEC struct UPNPDev *
|
||||
upnpDiscoverDevice(const char * device, int delay, const char * multicastif,
|
||||
const char * minissdpdsock, int sameport,
|
||||
const char * minissdpdsock, int localport,
|
||||
int ipv6,
|
||||
int * error)
|
||||
{
|
||||
|
@ -765,7 +767,7 @@ upnpDiscoverDevice(const char * device, int delay, const char * multicastif,
|
|||
0
|
||||
};
|
||||
return upnpDiscoverDevices(deviceList,
|
||||
delay, multicastif, minissdpdsock, sameport,
|
||||
delay, multicastif, minissdpdsock, localport,
|
||||
ipv6, error);
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,12 @@
|
|||
#define MINIUPNPC_VERSION "1.9"
|
||||
#define MINIUPNPC_API_VERSION 12
|
||||
|
||||
/* Source port:
|
||||
Using "1" as an alias for 1900 for backwards compatability
|
||||
(presuming one would have used that for the "sameport" parameter) */
|
||||
#define UPNP_LOCAL_PORT_ANY 0
|
||||
#define UPNP_LOCAL_PORT_SAME 1
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -52,30 +58,32 @@ struct UPNPDev {
|
|||
* is NULL.
|
||||
* If multicastif is not NULL, it will be used instead of the default
|
||||
* multicast interface for sending SSDP discover packets.
|
||||
* If sameport is not null, SSDP packets will be sent from the source port
|
||||
* 1900 (same as destination port) otherwise system assign a source port. */
|
||||
* If localport is set to UPNP_LOCAL_PORT_SAME(1) SSDP packets will be sent
|
||||
* from the source port 1900 (same as destination port), if set to
|
||||
* UPNP_LOCAL_PORT_ANY(0) system assign a source port, any other value will
|
||||
* be attempted as the source port */
|
||||
MINIUPNP_LIBSPEC struct UPNPDev *
|
||||
upnpDiscover(int delay, const char * multicastif,
|
||||
const char * minissdpdsock, int sameport,
|
||||
const char * minissdpdsock, int localport,
|
||||
int ipv6,
|
||||
int * error);
|
||||
|
||||
MINIUPNP_LIBSPEC struct UPNPDev *
|
||||
upnpDiscoverAll(int delay, const char * multicastif,
|
||||
const char * minissdpdsock, int sameport,
|
||||
const char * minissdpdsock, int localport,
|
||||
int ipv6,
|
||||
int * error);
|
||||
|
||||
MINIUPNP_LIBSPEC struct UPNPDev *
|
||||
upnpDiscoverDevice(const char * device, int delay, const char * multicastif,
|
||||
const char * minissdpdsock, int sameport,
|
||||
const char * minissdpdsock, int localport,
|
||||
int ipv6,
|
||||
int * error);
|
||||
|
||||
MINIUPNP_LIBSPEC struct UPNPDev *
|
||||
upnpDiscoverDevices(const char * const deviceTypes[],
|
||||
int delay, const char * multicastif,
|
||||
const char * minissdpdsock, int sameport,
|
||||
const char * minissdpdsock, int localport,
|
||||
int ipv6,
|
||||
int * error);
|
||||
|
||||
|
|
|
@ -42,6 +42,7 @@ typedef struct {
|
|||
struct UPNPUrls urls;
|
||||
struct IGDdatas data;
|
||||
unsigned int discoverdelay; /* value passed to upnpDiscover() */
|
||||
unsigned int localport; /* value passed to upnpDiscover() */
|
||||
char lanaddr[40]; /* our ip address on the LAN */
|
||||
char * multicastif;
|
||||
char * minissdpdsocket;
|
||||
|
@ -54,6 +55,15 @@ static PyMemberDef UPnP_members[] = {
|
|||
{"discoverdelay", T_UINT, offsetof(UPnPObject, discoverdelay),
|
||||
0/*READWRITE*/, "value in ms used to wait for SSDP responses"
|
||||
},
|
||||
{"localport", T_UINT, offsetof(UPnPObject, localport),
|
||||
0/*READWRITE*/,
|
||||
"If localport is set to UPNP_LOCAL_PORT_SAME(1) "
|
||||
"SSDP packets will be sent from the source port "
|
||||
"1900 (same as destination port), if set to "
|
||||
"UPNP_LOCAL_PORT_ANY(0) system assign a source "
|
||||
"port, any other value will be attempted as the "
|
||||
"source port"
|
||||
},
|
||||
/* T_STRING is allways readonly :( */
|
||||
{"multicastif", T_STRING, offsetof(UPnPObject, multicastif),
|
||||
0, "IP of the network interface to be used for multicast operations"
|
||||
|
@ -70,15 +80,22 @@ static int UPnP_init(UPnPObject *self, PyObject *args, PyObject *kwds)
|
|||
char* multicastif = NULL;
|
||||
char* minissdpdsocket = NULL;
|
||||
static char *kwlist[] = {
|
||||
"multicastif", "minissdpdsocket", "discoverdelay", NULL
|
||||
"multicastif", "minissdpdsocket", "discoverdelay",
|
||||
"localport", NULL
|
||||
};
|
||||
|
||||
if(!PyArg_ParseTupleAndKeywords(args, kwds, "|zzI", kwlist,
|
||||
if(!PyArg_ParseTupleAndKeywords(args, kwds, "|zzII", kwlist,
|
||||
&multicastif,
|
||||
&minissdpdsocket,
|
||||
&self->discoverdelay))
|
||||
&self->discoverdelay,
|
||||
&self->localport))
|
||||
return -1;
|
||||
|
||||
if(self->localport>1 &&
|
||||
(self->localport>65534||self->localport<1024)) {
|
||||
PyErr_SetString(PyExc_Exception, "Invalid localport value");
|
||||
return -1;
|
||||
}
|
||||
if(multicastif)
|
||||
self->multicastif = strdup(multicastif);
|
||||
if(minissdpdsocket)
|
||||
|
@ -112,7 +129,7 @@ UPnP_discover(UPnPObject *self)
|
|||
self->devlist = upnpDiscover((int)self->discoverdelay/*timeout in ms*/,
|
||||
self->multicastif,
|
||||
self->minissdpdsocket,
|
||||
0/*sameport flag*/,
|
||||
(int)self->localport,
|
||||
0/*ip v6*/,
|
||||
0/*error */);
|
||||
Py_END_ALLOW_THREADS
|
||||
|
|
|
@ -14,6 +14,7 @@ parser = argparse.ArgumentParser()
|
|||
parser.add_argument('-m', '--multicastif')
|
||||
parser.add_argument('-p', '--minissdpdsocket')
|
||||
parser.add_argument('-d', '--discoverdelay', type=int, default=200)
|
||||
parser.add_argument('-z', '--localport', type=int, default=0)
|
||||
|
||||
# create the object
|
||||
u = miniupnpc.UPnP(**vars(parser.parse_args()))
|
||||
|
|
|
@ -543,6 +543,7 @@ int main(int argc, char ** argv)
|
|||
const char * rootdescurl = 0;
|
||||
const char * multicastif = 0;
|
||||
const char * minissdpdpath = 0;
|
||||
int localport = UPNP_LOCAL_PORT_ANY;
|
||||
int retcode = 0;
|
||||
int error = 0;
|
||||
int ipv6 = 0;
|
||||
|
@ -575,6 +576,16 @@ int main(int argc, char ** argv)
|
|||
rootdescurl = argv[++i];
|
||||
else if(argv[i][1] == 'm')
|
||||
multicastif = argv[++i];
|
||||
else if(argv[i][1] == 'z'){
|
||||
char junk;
|
||||
if(sscanf(argv[++i], "%d%c", &localport, &junk)!=1 ||
|
||||
localport<0 || localport>65535 ||
|
||||
(localport >1 && localport < 1024)){
|
||||
fprintf(stderr, "Invalid localport '%s'\n", argv[i]);
|
||||
localport = UPNP_LOCAL_PORT_ANY;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if(argv[i][1] == 'p')
|
||||
minissdpdpath = argv[++i];
|
||||
else if(argv[i][1] == '6')
|
||||
|
@ -626,13 +637,14 @@ int main(int argc, char ** argv)
|
|||
fprintf(stderr, " -6 : use ip v6 instead of ip v4.\n");
|
||||
fprintf(stderr, " -u url : bypass discovery process by providing the XML root description url.\n");
|
||||
fprintf(stderr, " -m address/interface : provide ip address (ip v4) or interface name (ip v4 or v6) to use for sending SSDP multicast packets.\n");
|
||||
fprintf(stderr, " -z localport : SSDP packets local (source) port (1024-65535).\n");
|
||||
fprintf(stderr, " -p path : use this path for MiniSSDPd socket.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if( rootdescurl
|
||||
|| (devlist = upnpDiscover(2000, multicastif, minissdpdpath,
|
||||
0/*sameport*/, ipv6, &error)))
|
||||
localport, ipv6, &error)))
|
||||
{
|
||||
struct UPNPDev * device;
|
||||
struct UPNPUrls urls;
|
||||
|
|
Loading…
Reference in New Issue