Annotation of embedaddon/miniupnpc/src/miniupnpcmodule.c, revision 1.1
1.1 ! misho 1: /* $Id: miniupnpcmodule.c,v 1.38 2021/11/09 18:46:49 nanard Exp $*/
! 2: /* vim: tabstop=4 shiftwidth=4 noexpandtab
! 3: * Project : miniupnp
! 4: * Author : Thomas BERNARD
! 5: * website : https://miniupnp.tuxfamily.org/
! 6: * copyright (c) 2007-2021 Thomas Bernard
! 7: * This software is subjet to the conditions detailed in the
! 8: * provided LICENCE file. */
! 9: #include <Python.h>
! 10: #define MINIUPNP_STATICLIB
! 11: #include <structmember.h>
! 12: #include "miniupnpc.h"
! 13: #include "upnpcommands.h"
! 14: #include "upnperrors.h"
! 15:
! 16: #ifdef _WIN32
! 17: #include <winsock2.h>
! 18: #endif
! 19:
! 20: /* for compatibility with Python < 2.4 */
! 21: #ifndef Py_RETURN_NONE
! 22: #define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
! 23: #endif
! 24:
! 25: #ifndef Py_RETURN_TRUE
! 26: #define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True
! 27: #endif
! 28:
! 29: #ifndef Py_RETURN_FALSE
! 30: #define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False
! 31: #endif
! 32:
! 33: /* for compatibility with Python < 3.0 */
! 34: #ifndef PyVarObject_HEAD_INIT
! 35: #define PyVarObject_HEAD_INIT(type, size) \
! 36: PyObject_HEAD_INIT(type) size,
! 37: #endif
! 38:
! 39: #ifndef Py_TYPE
! 40: #define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
! 41: #endif
! 42:
! 43: typedef struct {
! 44: PyObject_HEAD
! 45: /* Type-specific fields go here. */
! 46: struct UPNPDev * devlist;
! 47: struct UPNPUrls urls;
! 48: struct IGDdatas data;
! 49: unsigned int discoverdelay; /* value passed to upnpDiscover() */
! 50: unsigned int localport; /* value passed to upnpDiscover() */
! 51: char lanaddr[40]; /* our ip address on the LAN */
! 52: char * multicastif;
! 53: char * minissdpdsocket;
! 54: } UPnPObject;
! 55:
! 56: static PyMemberDef UPnP_members[] = {
! 57: {"lanaddr", T_STRING_INPLACE, offsetof(UPnPObject, lanaddr),
! 58: READONLY, "ip address on the LAN"
! 59: },
! 60: {"discoverdelay", T_UINT, offsetof(UPnPObject, discoverdelay),
! 61: 0/*READWRITE*/, "value in ms used to wait for SSDP responses"
! 62: },
! 63: {"localport", T_UINT, offsetof(UPnPObject, localport),
! 64: 0/*READWRITE*/,
! 65: "If localport is set to UPNP_LOCAL_PORT_SAME(1) "
! 66: "SSDP packets will be sent from the source port "
! 67: "1900 (same as destination port), if set to "
! 68: "UPNP_LOCAL_PORT_ANY(0) system assign a source "
! 69: "port, any other value will be attempted as the "
! 70: "source port"
! 71: },
! 72: /* T_STRING is always readonly :( */
! 73: {"multicastif", T_STRING, offsetof(UPnPObject, multicastif),
! 74: 0, "IP of the network interface to be used for multicast operations"
! 75: },
! 76: {"minissdpdsocket", T_STRING, offsetof(UPnPObject, minissdpdsocket),
! 77: 0, "path of the MiniSSDPd unix socket"
! 78: },
! 79: {NULL}
! 80: };
! 81:
! 82:
! 83: static int UPnP_init(UPnPObject *self, PyObject *args, PyObject *kwds)
! 84: {
! 85: char* multicastif = NULL;
! 86: char* minissdpdsocket = NULL;
! 87: static char *kwlist[] = {
! 88: "multicastif", "minissdpdsocket", "discoverdelay",
! 89: "localport", NULL
! 90: };
! 91:
! 92: if(!PyArg_ParseTupleAndKeywords(args, kwds, "|zzII", kwlist,
! 93: &multicastif,
! 94: &minissdpdsocket,
! 95: &self->discoverdelay,
! 96: &self->localport))
! 97: return -1;
! 98:
! 99: if(self->localport>1 &&
! 100: (self->localport>65534||self->localport<1024)) {
! 101: PyErr_SetString(PyExc_Exception, "Invalid localport value");
! 102: return -1;
! 103: }
! 104: if(multicastif)
! 105: self->multicastif = strdup(multicastif);
! 106: if(minissdpdsocket)
! 107: self->minissdpdsocket = strdup(minissdpdsocket);
! 108:
! 109: return 0;
! 110: }
! 111:
! 112: static void
! 113: UPnPObject_dealloc(UPnPObject *self)
! 114: {
! 115: freeUPNPDevlist(self->devlist);
! 116: FreeUPNPUrls(&self->urls);
! 117: free(self->multicastif);
! 118: free(self->minissdpdsocket);
! 119: Py_TYPE(self)->tp_free((PyObject*)self);
! 120: }
! 121:
! 122: static PyObject *
! 123: UPnP_discover(UPnPObject *self)
! 124: {
! 125: int error = 0;
! 126: PyObject *res = NULL;
! 127:
! 128: if(self->devlist)
! 129: {
! 130: freeUPNPDevlist(self->devlist);
! 131: self->devlist = 0;
! 132: }
! 133: Py_BEGIN_ALLOW_THREADS
! 134: self->devlist = upnpDiscover((int)self->discoverdelay/*timeout in ms*/,
! 135: self->multicastif,
! 136: self->minissdpdsocket,
! 137: (int)self->localport,
! 138: 0/*ip v6*/,
! 139: 2/* TTL */,
! 140: &error);
! 141: Py_END_ALLOW_THREADS
! 142: /* Py_RETURN_NONE ??? */
! 143: if (self->devlist != NULL) {
! 144: struct UPNPDev * dev;
! 145: int i = 0;
! 146:
! 147: for(dev = self->devlist; dev; dev = dev->pNext)
! 148: i++;
! 149: res = Py_BuildValue("i", i);
! 150: return res;
! 151: } else {
! 152: PyErr_SetString(PyExc_Exception, strupnperror(error));
! 153: return NULL;
! 154: }
! 155: }
! 156:
! 157: static PyObject *
! 158: UPnP_selectigd(UPnPObject *self, PyObject *args)
! 159: {
! 160: const char * rootDescUrl = NULL;
! 161: int r;
! 162: if(!PyArg_ParseTuple(args, "|z", &rootDescUrl))
! 163: return NULL;
! 164: Py_BEGIN_ALLOW_THREADS
! 165: if (rootDescUrl == NULL) {
! 166: r = UPNP_GetValidIGD(self->devlist, &self->urls, &self->data,
! 167: self->lanaddr, sizeof(self->lanaddr));
! 168: } else {
! 169: r = UPNP_GetIGDFromUrl(rootDescUrl, &self->urls, &self->data,
! 170: self->lanaddr, sizeof(self->lanaddr));
! 171: }
! 172: Py_END_ALLOW_THREADS
! 173: if(r)
! 174: {
! 175: return Py_BuildValue("s", self->urls.controlURL);
! 176: }
! 177: else
! 178: {
! 179: /* TODO: have our own exception type ! */
! 180: PyErr_SetString(PyExc_Exception, "No UPnP device discovered");
! 181: return NULL;
! 182: }
! 183: }
! 184:
! 185: static PyObject *
! 186: UPnP_totalbytesent(UPnPObject *self)
! 187: {
! 188: UNSIGNED_INTEGER i;
! 189: Py_BEGIN_ALLOW_THREADS
! 190: i = UPNP_GetTotalBytesSent(self->urls.controlURL_CIF,
! 191: self->data.CIF.servicetype);
! 192: Py_END_ALLOW_THREADS
! 193: #if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3)
! 194: return Py_BuildValue("I", i);
! 195: #else
! 196: return Py_BuildValue("i", (int)i);
! 197: #endif
! 198: }
! 199:
! 200: static PyObject *
! 201: UPnP_totalbytereceived(UPnPObject *self)
! 202: {
! 203: UNSIGNED_INTEGER i;
! 204: Py_BEGIN_ALLOW_THREADS
! 205: i = UPNP_GetTotalBytesReceived(self->urls.controlURL_CIF,
! 206: self->data.CIF.servicetype);
! 207: Py_END_ALLOW_THREADS
! 208: #if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3)
! 209: return Py_BuildValue("I", i);
! 210: #else
! 211: return Py_BuildValue("i", (int)i);
! 212: #endif
! 213: }
! 214:
! 215: static PyObject *
! 216: UPnP_totalpacketsent(UPnPObject *self)
! 217: {
! 218: UNSIGNED_INTEGER i;
! 219: Py_BEGIN_ALLOW_THREADS
! 220: i = UPNP_GetTotalPacketsSent(self->urls.controlURL_CIF,
! 221: self->data.CIF.servicetype);
! 222: Py_END_ALLOW_THREADS
! 223: #if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3)
! 224: return Py_BuildValue("I", i);
! 225: #else
! 226: return Py_BuildValue("i", (int)i);
! 227: #endif
! 228: }
! 229:
! 230: static PyObject *
! 231: UPnP_totalpacketreceived(UPnPObject *self)
! 232: {
! 233: UNSIGNED_INTEGER i;
! 234: Py_BEGIN_ALLOW_THREADS
! 235: i = UPNP_GetTotalPacketsReceived(self->urls.controlURL_CIF,
! 236: self->data.CIF.servicetype);
! 237: Py_END_ALLOW_THREADS
! 238: #if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3)
! 239: return Py_BuildValue("I", i);
! 240: #else
! 241: return Py_BuildValue("i", (int)i);
! 242: #endif
! 243: }
! 244:
! 245: static PyObject *
! 246: UPnP_statusinfo(UPnPObject *self)
! 247: {
! 248: char status[64];
! 249: char lastconnerror[64];
! 250: unsigned int uptime = 0;
! 251: int r;
! 252: status[0] = '\0';
! 253: lastconnerror[0] = '\0';
! 254: Py_BEGIN_ALLOW_THREADS
! 255: r = UPNP_GetStatusInfo(self->urls.controlURL, self->data.first.servicetype,
! 256: status, &uptime, lastconnerror);
! 257: Py_END_ALLOW_THREADS
! 258: if(r==UPNPCOMMAND_SUCCESS) {
! 259: #if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3)
! 260: return Py_BuildValue("(s,I,s)", status, uptime, lastconnerror);
! 261: #else
! 262: return Py_BuildValue("(s,i,s)", status, (int)uptime, lastconnerror);
! 263: #endif
! 264: } else {
! 265: /* TODO: have our own exception type ! */
! 266: PyErr_SetString(PyExc_Exception, strupnperror(r));
! 267: return NULL;
! 268: }
! 269: }
! 270:
! 271: static PyObject *
! 272: UPnP_connectiontype(UPnPObject *self)
! 273: {
! 274: char connectionType[64];
! 275: int r;
! 276: connectionType[0] = '\0';
! 277: Py_BEGIN_ALLOW_THREADS
! 278: r = UPNP_GetConnectionTypeInfo(self->urls.controlURL,
! 279: self->data.first.servicetype,
! 280: connectionType);
! 281: Py_END_ALLOW_THREADS
! 282: if(r==UPNPCOMMAND_SUCCESS) {
! 283: return Py_BuildValue("s", connectionType);
! 284: } else {
! 285: /* TODO: have our own exception type ! */
! 286: PyErr_SetString(PyExc_Exception, strupnperror(r));
! 287: return NULL;
! 288: }
! 289: }
! 290:
! 291: static PyObject *
! 292: UPnP_externalipaddress(UPnPObject *self)
! 293: {
! 294: char externalIPAddress[40];
! 295: int r;
! 296: externalIPAddress[0] = '\0';
! 297: Py_BEGIN_ALLOW_THREADS
! 298: r = UPNP_GetExternalIPAddress(self->urls.controlURL,
! 299: self->data.first.servicetype,
! 300: externalIPAddress);
! 301: Py_END_ALLOW_THREADS
! 302: if(r==UPNPCOMMAND_SUCCESS) {
! 303: return Py_BuildValue("s", externalIPAddress);
! 304: } else {
! 305: /* TODO: have our own exception type ! */
! 306: PyErr_SetString(PyExc_Exception, strupnperror(r));
! 307: return NULL;
! 308: }
! 309: }
! 310:
! 311: /* AddPortMapping(externalPort, protocol, internalHost, internalPort, desc,
! 312: * remoteHost, leaseDuration)
! 313: * protocol is 'UDP' or 'TCP' */
! 314: static PyObject *
! 315: UPnP_addportmapping(UPnPObject *self, PyObject *args)
! 316: {
! 317: char extPort[6];
! 318: unsigned short ePort;
! 319: char inPort[6];
! 320: unsigned short iPort;
! 321: const char * proto;
! 322: const char * host;
! 323: const char * desc;
! 324: const char * remoteHost;
! 325: unsigned int intLeaseDuration = 0;
! 326: char strLeaseDuration[12];
! 327: int r;
! 328: #if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3)
! 329: if (!PyArg_ParseTuple(args, "HssHzz|I", &ePort, &proto,
! 330: &host, &iPort, &desc, &remoteHost, &intLeaseDuration))
! 331: #else
! 332: if (!PyArg_ParseTuple(args, "HssHzz|i", &ePort, &proto,
! 333: &host, &iPort, &desc, &remoteHost, (int *)&intLeaseDuration))
! 334: #endif
! 335: return NULL;
! 336: Py_BEGIN_ALLOW_THREADS
! 337: sprintf(extPort, "%hu", ePort);
! 338: sprintf(inPort, "%hu", iPort);
! 339: sprintf(strLeaseDuration, "%u", intLeaseDuration);
! 340: r = UPNP_AddPortMapping(self->urls.controlURL, self->data.first.servicetype,
! 341: extPort, inPort, host, desc, proto,
! 342: remoteHost, strLeaseDuration);
! 343: Py_END_ALLOW_THREADS
! 344: if(r==UPNPCOMMAND_SUCCESS)
! 345: {
! 346: Py_RETURN_TRUE;
! 347: }
! 348: else
! 349: {
! 350: // TODO: RAISE an Exception. See upnpcommands.h for errors codes.
! 351: // upnperrors.c
! 352: //Py_RETURN_FALSE;
! 353: /* TODO: have our own exception type ! */
! 354: PyErr_SetString(PyExc_Exception, strupnperror(r));
! 355: return NULL;
! 356: }
! 357: }
! 358:
! 359: /* AddAnyPortMapping(externalPort, protocol, internalHost, internalPort, desc,
! 360: * remoteHost)
! 361: * protocol is 'UDP' or 'TCP' */
! 362: static PyObject *
! 363: UPnP_addanyportmapping(UPnPObject *self, PyObject *args)
! 364: {
! 365: char extPort[6];
! 366: unsigned short ePort;
! 367: char inPort[6];
! 368: unsigned short iPort;
! 369: char reservedPort[6];
! 370: const char * proto;
! 371: const char * host;
! 372: const char * desc;
! 373: const char * remoteHost;
! 374: const char * leaseDuration = "0";
! 375: int r;
! 376: if (!PyArg_ParseTuple(args, "HssHzz", &ePort, &proto, &host, &iPort, &desc, &remoteHost))
! 377: return NULL;
! 378: Py_BEGIN_ALLOW_THREADS
! 379: sprintf(extPort, "%hu", ePort);
! 380: sprintf(inPort, "%hu", iPort);
! 381: r = UPNP_AddAnyPortMapping(self->urls.controlURL, self->data.first.servicetype,
! 382: extPort, inPort, host, desc, proto,
! 383: remoteHost, leaseDuration, reservedPort);
! 384: Py_END_ALLOW_THREADS
! 385: if(r==UPNPCOMMAND_SUCCESS) {
! 386: return Py_BuildValue("i", atoi(reservedPort));
! 387: } else {
! 388: /* TODO: have our own exception type ! */
! 389: PyErr_SetString(PyExc_Exception, strupnperror(r));
! 390: return NULL;
! 391: }
! 392: }
! 393:
! 394:
! 395: /* DeletePortMapping(extPort, proto, removeHost='')
! 396: * proto = 'UDP', 'TCP' */
! 397: static PyObject *
! 398: UPnP_deleteportmapping(UPnPObject *self, PyObject *args)
! 399: {
! 400: char extPort[6];
! 401: unsigned short ePort;
! 402: const char * proto;
! 403: const char * remoteHost = "";
! 404: int r;
! 405: if(!PyArg_ParseTuple(args, "Hs|z", &ePort, &proto, &remoteHost))
! 406: return NULL;
! 407: Py_BEGIN_ALLOW_THREADS
! 408: sprintf(extPort, "%hu", ePort);
! 409: r = UPNP_DeletePortMapping(self->urls.controlURL, self->data.first.servicetype,
! 410: extPort, proto, remoteHost);
! 411: Py_END_ALLOW_THREADS
! 412: if(r==UPNPCOMMAND_SUCCESS) {
! 413: Py_RETURN_TRUE;
! 414: } else {
! 415: /* TODO: have our own exception type ! */
! 416: PyErr_SetString(PyExc_Exception, strupnperror(r));
! 417: return NULL;
! 418: }
! 419: }
! 420:
! 421: /* DeletePortMappingRange(extPort, proto, removeHost='')
! 422: * proto = 'UDP', 'TCP' */
! 423: static PyObject *
! 424: UPnP_deleteportmappingrange(UPnPObject *self, PyObject *args)
! 425: {
! 426: char extPortStart[6];
! 427: unsigned short ePortStart;
! 428: char extPortEnd[6];
! 429: unsigned short ePortEnd;
! 430: const char * proto;
! 431: unsigned char manage;
! 432: char manageStr[6];
! 433: int r;
! 434: if(!PyArg_ParseTuple(args, "HHsb", &ePortStart, &ePortEnd, &proto, &manage))
! 435: return NULL;
! 436: Py_BEGIN_ALLOW_THREADS
! 437: sprintf(extPortStart, "%hu", ePortStart);
! 438: sprintf(extPortEnd, "%hu", ePortEnd);
! 439: sprintf(manageStr, "%hu", (unsigned short)manage);
! 440: r = UPNP_DeletePortMappingRange(self->urls.controlURL, self->data.first.servicetype,
! 441: extPortStart, extPortEnd, proto, manageStr);
! 442: Py_END_ALLOW_THREADS
! 443: if(r==UPNPCOMMAND_SUCCESS) {
! 444: Py_RETURN_TRUE;
! 445: } else {
! 446: /* TODO: have our own exception type ! */
! 447: PyErr_SetString(PyExc_Exception, strupnperror(r));
! 448: return NULL;
! 449: }
! 450: }
! 451:
! 452: static PyObject *
! 453: UPnP_getportmappingnumberofentries(UPnPObject *self)
! 454: {
! 455: unsigned int n = 0;
! 456: int r;
! 457: Py_BEGIN_ALLOW_THREADS
! 458: r = UPNP_GetPortMappingNumberOfEntries(self->urls.controlURL,
! 459: self->data.first.servicetype,
! 460: &n);
! 461: Py_END_ALLOW_THREADS
! 462: if(r==UPNPCOMMAND_SUCCESS) {
! 463: #if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3)
! 464: return Py_BuildValue("I", n);
! 465: #else
! 466: return Py_BuildValue("i", (int)n);
! 467: #endif
! 468: } else {
! 469: /* TODO: have our own exception type ! */
! 470: PyErr_SetString(PyExc_Exception, strupnperror(r));
! 471: return NULL;
! 472: }
! 473: }
! 474:
! 475: /* GetSpecificPortMapping(ePort, proto, remoteHost='')
! 476: * proto = 'UDP' or 'TCP' */
! 477: static PyObject *
! 478: UPnP_getspecificportmapping(UPnPObject *self, PyObject *args)
! 479: {
! 480: char extPort[6];
! 481: unsigned short ePort;
! 482: const char * proto;
! 483: const char * remoteHost = "";
! 484: char intClient[40];
! 485: char intPort[6];
! 486: unsigned short iPort;
! 487: char desc[80];
! 488: char enabled[4];
! 489: char leaseDuration[16];
! 490: if(!PyArg_ParseTuple(args, "Hs|z", &ePort, &proto, &remoteHost))
! 491: return NULL;
! 492: extPort[0] = '\0'; intClient[0] = '\0'; intPort[0] = '\0';
! 493: desc[0] = '\0'; enabled[0] = '\0'; leaseDuration[0] = '\0';
! 494: Py_BEGIN_ALLOW_THREADS
! 495: sprintf(extPort, "%hu", ePort);
! 496: UPNP_GetSpecificPortMappingEntry(self->urls.controlURL,
! 497: self->data.first.servicetype,
! 498: extPort, proto, remoteHost,
! 499: intClient, intPort,
! 500: desc, enabled, leaseDuration);
! 501: Py_END_ALLOW_THREADS
! 502: if(intClient[0])
! 503: {
! 504: iPort = (unsigned short)atoi(intPort);
! 505: return Py_BuildValue("(s,H,s,O,i)",
! 506: intClient, iPort, desc,
! 507: PyBool_FromLong(atoi(enabled)),
! 508: atoi(leaseDuration));
! 509: }
! 510: else
! 511: {
! 512: Py_RETURN_NONE;
! 513: }
! 514: }
! 515:
! 516: /* GetGenericPortMapping(index) */
! 517: static PyObject *
! 518: UPnP_getgenericportmapping(UPnPObject *self, PyObject *args)
! 519: {
! 520: int i, r;
! 521: char index[8];
! 522: char intClient[40];
! 523: char intPort[6];
! 524: unsigned short iPort;
! 525: char extPort[6];
! 526: unsigned short ePort;
! 527: char protocol[4];
! 528: char desc[80];
! 529: char enabled[6];
! 530: char rHost[64];
! 531: char duration[16]; /* lease duration */
! 532: unsigned int dur;
! 533: if(!PyArg_ParseTuple(args, "i", &i))
! 534: return NULL;
! 535: Py_BEGIN_ALLOW_THREADS
! 536: snprintf(index, sizeof(index), "%d", i);
! 537: rHost[0] = '\0'; enabled[0] = '\0';
! 538: duration[0] = '\0'; desc[0] = '\0';
! 539: extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0';
! 540: r = UPNP_GetGenericPortMappingEntry(self->urls.controlURL,
! 541: self->data.first.servicetype,
! 542: index,
! 543: extPort, intClient, intPort,
! 544: protocol, desc, enabled, rHost,
! 545: duration);
! 546: Py_END_ALLOW_THREADS
! 547: if(r==UPNPCOMMAND_SUCCESS)
! 548: {
! 549: ePort = (unsigned short)atoi(extPort);
! 550: iPort = (unsigned short)atoi(intPort);
! 551: dur = (unsigned int)strtoul(duration, 0, 0);
! 552: #if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3)
! 553: return Py_BuildValue("(H,s,(s,H),s,s,s,I)",
! 554: ePort, protocol, intClient, iPort,
! 555: desc, enabled, rHost, dur);
! 556: #else
! 557: return Py_BuildValue("(i,s,(s,i),s,s,s,i)",
! 558: (int)ePort, protocol, intClient, (int)iPort,
! 559: desc, enabled, rHost, (int)dur);
! 560: #endif
! 561: }
! 562: else
! 563: {
! 564: Py_RETURN_NONE;
! 565: }
! 566: }
! 567:
! 568: /* miniupnpc.UPnP object Method Table */
! 569: static PyMethodDef UPnP_methods[] = {
! 570: {"discover", (PyCFunction)UPnP_discover, METH_NOARGS,
! 571: "discover UPnP IGD devices on the network"
! 572: },
! 573: {"selectigd", (PyCFunction)UPnP_selectigd, METH_VARARGS,
! 574: "select a valid UPnP IGD among discovered devices"
! 575: },
! 576: {"totalbytesent", (PyCFunction)UPnP_totalbytesent, METH_NOARGS,
! 577: "return the total number of bytes sent by UPnP IGD"
! 578: },
! 579: {"totalbytereceived", (PyCFunction)UPnP_totalbytereceived, METH_NOARGS,
! 580: "return the total number of bytes received by UPnP IGD"
! 581: },
! 582: {"totalpacketsent", (PyCFunction)UPnP_totalpacketsent, METH_NOARGS,
! 583: "return the total number of packets sent by UPnP IGD"
! 584: },
! 585: {"totalpacketreceived", (PyCFunction)UPnP_totalpacketreceived, METH_NOARGS,
! 586: "return the total number of packets received by UPnP IGD"
! 587: },
! 588: {"statusinfo", (PyCFunction)UPnP_statusinfo, METH_NOARGS,
! 589: "return status and uptime"
! 590: },
! 591: {"connectiontype", (PyCFunction)UPnP_connectiontype, METH_NOARGS,
! 592: "return IGD WAN connection type"
! 593: },
! 594: {"externalipaddress", (PyCFunction)UPnP_externalipaddress, METH_NOARGS,
! 595: "return external IP address"
! 596: },
! 597: {"addportmapping", (PyCFunction)UPnP_addportmapping, METH_VARARGS,
! 598: "add a port mapping"
! 599: },
! 600: {"addanyportmapping", (PyCFunction)UPnP_addanyportmapping, METH_VARARGS,
! 601: "add a port mapping, IGD to select alternative if necessary"
! 602: },
! 603: {"deleteportmapping", (PyCFunction)UPnP_deleteportmapping, METH_VARARGS,
! 604: "delete a port mapping"
! 605: },
! 606: {"deleteportmappingrange", (PyCFunction)UPnP_deleteportmappingrange, METH_VARARGS,
! 607: "delete a range of port mappings"
! 608: },
! 609: {"getportmappingnumberofentries", (PyCFunction)UPnP_getportmappingnumberofentries, METH_NOARGS,
! 610: "-- non standard --"
! 611: },
! 612: {"getspecificportmapping", (PyCFunction)UPnP_getspecificportmapping, METH_VARARGS,
! 613: "get details about a specific port mapping entry"
! 614: },
! 615: {"getgenericportmapping", (PyCFunction)UPnP_getgenericportmapping, METH_VARARGS,
! 616: "get all details about the port mapping at index"
! 617: },
! 618: {NULL} /* Sentinel */
! 619: };
! 620:
! 621: static PyTypeObject UPnPType = {
! 622: PyVarObject_HEAD_INIT(NULL,
! 623: 0) /*ob_size*/
! 624: "miniupnpc.UPnP", /*tp_name*/
! 625: sizeof(UPnPObject), /*tp_basicsize*/
! 626: 0, /*tp_itemsize*/
! 627: (destructor)UPnPObject_dealloc,/*tp_dealloc*/
! 628: 0, /*tp_print*/
! 629: 0, /*tp_getattr*/
! 630: 0, /*tp_setattr*/
! 631: 0, /*tp_compare*/
! 632: 0, /*tp_repr*/
! 633: 0, /*tp_as_number*/
! 634: 0, /*tp_as_sequence*/
! 635: 0, /*tp_as_mapping*/
! 636: 0, /*tp_hash */
! 637: 0, /*tp_call*/
! 638: 0, /*tp_str*/
! 639: 0, /*tp_getattro*/
! 640: 0, /*tp_setattro*/
! 641: 0, /*tp_as_buffer*/
! 642: Py_TPFLAGS_DEFAULT, /*tp_flags*/
! 643: "UPnP objects", /* tp_doc */
! 644: 0, /* tp_traverse */
! 645: 0, /* tp_clear */
! 646: 0, /* tp_richcompare */
! 647: 0, /* tp_weaklistoffset */
! 648: 0, /* tp_iter */
! 649: 0, /* tp_iternext */
! 650: UPnP_methods, /* tp_methods */
! 651: UPnP_members, /* tp_members */
! 652: 0, /* tp_getset */
! 653: 0, /* tp_base */
! 654: 0, /* tp_dict */
! 655: 0, /* tp_descr_get */
! 656: 0, /* tp_descr_set */
! 657: 0, /* tp_dictoffset */
! 658: (initproc)UPnP_init, /* tp_init */
! 659: 0, /* tp_alloc */
! 660: #ifndef _WIN32
! 661: PyType_GenericNew,/*UPnP_new,*/ /* tp_new */
! 662: #else
! 663: 0, /* tp_new */
! 664: #endif
! 665: 0, /* tp_free */
! 666: };
! 667:
! 668: /* module methods */
! 669: static PyMethodDef miniupnpc_methods[] = {
! 670: {NULL} /* Sentinel */
! 671: };
! 672:
! 673: #if PY_MAJOR_VERSION >= 3
! 674: static struct PyModuleDef moduledef = {
! 675: PyModuleDef_HEAD_INIT,
! 676: "miniupnpc", /* m_name */
! 677: "miniupnpc module.", /* m_doc */
! 678: -1, /* m_size */
! 679: miniupnpc_methods, /* m_methods */
! 680: NULL, /* m_reload */
! 681: NULL, /* m_traverse */
! 682: NULL, /* m_clear */
! 683: NULL, /* m_free */
! 684: };
! 685: #endif
! 686:
! 687: #ifndef PyMODINIT_FUNC /* declarations for DLL import/export */
! 688: #define PyMODINIT_FUNC void
! 689: #endif
! 690:
! 691: PyMODINIT_FUNC
! 692: #if PY_MAJOR_VERSION >= 3
! 693: PyInit_miniupnpc(void)
! 694: #else
! 695: initminiupnpc(void)
! 696: #endif
! 697: {
! 698: PyObject* m;
! 699:
! 700: #ifdef _WIN32
! 701: /* initialize Winsock. */
! 702: WSADATA wsaData;
! 703: int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
! 704: if (nResult != 0)
! 705: {
! 706: /* error code could be WSASYSNOTREADY WSASYSNOTREADY
! 707: * WSASYSNOTREADY WSASYSNOTREADY WSASYSNOTREADY */
! 708: #if PY_MAJOR_VERSION >= 3
! 709: return 0;
! 710: #else
! 711: return;
! 712: #endif
! 713: }
! 714:
! 715: UPnPType.tp_new = PyType_GenericNew;
! 716: #endif
! 717: if (PyType_Ready(&UPnPType) < 0)
! 718: #if PY_MAJOR_VERSION >= 3
! 719: return 0;
! 720: #else
! 721: return;
! 722: #endif
! 723:
! 724: #if PY_MAJOR_VERSION >= 3
! 725: m = PyModule_Create(&moduledef);
! 726: #else
! 727: m = Py_InitModule3("miniupnpc", miniupnpc_methods,
! 728: "miniupnpc module.");
! 729: #endif
! 730:
! 731: Py_INCREF(&UPnPType);
! 732: PyModule_AddObject(m, "UPnP", (PyObject *)&UPnPType);
! 733:
! 734: #if PY_MAJOR_VERSION >= 3
! 735: return m;
! 736: #endif
! 737: }
! 738:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>