Changeset 12593


Ignore:
Timestamp:
Jul 26, 2011, 1:36:30 AM (10 years ago)
Author:
livings124
Message:

#4387 Update miniupnpc to 1.6

Location:
trunk
Files:
5 added
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/Transmission.xcodeproj/project.pbxproj

    r12579 r12593  
    6969                A20152640D1C1BE70081714F /* PinTemplate.png in Resources */ = {isa = PBXBuildFile; fileRef = A20152630D1C1BE70081714F /* PinTemplate.png */; };
    7070                A201527E0D1C270F0081714F /* torrent-ctor.c in Sources */ = {isa = PBXBuildFile; fileRef = A20152790D1C26EB0081714F /* torrent-ctor.c */; };
     71                A20162C913DE48BF00E15488 /* receivedata.c in Sources */ = {isa = PBXBuildFile; fileRef = A20162C713DE48BF00E15488 /* receivedata.c */; };
     72                A20162CA13DE48BF00E15488 /* receivedata.h in Headers */ = {isa = PBXBuildFile; fileRef = A20162C813DE48BF00E15488 /* receivedata.h */; };
     73                A20162CD13DE497000E15488 /* portlistingparse.c in Sources */ = {isa = PBXBuildFile; fileRef = A20162CB13DE497000E15488 /* portlistingparse.c */; };
     74                A20162CE13DE497000E15488 /* portlistingparse.h in Headers */ = {isa = PBXBuildFile; fileRef = A20162CC13DE497000E15488 /* portlistingparse.h */; };
     75                A20162D013DE49E500E15488 /* miniupnpctypes.h in Headers */ = {isa = PBXBuildFile; fileRef = A20162CF13DE49E500E15488 /* miniupnpctypes.h */; };
    7176                A2074F4C12BEA8CE00F70985 /* buffer.c in Sources */ = {isa = PBXBuildFile; fileRef = A2074F4B12BEA8CE00F70985 /* buffer.c */; };
    7277                A2074F5912BEA8E000F70985 /* bufferevent_filter.c in Sources */ = {isa = PBXBuildFile; fileRef = A2074F5012BEA8E000F70985 /* bufferevent_filter.c */; };
     
    526531                A20152630D1C1BE70081714F /* PinTemplate.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = PinTemplate.png; path = macosx/Images/PinTemplate.png; sourceTree = "<group>"; };
    527532                A20152790D1C26EB0081714F /* torrent-ctor.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = "torrent-ctor.c"; path = "libtransmission/torrent-ctor.c"; sourceTree = "<group>"; };
     533                A20162C713DE48BF00E15488 /* receivedata.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = receivedata.c; path = "third-party/miniupnp/receivedata.c"; sourceTree = "<group>"; };
     534                A20162C813DE48BF00E15488 /* receivedata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = receivedata.h; path = "third-party/miniupnp/receivedata.h"; sourceTree = "<group>"; };
     535                A20162CB13DE497000E15488 /* portlistingparse.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = portlistingparse.c; path = "third-party/miniupnp/portlistingparse.c"; sourceTree = "<group>"; };
     536                A20162CC13DE497000E15488 /* portlistingparse.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = portlistingparse.h; path = "third-party/miniupnp/portlistingparse.h"; sourceTree = "<group>"; };
     537                A20162CF13DE49E500E15488 /* miniupnpctypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = miniupnpctypes.h; path = "third-party/miniupnp/miniupnpctypes.h"; sourceTree = "<group>"; };
    528538                A202FF5B0DDA9275009938FF /* it */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = it; path = macosx/it.lproj/AddWindow.xib; sourceTree = "<group>"; };
    529539                A202FF5C0DDA9275009938FF /* it */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = it; path = macosx/it.lproj/Creator.xib; sourceTree = "<group>"; };
     
    15351545                                BE1183670CE160D50002D0F3 /* upnpcommands.c */,
    15361546                                BE1183680CE160D50002D0F3 /* miniupnpc.c */,
     1547                                A20162CB13DE497000E15488 /* portlistingparse.c */,
     1548                                A20162C713DE48BF00E15488 /* receivedata.c */,
    15371549                                BE11834D0CE160C50002D0F3 /* bsdqueue.h */,
    15381550                                A22B00AF116A9E90003315FC /* connecthostport.h */,
     
    15431555                                BE1183520CE160C50002D0F3 /* minisoap.h */,
    15441556                                A2F8CD420F3D0F4A00DB356A /* miniupnpcstrings.h */,
     1557                                A20162CF13DE49E500E15488 /* miniupnpctypes.h */,
    15451558                                BE1183530CE160C50002D0F3 /* upnpreplyparse.h */,
    15461559                                BE1183540CE160C50002D0F3 /* upnpcommands.h */,
     
    15481561                                BE1183560CE160C50002D0F3 /* minissdpc.h */,
    15491562                                A25485390EB66CBB004539DA /* codelength.h */,
     1563                                A20162CC13DE497000E15488 /* portlistingparse.h */,
     1564                                A20162C813DE48BF00E15488 /* receivedata.h */,
    15501565                        );
    15511566                        name = libminiupnp;
     
    17741789                                A2F8CD430F3D0F4A00DB356A /* miniupnpcstrings.h in Headers */,
    17751790                                A22B00B2116A9E9F003315FC /* connecthostport.h in Headers */,
     1791                                A20162CA13DE48BF00E15488 /* receivedata.h in Headers */,
     1792                                A20162CE13DE497000E15488 /* portlistingparse.h in Headers */,
     1793                                A20162D013DE49E500E15488 /* miniupnpctypes.h in Headers */,
    17761794                        );
    17771795                        runOnlyForDeploymentPostprocessing = 0;
     
    23552373                                BE1183700CE160D50002D0F3 /* miniupnpc.c in Sources */,
    23562374                                A22B00B3116A9EA4003315FC /* connecthostport.c in Sources */,
     2375                                A20162C913DE48BF00E15488 /* receivedata.c in Sources */,
     2376                                A20162CD13DE497000E15488 /* portlistingparse.c in Sources */,
    23572377                        );
    23582378                        runOnlyForDeploymentPostprocessing = 0;
  • trunk/libtransmission/upnp.c

    r12204 r12593  
    9898        struct UPNPDev * devlist;
    9999        errno = 0;
    100         devlist = upnpDiscover( 2000, NULL, NULL, 0 );
     100        devlist = upnpDiscover( 2000, NULL, NULL, 0, 0, &errno );
    101101        if( devlist == NULL )
    102102        {
     
    145145        tr_snprintf( portStr, sizeof( portStr ), "%d", handle->port );
    146146        if( UPNP_GetSpecificPortMappingEntry( handle->urls.controlURL, handle->data.first.servicetype,
    147             portStr, "TCP", intClient, intPort ) != UPNPCOMMAND_SUCCESS  ||
     147            portStr, "TCP", intClient, intPort, NULL, NULL, NULL ) != UPNPCOMMAND_SUCCESS  ||
    148148            UPNP_GetSpecificPortMappingEntry( handle->urls.controlURL, handle->data.first.servicetype,
    149             portStr, "UDP", intClient, intPort ) != UPNPCOMMAND_SUCCESS )
     149            portStr, "UDP", intClient, intPort, NULL, NULL, NULL ) != UPNPCOMMAND_SUCCESS )
    150150        {
    151151            tr_ninf( getKey( ), _( "Port %d isn't forwarded" ), handle->port );
     
    199199                                       handle->data.first.servicetype,
    200200                                       portStr, portStr, handle->lanaddr,
    201                                        desc, "TCP", NULL );
     201                                       desc, "TCP", NULL, NULL );
    202202            if( err_tcp )
    203203                tr_ndbg( getKey( ), "TCP Port forwarding failed with error %d (errno %d - %s)",
     
    208208                                       handle->data.first.servicetype,
    209209                                       portStr, portStr, handle->lanaddr,
    210                                        desc, "UDP", NULL );
     210                                       desc, "UDP", NULL, NULL );
    211211            if( err_udp )
    212212                tr_ndbg( getKey( ), "UDP Port forwarding failed with error %d (errno %d - %s)",
  • trunk/third-party/miniupnp/Changelog.txt

    r11577 r12593  
    1 $Id: Changelog.txt,v 1.125 2010/12/21 16:13:13 nanard Exp $
     1$Id: Changelog.txt,v 1.152 2011/07/25 18:02:11 nanard Exp $
    22miniUPnP client Changelog.
     3
     4VERSION 1.6 : released 2011/07/25
     5
     62011/07/25:
     7  Update doc for version 1.6 release
     8
     92011/06/18:
     10  Fix for windows in miniwget.c
     11
     122011/06/04:
     13  display remote host in port mapping listing
     14
     152011/06/03:
     16  Fix in make install : there were missing headers
     17
     182011/05/26:
     19  Fix the socket leak in miniwget thanks to Richard Marsh.
     20  Permit to add leaseduration in -a command. Display lease duration.
     21
     222011/05/15:
     23  Try both LinkLocal and SiteLocal multicast address for SSDP in IPv6
     24
     252011/05/09:
     26  add a test in testminiwget.sh.
     27  more error checking in miniwget.c
     28
     292011/05/06:
     30  Adding some tool to test and validate miniwget.c
     31  simplified and debugged miniwget.c
     32
     332011/04/11:
     34  moving ReceiveData() to a receivedata.c file.
     35  parsing presentation url
     36  adding IGD v2 WANIPv6FirewallControl commands
     37
     382011/04/10:
     39  update of miniupnpcmodule.c
     40  comments in miniwget.c, update in testminiwget
     41  Adding errors codes from IGD v2
     42  new functions in upnpc.c for IGD v2
     43
     442011/04/09:
     45  Support for litteral ip v6 address in miniwget
     46
     472011/04/08:
     48  Adding support for urn:schemas-upnp-org:service:WANIPv6FirewallControl:1
     49  Updating APIVERSION
     50  Supporting IPV6 in upnpDiscover()
     51  Adding a -6 option to upnpc command line tool
     52
     532011/03/18:
     54  miniwget/parseURL() : return an error when url param is null.
     55  fixing GetListOfPortMappings()
     56
     572011/03/14:
     58  upnpDiscover() now reporting an error code.
     59  improvements in comments.
     60
     612011/03/11:
     62  adding miniupnpcstrings.h.cmake and CMakeLists.txt files.
     63
     642011/02/15:
     65  Implementation of GetListOfPortMappings()
     66
     672011/02/07:
     68  updates to minixml to support character data starting with spaces
     69  minixml now support CDATA
     70  upnpreplyparse treats <NewPortListing> specificaly
     71  change in simpleUPnPcommand to return the buffer (simplification)
     72
     732011/02/06:
     74  Added leaseDuration argument to AddPortMapping()
     75  Starting to implement GetListOfPortMappings()
     76
     772011/01/11:
     78  updating wingenminiupnpcstrings.c
     79
     802011/01/04:
     81  improving updateminiupnpcstrings.sh
     82
     83VERSION 1.5 : released 2011/01/01
    384
    4852010/12/21:
  • trunk/third-party/miniupnp/LICENSE

    r10285 r12593  
    1 Copyright (c) 2005-2009, Thomas BERNARD
     1MiniUPnPc
     2Copyright (c) 2005-2011, Thomas BERNARD
    23All rights reserved.
    34
  • trunk/third-party/miniupnp/Makefile.am

    r10447 r12593  
    1111    miniwget.c \
    1212    minixml.c \
     13    portlistingparse.c \
     14    receivedata.c \
    1315    upnpcommands.c \
    1416    upnpreplyparse.c
     
    2325    minissdpc.h \
    2426    miniupnpc.h \
     27    miniupnpctypes.h \
    2528    miniwget.h \
    2629    minixml.h \
     30    portlistingparse.h \
     31    receivedata.h \
    2732    upnpcommands.h \
    2833    upnpreplyparse.h
  • trunk/third-party/miniupnp/README

    r10285 r12593  
    22Project web page: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
    33Author: Thomas Bernard
    4 Copyright (c) 2005-2009 Thomas Bernard
     4Copyright (c) 2005-2011 Thomas Bernard
    55This software is subject to the conditions detailed in the
    66LICENSE file provided within this distribution.
     
    1717OpenBSD, MacOS X, AmigaOS and cygwin.
    1818The official AmigaOS4.1 SDK was used for AmigaOS4 and GeekGadgets for AmigaOS3.
     19upx (http://upx.sourceforge.net) is used to compress the win32 .exe files.
    1920
    2021To install the library and headers on the system use :
     
    5455send me an email !
    5556
     57For any question, you can use the web forum :
     58http://miniupnp.tuxfamily.org/forum/
    5659
  • trunk/third-party/miniupnp/VERSION

    r10285 r12593  
    1 1.4
     11.6
  • trunk/third-party/miniupnp/connecthostport.c

    r11577 r12593  
    1 /* $Id: connecthostport.c,v 1.3 2010/12/21 16:13:14 nanard Exp $ */
     1/* $Id: connecthostport.c,v 1.5 2011/04/09 08:49:50 nanard Exp $ */
    22/* Project : miniupnp
    33 * Author : Thomas Bernard
    4  * Copyright (c) 2010 Thomas Bernard
     4 * Copyright (c) 2010-2011 Thomas Bernard
    55 * This software is subject to the conditions detailed in the
    66 * LICENCE file provided in this distribution. */
     
    1818#include <ws2tcpip.h>
    1919#include <io.h>
     20#define MAXHOSTNAMELEN 64
    2021#define snprintf _snprintf
    2122#define herror
     
    2324#else /* #ifdef WIN32 */
    2425#include <unistd.h>
     26#include <sys/param.h>
    2527#include <errno.h>
    2628#define closesocket close
     
    5860        struct hostent *hp;
    5961#else /* #ifdef USE_GETHOSTBYNAME */
     62        char tmp_host[MAXHOSTNAMELEN+1];
    6063        char port_str[8];
    6164        struct addrinfo *ai, *p;
     
    140143        /* hints.ai_protocol = IPPROTO_TCP; */
    141144        snprintf(port_str, sizeof(port_str), "%hu", port);
    142         n = getaddrinfo(host, port_str, &hints, &ai);
     145        if(host[0] == '[')
     146        {
     147                /* literal ip v6 address */
     148                int i;
     149                for(i = 0; host[i+1] && (host[i+1] != ']') && i < MAXHOSTNAMELEN; i++)
     150                {
     151                        tmp_host[i] = host[i+1];
     152                }
     153                tmp_host[i] = '\0';
     154        }
     155        else
     156        {
     157                strncpy(tmp_host, host, MAXHOSTNAMELEN);
     158        }
     159        tmp_host[MAXHOSTNAMELEN] = '\0';
     160        n = getaddrinfo(tmp_host, port_str, &hints, &ai);
    143161        if(n != 0)
    144162        {
  • trunk/third-party/miniupnp/igd_desc_parse.c

    r11577 r12593  
    1 /* $Id: igd_desc_parse.c,v 1.11 2010/12/11 17:56:51 nanard Exp $ */
     1/* $Id: igd_desc_parse.c,v 1.14 2011/04/11 09:19:24 nanard Exp $ */
    22/* Project : miniupnp
    33 * http://miniupnp.free.fr/
     
    4848                        memcpy(&datas->CIF, &datas->tmp, sizeof(struct IGDdatas_service));
    4949                } else if(0==strcmp(datas->tmp.servicetype,
     50                                "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1")) {
     51                        memcpy(&datas->IPv6FC, &datas->tmp, sizeof(struct IGDdatas_service));
     52                } else if(0==strcmp(datas->tmp.servicetype,
    5053                                "urn:schemas-upnp-org:service:WANIPConnection:1")
    5154                                 || 0==strcmp(datas->tmp.servicetype,
     
    7073        if( !strcmp(datas->cureltname, "URLBase") )
    7174                dstmember = datas->urlbase;
     75        else if( !strcmp(datas->cureltname, "presentationURL") )
     76                dstmember = datas->presentationurl;
    7277        else if( !strcmp(datas->cureltname, "serviceType") )
    7378                dstmember = datas->tmp.servicetype;
     
    110115        printf(" eventSubURL = '%s'\n", d->second.eventsuburl);
    111116        printf(" SCPDURL = '%s'\n", d->second.scpdurl);
     117        printf("WAN IPv6 Firewall Control :\n");
     118        /*printf(" deviceType = '%s'\n", d->IPv6FC.devicetype);*/
     119        printf(" servicetype = '%s'\n", d->IPv6FC.servicetype);
     120        printf(" controlURL = '%s'\n", d->IPv6FC.controlurl);
     121        printf(" eventSubURL = '%s'\n", d->IPv6FC.eventsuburl);
     122        printf(" SCPDURL = '%s'\n", d->IPv6FC.scpdurl);
    112123}
    113124
  • trunk/third-party/miniupnp/igd_desc_parse.h

    r10460 r12593  
    1 /* $Id: igd_desc_parse.h,v 1.7 2010/04/05 20:36:59 nanard Exp $ */
     1/* $Id: igd_desc_parse.h,v 1.10 2011/04/11 09:19:24 nanard Exp $ */
    22/* Project : miniupnp
    33 * http://miniupnp.free.fr/
     
    2424        char cureltname[MINIUPNPC_URL_MAXSIZE];
    2525        char urlbase[MINIUPNPC_URL_MAXSIZE];
     26        char presentationurl[MINIUPNPC_URL_MAXSIZE];
    2627        int level;
    2728        /*int state;*/
     
    3334        /* if both WANIPConnection and WANPPPConnection are present */
    3435        struct IGDdatas_service second;
     36        /* "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1" */
     37        struct IGDdatas_service IPv6FC;
    3538        /* tmp */
    3639        struct IGDdatas_service tmp;
  • trunk/third-party/miniupnp/minisoap.c

    r11577 r12593  
    1 /* $Id: minisoap.c,v 1.20 2010/12/11 17:56:51 nanard Exp $ */
     1/* $Id: minisoap.c,v 1.21 2011/03/22 19:15:35 nanard Exp $ */
    22/* Project : miniupnp
    33 * Author : Thomas Bernard
     
    113113                url, httpversion, host, portstr);
    114114        printf("SOAPAction: \"%s\" - Content-Length: %d\n", action, bodysize);
    115         /*printf("%s", headerbuf);*/
     115        printf("Headers :\n%s", headerbuf);
     116        printf("Body :\n%s\n", body);
    116117#endif
    117118        return httpWrite(fd, body, bodysize, headerbuf, headerssize);
  • trunk/third-party/miniupnp/miniupnpc.c

    r11577 r12593  
    1 /* $Id: miniupnpc.c,v 1.85 2010/12/21 16:13:14 nanard Exp $ */
     1/* $Id: miniupnpc.c,v 1.95 2011/05/15 21:42:26 nanard Exp $ */
    22/* Project : miniupnp
    33 * Author : Thomas BERNARD
    4  * copyright (c) 2005-2010 Thomas Bernard
     4 * copyright (c) 2005-2011 Thomas Bernard
    55 * This software is subjet to the conditions detailed in the
    66 * provided LICENSE file. */
     
    2727#include <iphlpapi.h>
    2828#define snprintf _snprintf
     29#ifndef strncasecmp
    2930#if defined(_MSC_VER) && (_MSC_VER >= 1400)
    3031#define strncasecmp _memicmp
     
    3233#define strncasecmp memicmp
    3334#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
     35#endif /* #ifndef strncasecmp */
    3436#define MAXHOSTNAMELEN 64
    3537#else /* #ifdef WIN32 */
     
    4850#include <arpa/inet.h>
    4951#include <netdb.h>
     52#include <net/if.h>
    5053#if !defined(__amigaos__) && !defined(__amigaos4__)
    5154#include <poll.h>
     
    5457#include <errno.h>
    5558#define closesocket close
    56 #define MINIUPNPC_IGNORE_EINTR
    5759#endif /* #else WIN32 */
    5860#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
     
    7173#include "upnpcommands.h"
    7274#include "connecthostport.h"
     75#include "receivedata.h"
    7376
    7477#ifdef WIN32
     
    100103}
    101104
    102 #if 0
    103 /* getcontentlenfromline() : parse the Content-Length HTTP header line.
    104  * Content-length: nnn */
    105 static int getcontentlenfromline(const char * p, int n)
    106 {
    107         static const char contlenstr[] = "content-length";
    108         const char * p2 = contlenstr;
    109         int a = 0;
    110         while(*p2)
    111         {
    112                 if(n==0)
    113                         return -1;
    114                 if(*p2 != *p && *p2 != (*p + 32))
    115                         return -1;
    116                 p++; p2++; n--;
    117         }
    118         if(n==0)
    119                 return -1;
    120         if(*p != ':')
    121                 return -1;
    122         p++; n--;
    123         while(*p == ' ')
    124         {
    125                 if(n==0)
    126                         return -1;
    127                 p++; n--;
    128         }
    129         while(*p >= '0' && *p <= '9')
    130         {
    131                 if(n==0)
    132                         return -1;
    133                 a = (a * 10) + (*p - '0');
    134                 p++; n--;
    135         }
    136         return a;
    137 }
    138 
    139 /* getContentLengthAndHeaderLength()
    140  * retrieve header length and content length from an HTTP response
    141  * TODO : retrieve Transfer-Encoding: header value, in order to support
    142  *        HTTP/1.1, chunked transfer encoding must be supported. */
    143 static void
    144 getContentLengthAndHeaderLength(char * p, int n,
    145                                 int * contentlen, int * headerlen)
    146 {
    147         char * line;
    148         int linelen;
    149         int r;
    150         line = p;
    151         while(line < p + n)
    152         {
    153                 linelen = 0;
    154                 while(line[linelen] != '\r' && line[linelen] != '\r')
    155                 {
    156                         if(line+linelen >= p+n)
    157                                 return;
    158                         linelen++;
    159                 }
    160                 r = getcontentlenfromline(line, linelen);
    161                 if(r>0)
    162                         *contentlen = r;
    163                 line = line + linelen + 2;
    164                 if(line[0] == '\r' && line[1] == '\n')
    165                 {
    166                         *headerlen = (line - p) + 2;
    167                         return;
    168                 }
    169         }
    170 }
    171 #endif
    172 
    173105/* simpleUPnPcommand2 :
    174106 * not so simple !
    175107 * return values :
    176  *   0 - OK
    177  *  -1 - error */
    178 static int simpleUPnPcommand2(int s, const char * url, const char * service,
     108 *   pointer - OK
     109 *   NULL - error */
     110char * simpleUPnPcommand2(int s, const char * url, const char * service,
    179111                       const char * action, struct UPNParg * args,
    180                        char * buffer, int * bufsize, const char * httpversion)
     112                       int * bufsize, const char * httpversion)
    181113{
    182114        char hostname[MAXHOSTNAMELEN+1];
     
    186118        char soapbody[2048];
    187119        char * buf;
    188         /*int buffree;*/
    189120    int n;
    190         /*int contentlen, headerlen;*/  /* for the response */
    191 
     121
     122        *bufsize = 0;
    192123        snprintf(soapact, sizeof(soapact), "%s#%s", service, action);
    193124        if(args==NULL)
     
    224155                        {
    225156                                /* we keep a margin of at least 100 bytes */
    226                                 *bufsize = 0;
    227                                 return -1;
     157                                return NULL;
    228158                        }
    229159                        *(p++) = '<';
     
    255185                        soapbody + sizeof(soapbody) - p);
    256186        }
    257         if(!parseURL(url, hostname, &port, &path)) return -1;
     187        if(!parseURL(url, hostname, &port, &path)) return NULL;
    258188        if(s<0)
    259189        {
     
    261191                if(s < 0)
    262192                {
    263                         *bufsize = 0;
    264                         return -1;
     193                        return NULL;
    265194                }
    266195        }
     
    272201#endif
    273202                closesocket(s);
    274                 return -1;
    275         }
    276 
    277 #if 0
    278         contentlen = -1;
    279         headerlen = -1;
    280         buf = buffer;
    281         buffree = *bufsize;
    282         *bufsize = 0;
    283         while ((n = ReceiveData(s, buf, buffree, 5000)) > 0) {
    284                 buffree -= n;
    285                 buf += n;
    286                 *bufsize += n;
    287                 getContentLengthAndHeaderLength(buffer, *bufsize,
    288                                                 &contentlen, &headerlen);
    289 #ifdef DEBUG
    290                 printf("received n=%dbytes bufsize=%d ContLen=%d HeadLen=%d\n",
    291                        n, *bufsize, contentlen, headerlen);
    292 #endif
    293                 /* break if we received everything */
    294                 if(contentlen > 0 && headerlen > 0 && *bufsize >= contentlen+headerlen)
    295                         break;
    296         }
    297 #endif
    298         buf = getHTTPResponse(s, &n);
    299         if(n > 0 && buf)
    300         {
    301 #ifdef DEBUG
    302                 printf("SOAP Response :\n%.*s\n", n, buf);
    303 #endif
    304                 if(*bufsize > n)
    305                 {
    306                         memcpy(buffer, buf, n);
    307                         *bufsize = n;
    308                 }
    309                 else
    310                 {
    311                         memcpy(buffer, buf, *bufsize);
    312                 }
    313                 free(buf);
    314                 buf = 0;
    315         }
     203                return NULL;
     204        }
     205
     206        buf = getHTTPResponse(s, bufsize);
     207#ifdef DEBUG
     208        if(*bufsize > 0 && buf)
     209        {
     210                printf("SOAP Response :\n%.*s\n", *bufsize, buf);
     211        }
     212#endif
    316213        closesocket(s);
    317         return 0;
     214        return buf;
    318215}
    319216
     
    321218 * not so simple !
    322219 * return values :
    323  *   0 - OK
    324  *  -1 - error */
    325 int simpleUPnPcommand(int s, const char * url, const char * service,
     220 *   pointer - OK
     221 *   NULL    - error */
     222char * simpleUPnPcommand(int s, const char * url, const char * service,
    326223                       const char * action, struct UPNParg * args,
    327                        char * buffer, int * bufsize)
    328 {
    329         int result;
    330         /*int origbufsize = *bufsize;*/
    331 
    332         result = simpleUPnPcommand2(s, url, service, action, args, buffer, bufsize, "1.1");
     224                       int * bufsize)
     225{
     226        char * buf;
     227
     228        buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1");
    333229/*
    334         result = simpleUPnPcommand2(s, url, service, action, args, buffer, bufsize, "1.0");
    335         if (result < 0 || *bufsize == 0)
     230        buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.0");
     231        if (!buf || *bufsize == 0)
    336232        {
    337233#if DEBUG
    338234            printf("Error or no result from SOAP request; retrying with HTTP/1.1\n");
    339235#endif
    340                 *bufsize = origbufsize;
    341                 result = simpleUPnPcommand2(s, url, service, action, args, buffer, bufsize, "1.1");
     236                buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1");
    342237        }
    343238*/
    344         return result;
     239        return buf;
    345240}
    346241
     
    358253        i = 0;
    359254        a = i;  /* start of the line */
    360         b = 0;
     255        b = 0;  /* end of the "header" (position of the colon) */
    361256        while(i<size)
    362257        {
     
    383278                                        }
    384279                                        putchar('\n');*/
     280                                        /* skip the colon and white spaces */
    385281                                        do { b++; } while(reply[b]==' ');
    386282                                        if(0==strncasecmp(reply+a, "location", 8))
     
    410306#define STR(s) #s
    411307#define UPNP_MCAST_ADDR "239.255.255.250"
     308/* for IPv6 */
     309#define UPNP_MCAST_LL_ADDR "FF02::C" /* link-local */
     310#define UPNP_MCAST_SL_ADDR "FF05::C" /* site-local */
    412311
    413312/* upnpDiscover() :
     
    416315 * It is up to the caller to free the chained list
    417316 * delay is in millisecond (poll) */
    418 LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
    419                               const char * minissdpdsock, int sameport)
     317LIBSPEC struct UPNPDev *
     318upnpDiscover(int delay, const char * multicastif,
     319             const char * minissdpdsock, int sameport,
     320             int ipv6,
     321             int * error)
    420322{
    421323        struct UPNPDev * tmp;
     
    424326        static const char MSearchMsgFmt[] =
    425327        "M-SEARCH * HTTP/1.1\r\n"
    426         "HOST: " UPNP_MCAST_ADDR ":" XSTR(PORT) "\r\n"
     328        "HOST: %s:" XSTR(PORT) "\r\n"
    427329        "ST: %s\r\n"
    428330        "MAN: \"ssdp:discover\"\r\n"
     
    430332        "\r\n";
    431333        static const char * const deviceList[] = {
     334#if 0
     335                "urn:schemas-upnp-org:device:InternetGatewayDevice:2",
     336                "urn:schemas-upnp-org:service:WANIPConnection:2",
     337#endif
    432338                "urn:schemas-upnp-org:device:InternetGatewayDevice:1",
    433339                "urn:schemas-upnp-org:service:WANIPConnection:1",
     
    440346        int sudp;
    441347        int n;
    442         struct sockaddr sockudp_r;
     348        struct sockaddr_storage sockudp_r;
    443349        unsigned int mx;
    444350#ifdef NO_GETADDRINFO
    445         struct sockaddr_in sockudp_w;
     351        struct sockaddr_storage sockudp_w;
    446352#else
    447353        int rv;
     
    451357        MIB_IPFORWARDROW ip_forward;
    452358#endif
    453 
     359        int linklocal = 1;
     360
     361        if(error)
     362                *error = UPNPDISCOVER_UNKNOWN_ERROR;
    454363#if !defined(WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
    455364        /* first try to get infos from minissdpd ! */
     
    460369                                                  minissdpdsock);
    461370                /* We return what we have found if it was not only a rootdevice */
    462                 if(devlist && !strstr(deviceList[deviceIndex], "rootdevice"))
     371                if(devlist && !strstr(deviceList[deviceIndex], "rootdevice")) {
     372                        if(error)
     373                                *error = UPNPDISCOVER_SUCCESS;
    463374                        return devlist;
     375                }
    464376                deviceIndex++;
    465377        }
     
    468380        /* fallback to direct discovery */
    469381#ifdef WIN32
    470         sudp = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
     382        sudp = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, IPPROTO_UDP);
    471383#else
    472         sudp = socket(PF_INET, SOCK_DGRAM, 0);
     384        sudp = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, 0);
    473385#endif
    474386        if(sudp < 0)
    475387        {
     388                if(error)
     389                        *error = UPNPDISCOVER_SOCKET_ERROR;
    476390                PRINT_SOCKET_ERROR("socket");
    477391                return NULL;
    478392        }
    479393        /* reception */
    480         memset(&sockudp_r, 0, sizeof(struct sockaddr));
    481         if(0/*ipv6*/) {
     394        memset(&sockudp_r, 0, sizeof(struct sockaddr_storage));
     395        if(ipv6) {
    482396                struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_r;
    483397                p->sin6_family = AF_INET6;
    484398                if(sameport)
    485399                        p->sin6_port = htons(PORT);
    486                 p->sin6_addr = in6addr_any;//IN6ADDR_ANY_INIT;/*INADDR_ANY;*/
     400                p->sin6_addr = in6addr_any; /* in6addr_any is not available with MinGW32 3.4.2 */
    487401        } else {
    488402                struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_r;
     
    497411/* Get IP associated with the index given in the ip_forward struct
    498412 * in order to give this ip to setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF) */
    499         if(GetBestRoute(inet_addr("223.255.255.255"), 0, &ip_forward) == NO_ERROR) {
     413        if(!ipv6
     414           && (GetBestRoute(inet_addr("223.255.255.255"), 0, &ip_forward) == NO_ERROR)) {
    500415                DWORD dwRetVal = 0;
    501416                PMIB_IPADDRTABLE pIPAddrTable;
     
    557472#endif
    558473        {
     474                if(error)
     475                        *error = UPNPDISCOVER_SOCKET_ERROR;
    559476                PRINT_SOCKET_ERROR("setsockopt");
    560477                return NULL;
     
    563480        if(multicastif)
    564481        {
    565                 struct in_addr mc_if;
    566                 mc_if.s_addr = inet_addr(multicastif);
    567                 if(0/*ipv6*/) {
     482                if(ipv6) {
     483#if !defined(WIN32)
     484                        /* according to MSDN, if_nametoindex() is supported since
     485                         * MS Windows Vista and MS Windows Server 2008.
     486                         * http://msdn.microsoft.com/en-us/library/bb408409%28v=vs.85%29.aspx */
     487                        unsigned int ifindex = if_nametoindex(multicastif); /* eth0, etc. */
     488                        if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(&ifindex)) < 0)
     489                        {
     490                                PRINT_SOCKET_ERROR("setsockopt");
     491                        }
     492#else
     493#ifdef DEBUG
     494                        printf("Setting of multicast interface not supported in IPv6 under Windows.\n");
     495#endif
     496#endif
    568497                } else {
     498                        struct in_addr mc_if;
     499                        mc_if.s_addr = inet_addr(multicastif); /* ex: 192.168.x.x */
    569500                        ((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = mc_if.s_addr;
    570                 }
    571                 if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0)
    572                 {
    573                         PRINT_SOCKET_ERROR("setsockopt");
     501                        if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0)
     502                        {
     503                                PRINT_SOCKET_ERROR("setsockopt");
     504                        }
    574505                }
    575506        }
    576507
    577508        /* Avant d'envoyer le paquet on bind pour recevoir la reponse */
    578     if (bind(sudp, &sockudp_r, 0/*ipv6*/?sizeof(struct sockaddr_in6):sizeof(struct sockaddr_in)) != 0)
    579         {
     509    if (bind(sudp, (const struct sockaddr *)&sockudp_r,
     510                 ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) != 0)
     511        {
     512                if(error)
     513                        *error = UPNPDISCOVER_SOCKET_ERROR;
    580514        PRINT_SOCKET_ERROR("bind");
    581515                closesocket(sudp);
     
    583517    }
    584518
     519        if(error)
     520                *error = UPNPDISCOVER_SUCCESS;
    585521        /* Calculating maximum response time in seconds */
    586522        mx = ((unsigned int)delay) / 1000u;
    587523        /* receiving SSDP response packet */
    588         for(n = 0;;)
     524        for(n = 0; deviceList[deviceIndex]; deviceIndex++)
    589525        {
    590526        if(n == 0)
     
    592528                /* sending the SSDP M-SEARCH packet */
    593529                n = snprintf(bufr, sizeof(bufr),
    594                              MSearchMsgFmt, deviceList[deviceIndex++], mx);
    595                 /*printf("Sending %s", bufr);*/
     530                             MSearchMsgFmt,
     531                             ipv6 ?
     532                             (linklocal ? "[" UPNP_MCAST_LL_ADDR "]" :  "[" UPNP_MCAST_SL_ADDR "]")
     533                             : UPNP_MCAST_ADDR,
     534                             deviceList[deviceIndex], mx);
     535#ifdef DEBUG
     536                printf("Sending %s", bufr);
     537#endif
    596538#ifdef NO_GETADDRINFO
    597539                /* the following code is not using getaddrinfo */
    598540                /* emission */
    599                 memset(&sockudp_w, 0, sizeof(struct sockaddr_in));
    600                 sockudp_w.sin_family = AF_INET;
    601                 sockudp_w.sin_port = htons(PORT);
    602                 sockudp_w.sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR);
     541                memset(&sockudp_w, 0, sizeof(struct sockaddr_storage));
     542                if(ipv6) {
     543                        struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_w;
     544                        p->sin6_family = AF_INET6;
     545                        p->sin6_port = htons(PORT);
     546                        inet_pton(AF_INET6,
     547                                  linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR,
     548                                  &(p->sin6_addr));
     549                } else {
     550                        struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_w;
     551                        p->sin_family = AF_INET;
     552                        p->sin_port = htons(PORT);
     553                        p->sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR);
     554                }
    603555                n = sendto(sudp, bufr, n, 0,
    604                            (struct sockaddr *)&sockudp_w, sizeof(struct sockaddr_in));
     556                           &sockudp_w,
     557                           ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in));
    605558                if (n < 0) {
     559                        if(error)
     560                                *error = UPNPDISCOVER_SOCKET_ERROR;
    606561                        PRINT_SOCKET_ERROR("sendto");
    607                         closesocket(sudp);
    608                         return devlist;
     562                        break;
    609563                }
    610564#else /* #ifdef NO_GETADDRINFO */
     
    613567                hints.ai_socktype = SOCK_DGRAM;
    614568                /*hints.ai_flags = */
    615                 if ((rv = getaddrinfo(UPNP_MCAST_ADDR, XSTR(PORT), &hints, &servinfo)) != 0) {
     569                if ((rv = getaddrinfo(ipv6
     570                                      ? (linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR)
     571                                      : UPNP_MCAST_ADDR,
     572                                      XSTR(PORT), &hints, &servinfo)) != 0) {
     573                        if(error)
     574                                *error = UPNPDISCOVER_SOCKET_ERROR;
    616575#ifdef WIN32
    617576                    fprintf(stderr, "getaddrinfo() failed: %d\n", rv);
     
    619578                    fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
    620579#endif
    621                     return devlist;
     580                        break;
    622581                }
    623582                for(p = servinfo; p; p = p->ai_next) {
     
    630589                freeaddrinfo(servinfo);
    631590                if(n < 0) {
    632                         closesocket(sudp);
    633                         return devlist;
     591                        if(error)
     592                                *error = UPNPDISCOVER_SOCKET_ERROR;
     593                        break;
    634594                }
    635595#endif /* #ifdef NO_GETADDRINFO */
    636596        }
    637597        /* Waiting for SSDP REPLY packet to M-SEARCH */
    638         n = ReceiveData(sudp, bufr, sizeof(bufr), delay);
     598        n = receivedata(sudp, bufr, sizeof(bufr), delay);
    639599        if (n < 0) {
    640600                /* error */
    641                 closesocket(sudp);
    642                 return devlist;
     601                if(error)
     602                        *error = UPNPDISCOVER_SOCKET_ERROR;
     603                break;
    643604        } else if (n == 0) {
    644605                /* no data or Time Out */
    645                 if (devlist || (deviceList[deviceIndex] == 0)) {
     606                if (devlist) {
    646607                        /* no more device type to look for... */
    647                         closesocket(sudp);
    648                         return devlist;
     608                        if(error)
     609                                *error = UPNPDISCOVER_SUCCESS;
     610                        break;
     611                }
     612                if(ipv6) {
     613                        if(linklocal) {
     614                                linklocal = 0;
     615                                --deviceIndex;
     616                        } else {
     617                                linklocal = 1;
     618                        }
    649619                }
    650620        } else {
     
    673643                                continue;
    674644                        tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize);
     645                        if(!tmp) {
     646                                /* memory allocation error */
     647                                if(error)
     648                                        *error = UPNPDISCOVER_MEMORY_ERROR;
     649                                break;
     650                        }
    675651                        tmp->pNext = devlist;
    676652                        tmp->descURL = tmp->buffer;
     
    684660        }
    685661        }
     662        closesocket(sudp);
     663        return devlist;
    686664}
    687665
     
    728706{
    729707        char * p;
    730         int n1, n2, n3;
     708        int n1, n2, n3, n4;
    731709        n1 = strlen(data->urlbase);
    732710        if(n1==0)
    733711                n1 = strlen(descURL);
    734712        n1 += 2;        /* 1 byte more for Null terminator, 1 byte for '/' if needed */
    735         n2 = n1; n3 = n1;
     713        n2 = n1; n3 = n1; n4 = n1;
    736714        n1 += strlen(data->first.scpdurl);
    737715        n2 += strlen(data->first.controlurl);
    738716        n3 += strlen(data->CIF.controlurl);
     717        n4 += strlen(data->IPv6FC.controlurl);
    739718
    740719        urls->ipcondescURL = (char *)malloc(n1);
    741720        urls->controlURL = (char *)malloc(n2);
    742721        urls->controlURL_CIF = (char *)malloc(n3);
     722        urls->controlURL_6FC = (char *)malloc(n4);
    743723        /* maintenant on chope la desc du WANIPConnection */
    744724        if(data->urlbase[0] != '\0')
     
    750730        strncpy(urls->controlURL, urls->ipcondescURL, n2);
    751731        strncpy(urls->controlURL_CIF, urls->ipcondescURL, n3);
     732        strncpy(urls->controlURL_6FC, urls->ipcondescURL, n4);
    752733       
    753734        url_cpy_or_cat(urls->ipcondescURL, data->first.scpdurl, n1);
     
    756737
    757738        url_cpy_or_cat(urls->controlURL_CIF, data->CIF.controlurl, n3);
     739
     740        url_cpy_or_cat(urls->controlURL_6FC, data->IPv6FC.controlurl, n4);
    758741
    759742#ifdef DEBUG
     
    764747        printf("urls->controlURL_CIF='%s' %u n3=%d\n", urls->controlURL_CIF,
    765748               (unsigned)strlen(urls->controlURL_CIF), n3);
     749        printf("urls->controlURL_6FC='%s' %u n4=%d\n", urls->controlURL_6FC,
     750               (unsigned)strlen(urls->controlURL_6FC), n4);
    766751#endif
    767752}
     
    778763        free(urls->controlURL_CIF);
    779764        urls->controlURL_CIF = 0;
    780 }
    781 
    782 
    783 int ReceiveData(int socket, char * data, int length, int timeout)
    784 {
    785     int n;
    786 #if !defined(WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
    787     struct pollfd fds[1]; /* for the poll */
    788 #ifdef MINIUPNPC_IGNORE_EINTR
    789     do {
    790 #endif
    791         fds[0].fd = socket;
    792         fds[0].events = POLLIN;
    793         n = poll(fds, 1, timeout);
    794 #ifdef MINIUPNPC_IGNORE_EINTR
    795     } while(n < 0 && errno == EINTR);
    796 #endif
    797     if(n < 0)
    798     {
    799         PRINT_SOCKET_ERROR("poll");
    800         return -1;
    801     }
    802     else if(n == 0)
    803     {
    804         return 0;
    805     }
    806 #else
    807     fd_set socketSet;
    808     TIMEVAL timeval;
    809     FD_ZERO(&socketSet);
    810     FD_SET(socket, &socketSet);
    811     timeval.tv_sec = timeout / 1000;
    812     timeval.tv_usec = (timeout % 1000) * 1000;
    813     n = select(FD_SETSIZE, &socketSet, NULL, NULL, &timeval);
    814     if(n < 0)
    815     {
    816         PRINT_SOCKET_ERROR("select");
    817         return -1;
    818     }
    819     else if(n == 0)
    820     {
    821         return 0;
    822     }   
    823 #endif
    824         n = recv(socket, data, length, 0);
    825         if(n<0)
    826         {
    827                 PRINT_SOCKET_ERROR("recv");
    828         }
    829         return n;
     765        free(urls->controlURL_6FC);
     766        urls->controlURL_6FC = 0;
    830767}
    831768
  • trunk/third-party/miniupnp/miniupnpc.h

    r9282 r12593  
    1 /* $Id: miniupnpc.h,v 1.19 2009/10/10 19:15:35 nanard Exp $ */
     1/* $Id: miniupnpc.h,v 1.23 2011/04/11 08:21:46 nanard Exp $ */
    22/* Project: miniupnp
    33 * http://miniupnp.free.fr/
    44 * Author: Thomas Bernard
    5  * Copyright (c) 2005-2006 Thomas Bernard
     5 * Copyright (c) 2005-2011 Thomas Bernard
    66 * This software is subjects to the conditions detailed
    77 * in the LICENCE file provided within this distribution */
     
    1212#include "igd_desc_parse.h"
    1313
     14/* error codes : */
     15#define UPNPDISCOVER_SUCCESS (0)
     16#define UPNPDISCOVER_UNKNOWN_ERROR (-1)
     17#define UPNPDISCOVER_SOCKET_ERROR (-101)
     18#define UPNPDISCOVER_MEMORY_ERROR (-102)
     19
    1420#ifdef __cplusplus
    1521extern "C" {
     
    1925struct UPNParg { const char * elt; const char * val; };
    2026
    21 int simpleUPnPcommand(int, const char *, const char *,
    22                       const char *, struct UPNParg *,
    23                       char *, int *);
     27char *
     28simpleUPnPcommand(int, const char *, const char *,
     29                  const char *, struct UPNParg *,
     30                  int *);
    2431
    2532struct UPNPDev {
     
    4350 * If sameport is not null, SSDP packets will be sent from the source port
    4451 * 1900 (same as destination port) otherwise system assign a source port. */
    45 LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
    46                                       const char * minissdpdsock, int sameport);
     52LIBSPEC struct UPNPDev *
     53upnpDiscover(int delay, const char * multicastif,
     54             const char * minissdpdsock, int sameport,
     55             int ipv6,
     56             int * error);
    4757/* freeUPNPDevlist()
    4858 * free list returned by upnpDiscover() */
     
    5868 * ipcondescURL: url of the description of the WANIPConnection
    5969 * controlURL_CIF: controlURL of the WANCommonInterfaceConfig
     70 * controlURL_6FC: controlURL of the WANIPv6FirewallControl
    6071 */
    6172struct UPNPUrls {
     
    6374        char * ipcondescURL;
    6475        char * controlURL_CIF;
     76        char * controlURL_6FC;
    6577};
    6678
     
    98110LIBSPEC void FreeUPNPUrls(struct UPNPUrls *);
    99111
    100 /* Reads data from the specified socket.
    101  * Returns the number of bytes read if successful, zero if no bytes were
    102  * read or if we timed out. Returns negative if there was an error. */
    103 int ReceiveData(int socket, char * data, int length, int timeout);
    104 
    105112/* return 0 or 1 */
    106113LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *);
  • trunk/third-party/miniupnp/miniupnpcstrings.h.in

    r10285 r12593  
    1 /* $Id: miniupnpcstrings.h.in,v 1.2 2009/10/30 09:18:18 nanard Exp $ */
     1/* $Id: miniupnpcstrings.h.in,v 1.4 2011/01/04 11:41:53 nanard Exp $ */
    22/* Project: miniupnp
    33 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
    44 * Author: Thomas Bernard
    5  * Copyright (c) 2005-2009 Thomas Bernard
     5 * Copyright (c) 2005-2011 Thomas Bernard
    66 * This software is subjects to the conditions detailed
    77 * in the LICENCE file provided within this distribution */
     
    1010
    1111#define OS_STRING "OS/version"
    12 #define MINIUPNPC_VERSION_STRING "1.4"
     12#define MINIUPNPC_VERSION_STRING "version"
    1313
    1414#endif
  • trunk/third-party/miniupnp/miniwget.c

    r11577 r12593  
    1 /* $Id: miniwget.c,v 1.41 2010/12/12 23:52:02 nanard Exp $ */
     1/* $Id: miniwget.c,v 1.52 2011/06/17 22:59:42 nanard Exp $ */
    22/* Project : miniupnp
    33 * Author : Thomas Bernard
    4  * Copyright (c) 2005-2010 Thomas Bernard
     4 * Copyright (c) 2005-2011 Thomas Bernard
    55 * This software is subject to the conditions detailed in the
    66 * LICENCE file provided in this distribution. */
     
    1010#include <string.h>
    1111#include <ctype.h>
    12 #include "miniupnpc.h"
    1312#ifdef WIN32
    1413#include <winsock2.h>
     
    1918#define snprintf _snprintf
    2019#define socklen_t int
     20#ifndef strncasecmp
    2121#if defined(_MSC_VER) && (_MSC_VER >= 1400)
    2222#define strncasecmp _memicmp
     
    2424#define strncasecmp memicmp
    2525#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
     26#endif /* #ifndef strncasecmp */
    2627#else /* #ifdef WIN32 */
    2728#include <unistd.h>
     
    4748#include "miniwget.h"
    4849#include "connecthostport.h"
     50#include "receivedata.h"
    4951
    5052/*
    5153 * Read a HTTP response from a socket.
    5254 * Process Content-Length and Transfer-encoding headers.
     55 * return a pointer to the content buffer, which length is saved
     56 * to the length parameter.
    5357 */
    5458void *
     
    5761        char buf[2048];
    5862        int n;
    59         int headers = 1;
     63        int endofheaders = 0;
    6064        int chunked = 0;
    6165        int content_length = -1;
     
    6973        int content_buf_len = 2048;
    7074        int content_buf_used = 0;
     75        char chunksize_buf[32];
     76        int chunksize_buf_index;
    7177
    7278        header_buf = malloc(header_buf_len);
    7379        content_buf = malloc(content_buf_len);
    74 
    75         while((n = ReceiveData(s, buf, 2048, 5000)) > 0)
    76         {
    77                 if(headers)
     80        chunksize_buf[0] = '\0';
     81        chunksize_buf_index = 0;
     82
     83        while((n = receivedata(s, buf, 2048, 5000)) > 0)
     84        {
     85                if(endofheaders == 0)
    7886                {
    7987                        int i;
     
    8795                        memcpy(header_buf + header_buf_used, buf, n);
    8896                        header_buf_used += n;
    89                         for(i = 0; i < (header_buf_used-3); i++) {
     97                        /* search for CR LF CR LF (end of headers)
     98                         * recognize also LF LF */
     99                        i = 0;
     100                        while(i < (header_buf_used-1) && (endofheaders == 0)) {
     101                                if(header_buf[i] == '\r') {
     102                                        i++;
     103                                        if(header_buf[i] == '\n') {
     104                                                i++;
     105                                                if(i < header_buf_used && header_buf[i] == '\r') {
     106                                                        i++;
     107                                                        if(i < header_buf_used && header_buf[i] == '\n') {
     108                                                                endofheaders = i+1;
     109                                                        }
     110                                                }
     111                                        }
     112                                } else if(header_buf[i] == '\n') {
     113                                        i++;
     114                                        if(header_buf[i] == '\n') {
     115                                                endofheaders = i+1;
     116                                        }
     117                                }
     118                                i++;
     119                        }
     120                        if(endofheaders == 0)
     121                                continue;
     122                        /* parse header lines */
     123                        for(i = 0; i < endofheaders - 1; i++) {
    90124                                if(colon <= linestart && header_buf[i]==':')
    91125                                {
    92126                                        colon = i;
    93                                         while(i < (n-3)
     127                                        while(i < (endofheaders-1)
    94128                                              && (header_buf[i+1] == ' ' || header_buf[i+1] == '\t'))
    95129                                                i++;
     
    97131                                }
    98132                                /* detecting end of line */
    99                                 else if(header_buf[i]=='\r' && header_buf[i+1]=='\n')
     133                                else if(header_buf[i]=='\r' || header_buf[i]=='\n')
    100134                                {
    101135                                        if(colon > linestart && valuestart > colon)
     
    114148                                                }
    115149                                                else if(0==strncasecmp(header_buf+linestart, "transfer-encoding", colon-linestart)
    116                                                    && 0==strncasecmp(buf+valuestart, "chunked", 7))
     150                                                   && 0==strncasecmp(header_buf+valuestart, "chunked", 7))
    117151                                                {
    118152#ifdef DEBUG
     
    122156                                                }
    123157                                        }
    124                                         linestart = i+2;
     158                                        while(header_buf[i]=='\r' || header_buf[i] == '\n')
     159                                                i++;
     160                                        linestart = i;
    125161                                        colon = linestart;
    126162                                        valuestart = 0;
    127163                                }
    128                                 /* searching for the end of the HTTP headers */
    129                                 if(header_buf[i]=='\r' && header_buf[i+1]=='\n'
    130                                    && header_buf[i+2]=='\r' && header_buf[i+3]=='\n')
    131                                 {
    132                                         headers = 0;    /* end */
    133                                         i += 4;
    134                                         if(i < header_buf_used)
    135                                         {
    136                                                 if(chunked)
    137                                                 {
    138                                                         while(i<header_buf_used)
    139                                                         {
    140                                                                 while(i<header_buf_used && isxdigit(header_buf[i]))
    141                                                                 {
    142                                                                         if(header_buf[i] >= '0' && header_buf[i] <= '9')
    143                                                                                 chunksize = (chunksize << 4) + (header_buf[i] - '0');
    144                                                                         else
    145                                                                                 chunksize = (chunksize << 4) + ((header_buf[i] | 32) - 'a' + 10);
    146                                                                         i++;
    147                                                                 }
    148                                                                 /* discarding chunk-extension */
    149                                                                 while(i < header_buf_used && header_buf[i] != '\r') i++;
    150                                                                 if(i < header_buf_used && header_buf[i] == '\r') i++;
    151                                                                 if(i < header_buf_used && header_buf[i] == '\n') i++;
    152 #ifdef DEBUG
    153                                                                 printf("chunksize = %u (%x)\n", chunksize, chunksize);
    154 #endif
    155                                                                 if(chunksize == 0)
    156                                                                 {
    157 #ifdef DEBUG
    158                                                                         printf("end of HTTP content !\n");
    159 #endif
    160                                                                         goto end_of_stream;     
    161                                                                 }
    162                                                                 bytestocopy = ((int)chunksize < header_buf_used - i)?chunksize:(header_buf_used - i);
    163 #ifdef DEBUG
    164                                                                 printf("chunksize=%u bytestocopy=%u (i=%d header_buf_used=%d)\n",
    165                                                                        chunksize, bytestocopy, i, header_buf_used);
    166 #endif
    167                                                                 if(content_buf_len < (int)(content_buf_used + bytestocopy))
    168                                                                 {
    169                                                                         content_buf = realloc(content_buf, content_buf_used + bytestocopy);
    170                                                                         content_buf_len = content_buf_used + bytestocopy;
    171                                                                 }
    172                                                                 memcpy(content_buf + content_buf_used, header_buf + i, bytestocopy);
    173                                                                 content_buf_used += bytestocopy;
    174                                                                 chunksize -= bytestocopy;
    175                                                                 i += bytestocopy;
    176                                                         }
    177                                                 }
    178                                                 else
    179                                                 {
    180                                                         if(content_buf_len < header_buf_used - i)
    181                                                         {
    182                                                                 content_buf = realloc(content_buf, header_buf_used - i);
    183                                                                 content_buf_len = header_buf_used - i;
    184                                                         }
    185                                                         memcpy(content_buf, header_buf + i, header_buf_used - i);
    186                                                         content_buf_used = header_buf_used - i;
    187                                                         i = header_buf_used;
    188                                                 }
    189                                         }
    190                                 }
    191                         }
    192                 }
    193                 else
     164                        }
     165                        /* copy the remaining of the received data back to buf */
     166                        n = header_buf_used - endofheaders;
     167                        memcpy(buf, header_buf + endofheaders, n);
     168                        /* if(headers) */
     169                }
     170                if(endofheaders)
    194171                {
    195172                        /* content */
     
    202179                                        {
    203180                                                /* reading chunk size */
     181                                                if(chunksize_buf_index == 0) {
     182                                                        /* skipping any leading CR LF */
     183                                                        if(i<n && buf[i] == '\r') i++;
     184                                                        if(i<n && buf[i] == '\n') i++;
     185                                                }
     186                                                while(i<n && isxdigit(buf[i])
     187                                                     && chunksize_buf_index < (sizeof(chunksize_buf)-1))
     188                                                {
     189                                                        chunksize_buf[chunksize_buf_index++] = buf[i];
     190                                                        chunksize_buf[chunksize_buf_index] = '\0';
     191                                                        i++;
     192                                                }
     193                                                while(i<n && buf[i] != '\r' && buf[i] != '\n')
     194                                                        i++; /* discarding chunk-extension */
    204195                                                if(i<n && buf[i] == '\r') i++;
    205                                                 if(i<n && buf[i] == '\n') i++;
    206                                                 while(i<n && isxdigit(buf[i]))
    207                                                 {
    208                                                         if(buf[i] >= '0' && buf[i] <= '9')
    209                                                                 chunksize = (chunksize << 4) + (buf[i] - '0');
     196                                                if(i<n && buf[i] == '\n') {
     197                                                        int j;
     198                                                        for(j = 0; j < chunksize_buf_index; j++) {
     199                                                        if(chunksize_buf[j] >= '0'
     200                                                           && chunksize_buf[j] <= '9')
     201                                                                chunksize = (chunksize << 4) + (chunksize_buf[j] - '0');
    210202                                                        else
    211                                                                 chunksize = (chunksize << 4) + ((buf[i] | 32) - 'a' + 10);
     203                                                                chunksize = (chunksize << 4) + ((chunksize_buf[j] | 32) - 'a' + 10);
     204                                                        }
     205                                                        chunksize_buf[0] = '\0';
     206                                                        chunksize_buf_index = 0;
    212207                                                        i++;
    213                                                 }
    214                                                 while(i<n && buf[i] != '\r') i++; /* discarding chunk-extension */
    215                                                 if(i<n && buf[i] == '\r') i++;
    216                                                 if(i<n && buf[i] == '\n') i++;
     208                                                } else {
     209                                                        /* not finished to get chunksize */
     210                                                        continue;
     211                                                }
    217212#ifdef DEBUG
    218213                                                printf("chunksize = %u (%x)\n", chunksize, chunksize);
     
    230225                                        if((int)(content_buf_used + bytestocopy) > content_buf_len)
    231226                                        {
     227                                                if(content_length >= content_buf_used + (int)bytestocopy) {
     228                                                        content_buf_len = content_length;
     229                                                } else {
     230                                                        content_buf_len = content_buf_used + (int)bytestocopy;
     231                                                }
    232232                                                content_buf = (char *)realloc((void *)content_buf,
    233                                                                               content_buf_used + bytestocopy);
    234                                                 content_buf_len = content_buf_used + bytestocopy;
     233                                                                              content_buf_len);
    235234                                        }
    236235                                        memcpy(content_buf + content_buf_used, buf + i, bytestocopy);
     
    242241                        else
    243242                        {
     243                                /* not chunked */
     244                                if(content_length > 0
     245                                   && (content_buf_used + n) > content_length) {
     246                                        /* skipping additional bytes */
     247                                        n = content_length - content_buf_used;
     248                                }
    244249                                if(content_buf_used + n > content_buf_len)
    245250                                {
     251                                        if(content_length >= content_buf_used + n) {
     252                                                content_buf_len = content_length;
     253                                        } else {
     254                                                content_buf_len = content_buf_used + n;
     255                                        }
    246256                                        content_buf = (char *)realloc((void *)content_buf,
    247                                                                       content_buf_used + n);
    248                                         content_buf_len = content_buf_used + n;
     257                                                                      content_buf_len);
    249258                                }
    250259                                memcpy(content_buf + content_buf_used, buf, n);
     
    252261                        }
    253262                }
     263                /* use the Content-Length header value if available */
    254264                if(content_length > 0 && content_buf_used >= content_length)
    255265                {
     
    276286static void *
    277287miniwget3(const char * url, const char * host,
    278                   unsigned short port, const char * path,
    279                   int * size, char * addr_str, int addr_str_len, const char * httpversion)
     288          unsigned short port, const char * path,
     289          int * size, char * addr_str, int addr_str_len,
     290          const char * httpversion)
    280291{
    281292        char buf[2048];
     
    284295        int len;
    285296        int sent;
     297        void * content;
    286298
    287299        *size = 0;
     
    293305        if(addr_str)
    294306        {
    295                 struct sockaddr saddr;
     307                struct sockaddr_storage saddr;
    296308                socklen_t saddrlen;
    297309
    298310                saddrlen = sizeof(saddr);
    299                 if(getsockname(s, &saddr, &saddrlen) < 0)
     311                if(getsockname(s, (struct sockaddr *)&saddr, &saddrlen) < 0)
    300312                {
    301313                        perror("getsockname");
     
    311323                    printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError());
    312324                }*/
     325                        /* the following code is only compatible with ip v4 addresses */
    313326                        strncpy(addr_str, inet_ntoa(((struct sockaddr_in *)&saddr)->sin_addr), addr_str_len);
    314327#else
    315                         /*inet_ntop(AF_INET, &saddr.sin_addr, addr_str, addr_str_len);*/
    316                         n = getnameinfo(&saddr, saddrlen,
     328#if 0
     329                        if(saddr.sa_family == AF_INET6) {
     330                                inet_ntop(AF_INET6,
     331                                          &(((struct sockaddr_in6 *)&saddr)->sin6_addr),
     332                                          addr_str, addr_str_len);
     333                        } else {
     334                                inet_ntop(AF_INET,
     335                                          &(((struct sockaddr_in *)&saddr)->sin_addr),
     336                                          addr_str, addr_str_len);
     337                        }
     338#endif
     339                        /* getnameinfo return ip v6 address with the scope identifier
     340                         * such as : 2a01:e35:8b2b:7330::%4281128194 */
     341                        n = getnameinfo((const struct sockaddr *)&saddr, saddrlen,
    317342                                        addr_str, addr_str_len,
    318343                                        NULL, 0,
     
    356381                }
    357382        }
    358         return getHTTPResponse(s, size);
     383        content = getHTTPResponse(s, size);
     384        closesocket(s);
     385        return content;
    359386}
    360387
     
    399426{
    400427        char * p1, *p2, *p3;
     428        if(!url)
     429                return 0;
    401430        p1 = strstr(url, "://");
    402431        if(!p1)
     
    406435           ||(url[2]!='t') || (url[3]!='p'))
    407436                return 0;
     437        memset(hostname, 0, MAXHOSTNAMELEN + 1);
     438        if(*p1 == '[')
     439        {
     440                /* IP v6 : http://[2a00:1450:8002::6a]/path/abc */
     441                p2 = strchr(p1, ']');
     442                p3 = strchr(p1, '/');
     443                if(p2 && p3)
     444                {
     445                        p2++;
     446                        strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1)));
     447                        if(*p2 == ':')
     448                        {
     449                                *port = 0;
     450                                p2++;
     451                                while( (*p2 >= '0') && (*p2 <= '9'))
     452                                {
     453                                        *port *= 10;
     454                                        *port += (unsigned short)(*p2 - '0');
     455                                        p2++;
     456                                }
     457                        }
     458                        else
     459                        {
     460                                *port = 80;
     461                        }
     462                        *path = p3;
     463                        return 1;
     464                }
     465        }
    408466        p2 = strchr(p1, ':');
    409467        p3 = strchr(p1, '/');
    410468        if(!p3)
    411469                return 0;
    412         memset(hostname, 0, MAXHOSTNAMELEN + 1);
    413470        if(!p2 || (p2>p3))
    414471        {
     
    441498        if(!parseURL(url, hostname, &port, &path))
    442499                return NULL;
     500#ifdef DEBUG
     501        printf("parsed url : hostname='%s' port=%hu path='%s'\n", hostname, port, path);
     502#endif
    443503        return miniwget2(url, hostname, port, path, size, 0, 0);
    444504}
     
    455515        if(!parseURL(url, hostname, &port, &path))
    456516                return NULL;
     517#ifdef DEBUG
     518        printf("parsed url : hostname='%s' port=%hu path='%s'\n", hostname, port, path);
     519#endif
    457520        return miniwget2(url, hostname, port, path, size, addr, addrlen);
    458521}
  • trunk/third-party/miniupnp/minixml.c

    r9282 r12593  
    1 /* $Id: minixml.c,v 1.7 2009/10/10 19:15:35 nanard Exp $ */
     1/* $Id: minixml.c,v 1.9 2011/02/07 13:44:57 nanard Exp $ */
    22/* minixml.c : the minimum size a xml parser can be ! */
    33/* Project : miniupnp
     
    55 * Author : Thomas Bernard
    66
    7 Copyright (c) 2005-2009, Thomas BERNARD
     7Copyright (c) 2005-2011, Thomas BERNARD
    88All rights reserved.
    99
     
    3131POSSIBILITY OF SUCH DAMAGE.
    3232*/
     33#include <string.h>
    3334#include "minixml.h"
    3435
     
    144145                                        while( IS_WHITE_SPACE(*p->xml) )
    145146                                        {
    146                                                 p->xml++;
    147                                                 if (p->xml >= p->xmlend)
    148                                                         return;
    149                                         }
    150                                         while(*p->xml!='<')
    151                                         {
    152147                                                i++; p->xml++;
    153148                                                if (p->xml >= p->xmlend)
    154149                                                        return;
    155150                                        }
    156                                         if(i>0 && p->datafunc)
    157                                                 p->datafunc(p->data, data, i);
     151                                        if(memcmp(p->xml, "<![CDATA[", 9) == 0)
     152                                        {
     153                                                /* CDATA handling */
     154                                                p->xml += 9;
     155                                                data = p->xml;
     156                                                i = 0;
     157                                                while(memcmp(p->xml, "]]>", 3) != 0)
     158                                                {
     159                                                        i++; p->xml++;
     160                                                        if ((p->xml + 3) >= p->xmlend)
     161                                                                return;
     162                                                }
     163                                                if(i>0 && p->datafunc)
     164                                                        p->datafunc(p->data, data, i);
     165                                                while(*p->xml!='<')
     166                                                {
     167                                                        p->xml++;
     168                                                        if (p->xml >= p->xmlend)
     169                                                                return;
     170                                                }
     171                                        }
     172                                        else
     173                                        {
     174                                                while(*p->xml!='<')
     175                                                {
     176                                                        i++; p->xml++;
     177                                                        if ((p->xml + 1) >= p->xmlend)
     178                                                                return;
     179                                                }
     180                                                if(i>0 && p->datafunc && *(p->xml + 1) == '/')
     181                                                        p->datafunc(p->data, data, i);
     182                                        }
    158183                                }
    159184                        }
  • trunk/third-party/miniupnp/upnpcommands.c

    r10739 r12593  
    1 /* $Id: upnpcommands.c,v 1.26 2010/06/09 10:59:09 nanard Exp $ */
     1/* $Id: upnpcommands.c,v 1.37 2011/06/04 15:56:23 nanard Exp $ */
    22/* Project : miniupnp
    33 * Author : Thomas Bernard
    4  * Copyright (c) 2005-2010 Thomas Bernard
     4 * Copyright (c) 2005-2011 Thomas Bernard
    55 * This software is subject to the conditions detailed in the
    66 * LICENCE file provided in this distribution.
     
    1111#include "upnpcommands.h"
    1212#include "miniupnpc.h"
     13#include "portlistingparse.h"
    1314
    1415static UNSIGNED_INTEGER
     
    2526{
    2627        struct NameValueParserData pdata;
    27         char buffer[4096];
    28         int bufsize = 4096;
     28        char * buffer;
     29        int bufsize;
    2930        unsigned int r = 0;
    3031        char * p;
    31         if(simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalBytesSent", 0, buffer, &bufsize) < 0) {
    32                 return UPNPCOMMAND_HTTP_ERROR;
    33         }
    34         ParseNameValue(buffer, bufsize, &pdata);
    35         /*DisplayNameValueList(buffer, bufsize);*/
     32        if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
     33                                        "GetTotalBytesSent", 0, &bufsize))) {
     34                return UPNPCOMMAND_HTTP_ERROR;
     35        }
     36        ParseNameValue(buffer, bufsize, &pdata);
     37        /*DisplayNameValueList(buffer, bufsize);*/
     38        free(buffer); buffer = NULL;
    3639        p = GetValueFromNameValueList(&pdata, "NewTotalBytesSent");
    3740        r = my_atoui(p);
     
    4750{
    4851        struct NameValueParserData pdata;
    49         char buffer[4096];
    50         int bufsize = 4096;
     52        char * buffer;
     53        int bufsize;
    5154        unsigned int r = 0;
    5255        char * p;
    53         if(simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalBytesReceived", 0, buffer, &bufsize) < 0) {
    54                 return UPNPCOMMAND_HTTP_ERROR;
    55         }
    56         ParseNameValue(buffer, bufsize, &pdata);
    57         /*DisplayNameValueList(buffer, bufsize);*/
     56        if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
     57                                        "GetTotalBytesReceived", 0, &bufsize))) {
     58                return UPNPCOMMAND_HTTP_ERROR;
     59        }
     60        ParseNameValue(buffer, bufsize, &pdata);
     61        /*DisplayNameValueList(buffer, bufsize);*/
     62        free(buffer); buffer = NULL;
    5863        p = GetValueFromNameValueList(&pdata, "NewTotalBytesReceived");
    5964        r = my_atoui(p);
     
    6974{
    7075        struct NameValueParserData pdata;
    71         char buffer[4096];
    72         int bufsize = 4096;
     76        char * buffer;
     77        int bufsize;
    7378        unsigned int r = 0;
    7479        char * p;
    75         if(simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalPacketsSent", 0, buffer, &bufsize) < 0) {
    76                 return UPNPCOMMAND_HTTP_ERROR;
    77         }
    78         ParseNameValue(buffer, bufsize, &pdata);
    79         /*DisplayNameValueList(buffer, bufsize);*/
     80        if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
     81                                        "GetTotalPacketsSent", 0, &bufsize))) {
     82                return UPNPCOMMAND_HTTP_ERROR;
     83        }
     84        ParseNameValue(buffer, bufsize, &pdata);
     85        /*DisplayNameValueList(buffer, bufsize);*/
     86        free(buffer); buffer = NULL;
    8087        p = GetValueFromNameValueList(&pdata, "NewTotalPacketsSent");
    8188        r = my_atoui(p);
     
    9198{
    9299        struct NameValueParserData pdata;
    93         char buffer[4096];
    94         int bufsize = 4096;
     100        char * buffer;
     101        int bufsize;
    95102        unsigned int r = 0;
    96103        char * p;
    97         if(simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalPacketsReceived", 0, buffer, &bufsize) < 0) {
    98                 return UPNPCOMMAND_HTTP_ERROR;
    99         }
    100         ParseNameValue(buffer, bufsize, &pdata);
    101         /*DisplayNameValueList(buffer, bufsize);*/
     104        if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
     105                                        "GetTotalPacketsReceived", 0, &bufsize))) {
     106                return UPNPCOMMAND_HTTP_ERROR;
     107        }
     108        ParseNameValue(buffer, bufsize, &pdata);
     109        /*DisplayNameValueList(buffer, bufsize);*/
     110        free(buffer); buffer = NULL;
    102111        p = GetValueFromNameValueList(&pdata, "NewTotalPacketsReceived");
    103112        r = my_atoui(p);
     
    116125{
    117126        struct NameValueParserData pdata;
    118         char buffer[4096];
    119         int bufsize = 4096;
     127        char * buffer;
     128        int bufsize;
    120129        char * p;
    121130        char * up;
     
    126135                return UPNPCOMMAND_INVALID_ARGS;
    127136
    128         if(simpleUPnPcommand(-1, controlURL, servicetype, "GetStatusInfo", 0, buffer, &bufsize) < 0) {
    129                 return UPNPCOMMAND_HTTP_ERROR;
    130         }
    131         ParseNameValue(buffer, bufsize, &pdata);
    132         /*DisplayNameValueList(buffer, bufsize);*/
     137        if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
     138                                        "GetStatusInfo", 0, &bufsize))) {
     139                return UPNPCOMMAND_HTTP_ERROR;
     140        }
     141        ParseNameValue(buffer, bufsize, &pdata);
     142        /*DisplayNameValueList(buffer, bufsize);*/
     143        free(buffer); buffer = NULL;
    133144        up = GetValueFromNameValueList(&pdata, "NewUptime");
    134145        p = GetValueFromNameValueList(&pdata, "NewConnectionStatus");
     
    177188{
    178189        struct NameValueParserData pdata;
    179         char buffer[4096];
    180         int bufsize = 4096;
     190        char * buffer;
     191        int bufsize;
    181192        char * p;
    182193        int ret = UPNPCOMMAND_UNKNOWN_ERROR;
     
    185196                return UPNPCOMMAND_INVALID_ARGS;
    186197
    187         if(simpleUPnPcommand(-1, controlURL, servicetype,
    188                           "GetConnectionTypeInfo", 0, buffer, &bufsize) < 0) {
    189                 return UPNPCOMMAND_HTTP_ERROR;
    190         }
    191         ParseNameValue(buffer, bufsize, &pdata);
     198        if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
     199                                        "GetConnectionTypeInfo", 0, &bufsize))) {
     200                return UPNPCOMMAND_HTTP_ERROR;
     201        }
     202        ParseNameValue(buffer, bufsize, &pdata);
     203        free(buffer); buffer = NULL;
    192204        p = GetValueFromNameValueList(&pdata, "NewConnectionType");
    193205        /*p = GetValueFromNameValueList(&pdata, "NewPossibleConnectionTypes");*/
     
    217229                             const char * servicetype,
    218230                             unsigned int * bitrateDown,
    219                              unsigned int* bitrateUp)
    220 {
    221         struct NameValueParserData pdata;
    222         char buffer[4096];
    223         int bufsize = 4096;
     231                             unsigned int * bitrateUp)
     232{
     233        struct NameValueParserData pdata;
     234        char * buffer;
     235        int bufsize;
    224236        int ret = UPNPCOMMAND_UNKNOWN_ERROR;
    225237        char * down;
     
    231243
    232244        /* shouldn't we use GetCommonLinkProperties ? */
    233         if(simpleUPnPcommand(-1, controlURL, servicetype,
    234                           "GetCommonLinkProperties", 0, buffer, &bufsize) < 0) {
    235                           /*"GetLinkLayerMaxBitRates", 0, buffer, &bufsize);*/
    236                 return UPNPCOMMAND_HTTP_ERROR;
    237         }
    238         /*DisplayNameValueList(buffer, bufsize);*/
    239         ParseNameValue(buffer, bufsize, &pdata);
     245        if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
     246                                        "GetCommonLinkProperties", 0, &bufsize))) {
     247                                      /*"GetLinkLayerMaxBitRates", 0, &bufsize);*/
     248                return UPNPCOMMAND_HTTP_ERROR;
     249        }
     250        /*DisplayNameValueList(buffer, bufsize);*/
     251        ParseNameValue(buffer, bufsize, &pdata);
     252        free(buffer); buffer = NULL;
    240253        /*down = GetValueFromNameValueList(&pdata, "NewDownstreamMaxBitRate");*/
    241254        /*up = GetValueFromNameValueList(&pdata, "NewUpstreamMaxBitRate");*/
     
    243256        up = GetValueFromNameValueList(&pdata, "NewLayer1UpstreamMaxBitRate");
    244257        /*GetValueFromNameValueList(&pdata, "NewWANAccessType");*/
    245         /*GetValueFromNameValueList(&pdata, "NewPhysicalLinkSatus");*/
     258        /*GetValueFromNameValueList(&pdata, "NewPhysicalLinkStatus");*/
    246259        if(down && up)
    247260                ret = UPNPCOMMAND_SUCCESS;
     
    287300{
    288301        struct NameValueParserData pdata;
    289         char buffer[4096];
    290         int bufsize = 4096;
     302        char * buffer;
     303        int bufsize;
    291304        char * p;
    292305        int ret = UPNPCOMMAND_UNKNOWN_ERROR;
     
    295308                return UPNPCOMMAND_INVALID_ARGS;
    296309
    297         if(simpleUPnPcommand(-1, controlURL, servicetype, "GetExternalIPAddress", 0, buffer, &bufsize) < 0) {
    298                 return UPNPCOMMAND_HTTP_ERROR;
    299         }
    300         /*DisplayNameValueList(buffer, bufsize);*/
    301         ParseNameValue(buffer, bufsize, &pdata);
     310        if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
     311                                        "GetExternalIPAddress", 0, &bufsize))) {
     312                return UPNPCOMMAND_HTTP_ERROR;
     313        }
     314        /*DisplayNameValueList(buffer, bufsize);*/
     315        ParseNameValue(buffer, bufsize, &pdata);
     316        free(buffer); buffer = NULL;
    302317        /*printf("external ip = %s\n", GetValueFromNameValueList(&pdata, "NewExternalIPAddress") );*/
    303318        p = GetValueFromNameValueList(&pdata, "NewExternalIPAddress");
     
    326341                                        const char * desc,
    327342                                        const char * proto,
    328                     const char * remoteHost)
     343                    const char * remoteHost,
     344                    const char * leaseDuration)
    329345{
    330346        struct UPNParg * AddPortMappingArgs;
    331         char buffer[4096];
    332         int bufsize = 4096;
     347        char * buffer;
     348        int bufsize;
    333349        struct NameValueParserData pdata;
    334350        const char * resVal;
     
    354370        AddPortMappingArgs[6].val = desc?desc:"libminiupnpc";
    355371        AddPortMappingArgs[7].elt = "NewLeaseDuration";
    356         AddPortMappingArgs[7].val = "0";
    357         if(simpleUPnPcommand(-1, controlURL, servicetype, "AddPortMapping", AddPortMappingArgs, buffer, &bufsize) < 0) {
     372        AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0";
     373        if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
     374                                        "AddPortMapping", AddPortMappingArgs,
     375                                        &bufsize))) {
    358376                free(AddPortMappingArgs);
    359377                return UPNPCOMMAND_HTTP_ERROR;
     
    363381        /*puts(buffer);*/
    364382        ParseNameValue(buffer, bufsize, &pdata);
     383        free(buffer); buffer = NULL;
    365384        resVal = GetValueFromNameValueList(&pdata, "errorCode");
    366385        if(resVal) {
     
    383402        /*struct NameValueParserData pdata;*/
    384403        struct UPNParg * DeletePortMappingArgs;
    385         char buffer[4096];
    386         int bufsize = 4096;
     404        char * buffer;
     405        int bufsize;
    387406        struct NameValueParserData pdata;
    388407        const char * resVal;
     
    399418        DeletePortMappingArgs[2].elt = "NewProtocol";
    400419        DeletePortMappingArgs[2].val = proto;
    401         if(simpleUPnPcommand(-1, controlURL, servicetype,
    402                              "DeletePortMapping",
    403                              DeletePortMappingArgs, buffer, &bufsize) < 0 ) {
     420        if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
     421                                       "DeletePortMapping",
     422                                       DeletePortMappingArgs, &bufsize))) {
    404423                free(DeletePortMappingArgs);
    405424                return UPNPCOMMAND_HTTP_ERROR;
     
    407426        /*DisplayNameValueList(buffer, bufsize);*/
    408427        ParseNameValue(buffer, bufsize, &pdata);
     428        free(buffer); buffer = NULL;
    409429        resVal = GetValueFromNameValueList(&pdata, "errorCode");
    410430        if(resVal) {
     
    434454        struct NameValueParserData pdata;
    435455        struct UPNParg * GetPortMappingArgs;
    436         char buffer[4096];
    437         int bufsize = 4096;
     456        char * buffer;
     457        int bufsize;
    438458        char * p;
    439459        int r = UPNPCOMMAND_UNKNOWN_ERROR;
     
    445465        GetPortMappingArgs[0].elt = "NewPortMappingIndex";
    446466        GetPortMappingArgs[0].val = index;
    447         if(simpleUPnPcommand(-1, controlURL, servicetype,
    448                           "GetGenericPortMappingEntry",
    449                                           GetPortMappingArgs, buffer, &bufsize) < 0) {
     467        if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
     468                                       "GetGenericPortMappingEntry",
     469                                       GetPortMappingArgs, &bufsize))) {
    450470                free(GetPortMappingArgs);
    451471                return UPNPCOMMAND_HTTP_ERROR;
    452472        }
    453473        ParseNameValue(buffer, bufsize, &pdata);
     474        free(buffer); buffer = NULL;
     475
    454476        p = GetValueFromNameValueList(&pdata, "NewRemoteHost");
    455477        if(p && rHost)
     
    518540{
    519541        struct NameValueParserData pdata;
    520         char buffer[4096];
    521         int bufsize = 4096;
     542        char * buffer;
     543        int bufsize;
    522544        char* p;
    523545        int ret = UPNPCOMMAND_UNKNOWN_ERROR;
    524         if(simpleUPnPcommand(-1, controlURL, servicetype, "GetPortMappingNumberOfEntries", 0, buffer, &bufsize) < 0) {
     546        if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
     547                                        "GetPortMappingNumberOfEntries", 0,
     548                                        &bufsize))) {
    525549                return UPNPCOMMAND_HTTP_ERROR;
    526550        }
     
    529553#endif
    530554        ParseNameValue(buffer, bufsize, &pdata);
     555        free(buffer); buffer = NULL;
    531556
    532557        p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries");
     
    556581                                                             const char * proto,
    557582                                 char * intClient,
    558                                  char * intPort)
     583                                 char * intPort,
     584                                 char * desc,
     585                                 char * enabled,
     586                                 char * leaseDuration)
    559587{
    560588        struct NameValueParserData pdata;
    561589        struct UPNParg * GetPortMappingArgs;
    562         char buffer[4096];
    563         int bufsize = 4096;
     590        char * buffer;
     591        int bufsize;
    564592        char * p;
    565593        int ret = UPNPCOMMAND_UNKNOWN_ERROR;
     
    570598        GetPortMappingArgs = calloc(4, sizeof(struct UPNParg));
    571599        GetPortMappingArgs[0].elt = "NewRemoteHost";
     600        /* TODO : add remote host ? */
    572601        GetPortMappingArgs[1].elt = "NewExternalPort";
    573602        GetPortMappingArgs[1].val = extPort;
    574603        GetPortMappingArgs[2].elt = "NewProtocol";
    575604        GetPortMappingArgs[2].val = proto;
    576         if(simpleUPnPcommand(-1, controlURL, servicetype,
    577                              "GetSpecificPortMappingEntry",
    578                              GetPortMappingArgs, buffer, &bufsize) < 0) {
     605        if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
     606                                        "GetSpecificPortMappingEntry",
     607                                        GetPortMappingArgs, &bufsize))) {
    579608                free(GetPortMappingArgs);
    580609                return UPNPCOMMAND_HTTP_ERROR;
     
    582611        /*DisplayNameValueList(buffer, bufsize);*/
    583612        ParseNameValue(buffer, bufsize, &pdata);
     613        free(buffer); buffer = NULL;
    584614
    585615        p = GetValueFromNameValueList(&pdata, "NewInternalClient");
     
    598628                intPort[0] = '\0';
    599629
     630        p = GetValueFromNameValueList(&pdata, "NewEnabled");
     631        if(p && enabled) {
     632                strncpy(enabled, p, 4);
     633                enabled[3] = '\0';
     634        }
     635
     636        p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
     637        if(p && desc) {
     638                strncpy(desc, p, 80);
     639                desc[79] = '\0';
     640        }
     641
     642        p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
     643        if(p && leaseDuration)
     644        {
     645                strncpy(leaseDuration, p, 16);
     646                leaseDuration[15] = '\0';
     647        }
     648
    600649        p = GetValueFromNameValueList(&pdata, "errorCode");
    601650        if(p) {
     
    609658}
    610659
    611 
     660/* UPNP_GetListOfPortMappings()
     661 *
     662 * Possible UPNP Error codes :
     663 * 606 Action not Authorized
     664 * 730 PortMappingNotFound - no port mapping is found in the specified range.
     665 * 733 InconsistantParameters - NewStartPort and NewEndPort values are not
     666 *                              consistent.
     667 */
     668LIBSPEC int
     669UPNP_GetListOfPortMappings(const char * controlURL,
     670                           const char * servicetype,
     671                           const char * startPort,
     672                           const char * endPort,
     673                           const char * protocol,
     674                           const char * numberOfPorts,
     675                           struct PortMappingParserData * data)
     676{
     677        struct NameValueParserData pdata;
     678        struct UPNParg * GetListOfPortMappingsArgs;
     679        const char * p;
     680        char * buffer;
     681        int bufsize;
     682        int ret = UPNPCOMMAND_UNKNOWN_ERROR;
     683
     684        if(!startPort || !endPort || !protocol)
     685                return UPNPCOMMAND_INVALID_ARGS;
     686
     687        GetListOfPortMappingsArgs = calloc(6, sizeof(struct UPNParg));
     688        GetListOfPortMappingsArgs[0].elt = "NewStartPort";
     689        GetListOfPortMappingsArgs[0].val = startPort;
     690        GetListOfPortMappingsArgs[1].elt = "NewEndPort";
     691        GetListOfPortMappingsArgs[1].val = endPort;
     692        GetListOfPortMappingsArgs[2].elt = "NewProtocol";
     693        GetListOfPortMappingsArgs[2].val = protocol;
     694        GetListOfPortMappingsArgs[3].elt = "NewManage";
     695        GetListOfPortMappingsArgs[3].val = "1";
     696        GetListOfPortMappingsArgs[4].elt = "NewNumberOfPorts";
     697        GetListOfPortMappingsArgs[4].val = numberOfPorts?numberOfPorts:"1000";
     698
     699        if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
     700                                        "GetListOfPortMappings",
     701                                        GetListOfPortMappingsArgs, &bufsize))) {
     702                free(GetListOfPortMappingsArgs);
     703                return UPNPCOMMAND_HTTP_ERROR;
     704        }
     705        free(GetListOfPortMappingsArgs);
     706
     707        /*DisplayNameValueList(buffer, bufsize);*/
     708        ParseNameValue(buffer, bufsize, &pdata);
     709        free(buffer); buffer = NULL;
     710
     711        /*p = GetValueFromNameValueList(&pdata, "NewPortListing");*/
     712        /*if(p) {
     713                printf("NewPortListing : %s\n", p);
     714        }*/
     715        /*printf("NewPortListing(%d chars) : %s\n",
     716               pdata.portListingLength, pdata.portListing);*/
     717        if(pdata.portListing)
     718        {
     719                /*struct PortMapping * pm;
     720                int i = 0;*/
     721                ParsePortListing(pdata.portListing, pdata.portListingLength,
     722                                 data);
     723                ret = UPNPCOMMAND_SUCCESS;
     724                /*
     725                for(pm = data->head.lh_first; pm != NULL; pm = pm->entries.le_next)
     726                {
     727                        printf("%2d %s %5hu->%s:%-5hu '%s' '%s'\n",
     728                               i, pm->protocol, pm->externalPort, pm->internalClient,
     729                               pm->internalPort,
     730                               pm->description, pm->remoteHost);
     731                        i++;
     732                }
     733                */
     734                /*FreePortListing(&data);*/
     735        }
     736
     737        p = GetValueFromNameValueList(&pdata, "errorCode");
     738        if(p) {
     739                ret = UPNPCOMMAND_UNKNOWN_ERROR;
     740                sscanf(p, "%d", &ret);
     741        }
     742        ClearNameValueList(&pdata);
     743
     744        //printf("%.*s", bufsize, buffer);
     745
     746        return ret;
     747}
     748
     749/* IGD:2, functions for service WANIPv6FirewallControl:1 */
     750LIBSPEC int
     751UPNP_GetFirewallStatus(const char * controlURL,
     752                                const char * servicetype,
     753                                int * firewallEnabled,
     754                                int * inboundPinholeAllowed)
     755{
     756        struct NameValueParserData pdata;
     757        char * buffer;
     758        int bufsize;
     759        char * fe, *ipa, *p;
     760        int ret = UPNPCOMMAND_UNKNOWN_ERROR;
     761
     762        if(!firewallEnabled && !inboundPinholeAllowed)
     763                return UPNPCOMMAND_INVALID_ARGS;
     764
     765        buffer = simpleUPnPcommand(-1, controlURL, servicetype,
     766                                   "GetFirewallStatus", 0, &bufsize);
     767        if(!buffer) {
     768                return UPNPCOMMAND_HTTP_ERROR;
     769        }
     770        ParseNameValue(buffer, bufsize, &pdata);
     771        free(buffer); buffer = NULL;
     772        fe = GetValueFromNameValueList(&pdata, "FirewallEnabled");
     773        ipa = GetValueFromNameValueList(&pdata, "InboundPinholeAllowed");
     774        if(ipa && fe)
     775                ret = UPNPCOMMAND_SUCCESS;
     776        if(fe)
     777                *firewallEnabled = my_atoui(fe);
     778        /*else
     779                *firewallEnabled = 0;*/
     780        if(ipa)
     781                *inboundPinholeAllowed = my_atoui(ipa);
     782        /*else
     783                *inboundPinholeAllowed = 0;*/
     784        p = GetValueFromNameValueList(&pdata, "errorCode");
     785        if(p)
     786        {
     787                ret = UPNPCOMMAND_UNKNOWN_ERROR;
     788                sscanf(p, "%d", &ret);
     789        }
     790        ClearNameValueList(&pdata);
     791        return ret;
     792}
     793
     794LIBSPEC int
     795UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype,
     796                    const char * remoteHost,
     797                    const char * remotePort,
     798                    const char * intClient,
     799                    const char * intPort,
     800                    const char * proto,
     801                    int * opTimeout)
     802{
     803        struct UPNParg * GetOutboundPinholeTimeoutArgs;
     804        char * buffer;
     805        int bufsize;
     806        struct NameValueParserData pdata;
     807        const char * resVal;
     808        char * p;
     809        int ret;
     810
     811        if(!intPort || !intClient || !proto || !remotePort || !remoteHost)
     812                return UPNPCOMMAND_INVALID_ARGS;
     813
     814        GetOutboundPinholeTimeoutArgs = calloc(6, sizeof(struct UPNParg));
     815        GetOutboundPinholeTimeoutArgs[0].elt = "RemoteHost";
     816        GetOutboundPinholeTimeoutArgs[0].val = remoteHost;
     817        GetOutboundPinholeTimeoutArgs[1].elt = "RemotePort";
     818        GetOutboundPinholeTimeoutArgs[1].val = remotePort;
     819        GetOutboundPinholeTimeoutArgs[2].elt = "Protocol";
     820        GetOutboundPinholeTimeoutArgs[2].val = proto;
     821        GetOutboundPinholeTimeoutArgs[3].elt = "InternalPort";
     822        GetOutboundPinholeTimeoutArgs[3].val = intPort;
     823        GetOutboundPinholeTimeoutArgs[4].elt = "InternalClient";
     824        GetOutboundPinholeTimeoutArgs[4].val = intClient;
     825        buffer = simpleUPnPcommand(-1, controlURL, servicetype,
     826                                   "GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs, &bufsize);
     827        if(!buffer)
     828                return UPNPCOMMAND_HTTP_ERROR;
     829        ParseNameValue(buffer, bufsize, &pdata);
     830        free(buffer); buffer = NULL;
     831        resVal = GetValueFromNameValueList(&pdata, "errorCode");
     832        if(resVal)
     833        {
     834                ret = UPNPCOMMAND_UNKNOWN_ERROR;
     835                sscanf(resVal, "%d", &ret);
     836        }
     837        else
     838        {
     839                ret = UPNPCOMMAND_SUCCESS;
     840                p = GetValueFromNameValueList(&pdata, "OutboundPinholeTimeout");
     841                if(p)
     842                        *opTimeout = my_atoui(p);
     843        }
     844        ClearNameValueList(&pdata);
     845        free(GetOutboundPinholeTimeoutArgs);
     846        return ret;
     847}
     848
     849LIBSPEC int
     850UPNP_AddPinhole(const char * controlURL, const char * servicetype,
     851                    const char * remoteHost,
     852                    const char * remotePort,
     853                    const char * intClient,
     854                    const char * intPort,
     855                    const char * proto,
     856                    const char * leaseTime,
     857                    char * uniqueID)
     858{
     859        struct UPNParg * AddPinholeArgs;
     860        char * buffer;
     861        int bufsize;
     862        struct NameValueParserData pdata;
     863        const char * resVal;
     864        char * p;
     865        int ret;
     866
     867        if(!intPort || !intClient || !proto || !remoteHost || !remotePort || !leaseTime)
     868                return UPNPCOMMAND_INVALID_ARGS;
     869
     870        AddPinholeArgs = calloc(7, sizeof(struct UPNParg));
     871        // RemoteHost can be wilcarded
     872        if(strncmp(remoteHost, "empty", 5)==0)
     873        {
     874                AddPinholeArgs[0].elt = "RemoteHost";
     875                AddPinholeArgs[0].val = "";
     876        }
     877        else
     878        {
     879                AddPinholeArgs[0].elt = "RemoteHost";
     880                AddPinholeArgs[0].val = remoteHost;
     881        }
     882        AddPinholeArgs[1].elt = "RemotePort";
     883        AddPinholeArgs[1].val = remotePort;
     884        AddPinholeArgs[2].elt = "Protocol";
     885        AddPinholeArgs[2].val = proto;
     886        AddPinholeArgs[3].elt = "InternalPort";
     887        AddPinholeArgs[3].val = intPort;
     888        if(strncmp(intClient, "empty", 5)==0)
     889        {
     890                AddPinholeArgs[4].elt = "InternalClient";
     891                AddPinholeArgs[4].val = "";
     892        }
     893        else
     894        {
     895                AddPinholeArgs[4].elt = "InternalClient";
     896                AddPinholeArgs[4].val = intClient;
     897        }
     898        AddPinholeArgs[5].elt = "LeaseTime";
     899        AddPinholeArgs[5].val = leaseTime;
     900        buffer = simpleUPnPcommand(-1, controlURL, servicetype,
     901                                   "AddPinhole", AddPinholeArgs, &bufsize);
     902        if(!buffer)
     903                return UPNPCOMMAND_HTTP_ERROR;
     904        ParseNameValue(buffer, bufsize, &pdata);
     905        free(buffer); buffer = NULL;
     906        p = GetValueFromNameValueList(&pdata, "UniqueID");
     907        if(p)
     908        {
     909                strncpy(uniqueID, p, 8);
     910                uniqueID[7] = '\0';
     911        }
     912        resVal = GetValueFromNameValueList(&pdata, "errorCode");
     913        if(resVal)
     914        {
     915                //printf("AddPortMapping errorCode = '%s'\n", resVal);
     916                ret = UPNPCOMMAND_UNKNOWN_ERROR;
     917                sscanf(resVal, "%d", &ret);
     918        }
     919        else
     920        {
     921                ret = UPNPCOMMAND_SUCCESS;
     922        }
     923        ClearNameValueList(&pdata);
     924        free(AddPinholeArgs);
     925        return ret;
     926}
     927
     928LIBSPEC int
     929UPNP_UpdatePinhole(const char * controlURL, const char * servicetype,
     930                    const char * uniqueID,
     931                    const char * leaseTime)
     932{
     933        struct UPNParg * UpdatePinholeArgs;
     934        char * buffer;
     935        int bufsize;
     936        struct NameValueParserData pdata;
     937        const char * resVal;
     938        int ret;
     939
     940        if(!uniqueID || !leaseTime)
     941                return UPNPCOMMAND_INVALID_ARGS;
     942
     943        UpdatePinholeArgs = calloc(3, sizeof(struct UPNParg));
     944        UpdatePinholeArgs[0].elt = "UniqueID";
     945        UpdatePinholeArgs[0].val = uniqueID;
     946        UpdatePinholeArgs[1].elt = "NewLeaseTime";
     947        UpdatePinholeArgs[1].val = leaseTime;
     948        buffer = simpleUPnPcommand(-1, controlURL, servicetype,
     949                                   "UpdatePinhole", UpdatePinholeArgs, &bufsize);
     950        if(!buffer)
     951                return UPNPCOMMAND_HTTP_ERROR;
     952        ParseNameValue(buffer, bufsize, &pdata);
     953        free(buffer); buffer = NULL;
     954        resVal = GetValueFromNameValueList(&pdata, "errorCode");
     955        if(resVal)
     956        {
     957                /*printf("AddPortMapping errorCode = '%s'\n", resVal); */
     958                ret = UPNPCOMMAND_UNKNOWN_ERROR;
     959                sscanf(resVal, "%d", &ret);
     960        }
     961        else
     962        {
     963                ret = UPNPCOMMAND_SUCCESS;
     964        }
     965        ClearNameValueList(&pdata);
     966        free(UpdatePinholeArgs);
     967        return ret;
     968}
     969
     970LIBSPEC int
     971UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID)
     972{
     973        /*struct NameValueParserData pdata;*/
     974        struct UPNParg * DeletePinholeArgs;
     975        char * buffer;
     976        int bufsize;
     977        struct NameValueParserData pdata;
     978        const char * resVal;
     979        int ret;
     980
     981        if(!uniqueID)
     982                return UPNPCOMMAND_INVALID_ARGS;
     983
     984        DeletePinholeArgs = calloc(2, sizeof(struct UPNParg));
     985        DeletePinholeArgs[0].elt = "UniqueID";
     986        DeletePinholeArgs[0].val = uniqueID;
     987        buffer = simpleUPnPcommand(-1, controlURL, servicetype,
     988                                   "DeletePinhole", DeletePinholeArgs, &bufsize);
     989        if(!buffer)
     990                return UPNPCOMMAND_HTTP_ERROR;
     991        /*DisplayNameValueList(buffer, bufsize);*/
     992        ParseNameValue(buffer, bufsize, &pdata);
     993        free(buffer); buffer = NULL;
     994        resVal = GetValueFromNameValueList(&pdata, "errorCode");
     995        if(resVal)
     996        {
     997                ret = UPNPCOMMAND_UNKNOWN_ERROR;
     998                sscanf(resVal, "%d", &ret);
     999        }
     1000        else
     1001        {
     1002                ret = UPNPCOMMAND_SUCCESS;
     1003        }
     1004        ClearNameValueList(&pdata);
     1005        free(DeletePinholeArgs);
     1006        return ret;
     1007}
     1008
     1009LIBSPEC int
     1010UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype,
     1011                                 const char * uniqueID, int * isWorking)
     1012{
     1013        struct NameValueParserData pdata;
     1014        struct UPNParg * CheckPinholeWorkingArgs;
     1015        char * buffer;
     1016        int bufsize;
     1017        char * p;
     1018        int ret = UPNPCOMMAND_UNKNOWN_ERROR;
     1019
     1020        if(!uniqueID)
     1021                return UPNPCOMMAND_INVALID_ARGS;
     1022
     1023        CheckPinholeWorkingArgs = calloc(4, sizeof(struct UPNParg));
     1024        CheckPinholeWorkingArgs[0].elt = "UniqueID";
     1025        CheckPinholeWorkingArgs[0].val = uniqueID;
     1026        buffer = simpleUPnPcommand(-1, controlURL, servicetype,
     1027                                   "CheckPinholeWorking", CheckPinholeWorkingArgs, &bufsize);
     1028        if(!buffer)
     1029                return UPNPCOMMAND_HTTP_ERROR;
     1030        ParseNameValue(buffer, bufsize, &pdata);
     1031        free(buffer); buffer = NULL;
     1032
     1033        p = GetValueFromNameValueList(&pdata, "IsWorking");
     1034        if(p)
     1035        {
     1036                *isWorking=my_atoui(p);
     1037                ret = UPNPCOMMAND_SUCCESS;
     1038        }
     1039        else
     1040                *isWorking = 0;
     1041
     1042        p = GetValueFromNameValueList(&pdata, "errorCode");
     1043        if(p)
     1044        {
     1045                ret = UPNPCOMMAND_UNKNOWN_ERROR;
     1046                sscanf(p, "%d", &ret);
     1047        }
     1048
     1049        ClearNameValueList(&pdata);
     1050        free(CheckPinholeWorkingArgs);
     1051        return ret;
     1052}
     1053
     1054LIBSPEC int
     1055UPNP_GetPinholePackets(const char * controlURL, const char * servicetype,
     1056                                 const char * uniqueID, int * packets)
     1057{
     1058        struct NameValueParserData pdata;
     1059        struct UPNParg * GetPinholePacketsArgs;
     1060        char * buffer;
     1061        int bufsize;
     1062        char * p;
     1063        int ret = UPNPCOMMAND_UNKNOWN_ERROR;
     1064
     1065        if(!uniqueID)
     1066                return UPNPCOMMAND_INVALID_ARGS;
     1067
     1068        GetPinholePacketsArgs = calloc(4, sizeof(struct UPNParg));
     1069        GetPinholePacketsArgs[0].elt = "UniqueID";
     1070        GetPinholePacketsArgs[0].val = uniqueID;
     1071        buffer = simpleUPnPcommand(-1, controlURL, servicetype,
     1072                                   "GetPinholePackets", GetPinholePacketsArgs, &bufsize);
     1073        if(!buffer)
     1074                return UPNPCOMMAND_HTTP_ERROR;
     1075        ParseNameValue(buffer, bufsize, &pdata);
     1076        free(buffer); buffer = NULL;
     1077
     1078        p = GetValueFromNameValueList(&pdata, "PinholePackets");
     1079        if(p)
     1080        {
     1081                *packets=my_atoui(p);
     1082                ret = UPNPCOMMAND_SUCCESS;
     1083        }
     1084
     1085        p = GetValueFromNameValueList(&pdata, "errorCode");
     1086        if(p)
     1087        {
     1088                ret = UPNPCOMMAND_UNKNOWN_ERROR;
     1089                sscanf(p, "%d", &ret);
     1090        }
     1091
     1092        ClearNameValueList(&pdata);
     1093        free(GetPinholePacketsArgs);
     1094        return ret;
     1095}
     1096
     1097
  • trunk/third-party/miniupnp/upnpcommands.h

    r10740 r12593  
    1 /* $Id: upnpcommands.h,v 1.18 2010/06/09 10:59:09 nanard Exp $ */
     1/* $Id: upnpcommands.h,v 1.23 2011/04/11 09:14:00 nanard Exp $ */
    22/* Miniupnp project : http://miniupnp.free.fr/
    33 * Author : Thomas Bernard
    4  * Copyright (c) 2005-2010 Thomas Bernard
     4 * Copyright (c) 2005-2011 Thomas Bernard
    55 * This software is subject to the conditions detailed in the
    66 * LICENCE file provided within this distribution */
     
    99
    1010#include "upnpreplyparse.h"
     11#include "portlistingparse.h"
    1112#include "declspec.h"
     13#include "miniupnpctypes.h"
    1214
    1315/* MiniUPnPc return codes : */
     
    1921#ifdef __cplusplus
    2022extern "C" {
    21 #endif
    22 
    23 #if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
    24 #define UNSIGNED_INTEGER unsigned long long
    25 #define STRTOUI strtoull
    26 #else
    27 #define UNSIGNED_INTEGER unsigned int
    28 #define STRTOUI strtoul
    2923#endif
    3024
     
    127121                                        const char * desc,
    128122                    const char * proto,
    129                     const char * remoteHost);
     123                    const char * remoteHost,
     124                    const char * leaseDuration);
    130125
    131126/* UPNP_DeletePortMapping()
     
    147142 * not supported by all routers */
    148143LIBSPEC int
    149 UPNP_GetPortMappingNumberOfEntries(const char* controlURL, const char* servicetype, unsigned int * num);
    150 
    151 /* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping
    152  * the result is returned in the intClient and intPort strings
    153  * please provide 16 and 6 bytes of data
     144UPNP_GetPortMappingNumberOfEntries(const char* controlURL,
     145                                   const char* servicetype,
     146                                   unsigned int * num);
     147
     148/* UPNP_GetSpecificPortMappingEntry()
     149 *    retrieves an existing port mapping
     150 * params :
     151 *  in   extPort
     152 *  in   proto
     153 *  out  intClient (16 bytes)
     154 *  out  intPort (6 bytes)
     155 *  out  desc (80 bytes)
     156 *  out  enabled (4 bytes)
     157 *  out  leaseDuration (16 bytes)
    154158 *
    155159 * return value :
     
    162166                                 const char * proto,
    163167                                 char * intClient,
    164                                  char * intPort);
     168                                 char * intPort,
     169                                 char * desc,
     170                                 char * enabled,
     171                                 char * leaseDuration);
    165172
    166173/* UPNP_GetGenericPortMappingEntry()
     174 * params :
     175 *  in   index
     176 *  out  extPort (6 bytes)
     177 *  out  intClient (16 bytes)
     178 *  out  intPort (6 bytes)
     179 *  out  protocol (4 bytes)
     180 *  out  desc (80 bytes)
     181 *  out  enabled (4 bytes)
     182 *  out  rHost (64 bytes)
     183 *  out  duration (16 bytes)
    167184 *
    168185 * return value :
     
    187204                                                                char * duration);
    188205
     206/* UPNP_GetListOfPortMappings()      Available in IGD v2
     207 *
     208 *
     209 * Possible UPNP Error codes :
     210 * 606 Action not Authorized
     211 * 730 PortMappingNotFound - no port mapping is found in the specified range.
     212 * 733 InconsistantParameters - NewStartPort and NewEndPort values are not
     213 *                              consistent.
     214 */
     215LIBSPEC int
     216UPNP_GetListOfPortMappings(const char * controlURL,
     217                           const char * servicetype,
     218                           const char * startPort,
     219                           const char * endPort,
     220                           const char * protocol,
     221                           const char * numberOfPorts,
     222                           struct PortMappingParserData * data);
     223
     224/* IGD:2, functions for service WANIPv6FirewallControl:1 */
     225LIBSPEC int
     226UPNP_GetFirewallStatus(const char * controlURL,
     227                                const char * servicetype,
     228                                int * firewallEnabled,
     229                                int * inboundPinholeAllowed);
     230
     231LIBSPEC int
     232UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype,
     233                    const char * remoteHost,
     234                    const char * remotePort,
     235                    const char * intClient,
     236                    const char * intPort,
     237                    const char * proto,
     238                    int * opTimeout);
     239
     240LIBSPEC int
     241UPNP_AddPinhole(const char * controlURL, const char * servicetype,
     242                    const char * remoteHost,
     243                    const char * remotePort,
     244                    const char * intClient,
     245                    const char * intPort,
     246                    const char * proto,
     247                    const char * leaseTime,
     248                    char * uniqueID);
     249
     250LIBSPEC int
     251UPNP_UpdatePinhole(const char * controlURL, const char * servicetype,
     252                    const char * uniqueID,
     253                    const char * leaseTime);
     254
     255LIBSPEC int
     256UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID);
     257
     258LIBSPEC int
     259UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype,
     260                                 const char * uniqueID, int * isWorking);
     261
     262LIBSPEC int
     263UPNP_GetPinholePackets(const char * controlURL, const char * servicetype,
     264                                 const char * uniqueID, int * packets);
     265
    189266#ifdef __cplusplus
    190267}
  • trunk/third-party/miniupnp/upnpreplyparse.c

    r5094 r12593  
    1 /* $Id: upnpreplyparse.c,v 1.10 2008/02/21 13:05:27 nanard Exp $ */
     1/* $Id: upnpreplyparse.c,v 1.11 2011/02/07 16:17:06 nanard Exp $ */
    22/* MiniUPnP project
    33 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
    4  * (c) 2006 Thomas Bernard
     4 * (c) 2006-2011 Thomas Bernard
    55 * This software is subject to the conditions detailed
    66 * in the LICENCE file provided within the distribution */
     
    2828    struct NameValueParserData * data = (struct NameValueParserData *)d;
    2929    struct NameValue * nv;
    30     nv = malloc(sizeof(struct NameValue));
    31     if(l>63)
    32         l = 63;
    33     strncpy(nv->name, data->curelt, 64);
    34         nv->name[63] = '\0';
    35     memcpy(nv->value, datas, l);
    36     nv->value[l] = '\0';
    37     LIST_INSERT_HEAD( &(data->head), nv, entries);
     30        if(strcmp(data->curelt, "NewPortListing") == 0)
     31        {
     32                /* specific case for NewPortListing which is a XML Document */
     33                data->portListing = malloc(l + 1);
     34                if(!data->portListing)
     35                {
     36                        /* malloc error */
     37                        return;
     38                }
     39                memcpy(data->portListing, datas, l);
     40                data->portListing[l] = '\0';
     41                data->portListingLength = l;
     42        }
     43        else
     44        {
     45                /* standard case. Limited to 63 chars strings */
     46            nv = malloc(sizeof(struct NameValue));
     47            if(l>63)
     48                l = 63;
     49            strncpy(nv->name, data->curelt, 64);
     50                nv->name[63] = '\0';
     51            memcpy(nv->value, datas, l);
     52            nv->value[l] = '\0';
     53            LIST_INSERT_HEAD( &(data->head), nv, entries);
     54        }
    3855}
    3956
    4057void
    4158ParseNameValue(const char * buffer, int bufsize,
    42                     struct NameValueParserData * data)
     59               struct NameValueParserData * data)
    4360{
    4461    struct xmlparser parser;
    4562    LIST_INIT(&(data->head));
     63        data->portListing = NULL;
     64        data->portListingLength = 0;
    4665    /* init xmlparser object */
    4766    parser.xmlstart = buffer;
     
    5978{
    6079    struct NameValue * nv;
     80        if(pdata->portListing)
     81        {
     82                free(pdata->portListing);
     83                pdata->portListing = NULL;
     84                pdata->portListingLength = 0;
     85        }
    6186    while((nv = pdata->head.lh_first) != NULL)
    6287    {
  • trunk/third-party/miniupnp/upnpreplyparse.h

    r8798 r12593  
    1 /* $Id: upnpreplyparse.h,v 1.10 2009/07/09 16:01:50 nanard Exp $ */
     1/* $Id: upnpreplyparse.h,v 1.11 2011/02/07 16:17:06 nanard Exp $ */
    22/* MiniUPnP project
    33 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
    4  * (c) 2006-2009 Thomas Bernard
     4 * (c) 2006-2011 Thomas Bernard
    55 * This software is subject to the conditions detailed
    66 * in the LICENCE file provided within the distribution */
     
    2828    LIST_HEAD(listhead, NameValue) head;
    2929    char curelt[64];
     30        char * portListing;
     31        int portListingLength;
    3032};
    3133
Note: See TracChangeset for help on using the changeset viewer.