Browse Source

Clean out obsolete dependencies.

Adam Ierymenko 5 years ago
parent
commit
4df090469a
57 changed files with 4 additions and 13425 deletions
  1. 0 68
      ext/http-parser/AUTHORS
  2. 0 23
      ext/http-parser/LICENSE-MIT
  3. 0 246
      ext/http-parser/README.md
  4. 0 2470
      ext/http-parser/http_parser.c
  5. 0 432
      ext/http-parser/http_parser.h
  6. 0 98
      ext/libnatpmp/Changelog.txt
  7. 0 26
      ext/libnatpmp/LICENSE
  8. 0 7
      ext/libnatpmp/README
  9. 0 21
      ext/libnatpmp/declspec.h
  10. 0 573
      ext/libnatpmp/getgateway.c
  11. 0 49
      ext/libnatpmp/getgateway.h
  12. 0 383
      ext/libnatpmp/natpmp.c
  13. 0 219
      ext/libnatpmp/natpmp.h
  14. 0 60
      ext/libnatpmp/wingettimeofday.c
  15. 0 39
      ext/libnatpmp/wingettimeofday.h
  16. 0 691
      ext/miniupnpc/Changelog.txt
  17. 0 27
      ext/miniupnpc/LICENSE
  18. 0 63
      ext/miniupnpc/README
  19. 0 1
      ext/miniupnpc/VERSION
  20. 0 54
      ext/miniupnpc/codelength.h
  21. 0 262
      ext/miniupnpc/connecthostport.c
  22. 0 18
      ext/miniupnpc/connecthostport.h
  23. 0 123
      ext/miniupnpc/igd_desc_parse.c
  24. 0 49
      ext/miniupnpc/igd_desc_parse.h
  25. 0 110
      ext/miniupnpc/listdevices.c
  26. 0 134
      ext/miniupnpc/minisoap.c
  27. 0 15
      ext/miniupnpc/minisoap.h
  28. 0 893
      ext/miniupnpc/minissdpc.c
  29. 0 58
      ext/miniupnpc/minissdpc.h
  30. 0 722
      ext/miniupnpc/miniupnpc.c
  31. 0 45
      ext/miniupnpc/miniupnpc.def
  32. 0 152
      ext/miniupnpc/miniupnpc.h
  33. 0 21
      ext/miniupnpc/miniupnpc_declspec.h
  34. 0 703
      ext/miniupnpc/miniupnpcmodule.c
  35. 0 23
      ext/miniupnpc/miniupnpcstrings.h.in
  36. 0 19
      ext/miniupnpc/miniupnpctypes.h
  37. 0 673
      ext/miniupnpc/miniwget.c
  38. 0 30
      ext/miniupnpc/miniwget.h
  39. 0 231
      ext/miniupnpc/minixml.c
  40. 0 37
      ext/miniupnpc/minixml.h
  41. 0 163
      ext/miniupnpc/minixmlvalid.c
  42. 0 172
      ext/miniupnpc/portlistingparse.c
  43. 0 65
      ext/miniupnpc/portlistingparse.h
  44. 0 105
      ext/miniupnpc/receivedata.c
  45. 0 19
      ext/miniupnpc/receivedata.h
  46. 0 53
      ext/miniupnpc/updateminiupnpcstrings.sh
  47. 0 857
      ext/miniupnpc/upnpc.c
  48. 0 1240
      ext/miniupnpc/upnpcommands.c
  49. 0 348
      ext/miniupnpc/upnpcommands.h
  50. 0 23
      ext/miniupnpc/upnpdev.c
  51. 0 36
      ext/miniupnpc/upnpdev.h
  52. 0 107
      ext/miniupnpc/upnperrors.c
  53. 0 26
      ext/miniupnpc/upnperrors.h
  54. 0 196
      ext/miniupnpc/upnpreplyparse.c
  55. 0 63
      ext/miniupnpc/upnpreplyparse.h
  56. 0 83
      ext/miniupnpc/wingenminiupnpcstrings.c
  57. 4 1
      go/pkg/zerotier/node.go

+ 0 - 68
ext/http-parser/AUTHORS

@@ -1,68 +0,0 @@
-# Authors ordered by first contribution.
-Ryan Dahl <[email protected]>
-Jeremy Hinegardner <[email protected]>
-Sergey Shepelev <[email protected]>
-Joe Damato <[email protected]>
-tomika <[email protected]>
-Phoenix Sol <[email protected]>
-Cliff Frey <[email protected]>
-Ewen Cheslack-Postava <[email protected]>
-Santiago Gala <[email protected]>
-Tim Becker <[email protected]>
-Jeff Terrace <[email protected]>
-Ben Noordhuis <[email protected]>
-Nathan Rajlich <[email protected]>
-Mark Nottingham <[email protected]>
-Aman Gupta <[email protected]>
-Tim Becker <[email protected]>
-Sean Cunningham <[email protected]>
-Peter Griess <[email protected]>
-Salman Haq <[email protected]>
-Cliff Frey <[email protected]>
-Jon Kolb <[email protected]>
-Fouad Mardini <[email protected]>
-Paul Querna <[email protected]>
-Felix Geisendörfer <[email protected]>
-koichik <[email protected]>
-Andre Caron <[email protected]>
-Ivo Raisr <[email protected]>
-James McLaughlin <[email protected]>
-David Gwynne <[email protected]>
-Thomas LE ROUX <[email protected]>
-Randy Rizun <[email protected]>
-Andre Louis Caron <[email protected]>
-Simon Zimmermann <[email protected]>
-Erik Dubbelboer <[email protected]>
-Martell Malone <[email protected]>
-Bertrand Paquet <[email protected]>
-BogDan Vatra <[email protected]>
-Peter Faiman <[email protected]>
-Corey Richardson <[email protected]>
-Tóth Tamás <[email protected]>
-Cam Swords <[email protected]>
-Chris Dickinson <[email protected]>
-Uli Köhler <[email protected]>
-Charlie Somerville <[email protected]>
-Patrik Stutz <[email protected]>
-Fedor Indutny <[email protected]>
-runner <[email protected]>
-Alexis Campailla <[email protected]>
-David Wragg <[email protected]>
-Vinnie Falco <[email protected]>
-Alex Butum <[email protected]>
-Rex Feng <[email protected]>
-Alex Kocharin <[email protected]>
-Mark Koopman <[email protected]>
-Helge Heß <[email protected]>
-Alexis La Goutte <[email protected]>
-George Miroshnykov <[email protected]>
-Maciej Małecki <[email protected]>
-Marc O'Morain <[email protected]>
-Jeff Pinner <[email protected]>
-Timothy J Fontaine <[email protected]>
-Akagi201 <[email protected]>
-Romain Giraud <[email protected]>
-Jay Satiro <[email protected]>
-Arne Steen <[email protected]>
-Kjell Schubert <[email protected]>
-Olivier Mengué <[email protected]>

+ 0 - 23
ext/http-parser/LICENSE-MIT

@@ -1,23 +0,0 @@
-http_parser.c is based on src/http/ngx_http_parse.c from NGINX copyright
-Igor Sysoev.
-
-Additional changes are licensed under the same terms as NGINX and
-copyright Joyent, Inc. and other Node contributors. All rights reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to
-deal in the Software without restriction, including without limitation the
-rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
-sell copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
-IN THE SOFTWARE. 

+ 0 - 246
ext/http-parser/README.md

@@ -1,246 +0,0 @@
-HTTP Parser
-===========
-
-[![Build Status](https://api.travis-ci.org/nodejs/http-parser.svg?branch=master)](https://travis-ci.org/nodejs/http-parser)
-
-This is a parser for HTTP messages written in C. It parses both requests and
-responses. The parser is designed to be used in performance HTTP
-applications. It does not make any syscalls nor allocations, it does not
-buffer data, it can be interrupted at anytime. Depending on your
-architecture, it only requires about 40 bytes of data per message
-stream (in a web server that is per connection).
-
-Features:
-
-  * No dependencies
-  * Handles persistent streams (keep-alive).
-  * Decodes chunked encoding.
-  * Upgrade support
-  * Defends against buffer overflow attacks.
-
-The parser extracts the following information from HTTP messages:
-
-  * Header fields and values
-  * Content-Length
-  * Request method
-  * Response status code
-  * Transfer-Encoding
-  * HTTP version
-  * Request URL
-  * Message body
-
-
-Usage
------
-
-One `http_parser` object is used per TCP connection. Initialize the struct
-using `http_parser_init()` and set the callbacks. That might look something
-like this for a request parser:
-```c
-http_parser_settings settings;
-settings.on_url = my_url_callback;
-settings.on_header_field = my_header_field_callback;
-/* ... */
-
-http_parser *parser = malloc(sizeof(http_parser));
-http_parser_init(parser, HTTP_REQUEST);
-parser->data = my_socket;
-```
-
-When data is received on the socket execute the parser and check for errors.
-
-```c
-size_t len = 80*1024, nparsed;
-char buf[len];
-ssize_t recved;
-
-recved = recv(fd, buf, len, 0);
-
-if (recved < 0) {
-  /* Handle error. */
-}
-
-/* Start up / continue the parser.
- * Note we pass recved==0 to signal that EOF has been received.
- */
-nparsed = http_parser_execute(parser, &settings, buf, recved);
-
-if (parser->upgrade) {
-  /* handle new protocol */
-} else if (nparsed != recved) {
-  /* Handle error. Usually just close the connection. */
-}
-```
-
-HTTP needs to know where the end of the stream is. For example, sometimes
-servers send responses without Content-Length and expect the client to
-consume input (for the body) until EOF. To tell http_parser about EOF, give
-`0` as the fourth parameter to `http_parser_execute()`. Callbacks and errors
-can still be encountered during an EOF, so one must still be prepared
-to receive them.
-
-Scalar valued message information such as `status_code`, `method`, and the
-HTTP version are stored in the parser structure. This data is only
-temporally stored in `http_parser` and gets reset on each new message. If
-this information is needed later, copy it out of the structure during the
-`headers_complete` callback.
-
-The parser decodes the transfer-encoding for both requests and responses
-transparently. That is, a chunked encoding is decoded before being sent to
-the on_body callback.
-
-
-The Special Problem of Upgrade
-------------------------------
-
-HTTP supports upgrading the connection to a different protocol. An
-increasingly common example of this is the WebSocket protocol which sends
-a request like
-
-        GET /demo HTTP/1.1
-        Upgrade: WebSocket
-        Connection: Upgrade
-        Host: example.com
-        Origin: http://example.com
-        WebSocket-Protocol: sample
-
-followed by non-HTTP data.
-
-(See [RFC6455](https://tools.ietf.org/html/rfc6455) for more information the
-WebSocket protocol.)
-
-To support this, the parser will treat this as a normal HTTP message without a
-body, issuing both on_headers_complete and on_message_complete callbacks. However
-http_parser_execute() will stop parsing at the end of the headers and return.
-
-The user is expected to check if `parser->upgrade` has been set to 1 after
-`http_parser_execute()` returns. Non-HTTP data begins at the buffer supplied
-offset by the return value of `http_parser_execute()`.
-
-
-Callbacks
----------
-
-During the `http_parser_execute()` call, the callbacks set in
-`http_parser_settings` will be executed. The parser maintains state and
-never looks behind, so buffering the data is not necessary. If you need to
-save certain data for later usage, you can do that from the callbacks.
-
-There are two types of callbacks:
-
-* notification `typedef int (*http_cb) (http_parser*);`
-    Callbacks: on_message_begin, on_headers_complete, on_message_complete.
-* data `typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);`
-    Callbacks: (requests only) on_url,
-               (common) on_header_field, on_header_value, on_body;
-
-Callbacks must return 0 on success. Returning a non-zero value indicates
-error to the parser, making it exit immediately.
-
-For cases where it is necessary to pass local information to/from a callback,
-the `http_parser` object's `data` field can be used.
-An example of such a case is when using threads to handle a socket connection,
-parse a request, and then give a response over that socket. By instantiation
-of a thread-local struct containing relevant data (e.g. accepted socket,
-allocated memory for callbacks to write into, etc), a parser's callbacks are
-able to communicate data between the scope of the thread and the scope of the
-callback in a threadsafe manner. This allows http-parser to be used in
-multi-threaded contexts.
-
-Example:
-```c
- typedef struct {
-  socket_t sock;
-  void* buffer;
-  int buf_len;
- } custom_data_t;
-
-
-int my_url_callback(http_parser* parser, const char *at, size_t length) {
-  /* access to thread local custom_data_t struct.
-  Use this access save parsed data for later use into thread local
-  buffer, or communicate over socket
-  */
-  parser->data;
-  ...
-  return 0;
-}
-
-...
-
-void http_parser_thread(socket_t sock) {
- int nparsed = 0;
- /* allocate memory for user data */
- custom_data_t *my_data = malloc(sizeof(custom_data_t));
-
- /* some information for use by callbacks.
- * achieves thread -> callback information flow */
- my_data->sock = sock;
-
- /* instantiate a thread-local parser */
- http_parser *parser = malloc(sizeof(http_parser));
- http_parser_init(parser, HTTP_REQUEST); /* initialise parser */
- /* this custom data reference is accessible through the reference to the
- parser supplied to callback functions */
- parser->data = my_data;
-
- http_parser_settings settings; /* set up callbacks */
- settings.on_url = my_url_callback;
-
- /* execute parser */
- nparsed = http_parser_execute(parser, &settings, buf, recved);
-
- ...
- /* parsed information copied from callback.
- can now perform action on data copied into thread-local memory from callbacks.
- achieves callback -> thread information flow */
- my_data->buffer;
- ...
-}
-
-```
-
-In case you parse HTTP message in chunks (i.e. `read()` request line
-from socket, parse, read half headers, parse, etc) your data callbacks
-may be called more than once. Http-parser guarantees that data pointer is only
-valid for the lifetime of callback. You can also `read()` into a heap allocated
-buffer to avoid copying memory around if this fits your application.
-
-Reading headers may be a tricky task if you read/parse headers partially.
-Basically, you need to remember whether last header callback was field or value
-and apply the following logic:
-
-    (on_header_field and on_header_value shortened to on_h_*)
-     ------------------------ ------------ --------------------------------------------
-    | State (prev. callback) | Callback   | Description/action                         |
-     ------------------------ ------------ --------------------------------------------
-    | nothing (first call)   | on_h_field | Allocate new buffer and copy callback data |
-    |                        |            | into it                                    |
-     ------------------------ ------------ --------------------------------------------
-    | value                  | on_h_field | New header started.                        |
-    |                        |            | Copy current name,value buffers to headers |
-    |                        |            | list and allocate new buffer for new name  |
-     ------------------------ ------------ --------------------------------------------
-    | field                  | on_h_field | Previous name continues. Reallocate name   |
-    |                        |            | buffer and append callback data to it      |
-     ------------------------ ------------ --------------------------------------------
-    | field                  | on_h_value | Value for current header started. Allocate |
-    |                        |            | new buffer and copy callback data to it    |
-     ------------------------ ------------ --------------------------------------------
-    | value                  | on_h_value | Value continues. Reallocate value buffer   |
-    |                        |            | and append callback data to it             |
-     ------------------------ ------------ --------------------------------------------
-
-
-Parsing URLs
-------------
-
-A simplistic zero-copy URL parser is provided as `http_parser_parse_url()`.
-Users of this library may wish to use it to parse URLs constructed from
-consecutive `on_url` callbacks.
-
-See examples of reading in headers:
-
-* [partial example](http://gist.github.com/155877) in C
-* [from http-parser tests](http://github.com/joyent/http-parser/blob/37a0ff8/test.c#L403) in C
-* [from Node library](http://github.com/joyent/node/blob/842eaf4/src/http.js#L284) in Javascript

+ 0 - 2470
ext/http-parser/http_parser.c

@@ -1,2470 +0,0 @@
-/* Based on src/http/ngx_http_parse.c from NGINX copyright Igor Sysoev
- *
- * Additional changes are licensed under the same terms as NGINX and
- * copyright Joyent, Inc. and other Node contributors. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-#include "http_parser.h"
-#include <assert.h>
-#include <stddef.h>
-#include <ctype.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-
-#ifndef ULLONG_MAX
-# define ULLONG_MAX ((uint64_t) -1) /* 2^64-1 */
-#endif
-
-#ifndef MIN
-# define MIN(a,b) ((a) < (b) ? (a) : (b))
-#endif
-
-#ifndef ARRAY_SIZE
-# define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
-#endif
-
-#ifndef BIT_AT
-# define BIT_AT(a, i)                                                \
-  (!!((unsigned int) (a)[(unsigned int) (i) >> 3] &                  \
-   (1 << ((unsigned int) (i) & 7))))
-#endif
-
-#ifndef ELEM_AT
-# define ELEM_AT(a, i, v) ((unsigned int) (i) < ARRAY_SIZE(a) ? (a)[(i)] : (v))
-#endif
-
-#define SET_ERRNO(e)                                                 \
-do {                                                                 \
-  parser->http_errno = (e);                                          \
-} while(0)
-
-#define CURRENT_STATE() p_state
-#define UPDATE_STATE(V) p_state = (enum state) (V);
-#define RETURN(V)                                                    \
-do {                                                                 \
-  parser->state = CURRENT_STATE();                                   \
-  return (V);                                                        \
-} while (0);
-#define REEXECUTE()                                                  \
-  goto reexecute;                                                    \
-
-
-#ifdef __GNUC__
-# define LIKELY(X) __builtin_expect(!!(X), 1)
-# define UNLIKELY(X) __builtin_expect(!!(X), 0)
-#else
-# define LIKELY(X) (X)
-# define UNLIKELY(X) (X)
-#endif
-
-
-/* Run the notify callback FOR, returning ER if it fails */
-#define CALLBACK_NOTIFY_(FOR, ER)                                    \
-do {                                                                 \
-  assert(HTTP_PARSER_ERRNO(parser) == HPE_OK);                       \
-                                                                     \
-  if (LIKELY(settings->on_##FOR)) {                                  \
-    parser->state = CURRENT_STATE();                                 \
-    if (UNLIKELY(0 != settings->on_##FOR(parser))) {                 \
-      SET_ERRNO(HPE_CB_##FOR);                                       \
-    }                                                                \
-    UPDATE_STATE(parser->state);                                     \
-                                                                     \
-    /* We either errored above or got paused; get out */             \
-    if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) {             \
-      return (ER);                                                   \
-    }                                                                \
-  }                                                                  \
-} while (0)
-
-/* Run the notify callback FOR and consume the current byte */
-#define CALLBACK_NOTIFY(FOR)            CALLBACK_NOTIFY_(FOR, p - data + 1)
-
-/* Run the notify callback FOR and don't consume the current byte */
-#define CALLBACK_NOTIFY_NOADVANCE(FOR)  CALLBACK_NOTIFY_(FOR, p - data)
-
-/* Run data callback FOR with LEN bytes, returning ER if it fails */
-#define CALLBACK_DATA_(FOR, LEN, ER)                                 \
-do {                                                                 \
-  assert(HTTP_PARSER_ERRNO(parser) == HPE_OK);                       \
-                                                                     \
-  if (FOR##_mark) {                                                  \
-    if (LIKELY(settings->on_##FOR)) {                                \
-      parser->state = CURRENT_STATE();                               \
-      if (UNLIKELY(0 !=                                              \
-                   settings->on_##FOR(parser, FOR##_mark, (LEN)))) { \
-        SET_ERRNO(HPE_CB_##FOR);                                     \
-      }                                                              \
-      UPDATE_STATE(parser->state);                                   \
-                                                                     \
-      /* We either errored above or got paused; get out */           \
-      if (UNLIKELY(HTTP_PARSER_ERRNO(parser) != HPE_OK)) {           \
-        return (ER);                                                 \
-      }                                                              \
-    }                                                                \
-    FOR##_mark = NULL;                                               \
-  }                                                                  \
-} while (0)
-
-/* Run the data callback FOR and consume the current byte */
-#define CALLBACK_DATA(FOR)                                           \
-    CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1)
-
-/* Run the data callback FOR and don't consume the current byte */
-#define CALLBACK_DATA_NOADVANCE(FOR)                                 \
-    CALLBACK_DATA_(FOR, p - FOR##_mark, p - data)
-
-/* Set the mark FOR; non-destructive if mark is already set */
-#define MARK(FOR)                                                    \
-do {                                                                 \
-  if (!FOR##_mark) {                                                 \
-    FOR##_mark = p;                                                  \
-  }                                                                  \
-} while (0)
-
-/* Don't allow the total size of the HTTP headers (including the status
- * line) to exceed HTTP_MAX_HEADER_SIZE.  This check is here to protect
- * embedders against denial-of-service attacks where the attacker feeds
- * us a never-ending header that the embedder keeps buffering.
- *
- * This check is arguably the responsibility of embedders but we're doing
- * it on the embedder's behalf because most won't bother and this way we
- * make the web a little safer.  HTTP_MAX_HEADER_SIZE is still far bigger
- * than any reasonable request or response so this should never affect
- * day-to-day operation.
- */
-#define COUNT_HEADER_SIZE(V)                                         \
-do {                                                                 \
-  parser->nread += (V);                                              \
-  if (UNLIKELY(parser->nread > (HTTP_MAX_HEADER_SIZE))) {            \
-    SET_ERRNO(HPE_HEADER_OVERFLOW);                                  \
-    goto error;                                                      \
-  }                                                                  \
-} while (0)
-
-
-#define PROXY_CONNECTION "proxy-connection"
-#define CONNECTION "connection"
-#define CONTENT_LENGTH "content-length"
-#define TRANSFER_ENCODING "transfer-encoding"
-#define UPGRADE "upgrade"
-#define CHUNKED "chunked"
-#define KEEP_ALIVE "keep-alive"
-#define CLOSE "close"
-
-
-static const char *method_strings[] =
-  {
-#define XX(num, name, string) #string,
-  HTTP_METHOD_MAP(XX)
-#undef XX
-  };
-
-
-/* Tokens as defined by rfc 2616. Also lowercases them.
- *        token       = 1*<any CHAR except CTLs or separators>
- *     separators     = "(" | ")" | "<" | ">" | "@"
- *                    | "," | ";" | ":" | "\" | <">
- *                    | "/" | "[" | "]" | "?" | "="
- *                    | "{" | "}" | SP | HT
- */
-static const char tokens[256] = {
-/*   0 nul    1 soh    2 stx    3 etx    4 eot    5 enq    6 ack    7 bel  */
-        0,       0,       0,       0,       0,       0,       0,       0,
-/*   8 bs     9 ht    10 nl    11 vt    12 np    13 cr    14 so    15 si   */
-        0,       0,       0,       0,       0,       0,       0,       0,
-/*  16 dle   17 dc1   18 dc2   19 dc3   20 dc4   21 nak   22 syn   23 etb */
-        0,       0,       0,       0,       0,       0,       0,       0,
-/*  24 can   25 em    26 sub   27 esc   28 fs    29 gs    30 rs    31 us  */
-        0,       0,       0,       0,       0,       0,       0,       0,
-/*  32 sp    33  !    34  "    35  #    36  $    37  %    38  &    39  '  */
-        0,      '!',      0,      '#',     '$',     '%',     '&',    '\'',
-/*  40  (    41  )    42  *    43  +    44  ,    45  -    46  .    47  /  */
-        0,       0,      '*',     '+',      0,      '-',     '.',      0,
-/*  48  0    49  1    50  2    51  3    52  4    53  5    54  6    55  7  */
-       '0',     '1',     '2',     '3',     '4',     '5',     '6',     '7',
-/*  56  8    57  9    58  :    59  ;    60  <    61  =    62  >    63  ?  */
-       '8',     '9',      0,       0,       0,       0,       0,       0,
-/*  64  @    65  A    66  B    67  C    68  D    69  E    70  F    71  G  */
-        0,      'a',     'b',     'c',     'd',     'e',     'f',     'g',
-/*  72  H    73  I    74  J    75  K    76  L    77  M    78  N    79  O  */
-       'h',     'i',     'j',     'k',     'l',     'm',     'n',     'o',
-/*  80  P    81  Q    82  R    83  S    84  T    85  U    86  V    87  W  */
-       'p',     'q',     'r',     's',     't',     'u',     'v',     'w',
-/*  88  X    89  Y    90  Z    91  [    92  \    93  ]    94  ^    95  _  */
-       'x',     'y',     'z',      0,       0,       0,      '^',     '_',
-/*  96  `    97  a    98  b    99  c   100  d   101  e   102  f   103  g  */
-       '`',     'a',     'b',     'c',     'd',     'e',     'f',     'g',
-/* 104  h   105  i   106  j   107  k   108  l   109  m   110  n   111  o  */
-       'h',     'i',     'j',     'k',     'l',     'm',     'n',     'o',
-/* 112  p   113  q   114  r   115  s   116  t   117  u   118  v   119  w  */
-       'p',     'q',     'r',     's',     't',     'u',     'v',     'w',
-/* 120  x   121  y   122  z   123  {   124  |   125  }   126  ~   127 del */
-       'x',     'y',     'z',      0,      '|',      0,      '~',       0 };
-
-
-static const int8_t unhex[256] =
-  {-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
-  ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
-  ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
-  , 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,-1,-1,-1,-1,-1,-1
-  ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
-  ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
-  ,-1,10,11,12,13,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1
-  ,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
-  };
-
-
-#if HTTP_PARSER_STRICT
-# define T(v) 0
-#else
-# define T(v) v
-#endif
-
-
-static const uint8_t normal_url_char[32] = {
-/*   0 nul    1 soh    2 stx    3 etx    4 eot    5 enq    6 ack    7 bel  */
-        0    |   0    |   0    |   0    |   0    |   0    |   0    |   0,
-/*   8 bs     9 ht    10 nl    11 vt    12 np    13 cr    14 so    15 si   */
-        0    | T(2)   |   0    |   0    | T(16)  |   0    |   0    |   0,
-/*  16 dle   17 dc1   18 dc2   19 dc3   20 dc4   21 nak   22 syn   23 etb */
-        0    |   0    |   0    |   0    |   0    |   0    |   0    |   0,
-/*  24 can   25 em    26 sub   27 esc   28 fs    29 gs    30 rs    31 us  */
-        0    |   0    |   0    |   0    |   0    |   0    |   0    |   0,
-/*  32 sp    33  !    34  "    35  #    36  $    37  %    38  &    39  '  */
-        0    |   2    |   4    |   0    |   16   |   32   |   64   |  128,
-/*  40  (    41  )    42  *    43  +    44  ,    45  -    46  .    47  /  */
-        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
-/*  48  0    49  1    50  2    51  3    52  4    53  5    54  6    55  7  */
-        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
-/*  56  8    57  9    58  :    59  ;    60  <    61  =    62  >    63  ?  */
-        1    |   2    |   4    |   8    |   16   |   32   |   64   |   0,
-/*  64  @    65  A    66  B    67  C    68  D    69  E    70  F    71  G  */
-        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
-/*  72  H    73  I    74  J    75  K    76  L    77  M    78  N    79  O  */
-        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
-/*  80  P    81  Q    82  R    83  S    84  T    85  U    86  V    87  W  */
-        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
-/*  88  X    89  Y    90  Z    91  [    92  \    93  ]    94  ^    95  _  */
-        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
-/*  96  `    97  a    98  b    99  c   100  d   101  e   102  f   103  g  */
-        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
-/* 104  h   105  i   106  j   107  k   108  l   109  m   110  n   111  o  */
-        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
-/* 112  p   113  q   114  r   115  s   116  t   117  u   118  v   119  w  */
-        1    |   2    |   4    |   8    |   16   |   32   |   64   |  128,
-/* 120  x   121  y   122  z   123  {   124  |   125  }   126  ~   127 del */
-        1    |   2    |   4    |   8    |   16   |   32   |   64   |   0, };
-
-#undef T
-
-enum state
-  { s_dead = 1 /* important that this is > 0 */
-
-  , s_start_req_or_res
-  , s_res_or_resp_H
-  , s_start_res
-  , s_res_H
-  , s_res_HT
-  , s_res_HTT
-  , s_res_HTTP
-  , s_res_first_http_major
-  , s_res_http_major
-  , s_res_first_http_minor
-  , s_res_http_minor
-  , s_res_first_status_code
-  , s_res_status_code
-  , s_res_status_start
-  , s_res_status
-  , s_res_line_almost_done
-
-  , s_start_req
-
-  , s_req_method
-  , s_req_spaces_before_url
-  , s_req_schema
-  , s_req_schema_slash
-  , s_req_schema_slash_slash
-  , s_req_server_start
-  , s_req_server
-  , s_req_server_with_at
-  , s_req_path
-  , s_req_query_string_start
-  , s_req_query_string
-  , s_req_fragment_start
-  , s_req_fragment
-  , s_req_http_start
-  , s_req_http_H
-  , s_req_http_HT
-  , s_req_http_HTT
-  , s_req_http_HTTP
-  , s_req_first_http_major
-  , s_req_http_major
-  , s_req_first_http_minor
-  , s_req_http_minor
-  , s_req_line_almost_done
-
-  , s_header_field_start
-  , s_header_field
-  , s_header_value_discard_ws
-  , s_header_value_discard_ws_almost_done
-  , s_header_value_discard_lws
-  , s_header_value_start
-  , s_header_value
-  , s_header_value_lws
-
-  , s_header_almost_done
-
-  , s_chunk_size_start
-  , s_chunk_size
-  , s_chunk_parameters
-  , s_chunk_size_almost_done
-
-  , s_headers_almost_done
-  , s_headers_done
-
-  /* Important: 's_headers_done' must be the last 'header' state. All
-   * states beyond this must be 'body' states. It is used for overflow
-   * checking. See the PARSING_HEADER() macro.
-   */
-
-  , s_chunk_data
-  , s_chunk_data_almost_done
-  , s_chunk_data_done
-
-  , s_body_identity
-  , s_body_identity_eof
-
-  , s_message_done
-  };
-
-
-#define PARSING_HEADER(state) (state <= s_headers_done)
-
-
-enum header_states
-  { h_general = 0
-  , h_C
-  , h_CO
-  , h_CON
-
-  , h_matching_connection
-  , h_matching_proxy_connection
-  , h_matching_content_length
-  , h_matching_transfer_encoding
-  , h_matching_upgrade
-
-  , h_connection
-  , h_content_length
-  , h_transfer_encoding
-  , h_upgrade
-
-  , h_matching_transfer_encoding_chunked
-  , h_matching_connection_token_start
-  , h_matching_connection_keep_alive
-  , h_matching_connection_close
-  , h_matching_connection_upgrade
-  , h_matching_connection_token
-
-  , h_transfer_encoding_chunked
-  , h_connection_keep_alive
-  , h_connection_close
-  , h_connection_upgrade
-  };
-
-enum http_host_state
-  {
-    s_http_host_dead = 1
-  , s_http_userinfo_start
-  , s_http_userinfo
-  , s_http_host_start
-  , s_http_host_v6_start
-  , s_http_host
-  , s_http_host_v6
-  , s_http_host_v6_end
-  , s_http_host_v6_zone_start
-  , s_http_host_v6_zone
-  , s_http_host_port_start
-  , s_http_host_port
-};
-
-/* Macros for character classes; depends on strict-mode  */
-#define CR                  '\r'
-#define LF                  '\n'
-#define LOWER(c)            (unsigned char)(c | 0x20)
-#define IS_ALPHA(c)         (LOWER(c) >= 'a' && LOWER(c) <= 'z')
-#define IS_NUM(c)           ((c) >= '0' && (c) <= '9')
-#define IS_ALPHANUM(c)      (IS_ALPHA(c) || IS_NUM(c))
-#define IS_HEX(c)           (IS_NUM(c) || (LOWER(c) >= 'a' && LOWER(c) <= 'f'))
-#define IS_MARK(c)          ((c) == '-' || (c) == '_' || (c) == '.' || \
-  (c) == '!' || (c) == '~' || (c) == '*' || (c) == '\'' || (c) == '(' || \
-  (c) == ')')
-#define IS_USERINFO_CHAR(c) (IS_ALPHANUM(c) || IS_MARK(c) || (c) == '%' || \
-  (c) == ';' || (c) == ':' || (c) == '&' || (c) == '=' || (c) == '+' || \
-  (c) == '$' || (c) == ',')
-
-#define STRICT_TOKEN(c)     (tokens[(unsigned char)c])
-
-#if HTTP_PARSER_STRICT
-#define TOKEN(c)            (tokens[(unsigned char)c])
-#define IS_URL_CHAR(c)      (BIT_AT(normal_url_char, (unsigned char)c))
-#define IS_HOST_CHAR(c)     (IS_ALPHANUM(c) || (c) == '.' || (c) == '-')
-#else
-#define TOKEN(c)            ((c == ' ') ? ' ' : tokens[(unsigned char)c])
-#define IS_URL_CHAR(c)                                                         \
-  (BIT_AT(normal_url_char, (unsigned char)c) || ((c) & 0x80))
-#define IS_HOST_CHAR(c)                                                        \
-  (IS_ALPHANUM(c) || (c) == '.' || (c) == '-' || (c) == '_')
-#endif
-
-/**
- * Verify that a char is a valid visible (printable) US-ASCII
- * character or %x80-FF
- **/
-#define IS_HEADER_CHAR(ch)                                                     \
-  (ch == CR || ch == LF || ch == 9 || ((unsigned char)ch > 31 && ch != 127))
-
-#define start_state (parser->type == HTTP_REQUEST ? s_start_req : s_start_res)
-
-
-#if HTTP_PARSER_STRICT
-# define STRICT_CHECK(cond)                                          \
-do {                                                                 \
-  if (cond) {                                                        \
-    SET_ERRNO(HPE_STRICT);                                           \
-    goto error;                                                      \
-  }                                                                  \
-} while (0)
-# define NEW_MESSAGE() (http_should_keep_alive(parser) ? start_state : s_dead)
-#else
-# define STRICT_CHECK(cond)
-# define NEW_MESSAGE() start_state
-#endif
-
-
-/* Map errno values to strings for human-readable output */
-#define HTTP_STRERROR_GEN(n, s) { "HPE_" #n, s },
-static struct {
-  const char *name;
-  const char *description;
-} http_strerror_tab[] = {
-  HTTP_ERRNO_MAP(HTTP_STRERROR_GEN)
-};
-#undef HTTP_STRERROR_GEN
-
-int http_message_needs_eof(const http_parser *parser);
-
-/* Our URL parser.
- *
- * This is designed to be shared by http_parser_execute() for URL validation,
- * hence it has a state transition + byte-for-byte interface. In addition, it
- * is meant to be embedded in http_parser_parse_url(), which does the dirty
- * work of turning state transitions URL components for its API.
- *
- * This function should only be invoked with non-space characters. It is
- * assumed that the caller cares about (and can detect) the transition between
- * URL and non-URL states by looking for these.
- */
-static enum state
-parse_url_char(enum state s, const char ch)
-{
-  if (ch == ' ' || ch == '\r' || ch == '\n') {
-    return s_dead;
-  }
-
-#if HTTP_PARSER_STRICT
-  if (ch == '\t' || ch == '\f') {
-    return s_dead;
-  }
-#endif
-
-  switch (s) {
-    case s_req_spaces_before_url:
-      /* Proxied requests are followed by scheme of an absolute URI (alpha).
-       * All methods except CONNECT are followed by '/' or '*'.
-       */
-
-      if (ch == '/' || ch == '*') {
-        return s_req_path;
-      }
-
-      if (IS_ALPHA(ch)) {
-        return s_req_schema;
-      }
-
-      break;
-
-    case s_req_schema:
-      if (IS_ALPHA(ch)) {
-        return s;
-      }
-
-      if (ch == ':') {
-        return s_req_schema_slash;
-      }
-
-      break;
-
-    case s_req_schema_slash:
-      if (ch == '/') {
-        return s_req_schema_slash_slash;
-      }
-
-      break;
-
-    case s_req_schema_slash_slash:
-      if (ch == '/') {
-        return s_req_server_start;
-      }
-
-      break;
-
-    case s_req_server_with_at:
-      if (ch == '@') {
-        return s_dead;
-      }
-
-    /* FALLTHROUGH */
-    case s_req_server_start:
-    case s_req_server:
-      if (ch == '/') {
-        return s_req_path;
-      }
-
-      if (ch == '?') {
-        return s_req_query_string_start;
-      }
-
-      if (ch == '@') {
-        return s_req_server_with_at;
-      }
-
-      if (IS_USERINFO_CHAR(ch) || ch == '[' || ch == ']') {
-        return s_req_server;
-      }
-
-      break;
-
-    case s_req_path:
-      if (IS_URL_CHAR(ch)) {
-        return s;
-      }
-
-      switch (ch) {
-        case '?':
-          return s_req_query_string_start;
-
-        case '#':
-          return s_req_fragment_start;
-      }
-
-      break;
-
-    case s_req_query_string_start:
-    case s_req_query_string:
-      if (IS_URL_CHAR(ch)) {
-        return s_req_query_string;
-      }
-
-      switch (ch) {
-        case '?':
-          /* allow extra '?' in query string */
-          return s_req_query_string;
-
-        case '#':
-          return s_req_fragment_start;
-      }
-
-      break;
-
-    case s_req_fragment_start:
-      if (IS_URL_CHAR(ch)) {
-        return s_req_fragment;
-      }
-
-      switch (ch) {
-        case '?':
-          return s_req_fragment;
-
-        case '#':
-          return s;
-      }
-
-      break;
-
-    case s_req_fragment:
-      if (IS_URL_CHAR(ch)) {
-        return s;
-      }
-
-      switch (ch) {
-        case '?':
-        case '#':
-          return s;
-      }
-
-      break;
-
-    default:
-      break;
-  }
-
-  /* We should never fall out of the switch above unless there's an error */
-  return s_dead;
-}
-
-size_t http_parser_execute (http_parser *parser,
-                            const http_parser_settings *settings,
-                            const char *data,
-                            size_t len)
-{
-  char c, ch;
-  int8_t unhex_val;
-  const char *p = data;
-  const char *header_field_mark = 0;
-  const char *header_value_mark = 0;
-  const char *url_mark = 0;
-  const char *body_mark = 0;
-  const char *status_mark = 0;
-  enum state p_state = (enum state) parser->state;
-  const unsigned int lenient = parser->lenient_http_headers;
-
-  /* We're in an error state. Don't bother doing anything. */
-  if (HTTP_PARSER_ERRNO(parser) != HPE_OK) {
-    return 0;
-  }
-
-  if (len == 0) {
-    switch (CURRENT_STATE()) {
-      case s_body_identity_eof:
-        /* Use of CALLBACK_NOTIFY() here would erroneously return 1 byte read if
-         * we got paused.
-         */
-        CALLBACK_NOTIFY_NOADVANCE(message_complete);
-        return 0;
-
-      case s_dead:
-      case s_start_req_or_res:
-      case s_start_res:
-      case s_start_req:
-        return 0;
-
-      default:
-        SET_ERRNO(HPE_INVALID_EOF_STATE);
-        return 1;
-    }
-  }
-
-
-  if (CURRENT_STATE() == s_header_field)
-    header_field_mark = data;
-  if (CURRENT_STATE() == s_header_value)
-    header_value_mark = data;
-  switch (CURRENT_STATE()) {
-  case s_req_path:
-  case s_req_schema:
-  case s_req_schema_slash:
-  case s_req_schema_slash_slash:
-  case s_req_server_start:
-  case s_req_server:
-  case s_req_server_with_at:
-  case s_req_query_string_start:
-  case s_req_query_string:
-  case s_req_fragment_start:
-  case s_req_fragment:
-    url_mark = data;
-    break;
-  case s_res_status:
-    status_mark = data;
-    break;
-  default:
-    break;
-  }
-
-  for (p=data; p != data + len; p++) {
-    ch = *p;
-
-    if (PARSING_HEADER(CURRENT_STATE()))
-      COUNT_HEADER_SIZE(1);
-
-reexecute:
-    switch (CURRENT_STATE()) {
-
-      case s_dead:
-        /* this state is used after a 'Connection: close' message
-         * the parser will error out if it reads another message
-         */
-        if (LIKELY(ch == CR || ch == LF))
-          break;
-
-        SET_ERRNO(HPE_CLOSED_CONNECTION);
-        goto error;
-
-      case s_start_req_or_res:
-      {
-        if (ch == CR || ch == LF)
-          break;
-        parser->flags = 0;
-        parser->content_length = ULLONG_MAX;
-
-        if (ch == 'H') {
-          UPDATE_STATE(s_res_or_resp_H);
-
-          CALLBACK_NOTIFY(message_begin);
-        } else {
-          parser->type = HTTP_REQUEST;
-          UPDATE_STATE(s_start_req);
-          REEXECUTE();
-        }
-
-        break;
-      }
-
-      case s_res_or_resp_H:
-        if (ch == 'T') {
-          parser->type = HTTP_RESPONSE;
-          UPDATE_STATE(s_res_HT);
-        } else {
-          if (UNLIKELY(ch != 'E')) {
-            SET_ERRNO(HPE_INVALID_CONSTANT);
-            goto error;
-          }
-
-          parser->type = HTTP_REQUEST;
-          parser->method = HTTP_HEAD;
-          parser->index = 2;
-          UPDATE_STATE(s_req_method);
-        }
-        break;
-
-      case s_start_res:
-      {
-        parser->flags = 0;
-        parser->content_length = ULLONG_MAX;
-
-        switch (ch) {
-          case 'H':
-            UPDATE_STATE(s_res_H);
-            break;
-
-          case CR:
-          case LF:
-            break;
-
-          default:
-            SET_ERRNO(HPE_INVALID_CONSTANT);
-            goto error;
-        }
-
-        CALLBACK_NOTIFY(message_begin);
-        break;
-      }
-
-      case s_res_H:
-        STRICT_CHECK(ch != 'T');
-        UPDATE_STATE(s_res_HT);
-        break;
-
-      case s_res_HT:
-        STRICT_CHECK(ch != 'T');
-        UPDATE_STATE(s_res_HTT);
-        break;
-
-      case s_res_HTT:
-        STRICT_CHECK(ch != 'P');
-        UPDATE_STATE(s_res_HTTP);
-        break;
-
-      case s_res_HTTP:
-        STRICT_CHECK(ch != '/');
-        UPDATE_STATE(s_res_first_http_major);
-        break;
-
-      case s_res_first_http_major:
-        if (UNLIKELY(ch < '0' || ch > '9')) {
-          SET_ERRNO(HPE_INVALID_VERSION);
-          goto error;
-        }
-
-        parser->http_major = ch - '0';
-        UPDATE_STATE(s_res_http_major);
-        break;
-
-      /* major HTTP version or dot */
-      case s_res_http_major:
-      {
-        if (ch == '.') {
-          UPDATE_STATE(s_res_first_http_minor);
-          break;
-        }
-
-        if (!IS_NUM(ch)) {
-          SET_ERRNO(HPE_INVALID_VERSION);
-          goto error;
-        }
-
-        parser->http_major *= 10;
-        parser->http_major += ch - '0';
-
-        if (UNLIKELY(parser->http_major > 999)) {
-          SET_ERRNO(HPE_INVALID_VERSION);
-          goto error;
-        }
-
-        break;
-      }
-
-      /* first digit of minor HTTP version */
-      case s_res_first_http_minor:
-        if (UNLIKELY(!IS_NUM(ch))) {
-          SET_ERRNO(HPE_INVALID_VERSION);
-          goto error;
-        }
-
-        parser->http_minor = ch - '0';
-        UPDATE_STATE(s_res_http_minor);
-        break;
-
-      /* minor HTTP version or end of request line */
-      case s_res_http_minor:
-      {
-        if (ch == ' ') {
-          UPDATE_STATE(s_res_first_status_code);
-          break;
-        }
-
-        if (UNLIKELY(!IS_NUM(ch))) {
-          SET_ERRNO(HPE_INVALID_VERSION);
-          goto error;
-        }
-
-        parser->http_minor *= 10;
-        parser->http_minor += ch - '0';
-
-        if (UNLIKELY(parser->http_minor > 999)) {
-          SET_ERRNO(HPE_INVALID_VERSION);
-          goto error;
-        }
-
-        break;
-      }
-
-      case s_res_first_status_code:
-      {
-        if (!IS_NUM(ch)) {
-          if (ch == ' ') {
-            break;
-          }
-
-          SET_ERRNO(HPE_INVALID_STATUS);
-          goto error;
-        }
-        parser->status_code = ch - '0';
-        UPDATE_STATE(s_res_status_code);
-        break;
-      }
-
-      case s_res_status_code:
-      {
-        if (!IS_NUM(ch)) {
-          switch (ch) {
-            case ' ':
-              UPDATE_STATE(s_res_status_start);
-              break;
-            case CR:
-              UPDATE_STATE(s_res_line_almost_done);
-              break;
-            case LF:
-              UPDATE_STATE(s_header_field_start);
-              break;
-            default:
-              SET_ERRNO(HPE_INVALID_STATUS);
-              goto error;
-          }
-          break;
-        }
-
-        parser->status_code *= 10;
-        parser->status_code += ch - '0';
-
-        if (UNLIKELY(parser->status_code > 999)) {
-          SET_ERRNO(HPE_INVALID_STATUS);
-          goto error;
-        }
-
-        break;
-      }
-
-      case s_res_status_start:
-      {
-        if (ch == CR) {
-          UPDATE_STATE(s_res_line_almost_done);
-          break;
-        }
-
-        if (ch == LF) {
-          UPDATE_STATE(s_header_field_start);
-          break;
-        }
-
-        MARK(status);
-        UPDATE_STATE(s_res_status);
-        parser->index = 0;
-        break;
-      }
-
-      case s_res_status:
-        if (ch == CR) {
-          UPDATE_STATE(s_res_line_almost_done);
-          CALLBACK_DATA(status);
-          break;
-        }
-
-        if (ch == LF) {
-          UPDATE_STATE(s_header_field_start);
-          CALLBACK_DATA(status);
-          break;
-        }
-
-        break;
-
-      case s_res_line_almost_done:
-        STRICT_CHECK(ch != LF);
-        UPDATE_STATE(s_header_field_start);
-        break;
-
-      case s_start_req:
-      {
-        if (ch == CR || ch == LF)
-          break;
-        parser->flags = 0;
-        parser->content_length = ULLONG_MAX;
-
-        if (UNLIKELY(!IS_ALPHA(ch))) {
-          SET_ERRNO(HPE_INVALID_METHOD);
-          goto error;
-        }
-
-        parser->method = (enum http_method) 0;
-        parser->index = 1;
-        switch (ch) {
-          case 'A': parser->method = HTTP_ACL; break;
-          case 'B': parser->method = HTTP_BIND; break;
-          case 'C': parser->method = HTTP_CONNECT; /* or COPY, CHECKOUT */ break;
-          case 'D': parser->method = HTTP_DELETE; break;
-          case 'G': parser->method = HTTP_GET; break;
-          case 'H': parser->method = HTTP_HEAD; break;
-          case 'L': parser->method = HTTP_LOCK; /* or LINK */ break;
-          case 'M': parser->method = HTTP_MKCOL; /* or MOVE, MKACTIVITY, MERGE, M-SEARCH, MKCALENDAR */ break;
-          case 'N': parser->method = HTTP_NOTIFY; break;
-          case 'O': parser->method = HTTP_OPTIONS; break;
-          case 'P': parser->method = HTTP_POST;
-            /* or PROPFIND|PROPPATCH|PUT|PATCH|PURGE */
-            break;
-          case 'R': parser->method = HTTP_REPORT; /* or REBIND */ break;
-          case 'S': parser->method = HTTP_SUBSCRIBE; /* or SEARCH */ break;
-          case 'T': parser->method = HTTP_TRACE; break;
-          case 'U': parser->method = HTTP_UNLOCK; /* or UNSUBSCRIBE, UNBIND, UNLINK */ break;
-          default:
-            SET_ERRNO(HPE_INVALID_METHOD);
-            goto error;
-        }
-        UPDATE_STATE(s_req_method);
-
-        CALLBACK_NOTIFY(message_begin);
-
-        break;
-      }
-
-      case s_req_method:
-      {
-        const char *matcher;
-        if (UNLIKELY(ch == '\0')) {
-          SET_ERRNO(HPE_INVALID_METHOD);
-          goto error;
-        }
-
-        matcher = method_strings[parser->method];
-        if (ch == ' ' && matcher[parser->index] == '\0') {
-          UPDATE_STATE(s_req_spaces_before_url);
-        } else if (ch == matcher[parser->index]) {
-          ; /* nada */
-        } else if (IS_ALPHA(ch)) {
-
-          switch (parser->method << 16 | parser->index << 8 | ch) {
-#define XX(meth, pos, ch, new_meth) \
-            case (HTTP_##meth << 16 | pos << 8 | ch): \
-              parser->method = HTTP_##new_meth; break;
-
-            XX(POST,      1, 'U', PUT)
-            XX(POST,      1, 'A', PATCH)
-            XX(CONNECT,   1, 'H', CHECKOUT)
-            XX(CONNECT,   2, 'P', COPY)
-            XX(MKCOL,     1, 'O', MOVE)
-            XX(MKCOL,     1, 'E', MERGE)
-            XX(MKCOL,     2, 'A', MKACTIVITY)
-            XX(MKCOL,     3, 'A', MKCALENDAR)
-            XX(SUBSCRIBE, 1, 'E', SEARCH)
-            XX(REPORT,    2, 'B', REBIND)
-            XX(POST,      1, 'R', PROPFIND)
-            XX(PROPFIND,  4, 'P', PROPPATCH)
-            XX(PUT,       2, 'R', PURGE)
-            XX(LOCK,      1, 'I', LINK)
-            XX(UNLOCK,    2, 'S', UNSUBSCRIBE)
-            XX(UNLOCK,    2, 'B', UNBIND)
-            XX(UNLOCK,    3, 'I', UNLINK)
-#undef XX
-
-            default:
-              SET_ERRNO(HPE_INVALID_METHOD);
-              goto error;
-          }
-        } else if (ch == '-' &&
-                   parser->index == 1 &&
-                   parser->method == HTTP_MKCOL) {
-          parser->method = HTTP_MSEARCH;
-        } else {
-          SET_ERRNO(HPE_INVALID_METHOD);
-          goto error;
-        }
-
-        ++parser->index;
-        break;
-      }
-
-      case s_req_spaces_before_url:
-      {
-        if (ch == ' ') break;
-
-        MARK(url);
-        if (parser->method == HTTP_CONNECT) {
-          UPDATE_STATE(s_req_server_start);
-        }
-
-        UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch));
-        if (UNLIKELY(CURRENT_STATE() == s_dead)) {
-          SET_ERRNO(HPE_INVALID_URL);
-          goto error;
-        }
-
-        break;
-      }
-
-      case s_req_schema:
-      case s_req_schema_slash:
-      case s_req_schema_slash_slash:
-      case s_req_server_start:
-      {
-        switch (ch) {
-          /* No whitespace allowed here */
-          case ' ':
-          case CR:
-          case LF:
-            SET_ERRNO(HPE_INVALID_URL);
-            goto error;
-          default:
-            UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch));
-            if (UNLIKELY(CURRENT_STATE() == s_dead)) {
-              SET_ERRNO(HPE_INVALID_URL);
-              goto error;
-            }
-        }
-
-        break;
-      }
-
-      case s_req_server:
-      case s_req_server_with_at:
-      case s_req_path:
-      case s_req_query_string_start:
-      case s_req_query_string:
-      case s_req_fragment_start:
-      case s_req_fragment:
-      {
-        switch (ch) {
-          case ' ':
-            UPDATE_STATE(s_req_http_start);
-            CALLBACK_DATA(url);
-            break;
-          case CR:
-          case LF:
-            parser->http_major = 0;
-            parser->http_minor = 9;
-            UPDATE_STATE((ch == CR) ?
-              s_req_line_almost_done :
-              s_header_field_start);
-            CALLBACK_DATA(url);
-            break;
-          default:
-            UPDATE_STATE(parse_url_char(CURRENT_STATE(), ch));
-            if (UNLIKELY(CURRENT_STATE() == s_dead)) {
-              SET_ERRNO(HPE_INVALID_URL);
-              goto error;
-            }
-        }
-        break;
-      }
-
-      case s_req_http_start:
-        switch (ch) {
-          case 'H':
-            UPDATE_STATE(s_req_http_H);
-            break;
-          case ' ':
-            break;
-          default:
-            SET_ERRNO(HPE_INVALID_CONSTANT);
-            goto error;
-        }
-        break;
-
-      case s_req_http_H:
-        STRICT_CHECK(ch != 'T');
-        UPDATE_STATE(s_req_http_HT);
-        break;
-
-      case s_req_http_HT:
-        STRICT_CHECK(ch != 'T');
-        UPDATE_STATE(s_req_http_HTT);
-        break;
-
-      case s_req_http_HTT:
-        STRICT_CHECK(ch != 'P');
-        UPDATE_STATE(s_req_http_HTTP);
-        break;
-
-      case s_req_http_HTTP:
-        STRICT_CHECK(ch != '/');
-        UPDATE_STATE(s_req_first_http_major);
-        break;
-
-      /* first digit of major HTTP version */
-      case s_req_first_http_major:
-        if (UNLIKELY(ch < '1' || ch > '9')) {
-          SET_ERRNO(HPE_INVALID_VERSION);
-          goto error;
-        }
-
-        parser->http_major = ch - '0';
-        UPDATE_STATE(s_req_http_major);
-        break;
-
-      /* major HTTP version or dot */
-      case s_req_http_major:
-      {
-        if (ch == '.') {
-          UPDATE_STATE(s_req_first_http_minor);
-          break;
-        }
-
-        if (UNLIKELY(!IS_NUM(ch))) {
-          SET_ERRNO(HPE_INVALID_VERSION);
-          goto error;
-        }
-
-        parser->http_major *= 10;
-        parser->http_major += ch - '0';
-
-        if (UNLIKELY(parser->http_major > 999)) {
-          SET_ERRNO(HPE_INVALID_VERSION);
-          goto error;
-        }
-
-        break;
-      }
-
-      /* first digit of minor HTTP version */
-      case s_req_first_http_minor:
-        if (UNLIKELY(!IS_NUM(ch))) {
-          SET_ERRNO(HPE_INVALID_VERSION);
-          goto error;
-        }
-
-        parser->http_minor = ch - '0';
-        UPDATE_STATE(s_req_http_minor);
-        break;
-
-      /* minor HTTP version or end of request line */
-      case s_req_http_minor:
-      {
-        if (ch == CR) {
-          UPDATE_STATE(s_req_line_almost_done);
-          break;
-        }
-
-        if (ch == LF) {
-          UPDATE_STATE(s_header_field_start);
-          break;
-        }
-
-        /* XXX allow spaces after digit? */
-
-        if (UNLIKELY(!IS_NUM(ch))) {
-          SET_ERRNO(HPE_INVALID_VERSION);
-          goto error;
-        }
-
-        parser->http_minor *= 10;
-        parser->http_minor += ch - '0';
-
-        if (UNLIKELY(parser->http_minor > 999)) {
-          SET_ERRNO(HPE_INVALID_VERSION);
-          goto error;
-        }
-
-        break;
-      }
-
-      /* end of request line */
-      case s_req_line_almost_done:
-      {
-        if (UNLIKELY(ch != LF)) {
-          SET_ERRNO(HPE_LF_EXPECTED);
-          goto error;
-        }
-
-        UPDATE_STATE(s_header_field_start);
-        break;
-      }
-
-      case s_header_field_start:
-      {
-        if (ch == CR) {
-          UPDATE_STATE(s_headers_almost_done);
-          break;
-        }
-
-        if (ch == LF) {
-          /* they might be just sending \n instead of \r\n so this would be
-           * the second \n to denote the end of headers*/
-          UPDATE_STATE(s_headers_almost_done);
-          REEXECUTE();
-        }
-
-        c = TOKEN(ch);
-
-        if (UNLIKELY(!c)) {
-          SET_ERRNO(HPE_INVALID_HEADER_TOKEN);
-          goto error;
-        }
-
-        MARK(header_field);
-
-        parser->index = 0;
-        UPDATE_STATE(s_header_field);
-
-        switch (c) {
-          case 'c':
-            parser->header_state = h_C;
-            break;
-
-          case 'p':
-            parser->header_state = h_matching_proxy_connection;
-            break;
-
-          case 't':
-            parser->header_state = h_matching_transfer_encoding;
-            break;
-
-          case 'u':
-            parser->header_state = h_matching_upgrade;
-            break;
-
-          default:
-            parser->header_state = h_general;
-            break;
-        }
-        break;
-      }
-
-      case s_header_field:
-      {
-        const char* start = p;
-        for (; p != data + len; p++) {
-          ch = *p;
-          c = TOKEN(ch);
-
-          if (!c)
-            break;
-
-          switch (parser->header_state) {
-            case h_general:
-              break;
-
-            case h_C:
-              parser->index++;
-              parser->header_state = (c == 'o' ? h_CO : h_general);
-              break;
-
-            case h_CO:
-              parser->index++;
-              parser->header_state = (c == 'n' ? h_CON : h_general);
-              break;
-
-            case h_CON:
-              parser->index++;
-              switch (c) {
-                case 'n':
-                  parser->header_state = h_matching_connection;
-                  break;
-                case 't':
-                  parser->header_state = h_matching_content_length;
-                  break;
-                default:
-                  parser->header_state = h_general;
-                  break;
-              }
-              break;
-
-            /* connection */
-
-            case h_matching_connection:
-              parser->index++;
-              if (parser->index > sizeof(CONNECTION)-1
-                  || c != CONNECTION[parser->index]) {
-                parser->header_state = h_general;
-              } else if (parser->index == sizeof(CONNECTION)-2) {
-                parser->header_state = h_connection;
-              }
-              break;
-
-            /* proxy-connection */
-
-            case h_matching_proxy_connection:
-              parser->index++;
-              if (parser->index > sizeof(PROXY_CONNECTION)-1
-                  || c != PROXY_CONNECTION[parser->index]) {
-                parser->header_state = h_general;
-              } else if (parser->index == sizeof(PROXY_CONNECTION)-2) {
-                parser->header_state = h_connection;
-              }
-              break;
-
-            /* content-length */
-
-            case h_matching_content_length:
-              parser->index++;
-              if (parser->index > sizeof(CONTENT_LENGTH)-1
-                  || c != CONTENT_LENGTH[parser->index]) {
-                parser->header_state = h_general;
-              } else if (parser->index == sizeof(CONTENT_LENGTH)-2) {
-                parser->header_state = h_content_length;
-              }
-              break;
-
-            /* transfer-encoding */
-
-            case h_matching_transfer_encoding:
-              parser->index++;
-              if (parser->index > sizeof(TRANSFER_ENCODING)-1
-                  || c != TRANSFER_ENCODING[parser->index]) {
-                parser->header_state = h_general;
-              } else if (parser->index == sizeof(TRANSFER_ENCODING)-2) {
-                parser->header_state = h_transfer_encoding;
-              }
-              break;
-
-            /* upgrade */
-
-            case h_matching_upgrade:
-              parser->index++;
-              if (parser->index > sizeof(UPGRADE)-1
-                  || c != UPGRADE[parser->index]) {
-                parser->header_state = h_general;
-              } else if (parser->index == sizeof(UPGRADE)-2) {
-                parser->header_state = h_upgrade;
-              }
-              break;
-
-            case h_connection:
-            case h_content_length:
-            case h_transfer_encoding:
-            case h_upgrade:
-              if (ch != ' ') parser->header_state = h_general;
-              break;
-
-            default:
-              assert(0 && "Unknown header_state");
-              break;
-          }
-        }
-
-        COUNT_HEADER_SIZE(p - start);
-
-        if (p == data + len) {
-          --p;
-          break;
-        }
-
-        if (ch == ':') {
-          UPDATE_STATE(s_header_value_discard_ws);
-          CALLBACK_DATA(header_field);
-          break;
-        }
-
-        SET_ERRNO(HPE_INVALID_HEADER_TOKEN);
-        goto error;
-      }
-
-      case s_header_value_discard_ws:
-        if (ch == ' ' || ch == '\t') break;
-
-        if (ch == CR) {
-          UPDATE_STATE(s_header_value_discard_ws_almost_done);
-          break;
-        }
-
-        if (ch == LF) {
-          UPDATE_STATE(s_header_value_discard_lws);
-          break;
-        }
-
-        /* FALLTHROUGH */
-
-      case s_header_value_start:
-      {
-        MARK(header_value);
-
-        UPDATE_STATE(s_header_value);
-        parser->index = 0;
-
-        c = LOWER(ch);
-
-        switch (parser->header_state) {
-          case h_upgrade:
-            parser->flags |= F_UPGRADE;
-            parser->header_state = h_general;
-            break;
-
-          case h_transfer_encoding:
-            /* looking for 'Transfer-Encoding: chunked' */
-            if ('c' == c) {
-              parser->header_state = h_matching_transfer_encoding_chunked;
-            } else {
-              parser->header_state = h_general;
-            }
-            break;
-
-          case h_content_length:
-            if (UNLIKELY(!IS_NUM(ch))) {
-              SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
-              goto error;
-            }
-
-            if (parser->flags & F_CONTENTLENGTH) {
-              SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH);
-              goto error;
-            }
-
-            parser->flags |= F_CONTENTLENGTH;
-            parser->content_length = ch - '0';
-            break;
-
-          case h_connection:
-            /* looking for 'Connection: keep-alive' */
-            if (c == 'k') {
-              parser->header_state = h_matching_connection_keep_alive;
-            /* looking for 'Connection: close' */
-            } else if (c == 'c') {
-              parser->header_state = h_matching_connection_close;
-            } else if (c == 'u') {
-              parser->header_state = h_matching_connection_upgrade;
-            } else {
-              parser->header_state = h_matching_connection_token;
-            }
-            break;
-
-          /* Multi-value `Connection` header */
-          case h_matching_connection_token_start:
-            break;
-
-          default:
-            parser->header_state = h_general;
-            break;
-        }
-        break;
-      }
-
-      case s_header_value:
-      {
-        const char* start = p;
-        enum header_states h_state = (enum header_states) parser->header_state;
-        for (; p != data + len; p++) {
-          ch = *p;
-          if (ch == CR) {
-            UPDATE_STATE(s_header_almost_done);
-            parser->header_state = h_state;
-            CALLBACK_DATA(header_value);
-            break;
-          }
-
-          if (ch == LF) {
-            UPDATE_STATE(s_header_almost_done);
-            COUNT_HEADER_SIZE(p - start);
-            parser->header_state = h_state;
-            CALLBACK_DATA_NOADVANCE(header_value);
-            REEXECUTE();
-          }
-
-          if (!lenient && !IS_HEADER_CHAR(ch)) {
-            SET_ERRNO(HPE_INVALID_HEADER_TOKEN);
-            goto error;
-          }
-
-          c = LOWER(ch);
-
-          switch (h_state) {
-            case h_general:
-            {
-              const char* p_cr;
-              const char* p_lf;
-              size_t limit = data + len - p;
-
-              limit = MIN(limit, HTTP_MAX_HEADER_SIZE);
-
-              p_cr = (const char*) memchr(p, CR, limit);
-              p_lf = (const char*) memchr(p, LF, limit);
-              if (p_cr != NULL) {
-                if (p_lf != NULL && p_cr >= p_lf)
-                  p = p_lf;
-                else
-                  p = p_cr;
-              } else if (UNLIKELY(p_lf != NULL)) {
-                p = p_lf;
-              } else {
-                p = data + len;
-              }
-              --p;
-
-              break;
-            }
-
-            case h_connection:
-            case h_transfer_encoding:
-              assert(0 && "Shouldn't get here.");
-              break;
-
-            case h_content_length:
-            {
-              uint64_t t;
-
-              if (ch == ' ') break;
-
-              if (UNLIKELY(!IS_NUM(ch))) {
-                SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
-                parser->header_state = h_state;
-                goto error;
-              }
-
-              t = parser->content_length;
-              t *= 10;
-              t += ch - '0';
-
-              /* Overflow? Test against a conservative limit for simplicity. */
-              if (UNLIKELY((ULLONG_MAX - 10) / 10 < parser->content_length)) {
-                SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
-                parser->header_state = h_state;
-                goto error;
-              }
-
-              parser->content_length = t;
-              break;
-            }
-
-            /* Transfer-Encoding: chunked */
-            case h_matching_transfer_encoding_chunked:
-              parser->index++;
-              if (parser->index > sizeof(CHUNKED)-1
-                  || c != CHUNKED[parser->index]) {
-                h_state = h_general;
-              } else if (parser->index == sizeof(CHUNKED)-2) {
-                h_state = h_transfer_encoding_chunked;
-              }
-              break;
-
-            case h_matching_connection_token_start:
-              /* looking for 'Connection: keep-alive' */
-              if (c == 'k') {
-                h_state = h_matching_connection_keep_alive;
-              /* looking for 'Connection: close' */
-              } else if (c == 'c') {
-                h_state = h_matching_connection_close;
-              } else if (c == 'u') {
-                h_state = h_matching_connection_upgrade;
-              } else if (STRICT_TOKEN(c)) {
-                h_state = h_matching_connection_token;
-              } else if (c == ' ' || c == '\t') {
-                /* Skip lws */
-              } else {
-                h_state = h_general;
-              }
-              break;
-
-            /* looking for 'Connection: keep-alive' */
-            case h_matching_connection_keep_alive:
-              parser->index++;
-              if (parser->index > sizeof(KEEP_ALIVE)-1
-                  || c != KEEP_ALIVE[parser->index]) {
-                h_state = h_matching_connection_token;
-              } else if (parser->index == sizeof(KEEP_ALIVE)-2) {
-                h_state = h_connection_keep_alive;
-              }
-              break;
-
-            /* looking for 'Connection: close' */
-            case h_matching_connection_close:
-              parser->index++;
-              if (parser->index > sizeof(CLOSE)-1 || c != CLOSE[parser->index]) {
-                h_state = h_matching_connection_token;
-              } else if (parser->index == sizeof(CLOSE)-2) {
-                h_state = h_connection_close;
-              }
-              break;
-
-            /* looking for 'Connection: upgrade' */
-            case h_matching_connection_upgrade:
-              parser->index++;
-              if (parser->index > sizeof(UPGRADE) - 1 ||
-                  c != UPGRADE[parser->index]) {
-                h_state = h_matching_connection_token;
-              } else if (parser->index == sizeof(UPGRADE)-2) {
-                h_state = h_connection_upgrade;
-              }
-              break;
-
-            case h_matching_connection_token:
-              if (ch == ',') {
-                h_state = h_matching_connection_token_start;
-                parser->index = 0;
-              }
-              break;
-
-            case h_transfer_encoding_chunked:
-              if (ch != ' ') h_state = h_general;
-              break;
-
-            case h_connection_keep_alive:
-            case h_connection_close:
-            case h_connection_upgrade:
-              if (ch == ',') {
-                if (h_state == h_connection_keep_alive) {
-                  parser->flags |= F_CONNECTION_KEEP_ALIVE;
-                } else if (h_state == h_connection_close) {
-                  parser->flags |= F_CONNECTION_CLOSE;
-                } else if (h_state == h_connection_upgrade) {
-                  parser->flags |= F_CONNECTION_UPGRADE;
-                }
-                h_state = h_matching_connection_token_start;
-                parser->index = 0;
-              } else if (ch != ' ') {
-                h_state = h_matching_connection_token;
-              }
-              break;
-
-            default:
-              UPDATE_STATE(s_header_value);
-              h_state = h_general;
-              break;
-          }
-        }
-        parser->header_state = h_state;
-
-        COUNT_HEADER_SIZE(p - start);
-
-        if (p == data + len)
-          --p;
-        break;
-      }
-
-      case s_header_almost_done:
-      {
-        if (UNLIKELY(ch != LF)) {
-          SET_ERRNO(HPE_LF_EXPECTED);
-          goto error;
-        }
-
-        UPDATE_STATE(s_header_value_lws);
-        break;
-      }
-
-      case s_header_value_lws:
-      {
-        if (ch == ' ' || ch == '\t') {
-          UPDATE_STATE(s_header_value_start);
-          REEXECUTE();
-        }
-
-        /* finished the header */
-        switch (parser->header_state) {
-          case h_connection_keep_alive:
-            parser->flags |= F_CONNECTION_KEEP_ALIVE;
-            break;
-          case h_connection_close:
-            parser->flags |= F_CONNECTION_CLOSE;
-            break;
-          case h_transfer_encoding_chunked:
-            parser->flags |= F_CHUNKED;
-            break;
-          case h_connection_upgrade:
-            parser->flags |= F_CONNECTION_UPGRADE;
-            break;
-          default:
-            break;
-        }
-
-        UPDATE_STATE(s_header_field_start);
-        REEXECUTE();
-      }
-
-      case s_header_value_discard_ws_almost_done:
-      {
-        STRICT_CHECK(ch != LF);
-        UPDATE_STATE(s_header_value_discard_lws);
-        break;
-      }
-
-      case s_header_value_discard_lws:
-      {
-        if (ch == ' ' || ch == '\t') {
-          UPDATE_STATE(s_header_value_discard_ws);
-          break;
-        } else {
-          switch (parser->header_state) {
-            case h_connection_keep_alive:
-              parser->flags |= F_CONNECTION_KEEP_ALIVE;
-              break;
-            case h_connection_close:
-              parser->flags |= F_CONNECTION_CLOSE;
-              break;
-            case h_connection_upgrade:
-              parser->flags |= F_CONNECTION_UPGRADE;
-              break;
-            case h_transfer_encoding_chunked:
-              parser->flags |= F_CHUNKED;
-              break;
-            default:
-              break;
-          }
-
-          /* header value was empty */
-          MARK(header_value);
-          UPDATE_STATE(s_header_field_start);
-          CALLBACK_DATA_NOADVANCE(header_value);
-          REEXECUTE();
-        }
-      }
-
-      case s_headers_almost_done:
-      {
-        STRICT_CHECK(ch != LF);
-
-        if (parser->flags & F_TRAILING) {
-          /* End of a chunked request */
-          UPDATE_STATE(s_message_done);
-          CALLBACK_NOTIFY_NOADVANCE(chunk_complete);
-          REEXECUTE();
-        }
-
-        /* Cannot use chunked encoding and a content-length header together
-           per the HTTP specification. */
-        if ((parser->flags & F_CHUNKED) &&
-            (parser->flags & F_CONTENTLENGTH)) {
-          SET_ERRNO(HPE_UNEXPECTED_CONTENT_LENGTH);
-          goto error;
-        }
-
-        UPDATE_STATE(s_headers_done);
-
-        /* Set this here so that on_headers_complete() callbacks can see it */
-        parser->upgrade =
-          ((parser->flags & (F_UPGRADE | F_CONNECTION_UPGRADE)) ==
-           (F_UPGRADE | F_CONNECTION_UPGRADE) ||
-           parser->method == HTTP_CONNECT);
-
-        /* Here we call the headers_complete callback. This is somewhat
-         * different than other callbacks because if the user returns 1, we
-         * will interpret that as saying that this message has no body. This
-         * is needed for the annoying case of recieving a response to a HEAD
-         * request.
-         *
-         * We'd like to use CALLBACK_NOTIFY_NOADVANCE() here but we cannot, so
-         * we have to simulate it by handling a change in errno below.
-         */
-        if (settings->on_headers_complete) {
-          switch (settings->on_headers_complete(parser)) {
-            case 0:
-              break;
-
-            case 2:
-              parser->upgrade = 1;
-
-            case 1:
-              parser->flags |= F_SKIPBODY;
-              break;
-
-            default:
-              SET_ERRNO(HPE_CB_headers_complete);
-              RETURN(p - data); /* Error */
-          }
-        }
-
-        if (HTTP_PARSER_ERRNO(parser) != HPE_OK) {
-          RETURN(p - data);
-        }
-
-        REEXECUTE();
-      }
-
-      case s_headers_done:
-      {
-        int hasBody;
-        STRICT_CHECK(ch != LF);
-
-        parser->nread = 0;
-
-        hasBody = parser->flags & F_CHUNKED ||
-          (parser->content_length > 0 && parser->content_length != ULLONG_MAX);
-        if (parser->upgrade && (parser->method == HTTP_CONNECT ||
-                                (parser->flags & F_SKIPBODY) || !hasBody)) {
-          /* Exit, the rest of the message is in a different protocol. */
-          UPDATE_STATE(NEW_MESSAGE());
-          CALLBACK_NOTIFY(message_complete);
-          RETURN((p - data) + 1);
-        }
-
-        if (parser->flags & F_SKIPBODY) {
-          UPDATE_STATE(NEW_MESSAGE());
-          CALLBACK_NOTIFY(message_complete);
-        } else if (parser->flags & F_CHUNKED) {
-          /* chunked encoding - ignore Content-Length header */
-          UPDATE_STATE(s_chunk_size_start);
-        } else {
-          if (parser->content_length == 0) {
-            /* Content-Length header given but zero: Content-Length: 0\r\n */
-            UPDATE_STATE(NEW_MESSAGE());
-            CALLBACK_NOTIFY(message_complete);
-          } else if (parser->content_length != ULLONG_MAX) {
-            /* Content-Length header given and non-zero */
-            UPDATE_STATE(s_body_identity);
-          } else {
-            if (!http_message_needs_eof(parser)) {
-              /* Assume content-length 0 - read the next */
-              UPDATE_STATE(NEW_MESSAGE());
-              CALLBACK_NOTIFY(message_complete);
-            } else {
-              /* Read body until EOF */
-              UPDATE_STATE(s_body_identity_eof);
-            }
-          }
-        }
-
-        break;
-      }
-
-      case s_body_identity:
-      {
-        uint64_t to_read = MIN(parser->content_length,
-                               (uint64_t) ((data + len) - p));
-
-        assert(parser->content_length != 0
-            && parser->content_length != ULLONG_MAX);
-
-        /* The difference between advancing content_length and p is because
-         * the latter will automaticaly advance on the next loop iteration.
-         * Further, if content_length ends up at 0, we want to see the last
-         * byte again for our message complete callback.
-         */
-        MARK(body);
-        parser->content_length -= to_read;
-        p += to_read - 1;
-
-        if (parser->content_length == 0) {
-          UPDATE_STATE(s_message_done);
-
-          /* Mimic CALLBACK_DATA_NOADVANCE() but with one extra byte.
-           *
-           * The alternative to doing this is to wait for the next byte to
-           * trigger the data callback, just as in every other case. The
-           * problem with this is that this makes it difficult for the test
-           * harness to distinguish between complete-on-EOF and
-           * complete-on-length. It's not clear that this distinction is
-           * important for applications, but let's keep it for now.
-           */
-          CALLBACK_DATA_(body, p - body_mark + 1, p - data);
-          REEXECUTE();
-        }
-
-        break;
-      }
-
-      /* read until EOF */
-      case s_body_identity_eof:
-        MARK(body);
-        p = data + len - 1;
-
-        break;
-
-      case s_message_done:
-        UPDATE_STATE(NEW_MESSAGE());
-        CALLBACK_NOTIFY(message_complete);
-        if (parser->upgrade) {
-          /* Exit, the rest of the message is in a different protocol. */
-          RETURN((p - data) + 1);
-        }
-        break;
-
-      case s_chunk_size_start:
-      {
-        assert(parser->nread == 1);
-        assert(parser->flags & F_CHUNKED);
-
-        unhex_val = unhex[(unsigned char)ch];
-        if (UNLIKELY(unhex_val == -1)) {
-          SET_ERRNO(HPE_INVALID_CHUNK_SIZE);
-          goto error;
-        }
-
-        parser->content_length = unhex_val;
-        UPDATE_STATE(s_chunk_size);
-        break;
-      }
-
-      case s_chunk_size:
-      {
-        uint64_t t;
-
-        assert(parser->flags & F_CHUNKED);
-
-        if (ch == CR) {
-          UPDATE_STATE(s_chunk_size_almost_done);
-          break;
-        }
-
-        unhex_val = unhex[(unsigned char)ch];
-
-        if (unhex_val == -1) {
-          if (ch == ';' || ch == ' ') {
-            UPDATE_STATE(s_chunk_parameters);
-            break;
-          }
-
-          SET_ERRNO(HPE_INVALID_CHUNK_SIZE);
-          goto error;
-        }
-
-        t = parser->content_length;
-        t *= 16;
-        t += unhex_val;
-
-        /* Overflow? Test against a conservative limit for simplicity. */
-        if (UNLIKELY((ULLONG_MAX - 16) / 16 < parser->content_length)) {
-          SET_ERRNO(HPE_INVALID_CONTENT_LENGTH);
-          goto error;
-        }
-
-        parser->content_length = t;
-        break;
-      }
-
-      case s_chunk_parameters:
-      {
-        assert(parser->flags & F_CHUNKED);
-        /* just ignore this shit. TODO check for overflow */
-        if (ch == CR) {
-          UPDATE_STATE(s_chunk_size_almost_done);
-          break;
-        }
-        break;
-      }
-
-      case s_chunk_size_almost_done:
-      {
-        assert(parser->flags & F_CHUNKED);
-        STRICT_CHECK(ch != LF);
-
-        parser->nread = 0;
-
-        if (parser->content_length == 0) {
-          parser->flags |= F_TRAILING;
-          UPDATE_STATE(s_header_field_start);
-        } else {
-          UPDATE_STATE(s_chunk_data);
-        }
-        CALLBACK_NOTIFY(chunk_header);
-        break;
-      }
-
-      case s_chunk_data:
-      {
-        uint64_t to_read = MIN(parser->content_length,
-                               (uint64_t) ((data + len) - p));
-
-        assert(parser->flags & F_CHUNKED);
-        assert(parser->content_length != 0
-            && parser->content_length != ULLONG_MAX);
-
-        /* See the explanation in s_body_identity for why the content
-         * length and data pointers are managed this way.
-         */
-        MARK(body);
-        parser->content_length -= to_read;
-        p += to_read - 1;
-
-        if (parser->content_length == 0) {
-          UPDATE_STATE(s_chunk_data_almost_done);
-        }
-
-        break;
-      }
-
-      case s_chunk_data_almost_done:
-        assert(parser->flags & F_CHUNKED);
-        assert(parser->content_length == 0);
-        STRICT_CHECK(ch != CR);
-        UPDATE_STATE(s_chunk_data_done);
-        CALLBACK_DATA(body);
-        break;
-
-      case s_chunk_data_done:
-        assert(parser->flags & F_CHUNKED);
-        STRICT_CHECK(ch != LF);
-        parser->nread = 0;
-        UPDATE_STATE(s_chunk_size_start);
-        CALLBACK_NOTIFY(chunk_complete);
-        break;
-
-      default:
-        assert(0 && "unhandled state");
-        SET_ERRNO(HPE_INVALID_INTERNAL_STATE);
-        goto error;
-    }
-  }
-
-  /* Run callbacks for any marks that we have leftover after we ran our of
-   * bytes. There should be at most one of these set, so it's OK to invoke
-   * them in series (unset marks will not result in callbacks).
-   *
-   * We use the NOADVANCE() variety of callbacks here because 'p' has already
-   * overflowed 'data' and this allows us to correct for the off-by-one that
-   * we'd otherwise have (since CALLBACK_DATA() is meant to be run with a 'p'
-   * value that's in-bounds).
-   */
-
-  assert(((header_field_mark ? 1 : 0) +
-          (header_value_mark ? 1 : 0) +
-          (url_mark ? 1 : 0)  +
-          (body_mark ? 1 : 0) +
-          (status_mark ? 1 : 0)) <= 1);
-
-  CALLBACK_DATA_NOADVANCE(header_field);
-  CALLBACK_DATA_NOADVANCE(header_value);
-  CALLBACK_DATA_NOADVANCE(url);
-  CALLBACK_DATA_NOADVANCE(body);
-  CALLBACK_DATA_NOADVANCE(status);
-
-  RETURN(len);
-
-error:
-  if (HTTP_PARSER_ERRNO(parser) == HPE_OK) {
-    SET_ERRNO(HPE_UNKNOWN);
-  }
-
-  RETURN(p - data);
-}
-
-
-/* Does the parser need to see an EOF to find the end of the message? */
-int
-http_message_needs_eof (const http_parser *parser)
-{
-  if (parser->type == HTTP_REQUEST) {
-    return 0;
-  }
-
-  /* See RFC 2616 section 4.4 */
-  if (parser->status_code / 100 == 1 || /* 1xx e.g. Continue */
-      parser->status_code == 204 ||     /* No Content */
-      parser->status_code == 304 ||     /* Not Modified */
-      parser->flags & F_SKIPBODY) {     /* response to a HEAD request */
-    return 0;
-  }
-
-  if ((parser->flags & F_CHUNKED) || parser->content_length != ULLONG_MAX) {
-    return 0;
-  }
-
-  return 1;
-}
-
-
-int
-http_should_keep_alive (const http_parser *parser)
-{
-  if (parser->http_major > 0 && parser->http_minor > 0) {
-    /* HTTP/1.1 */
-    if (parser->flags & F_CONNECTION_CLOSE) {
-      return 0;
-    }
-  } else {
-    /* HTTP/1.0 or earlier */
-    if (!(parser->flags & F_CONNECTION_KEEP_ALIVE)) {
-      return 0;
-    }
-  }
-
-  return !http_message_needs_eof(parser);
-}
-
-
-const char *
-http_method_str (enum http_method m)
-{
-  return ELEM_AT(method_strings, m, "<unknown>");
-}
-
-
-void
-http_parser_init (http_parser *parser, enum http_parser_type t)
-{
-  void *data = parser->data; /* preserve application data */
-  memset(parser, 0, sizeof(*parser));
-  parser->data = data;
-  parser->type = t;
-  parser->state = (t == HTTP_REQUEST ? s_start_req : (t == HTTP_RESPONSE ? s_start_res : s_start_req_or_res));
-  parser->http_errno = HPE_OK;
-}
-
-void
-http_parser_settings_init(http_parser_settings *settings)
-{
-  memset(settings, 0, sizeof(*settings));
-}
-
-const char *
-http_errno_name(enum http_errno err) {
-  assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab));
-  return http_strerror_tab[err].name;
-}
-
-const char *
-http_errno_description(enum http_errno err) {
-  assert(((size_t) err) < ARRAY_SIZE(http_strerror_tab));
-  return http_strerror_tab[err].description;
-}
-
-static enum http_host_state
-http_parse_host_char(enum http_host_state s, const char ch) {
-  switch(s) {
-    case s_http_userinfo:
-    case s_http_userinfo_start:
-      if (ch == '@') {
-        return s_http_host_start;
-      }
-
-      if (IS_USERINFO_CHAR(ch)) {
-        return s_http_userinfo;
-      }
-      break;
-
-    case s_http_host_start:
-      if (ch == '[') {
-        return s_http_host_v6_start;
-      }
-
-      if (IS_HOST_CHAR(ch)) {
-        return s_http_host;
-      }
-
-      break;
-
-    case s_http_host:
-      if (IS_HOST_CHAR(ch)) {
-        return s_http_host;
-      }
-
-    /* FALLTHROUGH */
-    case s_http_host_v6_end:
-      if (ch == ':') {
-        return s_http_host_port_start;
-      }
-
-      break;
-
-    case s_http_host_v6:
-      if (ch == ']') {
-        return s_http_host_v6_end;
-      }
-
-    /* FALLTHROUGH */
-    case s_http_host_v6_start:
-      if (IS_HEX(ch) || ch == ':' || ch == '.') {
-        return s_http_host_v6;
-      }
-
-      if (s == s_http_host_v6 && ch == '%') {
-        return s_http_host_v6_zone_start;
-      }
-      break;
-
-    case s_http_host_v6_zone:
-      if (ch == ']') {
-        return s_http_host_v6_end;
-      }
-
-    /* FALLTHROUGH */
-    case s_http_host_v6_zone_start:
-      /* RFC 6874 Zone ID consists of 1*( unreserved / pct-encoded) */
-      if (IS_ALPHANUM(ch) || ch == '%' || ch == '.' || ch == '-' || ch == '_' ||
-          ch == '~') {
-        return s_http_host_v6_zone;
-      }
-      break;
-
-    case s_http_host_port:
-    case s_http_host_port_start:
-      if (IS_NUM(ch)) {
-        return s_http_host_port;
-      }
-
-      break;
-
-    default:
-      break;
-  }
-  return s_http_host_dead;
-}
-
-static int
-http_parse_host(const char * buf, struct http_parser_url *u, int found_at) {
-  enum http_host_state s;
-
-  const char *p;
-  size_t buflen = u->field_data[UF_HOST].off + u->field_data[UF_HOST].len;
-
-  assert(u->field_set & (1 << UF_HOST));
-
-  u->field_data[UF_HOST].len = 0;
-
-  s = found_at ? s_http_userinfo_start : s_http_host_start;
-
-  for (p = buf + u->field_data[UF_HOST].off; p < buf + buflen; p++) {
-    enum http_host_state new_s = http_parse_host_char(s, *p);
-
-    if (new_s == s_http_host_dead) {
-      return 1;
-    }
-
-    switch(new_s) {
-      case s_http_host:
-        if (s != s_http_host) {
-          u->field_data[UF_HOST].off = p - buf;
-        }
-        u->field_data[UF_HOST].len++;
-        break;
-
-      case s_http_host_v6:
-        if (s != s_http_host_v6) {
-          u->field_data[UF_HOST].off = p - buf;
-        }
-        u->field_data[UF_HOST].len++;
-        break;
-
-      case s_http_host_v6_zone_start:
-      case s_http_host_v6_zone:
-        u->field_data[UF_HOST].len++;
-        break;
-
-      case s_http_host_port:
-        if (s != s_http_host_port) {
-          u->field_data[UF_PORT].off = p - buf;
-          u->field_data[UF_PORT].len = 0;
-          u->field_set |= (1 << UF_PORT);
-        }
-        u->field_data[UF_PORT].len++;
-        break;
-
-      case s_http_userinfo:
-        if (s != s_http_userinfo) {
-          u->field_data[UF_USERINFO].off = p - buf ;
-          u->field_data[UF_USERINFO].len = 0;
-          u->field_set |= (1 << UF_USERINFO);
-        }
-        u->field_data[UF_USERINFO].len++;
-        break;
-
-      default:
-        break;
-    }
-    s = new_s;
-  }
-
-  /* Make sure we don't end somewhere unexpected */
-  switch (s) {
-    case s_http_host_start:
-    case s_http_host_v6_start:
-    case s_http_host_v6:
-    case s_http_host_v6_zone_start:
-    case s_http_host_v6_zone:
-    case s_http_host_port_start:
-    case s_http_userinfo:
-    case s_http_userinfo_start:
-      return 1;
-    default:
-      break;
-  }
-
-  return 0;
-}
-
-void
-http_parser_url_init(struct http_parser_url *u) {
-  memset(u, 0, sizeof(*u));
-}
-
-int
-http_parser_parse_url(const char *buf, size_t buflen, int is_connect,
-                      struct http_parser_url *u)
-{
-  enum state s;
-  const char *p;
-  enum http_parser_url_fields uf, old_uf;
-  int found_at = 0;
-
-  u->port = u->field_set = 0;
-  s = is_connect ? s_req_server_start : s_req_spaces_before_url;
-  old_uf = UF_MAX;
-
-  for (p = buf; p < buf + buflen; p++) {
-    s = parse_url_char(s, *p);
-
-    /* Figure out the next field that we're operating on */
-    switch (s) {
-      case s_dead:
-        return 1;
-
-      /* Skip delimeters */
-      case s_req_schema_slash:
-      case s_req_schema_slash_slash:
-      case s_req_server_start:
-      case s_req_query_string_start:
-      case s_req_fragment_start:
-        continue;
-
-      case s_req_schema:
-        uf = UF_SCHEMA;
-        break;
-
-      case s_req_server_with_at:
-        found_at = 1;
-
-      /* FALLTROUGH */
-      case s_req_server:
-        uf = UF_HOST;
-        break;
-
-      case s_req_path:
-        uf = UF_PATH;
-        break;
-
-      case s_req_query_string:
-        uf = UF_QUERY;
-        break;
-
-      case s_req_fragment:
-        uf = UF_FRAGMENT;
-        break;
-
-      default:
-        assert(!"Unexpected state");
-        return 1;
-    }
-
-    /* Nothing's changed; soldier on */
-    if (uf == old_uf) {
-      u->field_data[uf].len++;
-      continue;
-    }
-
-    u->field_data[uf].off = p - buf;
-    u->field_data[uf].len = 1;
-
-    u->field_set |= (1 << uf);
-    old_uf = uf;
-  }
-
-  /* host must be present if there is a schema */
-  /* parsing http:///toto will fail */
-  if ((u->field_set & (1 << UF_SCHEMA)) &&
-      (u->field_set & (1 << UF_HOST)) == 0) {
-    return 1;
-  }
-
-  if (u->field_set & (1 << UF_HOST)) {
-    if (http_parse_host(buf, u, found_at) != 0) {
-      return 1;
-    }
-  }
-
-  /* CONNECT requests can only contain "hostname:port" */
-  if (is_connect && u->field_set != ((1 << UF_HOST)|(1 << UF_PORT))) {
-    return 1;
-  }
-
-  if (u->field_set & (1 << UF_PORT)) {
-    /* Don't bother with endp; we've already validated the string */
-    unsigned long v = strtoul(buf + u->field_data[UF_PORT].off, NULL, 10);
-
-    /* Ports have a max value of 2^16 */
-    if (v > 0xffff) {
-      return 1;
-    }
-
-    u->port = (uint16_t) v;
-  }
-
-  return 0;
-}
-
-void
-http_parser_pause(http_parser *parser, int paused) {
-  /* Users should only be pausing/unpausing a parser that is not in an error
-   * state. In non-debug builds, there's not much that we can do about this
-   * other than ignore it.
-   */
-  if (HTTP_PARSER_ERRNO(parser) == HPE_OK ||
-      HTTP_PARSER_ERRNO(parser) == HPE_PAUSED) {
-    SET_ERRNO((paused) ? HPE_PAUSED : HPE_OK);
-  } else {
-    assert(0 && "Attempting to pause parser in error state");
-  }
-}
-
-int
-http_body_is_final(const struct http_parser *parser) {
-    return parser->state == s_message_done;
-}
-
-unsigned long
-http_parser_version(void) {
-  return HTTP_PARSER_VERSION_MAJOR * 0x10000 |
-         HTTP_PARSER_VERSION_MINOR * 0x00100 |
-         HTTP_PARSER_VERSION_PATCH * 0x00001;
-}

+ 0 - 432
ext/http-parser/http_parser.h

@@ -1,432 +0,0 @@
-/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-#ifndef http_parser_h
-#define http_parser_h
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Also update SONAME in the Makefile whenever you change these. */
-#define HTTP_PARSER_VERSION_MAJOR 2
-#define HTTP_PARSER_VERSION_MINOR 7
-#define HTTP_PARSER_VERSION_PATCH 1
-
-#include <sys/types.h>
-#if defined(_WIN32) && !defined(__MINGW32__) && \
-  (!defined(_MSC_VER) || _MSC_VER<1600) && !defined(__WINE__)
-#include <BaseTsd.h>
-#include <stddef.h>
-typedef __int8 int8_t;
-typedef unsigned __int8 uint8_t;
-typedef __int16 int16_t;
-typedef unsigned __int16 uint16_t;
-typedef __int32 int32_t;
-typedef unsigned __int32 uint32_t;
-typedef __int64 int64_t;
-typedef unsigned __int64 uint64_t;
-#else
-#include <stdint.h>
-#endif
-
-/* Compile with -DHTTP_PARSER_STRICT=0 to make less checks, but run
- * faster
- */
-#ifndef HTTP_PARSER_STRICT
-# define HTTP_PARSER_STRICT 1
-#endif
-
-/* Maximium header size allowed. If the macro is not defined
- * before including this header then the default is used. To
- * change the maximum header size, define the macro in the build
- * environment (e.g. -DHTTP_MAX_HEADER_SIZE=<value>). To remove
- * the effective limit on the size of the header, define the macro
- * to a very large number (e.g. -DHTTP_MAX_HEADER_SIZE=0x7fffffff)
- */
-#ifndef HTTP_MAX_HEADER_SIZE
-# define HTTP_MAX_HEADER_SIZE (80*1024)
-#endif
-
-typedef struct http_parser http_parser;
-typedef struct http_parser_settings http_parser_settings;
-
-
-/* Callbacks should return non-zero to indicate an error. The parser will
- * then halt execution.
- *
- * The one exception is on_headers_complete. In a HTTP_RESPONSE parser
- * returning '1' from on_headers_complete will tell the parser that it
- * should not expect a body. This is used when receiving a response to a
- * HEAD request which may contain 'Content-Length' or 'Transfer-Encoding:
- * chunked' headers that indicate the presence of a body.
- *
- * Returning `2` from on_headers_complete will tell parser that it should not
- * expect neither a body nor any futher responses on this connection. This is
- * useful for handling responses to a CONNECT request which may not contain
- * `Upgrade` or `Connection: upgrade` headers.
- *
- * http_data_cb does not return data chunks. It will be called arbitrarily
- * many times for each string. E.G. you might get 10 callbacks for "on_url"
- * each providing just a few characters more data.
- */
-typedef int (*http_data_cb) (http_parser*, const char *at, size_t length);
-typedef int (*http_cb) (http_parser*);
-
-
-/* Status Codes */
-#define HTTP_STATUS_MAP(XX)                                                 \
-  XX(100, CONTINUE,                        Continue)                        \
-  XX(101, SWITCHING_PROTOCOLS,             Switching Protocols)             \
-  XX(102, PROCESSING,                      Processing)                      \
-  XX(200, OK,                              OK)                              \
-  XX(201, CREATED,                         Created)                         \
-  XX(202, ACCEPTED,                        Accepted)                        \
-  XX(203, NON_AUTHORITATIVE_INFORMATION,   Non-Authoritative Information)   \
-  XX(204, NO_CONTENT,                      No Content)                      \
-  XX(205, RESET_CONTENT,                   Reset Content)                   \
-  XX(206, PARTIAL_CONTENT,                 Partial Content)                 \
-  XX(207, MULTI_STATUS,                    Multi-Status)                    \
-  XX(208, ALREADY_REPORTED,                Already Reported)                \
-  XX(226, IM_USED,                         IM Used)                         \
-  XX(300, MULTIPLE_CHOICES,                Multiple Choices)                \
-  XX(301, MOVED_PERMANENTLY,               Moved Permanently)               \
-  XX(302, FOUND,                           Found)                           \
-  XX(303, SEE_OTHER,                       See Other)                       \
-  XX(304, NOT_MODIFIED,                    Not Modified)                    \
-  XX(305, USE_PROXY,                       Use Proxy)                       \
-  XX(307, TEMPORARY_REDIRECT,              Temporary Redirect)              \
-  XX(308, PERMANENT_REDIRECT,              Permanent Redirect)              \
-  XX(400, BAD_REQUEST,                     Bad Request)                     \
-  XX(401, UNAUTHORIZED,                    Unauthorized)                    \
-  XX(402, PAYMENT_REQUIRED,                Payment Required)                \
-  XX(403, FORBIDDEN,                       Forbidden)                       \
-  XX(404, NOT_FOUND,                       Not Found)                       \
-  XX(405, METHOD_NOT_ALLOWED,              Method Not Allowed)              \
-  XX(406, NOT_ACCEPTABLE,                  Not Acceptable)                  \
-  XX(407, PROXY_AUTHENTICATION_REQUIRED,   Proxy Authentication Required)   \
-  XX(408, REQUEST_TIMEOUT,                 Request Timeout)                 \
-  XX(409, CONFLICT,                        Conflict)                        \
-  XX(410, GONE,                            Gone)                            \
-  XX(411, LENGTH_REQUIRED,                 Length Required)                 \
-  XX(412, PRECONDITION_FAILED,             Precondition Failed)             \
-  XX(413, PAYLOAD_TOO_LARGE,               Payload Too Large)               \
-  XX(414, URI_TOO_LONG,                    URI Too Long)                    \
-  XX(415, UNSUPPORTED_MEDIA_TYPE,          Unsupported Media Type)          \
-  XX(416, RANGE_NOT_SATISFIABLE,           Range Not Satisfiable)           \
-  XX(417, EXPECTATION_FAILED,              Expectation Failed)              \
-  XX(421, MISDIRECTED_REQUEST,             Misdirected Request)             \
-  XX(422, UNPROCESSABLE_ENTITY,            Unprocessable Entity)            \
-  XX(423, LOCKED,                          Locked)                          \
-  XX(424, FAILED_DEPENDENCY,               Failed Dependency)               \
-  XX(426, UPGRADE_REQUIRED,                Upgrade Required)                \
-  XX(428, PRECONDITION_REQUIRED,           Precondition Required)           \
-  XX(429, TOO_MANY_REQUESTS,               Too Many Requests)               \
-  XX(431, REQUEST_HEADER_FIELDS_TOO_LARGE, Request Header Fields Too Large) \
-  XX(451, UNAVAILABLE_FOR_LEGAL_REASONS,   Unavailable For Legal Reasons)   \
-  XX(500, INTERNAL_SERVER_ERROR,           Internal Server Error)           \
-  XX(501, NOT_IMPLEMENTED,                 Not Implemented)                 \
-  XX(502, BAD_GATEWAY,                     Bad Gateway)                     \
-  XX(503, SERVICE_UNAVAILABLE,             Service Unavailable)             \
-  XX(504, GATEWAY_TIMEOUT,                 Gateway Timeout)                 \
-  XX(505, HTTP_VERSION_NOT_SUPPORTED,      HTTP Version Not Supported)      \
-  XX(506, VARIANT_ALSO_NEGOTIATES,         Variant Also Negotiates)         \
-  XX(507, INSUFFICIENT_STORAGE,            Insufficient Storage)            \
-  XX(508, LOOP_DETECTED,                   Loop Detected)                   \
-  XX(510, NOT_EXTENDED,                    Not Extended)                    \
-  XX(511, NETWORK_AUTHENTICATION_REQUIRED, Network Authentication Required) \
-
-enum http_status
-  {
-#define XX(num, name, string) HTTP_STATUS_##name = num,
-  HTTP_STATUS_MAP(XX)
-#undef XX
-  };
-
-
-/* Request Methods */
-#define HTTP_METHOD_MAP(XX)         \
-  XX(0,  DELETE,      DELETE)       \
-  XX(1,  GET,         GET)          \
-  XX(2,  HEAD,        HEAD)         \
-  XX(3,  POST,        POST)         \
-  XX(4,  PUT,         PUT)          \
-  /* pathological */                \
-  XX(5,  CONNECT,     CONNECT)      \
-  XX(6,  OPTIONS,     OPTIONS)      \
-  XX(7,  TRACE,       TRACE)        \
-  /* WebDAV */                      \
-  XX(8,  COPY,        COPY)         \
-  XX(9,  LOCK,        LOCK)         \
-  XX(10, MKCOL,       MKCOL)        \
-  XX(11, MOVE,        MOVE)         \
-  XX(12, PROPFIND,    PROPFIND)     \
-  XX(13, PROPPATCH,   PROPPATCH)    \
-  XX(14, SEARCH,      SEARCH)       \
-  XX(15, UNLOCK,      UNLOCK)       \
-  XX(16, BIND,        BIND)         \
-  XX(17, REBIND,      REBIND)       \
-  XX(18, UNBIND,      UNBIND)       \
-  XX(19, ACL,         ACL)          \
-  /* subversion */                  \
-  XX(20, REPORT,      REPORT)       \
-  XX(21, MKACTIVITY,  MKACTIVITY)   \
-  XX(22, CHECKOUT,    CHECKOUT)     \
-  XX(23, MERGE,       MERGE)        \
-  /* upnp */                        \
-  XX(24, MSEARCH,     M-SEARCH)     \
-  XX(25, NOTIFY,      NOTIFY)       \
-  XX(26, SUBSCRIBE,   SUBSCRIBE)    \
-  XX(27, UNSUBSCRIBE, UNSUBSCRIBE)  \
-  /* RFC-5789 */                    \
-  XX(28, PATCH,       PATCH)        \
-  XX(29, PURGE,       PURGE)        \
-  /* CalDAV */                      \
-  XX(30, MKCALENDAR,  MKCALENDAR)   \
-  /* RFC-2068, section 19.6.1.2 */  \
-  XX(31, LINK,        LINK)         \
-  XX(32, UNLINK,      UNLINK)       \
-
-enum http_method
-  {
-#define XX(num, name, string) HTTP_##name = num,
-  HTTP_METHOD_MAP(XX)
-#undef XX
-  };
-
-
-enum http_parser_type { HTTP_REQUEST, HTTP_RESPONSE, HTTP_BOTH };
-
-
-/* Flag values for http_parser.flags field */
-enum flags
-  { F_CHUNKED               = 1 << 0
-  , F_CONNECTION_KEEP_ALIVE = 1 << 1
-  , F_CONNECTION_CLOSE      = 1 << 2
-  , F_CONNECTION_UPGRADE    = 1 << 3
-  , F_TRAILING              = 1 << 4
-  , F_UPGRADE               = 1 << 5
-  , F_SKIPBODY              = 1 << 6
-  , F_CONTENTLENGTH         = 1 << 7
-  };
-
-
-/* Map for errno-related constants
- *
- * The provided argument should be a macro that takes 2 arguments.
- */
-#define HTTP_ERRNO_MAP(XX)                                           \
-  /* No error */                                                     \
-  XX(OK, "success")                                                  \
-                                                                     \
-  /* Callback-related errors */                                      \
-  XX(CB_message_begin, "the on_message_begin callback failed")       \
-  XX(CB_url, "the on_url callback failed")                           \
-  XX(CB_header_field, "the on_header_field callback failed")         \
-  XX(CB_header_value, "the on_header_value callback failed")         \
-  XX(CB_headers_complete, "the on_headers_complete callback failed") \
-  XX(CB_body, "the on_body callback failed")                         \
-  XX(CB_message_complete, "the on_message_complete callback failed") \
-  XX(CB_status, "the on_status callback failed")                     \
-  XX(CB_chunk_header, "the on_chunk_header callback failed")         \
-  XX(CB_chunk_complete, "the on_chunk_complete callback failed")     \
-                                                                     \
-  /* Parsing-related errors */                                       \
-  XX(INVALID_EOF_STATE, "stream ended at an unexpected time")        \
-  XX(HEADER_OVERFLOW,                                                \
-     "too many header bytes seen; overflow detected")                \
-  XX(CLOSED_CONNECTION,                                              \
-     "data received after completed connection: close message")      \
-  XX(INVALID_VERSION, "invalid HTTP version")                        \
-  XX(INVALID_STATUS, "invalid HTTP status code")                     \
-  XX(INVALID_METHOD, "invalid HTTP method")                          \
-  XX(INVALID_URL, "invalid URL")                                     \
-  XX(INVALID_HOST, "invalid host")                                   \
-  XX(INVALID_PORT, "invalid port")                                   \
-  XX(INVALID_PATH, "invalid path")                                   \
-  XX(INVALID_QUERY_STRING, "invalid query string")                   \
-  XX(INVALID_FRAGMENT, "invalid fragment")                           \
-  XX(LF_EXPECTED, "LF character expected")                           \
-  XX(INVALID_HEADER_TOKEN, "invalid character in header")            \
-  XX(INVALID_CONTENT_LENGTH,                                         \
-     "invalid character in content-length header")                   \
-  XX(UNEXPECTED_CONTENT_LENGTH,                                      \
-     "unexpected content-length header")                             \
-  XX(INVALID_CHUNK_SIZE,                                             \
-     "invalid character in chunk size header")                       \
-  XX(INVALID_CONSTANT, "invalid constant string")                    \
-  XX(INVALID_INTERNAL_STATE, "encountered unexpected internal state")\
-  XX(STRICT, "strict mode assertion failed")                         \
-  XX(PAUSED, "parser is paused")                                     \
-  XX(UNKNOWN, "an unknown error occurred")
-
-
-/* Define HPE_* values for each errno value above */
-#define HTTP_ERRNO_GEN(n, s) HPE_##n,
-enum http_errno {
-  HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
-};
-#undef HTTP_ERRNO_GEN
-
-
-/* Get an http_errno value from an http_parser */
-#define HTTP_PARSER_ERRNO(p)            ((enum http_errno) (p)->http_errno)
-
-
-struct http_parser {
-  /** PRIVATE **/
-  unsigned int type : 2;         /* enum http_parser_type */
-  unsigned int flags : 8;        /* F_* values from 'flags' enum; semi-public */
-  unsigned int state : 7;        /* enum state from http_parser.c */
-  unsigned int header_state : 7; /* enum header_state from http_parser.c */
-  unsigned int index : 7;        /* index into current matcher */
-  unsigned int lenient_http_headers : 1;
-
-  uint32_t nread;          /* # bytes read in various scenarios */
-  uint64_t content_length; /* # bytes in body (0 if no Content-Length header) */
-
-  /** READ-ONLY **/
-  unsigned short http_major;
-  unsigned short http_minor;
-  unsigned int status_code : 16; /* responses only */
-  unsigned int method : 8;       /* requests only */
-  unsigned int http_errno : 7;
-
-  /* 1 = Upgrade header was present and the parser has exited because of that.
-   * 0 = No upgrade header present.
-   * Should be checked when http_parser_execute() returns in addition to
-   * error checking.
-   */
-  unsigned int upgrade : 1;
-
-  /** PUBLIC **/
-  void *data; /* A pointer to get hook to the "connection" or "socket" object */
-};
-
-
-struct http_parser_settings {
-  http_cb      on_message_begin;
-  http_data_cb on_url;
-  http_data_cb on_status;
-  http_data_cb on_header_field;
-  http_data_cb on_header_value;
-  http_cb      on_headers_complete;
-  http_data_cb on_body;
-  http_cb      on_message_complete;
-  /* When on_chunk_header is called, the current chunk length is stored
-   * in parser->content_length.
-   */
-  http_cb      on_chunk_header;
-  http_cb      on_chunk_complete;
-};
-
-
-enum http_parser_url_fields
-  { UF_SCHEMA           = 0
-  , UF_HOST             = 1
-  , UF_PORT             = 2
-  , UF_PATH             = 3
-  , UF_QUERY            = 4
-  , UF_FRAGMENT         = 5
-  , UF_USERINFO         = 6
-  , UF_MAX              = 7
-  };
-
-
-/* Result structure for http_parser_parse_url().
- *
- * Callers should index into field_data[] with UF_* values iff field_set
- * has the relevant (1 << UF_*) bit set. As a courtesy to clients (and
- * because we probably have padding left over), we convert any port to
- * a uint16_t.
- */
-struct http_parser_url {
-  uint16_t field_set;           /* Bitmask of (1 << UF_*) values */
-  uint16_t port;                /* Converted UF_PORT string */
-
-  struct {
-    uint16_t off;               /* Offset into buffer in which field starts */
-    uint16_t len;               /* Length of run in buffer */
-  } field_data[UF_MAX];
-};
-
-
-/* Returns the library version. Bits 16-23 contain the major version number,
- * bits 8-15 the minor version number and bits 0-7 the patch level.
- * Usage example:
- *
- *   unsigned long version = http_parser_version();
- *   unsigned major = (version >> 16) & 255;
- *   unsigned minor = (version >> 8) & 255;
- *   unsigned patch = version & 255;
- *   printf("http_parser v%u.%u.%u\n", major, minor, patch);
- */
-unsigned long http_parser_version(void);
-
-void http_parser_init(http_parser *parser, enum http_parser_type type);
-
-
-/* Initialize http_parser_settings members to 0
- */
-void http_parser_settings_init(http_parser_settings *settings);
-
-
-/* Executes the parser. Returns number of parsed bytes. Sets
- * `parser->http_errno` on error. */
-size_t http_parser_execute(http_parser *parser,
-                           const http_parser_settings *settings,
-                           const char *data,
-                           size_t len);
-
-
-/* If http_should_keep_alive() in the on_headers_complete or
- * on_message_complete callback returns 0, then this should be
- * the last message on the connection.
- * If you are the server, respond with the "Connection: close" header.
- * If you are the client, close the connection.
- */
-int http_should_keep_alive(const http_parser *parser);
-
-/* Returns a string version of the HTTP method. */
-const char *http_method_str(enum http_method m);
-
-/* Return a string name of the given error */
-const char *http_errno_name(enum http_errno err);
-
-/* Return a string description of the given error */
-const char *http_errno_description(enum http_errno err);
-
-/* Initialize all http_parser_url members to 0 */
-void http_parser_url_init(struct http_parser_url *u);
-
-/* Parse a URL; return nonzero on failure */
-int http_parser_parse_url(const char *buf, size_t buflen,
-                          int is_connect,
-                          struct http_parser_url *u);
-
-/* Pause or un-pause the parser; a nonzero value pauses */
-void http_parser_pause(http_parser *parser, int paused);
-
-/* Checks if this is the final chunk of the body. */
-int http_body_is_final(const http_parser *parser);
-
-#ifdef __cplusplus
-}
-#endif
-#endif

+ 0 - 98
ext/libnatpmp/Changelog.txt

@@ -1,98 +0,0 @@
-$Id: Changelog.txt,v 1.33 2013/11/26 08:47:36 nanard Exp $
-
-2013/11/26:
-  enforce strict aliasing rules.
-
-2013/09/10:
-  small patch for MSVC >= 16
-  rename win32 implementation of gettimeofday() to natpmp_gettimeofday()
-
-2012/08/21:
-  Little change in Makefile
-  removed warnings in testgetgateway.c
-  Fixed bugs in command line argumentparsing in natpmpc.c
-
-2011/08/07:
-  Patch to build on debian/kFreeBSD.
-
-2011/07/15:
-  Put 3 clauses BSD licence at the top of source files.
-
-2011/06/18:
-  --no-undefined => -Wl,--no-undefined
-  adding a natpmpc.1 man page
-
-2011/05/19:
-  Small fix in libnatpmpmodule.c thanks to Manuel Mausz
-
-2011/01/03:
-  Added an argument to initnatpmp() in order to force the gateway to be used
-
-2011/01/01:
-  fix in make install
-
-2010/05/21:
-  make install now working under MacOSX (and BSD)
-
-2010/04/12:
-  cplusplus stuff in natpmp.h
-
-2010/02/02:
-  Fixed compilation under Mac OS X
-
-2009/12/19:
-  improve and fix building under Windows.
-  Project files for MS Visual Studio 2008
-  More simple (and working) code for Win32.
-  More checks in the /proc/net/route parsing. Add some comments.
-
-2009/08/04:
-  improving getgateway.c for windows
-
-2009/07/13:
-  Adding Haiku code in getgateway.c
-
-2009/06/04:
-  Adding Python module thanks to David Wu
-
-2009/03/10:
-  Trying to have windows get gateway working if not using DHCP
-
-2009/02/27:
-  dont include declspec.h if not under WIN32.
-
-2009/01/23:
-  Prefixed the libraries name with lib
-
-2008/10/06:
-  Fixed a memory leak in getdefaultgateway() (USE_SYSCTL_NET_ROUTE)
-
-2008/07/03:
-  Adding WIN32 code from Robbie Hanson
-
-2008/06/30:
-  added a Solaris implementation for getgateway().
-  added a LICENCE file to the distribution
-
-2008/05/29:
-  Anonymous unions are forbidden in ANSI C. That was causing problems with
-  non-GCC compilers.
-
-2008/04/28:
-  introduced strnatpmperr()
-  improved natpmpc.c sample
-  make install now install the binary
-
-2007/12/13:
-  Fixed getgateway.c for working under OS X ;)
-  Fixed values for NATPMP_PROTOCOL_TCP and NATPMP_PROTOCOL_UDP
-
-2007/12/11:
-  Fixed getgateway.c for compilation under Mac OS X
-
-2007/12/01:
-  added some comments in .h
-
-2007/11/30:
-  implemented almost everything
-

+ 0 - 26
ext/libnatpmp/LICENSE

@@ -1,26 +0,0 @@
-Copyright (c) 2007-2011, Thomas BERNARD
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * The name of the author may not be used to endorse or promote products
-	  derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-

+ 0 - 7
ext/libnatpmp/README

@@ -1,7 +0,0 @@
-libnatpmp (c) 2007-2009 Thomas Bernard
-contact : [email protected]
-
-see http://miniupnp.free.fr/libnatpmp.html
-or http://miniupnp.tuxfamily.org/libnatpmp.html
-for some documentation and code samples.
-

+ 0 - 21
ext/libnatpmp/declspec.h

@@ -1,21 +0,0 @@
-#ifndef DECLSPEC_H_INCLUDED
-#define DECLSPEC_H_INCLUDED
-
-#if defined(WIN32) && !defined(STATICLIB)
-	/* for windows dll */
-	#ifdef NATPMP_EXPORTS
-		#define LIBSPEC __declspec(dllexport)
-	#else
-		#define LIBSPEC __declspec(dllimport)
-	#endif
-#else
-	#if defined(__GNUC__) && __GNUC__ >= 4
-		/* fix dynlib for OS X 10.9.2 and Apple LLVM version 5.0 */
-		#define LIBSPEC __attribute__ ((visibility ("default")))
-	#else
-		#define LIBSPEC
-	#endif
-#endif
-
-#endif
-

+ 0 - 573
ext/libnatpmp/getgateway.c

@@ -1,573 +0,0 @@
-/* $Id: getgateway.c,v 1.25 2014/04/22 10:28:57 nanard Exp $ */
-/* libnatpmp
-
-Copyright (c) 2007-2014, Thomas BERNARD
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * The name of the author may not be used to endorse or promote products
-	  derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-#include <stdio.h>
-#include <ctype.h>
-#ifndef WIN32
-#include <netinet/in.h>
-#endif
-#if !defined(_MSC_VER)
-#include <sys/param.h>
-#endif
-/* There is no portable method to get the default route gateway.
- * So below are four (or five ?) differents functions implementing this.
- * Parsing /proc/net/route is for linux.
- * sysctl is the way to access such informations on BSD systems.
- * Many systems should provide route information through raw PF_ROUTE
- * sockets.
- * In MS Windows, default gateway is found by looking into the registry
- * or by using GetBestRoute(). */
-#ifdef __linux__
-#define USE_PROC_NET_ROUTE
-#undef USE_SOCKET_ROUTE
-#undef USE_SYSCTL_NET_ROUTE
-#endif
-
-#if defined(BSD) || defined(__FreeBSD_kernel__)
-#undef USE_PROC_NET_ROUTE
-#define USE_SOCKET_ROUTE
-#undef USE_SYSCTL_NET_ROUTE
-#include <sys/sysctl.h>
-#endif
-
-#ifdef __APPLE__
-#undef USE_PROC_NET_ROUTE
-#undef USE_SOCKET_ROUTE
-#define USE_SYSCTL_NET_ROUTE
-#endif
-
-#if (defined(sun) && defined(__SVR4))
-#undef USE_PROC_NET_ROUTE
-#define USE_SOCKET_ROUTE
-#undef USE_SYSCTL_NET_ROUTE
-#endif
-
-#ifdef WIN32
-#undef USE_PROC_NET_ROUTE
-#undef USE_SOCKET_ROUTE
-#undef USE_SYSCTL_NET_ROUTE
-//#define USE_WIN32_CODE
-#define USE_WIN32_CODE_2
-#endif
-
-#ifdef __CYGWIN__
-#undef USE_PROC_NET_ROUTE
-#undef USE_SOCKET_ROUTE
-#undef USE_SYSCTL_NET_ROUTE
-#define USE_WIN32_CODE
-#include <stdarg.h>
-#include <w32api/windef.h>
-#include <w32api/winbase.h>
-#include <w32api/winreg.h>
-#endif
-
-#ifdef __HAIKU__
-#include <stdlib.h>
-#include <unistd.h>
-#include <net/if.h>
-#include <sys/sockio.h>
-#define USE_HAIKU_CODE
-#endif
-
-#ifdef USE_SYSCTL_NET_ROUTE
-#include <stdlib.h>
-#include <sys/socket.h>
-#include <net/route.h>
-#endif
-#ifdef USE_SOCKET_ROUTE
-#include <unistd.h>
-#include <string.h>
-#include <sys/socket.h>
-#include <net/if.h>
-#include <net/route.h>
-#endif
-
-#ifdef USE_WIN32_CODE
-#include <unknwn.h>
-#include <winreg.h>
-#define MAX_KEY_LENGTH 255
-#define MAX_VALUE_LENGTH 16383
-#endif
-
-#ifdef USE_WIN32_CODE_2
-#include <windows.h>
-#include <iphlpapi.h>
-#endif
-
-#include "getgateway.h"
-
-#ifndef WIN32
-#define SUCCESS (0)
-#define FAILED  (-1)
-#endif
-
-#ifdef USE_PROC_NET_ROUTE
-/*
- parse /proc/net/route which is as follow :
-
-Iface   Destination     Gateway         Flags   RefCnt  Use     Metric  Mask            MTU     Window  IRTT
-wlan0   0001A8C0        00000000        0001    0       0       0       00FFFFFF        0       0       0
-eth0    0000FEA9        00000000        0001    0       0       0       0000FFFF        0       0       0
-wlan0   00000000        0101A8C0        0003    0       0       0       00000000        0       0       0
-eth0    00000000        00000000        0001    0       0       1000    00000000        0       0       0
-
- One header line, and then one line by route by route table entry.
-*/
-int getdefaultgateway(in_addr_t * addr)
-{
-	unsigned long d, g;
-	char buf[256];
-	int line = 0;
-	FILE * f;
-	char * p;
-	f = fopen("/proc/net/route", "r");
-	if(!f)
-		return FAILED;
-	while(fgets(buf, sizeof(buf), f)) {
-		if(line > 0) {	/* skip the first line */
-			p = buf;
-			/* skip the interface name */
-			while(*p && !isspace(*p))
-				p++;
-			while(*p && isspace(*p))
-				p++;
-			if(sscanf(p, "%lx%lx", &d, &g)==2) {
-				if(d == 0 && g != 0) { /* default */
-					*addr = g;
-					fclose(f);
-					return SUCCESS;
-				}
-			}
-		}
-		line++;
-	}
-	/* default route not found ! */
-	if(f)
-		fclose(f);
-	return FAILED;
-}
-#endif /* #ifdef USE_PROC_NET_ROUTE */
-
-
-#ifdef USE_SYSCTL_NET_ROUTE
-
-#define ROUNDUP(a) \
-	((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
-
-int getdefaultgateway(in_addr_t * addr)
-{
-#if 0
-	/* net.route.0.inet.dump.0.0 ? */
-	int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET,
-	             NET_RT_DUMP, 0, 0/*tableid*/};
-#endif
-	/* net.route.0.inet.flags.gateway */
-	int mib[] = {CTL_NET, PF_ROUTE, 0, AF_INET,
-	             NET_RT_FLAGS, RTF_GATEWAY};
-	size_t l;
-	char * buf, * p;
-	struct rt_msghdr * rt;
-	struct sockaddr * sa;
-	struct sockaddr * sa_tab[RTAX_MAX];
-	int i;
-	int r = FAILED;
-	if(sysctl(mib, sizeof(mib)/sizeof(int), 0, &l, 0, 0) < 0) {
-		return FAILED;
-	}
-	if(l>0) {
-		buf = malloc(l);
-		if(sysctl(mib, sizeof(mib)/sizeof(int), buf, &l, 0, 0) < 0) {
-			free(buf);
-			return FAILED;
-		}
-		for(p=buf; p<buf+l; p+=rt->rtm_msglen) {
-			rt = (struct rt_msghdr *)p;
-			sa = (struct sockaddr *)(rt + 1);
-			for(i=0; i<RTAX_MAX; i++) {
-				if(rt->rtm_addrs & (1 << i)) {
-					sa_tab[i] = sa;
-					sa = (struct sockaddr *)((char *)sa + ROUNDUP(sa->sa_len));
-				} else {
-					sa_tab[i] = NULL;
-				}
-			}
-			if( ((rt->rtm_addrs & (RTA_DST|RTA_GATEWAY)) == (RTA_DST|RTA_GATEWAY))
-              && sa_tab[RTAX_DST]->sa_family == AF_INET
-              && sa_tab[RTAX_GATEWAY]->sa_family == AF_INET) {
-				if(((struct sockaddr_in *)sa_tab[RTAX_DST])->sin_addr.s_addr == 0) {
-					*addr = ((struct sockaddr_in *)(sa_tab[RTAX_GATEWAY]))->sin_addr.s_addr;
-					r = SUCCESS;
-				}
-			}
-		}
-		free(buf);
-	}
-	return r;
-}
-#endif /* #ifdef USE_SYSCTL_NET_ROUTE */
-
-
-#ifdef USE_SOCKET_ROUTE
-/* Thanks to Darren Kenny for this code */
-#define NEXTADDR(w, u) \
-        if (rtm_addrs & (w)) {\
-            l = sizeof(struct sockaddr); memmove(cp, &(u), l); cp += l;\
-        }
-
-#define rtm m_rtmsg.m_rtm
-
-struct {
-  struct rt_msghdr m_rtm;
-  char       m_space[512];
-} m_rtmsg;
-
-int getdefaultgateway(in_addr_t *addr)
-{
-  int s, seq, l, rtm_addrs, i;
-  pid_t pid;
-  struct sockaddr so_dst, so_mask;
-  char *cp = m_rtmsg.m_space;
-  struct sockaddr *gate = NULL, *sa;
-  struct rt_msghdr *msg_hdr;
-
-  pid = getpid();
-  seq = 0;
-  rtm_addrs = RTA_DST | RTA_NETMASK;
-
-  memset(&so_dst, 0, sizeof(so_dst));
-  memset(&so_mask, 0, sizeof(so_mask));
-  memset(&rtm, 0, sizeof(struct rt_msghdr));
-
-  rtm.rtm_type = RTM_GET;
-  rtm.rtm_flags = RTF_UP | RTF_GATEWAY;
-  rtm.rtm_version = RTM_VERSION;
-  rtm.rtm_seq = ++seq;
-  rtm.rtm_addrs = rtm_addrs;
-
-  so_dst.sa_family = AF_INET;
-  so_mask.sa_family = AF_INET;
-
-  NEXTADDR(RTA_DST, so_dst);
-  NEXTADDR(RTA_NETMASK, so_mask);
-
-  rtm.rtm_msglen = l = cp - (char *)&m_rtmsg;
-
-  s = socket(PF_ROUTE, SOCK_RAW, 0);
-
-  if (write(s, (char *)&m_rtmsg, l) < 0) {
-      close(s);
-      return FAILED;
-  }
-
-  do {
-    l = read(s, (char *)&m_rtmsg, sizeof(m_rtmsg));
-  } while (l > 0 && (rtm.rtm_seq != seq || rtm.rtm_pid != pid));
-
-  close(s);
-
-  msg_hdr = &rtm;
-
-  cp = ((char *)(msg_hdr + 1));
-  if (msg_hdr->rtm_addrs) {
-    for (i = 1; i; i <<= 1)
-      if (i & msg_hdr->rtm_addrs) {
-        sa = (struct sockaddr *)cp;
-        if (i == RTA_GATEWAY )
-          gate = sa;
-
-        cp += sizeof(struct sockaddr);
-      }
-  } else {
-      return FAILED;
-  }
-
-
-  if (gate != NULL ) {
-      *addr = ((struct sockaddr_in *)gate)->sin_addr.s_addr;
-      return SUCCESS;
-  } else {
-      return FAILED;
-  }
-}
-#endif /* #ifdef USE_SOCKET_ROUTE */
-
-#ifdef USE_WIN32_CODE
-LIBSPEC int getdefaultgateway(in_addr_t * addr)
-{
-	HKEY networkCardsKey;
-	HKEY networkCardKey;
-	HKEY interfacesKey;
-	HKEY interfaceKey;
-	DWORD i = 0;
-	DWORD numSubKeys = 0;
-	TCHAR keyName[MAX_KEY_LENGTH];
-	DWORD keyNameLength = MAX_KEY_LENGTH;
-	TCHAR keyValue[MAX_VALUE_LENGTH];
-	DWORD keyValueLength = MAX_VALUE_LENGTH;
-	DWORD keyValueType = REG_SZ;
-	TCHAR gatewayValue[MAX_VALUE_LENGTH];
-	DWORD gatewayValueLength = MAX_VALUE_LENGTH;
-	DWORD gatewayValueType = REG_MULTI_SZ;
-	int done = 0;
-
-	//const char * networkCardsPath = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards";
-	//const char * interfacesPath = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces";
-#ifdef UNICODE
-	LPCTSTR networkCardsPath = L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards";
-	LPCTSTR interfacesPath = L"SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces";
-#define STR_SERVICENAME	 L"ServiceName"
-#define STR_DHCPDEFAULTGATEWAY L"DhcpDefaultGateway"
-#define STR_DEFAULTGATEWAY	L"DefaultGateway"
-#else
-	LPCTSTR networkCardsPath = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards";
-	LPCTSTR interfacesPath = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces";
-#define STR_SERVICENAME	 "ServiceName"
-#define STR_DHCPDEFAULTGATEWAY "DhcpDefaultGateway"
-#define STR_DEFAULTGATEWAY	"DefaultGateway"
-#endif
-	// The windows registry lists its primary network devices in the following location:
-	// HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards
-	//
-	// Each network device has its own subfolder, named with an index, with various properties:
-	// -NetworkCards
-	//   -5
-	//     -Description = Broadcom 802.11n Network Adapter
-	//     -ServiceName = {E35A72F8-5065-4097-8DFE-C7790774EE4D}
-	//   -8
-	//     -Description = Marvell Yukon 88E8058 PCI-E Gigabit Ethernet Controller
-	//     -ServiceName = {86226414-5545-4335-A9D1-5BD7120119AD}
-	//
-	// The above service name is the name of a subfolder within:
-	// HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces
-	//
-	// There may be more subfolders in this interfaces path than listed in the network cards path above:
-	// -Interfaces
-	//   -{3a539854-6a70-11db-887c-806e6f6e6963}
-	//     -DhcpIPAddress = 0.0.0.0
-	//     -[more]
-	//   -{E35A72F8-5065-4097-8DFE-C7790774EE4D}
-	//     -DhcpIPAddress = 10.0.1.4
-	//     -DhcpDefaultGateway = 10.0.1.1
-	//     -[more]
-	//   -{86226414-5545-4335-A9D1-5BD7120119AD}
-	//     -DhcpIpAddress = 10.0.1.5
-	//     -DhcpDefaultGateay = 10.0.1.1
-	//     -[more]
-	//
-	// In order to extract this information, we enumerate each network card, and extract the ServiceName value.
-	// This is then used to open the interface subfolder, and attempt to extract a DhcpDefaultGateway value.
-	// Once one is found, we're done.
-	//
-	// It may be possible to simply enumerate the interface folders until we find one with a DhcpDefaultGateway value.
-	// However, the technique used is the technique most cited on the web, and we assume it to be more correct.
-
-	if(ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, // Open registry key or predifined key
-	                                 networkCardsPath,   // Name of registry subkey to open
-	                                 0,                  // Reserved - must be zero
-	                                 KEY_READ,           // Mask - desired access rights
-	                                 &networkCardsKey))  // Pointer to output key
-	{
-		// Unable to open network cards keys
-		return -1;
-	}
-
-	if(ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, // Open registry key or predefined key
-	                                 interfacesPath,     // Name of registry subkey to open
-	                                 0,                  // Reserved - must be zero
-	                                 KEY_READ,           // Mask - desired access rights
-	                                 &interfacesKey))    // Pointer to output key
-	{
-		// Unable to open interfaces key
-		RegCloseKey(networkCardsKey);
-		return -1;
-	}
-
-	// Figure out how many subfolders are within the NetworkCards folder
-	RegQueryInfoKey(networkCardsKey, NULL, NULL, NULL, &numSubKeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
-
-	//printf( "Number of subkeys: %u\n", (unsigned int)numSubKeys);
-
-	// Enumrate through each subfolder within the NetworkCards folder
-	for(i = 0; i < numSubKeys && !done; i++)
-	{
-		keyNameLength = MAX_KEY_LENGTH;
-		if(ERROR_SUCCESS == RegEnumKeyEx(networkCardsKey, // Open registry key
-		                                 i,               // Index of subkey to retrieve
-		                                 keyName,         // Buffer that receives the name of the subkey
-		                                 &keyNameLength,  // Variable that receives the size of the above buffer
-		                                 NULL,            // Reserved - must be NULL
-		                                 NULL,            // Buffer that receives the class string
-		                                 NULL,            // Variable that receives the size of the above buffer
-		                                 NULL))           // Variable that receives the last write time of subkey
-		{
-			if(RegOpenKeyEx(networkCardsKey,  keyName, 0, KEY_READ, &networkCardKey) == ERROR_SUCCESS)
-			{
-				keyValueLength = MAX_VALUE_LENGTH;
-				if(ERROR_SUCCESS == RegQueryValueEx(networkCardKey,   // Open registry key
-				                                    STR_SERVICENAME,    // Name of key to query
-				                                    NULL,             // Reserved - must be NULL
-				                                    &keyValueType,    // Receives value type
-				                                    (LPBYTE)keyValue, // Receives value
-				                                    &keyValueLength)) // Receives value length in bytes
-				{
-//					printf("keyValue: %s\n", keyValue);
-					if(RegOpenKeyEx(interfacesKey, keyValue, 0, KEY_READ, &interfaceKey) == ERROR_SUCCESS)
-					{
-						gatewayValueLength = MAX_VALUE_LENGTH;
-						if(ERROR_SUCCESS == RegQueryValueEx(interfaceKey,         // Open registry key
-						                                    STR_DHCPDEFAULTGATEWAY, // Name of key to query
-						                                    NULL,                 // Reserved - must be NULL
-						                                    &gatewayValueType,    // Receives value type
-						                                    (LPBYTE)gatewayValue, // Receives value
-						                                    &gatewayValueLength)) // Receives value length in bytes
-						{
-							// Check to make sure it's a string
-							if((gatewayValueType == REG_MULTI_SZ || gatewayValueType == REG_SZ) && (gatewayValueLength > 1))
-							{
-								//printf("gatewayValue: %s\n", gatewayValue);
-								done = 1;
-							}
-						}
-						else if(ERROR_SUCCESS == RegQueryValueEx(interfaceKey,         // Open registry key
-						                                    STR_DEFAULTGATEWAY, // Name of key to query
-						                                    NULL,                 // Reserved - must be NULL
-						                                    &gatewayValueType,    // Receives value type
-						                                    (LPBYTE)gatewayValue,// Receives value
-						                                    &gatewayValueLength)) // Receives value length in bytes
-						{
-							// Check to make sure it's a string
-							if((gatewayValueType == REG_MULTI_SZ || gatewayValueType == REG_SZ) && (gatewayValueLength > 1))
-							{
-								//printf("gatewayValue: %s\n", gatewayValue);
-								done = 1;
-							}
-						}
-						RegCloseKey(interfaceKey);
-					}
-				}
-				RegCloseKey(networkCardKey);
-			}
-		}
-	}
-
-	RegCloseKey(interfacesKey);
-	RegCloseKey(networkCardsKey);
-
-	if(done)
-	{
-#if UNICODE
-		char tmp[32];
-		for(i = 0; i < 32; i++) {
-			tmp[i] = (char)gatewayValue[i];
-			if(!tmp[i])
-				break;
-		}
-		tmp[31] = '\0';
-		*addr = inet_addr(tmp);
-#else
-		*addr = inet_addr(gatewayValue);
-#endif
-		return 0;
-	}
-
-	return -1;
-}
-#endif /* #ifdef USE_WIN32_CODE */
-
-#ifdef USE_WIN32_CODE_2
-int getdefaultgateway(in_addr_t *addr)
-{
-	MIB_IPFORWARDROW ip_forward;
-	memset(&ip_forward, 0, sizeof(ip_forward));
-	if(GetBestRoute(inet_addr("0.0.0.0"), 0, &ip_forward) != NO_ERROR)
-		return -1;
-	*addr = ip_forward.dwForwardNextHop;
-	return 0;
-}
-#endif /* #ifdef USE_WIN32_CODE_2 */
-
-#ifdef USE_HAIKU_CODE
-int getdefaultgateway(in_addr_t *addr)
-{
-    int fd, ret = -1;
-    struct ifconf config;
-    void *buffer = NULL;
-    struct ifreq *interface;
-
-    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
-        return -1;
-    }
-    if (ioctl(fd, SIOCGRTSIZE, &config, sizeof(config)) != 0) {
-        goto fail;
-    }
-    if (config.ifc_value < 1) {
-        goto fail; /* No routes */
-    }
-    if ((buffer = malloc(config.ifc_value)) == NULL) {
-        goto fail;
-    }
-    config.ifc_len = config.ifc_value;
-    config.ifc_buf = buffer;
-    if (ioctl(fd, SIOCGRTTABLE, &config, sizeof(config)) != 0) {
-        goto fail;
-    }
-    for (interface = buffer;
-      (uint8_t *)interface < (uint8_t *)buffer + config.ifc_len; ) {
-        struct route_entry route = interface->ifr_route;
-        int intfSize;
-        if (route.flags & (RTF_GATEWAY | RTF_DEFAULT)) {
-            *addr = ((struct sockaddr_in *)route.gateway)->sin_addr.s_addr;
-            ret = 0;
-            break;
-        }
-        intfSize = sizeof(route) + IF_NAMESIZE;
-        if (route.destination != NULL) {
-            intfSize += route.destination->sa_len;
-        }
-        if (route.mask != NULL) {
-            intfSize += route.mask->sa_len;
-        }
-        if (route.gateway != NULL) {
-            intfSize += route.gateway->sa_len;
-        }
-        interface = (struct ifreq *)((uint8_t *)interface + intfSize);
-    }
-fail:
-    free(buffer);
-    close(fd);
-    return ret;
-}
-#endif /* #ifdef USE_HAIKU_CODE */
-
-#if !defined(USE_PROC_NET_ROUTE) && !defined(USE_SOCKET_ROUTE) && !defined(USE_SYSCTL_NET_ROUTE) && !defined(USE_WIN32_CODE) && !defined(USE_WIN32_CODE_2) && !defined(USE_HAIKU_CODE)
-int getdefaultgateway(in_addr_t * addr)
-{
-	return -1;
-}
-#endif

+ 0 - 49
ext/libnatpmp/getgateway.h

@@ -1,49 +0,0 @@
-/* $Id: getgateway.h,v 1.8 2014/04/22 09:15:40 nanard Exp $ */
-/* libnatpmp
-Copyright (c) 2007-2014, Thomas BERNARD
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * The name of the author may not be used to endorse or promote products
-	  derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-#ifndef __GETGATEWAY_H__
-#define __GETGATEWAY_H__
-
-#ifdef WIN32
-#if !defined(_MSC_VER) || _MSC_VER >= 1600
-#include <stdint.h>
-#else
-typedef unsigned long uint32_t;
-typedef unsigned short uint16_t;
-#endif
-#define in_addr_t uint32_t
-#endif
-/* #include "declspec.h" */
-
-/* getdefaultgateway() :
- * return value :
- *    0 : success
- *   -1 : failure    */
-/* LIBSPEC */int getdefaultgateway(in_addr_t * addr);
-
-#endif

+ 0 - 383
ext/libnatpmp/natpmp.c

@@ -1,383 +0,0 @@
-/* $Id: natpmp.c,v 1.20 2015/05/27 12:43:15 nanard Exp $ */
-/* libnatpmp
-Copyright (c) 2007-2015, Thomas BERNARD
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * The name of the author may not be used to endorse or promote products
-	  derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-#ifdef __linux__
-#define _BSD_SOURCE 1
-#endif
-#include <string.h>
-#include <time.h>
-#if !defined(_MSC_VER)
-#include <sys/time.h>
-#endif
-#ifdef WIN32
-#include <errno.h>
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <io.h>
-#ifndef EWOULDBLOCK
-#define EWOULDBLOCK WSAEWOULDBLOCK
-#endif
-#ifndef ECONNREFUSED
-#define ECONNREFUSED WSAECONNREFUSED
-#endif
-#include "wingettimeofday.h"
-#define gettimeofday natpmp_gettimeofday
-#else
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#define closesocket close
-#endif
-#include "natpmp.h"
-#include "getgateway.h"
-#include <stdio.h>
-
-LIBSPEC int initnatpmp(natpmp_t * p, int forcegw, in_addr_t forcedgw)
-{
-#ifdef WIN32
-	u_long ioctlArg = 1;
-#else
-	int flags;
-#endif
-	struct sockaddr_in addr;
-	if(!p)
-		return NATPMP_ERR_INVALIDARGS;
-	memset(p, 0, sizeof(natpmp_t));
-	p->s = socket(PF_INET, SOCK_DGRAM, 0);
-	if(p->s < 0)
-		return NATPMP_ERR_SOCKETERROR;
-#ifdef WIN32
-	if(ioctlsocket(p->s, FIONBIO, &ioctlArg) == SOCKET_ERROR)
-		return NATPMP_ERR_FCNTLERROR;
-#else
-	if((flags = fcntl(p->s, F_GETFL, 0)) < 0)
-		return NATPMP_ERR_FCNTLERROR;
-	if(fcntl(p->s, F_SETFL, flags | O_NONBLOCK) < 0)
-		return NATPMP_ERR_FCNTLERROR;
-#endif
-
-	if(forcegw) {
-		p->gateway = forcedgw;
-	} else {
-		if(getdefaultgateway(&(p->gateway)) < 0)
-			return NATPMP_ERR_CANNOTGETGATEWAY;
-	}
-
-	memset(&addr, 0, sizeof(addr));
-	addr.sin_family = AF_INET;
-	addr.sin_port = htons(NATPMP_PORT);
-	addr.sin_addr.s_addr = p->gateway;
-	if(connect(p->s, (struct sockaddr *)&addr, sizeof(addr)) < 0)
-		return NATPMP_ERR_CONNECTERR;
-	return 0;
-}
-
-LIBSPEC int closenatpmp(natpmp_t * p)
-{
-	if(!p)
-		return NATPMP_ERR_INVALIDARGS;
-	if(closesocket(p->s) < 0)
-		return NATPMP_ERR_CLOSEERR;
-	return 0;
-}
-
-int sendpendingrequest(natpmp_t * p)
-{
-	int r;
-/*	struct sockaddr_in addr;*/
-	if(!p)
-		return NATPMP_ERR_INVALIDARGS;
-/*	memset(&addr, 0, sizeof(addr));
-	addr.sin_family = AF_INET;
-	addr.sin_port = htons(NATPMP_PORT);
-	addr.sin_addr.s_addr = p->gateway;
-	r = (int)sendto(p->s, p->pending_request, p->pending_request_len, 0,
-	                   (struct sockaddr *)&addr, sizeof(addr));*/
-	r = (int)send(p->s, (const char *)p->pending_request, p->pending_request_len, 0);
-	return (r<0) ? NATPMP_ERR_SENDERR : r;
-}
-
-int sendnatpmprequest(natpmp_t * p)
-{
-	int n;
-	if(!p)
-		return NATPMP_ERR_INVALIDARGS;
-	/* TODO : check if no request is already pending */
-	p->has_pending_request = 1;
-	p->try_number = 1;
-	n = sendpendingrequest(p);
-	gettimeofday(&p->retry_time, NULL);	// check errors !
-	p->retry_time.tv_usec += 250000;	/* add 250ms */
-	if(p->retry_time.tv_usec >= 1000000) {
-		p->retry_time.tv_usec -= 1000000;
-		p->retry_time.tv_sec++;
-	}
-	return n;
-}
-
-LIBSPEC int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout)
-{
-	struct timeval now;
-	if(!p || !timeout)
-		return NATPMP_ERR_INVALIDARGS;
-	if(!p->has_pending_request)
-		return NATPMP_ERR_NOPENDINGREQ;
-	if(gettimeofday(&now, NULL) < 0)
-		return NATPMP_ERR_GETTIMEOFDAYERR;
-	timeout->tv_sec = p->retry_time.tv_sec - now.tv_sec;
-	timeout->tv_usec = p->retry_time.tv_usec - now.tv_usec;
-	if(timeout->tv_usec < 0) {
-		timeout->tv_usec += 1000000;
-		timeout->tv_sec--;
-	}
-	return 0;
-}
-
-LIBSPEC int sendpublicaddressrequest(natpmp_t * p)
-{
-	if(!p)
-		return NATPMP_ERR_INVALIDARGS;
-	//static const unsigned char request[] = { 0, 0 };
-	p->pending_request[0] = 0;
-	p->pending_request[1] = 0;
-	p->pending_request_len = 2;
-	// TODO: return 0 instead of sizeof(request) ??
-	return sendnatpmprequest(p);
-}
-
-LIBSPEC int sendnewportmappingrequest(natpmp_t * p, int protocol,
-                              uint16_t privateport, uint16_t publicport,
-							  uint32_t lifetime)
-{
-	if(!p || (protocol!=NATPMP_PROTOCOL_TCP && protocol!=NATPMP_PROTOCOL_UDP))
-		return NATPMP_ERR_INVALIDARGS;
-	p->pending_request[0] = 0;
-	p->pending_request[1] = protocol;
-	p->pending_request[2] = 0;
-	p->pending_request[3] = 0;
-	/* break strict-aliasing rules :
-	*((uint16_t *)(p->pending_request + 4)) = htons(privateport); */
-	p->pending_request[4] = (privateport >> 8) & 0xff;
-	p->pending_request[5] = privateport & 0xff;
-	/* break stric-aliasing rules :
-	*((uint16_t *)(p->pending_request + 6)) = htons(publicport); */
-	p->pending_request[6] = (publicport >> 8) & 0xff;
-	p->pending_request[7] = publicport & 0xff;
-	/* break stric-aliasing rules :
-	*((uint32_t *)(p->pending_request + 8)) = htonl(lifetime); */
-	p->pending_request[8] = (lifetime >> 24) & 0xff;
-	p->pending_request[9] = (lifetime >> 16) & 0xff;
-	p->pending_request[10] = (lifetime >> 8) & 0xff;
-	p->pending_request[11] = lifetime & 0xff;
-	p->pending_request_len = 12;
-	return sendnatpmprequest(p);
-}
-
-LIBSPEC int readnatpmpresponse(natpmp_t * p, natpmpresp_t * response)
-{
-	unsigned char buf[16];
-	struct sockaddr_in addr;
-	socklen_t addrlen = sizeof(addr);
-	int n;
-	if(!p)
-		return NATPMP_ERR_INVALIDARGS;
-	n = recvfrom(p->s, (char *)buf, sizeof(buf), 0,
-	             (struct sockaddr *)&addr, &addrlen);
-	if(n<0)
-#ifdef WIN32
-		switch(WSAGetLastError()) {
-#else
-		switch(errno) {
-#endif
-		/*case EAGAIN:*/
-		case EWOULDBLOCK:
-			n = NATPMP_TRYAGAIN;
-			break;
-		case ECONNREFUSED:
-			n = NATPMP_ERR_NOGATEWAYSUPPORT;
-			break;
-		default:
-			n = NATPMP_ERR_RECVFROM;
-		}
-	/* check that addr is correct (= gateway) */
-	else if(addr.sin_addr.s_addr != p->gateway)
-		n = NATPMP_ERR_WRONGPACKETSOURCE;
-	else {
-		response->resultcode = ntohs(*((uint16_t *)(buf + 2)));
-		response->epoch = ntohl(*((uint32_t *)(buf + 4)));
-		if(buf[0] != 0)
-			n = NATPMP_ERR_UNSUPPORTEDVERSION;
-		else if(buf[1] < 128 || buf[1] > 130)
-			n = NATPMP_ERR_UNSUPPORTEDOPCODE;
-		else if(response->resultcode != 0) {
-			switch(response->resultcode) {
-			case 1:
-				n = NATPMP_ERR_UNSUPPORTEDVERSION;
-				break;
-			case 2:
-				n = NATPMP_ERR_NOTAUTHORIZED;
-				break;
-			case 3:
-				n = NATPMP_ERR_NETWORKFAILURE;
-				break;
-			case 4:
-				n = NATPMP_ERR_OUTOFRESOURCES;
-				break;
-			case 5:
-				n = NATPMP_ERR_UNSUPPORTEDOPCODE;
-				break;
-			default:
-				n = NATPMP_ERR_UNDEFINEDERROR;
-			}
-		} else {
-			response->type = buf[1] & 0x7f;
-			if(buf[1] == 128)
-				//response->publicaddress.addr = *((uint32_t *)(buf + 8));
-				response->pnu.publicaddress.addr.s_addr = *((uint32_t *)(buf + 8));
-			else {
-				response->pnu.newportmapping.privateport = ntohs(*((uint16_t *)(buf + 8)));
-				response->pnu.newportmapping.mappedpublicport = ntohs(*((uint16_t *)(buf + 10)));
-				response->pnu.newportmapping.lifetime = ntohl(*((uint32_t *)(buf + 12)));
-			}
-			n = 0;
-		}
-	}
-	return n;
-}
-
-int readnatpmpresponseorretry(natpmp_t * p, natpmpresp_t * response)
-{
-	int n;
-	if(!p || !response)
-		return NATPMP_ERR_INVALIDARGS;
-	if(!p->has_pending_request)
-		return NATPMP_ERR_NOPENDINGREQ;
-	n = readnatpmpresponse(p, response);
-	if(n<0) {
-		if(n==NATPMP_TRYAGAIN) {
-			struct timeval now;
-			gettimeofday(&now, NULL);	// check errors !
-			if(timercmp(&now, &p->retry_time, >=)) {
-				int delay, r;
-				if(p->try_number >= 9) {
-					return NATPMP_ERR_NOGATEWAYSUPPORT;
-				}
-				/*printf("retry! %d\n", p->try_number);*/
-				delay = 250 * (1<<p->try_number);	// ms
-				/*for(i=0; i<p->try_number; i++)
-					delay += delay;*/
-				p->retry_time.tv_sec += (delay / 1000);
-				p->retry_time.tv_usec += (delay % 1000) * 1000;
-				if(p->retry_time.tv_usec >= 1000000) {
-					p->retry_time.tv_usec -= 1000000;
-					p->retry_time.tv_sec++;
-				}
-				p->try_number++;
-				r = sendpendingrequest(p);
-				if(r<0)
-					return r;
-			}
-		}
-	} else {
-		p->has_pending_request = 0;
-	}
-	return n;
-}
-
-#ifdef ENABLE_STRNATPMPERR
-LIBSPEC const char * strnatpmperr(int r)
-{
-	const char * s;
-	switch(r) {
-	case NATPMP_ERR_INVALIDARGS:
-		s = "invalid arguments";
-		break;
-	case NATPMP_ERR_SOCKETERROR:
-		s = "socket() failed";
-		break;
-	case NATPMP_ERR_CANNOTGETGATEWAY:
-		s = "cannot get default gateway ip address";
-		break;
-	case NATPMP_ERR_CLOSEERR:
-#ifdef WIN32
-		s = "closesocket() failed";
-#else
-		s = "close() failed";
-#endif
-		break;
-	case NATPMP_ERR_RECVFROM:
-		s = "recvfrom() failed";
-		break;
-	case NATPMP_ERR_NOPENDINGREQ:
-		s = "no pending request";
-		break;
-	case NATPMP_ERR_NOGATEWAYSUPPORT:
-		s = "the gateway does not support nat-pmp";
-		break;
-	case NATPMP_ERR_CONNECTERR:
-		s = "connect() failed";
-		break;
-	case NATPMP_ERR_WRONGPACKETSOURCE:
-		s = "packet not received from the default gateway";
-		break;
-	case NATPMP_ERR_SENDERR:
-		s = "send() failed";
-		break;
-	case NATPMP_ERR_FCNTLERROR:
-		s = "fcntl() failed";
-		break;
-	case NATPMP_ERR_GETTIMEOFDAYERR:
-		s = "gettimeofday() failed";
-		break;
-	case NATPMP_ERR_UNSUPPORTEDVERSION:
-		s = "unsupported nat-pmp version error from server";
-		break;
-	case NATPMP_ERR_UNSUPPORTEDOPCODE:
-		s = "unsupported nat-pmp opcode error from server";
-		break;
-	case NATPMP_ERR_UNDEFINEDERROR:
-		s = "undefined nat-pmp server error";
-		break;
-	case NATPMP_ERR_NOTAUTHORIZED:
-		s = "not authorized";
-		break;
-	case NATPMP_ERR_NETWORKFAILURE:
-		s = "network failure";
-		break;
-	case NATPMP_ERR_OUTOFRESOURCES:
-		s = "nat-pmp server out of resources";
-		break;
-	default:
-		s = "Unknown libnatpmp error";
-	}
-	return s;
-}
-#endif
-

+ 0 - 219
ext/libnatpmp/natpmp.h

@@ -1,219 +0,0 @@
-/* $Id: natpmp.h,v 1.20 2014/04/22 09:15:40 nanard Exp $ */
-/* libnatpmp
-Copyright (c) 2007-2014, Thomas BERNARD
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * The name of the author may not be used to endorse or promote products
-	  derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-#ifndef __NATPMP_H__
-#define __NATPMP_H__
-
-/* NAT-PMP Port as defined by the NAT-PMP draft */
-#define NATPMP_PORT (5351)
-
-#include <time.h>
-#if !defined(_MSC_VER)
-#include <sys/time.h>
-#endif	/* !defined(_MSC_VER) */
-
-#ifdef WIN32
-#include <winsock2.h>
-#if !defined(_MSC_VER) || _MSC_VER >= 1600
-#include <stdint.h>
-#else	/* !defined(_MSC_VER) || _MSC_VER >= 1600 */
-typedef unsigned long uint32_t;
-typedef unsigned short uint16_t;
-#endif	/* !defined(_MSC_VER) || _MSC_VER >= 1600 */
-#define in_addr_t uint32_t
-#include "declspec.h"
-#else	/* WIN32 */
-#define LIBSPEC
-#include <netinet/in.h>
-#endif	/* WIN32 */
-
-/* causes problem when installing. Maybe should it be inlined ? */
-/* #include "declspec.h" */
-
-typedef struct {
-	int s;	/* socket */
-	in_addr_t gateway;	/* default gateway (IPv4) */
-	int has_pending_request;
-	unsigned char pending_request[12];
-	int pending_request_len;
-	int try_number;
-	struct timeval retry_time;
-} natpmp_t;
-
-typedef struct {
-	uint16_t type;	/* NATPMP_RESPTYPE_* */
-	uint16_t resultcode;	/* NAT-PMP response code */
-	uint32_t epoch;	/* Seconds since start of epoch */
-	union {
-		struct {
-			//in_addr_t addr;
-			struct in_addr addr;
-		} publicaddress;
-		struct {
-			uint16_t privateport;
-			uint16_t mappedpublicport;
-			uint32_t lifetime;
-		} newportmapping;
-	} pnu;
-} natpmpresp_t;
-
-/* possible values for type field of natpmpresp_t */
-#define NATPMP_RESPTYPE_PUBLICADDRESS (0)
-#define NATPMP_RESPTYPE_UDPPORTMAPPING (1)
-#define NATPMP_RESPTYPE_TCPPORTMAPPING (2)
-
-/* Values to pass to sendnewportmappingrequest() */
-#define NATPMP_PROTOCOL_UDP (1)
-#define NATPMP_PROTOCOL_TCP (2)
-
-/* return values */
-/* NATPMP_ERR_INVALIDARGS : invalid arguments passed to the function */
-#define NATPMP_ERR_INVALIDARGS (-1)
-/* NATPMP_ERR_SOCKETERROR : socket() failed. check errno for details */
-#define NATPMP_ERR_SOCKETERROR (-2)
-/* NATPMP_ERR_CANNOTGETGATEWAY : can't get default gateway IP */
-#define NATPMP_ERR_CANNOTGETGATEWAY (-3)
-/* NATPMP_ERR_CLOSEERR : close() failed. check errno for details */
-#define NATPMP_ERR_CLOSEERR (-4)
-/* NATPMP_ERR_RECVFROM : recvfrom() failed. check errno for details */
-#define NATPMP_ERR_RECVFROM (-5)
-/* NATPMP_ERR_NOPENDINGREQ : readnatpmpresponseorretry() called while
- * no NAT-PMP request was pending */
-#define NATPMP_ERR_NOPENDINGREQ (-6)
-/* NATPMP_ERR_NOGATEWAYSUPPORT : the gateway does not support NAT-PMP */
-#define NATPMP_ERR_NOGATEWAYSUPPORT (-7)
-/* NATPMP_ERR_CONNECTERR : connect() failed. check errno for details */
-#define NATPMP_ERR_CONNECTERR (-8)
-/* NATPMP_ERR_WRONGPACKETSOURCE : packet not received from the network gateway */
-#define NATPMP_ERR_WRONGPACKETSOURCE (-9)
-/* NATPMP_ERR_SENDERR : send() failed. check errno for details */
-#define NATPMP_ERR_SENDERR (-10)
-/* NATPMP_ERR_FCNTLERROR : fcntl() failed. check errno for details */
-#define NATPMP_ERR_FCNTLERROR (-11)
-/* NATPMP_ERR_GETTIMEOFDAYERR : gettimeofday() failed. check errno for details */
-#define NATPMP_ERR_GETTIMEOFDAYERR (-12)
-
-/* */
-#define NATPMP_ERR_UNSUPPORTEDVERSION (-14)
-#define NATPMP_ERR_UNSUPPORTEDOPCODE (-15)
-
-/* Errors from the server : */
-#define NATPMP_ERR_UNDEFINEDERROR (-49)
-#define NATPMP_ERR_NOTAUTHORIZED (-51)
-#define NATPMP_ERR_NETWORKFAILURE (-52)
-#define NATPMP_ERR_OUTOFRESOURCES (-53)
-
-/* NATPMP_TRYAGAIN : no data available for the moment. try again later */
-#define NATPMP_TRYAGAIN (-100)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* initnatpmp()
- * initialize a natpmp_t object
- * With forcegw=1 the gateway is not detected automaticaly.
- * Return values :
- * 0 = OK
- * NATPMP_ERR_INVALIDARGS
- * NATPMP_ERR_SOCKETERROR
- * NATPMP_ERR_FCNTLERROR
- * NATPMP_ERR_CANNOTGETGATEWAY
- * NATPMP_ERR_CONNECTERR */
-LIBSPEC int initnatpmp(natpmp_t * p, int forcegw, in_addr_t forcedgw);
-
-/* closenatpmp()
- * close resources associated with a natpmp_t object
- * Return values :
- * 0 = OK
- * NATPMP_ERR_INVALIDARGS
- * NATPMP_ERR_CLOSEERR */
-LIBSPEC int closenatpmp(natpmp_t * p);
-
-/* sendpublicaddressrequest()
- * send a public address NAT-PMP request to the network gateway
- * Return values :
- * 2 = OK (size of the request)
- * NATPMP_ERR_INVALIDARGS
- * NATPMP_ERR_SENDERR */
-LIBSPEC int sendpublicaddressrequest(natpmp_t * p);
-
-/* sendnewportmappingrequest()
- * send a new port mapping NAT-PMP request to the network gateway
- * Arguments :
- * protocol is either NATPMP_PROTOCOL_TCP or NATPMP_PROTOCOL_UDP,
- * lifetime is in seconds.
- * To remove a port mapping, set lifetime to zero.
- * To remove all port mappings to the host, set lifetime and both ports
- * to zero.
- * Return values :
- * 12 = OK (size of the request)
- * NATPMP_ERR_INVALIDARGS
- * NATPMP_ERR_SENDERR */
-LIBSPEC int sendnewportmappingrequest(natpmp_t * p, int protocol,
-                              uint16_t privateport, uint16_t publicport,
-							  uint32_t lifetime);
-
-/* getnatpmprequesttimeout()
- * fills the timeval structure with the timeout duration of the
- * currently pending NAT-PMP request.
- * Return values :
- * 0 = OK
- * NATPMP_ERR_INVALIDARGS
- * NATPMP_ERR_GETTIMEOFDAYERR
- * NATPMP_ERR_NOPENDINGREQ */
-LIBSPEC int getnatpmprequesttimeout(natpmp_t * p, struct timeval * timeout);
-
-/* readnatpmpresponseorretry()
- * fills the natpmpresp_t structure if possible
- * Return values :
- * 0 = OK
- * NATPMP_TRYAGAIN
- * NATPMP_ERR_INVALIDARGS
- * NATPMP_ERR_NOPENDINGREQ
- * NATPMP_ERR_NOGATEWAYSUPPORT
- * NATPMP_ERR_RECVFROM
- * NATPMP_ERR_WRONGPACKETSOURCE
- * NATPMP_ERR_UNSUPPORTEDVERSION
- * NATPMP_ERR_UNSUPPORTEDOPCODE
- * NATPMP_ERR_NOTAUTHORIZED
- * NATPMP_ERR_NETWORKFAILURE
- * NATPMP_ERR_OUTOFRESOURCES
- * NATPMP_ERR_UNSUPPORTEDOPCODE
- * NATPMP_ERR_UNDEFINEDERROR */
-LIBSPEC int readnatpmpresponseorretry(natpmp_t * p, natpmpresp_t * response);
-
-#ifdef ENABLE_STRNATPMPERR
-LIBSPEC const char * strnatpmperr(int t);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif

+ 0 - 60
ext/libnatpmp/wingettimeofday.c

@@ -1,60 +0,0 @@
-/* $Id: wingettimeofday.c,v 1.6 2013/09/10 20:13:26 nanard Exp $ */
-/* libnatpmp
-Copyright (c) 2007-2013, Thomas BERNARD
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * The name of the author may not be used to endorse or promote products
-	  derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-#ifdef WIN32
-#if defined(_MSC_VER)
-struct timeval {
-	long    tv_sec;
-	long    tv_usec;
-};
-#else
-#include <sys/time.h>
-#endif
-
-typedef struct _FILETIME {
-    unsigned long dwLowDateTime;
-    unsigned long dwHighDateTime;
-} FILETIME;
-
-void __stdcall GetSystemTimeAsFileTime(FILETIME*);
-
-int natpmp_gettimeofday(struct timeval* p, void* tz /* IGNORED */) {
-  union {
-   long long ns100; /*time since 1 Jan 1601 in 100ns units */
-   FILETIME ft;
-  } _now;
-
-	if(!p)
-		return -1;
-  GetSystemTimeAsFileTime( &(_now.ft) );
-  p->tv_usec =(long)((_now.ns100 / 10LL) % 1000000LL );
-  p->tv_sec = (long)((_now.ns100-(116444736000000000LL))/10000000LL);
-  return 0;
-}
-#endif
-

+ 0 - 39
ext/libnatpmp/wingettimeofday.h

@@ -1,39 +0,0 @@
-/* $Id: wingettimeofday.h,v 1.5 2013/09/11 07:22:25 nanard Exp $ */
-/* libnatpmp
-Copyright (c) 2007-2013, Thomas BERNARD
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * The name of the author may not be used to endorse or promote products
-	  derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-#ifndef __WINGETTIMEOFDAY_H__
-#define __WINGETTIMEOFDAY_H__
-#ifdef WIN32
-#if defined(_MSC_VER)
-#include <time.h>
-#else
-#include <sys/time.h>
-#endif
-int natpmp_gettimeofday(struct timeval* p, void* tz /* IGNORED */);
-#endif
-#endif

+ 0 - 691
ext/miniupnpc/Changelog.txt

@@ -1,691 +0,0 @@
-$Id: Changelog.txt,v 1.229 2017/12/12 11:26:25 nanard Exp $
-miniUPnP client Changelog.
-
-2017/12/11:
-  Fix buffer over run in minixml.c
-  Fix uninitialized variable access in upnpreplyparse.c
-
-2017/05/05:
-  Fix CVE-2017-8798   Thanks to tin/Team OSTStrom
-
-2016/11/11:
-  check strlen before memcmp in XML parsing portlistingparse.c
-  fix build under SOLARIS and CYGWIN
-
-2016/10/11:
-  Add python 3 compatibility to IGD test
-
-VERSION 2.0 : released 2016/04/19
-
-2016/01/24:
-  change miniwget to return HTTP status code
-  increments API_VERSION to 16
-
-2016/01/22:
-  Improve UPNPIGD_IsConnected() to check if WAN address is not private.
-  parse HTTP response status line in miniwget.c
-
-2015/10/26:
-  snprintf() overflow check. check overflow in simpleUPnPcommand2()
-
-2015/10/25:
-  fix compilation with old macs
-  fix compilation with mingw32 (for Appveyor)
-  fix python module for python <= 2.3
-
-2015/10/08:
-  Change sameport to localport
-    see https://github.com/miniupnp/miniupnp/pull/120
-  increments API_VERSION to 15
-
-2015/09/15:
-  Fix buffer overflow in igd_desc_parse.c/IGDstartelt()
-    Discovered by Aleksandar Nikolic of Cisco Talos
-
-2015/08/28:
-  move ssdpDiscoverDevices() to minissdpc.c
-
-2015/08/27:
-  avoid unix socket leak in getDevicesFromMiniSSDPD()
-
-2015/08/16:
-  Also accept "Up" as ConnectionStatus value
-
-2015/07/23:
-  split getDevicesFromMiniSSDPD
-  add ttl argument to upnpDiscover() functions
-  increments API_VERSION to 14
-
-2015/07/22:
-  Read USN from SSDP messages.
-
-2015/07/15:
-  Check malloc/calloc
-
-2015/06/16:
-  update getDevicesFromMiniSSDPD() to process longer minissdpd
-    responses
-
-2015/05/22:
-  add searchalltypes param to upnpDiscoverDevices()
-  increments API_VERSION to 13
-
-2015/04/30:
-  upnpc: output version on the terminal
-
-2015/04/27:
-  _BSD_SOURCE is deprecated in favor of _DEFAULT_SOURCE
-  fix CMakeLists.txt COMPILE_DEFINITIONS
-  fix getDevicesFromMiniSSDPD() not setting scope_id
-  improve -r command of upnpc command line tool
-
-2014/11/17:
-  search all :
-    upnpDiscoverDevices() / upnpDiscoverAll() functions
-    listdevices executable
-  increment API_VERSION to 12
-  validate igd_desc_parse
-
-2014/11/13:
-  increment API_VERSION to 11
-
-2014/11/05:
-  simplified function GetUPNPUrls()
-
-2014/09/11:
-  use remoteHost arg of DeletePortMapping
-
-2014/09/06:
-  Fix python3 build
-
-2014/07/01:
-  Fix parsing of IGD2 root descriptions
-
-2014/06/10:
-  rename LIBSPEC to MINIUPNP_LIBSPEC
-
-2014/05/15:
-  Add support for IGD2 AddAnyPortMapping and DeletePortMappingRange
-
-2014/02/05:
-  handle EINPROGRESS after connect()
-
-2014/02/03:
-  minixml now handle XML comments
-
-VERSION 1.9 : released 2014/01/31
-
-2014/01/31:
-  added argument remoteHost to UPNP_GetSpecificPortMappingEntry()
-  increment API_VERSION to 10
-
-2013/12/09:
-  --help and -h arguments in upnpc.c
-
-2013/10/07:
-  fixed potential buffer overrun in miniwget.c
-  Modified UPNP_GetValidIGD() to check for ExternalIpAddress
-
-2013/08/01:
-  define MAXHOSTNAMELEN if not already done
-
-2013/06/06:
-  update upnpreplyparse to allow larger values (128 chars instead of 64)
-
-2013/05/14:
-  Update upnpreplyparse to take into account "empty" elements
-  validate upnpreplyparse.c code with "make check"
-
-2013/05/03:
-  Fix Solaris build thanks to Maciej Małecki
-
-2013/04/27:
-  Fix testminiwget.sh for BSD
-
-2013/03/23:
-  Fixed Makefile for *BSD
-
-2013/03/11:
-  Update Makefile to use JNAerator version 0.11
-
-2013/02/11:
-  Fix testminiwget.sh for use with dash
-  Use $(DESTDIR) in Makefile
-
-VERSION 1.8 : released 2013/02/06
-
-2012/10/16:
-  fix testminiwget with no IPv6 support
-
-2012/09/27:
-  Rename all include guards to not clash with C99
-  (7.1.3 Reserved identifiers).
-
-2012/08/30:
-  Added -e option to upnpc program (set description for port mappings)
-
-2012/08/29:
-  Python 3 support (thanks to Christopher Foo)
-
-2012/08/11:
-  Fix a memory link in UPNP_GetValidIGD()
-  Try to handle scope id in link local IPv6 URL under MS Windows
-
-2012/07/20:
-  Disable HAS_IP_MREQN on DragonFly BSD
-
-2012/06/28:
-  GetUPNPUrls() now inserts scope into link-local IPv6 addresses
-
-2012/06/23:
-  More error return checks in upnpc.c
-  #define MINIUPNPC_GET_SRC_ADDR enables receivedata() to get scope_id
-  parseURL() now parses IPv6 addresses scope
-  new parameter for miniwget() : IPv6 address scope
-  increment API_VERSION to 9
-
-2012/06/20:
-  fixed CMakeLists.txt
-
-2012/05/29
-  Improvements in testminiwget.sh
-
-VERSION 1.7 : released 2012/05/24
-
-2012/05/01:
-  Cleanup settings of CFLAGS in Makefile
-  Fix signed/unsigned integer comparaisons
-
-2012/04/20:
-  Allow to specify protocol with TCP or UDP for -A option
-
-2012/04/09:
-  Only try to fetch XML description once in UPNP_GetValidIGD()
-  Added -ansi flag to compilation, and fixed C++ comments to ANSI C comments.
-
-2012/04/05:
-  minor improvements to minihttptestserver.c
-
-2012/03/15:
-  upnperrors.c returns valid error string for unrecognized error codes
-
-2012/03/08:
-  make minihttptestserver listen on loopback interface instead of 0.0.0.0
-
-2012/01/25:
-  Maven installation thanks to Alexey Kuznetsov
-
-2012/01/21:
-  Replace WIN32 macro by _WIN32
-
-2012/01/19:
-  Fixes in java wrappers thanks to Alexey Kuznetsov :
-    https://github.com/axet/miniupnp/tree/fix-javatest/miniupnpc
-  Make and install .deb packages (python) thanks to Alexey Kuznetsov :
-    https://github.com/axet/miniupnp/tree/feature-debbuild/miniupnpc
-
-2012/01/07:
-  The multicast interface can now be specified by name with IPv4.
-
-2012/01/02:
-  Install man page
-
-2011/11/25:
-  added header to Port Mappings list in upnpc.c
-
-2011/10/09:
-  Makefile : make clean now removes jnaerator generated files.
-  MINIUPNPC_VERSION in miniupnpc.h (updated by make)
-
-2011/09/12:
-  added rootdescURL to UPNPUrls structure.
-
-VERSION 1.6 : released 2011/07/25
-
-2011/07/25:
-  Update doc for version 1.6 release
-
-2011/06/18:
-  Fix for windows in miniwget.c
-
-2011/06/04:
-  display remote host in port mapping listing
-
-2011/06/03:
-  Fix in make install : there were missing headers
-
-2011/05/26:
-  Fix the socket leak in miniwget thanks to Richard Marsh.
-  Permit to add leaseduration in -a command. Display lease duration.
-
-2011/05/15:
-  Try both LinkLocal and SiteLocal multicast address for SSDP in IPv6
-
-2011/05/09:
-  add a test in testminiwget.sh.
-  more error checking in miniwget.c
-
-2011/05/06:
-  Adding some tool to test and validate miniwget.c
-  simplified and debugged miniwget.c
-
-2011/04/11:
-  moving ReceiveData() to a receivedata.c file.
-  parsing presentation url
-  adding IGD v2 WANIPv6FirewallControl commands
-
-2011/04/10:
-  update of miniupnpcmodule.c
-  comments in miniwget.c, update in testminiwget
-  Adding errors codes from IGD v2
-  new functions in upnpc.c for IGD v2
-
-2011/04/09:
-  Support for litteral ip v6 address in miniwget
-
-2011/04/08:
-  Adding support for urn:schemas-upnp-org:service:WANIPv6FirewallControl:1
-  Updating APIVERSION
-  Supporting IPV6 in upnpDiscover()
-  Adding a -6 option to upnpc command line tool
-
-2011/03/18:
-  miniwget/parseURL() : return an error when url param is null.
-  fixing GetListOfPortMappings()
-
-2011/03/14:
-  upnpDiscover() now reporting an error code.
-  improvements in comments.
-
-2011/03/11:
-  adding miniupnpcstrings.h.cmake and CMakeLists.txt files.
-
-2011/02/15:
-  Implementation of GetListOfPortMappings()
-
-2011/02/07:
-  updates to minixml to support character data starting with spaces
-  minixml now support CDATA
-  upnpreplyparse treats <NewPortListing> specificaly
-  change in simpleUPnPcommand to return the buffer (simplification)
-
-2011/02/06:
-  Added leaseDuration argument to AddPortMapping()
-  Starting to implement GetListOfPortMappings()
-
-2011/01/11:
-  updating wingenminiupnpcstrings.c
-
-2011/01/04:
-  improving updateminiupnpcstrings.sh
-
-VERSION 1.5 : released 2011/01/01
-
-2010/12/21:
-  use NO_GETADDRINFO macro to disable the use of getaddrinfo/freeaddrinfo
-
-2010/12/11:
-  Improvements on getHTTPResponse() code.
-
-2010/12/09:
-  new code for miniwget that handle Chunked transfer encoding
-  using getHTTPResponse() in SOAP call code
-  Adding MANIFEST.in for 'python setup.py bdist_rpm'
-
-2010/11/25:
-  changes to minissdpc.c to compile under Win32.
-  see http://miniupnp.tuxfamily.org/forum/viewtopic.php?t=729
-
-2010/09/17:
-  Various improvement to Makefile from Michał Górny
-
-2010/08/05:
-  Adding the script "external-ip.sh" from Reuben Hawkins
-
-2010/06/09:
-  update to python module to match modification made on 2010/04/05
-  update to Java test code to match modification made on 2010/04/05
-  all UPNP_* function now return an error if the SOAP request failed
-  at HTTP level.
-
-2010/04/17:
-  Using GetBestRoute() under win32 in order to find the
-  right interface to use.
-
-2010/04/12:
-  Retrying with HTTP/1.1 if HTTP/1.0 failed. see
-  http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=1703
-
-2010/04/07:
-  avoid returning duplicates in upnpDiscover()
-
-2010/04/05:
-  Create a connecthostport.h/.c with connecthostport() function
-  and use it in miniwget and miniupnpc.
-  Use getnameinfo() instead of inet_ntop or inet_ntoa
-  Work to make miniupnpc IPV6 compatible...
-  Add java test code.
-  Big changes in order to support device having both WANIPConnection
-  and WANPPPConnection.
-
-2010/04/04:
-  Use getaddrinfo() instead of gethostbyname() in miniwget.
-
-2010/01/06:
-  #define _DARWIN_C_SOURCE for Mac OS X
-
-2009/12/19:
-  Improve MinGW32 build
-
-2009/12/11:
-  adding a MSVC9 project to build the static library and executable
-
-2009/12/10:
-  Fixing some compilation stuff for Windows/MinGW
-
-2009/12/07:
-  adaptations in Makefile and updateminiupnpcstring.sh for AmigaOS
-  some fixes for Windows when using virtual ethernet adapters (it is the
-  case with VMWare installed).
-
-2009/12/04:
-  some fixes for AmigaOS compilation
-  Changed HTTP version to HTTP/1.0 for Soap too (to prevent chunked
-  transfer encoding)
-
-2009/12/03:
-  updating printIDG and testigddescparse.c for debug.
-  modifications to compile under AmigaOS
-  adding a testminiwget program
-  Changed miniwget to advertise itself as HTTP/1.0 to prevent chunked
-  transfer encoding
-
-2009/11/26:
-  fixing updateminiupnpcstrings.sh to take into account
-  which command that does not return an error code.
-
-VERSION 1.4 : released 2009/10/30
-
-2009/10/16:
-  using Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS in python module.
-
-2009/10/10:
-  Some fixes for compilation under Solaris
-  compilation fixes : http://miniupnp.tuxfamily.org/forum/viewtopic.php?p=1464
-
-2009/09/21:
-  fixing the code to ignore EINTR during connect() calls.
-
-2009/08/07:
-  Set socket timeout for connect()
-  Some cleanup in miniwget.c
-
-2009/08/04:
-  remove multiple redirections with -d in upnpc.c
-  Print textual error code in upnpc.c
-  Ignore EINTR during the connect() and poll() calls.
-
-2009/07/29:
-  fix in updateminiupnpcstrings.sh if OS name contains "/"
-  Sending a correct value for MX: field in SSDP request
-
-2009/07/20:
-  Change the Makefile to compile under Mac OS X
-  Fixed a stackoverflow in getDevicesFromMiniSSDPD()
-
-2009/07/09:
-  Compile under Haiku
-  generate miniupnpcstrings.h.in from miniupnpcstrings.h
-
-2009/06/04:
-  patching to compile under CygWin and cross compile for minGW
-
-VERSION 1.3 :
-
-2009/04/17:
-  updating python module
-  Use strtoull() when using C99
-
-2009/02/28:
-  Fixed miniwget.c for compiling under sun
-
-2008/12/18:
-  cleanup in Makefile (thanks to Paul de Weerd)
-  minissdpc.c : win32 compatibility
-  miniupnpc.c : changed xmlns prefix from 'm' to 'u'
-  Removed NDEBUG (using DEBUG)
-
-2008/10/14:
-  Added the ExternalHost argument to DeletePortMapping()
-
-2008/10/11:
-  Added the ExternalHost argument to AddPortMapping()
-  Put a correct User-Agent: header in HTTP requests.
-
-VERSION 1.2 :
-
-2008/10/07:
-  Update docs
-
-2008/09/25:
-  Integrated sameport patch from Dario Meloni : Added a "sameport"
-  argument to upnpDiscover().
-
-2008/07/18:
-  small modif to make Clang happy :)
-
-2008/07/17:
-  #define SOAPPREFIX "s" in miniupnpc.c in order to remove SOAP-ENV...
-
-2008/07/14:
-  include declspec.h in installation (to /usr/include/miniupnpc)
-
-VERSION 1.1 :
-
-2008/07/04:
-  standard options for install/ln instead of gnu-specific stuff.
-
-2008/07/03:
-  now builds a .dll and .lib with win32. (mingw32)
-
-2008/04/28:
-  make install now install the binary of the upnpc tool
-
-2008/04/27:
-  added testupnpigd.py
-  added error strings for miniupnpc "internal" errors
-  improved python module error/exception reporting.
-
-2008/04/23:
-  Completely rewrite igd_desc_parse.c in order to be compatible with
-  Linksys WAG200G
-  Added testigddescparse
-  updated python module
-
-VERSION 1.0 :
-
-2008/02/21:
-  put some #ifdef DEBUG around DisplayNameValueList()
-
-2008/02/18:
-  Improved error reporting in upnpcommands.c
-  UPNP_GetStatusInfo() returns LastConnectionError
-
-2008/02/16:
-  better error handling in minisoap.c
-  improving display of "valid IGD found" in upnpc.c
-
-2008/02/03:
-  Fixing UPNP_GetValidIGD()
-  improved make install :)
-
-2007/12/22:
-  Adding upnperrors.c/h to provide a strupnperror() function
-  used to translate UPnP error codes to string.
-
-2007/12/19:
-  Fixing getDevicesFromMiniSSDPD()
-  improved error reporting of UPnP functions
-
-2007/12/18:
-  It is now possible to specify a different location for MiniSSDPd socket.
-  working with MiniSSDPd is now more efficient.
-  python module improved.
-
-2007/12/16:
-  improving error reporting
-
-2007/12/13:
-  Try to improve compatibility by using HTTP/1.0 instead of 1.1 and
-  XML a bit different for SOAP.
-
-2007/11/25:
-  fixed select() call for linux
-
-2007/11/15:
-  Added -fPIC to CFLAG for better shared library code.
-
-2007/11/02:
-  Fixed a potential socket leak in miniwget2()
-
-2007/10/16:
-  added a parameter to upnpDiscover() in order to allow the use of another
-  interface than the default multicast interface.
-
-2007/10/12:
-  Fixed the creation of symbolic link in Makefile
-
-2007/10/08:
-  Added man page
-
-2007/10/02:
-  fixed memory bug in GetUPNPUrls()
-
-2007/10/01:
-  fixes in the Makefile
-  Added UPNP_GetIGDFromUrl() and adapted the sample program accordingly.
-  Added SONAME in the shared library to please debian :)
-  fixed MS Windows compilation (minissdpd is not available under MS Windows).
-
-2007/09/25:
-  small change to Makefile to be able to install in a different location
-  (default is /usr)
-
-2007/09/24:
-  now compiling both shared and static library
-
-2007/09/19:
-  Cosmetic changes on upnpc.c
-
-2007/09/02:
-  adapting to new miniSSDPd (release version ?)
-
-2007/08/31:
-  Usage of miniSSDPd to skip discovery process.
-
-2007/08/27:
-  fixed python module to allow compilation with Python older than Python 2.4
-
-2007/06/12:
-  Added a python module.
-
-2007/05/19:
-  Fixed compilation under MinGW
-
-2007/05/15:
-  fixed a memory leak in AddPortMapping()
-  Added testupnpreplyparse executable to check the parsing of
-  upnp soap messages
-  minixml now ignore namespace prefixes.
-
-2007/04/26:
-  upnpc now displays external ip address with -s or -l
-
-2007/04/11:
-  changed MINIUPNPC_URL_MAXSIZE to 128 to accomodate the "BT Voyager 210"
-
-2007/03/19:
-  cleanup in miniwget.c
-
-2007/03/01:
-  Small typo fix...
-
-2007/01/30:
-  Now parsing the HTTP header from SOAP responses in order to
-  get content-length value.
-
-2007/01/29:
-  Fixed the Soap Query to speedup the HTTP request.
-  added some Win32 DLL stuff...
-
-2007/01/27:
-  Fixed some WIN32 compatibility issues
-
-2006/12/14:
-  Added UPNPIGD_IsConnected() function in miniupnp.c/.h
-  Added UPNP_GetValidIGD() in miniupnp.c/.h
-  cleaned upnpc.c main(). now using UPNP_GetValidIGD()
-
-2006/12/07:
-  Version 1.0-RC1 released
-
-2006/12/03:
-  Minor changes to compile under SunOS/Solaris
-
-2006/11/30:
-  made a minixml parser validator program
-  updated minixml to handle attributes correctly
-
-2006/11/22:
-  Added a -r option to the upnpc sample thanks to Alexander Hubmann.
-
-2006/11/19:
-  Cleanup code to make it more ANSI C compliant
-
-2006/11/10:
-  detect and display local lan address.
-
-2006/11/04:
-  Packets and Bytes Sent/Received are now unsigned int.
-
-2006/11/01:
-  Bug fix thanks to Giuseppe D'Angelo
-
-2006/10/31:
-  C++ compatibility for .h files.
-  Added a way to get ip Address on the LAN used to reach the IGD.
-
-2006/10/25:
-  Added M-SEARCH to the services in the discovery process.
-
-2006/10/22:
-  updated the Makefile to use makedepend, added a "make install"
-  update Makefile
-
-2006/10/20:
-  fixing the description url parsing thanks to patch sent by
-  Wayne Dawe.
-  Fixed/translated some comments.
-  Implemented a better discover process, first looking
-  for IGD then for root devices (as some devices only reply to
-  M-SEARCH for root devices).
-
-2006/09/02:
-  added freeUPNPDevlist() function.
-
-2006/08/04:
-  More command line arguments checking
-
-2006/08/01:
-  Added the .bat file to compile under Win32 with minGW32
-
-2006/07/31:
-  Fixed the rootdesc parser (igd_desc_parse.c)
-
-2006/07/20:
-  parseMSEARCHReply() is now returning the ST: line as well
-  starting changes to detect several UPnP devices on the network
-
-2006/07/19:
-  using GetCommonLinkProperties to get down/upload bitrate
-

+ 0 - 27
ext/miniupnpc/LICENSE

@@ -1,27 +0,0 @@
-MiniUPnPc
-Copyright (c) 2005-2016, Thomas BERNARD
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * The name of the author may not be used to endorse or promote products
-	  derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-

+ 0 - 63
ext/miniupnpc/README

@@ -1,63 +0,0 @@
-Project: miniupnp
-Project web page: http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/
-github: https://github.com/miniupnp/miniupnp
-Author: Thomas Bernard
-Copyright (c) 2005-2017 Thomas Bernard
-This software is subject to the conditions detailed in the
-LICENSE file provided within this distribution.
-
-
-* miniUPnP Client - miniUPnPc *
-
-To compile, simply run 'gmake' (could be 'make' on your system).
-Under win32, to compile with MinGW, type "mingw32make.bat".
-MS Visual C solution and project files are supplied in the msvc/ subdirectory.
-
-The compilation is known to work under linux, FreeBSD,
-OpenBSD, MacOS X, AmigaOS and cygwin.
-The official AmigaOS4.1 SDK was used for AmigaOS4 and GeekGadgets for AmigaOS3.
-upx (http://upx.sourceforge.net) is used to compress the win32 .exe files.
-
-To install the library and headers on the system use :
-> su
-> make install
-> exit
-
-alternatively, to install into a specific location, use :
-> INSTALLPREFIX=/usr/local make install
-
-upnpc.c is a sample client using the libminiupnpc.
-To use the libminiupnpc in your application, link it with
-libminiupnpc.a (or .so) and use the following functions found in miniupnpc.h,
-upnpcommands.h and miniwget.h :
-- upnpDiscover()
-- UPNP_GetValidIGD()
-- miniwget()
-- parserootdesc()
-- GetUPNPUrls()
-- UPNP_* (calling UPNP methods)
-
-Note : use #include <miniupnpc/miniupnpc.h> etc... for the includes
-and -lminiupnpc for the link
-
-Discovery process is speeded up when MiniSSDPd is running on the machine.
-
-
-* Python module *
-
-you can build a python module with 'make pythonmodule'
-and install it with 'make installpythonmodule'.
-setup.py (and setupmingw32.py) are included in the distribution.
-
-
-Feel free to contact me if you have any problem :
-e-mail : [email protected]
-
-If you are using libminiupnpc in your application, please
-send me an email !
-
-For any question, you can use the web forum :
-https://miniupnp.tuxfamily.org/forum/
-
-Bugs should be reported on github :
-https://github.com/miniupnp/miniupnp/issues

+ 0 - 1
ext/miniupnpc/VERSION

@@ -1 +0,0 @@
-2.0

+ 0 - 54
ext/miniupnpc/codelength.h

@@ -1,54 +0,0 @@
-/* $Id: codelength.h,v 1.5 2015/07/09 12:40:18 nanard Exp $ */
-/* Project : miniupnp
- * Author : Thomas BERNARD
- * copyright (c) 2005-2015 Thomas Bernard
- * This software is subjet to the conditions detailed in the
- * provided LICENCE file. */
-#ifndef CODELENGTH_H_INCLUDED
-#define CODELENGTH_H_INCLUDED
-
-/* Encode length by using 7bit per Byte :
- * Most significant bit of each byte specifies that the
- * following byte is part of the code */
-
-/* n : unsigned
- * p : unsigned char *
- */
-#define DECODELENGTH(n, p) n = 0; \
-                           do { n = (n << 7) | (*p & 0x7f); } \
-                           while((*(p++)&0x80) && (n<(1<<25)));
-
-/* n :    unsigned
- * READ : function/macro to read one byte (unsigned char)
- */
-#define DECODELENGTH_READ(n, READ) \
-	n = 0; \
-	do { \
-		unsigned char c; \
-		READ(c); \
-		n = (n << 7) | (c & 0x07f); \
-		if(!(c&0x80)) break; \
-	} while(n<(1<<25));
-
-/* n :       unsigned
- * p :       unsigned char *
- * p_limit : unsigned char *
- */
-#define DECODELENGTH_CHECKLIMIT(n, p, p_limit) \
-	n = 0; \
-	do { \
-		if((p) >= (p_limit)) break; \
-		n = (n << 7) | (*(p) & 0x7f); \
-	} while((*((p)++)&0x80) && (n<(1<<25)));
-
-
-/* n : unsigned
- * p : unsigned char *
- */
-#define CODELENGTH(n, p) if(n>=268435456) *(p++) = (n >> 28) | 0x80; \
-                         if(n>=2097152) *(p++) = (n >> 21) | 0x80; \
-                         if(n>=16384) *(p++) = (n >> 14) | 0x80; \
-                         if(n>=128) *(p++) = (n >> 7) | 0x80; \
-                         *(p++) = n & 0x7f;
-
-#endif /* CODELENGTH_H_INCLUDED */

+ 0 - 262
ext/miniupnpc/connecthostport.c

@@ -1,262 +0,0 @@
-/* $Id: connecthostport.c,v 1.17 2017/04/21 09:58:30 nanard Exp $ */
-/* Project : miniupnp
- * Author : Thomas Bernard
- * Copyright (c) 2010-2017 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution. */
-
-/* use getaddrinfo() or gethostbyname()
- * uncomment the following line in order to use gethostbyname() */
-#ifdef NO_GETADDRINFO
-#define USE_GETHOSTBYNAME
-#endif
-
-#include <string.h>
-#include <stdio.h>
-#ifdef _WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <io.h>
-#define MAXHOSTNAMELEN 64
-#define snprintf _snprintf
-#define herror
-#define socklen_t int
-#else /* #ifdef _WIN32 */
-#include <unistd.h>
-#include <sys/types.h>
-#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
-#include <sys/time.h>
-#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
-#include <sys/param.h>
-#include <sys/select.h>
-#include <errno.h>
-#define closesocket close
-#include <netdb.h>
-#include <netinet/in.h>
-/* defining MINIUPNPC_IGNORE_EINTR enable the ignore of interruptions
- * during the connect() call */
-#define MINIUPNPC_IGNORE_EINTR
-#include <sys/socket.h>
-#include <sys/select.h>
-#endif /* #else _WIN32 */
-
-/* definition of PRINT_SOCKET_ERROR */
-#ifdef _WIN32
-#define PRINT_SOCKET_ERROR(x)    fprintf(stderr, "Socket error: %s, %d\n", x, WSAGetLastError());
-#else
-#define PRINT_SOCKET_ERROR(x) perror(x)
-#endif
-
-#if defined(__amigaos__) || defined(__amigaos4__)
-#define herror(A) printf("%s\n", A)
-#endif
-
-#include "connecthostport.h"
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif
-
-/* connecthostport()
- * return a socket connected (TCP) to the host and port
- * or -1 in case of error */
-int connecthostport(const char * host, unsigned short port,
-                    unsigned int scope_id)
-{
-	int s, n;
-#ifdef USE_GETHOSTBYNAME
-	struct sockaddr_in dest;
-	struct hostent *hp;
-#else /* #ifdef USE_GETHOSTBYNAME */
-	char tmp_host[MAXHOSTNAMELEN+1];
-	char port_str[8];
-	struct addrinfo *ai, *p;
-	struct addrinfo hints;
-#endif /* #ifdef USE_GETHOSTBYNAME */
-#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
-	struct timeval timeout;
-#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
-
-#ifdef USE_GETHOSTBYNAME
-	hp = gethostbyname(host);
-	if(hp == NULL)
-	{
-		herror(host);
-		return -1;
-	}
-	memcpy(&dest.sin_addr, hp->h_addr, sizeof(dest.sin_addr));
-	memset(dest.sin_zero, 0, sizeof(dest.sin_zero));
-	s = socket(PF_INET, SOCK_STREAM, 0);
-	if(s < 0)
-	{
-		PRINT_SOCKET_ERROR("socket");
-		return -1;
-	}
-#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
-	/* setting a 3 seconds timeout for the connect() call */
-	timeout.tv_sec = 3;
-	timeout.tv_usec = 0;
-	if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0)
-	{
-		PRINT_SOCKET_ERROR("setsockopt SO_RCVTIMEO");
-	}
-	timeout.tv_sec = 3;
-	timeout.tv_usec = 0;
-	if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0)
-	{
-		PRINT_SOCKET_ERROR("setsockopt SO_SNDTIMEO");
-	}
-#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
-	dest.sin_family = AF_INET;
-	dest.sin_port = htons(port);
-	n = connect(s, (struct sockaddr *)&dest, sizeof(struct sockaddr_in));
-#ifdef MINIUPNPC_IGNORE_EINTR
-	/* EINTR The system call was interrupted by a signal that was caught
-	 * EINPROGRESS The socket is nonblocking and the connection cannot
-	 *             be completed immediately. */
-	while(n < 0 && (errno == EINTR || errno == EINPROGRESS))
-	{
-		socklen_t len;
-		fd_set wset;
-		int err;
-		FD_ZERO(&wset);
-		FD_SET(s, &wset);
-		if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR)
-			continue;
-		/*len = 0;*/
-		/*n = getpeername(s, NULL, &len);*/
-		len = sizeof(err);
-		if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
-			PRINT_SOCKET_ERROR("getsockopt");
-			closesocket(s);
-			return -1;
-		}
-		if(err != 0) {
-			errno = err;
-			n = -1;
-		}
-	}
-#endif /* #ifdef MINIUPNPC_IGNORE_EINTR */
-	if(n<0)
-	{
-		PRINT_SOCKET_ERROR("connect");
-		closesocket(s);
-		return -1;
-	}
-#else /* #ifdef USE_GETHOSTBYNAME */
-	/* use getaddrinfo() instead of gethostbyname() */
-	memset(&hints, 0, sizeof(hints));
-	/* hints.ai_flags = AI_ADDRCONFIG; */
-#ifdef AI_NUMERICSERV
-	hints.ai_flags = AI_NUMERICSERV;
-#endif
-	hints.ai_socktype = SOCK_STREAM;
-	hints.ai_family = AF_UNSPEC; /* AF_INET, AF_INET6 or AF_UNSPEC */
-	/* hints.ai_protocol = IPPROTO_TCP; */
-	snprintf(port_str, sizeof(port_str), "%hu", port);
-	if(host[0] == '[')
-	{
-		/* literal ip v6 address */
-		int i, j;
-		for(i = 0, j = 1; host[j] && (host[j] != ']') && i < MAXHOSTNAMELEN; i++, j++)
-		{
-			tmp_host[i] = host[j];
-			if(0 == memcmp(host+j, "%25", 3))	/* %25 is just url encoding for '%' */
-				j+=2;							/* skip "25" */
-		}
-		tmp_host[i] = '\0';
-	}
-	else
-	{
-		strncpy(tmp_host, host, MAXHOSTNAMELEN);
-	}
-	tmp_host[MAXHOSTNAMELEN] = '\0';
-	n = getaddrinfo(tmp_host, port_str, &hints, &ai);
-	if(n != 0)
-	{
-#ifdef _WIN32
-		fprintf(stderr, "getaddrinfo() error : %d\n", n);
-#else
-		fprintf(stderr, "getaddrinfo() error : %s\n", gai_strerror(n));
-#endif
-		return -1;
-	}
-	s = -1;
-	for(p = ai; p; p = p->ai_next)
-	{
-		s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
-		if(s < 0)
-			continue;
-		if(p->ai_addr->sa_family == AF_INET6 && scope_id > 0) {
-			struct sockaddr_in6 * addr6 = (struct sockaddr_in6 *)p->ai_addr;
-			addr6->sin6_scope_id = scope_id;
-		}
-#ifdef MINIUPNPC_SET_SOCKET_TIMEOUT
-		/* setting a 3 seconds timeout for the connect() call */
-		timeout.tv_sec = 3;
-		timeout.tv_usec = 0;
-		if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0)
-		{
-			PRINT_SOCKET_ERROR("setsockopt");
-		}
-		timeout.tv_sec = 3;
-		timeout.tv_usec = 0;
-		if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0)
-		{
-			PRINT_SOCKET_ERROR("setsockopt");
-		}
-#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
-		n = connect(s, p->ai_addr, p->ai_addrlen);
-#ifdef MINIUPNPC_IGNORE_EINTR
-		/* EINTR The system call was interrupted by a signal that was caught
-		 * EINPROGRESS The socket is nonblocking and the connection cannot
-		 *             be completed immediately. */
-		while(n < 0 && (errno == EINTR || errno == EINPROGRESS))
-		{
-			socklen_t len;
-			fd_set wset;
-			int err;
-			FD_ZERO(&wset);
-			FD_SET(s, &wset);
-			if((n = select(s + 1, NULL, &wset, NULL, NULL)) == -1 && errno == EINTR)
-				continue;
-			/*len = 0;*/
-			/*n = getpeername(s, NULL, &len);*/
-			len = sizeof(err);
-			if(getsockopt(s, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
-				PRINT_SOCKET_ERROR("getsockopt");
-				closesocket(s);
-				freeaddrinfo(ai);
-				return -1;
-			}
-			if(err != 0) {
-				errno = err;
-				n = -1;
-			}
-		}
-#endif /* #ifdef MINIUPNPC_IGNORE_EINTR */
-		if(n < 0)
-		{
-			closesocket(s);
-			continue;
-		}
-		else
-		{
-			break;
-		}
-	}
-	freeaddrinfo(ai);
-	if(s < 0)
-	{
-		PRINT_SOCKET_ERROR("socket");
-		return -1;
-	}
-	if(n < 0)
-	{
-		PRINT_SOCKET_ERROR("connect");
-		return -1;
-	}
-#endif /* #ifdef USE_GETHOSTBYNAME */
-	return s;
-}
-

+ 0 - 18
ext/miniupnpc/connecthostport.h

@@ -1,18 +0,0 @@
-/* $Id: connecthostport.h,v 1.3 2012/09/27 15:42:10 nanard Exp $ */
-/* Project: miniupnp
- * http://miniupnp.free.fr/
- * Author: Thomas Bernard
- * Copyright (c) 2010-2012 Thomas Bernard
- * This software is subjects to the conditions detailed
- * in the LICENCE file provided within this distribution */
-#ifndef CONNECTHOSTPORT_H_INCLUDED
-#define CONNECTHOSTPORT_H_INCLUDED
-
-/* connecthostport()
- * return a socket connected (TCP) to the host and port
- * or -1 in case of error */
-int connecthostport(const char * host, unsigned short port,
-                    unsigned int scope_id);
-
-#endif
-

+ 0 - 123
ext/miniupnpc/igd_desc_parse.c

@@ -1,123 +0,0 @@
-/* $Id: igd_desc_parse.c,v 1.17 2015/09/15 13:30:04 nanard Exp $ */
-/* Project : miniupnp
- * http://miniupnp.free.fr/
- * Author : Thomas Bernard
- * Copyright (c) 2005-2015 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution. */
-
-#include "igd_desc_parse.h"
-#include <stdio.h>
-#include <string.h>
-
-/* Start element handler :
- * update nesting level counter and copy element name */
-void IGDstartelt(void * d, const char * name, int l)
-{
-	struct IGDdatas * datas = (struct IGDdatas *)d;
-	if(l >= MINIUPNPC_URL_MAXSIZE)
-		l = MINIUPNPC_URL_MAXSIZE-1;
-	memcpy(datas->cureltname, name, l);
-	datas->cureltname[l] = '\0';
-	datas->level++;
-	if( (l==7) && !memcmp(name, "service", l) ) {
-		datas->tmp.controlurl[0] = '\0';
-		datas->tmp.eventsuburl[0] = '\0';
-		datas->tmp.scpdurl[0] = '\0';
-		datas->tmp.servicetype[0] = '\0';
-	}
-}
-
-#define COMPARE(str, cstr) (0==memcmp(str, cstr, sizeof(cstr) - 1))
-
-/* End element handler :
- * update nesting level counter and update parser state if
- * service element is parsed */
-void IGDendelt(void * d, const char * name, int l)
-{
-	struct IGDdatas * datas = (struct IGDdatas *)d;
-	datas->level--;
-	/*printf("endelt %2d %.*s\n", datas->level, l, name);*/
-	if( (l==7) && !memcmp(name, "service", l) )
-	{
-		if(COMPARE(datas->tmp.servicetype,
-		           "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:")) {
-			memcpy(&datas->CIF, &datas->tmp, sizeof(struct IGDdatas_service));
-		} else if(COMPARE(datas->tmp.servicetype,
-			                "urn:schemas-upnp-org:service:WANIPv6FirewallControl:")) {
-			memcpy(&datas->IPv6FC, &datas->tmp, sizeof(struct IGDdatas_service));
-		} else if(COMPARE(datas->tmp.servicetype,
-		                  "urn:schemas-upnp-org:service:WANIPConnection:")
-		         || COMPARE(datas->tmp.servicetype,
-		                    "urn:schemas-upnp-org:service:WANPPPConnection:") ) {
-			if(datas->first.servicetype[0] == '\0') {
-				memcpy(&datas->first, &datas->tmp, sizeof(struct IGDdatas_service));
-			} else {
-				memcpy(&datas->second, &datas->tmp, sizeof(struct IGDdatas_service));
-			}
-		}
-	}
-}
-
-/* Data handler :
- * copy data depending on the current element name and state */
-void IGDdata(void * d, const char * data, int l)
-{
-	struct IGDdatas * datas = (struct IGDdatas *)d;
-	char * dstmember = 0;
-	/*printf("%2d %s : %.*s\n",
-           datas->level, datas->cureltname, l, data);	*/
-	if( !strcmp(datas->cureltname, "URLBase") )
-		dstmember = datas->urlbase;
-	else if( !strcmp(datas->cureltname, "presentationURL") )
-		dstmember = datas->presentationurl;
-	else if( !strcmp(datas->cureltname, "serviceType") )
-		dstmember = datas->tmp.servicetype;
-	else if( !strcmp(datas->cureltname, "controlURL") )
-		dstmember = datas->tmp.controlurl;
-	else if( !strcmp(datas->cureltname, "eventSubURL") )
-		dstmember = datas->tmp.eventsuburl;
-	else if( !strcmp(datas->cureltname, "SCPDURL") )
-		dstmember = datas->tmp.scpdurl;
-/*	else if( !strcmp(datas->cureltname, "deviceType") )
-		dstmember = datas->devicetype_tmp;*/
-	if(dstmember)
-	{
-		if(l>=MINIUPNPC_URL_MAXSIZE)
-			l = MINIUPNPC_URL_MAXSIZE-1;
-		memcpy(dstmember, data, l);
-		dstmember[l] = '\0';
-	}
-}
-
-#ifdef DEBUG
-void printIGD(struct IGDdatas * d)
-{
-	printf("urlbase = '%s'\n", d->urlbase);
-	printf("WAN Device (Common interface config) :\n");
-	/*printf(" deviceType = '%s'\n", d->CIF.devicetype);*/
-	printf(" serviceType = '%s'\n", d->CIF.servicetype);
-	printf(" controlURL = '%s'\n", d->CIF.controlurl);
-	printf(" eventSubURL = '%s'\n", d->CIF.eventsuburl);
-	printf(" SCPDURL = '%s'\n", d->CIF.scpdurl);
-	printf("primary WAN Connection Device (IP or PPP Connection):\n");
-	/*printf(" deviceType = '%s'\n", d->first.devicetype);*/
-	printf(" servicetype = '%s'\n", d->first.servicetype);
-	printf(" controlURL = '%s'\n", d->first.controlurl);
-	printf(" eventSubURL = '%s'\n", d->first.eventsuburl);
-	printf(" SCPDURL = '%s'\n", d->first.scpdurl);
-	printf("secondary WAN Connection Device (IP or PPP Connection):\n");
-	/*printf(" deviceType = '%s'\n", d->second.devicetype);*/
-	printf(" servicetype = '%s'\n", d->second.servicetype);
-	printf(" controlURL = '%s'\n", d->second.controlurl);
-	printf(" eventSubURL = '%s'\n", d->second.eventsuburl);
-	printf(" SCPDURL = '%s'\n", d->second.scpdurl);
-	printf("WAN IPv6 Firewall Control :\n");
-	/*printf(" deviceType = '%s'\n", d->IPv6FC.devicetype);*/
-	printf(" servicetype = '%s'\n", d->IPv6FC.servicetype);
-	printf(" controlURL = '%s'\n", d->IPv6FC.controlurl);
-	printf(" eventSubURL = '%s'\n", d->IPv6FC.eventsuburl);
-	printf(" SCPDURL = '%s'\n", d->IPv6FC.scpdurl);
-}
-#endif /* DEBUG */
-

+ 0 - 49
ext/miniupnpc/igd_desc_parse.h

@@ -1,49 +0,0 @@
-/* $Id: igd_desc_parse.h,v 1.12 2014/11/17 17:19:13 nanard Exp $ */
-/* Project : miniupnp
- * http://miniupnp.free.fr/
- * Author : Thomas Bernard
- * Copyright (c) 2005-2014 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution.
- * */
-#ifndef IGD_DESC_PARSE_H_INCLUDED
-#define IGD_DESC_PARSE_H_INCLUDED
-
-/* Structure to store the result of the parsing of UPnP
- * descriptions of Internet Gateway Devices */
-#define MINIUPNPC_URL_MAXSIZE (128)
-struct IGDdatas_service {
-	char controlurl[MINIUPNPC_URL_MAXSIZE];
-	char eventsuburl[MINIUPNPC_URL_MAXSIZE];
-	char scpdurl[MINIUPNPC_URL_MAXSIZE];
-	char servicetype[MINIUPNPC_URL_MAXSIZE];
-	/*char devicetype[MINIUPNPC_URL_MAXSIZE];*/
-};
-
-struct IGDdatas {
-	char cureltname[MINIUPNPC_URL_MAXSIZE];
-	char urlbase[MINIUPNPC_URL_MAXSIZE];
-	char presentationurl[MINIUPNPC_URL_MAXSIZE];
-	int level;
-	/*int state;*/
-	/* "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1" */
-	struct IGDdatas_service CIF;
-	/* "urn:schemas-upnp-org:service:WANIPConnection:1"
-	 * "urn:schemas-upnp-org:service:WANPPPConnection:1" */
-	struct IGDdatas_service first;
-	/* if both WANIPConnection and WANPPPConnection are present */
-	struct IGDdatas_service second;
-	/* "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1" */
-	struct IGDdatas_service IPv6FC;
-	/* tmp */
-	struct IGDdatas_service tmp;
-};
-
-void IGDstartelt(void *, const char *, int);
-void IGDendelt(void *, const char *, int);
-void IGDdata(void *, const char *, int);
-#ifdef DEBUG
-void printIGD(struct IGDdatas *);
-#endif /* DEBUG */
-
-#endif /* IGD_DESC_PARSE_H_INCLUDED */

+ 0 - 110
ext/miniupnpc/listdevices.c

@@ -1,110 +0,0 @@
-/* $Id: listdevices.c,v 1.7 2015/10/08 16:15:47 nanard Exp $ */
-/* Project : miniupnp
- * Author : Thomas Bernard
- * Copyright (c) 2013-2015 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution. */
-
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#ifdef _WIN32
-#include <winsock2.h>
-#endif /* _WIN32 */
-#include "miniupnpc.h"
-
-int main(int argc, char * * argv)
-{
-	const char * searched_device = NULL;
-	const char * * searched_devices = NULL;
-	const char * multicastif = 0;
-	const char * minissdpdpath = 0;
-	int ipv6 = 0;
-	unsigned char ttl = 2;
-	int error = 0;
-	struct UPNPDev * devlist = 0;
-	struct UPNPDev * dev;
-	int i;
-
-#ifdef _WIN32
-	WSADATA wsaData;
-	int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
-	if(nResult != NO_ERROR)
-	{
-		fprintf(stderr, "WSAStartup() failed.\n");
-		return -1;
-	}
-#endif
-
-	for(i = 1; i < argc; i++) {
-		if(strcmp(argv[i], "-6") == 0)
-			ipv6 = 1;
-		else if(strcmp(argv[i], "-d") == 0) {
-			if(++i >= argc) {
-				fprintf(stderr, "%s option needs one argument\n", "-d");
-				return 1;
-			}
-			searched_device = argv[i];
-		} else if(strcmp(argv[i], "-t") == 0) {
-			if(++i >= argc) {
-				fprintf(stderr, "%s option needs one argument\n", "-t");
-				return 1;
-			}
-			ttl = (unsigned char)atoi(argv[i]);
-		} else if(strcmp(argv[i], "-l") == 0) {
-			if(++i >= argc) {
-				fprintf(stderr, "-l option needs at least one argument\n");
-				return 1;
-			}
-			searched_devices = (const char * *)(argv + i);
-			break;
-		} else if(strcmp(argv[i], "-m") == 0) {
-			if(++i >= argc) {
-				fprintf(stderr, "-m option needs one argument\n");
-				return 1;
-			}
-			multicastif = argv[i];
-		} else {
-			printf("usage : %s [options] [-l <device1> <device2> ...]\n", argv[0]);
-			printf("options :\n");
-			printf("   -6 : use IPv6\n");
-			printf("   -m address/ifname : network interface to use for multicast\n");
-			printf("   -d <device string> : search only for this type of device\n");
-			printf("   -l <device1> <device2> ... : search only for theses types of device\n");
-			printf("   -t ttl : set multicast TTL. Default value is 2.\n");
-			printf("   -h : this help\n");
-			return 1;
-		}
-	}
-
-	if(searched_device) {
-		printf("searching UPnP device type %s\n", searched_device);
-		devlist = upnpDiscoverDevice(searched_device,
-		                             2000, multicastif, minissdpdpath,
-		                             0/*localport*/, ipv6, ttl, &error);
-	} else if(searched_devices) {
-		printf("searching UPnP device types :\n");
-		for(i = 0; searched_devices[i]; i++)
-			printf("\t%s\n", searched_devices[i]);
-		devlist = upnpDiscoverDevices(searched_devices,
-		                              2000, multicastif, minissdpdpath,
-		                              0/*localport*/, ipv6, ttl, &error, 1);
-	} else {
-		printf("searching all UPnP devices\n");
-		devlist = upnpDiscoverAll(2000, multicastif, minissdpdpath,
-		                             0/*localport*/, ipv6, ttl, &error);
-	}
-	if(devlist) {
-		for(dev = devlist, i = 1; dev != NULL; dev = dev->pNext, i++) {
-			printf("%3d: %-48s\n", i, dev->st);
-			printf("     %s\n", dev->descURL);
-			printf("     %s\n", dev->usn);
-		}
-		freeUPNPDevlist(devlist);
-	} else {
-		printf("no device found.\n");
-	}
-
-	return 0;
-}
-

+ 0 - 134
ext/miniupnpc/minisoap.c

@@ -1,134 +0,0 @@
-/* $Id: minisoap.c,v 1.25 2017/04/21 10:03:24 nanard Exp $ */
-/* Project : miniupnp
- * Author : Thomas Bernard
- * Copyright (c) 2005-2015 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution.
- *
- * Minimal SOAP implementation for UPnP protocol.
- */
-#include <stdio.h>
-#include <string.h>
-#ifdef _WIN32
-#include <io.h>
-#include <winsock2.h>
-#define snprintf _snprintf
-#else
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#endif
-#include "minisoap.h"
-
-#ifdef _WIN32
-#define OS_STRING "Win32"
-#define MINIUPNPC_VERSION_STRING "2.0"
-#define UPNP_VERSION_STRING "UPnP/1.1"
-#endif
-
-#ifdef __ANDROID__
-#define OS_STRING "Android"
-#define MINIUPNPC_VERSION_STRING "2.0"
-#define UPNP_VERSION_STRING "UPnP/1.1"
-#endif
-
-/* only for malloc */
-#include <stdlib.h>
-
-#ifdef _WIN32
-#define PRINT_SOCKET_ERROR(x)    fprintf(stderr, "Socket error: %s, %d\n", x, WSAGetLastError());
-#else
-#define PRINT_SOCKET_ERROR(x) perror(x)
-#endif
-
-/* httpWrite sends the headers and the body to the socket
- * and returns the number of bytes sent */
-static int
-httpWrite(int fd, const char * body, int bodysize,
-          const char * headers, int headerssize)
-{
-	int n = 0;
-	/*n = write(fd, headers, headerssize);*/
-	/*if(bodysize>0)
-		n += write(fd, body, bodysize);*/
-	/* Note : my old linksys router only took into account
-	 * soap request that are sent into only one packet */
-	char * p;
-	/* TODO: AVOID MALLOC, we could use writev() for that */
-	p = malloc(headerssize+bodysize);
-	if(!p)
-	  return -1;
-	memcpy(p, headers, headerssize);
-	memcpy(p+headerssize, body, bodysize);
-	/*n = write(fd, p, headerssize+bodysize);*/
-	n = send(fd, p, headerssize+bodysize, 0);
-	if(n<0) {
-	  PRINT_SOCKET_ERROR("send");
-	}
-	/* disable send on the socket */
-	/* draytek routers dont seems to like that... */
-#if 0
-#ifdef _WIN32
-	if(shutdown(fd, SD_SEND)<0) {
-#else
-	if(shutdown(fd, SHUT_WR)<0)	{ /*SD_SEND*/
-#endif
-		PRINT_SOCKET_ERROR("shutdown");
-	}
-#endif
-	free(p);
-	return n;
-}
-
-/* self explanatory  */
-int soapPostSubmit(int fd,
-                   const char * url,
-				   const char * host,
-				   unsigned short port,
-				   const char * action,
-				   const char * body,
-				   const char * httpversion)
-{
-	int bodysize;
-	char headerbuf[512];
-	int headerssize;
-	char portstr[8];
-	bodysize = (int)strlen(body);
-	/* We are not using keep-alive HTTP connections.
-	 * HTTP/1.1 needs the header Connection: close to do that.
-	 * This is the default with HTTP/1.0
-	 * Using HTTP/1.1 means we need to support chunked transfer-encoding :
-	 * When using HTTP/1.1, the router "BiPAC 7404VNOX" always use chunked
-	 * transfer encoding. */
-    /* Connection: Close is normally there only in HTTP/1.1 but who knows */
-	portstr[0] = '\0';
-	if(port != 80)
-		snprintf(portstr, sizeof(portstr), ":%hu", port);
-	headerssize = snprintf(headerbuf, sizeof(headerbuf),
-                       "POST %s HTTP/%s\r\n"
-	                   "Host: %s%s\r\n"
-					   "User-Agent: " OS_STRING ", " UPNP_VERSION_STRING ", MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n"
-	                   "Content-Length: %d\r\n"
-					   "Content-Type: text/xml\r\n"
-					   "SOAPAction: \"%s\"\r\n"
-					   "Connection: Close\r\n"
-					   "Cache-Control: no-cache\r\n"	/* ??? */
-					   "Pragma: no-cache\r\n"
-					   "\r\n",
-					   url, httpversion, host, portstr, bodysize, action);
-	if ((unsigned int)headerssize >= sizeof(headerbuf))
-		return -1;
-#ifdef DEBUG
-	/*printf("SOAP request : headersize=%d bodysize=%d\n",
-	       headerssize, bodysize);
-	*/
-	printf("SOAP request : POST %s HTTP/%s - Host: %s%s\n",
-	        url, httpversion, host, portstr);
-	printf("SOAPAction: \"%s\" - Content-Length: %d\n", action, bodysize);
-	printf("Headers :\n%s", headerbuf);
-	printf("Body :\n%s\n", body);
-#endif
-	return httpWrite(fd, body, bodysize, headerbuf, headerssize);
-}
-
-

+ 0 - 15
ext/miniupnpc/minisoap.h

@@ -1,15 +0,0 @@
-/* $Id: minisoap.h,v 1.5 2012/09/27 15:42:10 nanard Exp $ */
-/* Project : miniupnp
- * Author : Thomas Bernard
- * Copyright (c) 2005 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution. */
-#ifndef MINISOAP_H_INCLUDED
-#define MINISOAP_H_INCLUDED
-
-/*int httpWrite(int, const char *, int, const char *);*/
-int soapPostSubmit(int, const char *, const char *, unsigned short,
-		   const char *, const char *, const char *);
-
-#endif
-

+ 0 - 893
ext/miniupnpc/minissdpc.c

@@ -1,893 +0,0 @@
-/* $Id: minissdpc.c,v 1.35 2017/11/02 15:34:36 nanard Exp $ */
-/* vim: tabstop=4 shiftwidth=4 noexpandtab
- * Project : miniupnp
- * Web : http://miniupnp.free.fr/
- * Author : Thomas BERNARD
- * copyright (c) 2005-2017 Thomas Bernard
- * This software is subjet to the conditions detailed in the
- * provided LICENCE file. */
-/*#include <syslog.h>*/
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#if defined (__NetBSD__)
-#include <net/if.h>
-#endif
-#if defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)
-#ifdef _WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <io.h>
-#include <iphlpapi.h>
-#include <winsock.h>
-#define snprintf _snprintf
-#if !defined(_MSC_VER)
-#include <stdint.h>
-#else /* !defined(_MSC_VER) */
-typedef unsigned short uint16_t;
-#endif /* !defined(_MSC_VER) */
-#ifndef strncasecmp
-#if defined(_MSC_VER) && (_MSC_VER >= 1400)
-#define strncasecmp _memicmp
-#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
-#define strncasecmp memicmp
-#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
-#endif /* #ifndef strncasecmp */
-#endif /* _WIN32 */
-#if defined(__amigaos__) || defined(__amigaos4__)
-#include <sys/socket.h>
-#endif /* defined(__amigaos__) || defined(__amigaos4__) */
-#if defined(__amigaos__)
-#define uint16_t unsigned short
-#endif /* defined(__amigaos__) */
-/* Hack */
-#define UNIX_PATH_LEN   108
-struct sockaddr_un {
-  uint16_t sun_family;
-  char     sun_path[UNIX_PATH_LEN];
-};
-#else /* defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__) */
-#include <strings.h>
-#include <unistd.h>
-#include <sys/socket.h>
-#include <sys/param.h>
-#include <sys/time.h>
-#include <sys/un.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <net/if.h>
-#define closesocket close
-#endif
-
-#ifdef _WIN32
-#define PRINT_SOCKET_ERROR(x)    fprintf(stderr, "Socket error: %s, %d\n", x, WSAGetLastError());
-#else
-#define PRINT_SOCKET_ERROR(x) perror(x)
-#endif
-
-#if !defined(__DragonFly__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__APPLE__) && !defined(_WIN32) && !defined(__CYGWIN__) && !defined(__sun) && !defined(__GNU__) && !defined(__FreeBSD_kernel__)
-#define HAS_IP_MREQN
-#endif
-
-#if !defined(HAS_IP_MREQN) && !defined(_WIN32)
-#include <sys/ioctl.h>
-#if defined(__sun)
-#include <sys/sockio.h>
-#endif
-#endif
-
-#if defined(HAS_IP_MREQN) && defined(NEED_STRUCT_IP_MREQN)
-/* Several versions of glibc don't define this structure,
- * define it here and compile with CFLAGS NEED_STRUCT_IP_MREQN */
-struct ip_mreqn
-{
-	struct in_addr	imr_multiaddr;		/* IP multicast address of group */
-	struct in_addr	imr_address;		/* local IP address of interface */
-	int		imr_ifindex;		/* Interface index */
-};
-#endif
-
-#if defined(__amigaos__) || defined(__amigaos4__)
-/* Amiga OS specific stuff */
-#define TIMEVAL struct timeval
-#endif
-
-#include "minissdpc.h"
-#include "miniupnpc.h"
-#include "receivedata.h"
-
-#if !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__))
-
-#include "codelength.h"
-
-struct UPNPDev *
-getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath, int * error)
-{
-	struct UPNPDev * devlist = NULL;
-	int s;
-	int res;
-
-	s = connectToMiniSSDPD(socketpath);
-	if (s < 0) {
-		if (error)
-			*error = s;
-		return NULL;
-	}
-	res = requestDevicesFromMiniSSDPD(s, devtype);
-	if (res < 0) {
-		if (error)
-			*error = res;
-	} else {
-		devlist = receiveDevicesFromMiniSSDPD(s, error);
-	}
-	disconnectFromMiniSSDPD(s);
-	return devlist;
-}
-
-/* macros used to read from unix socket */
-#define READ_BYTE_BUFFER(c) \
-	if((int)bufferindex >= n) { \
-		n = read(s, buffer, sizeof(buffer)); \
-		if(n<=0) break; \
-		bufferindex = 0; \
-	} \
-	c = buffer[bufferindex++];
-
-#ifndef MIN
-#define MIN(a, b) (((a) < (b)) ? (a) : (b))
-#endif /* MIN */
-
-#define READ_COPY_BUFFER(dst, len) \
-	for(l = len, p = (unsigned char *)dst; l > 0; ) { \
-		unsigned int lcopy; \
-		if((int)bufferindex >= n) { \
-			n = read(s, buffer, sizeof(buffer)); \
-			if(n<=0) break; \
-			bufferindex = 0; \
-		} \
-		lcopy = MIN(l, (n - bufferindex)); \
-		memcpy(p, buffer + bufferindex, lcopy); \
-		l -= lcopy; \
-		p += lcopy; \
-		bufferindex += lcopy; \
-	}
-
-#define READ_DISCARD_BUFFER(len) \
-	for(l = len; l > 0; ) { \
-		unsigned int lcopy; \
-		if(bufferindex >= n) { \
-			n = read(s, buffer, sizeof(buffer)); \
-			if(n<=0) break; \
-			bufferindex = 0; \
-		} \
-		lcopy = MIN(l, (n - bufferindex)); \
-		l -= lcopy; \
-		bufferindex += lcopy; \
-	}
-
-int
-connectToMiniSSDPD(const char * socketpath)
-{
-	int s;
-	struct sockaddr_un addr;
-#if defined(MINIUPNPC_SET_SOCKET_TIMEOUT) && !defined(__sun)
-	struct timeval timeout;
-#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
-
-	s = socket(AF_UNIX, SOCK_STREAM, 0);
-	if(s < 0)
-	{
-		/*syslog(LOG_ERR, "socket(unix): %m");*/
-		perror("socket(unix)");
-		return MINISSDPC_SOCKET_ERROR;
-	}
-#if defined(MINIUPNPC_SET_SOCKET_TIMEOUT) && !defined(__sun)
-	/* setting a 3 seconds timeout */
-	/* not supported for AF_UNIX sockets under Solaris */
-	timeout.tv_sec = 3;
-	timeout.tv_usec = 0;
-	if(setsockopt(s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(struct timeval)) < 0)
-	{
-		perror("setsockopt SO_RCVTIMEO unix");
-	}
-	timeout.tv_sec = 3;
-	timeout.tv_usec = 0;
-	if(setsockopt(s, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(struct timeval)) < 0)
-	{
-		perror("setsockopt SO_SNDTIMEO unix");
-	}
-#endif /* #ifdef MINIUPNPC_SET_SOCKET_TIMEOUT */
-	if(!socketpath)
-		socketpath = "/var/run/minissdpd.sock";
-	memset(&addr, 0, sizeof(addr));
-	addr.sun_family = AF_UNIX;
-	strncpy(addr.sun_path, socketpath, sizeof(addr.sun_path));
-	/* TODO : check if we need to handle the EINTR */
-	if(connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un)) < 0)
-	{
-		/*syslog(LOG_WARNING, "connect(\"%s\"): %m", socketpath);*/
-		close(s);
-		return MINISSDPC_SOCKET_ERROR;
-	}
-	return s;
-}
-
-int
-disconnectFromMiniSSDPD(int s)
-{
-	if (close(s) < 0)
-		return MINISSDPC_SOCKET_ERROR;
-	return MINISSDPC_SUCCESS;
-}
-
-int
-requestDevicesFromMiniSSDPD(int s, const char * devtype)
-{
-	unsigned char buffer[256];
-	unsigned char * p;
-	unsigned int stsize, l;
-
-	stsize = strlen(devtype);
-	if(stsize == 8 && 0 == memcmp(devtype, "ssdp:all", 8))
-	{
-		buffer[0] = 3;	/* request type 3 : everything */
-	}
-	else
-	{
-		buffer[0] = 1; /* request type 1 : request devices/services by type */
-	}
-	p = buffer + 1;
-	l = stsize;	CODELENGTH(l, p);
-	if(p + stsize > buffer + sizeof(buffer))
-	{
-		/* devtype is too long ! */
-#ifdef DEBUG
-		fprintf(stderr, "devtype is too long ! stsize=%u sizeof(buffer)=%u\n",
-		        stsize, (unsigned)sizeof(buffer));
-#endif /* DEBUG */
-		return MINISSDPC_INVALID_INPUT;
-	}
-	memcpy(p, devtype, stsize);
-	p += stsize;
-	if(write(s, buffer, p - buffer) < 0)
-	{
-		/*syslog(LOG_ERR, "write(): %m");*/
-		perror("minissdpc.c: write()");
-		return MINISSDPC_SOCKET_ERROR;
-	}
-	return MINISSDPC_SUCCESS;
-}
-
-struct UPNPDev *
-receiveDevicesFromMiniSSDPD(int s, int * error)
-{
-	struct UPNPDev * tmp;
-	struct UPNPDev * devlist = NULL;
-	unsigned char buffer[256];
-	ssize_t n;
-	unsigned char * p;
-	unsigned char * url;
-	unsigned char * st;
-	unsigned int bufferindex;
-	unsigned int i, ndev;
-	unsigned int urlsize, stsize, usnsize, l;
-
-	n = read(s, buffer, sizeof(buffer));
-	if(n<=0)
-	{
-		perror("minissdpc.c: read()");
-		if (error)
-			*error = MINISSDPC_SOCKET_ERROR;
-		return NULL;
-	}
-	ndev = buffer[0];
-	bufferindex = 1;
-	for(i = 0; i < ndev; i++)
-	{
-		DECODELENGTH_READ(urlsize, READ_BYTE_BUFFER);
-		if(n<=0) {
-			if (error)
-				*error = MINISSDPC_INVALID_SERVER_REPLY;
-			return devlist;
-		}
-#ifdef DEBUG
-		printf("  urlsize=%u", urlsize);
-#endif /* DEBUG */
-		url = malloc(urlsize);
-		if(url == NULL) {
-			if (error)
-				*error = MINISSDPC_MEMORY_ERROR;
-			return devlist;
-		}
-		READ_COPY_BUFFER(url, urlsize);
-		if(n<=0) {
-			if (error)
-				*error = MINISSDPC_INVALID_SERVER_REPLY;
-			goto free_url_and_return;
-		}
-		DECODELENGTH_READ(stsize, READ_BYTE_BUFFER);
-		if(n<=0) {
-			if (error)
-				*error = MINISSDPC_INVALID_SERVER_REPLY;
-			goto free_url_and_return;
-		}
-#ifdef DEBUG
-		printf("   stsize=%u", stsize);
-#endif /* DEBUG */
-		st = malloc(stsize);
-		if (st == NULL) {
-			if (error)
-				*error = MINISSDPC_MEMORY_ERROR;
-			goto free_url_and_return;
-		}
-		READ_COPY_BUFFER(st, stsize);
-		if(n<=0) {
-			if (error)
-				*error = MINISSDPC_INVALID_SERVER_REPLY;
-			goto free_url_and_st_and_return;
-		}
-		DECODELENGTH_READ(usnsize, READ_BYTE_BUFFER);
-		if(n<=0) {
-			if (error)
-				*error = MINISSDPC_INVALID_SERVER_REPLY;
-			goto free_url_and_st_and_return;
-		}
-#ifdef DEBUG
-		printf("   usnsize=%u\n", usnsize);
-#endif /* DEBUG */
-		tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize+usnsize);
-		if(tmp == NULL) {
-			if (error)
-				*error = MINISSDPC_MEMORY_ERROR;
-			goto free_url_and_st_and_return;
-		}
-		tmp->pNext = devlist;
-		tmp->descURL = tmp->buffer;
-		tmp->st = tmp->buffer + 1 + urlsize;
-		memcpy(tmp->buffer, url, urlsize);
-		tmp->buffer[urlsize] = '\0';
-		memcpy(tmp->st, st, stsize);
-		tmp->buffer[urlsize+1+stsize] = '\0';
-		free(url);
-		free(st);
-		url = NULL;
-		st = NULL;
-		tmp->usn = tmp->buffer + 1 + urlsize + 1 + stsize;
-		READ_COPY_BUFFER(tmp->usn, usnsize);
-		if(n<=0) {
-			if (error)
-				*error = MINISSDPC_INVALID_SERVER_REPLY;
-			goto free_tmp_and_return;
-		}
-		tmp->buffer[urlsize+1+stsize+1+usnsize] = '\0';
-		tmp->scope_id = 0;	/* default value. scope_id is not available with MiniSSDPd */
-		devlist = tmp;
-	}
-	if (error)
-		*error = MINISSDPC_SUCCESS;
-	return devlist;
-
-free_url_and_st_and_return:
-	free(st);
-free_url_and_return:
-	free(url);
-	return devlist;
-
-free_tmp_and_return:
-	free(tmp);
-	return devlist;
-}
-
-#endif /* !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) */
-
-/* parseMSEARCHReply()
- * the last 4 arguments are filled during the parsing :
- *    - location/locationsize : "location:" field of the SSDP reply packet
- *    - st/stsize : "st:" field of the SSDP reply packet.
- * The strings are NOT null terminated */
-static void
-parseMSEARCHReply(const char * reply, int size,
-                  const char * * location, int * locationsize,
-			      const char * * st, int * stsize,
-			      const char * * usn, int * usnsize)
-{
-	int a, b, i;
-	i = 0;
-	a = i;	/* start of the line */
-	b = 0;	/* end of the "header" (position of the colon) */
-	while(i<size)
-	{
-		switch(reply[i])
-		{
-		case ':':
-				if(b==0)
-				{
-					b = i; /* end of the "header" */
-					/*for(j=a; j<b; j++)
-					{
-						putchar(reply[j]);
-					}
-					*/
-				}
-				break;
-		case '\x0a':
-		case '\x0d':
-				if(b!=0)
-				{
-					/*for(j=b+1; j<i; j++)
-					{
-						putchar(reply[j]);
-					}
-					putchar('\n');*/
-					/* skip the colon and white spaces */
-					do { b++; } while(reply[b]==' ');
-					if(0==strncasecmp(reply+a, "location", 8))
-					{
-						*location = reply+b;
-						*locationsize = i-b;
-					}
-					else if(0==strncasecmp(reply+a, "st", 2))
-					{
-						*st = reply+b;
-						*stsize = i-b;
-					}
-					else if(0==strncasecmp(reply+a, "usn", 3))
-					{
-						*usn = reply+b;
-						*usnsize = i-b;
-					}
-					b = 0;
-				}
-				a = i+1;
-				break;
-		default:
-				break;
-		}
-		i++;
-	}
-}
-
-/* port upnp discover : SSDP protocol */
-#define SSDP_PORT 1900
-#define XSTR(s) STR(s)
-#define STR(s) #s
-#define UPNP_MCAST_ADDR "239.255.255.250"
-/* for IPv6 */
-#define UPNP_MCAST_LL_ADDR "FF02::C" /* link-local */
-#define UPNP_MCAST_SL_ADDR "FF05::C" /* site-local */
-
-/* direct discovery if minissdpd responses are not sufficient */
-/* ssdpDiscoverDevices() :
- * return a chained list of all devices found or NULL if
- * no devices was found.
- * It is up to the caller to free the chained list
- * delay is in millisecond (poll).
- * UDA v1.1 says :
- *   The TTL for the IP packet SHOULD default to 2 and
- *   SHOULD be configurable. */
-struct UPNPDev *
-ssdpDiscoverDevices(const char * const deviceTypes[],
-                    int delay, const char * multicastif,
-                    int localport,
-                    int ipv6, unsigned char ttl,
-                    int * error,
-                    int searchalltypes)
-{
-	struct UPNPDev * tmp;
-	struct UPNPDev * devlist = 0;
-	unsigned int scope_id = 0;
-	int opt = 1;
-	static const char MSearchMsgFmt[] =
-	"M-SEARCH * HTTP/1.1\r\n"
-	"HOST: %s:" XSTR(SSDP_PORT) "\r\n"
-	"ST: %s\r\n"
-	"MAN: \"ssdp:discover\"\r\n"
-	"MX: %u\r\n"
-	"\r\n";
-	int deviceIndex;
-	char bufr[1536];	/* reception and emission buffer */
-	int sudp;
-	int n;
-	struct sockaddr_storage sockudp_r;
-	unsigned int mx;
-#ifdef NO_GETADDRINFO
-	struct sockaddr_storage sockudp_w;
-#else
-	int rv;
-	struct addrinfo hints, *servinfo, *p;
-#endif
-#ifdef _WIN32
-	MIB_IPFORWARDROW ip_forward;
-	unsigned long _ttl = (unsigned long)ttl;
-#endif
-	int linklocal = 1;
-	int sentok;
-
-	if(error)
-		*error = MINISSDPC_UNKNOWN_ERROR;
-
-	if(localport==UPNP_LOCAL_PORT_SAME)
-		localport = SSDP_PORT;
-
-#ifdef _WIN32
-	sudp = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, IPPROTO_UDP);
-#else
-	sudp = socket(ipv6 ? PF_INET6 : PF_INET, SOCK_DGRAM, 0);
-#endif
-	if(sudp < 0)
-	{
-		if(error)
-			*error = MINISSDPC_SOCKET_ERROR;
-		PRINT_SOCKET_ERROR("socket");
-		return NULL;
-	}
-	/* reception */
-	memset(&sockudp_r, 0, sizeof(struct sockaddr_storage));
-	if(ipv6) {
-		struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_r;
-		p->sin6_family = AF_INET6;
-		if(localport > 0 && localport < 65536)
-			p->sin6_port = htons((unsigned short)localport);
-		p->sin6_addr = in6addr_any; /* in6addr_any is not available with MinGW32 3.4.2 */
-	} else {
-		struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_r;
-		p->sin_family = AF_INET;
-		if(localport > 0 && localport < 65536)
-			p->sin_port = htons((unsigned short)localport);
-		p->sin_addr.s_addr = INADDR_ANY;
-	}
-#ifdef _WIN32
-/* This code could help us to use the right Network interface for
- * SSDP multicast traffic */
-/* Get IP associated with the index given in the ip_forward struct
- * in order to give this ip to setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF) */
-	if(!ipv6
-	   && (GetBestRoute(inet_addr("223.255.255.255"), 0, &ip_forward) == NO_ERROR)) {
-		DWORD dwRetVal = 0;
-		PMIB_IPADDRTABLE pIPAddrTable;
-		DWORD dwSize = 0;
-#ifdef DEBUG
-		IN_ADDR IPAddr;
-#endif
-		int i;
-#ifdef DEBUG
-		printf("ifIndex=%lu nextHop=%lx \n", ip_forward.dwForwardIfIndex, ip_forward.dwForwardNextHop);
-#endif
-		pIPAddrTable = (MIB_IPADDRTABLE *) malloc(sizeof (MIB_IPADDRTABLE));
-		if(pIPAddrTable) {
-			if (GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) {
-				free(pIPAddrTable);
-				pIPAddrTable = (MIB_IPADDRTABLE *) malloc(dwSize);
-			}
-		}
-		if(pIPAddrTable) {
-			dwRetVal = GetIpAddrTable( pIPAddrTable, &dwSize, 0 );
-			if (dwRetVal == NO_ERROR) {
-#ifdef DEBUG
-				printf("\tNum Entries: %ld\n", pIPAddrTable->dwNumEntries);
-#endif
-				for (i=0; i < (int) pIPAddrTable->dwNumEntries; i++) {
-#ifdef DEBUG
-					printf("\n\tInterface Index[%d]:\t%ld\n", i, pIPAddrTable->table[i].dwIndex);
-					IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwAddr;
-					printf("\tIP Address[%d]:     \t%s\n", i, inet_ntoa(IPAddr) );
-					IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwMask;
-					printf("\tSubnet Mask[%d]:    \t%s\n", i, inet_ntoa(IPAddr) );
-					IPAddr.S_un.S_addr = (u_long) pIPAddrTable->table[i].dwBCastAddr;
-					printf("\tBroadCast[%d]:      \t%s (%ld)\n", i, inet_ntoa(IPAddr), pIPAddrTable->table[i].dwBCastAddr);
-					printf("\tReassembly size[%d]:\t%ld\n", i, pIPAddrTable->table[i].dwReasmSize);
-					printf("\tType and State[%d]:", i);
-					printf("\n");
-#endif
-					if (pIPAddrTable->table[i].dwIndex == ip_forward.dwForwardIfIndex) {
-						/* Set the address of this interface to be used */
-						struct in_addr mc_if;
-						memset(&mc_if, 0, sizeof(mc_if));
-						mc_if.s_addr = pIPAddrTable->table[i].dwAddr;
-						if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0) {
-							PRINT_SOCKET_ERROR("setsockopt");
-						}
-						((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = pIPAddrTable->table[i].dwAddr;
-#ifndef DEBUG
-						break;
-#endif
-					}
-				}
-			}
-			free(pIPAddrTable);
-			pIPAddrTable = NULL;
-		}
-	}
-#endif	/* _WIN32 */
-
-#ifdef _WIN32
-	if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, (const char *)&opt, sizeof (opt)) < 0)
-#else
-	if (setsockopt(sudp, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof (opt)) < 0)
-#endif
-	{
-		if(error)
-			*error = MINISSDPC_SOCKET_ERROR;
-		PRINT_SOCKET_ERROR("setsockopt(SO_REUSEADDR,...)");
-		return NULL;
-	}
-
-	if(ipv6) {
-#ifdef _WIN32
-		DWORD mcastHops = ttl;
-		if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, (const char *)&mcastHops, sizeof(mcastHops)) < 0)
-#else  /* _WIN32 */
-		int mcastHops = ttl;
-		if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastHops, sizeof(mcastHops)) < 0)
-#endif /* _WIN32 */
-		{
-			PRINT_SOCKET_ERROR("setsockopt(IPV6_MULTICAST_HOPS,...)");
-		}
-	} else {
-#ifdef _WIN32
-		if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_TTL, (const char *)&_ttl, sizeof(_ttl)) < 0)
-#else  /* _WIN32 */
-		if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_TTL, &ttl, sizeof(ttl)) < 0)
-#endif /* _WIN32 */
-		{
-			/* not a fatal error */
-			PRINT_SOCKET_ERROR("setsockopt(IP_MULTICAST_TTL,...)");
-		}
-	}
-
-	if(multicastif)
-	{
-		if(ipv6) {
-#if !defined(_WIN32)
-			/* according to MSDN, if_nametoindex() is supported since
-			 * MS Windows Vista and MS Windows Server 2008.
-			 * http://msdn.microsoft.com/en-us/library/bb408409%28v=vs.85%29.aspx */
-			unsigned int ifindex = if_nametoindex(multicastif); /* eth0, etc. */
-			if(setsockopt(sudp, IPPROTO_IPV6, IPV6_MULTICAST_IF, &ifindex, sizeof(ifindex)) < 0)
-			{
-				PRINT_SOCKET_ERROR("setsockopt IPV6_MULTICAST_IF");
-			}
-#else
-#ifdef DEBUG
-			printf("Setting of multicast interface not supported in IPv6 under Windows.\n");
-#endif
-#endif
-		} else {
-			struct in_addr mc_if;
-			mc_if.s_addr = inet_addr(multicastif); /* ex: 192.168.x.x */
-			if(mc_if.s_addr != INADDR_NONE)
-			{
-				((struct sockaddr_in *)&sockudp_r)->sin_addr.s_addr = mc_if.s_addr;
-				if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0)
-				{
-					PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF");
-				}
-			} else {
-#ifdef HAS_IP_MREQN
-				/* was not an ip address, try with an interface name */
-				struct ip_mreqn reqn;	/* only defined with -D_BSD_SOURCE or -D_GNU_SOURCE */
-				memset(&reqn, 0, sizeof(struct ip_mreqn));
-				reqn.imr_ifindex = if_nametoindex(multicastif);
-				if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&reqn, sizeof(reqn)) < 0)
-				{
-					PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF");
-				}
-#elif !defined(_WIN32)
-				struct ifreq ifr;
-				int ifrlen = sizeof(ifr);
-				strncpy(ifr.ifr_name, multicastif, IFNAMSIZ);
-				ifr.ifr_name[IFNAMSIZ-1] = '\0';
-				if(ioctl(sudp, SIOCGIFADDR, &ifr, &ifrlen) < 0)
-				{
-					PRINT_SOCKET_ERROR("ioctl(...SIOCGIFADDR...)");
-				}
-				mc_if.s_addr = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
-				if(setsockopt(sudp, IPPROTO_IP, IP_MULTICAST_IF, (const char *)&mc_if, sizeof(mc_if)) < 0)
-				{
-					PRINT_SOCKET_ERROR("setsockopt IP_MULTICAST_IF");
-				}
-#else /* _WIN32 */
-#ifdef DEBUG
-				printf("Setting of multicast interface not supported with interface name.\n");
-#endif
-#endif /* #ifdef HAS_IP_MREQN / !defined(_WIN32) */
-			}
-		}
-	}
-
-	/* Before sending the packed, we first "bind" in order to be able
-	 * to receive the response */
-	if (bind(sudp, (const struct sockaddr *)&sockudp_r,
-	         ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) != 0)
-	{
-		if(error)
-			*error = MINISSDPC_SOCKET_ERROR;
-		PRINT_SOCKET_ERROR("bind");
-		closesocket(sudp);
-		return NULL;
-	}
-
-	if(error)
-		*error = MINISSDPC_SUCCESS;
-	/* Calculating maximum response time in seconds */
-	mx = ((unsigned int)delay) / 1000u;
-	if(mx == 0) {
-		mx = 1;
-		delay = 1000;
-	}
-	/* receiving SSDP response packet */
-	for(deviceIndex = 0; deviceTypes[deviceIndex]; deviceIndex++) {
-		sentok = 0;
-		/* sending the SSDP M-SEARCH packet */
-		n = snprintf(bufr, sizeof(bufr),
-		             MSearchMsgFmt,
-		             ipv6 ?
-		             (linklocal ? "[" UPNP_MCAST_LL_ADDR "]" :  "[" UPNP_MCAST_SL_ADDR "]")
-		             : UPNP_MCAST_ADDR,
-		             deviceTypes[deviceIndex], mx);
-		if ((unsigned int)n >= sizeof(bufr)) {
-			if(error)
-				*error = MINISSDPC_MEMORY_ERROR;
-			goto error;
-		}
-#ifdef DEBUG
-		/*printf("Sending %s", bufr);*/
-		printf("Sending M-SEARCH request to %s with ST: %s\n",
-		       ipv6 ?
-		       (linklocal ? "[" UPNP_MCAST_LL_ADDR "]" :  "[" UPNP_MCAST_SL_ADDR "]")
-		       : UPNP_MCAST_ADDR,
-		       deviceTypes[deviceIndex]);
-#endif
-#ifdef NO_GETADDRINFO
-		/* the following code is not using getaddrinfo */
-		/* emission */
-		memset(&sockudp_w, 0, sizeof(struct sockaddr_storage));
-		if(ipv6) {
-			struct sockaddr_in6 * p = (struct sockaddr_in6 *)&sockudp_w;
-			p->sin6_family = AF_INET6;
-			p->sin6_port = htons(SSDP_PORT);
-			inet_pton(AF_INET6,
-			          linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR,
-			          &(p->sin6_addr));
-		} else {
-			struct sockaddr_in * p = (struct sockaddr_in *)&sockudp_w;
-			p->sin_family = AF_INET;
-			p->sin_port = htons(SSDP_PORT);
-			p->sin_addr.s_addr = inet_addr(UPNP_MCAST_ADDR);
-		}
-		n = sendto(sudp, bufr, n, 0, &sockudp_w,
-		           ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in));
-		if (n < 0) {
-			if(error)
-				*error = MINISSDPC_SOCKET_ERROR;
-			PRINT_SOCKET_ERROR("sendto");
-		} else {
-			sentok = 1;
-		}
-#else /* #ifdef NO_GETADDRINFO */
-		memset(&hints, 0, sizeof(hints));
-		hints.ai_family = AF_UNSPEC; /* AF_INET6 or AF_INET */
-		hints.ai_socktype = SOCK_DGRAM;
-		/*hints.ai_flags = */
-		if ((rv = getaddrinfo(ipv6
-		                      ? (linklocal ? UPNP_MCAST_LL_ADDR : UPNP_MCAST_SL_ADDR)
-		                      : UPNP_MCAST_ADDR,
-		                      XSTR(SSDP_PORT), &hints, &servinfo)) != 0) {
-			if(error)
-				*error = MINISSDPC_SOCKET_ERROR;
-#ifdef _WIN32
-			fprintf(stderr, "getaddrinfo() failed: %d\n", rv);
-#else
-			fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
-#endif
-			break;
-		}
-		for(p = servinfo; p; p = p->ai_next) {
-			n = sendto(sudp, bufr, n, 0, p->ai_addr, p->ai_addrlen);
-			if (n < 0) {
-#ifdef DEBUG
-				char hbuf[NI_MAXHOST], sbuf[NI_MAXSERV];
-				if (getnameinfo(p->ai_addr, p->ai_addrlen, hbuf, sizeof(hbuf), sbuf,
-				                sizeof(sbuf), NI_NUMERICHOST | NI_NUMERICSERV) == 0) {
-					fprintf(stderr, "host:%s port:%s\n", hbuf, sbuf);
-				}
-#endif
-				PRINT_SOCKET_ERROR("sendto");
-				continue;
-			} else {
-				sentok = 1;
-			}
-		}
-		freeaddrinfo(servinfo);
-		if(!sentok) {
-			if(error)
-				*error = MINISSDPC_SOCKET_ERROR;
-		}
-#endif /* #ifdef NO_GETADDRINFO */
-		/* Waiting for SSDP REPLY packet to M-SEARCH
-		 * if searchalltypes is set, enter the loop only
-		 * when the last deviceType is reached */
-		if((sentok && !searchalltypes) || !deviceTypes[deviceIndex + 1]) do {
-			n = receivedata(sudp, bufr, sizeof(bufr), delay, &scope_id);
-			if (n < 0) {
-				/* error */
-				if(error)
-					*error = MINISSDPC_SOCKET_ERROR;
-				goto error;
-			} else if (n == 0) {
-				/* no data or Time Out */
-#ifdef DEBUG
-				printf("NODATA or TIMEOUT\n");
-#endif /* DEBUG */
-				if (devlist && !searchalltypes) {
-					/* found some devices, stop now*/
-					if(error)
-						*error = MINISSDPC_SUCCESS;
-					goto error;
-				}
-			} else {
-				const char * descURL=NULL;
-				int urlsize=0;
-				const char * st=NULL;
-				int stsize=0;
-				const char * usn=NULL;
-				int usnsize=0;
-				parseMSEARCHReply(bufr, n, &descURL, &urlsize, &st, &stsize, &usn, &usnsize);
-				if(st&&descURL) {
-#ifdef DEBUG
-					printf("M-SEARCH Reply:\n  ST: %.*s\n  USN: %.*s\n  Location: %.*s\n",
-					       stsize, st, usnsize, (usn?usn:""), urlsize, descURL);
-#endif /* DEBUG */
-					for(tmp=devlist; tmp; tmp = tmp->pNext) {
-						if(memcmp(tmp->descURL, descURL, urlsize) == 0 &&
-						   tmp->descURL[urlsize] == '\0' &&
-						   memcmp(tmp->st, st, stsize) == 0 &&
-						   tmp->st[stsize] == '\0' &&
-						   (usnsize == 0 || memcmp(tmp->usn, usn, usnsize) == 0) &&
-						   tmp->usn[usnsize] == '\0')
-							break;
-					}
-					/* at the exit of the loop above, tmp is null if
-					 * no duplicate device was found */
-					if(tmp)
-						continue;
-					tmp = (struct UPNPDev *)malloc(sizeof(struct UPNPDev)+urlsize+stsize+usnsize);
-					if(!tmp) {
-						/* memory allocation error */
-						if(error)
-							*error = MINISSDPC_MEMORY_ERROR;
-						goto error;
-					}
-					tmp->pNext = devlist;
-					tmp->descURL = tmp->buffer;
-					tmp->st = tmp->buffer + 1 + urlsize;
-					tmp->usn = tmp->st + 1 + stsize;
-					memcpy(tmp->buffer, descURL, urlsize);
-					tmp->buffer[urlsize] = '\0';
-					memcpy(tmp->st, st, stsize);
-					tmp->buffer[urlsize+1+stsize] = '\0';
-					if(usn != NULL)
-						memcpy(tmp->usn, usn, usnsize);
-					tmp->buffer[urlsize+1+stsize+1+usnsize] = '\0';
-					tmp->scope_id = scope_id;
-					devlist = tmp;
-				}
-			}
-		} while(n > 0);
-		if(ipv6) {
-			/* switch linklocal flag */
-			if(linklocal) {
-				linklocal = 0;
-				--deviceIndex;
-			} else {
-				linklocal = 1;
-			}
-		}
-	}
-error:
-	closesocket(sudp);
-	return devlist;
-}
-

+ 0 - 58
ext/miniupnpc/minissdpc.h

@@ -1,58 +0,0 @@
-/* $Id: minissdpc.h,v 1.7 2015/10/08 16:15:47 nanard Exp $ */
-/* Project: miniupnp
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * Author: Thomas Bernard
- * Copyright (c) 2005-2015 Thomas Bernard
- * This software is subjects to the conditions detailed
- * in the LICENCE file provided within this distribution */
-#ifndef MINISSDPC_H_INCLUDED
-#define MINISSDPC_H_INCLUDED
-
-#include "miniupnpc_declspec.h"
-#include "upnpdev.h"
-
-/* error codes : */
-#define MINISSDPC_SUCCESS (0)
-#define MINISSDPC_UNKNOWN_ERROR (-1)
-#define MINISSDPC_SOCKET_ERROR (-101)
-#define MINISSDPC_MEMORY_ERROR (-102)
-#define MINISSDPC_INVALID_INPUT (-103)
-#define MINISSDPC_INVALID_SERVER_REPLY (-104)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__))
-
-MINIUPNP_LIBSPEC struct UPNPDev *
-getDevicesFromMiniSSDPD(const char * devtype, const char * socketpath, int * error);
-
-MINIUPNP_LIBSPEC int
-connectToMiniSSDPD(const char * socketpath);
-
-MINIUPNP_LIBSPEC int
-disconnectFromMiniSSDPD(int fd);
-
-MINIUPNP_LIBSPEC int
-requestDevicesFromMiniSSDPD(int fd, const char * devtype);
-
-MINIUPNP_LIBSPEC struct UPNPDev *
-receiveDevicesFromMiniSSDPD(int fd, int * error);
-
-#endif /* !(defined(_WIN32) || defined(__amigaos__) || defined(__amigaos4__)) */
-
-MINIUPNP_LIBSPEC struct UPNPDev *
-ssdpDiscoverDevices(const char * const deviceTypes[],
-                    int delay, const char * multicastif,
-                    int localport,
-                    int ipv6, unsigned char ttl,
-                    int * error,
-                    int searchalltypes);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-

+ 0 - 722
ext/miniupnpc/miniupnpc.c

@@ -1,722 +0,0 @@
-/* $Id: miniupnpc.c,v 1.149 2016/02/09 09:50:46 nanard Exp $ */
-/* vim: tabstop=4 shiftwidth=4 noexpandtab
- * Project : miniupnp
- * Web : http://miniupnp.free.fr/
- * Author : Thomas BERNARD
- * copyright (c) 2005-2016 Thomas Bernard
- * This software is subjet to the conditions detailed in the
- * provided LICENSE file. */
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#ifdef _WIN32
-/* Win32 Specific includes and defines */
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <io.h>
-#include <iphlpapi.h>
-#define snprintf _snprintf
-#define strdup _strdup
-#ifndef strncasecmp
-#if defined(_MSC_VER) && (_MSC_VER >= 1400)
-#define strncasecmp _memicmp
-#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
-#define strncasecmp memicmp
-#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
-#endif /* #ifndef strncasecmp */
-#define MAXHOSTNAMELEN 64
-#else /* #ifdef _WIN32 */
-/* Standard POSIX includes */
-#include <unistd.h>
-#if defined(__amigaos__) && !defined(__amigaos4__)
-/* Amiga OS 3 specific stuff */
-#define socklen_t int
-#else
-#include <sys/select.h>
-#endif
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#include <net/if.h>
-#if !defined(__amigaos__) && !defined(__amigaos4__)
-#include <poll.h>
-#endif
-#include <strings.h>
-#include <errno.h>
-#define closesocket close
-#endif /* #else _WIN32 */
-#ifdef __GNU__
-#define MAXHOSTNAMELEN 64
-#endif
-
-
-#include "miniupnpc.h"
-#include "minissdpc.h"
-#include "miniwget.h"
-#include "minisoap.h"
-#include "minixml.h"
-#include "upnpcommands.h"
-#include "connecthostport.h"
-
-/* compare the begining of a string with a constant string */
-#define COMPARE(str, cstr) (0==memcmp(str, cstr, sizeof(cstr) - 1))
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif
-
-#define SOAPPREFIX "s"
-#define SERVICEPREFIX "u"
-#define SERVICEPREFIX2 'u'
-
-/* check if an ip address is a private (LAN) address
- * see https://tools.ietf.org/html/rfc1918 */
-static int is_rfc1918addr(const char * addr)
-{
-	/* 192.168.0.0     -   192.168.255.255 (192.168/16 prefix) */
-	if(COMPARE(addr, "192.168."))
-		return 1;
-	/* 10.0.0.0        -   10.255.255.255  (10/8 prefix) */
-	if(COMPARE(addr, "10."))
-		return 1;
-	/* 172.16.0.0      -   172.31.255.255  (172.16/12 prefix) */
-	if(COMPARE(addr, "172.")) {
-		int i = atoi(addr + 4);
-		if((16 <= i) && (i <= 31))
-			return 1;
-	}
-	return 0;
-}
-
-/* root description parsing */
-MINIUPNP_LIBSPEC void parserootdesc(const char * buffer, int bufsize, struct IGDdatas * data)
-{
-	struct xmlparser parser;
-	/* xmlparser object */
-	parser.xmlstart = buffer;
-	parser.xmlsize = bufsize;
-	parser.data = data;
-	parser.starteltfunc = IGDstartelt;
-	parser.endeltfunc = IGDendelt;
-	parser.datafunc = IGDdata;
-	parser.attfunc = 0;
-	parsexml(&parser);
-#ifdef DEBUG
-	printIGD(data);
-#endif
-}
-
-/* simpleUPnPcommand2 :
- * not so simple !
- * return values :
- *   pointer - OK
- *   NULL - error */
-char * simpleUPnPcommand2(int s, const char * url, const char * service,
-		       const char * action, struct UPNParg * args,
-		       int * bufsize, const char * httpversion)
-{
-	char hostname[MAXHOSTNAMELEN+1];
-	unsigned short port = 0;
-	char * path;
-	char soapact[128];
-	char soapbody[2048];
-	int soapbodylen;
-	char * buf;
-	int n;
-	int status_code;
-
-	*bufsize = 0;
-	snprintf(soapact, sizeof(soapact), "%s#%s", service, action);
-	if(args==NULL)
-	{
-		soapbodylen = snprintf(soapbody, sizeof(soapbody),
-						  "<?xml version=\"1.0\"?>\r\n"
-						  "<" SOAPPREFIX ":Envelope "
-						  "xmlns:" SOAPPREFIX "=\"http://schemas.xmlsoap.org/soap/envelope/\" "
-						  SOAPPREFIX ":encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
-						  "<" SOAPPREFIX ":Body>"
-						  "<" SERVICEPREFIX ":%s xmlns:" SERVICEPREFIX "=\"%s\">"
-						  "</" SERVICEPREFIX ":%s>"
-						  "</" SOAPPREFIX ":Body></" SOAPPREFIX ":Envelope>"
-						  "\r\n", action, service, action);
-		if ((unsigned int)soapbodylen >= sizeof(soapbody))
-			return NULL;
-	}
-	else
-	{
-		char * p;
-		const char * pe, * pv;
-		const char * const pend = soapbody + sizeof(soapbody);
-		soapbodylen = snprintf(soapbody, sizeof(soapbody),
-						"<?xml version=\"1.0\"?>\r\n"
-						"<" SOAPPREFIX ":Envelope "
-						"xmlns:" SOAPPREFIX "=\"http://schemas.xmlsoap.org/soap/envelope/\" "
-						SOAPPREFIX ":encodingStyle=\"http://schemas.xmlsoap.org/soap/encoding/\">"
-						"<" SOAPPREFIX ":Body>"
-						"<" SERVICEPREFIX ":%s xmlns:" SERVICEPREFIX "=\"%s\">",
-						action, service);
-		if ((unsigned int)soapbodylen >= sizeof(soapbody))
-			return NULL;
-		p = soapbody + soapbodylen;
-		while(args->elt)
-		{
-			if(p >= pend) /* check for space to write next byte */
-				return NULL;
-			*(p++) = '<';
-
-			pe = args->elt;
-			while(p < pend && *pe)
-				*(p++) = *(pe++);
-
-			if(p >= pend) /* check for space to write next byte */
-				return NULL;
-			*(p++) = '>';
-
-			if((pv = args->val))
-			{
-				while(p < pend && *pv)
-					*(p++) = *(pv++);
-			}
-
-			if((p+2) > pend) /* check for space to write next 2 bytes */
-				return NULL;
-			*(p++) = '<';
-			*(p++) = '/';
-
-			pe = args->elt;
-			while(p < pend && *pe)
-				*(p++) = *(pe++);
-
-			if(p >= pend) /* check for space to write next byte */
-				return NULL;
-			*(p++) = '>';
-
-			args++;
-		}
-		if((p+4) > pend) /* check for space to write next 4 bytes */
-			return NULL;
-		*(p++) = '<';
-		*(p++) = '/';
-		*(p++) = SERVICEPREFIX2;
-		*(p++) = ':';
-
-		pe = action;
-		while(p < pend && *pe)
-			*(p++) = *(pe++);
-
-		strncpy(p, "></" SOAPPREFIX ":Body></" SOAPPREFIX ":Envelope>\r\n",
-		        pend - p);
-		if(soapbody[sizeof(soapbody)-1]) /* strncpy pads buffer with 0s, so if it doesn't end in 0, could not fit full string */
-			return NULL;
-	}
-	if(!parseURL(url, hostname, &port, &path, NULL)) return NULL;
-	if(s < 0) {
-		s = connecthostport(hostname, port, 0);
-		if(s < 0) {
-			/* failed to connect */
-			return NULL;
-		}
-	}
-
-	n = soapPostSubmit(s, path, hostname, port, soapact, soapbody, httpversion);
-	if(n<=0) {
-#ifdef DEBUG
-		printf("Error sending SOAP request\n");
-#endif
-		closesocket(s);
-		return NULL;
-	}
-
-	buf = getHTTPResponse(s, bufsize, &status_code);
-#ifdef DEBUG
-	if(*bufsize > 0 && buf)
-	{
-		printf("HTTP %d SOAP Response :\n%.*s\n", status_code, *bufsize, buf);
-	}
-	else
-	{
-		printf("HTTP %d, empty SOAP response. size=%d\n", status_code, *bufsize);
-	}
-#endif
-	closesocket(s);
-	return buf;
-}
-
-/* simpleUPnPcommand :
- * not so simple !
- * return values :
- *   pointer - OK
- *   NULL    - error */
-char * simpleUPnPcommand(int s, const char * url, const char * service,
-		       const char * action, struct UPNParg * args,
-		       int * bufsize)
-{
-	char * buf;
-
-#if 1
-	buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1");
-#else
-	buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.0");
-	if (!buf || *bufsize == 0)
-	{
-#if DEBUG
-	    printf("Error or no result from SOAP request; retrying with HTTP/1.1\n");
-#endif
-		buf = simpleUPnPcommand2(s, url, service, action, args, bufsize, "1.1");
-	}
-#endif
-	return buf;
-}
-
-/* upnpDiscoverDevices() :
- * return a chained list of all devices found or NULL if
- * no devices was found.
- * It is up to the caller to free the chained list
- * delay is in millisecond (poll).
- * UDA v1.1 says :
- *   The TTL for the IP packet SHOULD default to 2 and
- *   SHOULD be configurable. */
-MINIUPNP_LIBSPEC struct UPNPDev *
-upnpDiscoverDevices(const char * const deviceTypes[],
-                    int delay, const char * multicastif,
-                    const char * minissdpdsock, int localport,
-                    int ipv6, unsigned char ttl,
-                    int * error,
-                    int searchalltypes)
-{
-	struct UPNPDev * tmp;
-	struct UPNPDev * devlist = 0;
-#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
-	int deviceIndex;
-#endif /* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
-
-	if(error)
-		*error = UPNPDISCOVER_UNKNOWN_ERROR;
-#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
-	/* first try to get infos from minissdpd ! */
-	if(!minissdpdsock)
-		minissdpdsock = "/var/run/minissdpd.sock";
-	for(deviceIndex = 0; deviceTypes[deviceIndex]; deviceIndex++) {
-		struct UPNPDev * minissdpd_devlist;
-		int only_rootdevice = 1;
-		minissdpd_devlist = getDevicesFromMiniSSDPD(deviceTypes[deviceIndex],
-		                                            minissdpdsock, 0);
-		if(minissdpd_devlist) {
-#ifdef DEBUG
-			printf("returned by MiniSSDPD: %s\t%s\n",
-			       minissdpd_devlist->st, minissdpd_devlist->descURL);
-#endif /* DEBUG */
-			if(!strstr(minissdpd_devlist->st, "rootdevice"))
-				only_rootdevice = 0;
-			for(tmp = minissdpd_devlist; tmp->pNext != NULL; tmp = tmp->pNext) {
-#ifdef DEBUG
-				printf("returned by MiniSSDPD: %s\t%s\n",
-				       tmp->pNext->st, tmp->pNext->descURL);
-#endif /* DEBUG */
-				if(!strstr(tmp->st, "rootdevice"))
-					only_rootdevice = 0;
-			}
-			tmp->pNext = devlist;
-			devlist = minissdpd_devlist;
-			if(!searchalltypes && !only_rootdevice)
-				break;
-		}
-	}
-	for(tmp = devlist; tmp != NULL; tmp = tmp->pNext) {
-		/* We return what we have found if it was not only a rootdevice */
-		if(!strstr(tmp->st, "rootdevice")) {
-			if(error)
-				*error = UPNPDISCOVER_SUCCESS;
-			return devlist;
-		}
-	}
-#endif	/* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
-
-	/* direct discovery if minissdpd responses are not sufficient */
-	{
-		struct UPNPDev * discovered_devlist;
-		discovered_devlist = ssdpDiscoverDevices(deviceTypes, delay, multicastif, localport,
-		                                         ipv6, ttl, error, searchalltypes);
-		if(devlist == NULL)
-			devlist = discovered_devlist;
-		else {
-			for(tmp = devlist; tmp->pNext != NULL; tmp = tmp->pNext);
-			tmp->pNext = discovered_devlist;
-		}
-	}
-	return devlist;
-}
-
-/* upnpDiscover() Discover IGD device */
-MINIUPNP_LIBSPEC struct UPNPDev *
-upnpDiscover(int delay, const char * multicastif,
-             const char * minissdpdsock, int localport,
-             int ipv6, unsigned char ttl,
-             int * error)
-{
-	static const char * const deviceList[] = {
-#if 0
-		"urn:schemas-upnp-org:device:InternetGatewayDevice:2",
-		"urn:schemas-upnp-org:service:WANIPConnection:2",
-#endif
-		"urn:schemas-upnp-org:device:InternetGatewayDevice:1",
-		"urn:schemas-upnp-org:service:WANIPConnection:1",
-		"urn:schemas-upnp-org:service:WANPPPConnection:1",
-		"upnp:rootdevice",
-		/*"ssdp:all",*/
-		0
-	};
-	return upnpDiscoverDevices(deviceList,
-	                           delay, multicastif, minissdpdsock, localport,
-	                           ipv6, ttl, error, 0);
-}
-
-/* upnpDiscoverAll() Discover all UPnP devices */
-MINIUPNP_LIBSPEC struct UPNPDev *
-upnpDiscoverAll(int delay, const char * multicastif,
-                const char * minissdpdsock, int localport,
-                int ipv6, unsigned char ttl,
-                int * error)
-{
-	static const char * const deviceList[] = {
-		/*"upnp:rootdevice",*/
-		"ssdp:all",
-		0
-	};
-	return upnpDiscoverDevices(deviceList,
-	                           delay, multicastif, minissdpdsock, localport,
-	                           ipv6, ttl, error, 0);
-}
-
-/* upnpDiscoverDevice() Discover a specific device */
-MINIUPNP_LIBSPEC struct UPNPDev *
-upnpDiscoverDevice(const char * device, int delay, const char * multicastif,
-                const char * minissdpdsock, int localport,
-                int ipv6, unsigned char ttl,
-                int * error)
-{
-	const char * const deviceList[] = {
-		device,
-		0
-	};
-	return upnpDiscoverDevices(deviceList,
-	                           delay, multicastif, minissdpdsock, localport,
-	                           ipv6, ttl, error, 0);
-}
-
-static char *
-build_absolute_url(const char * baseurl, const char * descURL,
-                   const char * url, unsigned int scope_id)
-{
-	int l, n;
-	char * s;
-	const char * base;
-	char * p;
-#if defined(IF_NAMESIZE) && !defined(_WIN32)
-	char ifname[IF_NAMESIZE];
-#else /* defined(IF_NAMESIZE) && !defined(_WIN32) */
-	char scope_str[8];
-#endif	/* defined(IF_NAMESIZE) && !defined(_WIN32) */
-
-	if(  (url[0] == 'h')
-	   &&(url[1] == 't')
-	   &&(url[2] == 't')
-	   &&(url[3] == 'p')
-	   &&(url[4] == ':')
-	   &&(url[5] == '/')
-	   &&(url[6] == '/'))
-		return strdup(url);
-	base = (baseurl[0] == '\0') ? descURL : baseurl;
-	n = strlen(base);
-	if(n > 7) {
-		p = strchr(base + 7, '/');
-		if(p)
-			n = p - base;
-	}
-	l = n + strlen(url) + 1;
-	if(url[0] != '/')
-		l++;
-	if(scope_id != 0) {
-#if defined(IF_NAMESIZE) && !defined(_WIN32)
-		if(if_indextoname(scope_id, ifname)) {
-			l += 3 + strlen(ifname);	/* 3 == strlen(%25) */
-		}
-#else /* defined(IF_NAMESIZE) && !defined(_WIN32) */
-		/* under windows, scope is numerical */
-		l += 3 + snprintf(scope_str, sizeof(scope_str), "%u", scope_id);
-#endif /* defined(IF_NAMESIZE) && !defined(_WIN32) */
-	}
-	s = malloc(l);
-	if(s == NULL) return NULL;
-	memcpy(s, base, n);
-	if(scope_id != 0) {
-		s[n] = '\0';
-		if(0 == memcmp(s, "http://[fe80:", 13)) {
-			/* this is a linklocal IPv6 address */
-			p = strchr(s, ']');
-			if(p) {
-				/* insert %25<scope> into URL */
-#if defined(IF_NAMESIZE) && !defined(_WIN32)
-				memmove(p + 3 + strlen(ifname), p, strlen(p) + 1);
-				memcpy(p, "%25", 3);
-				memcpy(p + 3, ifname, strlen(ifname));
-				n += 3 + strlen(ifname);
-#else /* defined(IF_NAMESIZE) && !defined(_WIN32) */
-				memmove(p + 3 + strlen(scope_str), p, strlen(p) + 1);
-				memcpy(p, "%25", 3);
-				memcpy(p + 3, scope_str, strlen(scope_str));
-				n += 3 + strlen(scope_str);
-#endif /* defined(IF_NAMESIZE) && !defined(_WIN32) */
-			}
-		}
-	}
-	if(url[0] != '/')
-		s[n++] = '/';
-	memcpy(s + n, url, l - n);
-	return s;
-}
-
-/* Prepare the Urls for usage...
- */
-MINIUPNP_LIBSPEC void
-GetUPNPUrls(struct UPNPUrls * urls, struct IGDdatas * data,
-            const char * descURL, unsigned int scope_id)
-{
-	/* strdup descURL */
-	urls->rootdescURL = strdup(descURL);
-
-	/* get description of WANIPConnection */
-	urls->ipcondescURL = build_absolute_url(data->urlbase, descURL,
-	                                        data->first.scpdurl, scope_id);
-	urls->controlURL = build_absolute_url(data->urlbase, descURL,
-	                                      data->first.controlurl, scope_id);
-	urls->controlURL_CIF = build_absolute_url(data->urlbase, descURL,
-	                                          data->CIF.controlurl, scope_id);
-	urls->controlURL_6FC = build_absolute_url(data->urlbase, descURL,
-	                                          data->IPv6FC.controlurl, scope_id);
-
-#ifdef DEBUG
-	printf("urls->ipcondescURL='%s'\n", urls->ipcondescURL);
-	printf("urls->controlURL='%s'\n", urls->controlURL);
-	printf("urls->controlURL_CIF='%s'\n", urls->controlURL_CIF);
-	printf("urls->controlURL_6FC='%s'\n", urls->controlURL_6FC);
-#endif
-}
-
-MINIUPNP_LIBSPEC void
-FreeUPNPUrls(struct UPNPUrls * urls)
-{
-	if(!urls)
-		return;
-	free(urls->controlURL);
-	urls->controlURL = 0;
-	free(urls->ipcondescURL);
-	urls->ipcondescURL = 0;
-	free(urls->controlURL_CIF);
-	urls->controlURL_CIF = 0;
-	free(urls->controlURL_6FC);
-	urls->controlURL_6FC = 0;
-	free(urls->rootdescURL);
-	urls->rootdescURL = 0;
-}
-
-int
-UPNPIGD_IsConnected(struct UPNPUrls * urls, struct IGDdatas * data)
-{
-	char status[64];
-	unsigned int uptime;
-	status[0] = '\0';
-	UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype,
-	                   status, &uptime, NULL);
-	if(0 == strcmp("Connected", status))
-		return 1;
-	else if(0 == strcmp("Up", status))	/* Also accept "Up" */
-		return 1;
-	else
-		return 0;
-}
-
-
-/* UPNP_GetValidIGD() :
- * return values :
- *    -1 = Internal error
- *     0 = NO IGD found
- *     1 = A valid connected IGD has been found
- *     2 = A valid IGD has been found but it reported as
- *         not connected
- *     3 = an UPnP device has been found but was not recognized as an IGD
- *
- * In any positive non zero return case, the urls and data structures
- * passed as parameters are set. Dont forget to call FreeUPNPUrls(urls) to
- * free allocated memory.
- */
-MINIUPNP_LIBSPEC int
-UPNP_GetValidIGD(struct UPNPDev * devlist,
-                 struct UPNPUrls * urls,
-				 struct IGDdatas * data,
-				 char * lanaddr, int lanaddrlen)
-{
-	struct xml_desc {
-		char * xml;
-		int size;
-		int is_igd;
-	} * desc = NULL;
-	struct UPNPDev * dev;
-	int ndev = 0;
-	int i;
-	int state = -1; /* state 1 : IGD connected. State 2 : IGD. State 3 : anything */
-	int n_igd = 0;
-	char extIpAddr[16];
-	char myLanAddr[40];
-	int status_code = -1;
-
-	if(!devlist)
-	{
-#ifdef DEBUG
-		printf("Empty devlist\n");
-#endif
-		return 0;
-	}
-	/* counting total number of devices in the list */
-	for(dev = devlist; dev; dev = dev->pNext)
-		ndev++;
-	if(ndev > 0)
-	{
-		desc = calloc(ndev, sizeof(struct xml_desc));
-		if(!desc)
-			return -1; /* memory allocation error */
-	}
-	/* Step 1 : downloading descriptions and testing type */
-	for(dev = devlist, i = 0; dev; dev = dev->pNext, i++)
-	{
-		/* we should choose an internet gateway device.
-		 * with st == urn:schemas-upnp-org:device:InternetGatewayDevice:1 */
-		desc[i].xml = miniwget_getaddr(dev->descURL, &(desc[i].size),
-		                               myLanAddr, sizeof(myLanAddr),
-		                               dev->scope_id, &status_code);
-#ifdef DEBUG
-		if(!desc[i].xml)
-		{
-			printf("error getting XML description %s\n", dev->descURL);
-		}
-#endif
-		if(desc[i].xml)
-		{
-			memset(data, 0, sizeof(struct IGDdatas));
-			memset(urls, 0, sizeof(struct UPNPUrls));
-			parserootdesc(desc[i].xml, desc[i].size, data);
-			if(COMPARE(data->CIF.servicetype,
-			           "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:"))
-			{
-				desc[i].is_igd = 1;
-				n_igd++;
-				if(lanaddr)
-					strncpy(lanaddr, myLanAddr, lanaddrlen);
-			}
-		}
-	}
-	/* iterate the list to find a device depending on state */
-	for(state = 1; state <= 3; state++)
-	{
-		for(dev = devlist, i = 0; dev; dev = dev->pNext, i++)
-		{
-			if(desc[i].xml)
-			{
-				memset(data, 0, sizeof(struct IGDdatas));
-				memset(urls, 0, sizeof(struct UPNPUrls));
-				parserootdesc(desc[i].xml, desc[i].size, data);
-				if(desc[i].is_igd || state >= 3 )
-				{
-				  int is_connected;
-
-				  GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
-
-				  /* in state 2 and 3 we dont test if device is connected ! */
-				  if(state >= 2)
-				    goto free_and_return;
-				  is_connected = UPNPIGD_IsConnected(urls, data);
-#ifdef DEBUG
-				  printf("UPNPIGD_IsConnected(%s) = %d\n",
-				     urls->controlURL, is_connected);
-#endif
-				  /* checks that status is connected AND there is a external IP address assigned */
-				  if(is_connected &&
-				     (UPNP_GetExternalIPAddress(urls->controlURL,  data->first.servicetype, extIpAddr) == 0)) {
-					if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0')
-					   && (0 != strcmp(extIpAddr, "0.0.0.0")))
-					  goto free_and_return;
-				  }
-				  FreeUPNPUrls(urls);
-				  if(data->second.servicetype[0] != '\0') {
-#ifdef DEBUG
-				    printf("We tried %s, now we try %s !\n",
-				           data->first.servicetype, data->second.servicetype);
-#endif
-				    /* swaping WANPPPConnection and WANIPConnection ! */
-				    memcpy(&data->tmp, &data->first, sizeof(struct IGDdatas_service));
-				    memcpy(&data->first, &data->second, sizeof(struct IGDdatas_service));
-				    memcpy(&data->second, &data->tmp, sizeof(struct IGDdatas_service));
-				    GetUPNPUrls(urls, data, dev->descURL, dev->scope_id);
-				    is_connected = UPNPIGD_IsConnected(urls, data);
-#ifdef DEBUG
-				    printf("UPNPIGD_IsConnected(%s) = %d\n",
-				       urls->controlURL, is_connected);
-#endif
-				    if(is_connected &&
-				       (UPNP_GetExternalIPAddress(urls->controlURL,  data->first.servicetype, extIpAddr) == 0)) {
-					  if(!is_rfc1918addr(extIpAddr) && (extIpAddr[0] != '\0')
-					     && (0 != strcmp(extIpAddr, "0.0.0.0")))
-					    goto free_and_return;
-				    }
-				    FreeUPNPUrls(urls);
-				  }
-				}
-				memset(data, 0, sizeof(struct IGDdatas));
-			}
-		}
-	}
-	state = 0;
-free_and_return:
-	if(desc) {
-		for(i = 0; i < ndev; i++) {
-			if(desc[i].xml) {
-				free(desc[i].xml);
-			}
-		}
-		free(desc);
-	}
-	return state;
-}
-
-/* UPNP_GetIGDFromUrl()
- * Used when skipping the discovery process.
- * return value :
- *   0 - Not ok
- *   1 - OK */
-int
-UPNP_GetIGDFromUrl(const char * rootdescurl,
-                   struct UPNPUrls * urls,
-                   struct IGDdatas * data,
-                   char * lanaddr, int lanaddrlen)
-{
-	char * descXML;
-	int descXMLsize = 0;
-
-	descXML = miniwget_getaddr(rootdescurl, &descXMLsize,
-	                           lanaddr, lanaddrlen, 0, NULL);
-	if(descXML) {
-		memset(data, 0, sizeof(struct IGDdatas));
-		memset(urls, 0, sizeof(struct UPNPUrls));
-		parserootdesc(descXML, descXMLsize, data);
-		free(descXML);
-		descXML = NULL;
-		GetUPNPUrls(urls, data, rootdescurl, 0);
-		return 1;
-	} else {
-		return 0;
-	}
-}
-

+ 0 - 45
ext/miniupnpc/miniupnpc.def

@@ -1,45 +0,0 @@
-LIBRARY
-; miniupnpc library
-   miniupnpc
-
-EXPORTS
-; miniupnpc
-   upnpDiscover
-   freeUPNPDevlist
-   parserootdesc
-   UPNP_GetValidIGD
-   UPNP_GetIGDFromUrl
-   GetUPNPUrls
-   FreeUPNPUrls
-; miniwget
-   miniwget
-   miniwget_getaddr
-; upnpcommands
-   UPNP_GetTotalBytesSent
-   UPNP_GetTotalBytesReceived
-   UPNP_GetTotalPacketsSent
-   UPNP_GetTotalPacketsReceived
-   UPNP_GetStatusInfo
-   UPNP_GetConnectionTypeInfo
-   UPNP_GetExternalIPAddress
-   UPNP_GetLinkLayerMaxBitRates
-   UPNP_AddPortMapping
-   UPNP_AddAnyPortMapping
-   UPNP_DeletePortMapping
-   UPNP_DeletePortMappingRange
-   UPNP_GetPortMappingNumberOfEntries
-   UPNP_GetSpecificPortMappingEntry
-   UPNP_GetGenericPortMappingEntry
-   UPNP_GetListOfPortMappings
-   UPNP_AddPinhole
-   UPNP_CheckPinholeWorking
-   UPNP_UpdatePinhole
-   UPNP_GetPinholePackets
-   UPNP_DeletePinhole
-   UPNP_GetFirewallStatus
-   UPNP_GetOutboundPinholeTimeout
-; upnperrors
-   strupnperror
-; portlistingparse
-   ParsePortListing
-   FreePortListing

+ 0 - 152
ext/miniupnpc/miniupnpc.h

@@ -1,152 +0,0 @@
-/* $Id: miniupnpc.h,v 1.50 2016/04/19 21:06:21 nanard Exp $ */
-/* Project: miniupnp
- * http://miniupnp.free.fr/
- * Author: Thomas Bernard
- * Copyright (c) 2005-2016 Thomas Bernard
- * This software is subjects to the conditions detailed
- * in the LICENCE file provided within this distribution */
-#ifndef MINIUPNPC_H_INCLUDED
-#define MINIUPNPC_H_INCLUDED
-
-#include "miniupnpc_declspec.h"
-#include "igd_desc_parse.h"
-#include "upnpdev.h"
-
-/* error codes : */
-#define UPNPDISCOVER_SUCCESS (0)
-#define UPNPDISCOVER_UNKNOWN_ERROR (-1)
-#define UPNPDISCOVER_SOCKET_ERROR (-101)
-#define UPNPDISCOVER_MEMORY_ERROR (-102)
-
-/* versions : */
-#define MINIUPNPC_VERSION	"2.0.20171212"
-#define MINIUPNPC_API_VERSION	16
-
-/* Source port:
-   Using "1" as an alias for 1900 for backwards compatability
-   (presuming one would have used that for the "sameport" parameter) */
-#define UPNP_LOCAL_PORT_ANY     0
-#define UPNP_LOCAL_PORT_SAME    1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Structures definitions : */
-struct UPNParg { const char * elt; const char * val; };
-
-char *
-simpleUPnPcommand(int, const char *, const char *,
-                  const char *, struct UPNParg *,
-                  int *);
-
-/* upnpDiscover()
- * discover UPnP devices on the network.
- * The discovered devices are returned as a chained list.
- * It is up to the caller to free the list with freeUPNPDevlist().
- * delay (in millisecond) is the maximum time for waiting any device
- * response.
- * If available, device list will be obtained from MiniSSDPd.
- * Default path for minissdpd socket will be used if minissdpdsock argument
- * is NULL.
- * If multicastif is not NULL, it will be used instead of the default
- * multicast interface for sending SSDP discover packets.
- * If localport is set to UPNP_LOCAL_PORT_SAME(1) SSDP packets will be sent
- * from the source port 1900 (same as destination port), if set to
- * UPNP_LOCAL_PORT_ANY(0) system assign a source port, any other value will
- * be attempted as the source port.
- * "searchalltypes" parameter is useful when searching several types,
- * if 0, the discovery will stop with the first type returning results.
- * TTL should default to 2. */
-MINIUPNP_LIBSPEC struct UPNPDev *
-upnpDiscover(int delay, const char * multicastif,
-             const char * minissdpdsock, int localport,
-             int ipv6, unsigned char ttl,
-             int * error);
-
-MINIUPNP_LIBSPEC struct UPNPDev *
-upnpDiscoverAll(int delay, const char * multicastif,
-                const char * minissdpdsock, int localport,
-                int ipv6, unsigned char ttl,
-                int * error);
-
-MINIUPNP_LIBSPEC struct UPNPDev *
-upnpDiscoverDevice(const char * device, int delay, const char * multicastif,
-                const char * minissdpdsock, int localport,
-                int ipv6, unsigned char ttl,
-                int * error);
-
-MINIUPNP_LIBSPEC struct UPNPDev *
-upnpDiscoverDevices(const char * const deviceTypes[],
-                    int delay, const char * multicastif,
-                    const char * minissdpdsock, int localport,
-                    int ipv6, unsigned char ttl,
-                    int * error,
-                    int searchalltypes);
-
-/* parserootdesc() :
- * parse root XML description of a UPnP device and fill the IGDdatas
- * structure. */
-MINIUPNP_LIBSPEC void parserootdesc(const char *, int, struct IGDdatas *);
-
-/* structure used to get fast access to urls
- * controlURL: controlURL of the WANIPConnection
- * ipcondescURL: url of the description of the WANIPConnection
- * controlURL_CIF: controlURL of the WANCommonInterfaceConfig
- * controlURL_6FC: controlURL of the WANIPv6FirewallControl
- */
-struct UPNPUrls {
-	char * controlURL;
-	char * ipcondescURL;
-	char * controlURL_CIF;
-	char * controlURL_6FC;
-	char * rootdescURL;
-};
-
-/* UPNP_GetValidIGD() :
- * return values :
- *     0 = NO IGD found
- *     1 = A valid connected IGD has been found
- *     2 = A valid IGD has been found but it reported as
- *         not connected
- *     3 = an UPnP device has been found but was not recognized as an IGD
- *
- * In any non zero return case, the urls and data structures
- * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to
- * free allocated memory.
- */
-MINIUPNP_LIBSPEC int
-UPNP_GetValidIGD(struct UPNPDev * devlist,
-                 struct UPNPUrls * urls,
-				 struct IGDdatas * data,
-				 char * lanaddr, int lanaddrlen);
-
-/* UPNP_GetIGDFromUrl()
- * Used when skipping the discovery process.
- * When succeding, urls, data, and lanaddr arguments are set.
- * return value :
- *   0 - Not ok
- *   1 - OK */
-MINIUPNP_LIBSPEC int
-UPNP_GetIGDFromUrl(const char * rootdescurl,
-                   struct UPNPUrls * urls,
-                   struct IGDdatas * data,
-                   char * lanaddr, int lanaddrlen);
-
-MINIUPNP_LIBSPEC void
-GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *,
-            const char *, unsigned int);
-
-MINIUPNP_LIBSPEC void
-FreeUPNPUrls(struct UPNPUrls *);
-
-/* return 0 or 1 */
-MINIUPNP_LIBSPEC int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-

+ 0 - 21
ext/miniupnpc/miniupnpc_declspec.h

@@ -1,21 +0,0 @@
-#ifndef MINIUPNPC_DECLSPEC_H_INCLUDED
-#define MINIUPNPC_DECLSPEC_H_INCLUDED
-
-#if defined(_WIN32) && !defined(MINIUPNP_STATICLIB)
-	/* for windows dll */
-	#ifdef MINIUPNP_EXPORTS
-		#define MINIUPNP_LIBSPEC __declspec(dllexport)
-	#else
-		#define MINIUPNP_LIBSPEC __declspec(dllimport)
-	#endif
-#else
-	#if defined(__GNUC__) && __GNUC__ >= 4
-		/* fix dynlib for OS X 10.9.2 and Apple LLVM version 5.0 */
-		#define MINIUPNP_LIBSPEC __attribute__ ((visibility ("default")))
-	#else
-		#define MINIUPNP_LIBSPEC
-	#endif
-#endif
-
-#endif /* MINIUPNPC_DECLSPEC_H_INCLUDED */
-

+ 0 - 703
ext/miniupnpc/miniupnpcmodule.c

@@ -1,703 +0,0 @@
-/* $Id: miniupnpcmodule.c,v 1.31 2017/11/02 15:37:28 nanard Exp $*/
-/* Project : miniupnp
- * Author : Thomas BERNARD
- * website : http://miniupnp.tuxfamily.org/
- * copyright (c) 2007-2016 Thomas Bernard
- * This software is subjet to the conditions detailed in the
- * provided LICENCE file. */
-#include <Python.h>
-#define MINIUPNP_STATICLIB
-#include "structmember.h"
-#include "miniupnpc.h"
-#include "upnpcommands.h"
-#include "upnperrors.h"
-
-#ifdef _WIN32
-#include <winsock2.h>
-#endif
-
-/* for compatibility with Python < 2.4 */
-#ifndef Py_RETURN_NONE
-#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
-#endif
-
-#ifndef Py_RETURN_TRUE
-#define Py_RETURN_TRUE return Py_INCREF(Py_True), Py_True
-#endif
-
-#ifndef Py_RETURN_FALSE
-#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False
-#endif
-
-/* for compatibility with Python < 3.0 */
-#ifndef PyVarObject_HEAD_INIT
-#define PyVarObject_HEAD_INIT(type, size) \
-    PyObject_HEAD_INIT(type) size,
-#endif
-
-#ifndef Py_TYPE
-#define Py_TYPE(ob) (((PyObject*)(ob))->ob_type)
-#endif
-
-typedef struct {
-    PyObject_HEAD
-    /* Type-specific fields go here. */
-	struct UPNPDev * devlist;
-	struct UPNPUrls urls;
-	struct IGDdatas data;
-	unsigned int discoverdelay;	/* value passed to upnpDiscover() */
-	unsigned int localport;		/* value passed to upnpDiscover() */
-	char lanaddr[40];	/* our ip address on the LAN */
-	char * multicastif;
-	char * minissdpdsocket;
-} UPnPObject;
-
-static PyMemberDef UPnP_members[] = {
-	{"lanaddr", T_STRING_INPLACE, offsetof(UPnPObject, lanaddr),
-	 READONLY, "ip address on the LAN"
-	},
-	{"discoverdelay", T_UINT, offsetof(UPnPObject, discoverdelay),
-	 0/*READWRITE*/, "value in ms used to wait for SSDP responses"
-	},
-	{"localport", T_UINT, offsetof(UPnPObject, localport),
-	 0/*READWRITE*/,
-	    "If localport is set to UPNP_LOCAL_PORT_SAME(1) "
-	    "SSDP packets will be sent from the source port "
-	    "1900 (same as destination port), if set to "
-	    "UPNP_LOCAL_PORT_ANY(0) system assign a source "
-	    "port, any other value will be attempted as the "
-	    "source port"
-	},
-	/* T_STRING is allways readonly :( */
-	{"multicastif", T_STRING, offsetof(UPnPObject, multicastif),
-	 0, "IP of the network interface to be used for multicast operations"
-	},
-	{"minissdpdsocket", T_STRING, offsetof(UPnPObject, minissdpdsocket),
-	 0, "path of the MiniSSDPd unix socket"
-	},
-	{NULL}
-};
-
-
-static int UPnP_init(UPnPObject *self, PyObject *args, PyObject *kwds)
-{
-	char* multicastif = NULL;
-	char* minissdpdsocket = NULL;
-	static char *kwlist[] = {
-		"multicastif", "minissdpdsocket", "discoverdelay",
-		"localport", NULL
-	};
-
-	if(!PyArg_ParseTupleAndKeywords(args, kwds, "|zzII", kwlist,
-					&multicastif,
-					&minissdpdsocket,
-					&self->discoverdelay,
-					&self->localport))
-		return -1;
-
-	if(self->localport>1 &&
-	   (self->localport>65534||self->localport<1024)) {
-	    PyErr_SetString(PyExc_Exception, "Invalid localport value");
-	    return -1;
-	}
-	if(multicastif)
-		self->multicastif = strdup(multicastif);
-	if(minissdpdsocket)
-		self->minissdpdsocket = strdup(minissdpdsocket);
-
-	return 0;
-}
-
-static void
-UPnPObject_dealloc(UPnPObject *self)
-{
-	freeUPNPDevlist(self->devlist);
-	FreeUPNPUrls(&self->urls);
-	free(self->multicastif);
-	free(self->minissdpdsocket);
-	Py_TYPE(self)->tp_free((PyObject*)self);
-}
-
-static PyObject *
-UPnP_discover(UPnPObject *self)
-{
-	struct UPNPDev * dev;
-	int i;
-	PyObject *res = NULL;
-	if(self->devlist)
-	{
-		freeUPNPDevlist(self->devlist);
-		self->devlist = 0;
-	}
-	Py_BEGIN_ALLOW_THREADS
-	self->devlist = upnpDiscover((int)self->discoverdelay/*timeout in ms*/,
-	                             self->multicastif,
-	                             self->minissdpdsocket,
-	                             (int)self->localport,
-	                             0/*ip v6*/,
-	                             2/* TTL */,
-	                             0/*error */);
-	Py_END_ALLOW_THREADS
-	/* Py_RETURN_NONE ??? */
-	for(dev = self->devlist, i = 0; dev; dev = dev->pNext)
-		i++;
-	res = Py_BuildValue("i", i);
-	return res;
-}
-
-static PyObject *
-UPnP_selectigd(UPnPObject *self)
-{
-	int r;
-Py_BEGIN_ALLOW_THREADS
-	r = UPNP_GetValidIGD(self->devlist, &self->urls, &self->data,
-	                     self->lanaddr, sizeof(self->lanaddr));
-Py_END_ALLOW_THREADS
-	if(r)
-	{
-		return Py_BuildValue("s", self->urls.controlURL);
-	}
-	else
-	{
-		/* TODO: have our own exception type ! */
-		PyErr_SetString(PyExc_Exception, "No UPnP device discovered");
-		return NULL;
-	}
-}
-
-static PyObject *
-UPnP_totalbytesent(UPnPObject *self)
-{
-	UNSIGNED_INTEGER i;
-Py_BEGIN_ALLOW_THREADS
-	i = UPNP_GetTotalBytesSent(self->urls.controlURL_CIF,
-	                           self->data.CIF.servicetype);
-Py_END_ALLOW_THREADS
-#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3)
-	return Py_BuildValue("I", i);
-#else
-	return Py_BuildValue("i", (int)i);
-#endif
-}
-
-static PyObject *
-UPnP_totalbytereceived(UPnPObject *self)
-{
-	UNSIGNED_INTEGER i;
-Py_BEGIN_ALLOW_THREADS
-	i = UPNP_GetTotalBytesReceived(self->urls.controlURL_CIF,
-		                           self->data.CIF.servicetype);
-Py_END_ALLOW_THREADS
-#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3)
-	return Py_BuildValue("I", i);
-#else
-	return Py_BuildValue("i", (int)i);
-#endif
-}
-
-static PyObject *
-UPnP_totalpacketsent(UPnPObject *self)
-{
-	UNSIGNED_INTEGER i;
-Py_BEGIN_ALLOW_THREADS
-	i = UPNP_GetTotalPacketsSent(self->urls.controlURL_CIF,
-		                         self->data.CIF.servicetype);
-Py_END_ALLOW_THREADS
-#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3)
-	return Py_BuildValue("I", i);
-#else
-	return Py_BuildValue("i", (int)i);
-#endif
-}
-
-static PyObject *
-UPnP_totalpacketreceived(UPnPObject *self)
-{
-	UNSIGNED_INTEGER i;
-Py_BEGIN_ALLOW_THREADS
-	i = UPNP_GetTotalPacketsReceived(self->urls.controlURL_CIF,
-		                          self->data.CIF.servicetype);
-Py_END_ALLOW_THREADS
-#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3)
-	return Py_BuildValue("I", i);
-#else
-	return Py_BuildValue("i", (int)i);
-#endif
-}
-
-static PyObject *
-UPnP_statusinfo(UPnPObject *self)
-{
-	char status[64];
-	char lastconnerror[64];
-	unsigned int uptime = 0;
-	int r;
-	status[0] = '\0';
-	lastconnerror[0] = '\0';
-Py_BEGIN_ALLOW_THREADS
-	r = UPNP_GetStatusInfo(self->urls.controlURL, self->data.first.servicetype,
-	                   status, &uptime, lastconnerror);
-Py_END_ALLOW_THREADS
-	if(r==UPNPCOMMAND_SUCCESS) {
-#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3)
-		return Py_BuildValue("(s,I,s)", status, uptime, lastconnerror);
-#else
-		return Py_BuildValue("(s,i,s)", status, (int)uptime, lastconnerror);
-#endif
-	} else {
-		/* TODO: have our own exception type ! */
-		PyErr_SetString(PyExc_Exception, strupnperror(r));
-		return NULL;
-	}
-}
-
-static PyObject *
-UPnP_connectiontype(UPnPObject *self)
-{
-	char connectionType[64];
-	int r;
-	connectionType[0] = '\0';
-Py_BEGIN_ALLOW_THREADS
-	r = UPNP_GetConnectionTypeInfo(self->urls.controlURL,
-	                               self->data.first.servicetype,
-	                               connectionType);
-Py_END_ALLOW_THREADS
-	if(r==UPNPCOMMAND_SUCCESS) {
-		return Py_BuildValue("s", connectionType);
-	} else {
-		/* TODO: have our own exception type ! */
-		PyErr_SetString(PyExc_Exception, strupnperror(r));
-		return NULL;
-	}
-}
-
-static PyObject *
-UPnP_externalipaddress(UPnPObject *self)
-{
-	char externalIPAddress[40];
-	int r;
-	externalIPAddress[0] = '\0';
-Py_BEGIN_ALLOW_THREADS
-	r = UPNP_GetExternalIPAddress(self->urls.controlURL,
-	                              self->data.first.servicetype,
-	                              externalIPAddress);
-Py_END_ALLOW_THREADS
-	if(r==UPNPCOMMAND_SUCCESS) {
-		return Py_BuildValue("s", externalIPAddress);
-	} else {
-		/* TODO: have our own exception type ! */
-		PyErr_SetString(PyExc_Exception, strupnperror(r));
-		return NULL;
-	}
-}
-
-/* AddPortMapping(externalPort, protocol, internalHost, internalPort, desc,
- *                remoteHost)
- * protocol is 'UDP' or 'TCP' */
-static PyObject *
-UPnP_addportmapping(UPnPObject *self, PyObject *args)
-{
-	char extPort[6];
-	unsigned short ePort;
-	char inPort[6];
-	unsigned short iPort;
-	const char * proto;
-	const char * host;
-	const char * desc;
-	const char * remoteHost;
-	const char * leaseDuration = "0";
-	int r;
-	if (!PyArg_ParseTuple(args, "HssHzz", &ePort, &proto,
-	                                     &host, &iPort, &desc, &remoteHost))
-        return NULL;
-Py_BEGIN_ALLOW_THREADS
-	sprintf(extPort, "%hu", ePort);
-	sprintf(inPort, "%hu", iPort);
-	r = UPNP_AddPortMapping(self->urls.controlURL, self->data.first.servicetype,
-	                        extPort, inPort, host, desc, proto,
-	                        remoteHost, leaseDuration);
-Py_END_ALLOW_THREADS
-	if(r==UPNPCOMMAND_SUCCESS)
-	{
-		Py_RETURN_TRUE;
-	}
-	else
-	{
-		// TODO: RAISE an Exception. See upnpcommands.h for errors codes.
-		// upnperrors.c
-		//Py_RETURN_FALSE;
-		/* TODO: have our own exception type ! */
-		PyErr_SetString(PyExc_Exception, strupnperror(r));
-		return NULL;
-	}
-}
-
-/* AddAnyPortMapping(externalPort, protocol, internalHost, internalPort, desc,
- *                   remoteHost)
- * protocol is 'UDP' or 'TCP' */
-static PyObject *
-UPnP_addanyportmapping(UPnPObject *self, PyObject *args)
-{
-	char extPort[6];
-	unsigned short ePort;
-	char inPort[6];
-	unsigned short iPort;
-	char reservedPort[6];
-	const char * proto;
-	const char * host;
-	const char * desc;
-	const char * remoteHost;
-	const char * leaseDuration = "0";
-	int r;
-	if (!PyArg_ParseTuple(args, "HssHzz", &ePort, &proto, &host, &iPort, &desc, &remoteHost))
-        return NULL;
-Py_BEGIN_ALLOW_THREADS
-	sprintf(extPort, "%hu", ePort);
-	sprintf(inPort, "%hu", iPort);
-	r = UPNP_AddAnyPortMapping(self->urls.controlURL, self->data.first.servicetype,
-	                           extPort, inPort, host, desc, proto,
-	                           remoteHost, leaseDuration, reservedPort);
-Py_END_ALLOW_THREADS
-	if(r==UPNPCOMMAND_SUCCESS) {
-		return Py_BuildValue("i", atoi(reservedPort));
-	} else {
-		/* TODO: have our own exception type ! */
-		PyErr_SetString(PyExc_Exception, strupnperror(r));
-		return NULL;
-	}
-}
-
-
-/* DeletePortMapping(extPort, proto, removeHost='')
- * proto = 'UDP', 'TCP' */
-static PyObject *
-UPnP_deleteportmapping(UPnPObject *self, PyObject *args)
-{
-	char extPort[6];
-	unsigned short ePort;
-	const char * proto;
-	const char * remoteHost = "";
-	int r;
-	if(!PyArg_ParseTuple(args, "Hs|z", &ePort, &proto, &remoteHost))
-		return NULL;
-Py_BEGIN_ALLOW_THREADS
-	sprintf(extPort, "%hu", ePort);
-	r = UPNP_DeletePortMapping(self->urls.controlURL, self->data.first.servicetype,
-	                           extPort, proto, remoteHost);
-Py_END_ALLOW_THREADS
-	if(r==UPNPCOMMAND_SUCCESS) {
-		Py_RETURN_TRUE;
-	} else {
-		/* TODO: have our own exception type ! */
-		PyErr_SetString(PyExc_Exception, strupnperror(r));
-		return NULL;
-	}
-}
-
-/* DeletePortMappingRange(extPort, proto, removeHost='')
- * proto = 'UDP', 'TCP' */
-static PyObject *
-UPnP_deleteportmappingrange(UPnPObject *self, PyObject *args)
-{
-	char extPortStart[6];
-	unsigned short ePortStart;
-	char extPortEnd[6];
-	unsigned short ePortEnd;
-	const char * proto;
-	unsigned char manage;
-	char manageStr[1];
-	int r;
-	if(!PyArg_ParseTuple(args, "HHsb", &ePortStart, &ePortEnd, &proto, &manage))
-		return NULL;
-Py_BEGIN_ALLOW_THREADS
-	sprintf(extPortStart, "%hu", ePortStart);
-	sprintf(extPortEnd, "%hu", ePortEnd);
-	sprintf(manageStr, "%hhu", manage);
-	r = UPNP_DeletePortMappingRange(self->urls.controlURL, self->data.first.servicetype,
-					extPortStart, extPortEnd, proto, manageStr);
-Py_END_ALLOW_THREADS
-	if(r==UPNPCOMMAND_SUCCESS) {
-		Py_RETURN_TRUE;
-	} else {
-		/* TODO: have our own exception type ! */
-		PyErr_SetString(PyExc_Exception, strupnperror(r));
-		return NULL;
-	}
-}
-
-static PyObject *
-UPnP_getportmappingnumberofentries(UPnPObject *self)
-{
-	unsigned int n = 0;
-	int r;
-Py_BEGIN_ALLOW_THREADS
-	r = UPNP_GetPortMappingNumberOfEntries(self->urls.controlURL,
-	                                   self->data.first.servicetype,
-									   &n);
-Py_END_ALLOW_THREADS
-	if(r==UPNPCOMMAND_SUCCESS) {
-#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3)
-		return Py_BuildValue("I", n);
-#else
-		return Py_BuildValue("i", (int)n);
-#endif
-	} else {
-		/* TODO: have our own exception type ! */
-		PyErr_SetString(PyExc_Exception, strupnperror(r));
-		return NULL;
-	}
-}
-
-/* GetSpecificPortMapping(ePort, proto, remoteHost='')
- * proto = 'UDP' or 'TCP' */
-static PyObject *
-UPnP_getspecificportmapping(UPnPObject *self, PyObject *args)
-{
-	char extPort[6];
-	unsigned short ePort;
-	const char * proto;
-	const char * remoteHost = "";
-	char intClient[40];
-	char intPort[6];
-	unsigned short iPort;
-	char desc[80];
-	char enabled[4];
-	char leaseDuration[16];
-	if(!PyArg_ParseTuple(args, "Hs|z", &ePort, &proto, &remoteHost))
-		return NULL;
-	extPort[0] = '\0'; intClient[0] = '\0'; intPort[0] = '\0';
-	desc[0] = '\0'; enabled[0] = '\0'; leaseDuration[0] = '\0';
-Py_BEGIN_ALLOW_THREADS
-	sprintf(extPort, "%hu", ePort);
-	UPNP_GetSpecificPortMappingEntry(self->urls.controlURL,
-	                                 self->data.first.servicetype,
-									 extPort, proto, remoteHost,
-									 intClient, intPort,
-	                                 desc, enabled, leaseDuration);
-Py_END_ALLOW_THREADS
-	if(intClient[0])
-	{
-		iPort = (unsigned short)atoi(intPort);
-		return Py_BuildValue("(s,H,s,O,i)",
-		                     intClient, iPort, desc,
-		                     PyBool_FromLong(atoi(enabled)),
-		                     atoi(leaseDuration));
-	}
-	else
-	{
-		Py_RETURN_NONE;
-	}
-}
-
-/* GetGenericPortMapping(index) */
-static PyObject *
-UPnP_getgenericportmapping(UPnPObject *self, PyObject *args)
-{
-	int i, r;
-	char index[8];
-	char intClient[40];
-	char intPort[6];
-	unsigned short iPort;
-	char extPort[6];
-	unsigned short ePort;
-	char protocol[4];
-	char desc[80];
-	char enabled[6];
-	char rHost[64];
-	char duration[16];	/* lease duration */
-	unsigned int dur;
-	if(!PyArg_ParseTuple(args, "i", &i))
-		return NULL;
-Py_BEGIN_ALLOW_THREADS
-	snprintf(index, sizeof(index), "%d", i);
-	rHost[0] = '\0'; enabled[0] = '\0';
-	duration[0] = '\0'; desc[0] = '\0';
-	extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0';
-	r = UPNP_GetGenericPortMappingEntry(self->urls.controlURL,
-	                                    self->data.first.servicetype,
-										index,
-										extPort, intClient, intPort,
-										protocol, desc, enabled, rHost,
-										duration);
-Py_END_ALLOW_THREADS
-	if(r==UPNPCOMMAND_SUCCESS)
-	{
-		ePort = (unsigned short)atoi(extPort);
-		iPort = (unsigned short)atoi(intPort);
-		dur = (unsigned int)strtoul(duration, 0, 0);
-#if (PY_MAJOR_VERSION >= 3) || (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION > 3)
-		return Py_BuildValue("(H,s,(s,H),s,s,s,I)",
-		                     ePort, protocol, intClient, iPort,
-		                     desc, enabled, rHost, dur);
-#else
-		return Py_BuildValue("(i,s,(s,i),s,s,s,i)",
-		                     (int)ePort, protocol, intClient, (int)iPort,
-		                     desc, enabled, rHost, (int)dur);
-#endif
-	}
-	else
-	{
-		Py_RETURN_NONE;
-	}
-}
-
-/* miniupnpc.UPnP object Method Table */
-static PyMethodDef UPnP_methods[] = {
-    {"discover", (PyCFunction)UPnP_discover, METH_NOARGS,
-     "discover UPnP IGD devices on the network"
-    },
-	{"selectigd", (PyCFunction)UPnP_selectigd, METH_NOARGS,
-	 "select a valid UPnP IGD among discovered devices"
-	},
-	{"totalbytesent", (PyCFunction)UPnP_totalbytesent, METH_NOARGS,
-	 "return the total number of bytes sent by UPnP IGD"
-	},
-	{"totalbytereceived", (PyCFunction)UPnP_totalbytereceived, METH_NOARGS,
-	 "return the total number of bytes received by UPnP IGD"
-	},
-	{"totalpacketsent", (PyCFunction)UPnP_totalpacketsent, METH_NOARGS,
-	 "return the total number of packets sent by UPnP IGD"
-	},
-	{"totalpacketreceived", (PyCFunction)UPnP_totalpacketreceived, METH_NOARGS,
-	 "return the total number of packets received by UPnP IGD"
-	},
-	{"statusinfo", (PyCFunction)UPnP_statusinfo, METH_NOARGS,
-	 "return status and uptime"
-	},
-	{"connectiontype", (PyCFunction)UPnP_connectiontype, METH_NOARGS,
-	 "return IGD WAN connection type"
-	},
-	{"externalipaddress", (PyCFunction)UPnP_externalipaddress, METH_NOARGS,
-	 "return external IP address"
-	},
-	{"addportmapping", (PyCFunction)UPnP_addportmapping, METH_VARARGS,
-	 "add a port mapping"
-	},
-	{"addanyportmapping", (PyCFunction)UPnP_addanyportmapping, METH_VARARGS,
-	 "add a port mapping, IGD to select alternative if necessary"
-	},
-	{"deleteportmapping", (PyCFunction)UPnP_deleteportmapping, METH_VARARGS,
-	 "delete a port mapping"
-	},
-	{"deleteportmappingrange", (PyCFunction)UPnP_deleteportmappingrange, METH_VARARGS,
-	 "delete a range of port mappings"
-	},
-	{"getportmappingnumberofentries", (PyCFunction)UPnP_getportmappingnumberofentries, METH_NOARGS,
-	 "-- non standard --"
-	},
-	{"getspecificportmapping", (PyCFunction)UPnP_getspecificportmapping, METH_VARARGS,
-	 "get details about a specific port mapping entry"
-	},
-	{"getgenericportmapping", (PyCFunction)UPnP_getgenericportmapping, METH_VARARGS,
-	 "get all details about the port mapping at index"
-	},
-    {NULL}  /* Sentinel */
-};
-
-static PyTypeObject UPnPType = {
-    PyVarObject_HEAD_INIT(NULL,
-    0)                         /*ob_size*/
-    "miniupnpc.UPnP",          /*tp_name*/
-    sizeof(UPnPObject),        /*tp_basicsize*/
-    0,                         /*tp_itemsize*/
-    (destructor)UPnPObject_dealloc,/*tp_dealloc*/
-    0,                         /*tp_print*/
-    0,                         /*tp_getattr*/
-    0,                         /*tp_setattr*/
-    0,                         /*tp_compare*/
-    0,                         /*tp_repr*/
-    0,                         /*tp_as_number*/
-    0,                         /*tp_as_sequence*/
-    0,                         /*tp_as_mapping*/
-    0,                         /*tp_hash */
-    0,                         /*tp_call*/
-    0,                         /*tp_str*/
-    0,                         /*tp_getattro*/
-    0,                         /*tp_setattro*/
-    0,                         /*tp_as_buffer*/
-    Py_TPFLAGS_DEFAULT,        /*tp_flags*/
-    "UPnP objects",            /* tp_doc */
-    0,		                   /* tp_traverse */
-    0,		                   /* tp_clear */
-    0,		                   /* tp_richcompare */
-    0,		                   /* tp_weaklistoffset */
-    0,		                   /* tp_iter */
-    0,		                   /* tp_iternext */
-    UPnP_methods,              /* tp_methods */
-    UPnP_members,              /* tp_members */
-    0,                         /* tp_getset */
-    0,                         /* tp_base */
-    0,                         /* tp_dict */
-    0,                         /* tp_descr_get */
-    0,                         /* tp_descr_set */
-    0,                         /* tp_dictoffset */
-    (initproc)UPnP_init,       /* tp_init */
-    0,                         /* tp_alloc */
-#ifndef _WIN32
-    PyType_GenericNew,/*UPnP_new,*/      /* tp_new */
-#else
-    0,
-#endif
-};
-
-/* module methods */
-static PyMethodDef miniupnpc_methods[] = {
-    {NULL}  /* Sentinel */
-};
-
-#if PY_MAJOR_VERSION >= 3
-static struct PyModuleDef moduledef = {
-    PyModuleDef_HEAD_INIT,
-    "miniupnpc",     /* m_name */
-    "miniupnpc module.",  /* m_doc */
-    -1,                  /* m_size */
-    miniupnpc_methods,    /* m_methods */
-    NULL,                /* m_reload */
-    NULL,                /* m_traverse */
-    NULL,                /* m_clear */
-    NULL,                /* m_free */
-};
-#endif
-
-#ifndef PyMODINIT_FUNC	/* declarations for DLL import/export */
-#define PyMODINIT_FUNC void
-#endif
-
-PyMODINIT_FUNC
-#if PY_MAJOR_VERSION >= 3
-PyInit_miniupnpc(void)
-#else
-initminiupnpc(void)
-#endif
-{
-    PyObject* m;
-
-#ifdef _WIN32
-    /* initialize Winsock. */
-    WSADATA wsaData;
-    int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
-
-    UPnPType.tp_new = PyType_GenericNew;
-#endif
-    if (PyType_Ready(&UPnPType) < 0)
-#if PY_MAJOR_VERSION >= 3
-        return 0;
-#else
-        return;
-#endif
-
-#if PY_MAJOR_VERSION >= 3
-    m = PyModule_Create(&moduledef);
-#else
-    m = Py_InitModule3("miniupnpc", miniupnpc_methods,
-                       "miniupnpc module.");
-#endif
-
-    Py_INCREF(&UPnPType);
-    PyModule_AddObject(m, "UPnP", (PyObject *)&UPnPType);
-
-#if PY_MAJOR_VERSION >= 3
-    return m;
-#endif
-}
-

+ 0 - 23
ext/miniupnpc/miniupnpcstrings.h.in

@@ -1,23 +0,0 @@
-/* $Id: miniupnpcstrings.h.in,v 1.6 2014/11/04 22:31:55 nanard Exp $ */
-/* Project: miniupnp
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * Author: Thomas Bernard
- * Copyright (c) 2005-2014 Thomas Bernard
- * This software is subjects to the conditions detailed
- * in the LICENCE file provided within this distribution */
-#ifndef MINIUPNPCSTRINGS_H_INCLUDED
-#define MINIUPNPCSTRINGS_H_INCLUDED
-
-#define OS_STRING "OS/version"
-#define MINIUPNPC_VERSION_STRING "version"
-
-#if 0
-/* according to "UPnP Device Architecture 1.0" */
-#define UPNP_VERSION_STRING "UPnP/1.0"
-#else
-/* according to "UPnP Device Architecture 1.1" */
-#define UPNP_VERSION_STRING "UPnP/1.1"
-#endif
-
-#endif
-

+ 0 - 19
ext/miniupnpc/miniupnpctypes.h

@@ -1,19 +0,0 @@
-/* $Id: miniupnpctypes.h,v 1.2 2012/09/27 15:42:10 nanard Exp $ */
-/* Miniupnp project : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org
- * Author : Thomas Bernard
- * Copyright (c) 2011 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided within this distribution */
-#ifndef MINIUPNPCTYPES_H_INCLUDED
-#define MINIUPNPCTYPES_H_INCLUDED
-
-#if (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L)
-#define UNSIGNED_INTEGER unsigned long long
-#define STRTOUI	strtoull
-#else
-#define UNSIGNED_INTEGER unsigned int
-#define STRTOUI	strtoul
-#endif
-
-#endif
-

+ 0 - 673
ext/miniupnpc/miniwget.c

@@ -1,673 +0,0 @@
-/* $Id: miniwget.c,v 1.77 2017/05/09 10:04:57 nanard Exp $ */
-/* Project : miniupnp
- * Website : http://miniupnp.free.fr/
- * Author : Thomas Bernard
- * Copyright (c) 2005-2017 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-#ifdef _WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#include <io.h>
-#define MAXHOSTNAMELEN 64
-#define snprintf _snprintf
-#define socklen_t int
-#ifndef strncasecmp
-#if defined(_MSC_VER) && (_MSC_VER >= 1400)
-#define strncasecmp _memicmp
-#else /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
-#define strncasecmp memicmp
-#endif /* defined(_MSC_VER) && (_MSC_VER >= 1400) */
-#endif /* #ifndef strncasecmp */
-#else /* #ifdef _WIN32 */
-#include <unistd.h>
-#include <sys/param.h>
-#if defined(__amigaos__) && !defined(__amigaos4__)
-#define socklen_t int
-#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */
-#include <sys/select.h>
-#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <net/if.h>
-#include <netdb.h>
-#define closesocket close
-#include <strings.h>
-#endif /* #else _WIN32 */
-#ifdef __GNU__
-#define MAXHOSTNAMELEN 64
-#endif /* __GNU__ */
-
-#ifndef MIN
-#define MIN(x,y) (((x)<(y))?(x):(y))
-#endif /* MIN */
-
-#ifdef _WIN32
-#define OS_STRING "Win32"
-#define MINIUPNPC_VERSION_STRING "2.0"
-#define UPNP_VERSION_STRING "UPnP/1.1"
-#endif
-
-#ifdef __ANDROID__
-#define OS_STRING "Android"
-#define MINIUPNPC_VERSION_STRING "2.0"
-#define UPNP_VERSION_STRING "UPnP/1.1"
-#endif
-
-#include "miniwget.h"
-#include "connecthostport.h"
-#include "receivedata.h"
-
-#ifndef MAXHOSTNAMELEN
-#define MAXHOSTNAMELEN 64
-#endif
-
-/*
- * Read a HTTP response from a socket.
- * Process Content-Length and Transfer-encoding headers.
- * return a pointer to the content buffer, which length is saved
- * to the length parameter.
- */
-void *
-getHTTPResponse(int s, int * size, int * status_code)
-{
-	char buf[2048];
-	int n;
-	int endofheaders = 0;
-	int chunked = 0;
-	int content_length = -1;
-	unsigned int chunksize = 0;
-	unsigned int bytestocopy = 0;
-	/* buffers : */
-	char * header_buf;
-	unsigned int header_buf_len = 2048;
-	unsigned int header_buf_used = 0;
-	char * content_buf;
-	unsigned int content_buf_len = 2048;
-	unsigned int content_buf_used = 0;
-	char chunksize_buf[32];
-	unsigned int chunksize_buf_index;
-#ifdef DEBUG
-	char * reason_phrase = NULL;
-	int reason_phrase_len = 0;
-#endif
-
-	if(status_code) *status_code = -1;
-	header_buf = malloc(header_buf_len);
-	if(header_buf == NULL)
-	{
-#ifdef DEBUG
-		fprintf(stderr, "%s: Memory allocation error\n", "getHTTPResponse");
-#endif /* DEBUG */
-		*size = -1;
-		return NULL;
-	}
-	content_buf = malloc(content_buf_len);
-	if(content_buf == NULL)
-	{
-		free(header_buf);
-#ifdef DEBUG
-		fprintf(stderr, "%s: Memory allocation error\n", "getHTTPResponse");
-#endif /* DEBUG */
-		*size = -1;
-		return NULL;
-	}
-	chunksize_buf[0] = '\0';
-	chunksize_buf_index = 0;
-
-	while((n = receivedata(s, buf, sizeof(buf), 5000, NULL)) > 0)
-	{
-		if(endofheaders == 0)
-		{
-			int i;
-			int linestart=0;
-			int colon=0;
-			int valuestart=0;
-			if(header_buf_used + n > header_buf_len) {
-				char * tmp = realloc(header_buf, header_buf_used + n);
-				if(tmp == NULL) {
-					/* memory allocation error */
-					free(header_buf);
-					free(content_buf);
-					*size = -1;
-					return NULL;
-				}
-				header_buf = tmp;
-				header_buf_len = header_buf_used + n;
-			}
-			memcpy(header_buf + header_buf_used, buf, n);
-			header_buf_used += n;
-			/* search for CR LF CR LF (end of headers)
-			 * recognize also LF LF */
-			i = 0;
-			while(i < ((int)header_buf_used-1) && (endofheaders == 0)) {
-				if(header_buf[i] == '\r') {
-					i++;
-					if(header_buf[i] == '\n') {
-						i++;
-						if(i < (int)header_buf_used && header_buf[i] == '\r') {
-							i++;
-							if(i < (int)header_buf_used && header_buf[i] == '\n') {
-								endofheaders = i+1;
-							}
-						}
-					}
-				} else if(header_buf[i] == '\n') {
-					i++;
-					if(header_buf[i] == '\n') {
-						endofheaders = i+1;
-					}
-				}
-				i++;
-			}
-			if(endofheaders == 0)
-				continue;
-			/* parse header lines */
-			for(i = 0; i < endofheaders - 1; i++) {
-				if(linestart > 0 && colon <= linestart && header_buf[i]==':')
-				{
-					colon = i;
-					while(i < (endofheaders-1)
-					      && (header_buf[i+1] == ' ' || header_buf[i+1] == '\t'))
-						i++;
-					valuestart = i + 1;
-				}
-				/* detecting end of line */
-				else if(header_buf[i]=='\r' || header_buf[i]=='\n')
-				{
-					if(linestart == 0 && status_code)
-					{
-						/* Status line
-						 * HTTP-Version SP Status-Code SP Reason-Phrase CRLF */
-						int sp;
-						for(sp = 0; sp < i; sp++)
-							if(header_buf[sp] == ' ')
-							{
-								if(*status_code < 0)
-									*status_code = atoi(header_buf + sp + 1);
-								else
-								{
-#ifdef DEBUG
-									reason_phrase = header_buf + sp + 1;
-									reason_phrase_len = i - sp - 1;
-#endif
-									break;
-								}
-							}
-#ifdef DEBUG
-						printf("HTTP status code = %d, Reason phrase = %.*s\n",
-						       *status_code, reason_phrase_len, reason_phrase);
-#endif
-					}
-					else if(colon > linestart && valuestart > colon)
-					{
-#ifdef DEBUG
-						printf("header='%.*s', value='%.*s'\n",
-						       colon-linestart, header_buf+linestart,
-						       i-valuestart, header_buf+valuestart);
-#endif
-						if(0==strncasecmp(header_buf+linestart, "content-length", colon-linestart))
-						{
-							content_length = atoi(header_buf+valuestart);
-#ifdef DEBUG
-							printf("Content-Length: %d\n", content_length);
-#endif
-						}
-						else if(0==strncasecmp(header_buf+linestart, "transfer-encoding", colon-linestart)
-						   && 0==strncasecmp(header_buf+valuestart, "chunked", 7))
-						{
-#ifdef DEBUG
-							printf("chunked transfer-encoding!\n");
-#endif
-							chunked = 1;
-						}
-					}
-					while((i < (int)header_buf_used) && (header_buf[i]=='\r' || header_buf[i] == '\n'))
-						i++;
-					linestart = i;
-					colon = linestart;
-					valuestart = 0;
-				}
-			}
-			/* copy the remaining of the received data back to buf */
-			n = header_buf_used - endofheaders;
-			memcpy(buf, header_buf + endofheaders, n);
-			/* if(headers) */
-		}
-		if(endofheaders)
-		{
-			/* content */
-			if(chunked)
-			{
-				int i = 0;
-				while(i < n)
-				{
-					if(chunksize == 0)
-					{
-						/* reading chunk size */
-						if(chunksize_buf_index == 0) {
-							/* skipping any leading CR LF */
-							if(i<n && buf[i] == '\r') i++;
-							if(i<n && buf[i] == '\n') i++;
-						}
-						while(i<n && isxdigit(buf[i])
-						     && chunksize_buf_index < (sizeof(chunksize_buf)-1))
-						{
-							chunksize_buf[chunksize_buf_index++] = buf[i];
-							chunksize_buf[chunksize_buf_index] = '\0';
-							i++;
-						}
-						while(i<n && buf[i] != '\r' && buf[i] != '\n')
-							i++; /* discarding chunk-extension */
-						if(i<n && buf[i] == '\r') i++;
-						if(i<n && buf[i] == '\n') {
-							unsigned int j;
-							for(j = 0; j < chunksize_buf_index; j++) {
-							if(chunksize_buf[j] >= '0'
-							   && chunksize_buf[j] <= '9')
-								chunksize = (chunksize << 4) + (chunksize_buf[j] - '0');
-							else
-								chunksize = (chunksize << 4) + ((chunksize_buf[j] | 32) - 'a' + 10);
-							}
-							chunksize_buf[0] = '\0';
-							chunksize_buf_index = 0;
-							i++;
-						} else {
-							/* not finished to get chunksize */
-							continue;
-						}
-#ifdef DEBUG
-						printf("chunksize = %u (%x)\n", chunksize, chunksize);
-#endif
-						if(chunksize == 0)
-						{
-#ifdef DEBUG
-							printf("end of HTTP content - %d %d\n", i, n);
-							/*printf("'%.*s'\n", n-i, buf+i);*/
-#endif
-							goto end_of_stream;
-						}
-					}
-					/* it is guaranteed that (n >= i) */
-					bytestocopy = (chunksize < (unsigned int)(n - i))?chunksize:(unsigned int)(n - i);
-					if((content_buf_used + bytestocopy) > content_buf_len)
-					{
-						char * tmp;
-						if((content_length >= 0) && ((unsigned int)content_length >= (content_buf_used + bytestocopy))) {
-							content_buf_len = content_length;
-						} else {
-							content_buf_len = content_buf_used + bytestocopy;
-						}
-						tmp = realloc(content_buf, content_buf_len);
-						if(tmp == NULL) {
-							/* memory allocation error */
-							free(content_buf);
-							free(header_buf);
-							*size = -1;
-							return NULL;
-						}
-						content_buf = tmp;
-					}
-					memcpy(content_buf + content_buf_used, buf + i, bytestocopy);
-					content_buf_used += bytestocopy;
-					i += bytestocopy;
-					chunksize -= bytestocopy;
-				}
-			}
-			else
-			{
-				/* not chunked */
-				if(content_length > 0
-				   && (content_buf_used + n) > (unsigned int)content_length) {
-					/* skipping additional bytes */
-					n = content_length - content_buf_used;
-				}
-				if(content_buf_used + n > content_buf_len)
-				{
-					char * tmp;
-					if(content_length >= 0
-					   && (unsigned int)content_length >= (content_buf_used + n)) {
-						content_buf_len = content_length;
-					} else {
-						content_buf_len = content_buf_used + n;
-					}
-					tmp = realloc(content_buf, content_buf_len);
-					if(tmp == NULL) {
-						/* memory allocation error */
-						free(content_buf);
-						free(header_buf);
-						*size = -1;
-						return NULL;
-					}
-					content_buf = tmp;
-				}
-				memcpy(content_buf + content_buf_used, buf, n);
-				content_buf_used += n;
-			}
-		}
-		/* use the Content-Length header value if available */
-		if(content_length > 0 && content_buf_used >= (unsigned int)content_length)
-		{
-#ifdef DEBUG
-			printf("End of HTTP content\n");
-#endif
-			break;
-		}
-	}
-end_of_stream:
-	free(header_buf); header_buf = NULL;
-	*size = content_buf_used;
-	if(content_buf_used == 0)
-	{
-		free(content_buf);
-		content_buf = NULL;
-	}
-	return content_buf;
-}
-
-/* miniwget3() :
- * do all the work.
- * Return NULL if something failed. */
-static void *
-miniwget3(const char * host,
-          unsigned short port, const char * path,
-          int * size, char * addr_str, int addr_str_len,
-          const char * httpversion, unsigned int scope_id,
-          int * status_code)
-{
-	char buf[2048];
-    int s;
-	int n;
-	int len;
-	int sent;
-	void * content;
-
-	*size = 0;
-	s = connecthostport(host, port, scope_id);
-	if(s < 0)
-		return NULL;
-
-	/* get address for caller ! */
-	if(addr_str)
-	{
-		struct sockaddr_storage saddr;
-		socklen_t saddrlen;
-
-		saddrlen = sizeof(saddr);
-		if(getsockname(s, (struct sockaddr *)&saddr, &saddrlen) < 0)
-		{
-			perror("getsockname");
-		}
-		else
-		{
-#if defined(__amigaos__) && !defined(__amigaos4__)
-	/* using INT WINAPI WSAAddressToStringA(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFOA, LPSTR, LPDWORD);
-     * But his function make a string with the port :  nn.nn.nn.nn:port */
-/*		if(WSAAddressToStringA((SOCKADDR *)&saddr, sizeof(saddr),
-                            NULL, addr_str, (DWORD *)&addr_str_len))
-		{
-		    printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError());
-		}*/
-			/* the following code is only compatible with ip v4 addresses */
-			strncpy(addr_str, inet_ntoa(((struct sockaddr_in *)&saddr)->sin_addr), addr_str_len);
-#else
-#if 0
-			if(saddr.sa_family == AF_INET6) {
-				inet_ntop(AF_INET6,
-				          &(((struct sockaddr_in6 *)&saddr)->sin6_addr),
-				          addr_str, addr_str_len);
-			} else {
-				inet_ntop(AF_INET,
-				          &(((struct sockaddr_in *)&saddr)->sin_addr),
-				          addr_str, addr_str_len);
-			}
-#endif
-			/* getnameinfo return ip v6 address with the scope identifier
-			 * such as : 2a01:e35:8b2b:7330::%4281128194 */
-			n = getnameinfo((const struct sockaddr *)&saddr, saddrlen,
-			                addr_str, addr_str_len,
-			                NULL, 0,
-			                NI_NUMERICHOST | NI_NUMERICSERV);
-			if(n != 0) {
-#ifdef _WIN32
-				fprintf(stderr, "getnameinfo() failed : %d\n", n);
-#else
-				fprintf(stderr, "getnameinfo() failed : %s\n", gai_strerror(n));
-#endif
-			}
-#endif
-		}
-#ifdef DEBUG
-		printf("address miniwget : %s\n", addr_str);
-#endif
-	}
-
-	len = snprintf(buf, sizeof(buf),
-                 "GET %s HTTP/%s\r\n"
-			     "Host: %s:%d\r\n"
-				 "Connection: Close\r\n"
-				 "User-Agent: " OS_STRING ", " UPNP_VERSION_STRING ", MiniUPnPc/" MINIUPNPC_VERSION_STRING "\r\n"
-
-				 "\r\n",
-			   path, httpversion, host, port);
-	if ((unsigned int)len >= sizeof(buf))
-	{
-		closesocket(s);
-		return NULL;
-	}
-	sent = 0;
-	/* sending the HTTP request */
-	while(sent < len)
-	{
-		n = send(s, buf+sent, len-sent, 0);
-		if(n < 0)
-		{
-			perror("send");
-			closesocket(s);
-			return NULL;
-		}
-		else
-		{
-			sent += n;
-		}
-	}
-	content = getHTTPResponse(s, size, status_code);
-	closesocket(s);
-	return content;
-}
-
-/* miniwget2() :
- * Call miniwget3(); retry with HTTP/1.1 if 1.0 fails. */
-static void *
-miniwget2(const char * host,
-          unsigned short port, const char * path,
-          int * size, char * addr_str, int addr_str_len,
-          unsigned int scope_id, int * status_code)
-{
-	char * respbuffer;
-
-#if 1
-	respbuffer = miniwget3(host, port, path, size,
-	                       addr_str, addr_str_len, "1.1",
-	                       scope_id, status_code);
-#else
-	respbuffer = miniwget3(host, port, path, size,
-	                       addr_str, addr_str_len, "1.0",
-	                       scope_id, status_code);
-	if (*size == 0)
-	{
-#ifdef DEBUG
-		printf("Retrying with HTTP/1.1\n");
-#endif
-		free(respbuffer);
-		respbuffer = miniwget3(host, port, path, size,
-		                       addr_str, addr_str_len, "1.1",
-		                       scope_id, status_code);
-	}
-#endif
-	return respbuffer;
-}
-
-
-
-
-/* parseURL()
- * arguments :
- *   url :		source string not modified
- *   hostname :	hostname destination string (size of MAXHOSTNAMELEN+1)
- *   port :		port (destination)
- *   path :		pointer to the path part of the URL
- *
- * Return values :
- *    0 - Failure
- *    1 - Success         */
-int
-parseURL(const char * url,
-         char * hostname, unsigned short * port,
-         char * * path, unsigned int * scope_id)
-{
-	char * p1, *p2, *p3;
-	if(!url)
-		return 0;
-	p1 = strstr(url, "://");
-	if(!p1)
-		return 0;
-	p1 += 3;
-	if(  (url[0]!='h') || (url[1]!='t')
-	   ||(url[2]!='t') || (url[3]!='p'))
-		return 0;
-	memset(hostname, 0, MAXHOSTNAMELEN + 1);
-	if(*p1 == '[')
-	{
-		/* IP v6 : http://[2a00:1450:8002::6a]/path/abc */
-		char * scope;
-		scope = strchr(p1, '%');
-		p2 = strchr(p1, ']');
-		if(p2 && scope && scope < p2 && scope_id) {
-			/* parse scope */
-#ifdef IF_NAMESIZE
-			char tmp[IF_NAMESIZE];
-			int l;
-			scope++;
-			/* "%25" is just '%' in URL encoding */
-			if(scope[0] == '2' && scope[1] == '5')
-				scope += 2;	/* skip "25" */
-			l = p2 - scope;
-			if(l >= IF_NAMESIZE)
-				l = IF_NAMESIZE - 1;
-			memcpy(tmp, scope, l);
-			tmp[l] = '\0';
-			*scope_id = if_nametoindex(tmp);
-			if(*scope_id == 0) {
-				*scope_id = (unsigned int)strtoul(tmp, NULL, 10);
-			}
-#else
-			/* under windows, scope is numerical */
-			char tmp[8];
-			int l;
-			scope++;
-			/* "%25" is just '%' in URL encoding */
-			if(scope[0] == '2' && scope[1] == '5')
-				scope += 2;	/* skip "25" */
-			l = p2 - scope;
-			if(l >= sizeof(tmp))
-				l = sizeof(tmp) - 1;
-			memcpy(tmp, scope, l);
-			tmp[l] = '\0';
-			*scope_id = (unsigned int)strtoul(tmp, NULL, 10);
-#endif
-		}
-		p3 = strchr(p1, '/');
-		if(p2 && p3)
-		{
-			p2++;
-			strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1)));
-			if(*p2 == ':')
-			{
-				*port = 0;
-				p2++;
-				while( (*p2 >= '0') && (*p2 <= '9'))
-				{
-					*port *= 10;
-					*port += (unsigned short)(*p2 - '0');
-					p2++;
-				}
-			}
-			else
-			{
-				*port = 80;
-			}
-			*path = p3;
-			return 1;
-		}
-	}
-	p2 = strchr(p1, ':');
-	p3 = strchr(p1, '/');
-	if(!p3)
-		return 0;
-	if(!p2 || (p2>p3))
-	{
-		strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p3-p1)));
-		*port = 80;
-	}
-	else
-	{
-		strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1)));
-		*port = 0;
-		p2++;
-		while( (*p2 >= '0') && (*p2 <= '9'))
-		{
-			*port *= 10;
-			*port += (unsigned short)(*p2 - '0');
-			p2++;
-		}
-	}
-	*path = p3;
-	return 1;
-}
-
-void *
-miniwget(const char * url, int * size,
-         unsigned int scope_id, int * status_code)
-{
-	unsigned short port;
-	char * path;
-	/* protocol://host:port/chemin */
-	char hostname[MAXHOSTNAMELEN+1];
-	*size = 0;
-	if(!parseURL(url, hostname, &port, &path, &scope_id))
-		return NULL;
-#ifdef DEBUG
-	printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
-	       hostname, port, path, scope_id);
-#endif
-	return miniwget2(hostname, port, path, size, 0, 0, scope_id, status_code);
-}
-
-void *
-miniwget_getaddr(const char * url, int * size,
-                 char * addr, int addrlen, unsigned int scope_id,
-                 int * status_code)
-{
-	unsigned short port;
-	char * path;
-	/* protocol://host:port/path */
-	char hostname[MAXHOSTNAMELEN+1];
-	*size = 0;
-	if(addr)
-		addr[0] = '\0';
-	if(!parseURL(url, hostname, &port, &path, &scope_id))
-		return NULL;
-#ifdef DEBUG
-	printf("parsed url : hostname='%s' port=%hu path='%s' scope_id=%u\n",
-	       hostname, port, path, scope_id);
-#endif
-	return miniwget2(hostname, port, path, size, addr, addrlen, scope_id, status_code);
-}
-

+ 0 - 30
ext/miniupnpc/miniwget.h

@@ -1,30 +0,0 @@
-/* $Id: miniwget.h,v 1.12 2016/01/24 17:24:36 nanard Exp $ */
-/* Project : miniupnp
- * Author : Thomas Bernard
- * Copyright (c) 2005-2016 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution.
- * */
-#ifndef MINIWGET_H_INCLUDED
-#define MINIWGET_H_INCLUDED
-
-#include "miniupnpc_declspec.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-MINIUPNP_LIBSPEC void * getHTTPResponse(int s, int * size, int * status_code);
-
-MINIUPNP_LIBSPEC void * miniwget(const char *, int *, unsigned int, int *);
-
-MINIUPNP_LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int, unsigned int, int *);
-
-int parseURL(const char *, char *, unsigned short *, char * *, unsigned int *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-

+ 0 - 231
ext/miniupnpc/minixml.c

@@ -1,231 +0,0 @@
-/* $Id: minixml.c,v 1.12 2017/12/12 11:17:40 nanard Exp $ */
-/* vim: tabstop=4 shiftwidth=4 noexpandtab
- * minixml.c : the minimum size a xml parser can be ! */
-/* Project : miniupnp
- * webpage: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * Author : Thomas Bernard
-
-Copyright (c) 2005-2017, Thomas BERNARD
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-    * Redistributions of source code must retain the above copyright notice,
-      this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright notice,
-      this list of conditions and the following disclaimer in the documentation
-      and/or other materials provided with the distribution.
-    * The name of the author may not be used to endorse or promote products
-	  derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
-LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
-CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
-SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
-CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
-ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGE.
-*/
-#include <string.h>
-#include "minixml.h"
-
-/* parseatt : used to parse the argument list
- * return 0 (false) in case of success and -1 (true) if the end
- * of the xmlbuffer is reached. */
-static int parseatt(struct xmlparser * p)
-{
-	const char * attname;
-	int attnamelen;
-	const char * attvalue;
-	int attvaluelen;
-	while(p->xml < p->xmlend)
-	{
-		if(*p->xml=='/' || *p->xml=='>')
-			return 0;
-		if( !IS_WHITE_SPACE(*p->xml) )
-		{
-			char sep;
-			attname = p->xml;
-			attnamelen = 0;
-			while(*p->xml!='=' && !IS_WHITE_SPACE(*p->xml) )
-			{
-				attnamelen++; p->xml++;
-				if(p->xml >= p->xmlend)
-					return -1;
-			}
-			while(*(p->xml++) != '=')
-			{
-				if(p->xml >= p->xmlend)
-					return -1;
-			}
-			while(IS_WHITE_SPACE(*p->xml))
-			{
-				p->xml++;
-				if(p->xml >= p->xmlend)
-					return -1;
-			}
-			sep = *p->xml;
-			if(sep=='\'' || sep=='\"')
-			{
-				p->xml++;
-				if(p->xml >= p->xmlend)
-					return -1;
-				attvalue = p->xml;
-				attvaluelen = 0;
-				while(*p->xml != sep)
-				{
-					attvaluelen++; p->xml++;
-					if(p->xml >= p->xmlend)
-						return -1;
-				}
-			}
-			else
-			{
-				attvalue = p->xml;
-				attvaluelen = 0;
-				while(   !IS_WHITE_SPACE(*p->xml)
-					  && *p->xml != '>' && *p->xml != '/')
-				{
-					attvaluelen++; p->xml++;
-					if(p->xml >= p->xmlend)
-						return -1;
-				}
-			}
-			/*printf("%.*s='%.*s'\n",
-			       attnamelen, attname, attvaluelen, attvalue);*/
-			if(p->attfunc)
-				p->attfunc(p->data, attname, attnamelen, attvalue, attvaluelen);
-		}
-		p->xml++;
-	}
-	return -1;
-}
-
-/* parseelt parse the xml stream and
- * call the callback functions when needed... */
-static void parseelt(struct xmlparser * p)
-{
-	int i;
-	const char * elementname;
-	while(p->xml < (p->xmlend - 1))
-	{
-		if((p->xml + 4) <= p->xmlend && (0 == memcmp(p->xml, "<!--", 4)))
-		{
-			p->xml += 3;
-			/* ignore comments */
-			do
-			{
-				p->xml++;
-				if ((p->xml + 3) >= p->xmlend)
-					return;
-			}
-			while(memcmp(p->xml, "-->", 3) != 0);
-			p->xml += 3;
-		}
-		else if((p->xml)[0]=='<' && (p->xml)[1]!='?')
-		{
-			i = 0; elementname = ++p->xml;
-			while( !IS_WHITE_SPACE(*p->xml)
-				  && (*p->xml!='>') && (*p->xml!='/')
-				 )
-			{
-				i++; p->xml++;
-				if (p->xml >= p->xmlend)
-					return;
-				/* to ignore namespace : */
-				if(*p->xml==':')
-				{
-					i = 0;
-					elementname = ++p->xml;
-				}
-			}
-			if(i>0)
-			{
-				if(p->starteltfunc)
-					p->starteltfunc(p->data, elementname, i);
-				if(parseatt(p))
-					return;
-				if(*p->xml!='/')
-				{
-					const char * data;
-					i = 0; data = ++p->xml;
-					if (p->xml >= p->xmlend)
-						return;
-					while( IS_WHITE_SPACE(*p->xml) )
-					{
-						i++; p->xml++;
-						if (p->xml >= p->xmlend)
-							return;
-					}
-					/* CDATA are at least 9 + 3 characters long : <![CDATA[ ]]> */
-					if((p->xmlend >= (p->xml + (9 + 3))) && (memcmp(p->xml, "<![CDATA[", 9) == 0))
-					{
-						/* CDATA handling */
-						p->xml += 9;
-						data = p->xml;
-						i = 0;
-						while(memcmp(p->xml, "]]>", 3) != 0)
-						{
-							i++; p->xml++;
-							if ((p->xml + 3) >= p->xmlend)
-								return;
-						}
-						if(i>0 && p->datafunc)
-							p->datafunc(p->data, data, i);
-						while(*p->xml!='<')
-						{
-							p->xml++;
-							if (p->xml >= p->xmlend)
-								return;
-						}
-					}
-					else
-					{
-						while(*p->xml!='<')
-						{
-							i++; p->xml++;
-							if ((p->xml + 1) >= p->xmlend)
-								return;
-						}
-						if(i>0 && p->datafunc && *(p->xml + 1) == '/')
-							p->datafunc(p->data, data, i);
-					}
-				}
-			}
-			else if(*p->xml == '/')
-			{
-				i = 0; elementname = ++p->xml;
-				if (p->xml >= p->xmlend)
-					return;
-				while((*p->xml != '>'))
-				{
-					i++; p->xml++;
-					if (p->xml >= p->xmlend)
-						return;
-				}
-				if(p->endeltfunc)
-					p->endeltfunc(p->data, elementname, i);
-				p->xml++;
-			}
-		}
-		else
-		{
-			p->xml++;
-		}
-	}
-}
-
-/* the parser must be initialized before calling this function */
-void parsexml(struct xmlparser * parser)
-{
-	parser->xml = parser->xmlstart;
-	parser->xmlend = parser->xmlstart + parser->xmlsize;
-	parseelt(parser);
-}
-
-

+ 0 - 37
ext/miniupnpc/minixml.h

@@ -1,37 +0,0 @@
-/* $Id: minixml.h,v 1.7 2012/09/27 15:42:10 nanard Exp $ */
-/* minimal xml parser
- *
- * Project : miniupnp
- * Website : http://miniupnp.free.fr/
- * Author : Thomas Bernard
- * Copyright (c) 2005 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution.
- * */
-#ifndef MINIXML_H_INCLUDED
-#define MINIXML_H_INCLUDED
-#define IS_WHITE_SPACE(c) ((c==' ') || (c=='\t') || (c=='\r') || (c=='\n'))
-
-/* if a callback function pointer is set to NULL,
- * the function is not called */
-struct xmlparser {
-	const char *xmlstart;
-	const char *xmlend;
-	const char *xml;	/* pointer to current character */
-	int xmlsize;
-	void * data;
-	void (*starteltfunc) (void *, const char *, int);
-	void (*endeltfunc) (void *, const char *, int);
-	void (*datafunc) (void *, const char *, int);
-	void (*attfunc) (void *, const char *, int, const char *, int);
-};
-
-/* parsexml()
- * the xmlparser structure must be initialized before the call
- * the following structure members have to be initialized :
- * xmlstart, xmlsize, data, *func
- * xml is for internal usage, xmlend is computed automatically */
-void parsexml(struct xmlparser *);
-
-#endif
-

+ 0 - 163
ext/miniupnpc/minixmlvalid.c

@@ -1,163 +0,0 @@
-/* $Id: minixmlvalid.c,v 1.7 2015/07/15 12:41:15 nanard Exp $ */
-/* MiniUPnP Project
- * http://miniupnp.tuxfamily.org/ or http://miniupnp.free.fr/
- * minixmlvalid.c :
- * validation program for the minixml parser
- *
- * (c) 2006-2011 Thomas Bernard */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "minixml.h"
-
-/* xml event structure */
-struct event {
-	enum { ELTSTART, ELTEND, ATT, CHARDATA } type;
-	const char * data;
-	int len;
-};
-
-struct eventlist {
-	int n;
-	struct event * events;
-};
-
-/* compare 2 xml event lists
- * return 0 if the two lists are equals */
-int evtlistcmp(struct eventlist * a, struct eventlist * b)
-{
-	int i;
-	struct event * ae, * be;
-	if(a->n != b->n)
-	{
-		printf("event number not matching : %d != %d\n", a->n, b->n);
-		/*return 1;*/
-	}
-	for(i=0; i<a->n; i++)
-	{
-		ae = a->events + i;
-		be = b->events + i;
-		if(  (ae->type != be->type)
-		   ||(ae->len != be->len)
-		   ||memcmp(ae->data, be->data, ae->len))
-		{
-			printf("Found a difference : %d '%.*s' != %d '%.*s'\n",
-			       ae->type, ae->len, ae->data,
-			       be->type, be->len, be->data);
-			return 1;
-		}
-	}
-	return 0;
-}
-
-/* Test data */
-static const char xmldata[] =
-"<xmlroot>\n"
-" <elt1 att1=\"attvalue1\" att2=\"attvalue2\">"
-"character data"
-"</elt1> \n \t"
-"<elt1b/>"
-"<elt1>\n<![CDATA[ <html>stuff !\n ]]> \n</elt1>\n"
-"<elt2a> \t<elt2b>chardata1</elt2b><elt2b> chardata2 </elt2b></elt2a>"
-"</xmlroot>";
-
-static const struct event evtref[] =
-{
-	{ELTSTART, "xmlroot", 7},
-	{ELTSTART, "elt1", 4},
-	/* attributes */
-	{CHARDATA, "character data", 14},
-	{ELTEND, "elt1", 4},
-	{ELTSTART, "elt1b", 5},
-	{ELTSTART, "elt1", 4},
-	{CHARDATA, " <html>stuff !\n ", 16},
-	{ELTEND, "elt1", 4},
-	{ELTSTART, "elt2a", 5},
-	{ELTSTART, "elt2b", 5},
-	{CHARDATA, "chardata1", 9},
-	{ELTEND, "elt2b", 5},
-	{ELTSTART, "elt2b", 5},
-	{CHARDATA, " chardata2 ", 11},
-	{ELTEND, "elt2b", 5},
-	{ELTEND, "elt2a", 5},
-	{ELTEND, "xmlroot", 7}
-};
-
-void startelt(void * data, const char * p, int l)
-{
-	struct eventlist * evtlist = data;
-	struct event * evt;
-	evt = evtlist->events + evtlist->n;
-	/*printf("startelt : %.*s\n", l, p);*/
-	evt->type = ELTSTART;
-	evt->data = p;
-	evt->len = l;
-	evtlist->n++;
-}
-
-void endelt(void * data, const char * p, int l)
-{
-	struct eventlist * evtlist = data;
-	struct event * evt;
-	evt = evtlist->events + evtlist->n;
-	/*printf("endelt : %.*s\n", l, p);*/
-	evt->type = ELTEND;
-	evt->data = p;
-	evt->len = l;
-	evtlist->n++;
-}
-
-void chardata(void * data, const char * p, int l)
-{
-	struct eventlist * evtlist = data;
-	struct event * evt;
-	evt = evtlist->events + evtlist->n;
-	/*printf("chardata : '%.*s'\n", l, p);*/
-	evt->type = CHARDATA;
-	evt->data = p;
-	evt->len = l;
-	evtlist->n++;
-}
-
-int testxmlparser(const char * xml, int size)
-{
-	int r;
-	struct eventlist evtlist;
-	struct eventlist evtlistref;
-	struct xmlparser parser;
-	evtlist.n = 0;
-	evtlist.events = malloc(sizeof(struct event)*100);
-	if(evtlist.events == NULL)
-	{
-		fprintf(stderr, "Memory allocation error.\n");
-		return -1;
-	}
-	memset(&parser, 0, sizeof(parser));
-	parser.xmlstart = xml;
-	parser.xmlsize = size;
-	parser.data = &evtlist;
-	parser.starteltfunc = startelt;
-	parser.endeltfunc = endelt;
-	parser.datafunc = chardata;
-	parsexml(&parser);
-	printf("%d events\n", evtlist.n);
-	/* compare */
-	evtlistref.n = sizeof(evtref)/sizeof(struct event);
-	evtlistref.events = (struct event *)evtref;
-	r = evtlistcmp(&evtlistref, &evtlist);
-	free(evtlist.events);
-	return r;
-}
-
-int main(int argc, char * * argv)
-{
-	int r;
-	(void)argc; (void)argv;
-
-	r = testxmlparser(xmldata, sizeof(xmldata)-1);
-	if(r)
-		printf("minixml validation test failed\n");
-	return r;
-}
-

+ 0 - 172
ext/miniupnpc/portlistingparse.c

@@ -1,172 +0,0 @@
-/* $Id: portlistingparse.c,v 1.10 2016/12/16 08:53:21 nanard Exp $ */
-/* MiniUPnP project
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * (c) 2011-2016 Thomas Bernard
- * This software is subject to the conditions detailed
- * in the LICENCE file provided within the distribution */
-#include <string.h>
-#include <stdlib.h>
-#ifdef DEBUG
-#include <stdio.h>
-#endif /* DEBUG */
-#include "portlistingparse.h"
-#include "minixml.h"
-
-/* list of the elements */
-static const struct {
-	const portMappingElt code;
-	const char * const str;
-} elements[] = {
-	{ PortMappingEntry, "PortMappingEntry"},
-	{ NewRemoteHost, "NewRemoteHost"},
-	{ NewExternalPort, "NewExternalPort"},
-	{ NewProtocol, "NewProtocol"},
-	{ NewInternalPort, "NewInternalPort"},
-	{ NewInternalClient, "NewInternalClient"},
-	{ NewEnabled, "NewEnabled"},
-	{ NewDescription, "NewDescription"},
-	{ NewLeaseTime, "NewLeaseTime"},
-	{ PortMappingEltNone, NULL}
-};
-
-/* Helper function */
-static UNSIGNED_INTEGER
-atoui(const char * p, int l)
-{
-	UNSIGNED_INTEGER r = 0;
-	while(l > 0 && *p)
-	{
-		if(*p >= '0' && *p <= '9')
-			r = r*10 + (*p - '0');
-		else
-			break;
-		p++;
-		l--;
-	}
-	return r;
-}
-
-/* Start element handler */
-static void
-startelt(void * d, const char * name, int l)
-{
-	int i;
-	struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
-	pdata->curelt = PortMappingEltNone;
-	for(i = 0; elements[i].str; i++)
-	{
-		if(strlen(elements[i].str) == (size_t)l && memcmp(name, elements[i].str, l) == 0)
-		{
-			pdata->curelt = elements[i].code;
-			break;
-		}
-	}
-	if(pdata->curelt == PortMappingEntry)
-	{
-		struct PortMapping * pm;
-		pm = calloc(1, sizeof(struct PortMapping));
-		if(pm == NULL)
-		{
-			/* malloc error */
-#ifdef DEBUG
-			fprintf(stderr, "%s: error allocating memory",
-			        "startelt");
-#endif /* DEBUG */
-			return;
-		}
-		pm->l_next = pdata->l_head;	/* insert in list */
-		pdata->l_head = pm;
-	}
-}
-
-/* End element handler */
-static void
-endelt(void * d, const char * name, int l)
-{
-	struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
-	(void)name;
-	(void)l;
-	pdata->curelt = PortMappingEltNone;
-}
-
-/* Data handler */
-static void
-data(void * d, const char * data, int l)
-{
-	struct PortMapping * pm;
-	struct PortMappingParserData * pdata = (struct PortMappingParserData *)d;
-	pm = pdata->l_head;
-	if(!pm)
-		return;
-	if(l > 63)
-		l = 63;
-	switch(pdata->curelt)
-	{
-	case NewRemoteHost:
-		memcpy(pm->remoteHost, data, l);
-		pm->remoteHost[l] = '\0';
-		break;
-	case NewExternalPort:
-		pm->externalPort = (unsigned short)atoui(data, l);
-		break;
-	case NewProtocol:
-		if(l > 3)
-			l = 3;
-		memcpy(pm->protocol, data, l);
-		pm->protocol[l] = '\0';
-		break;
-	case NewInternalPort:
-		pm->internalPort = (unsigned short)atoui(data, l);
-		break;
-	case NewInternalClient:
-		memcpy(pm->internalClient, data, l);
-		pm->internalClient[l] = '\0';
-		break;
-	case NewEnabled:
-		pm->enabled = (unsigned char)atoui(data, l);
-		break;
-	case NewDescription:
-		memcpy(pm->description, data, l);
-		pm->description[l] = '\0';
-		break;
-	case NewLeaseTime:
-		pm->leaseTime = atoui(data, l);
-		break;
-	default:
-		break;
-	}
-}
-
-
-/* Parse the PortMappingList XML document for IGD version 2
- */
-void
-ParsePortListing(const char * buffer, int bufsize,
-                 struct PortMappingParserData * pdata)
-{
-	struct xmlparser parser;
-
-	memset(pdata, 0, sizeof(struct PortMappingParserData));
-	/* init xmlparser */
-	parser.xmlstart = buffer;
-	parser.xmlsize = bufsize;
-	parser.data = pdata;
-	parser.starteltfunc = startelt;
-	parser.endeltfunc = endelt;
-	parser.datafunc = data;
-	parser.attfunc = 0;
-	parsexml(&parser);
-}
-
-void
-FreePortListing(struct PortMappingParserData * pdata)
-{
-	struct PortMapping * pm;
-	while((pm = pdata->l_head) != NULL)
-	{
-		/* remove from list */
-		pdata->l_head = pm->l_next;
-		free(pm);
-	}
-}
-

+ 0 - 65
ext/miniupnpc/portlistingparse.h

@@ -1,65 +0,0 @@
-/* $Id: portlistingparse.h,v 1.11 2015/07/21 13:16:55 nanard Exp $ */
-/* MiniUPnP project
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * (c) 2011-2015 Thomas Bernard
- * This software is subject to the conditions detailed
- * in the LICENCE file provided within the distribution */
-#ifndef PORTLISTINGPARSE_H_INCLUDED
-#define PORTLISTINGPARSE_H_INCLUDED
-
-#include "miniupnpc_declspec.h"
-/* for the definition of UNSIGNED_INTEGER */
-#include "miniupnpctypes.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* sample of PortMappingEntry :
-  <p:PortMappingEntry>
-    <p:NewRemoteHost>202.233.2.1</p:NewRemoteHost>
-    <p:NewExternalPort>2345</p:NewExternalPort>
-    <p:NewProtocol>TCP</p:NewProtocol>
-    <p:NewInternalPort>2345</p:NewInternalPort>
-    <p:NewInternalClient>192.168.1.137</p:NewInternalClient>
-    <p:NewEnabled>1</p:NewEnabled>
-    <p:NewDescription>dooom</p:NewDescription>
-    <p:NewLeaseTime>345</p:NewLeaseTime>
-  </p:PortMappingEntry>
- */
-typedef enum { PortMappingEltNone,
-       PortMappingEntry, NewRemoteHost,
-       NewExternalPort, NewProtocol,
-       NewInternalPort, NewInternalClient,
-       NewEnabled, NewDescription,
-       NewLeaseTime } portMappingElt;
-
-struct PortMapping {
-	struct PortMapping * l_next;	/* list next element */
-	UNSIGNED_INTEGER leaseTime;
-	unsigned short externalPort;
-	unsigned short internalPort;
-	char remoteHost[64];
-	char internalClient[64];
-	char description[64];
-	char protocol[4];
-	unsigned char enabled;
-};
-
-struct PortMappingParserData {
-	struct PortMapping * l_head;	/* list head */
-	portMappingElt curelt;
-};
-
-MINIUPNP_LIBSPEC void
-ParsePortListing(const char * buffer, int bufsize,
-                 struct PortMappingParserData * pdata);
-
-MINIUPNP_LIBSPEC void
-FreePortListing(struct PortMappingParserData * pdata);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif

+ 0 - 105
ext/miniupnpc/receivedata.c

@@ -1,105 +0,0 @@
-/* $Id: receivedata.c,v 1.8 2017/04/21 10:16:45 nanard Exp $ */
-/* Project : miniupnp
- * Website : http://miniupnp.free.fr/
- * Author : Thomas Bernard
- * Copyright (c) 2011-2014 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution. */
-
-#include <stdio.h>
-#include <string.h>
-#ifdef _WIN32
-#include <winsock2.h>
-#include <ws2tcpip.h>
-#else /* _WIN32 */
-#include <unistd.h>
-#if defined(__amigaos__) && !defined(__amigaos4__)
-#define socklen_t int
-#else /* #if defined(__amigaos__) && !defined(__amigaos4__) */
-#include <sys/select.h>
-#endif /* #else defined(__amigaos__) && !defined(__amigaos4__) */
-#include <sys/socket.h>
-#include <netinet/in.h>
-#if !defined(__amigaos__) && !defined(__amigaos4__)
-#include <poll.h>
-#endif	/* !defined(__amigaos__) && !defined(__amigaos4__) */
-#include <errno.h>
-#define MINIUPNPC_IGNORE_EINTR
-#endif /* _WIN32 */
-
-#ifdef _WIN32
-#define PRINT_SOCKET_ERROR(x)    fprintf(stderr, "Socket error: %s, %d\n", x, WSAGetLastError());
-#else
-#define PRINT_SOCKET_ERROR(x) perror(x)
-#endif
-
-#include "receivedata.h"
-
-int
-receivedata(int socket,
-            char * data, int length,
-            int timeout, unsigned int * scope_id)
-{
-#ifdef MINIUPNPC_GET_SRC_ADDR
-	struct sockaddr_storage src_addr;
-	socklen_t src_addr_len = sizeof(src_addr);
-#endif	/* MINIUPNPC_GET_SRC_ADDR */
-    int n;
-#if !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__)
-	/* using poll */
-    struct pollfd fds[1]; /* for the poll */
-#ifdef MINIUPNPC_IGNORE_EINTR
-    do {
-#endif	/* MINIUPNPC_IGNORE_EINTR */
-        fds[0].fd = socket;
-        fds[0].events = POLLIN;
-        n = poll(fds, 1, timeout);
-#ifdef MINIUPNPC_IGNORE_EINTR
-    } while(n < 0 && errno == EINTR);
-#endif	/* MINIUPNPC_IGNORE_EINTR */
-    if(n < 0) {
-        PRINT_SOCKET_ERROR("poll");
-        return -1;
-    } else if(n == 0) {
-		/* timeout */
-        return 0;
-    }
-#else	/* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
-	/* using select under _WIN32 and amigaos */
-    fd_set socketSet;
-    TIMEVAL timeval;
-    FD_ZERO(&socketSet);
-    FD_SET(socket, &socketSet);
-    timeval.tv_sec = timeout / 1000;
-    timeval.tv_usec = (timeout % 1000) * 1000;
-    n = select(FD_SETSIZE, &socketSet, NULL, NULL, &timeval);
-    if(n < 0) {
-        PRINT_SOCKET_ERROR("select");
-        return -1;
-    } else if(n == 0) {
-        return 0;
-    }
-#endif	/* !defined(_WIN32) && !defined(__amigaos__) && !defined(__amigaos4__) */
-#ifdef MINIUPNPC_GET_SRC_ADDR
-	memset(&src_addr, 0, sizeof(src_addr));
-	n = recvfrom(socket, data, length, 0,
-	             (struct sockaddr *)&src_addr, &src_addr_len);
-#else	/* MINIUPNPC_GET_SRC_ADDR */
-	n = recv(socket, data, length, 0);
-#endif	/* MINIUPNPC_GET_SRC_ADDR */
-	if(n<0) {
-		PRINT_SOCKET_ERROR("recv");
-	}
-#ifdef MINIUPNPC_GET_SRC_ADDR
-	if (src_addr.ss_family == AF_INET6) {
-		const struct sockaddr_in6 * src_addr6 = (struct sockaddr_in6 *)&src_addr;
-#ifdef DEBUG
-		printf("scope_id=%u\n", src_addr6->sin6_scope_id);
-#endif	/* DEBUG */
-		if(scope_id)
-			*scope_id = src_addr6->sin6_scope_id;
-	}
-#endif	/* MINIUPNPC_GET_SRC_ADDR */
-	return n;
-}
-

+ 0 - 19
ext/miniupnpc/receivedata.h

@@ -1,19 +0,0 @@
-/* $Id: receivedata.h,v 1.4 2012/09/27 15:42:10 nanard Exp $ */
-/* Project: miniupnp
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * Author: Thomas Bernard
- * Copyright (c) 2011-2012 Thomas Bernard
- * This software is subjects to the conditions detailed
- * in the LICENCE file provided within this distribution */
-#ifndef RECEIVEDATA_H_INCLUDED
-#define RECEIVEDATA_H_INCLUDED
-
-/* Reads data from the specified socket.
- * Returns the number of bytes read if successful, zero if no bytes were
- * read or if we timed out. Returns negative if there was an error. */
-int receivedata(int socket,
-                char * data, int length,
-                int timeout, unsigned int * scope_id);
-
-#endif
-

+ 0 - 53
ext/miniupnpc/updateminiupnpcstrings.sh

@@ -1,53 +0,0 @@
-#! /bin/sh
-# $Id: updateminiupnpcstrings.sh,v 1.7 2011/01/04 11:41:53 nanard Exp $
-# project miniupnp : http://miniupnp.free.fr/
-# (c) 2009 Thomas Bernard
-
-FILE=miniupnpcstrings.h
-TMPFILE=miniupnpcstrings.h.tmp
-TEMPLATE_FILE=${FILE}.in
-
-# detecting the OS name and version
-OS_NAME=`uname -s`
-OS_VERSION=`uname -r`
-if [ -f /etc/debian_version ]; then
-	OS_NAME=Debian
-	OS_VERSION=`cat /etc/debian_version`
-fi
-# use lsb_release (Linux Standard Base) when available
-LSB_RELEASE=`which lsb_release`
-if [ 0 -eq $? -a -x "${LSB_RELEASE}" ]; then
-	OS_NAME=`${LSB_RELEASE} -i -s`
-	OS_VERSION=`${LSB_RELEASE} -r -s`
-	case $OS_NAME in
-		Debian)
-			#OS_VERSION=`${LSB_RELEASE} -c -s`
-			;;
-		Ubuntu)
-			#OS_VERSION=`${LSB_RELEASE} -c -s`
-			;;
-	esac
-fi
-
-# on AmigaOS 3, uname -r returns "unknown", so we use uname -v
-if [ "$OS_NAME" = "AmigaOS" ]; then
-	if [ "$OS_VERSION" = "unknown" ]; then
-		OS_VERSION=`uname -v`
-	fi
-fi
-
-echo "Detected OS [$OS_NAME] version [$OS_VERSION]"
-MINIUPNPC_VERSION=`cat VERSION`
-echo "MiniUPnPc version [${MINIUPNPC_VERSION}]"
-
-EXPR="s|OS_STRING \".*\"|OS_STRING \"${OS_NAME}/${OS_VERSION}\"|"
-#echo $EXPR
-test -f ${FILE}.in
-echo "setting OS_STRING macro value to ${OS_NAME}/${OS_VERSION} in $FILE."
-sed -e "$EXPR" < $TEMPLATE_FILE > $TMPFILE
-
-EXPR="s|MINIUPNPC_VERSION_STRING \".*\"|MINIUPNPC_VERSION_STRING \"${MINIUPNPC_VERSION}\"|"
-echo "setting MINIUPNPC_VERSION_STRING macro value to ${MINIUPNPC_VERSION} in $FILE."
-sed -e "$EXPR" < $TMPFILE > $FILE
-rm $TMPFILE
-

+ 0 - 857
ext/miniupnpc/upnpc.c

@@ -1,857 +0,0 @@
-/* $Id: upnpc.c,v 1.117 2017/05/26 15:26:55 nanard Exp $ */
-/* Project : miniupnp
- * Author : Thomas Bernard
- * Copyright (c) 2005-2017 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution. */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-#ifdef _WIN32
-#include <winsock2.h>
-#define snprintf _snprintf
-#else
-/* for IPPROTO_TCP / IPPROTO_UDP */
-#include <netinet/in.h>
-#endif
-#include <ctype.h>
-#include "miniwget.h"
-#include "miniupnpc.h"
-#include "upnpcommands.h"
-#include "upnperrors.h"
-#include "miniupnpcstrings.h"
-
-/* protofix() checks if protocol is "UDP" or "TCP"
- * returns NULL if not */
-const char * protofix(const char * proto)
-{
-	static const char proto_tcp[4] = { 'T', 'C', 'P', 0};
-	static const char proto_udp[4] = { 'U', 'D', 'P', 0};
-	int i, b;
-	for(i=0, b=1; i<4; i++)
-		b = b && (   (proto[i] == proto_tcp[i])
-		          || (proto[i] == (proto_tcp[i] | 32)) );
-	if(b)
-		return proto_tcp;
-	for(i=0, b=1; i<4; i++)
-		b = b && (   (proto[i] == proto_udp[i])
-		          || (proto[i] == (proto_udp[i] | 32)) );
-	if(b)
-		return proto_udp;
-	return 0;
-}
-
-/* is_int() checks if parameter is an integer or not
- * 1 for integer
- * 0 for not an integer */
-int is_int(char const* s)
-{
-	if(s == NULL)
-		return 0;
-	while(*s) {
-		/* #define isdigit(c) ((c) >= '0' && (c) <= '9') */
-		if(!isdigit(*s))
-			return 0;
-		s++;
-	}
-	return 1;
-}
-
-static void DisplayInfos(struct UPNPUrls * urls,
-                         struct IGDdatas * data)
-{
-	char externalIPAddress[40];
-	char connectionType[64];
-	char status[64];
-	char lastconnerr[64];
-	unsigned int uptime = 0;
-	unsigned int brUp, brDown;
-	time_t timenow, timestarted;
-	int r;
-	if(UPNP_GetConnectionTypeInfo(urls->controlURL,
-	                              data->first.servicetype,
-	                              connectionType) != UPNPCOMMAND_SUCCESS)
-		printf("GetConnectionTypeInfo failed.\n");
-	else
-		printf("Connection Type : %s\n", connectionType);
-	if(UPNP_GetStatusInfo(urls->controlURL, data->first.servicetype,
-	                      status, &uptime, lastconnerr) != UPNPCOMMAND_SUCCESS)
-		printf("GetStatusInfo failed.\n");
-	else
-		printf("Status : %s, uptime=%us, LastConnectionError : %s\n",
-		       status, uptime, lastconnerr);
-	if(uptime > 0) {
-		timenow = time(NULL);
-		timestarted = timenow - uptime;
-		printf("  Time started : %s", ctime(&timestarted));
-	}
-	if(UPNP_GetLinkLayerMaxBitRates(urls->controlURL_CIF, data->CIF.servicetype,
-	                                &brDown, &brUp) != UPNPCOMMAND_SUCCESS) {
-		printf("GetLinkLayerMaxBitRates failed.\n");
-	} else {
-		printf("MaxBitRateDown : %u bps", brDown);
-		if(brDown >= 1000000) {
-			printf(" (%u.%u Mbps)", brDown / 1000000, (brDown / 100000) % 10);
-		} else if(brDown >= 1000) {
-			printf(" (%u Kbps)", brDown / 1000);
-		}
-		printf("   MaxBitRateUp %u bps", brUp);
-		if(brUp >= 1000000) {
-			printf(" (%u.%u Mbps)", brUp / 1000000, (brUp / 100000) % 10);
-		} else if(brUp >= 1000) {
-			printf(" (%u Kbps)", brUp / 1000);
-		}
-		printf("\n");
-	}
-	r = UPNP_GetExternalIPAddress(urls->controlURL,
-	                          data->first.servicetype,
-							  externalIPAddress);
-	if(r != UPNPCOMMAND_SUCCESS) {
-		printf("GetExternalIPAddress failed. (errorcode=%d)\n", r);
-	} else {
-		printf("ExternalIPAddress = %s\n", externalIPAddress);
-	}
-}
-
-static void GetConnectionStatus(struct UPNPUrls * urls,
-                               struct IGDdatas * data)
-{
-	unsigned int bytessent, bytesreceived, packetsreceived, packetssent;
-	DisplayInfos(urls, data);
-	bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype);
-	bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype);
-	packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->CIF.servicetype);
-	packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->CIF.servicetype);
-	printf("Bytes:   Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived);
-	printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived);
-}
-
-static void ListRedirections(struct UPNPUrls * urls,
-                             struct IGDdatas * data)
-{
-	int r;
-	int i = 0;
-	char index[6];
-	char intClient[40];
-	char intPort[6];
-	char extPort[6];
-	char protocol[4];
-	char desc[80];
-	char enabled[6];
-	char rHost[64];
-	char duration[16];
-	/*unsigned int num=0;
-	UPNP_GetPortMappingNumberOfEntries(urls->controlURL, data->servicetype, &num);
-	printf("PortMappingNumberOfEntries : %u\n", num);*/
-	printf(" i protocol exPort->inAddr:inPort description remoteHost leaseTime\n");
-	do {
-		snprintf(index, 6, "%d", i);
-		rHost[0] = '\0'; enabled[0] = '\0';
-		duration[0] = '\0'; desc[0] = '\0';
-		extPort[0] = '\0'; intPort[0] = '\0'; intClient[0] = '\0';
-		r = UPNP_GetGenericPortMappingEntry(urls->controlURL,
-		                               data->first.servicetype,
-		                               index,
-		                               extPort, intClient, intPort,
-									   protocol, desc, enabled,
-									   rHost, duration);
-		if(r==0)
-		/*
-			printf("%02d - %s %s->%s:%s\tenabled=%s leaseDuration=%s\n"
-			       "     desc='%s' rHost='%s'\n",
-			       i, protocol, extPort, intClient, intPort,
-				   enabled, duration,
-				   desc, rHost);
-				   */
-			printf("%2d %s %5s->%s:%-5s '%s' '%s' %s\n",
-			       i, protocol, extPort, intClient, intPort,
-			       desc, rHost, duration);
-		else
-			printf("GetGenericPortMappingEntry() returned %d (%s)\n",
-			       r, strupnperror(r));
-		i++;
-	} while(r==0);
-}
-
-static void NewListRedirections(struct UPNPUrls * urls,
-                                struct IGDdatas * data)
-{
-	int r;
-	int i = 0;
-	struct PortMappingParserData pdata;
-	struct PortMapping * pm;
-
-	memset(&pdata, 0, sizeof(struct PortMappingParserData));
-	r = UPNP_GetListOfPortMappings(urls->controlURL,
-                                   data->first.servicetype,
-	                               "0",
-	                               "65535",
-	                               "TCP",
-	                               "1000",
-	                               &pdata);
-	if(r == UPNPCOMMAND_SUCCESS)
-	{
-		printf(" i protocol exPort->inAddr:inPort description remoteHost leaseTime\n");
-		for(pm = pdata.l_head; pm != NULL; pm = pm->l_next)
-		{
-			printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n",
-			       i, pm->protocol, pm->externalPort, pm->internalClient,
-			       pm->internalPort,
-			       pm->description, pm->remoteHost,
-			       (unsigned)pm->leaseTime);
-			i++;
-		}
-		FreePortListing(&pdata);
-	}
-	else
-	{
-		printf("GetListOfPortMappings() returned %d (%s)\n",
-		       r, strupnperror(r));
-	}
-	r = UPNP_GetListOfPortMappings(urls->controlURL,
-                                   data->first.servicetype,
-	                               "0",
-	                               "65535",
-	                               "UDP",
-	                               "1000",
-	                               &pdata);
-	if(r == UPNPCOMMAND_SUCCESS)
-	{
-		for(pm = pdata.l_head; pm != NULL; pm = pm->l_next)
-		{
-			printf("%2d %s %5hu->%s:%-5hu '%s' '%s' %u\n",
-			       i, pm->protocol, pm->externalPort, pm->internalClient,
-			       pm->internalPort,
-			       pm->description, pm->remoteHost,
-			       (unsigned)pm->leaseTime);
-			i++;
-		}
-		FreePortListing(&pdata);
-	}
-	else
-	{
-		printf("GetListOfPortMappings() returned %d (%s)\n",
-		       r, strupnperror(r));
-	}
-}
-
-/* Test function
- * 1 - get connection type
- * 2 - get extenal ip address
- * 3 - Add port mapping
- * 4 - get this port mapping from the IGD */
-static int SetRedirectAndTest(struct UPNPUrls * urls,
-			       struct IGDdatas * data,
-			       const char * iaddr,
-			       const char * iport,
-			       const char * eport,
-			       const char * proto,
-			       const char * leaseDuration,
-			       const char * description,
-			       int addAny)
-{
-	char externalIPAddress[40];
-	char intClient[40];
-	char intPort[6];
-	char reservedPort[6];
-	char duration[16];
-	int r;
-
-	if(!iaddr || !iport || !eport || !proto)
-	{
-		fprintf(stderr, "Wrong arguments\n");
-		return -1;
-	}
-	proto = protofix(proto);
-	if(!proto)
-	{
-		fprintf(stderr, "invalid protocol\n");
-		return -1;
-	}
-
-	r = UPNP_GetExternalIPAddress(urls->controlURL,
-				      data->first.servicetype,
-				      externalIPAddress);
-	if(r!=UPNPCOMMAND_SUCCESS)
-		printf("GetExternalIPAddress failed.\n");
-	else
-		printf("ExternalIPAddress = %s\n", externalIPAddress);
-
-	if (addAny) {
-		r = UPNP_AddAnyPortMapping(urls->controlURL, data->first.servicetype,
-					   eport, iport, iaddr, description,
-					   proto, 0, leaseDuration, reservedPort);
-		if(r==UPNPCOMMAND_SUCCESS)
-			eport = reservedPort;
-		else
-			printf("AddAnyPortMapping(%s, %s, %s) failed with code %d (%s)\n",
-			       eport, iport, iaddr, r, strupnperror(r));
-	} else {
-		r = UPNP_AddPortMapping(urls->controlURL, data->first.servicetype,
-					eport, iport, iaddr, description,
-					proto, 0, leaseDuration);
-		if(r!=UPNPCOMMAND_SUCCESS) {
-			printf("AddPortMapping(%s, %s, %s) failed with code %d (%s)\n",
-			       eport, iport, iaddr, r, strupnperror(r));
-			return -2;
-	}
-	}
-
-	r = UPNP_GetSpecificPortMappingEntry(urls->controlURL,
-					     data->first.servicetype,
-					     eport, proto, NULL/*remoteHost*/,
-					     intClient, intPort, NULL/*desc*/,
-					     NULL/*enabled*/, duration);
-	if(r!=UPNPCOMMAND_SUCCESS) {
-		printf("GetSpecificPortMappingEntry() failed with code %d (%s)\n",
-		       r, strupnperror(r));
-		return -2;
-	} else {
-		printf("InternalIP:Port = %s:%s\n", intClient, intPort);
-		printf("external %s:%s %s is redirected to internal %s:%s (duration=%s)\n",
-		       externalIPAddress, eport, proto, intClient, intPort, duration);
-	}
-	return 0;
-}
-
-static int
-RemoveRedirect(struct UPNPUrls * urls,
-               struct IGDdatas * data,
-               const char * eport,
-               const char * proto,
-               const char * remoteHost)
-{
-	int r;
-	if(!proto || !eport)
-	{
-		fprintf(stderr, "invalid arguments\n");
-		return -1;
-	}
-	proto = protofix(proto);
-	if(!proto)
-	{
-		fprintf(stderr, "protocol invalid\n");
-		return -1;
-	}
-	r = UPNP_DeletePortMapping(urls->controlURL, data->first.servicetype, eport, proto, remoteHost);
-	if(r!=UPNPCOMMAND_SUCCESS) {
-		printf("UPNP_DeletePortMapping() failed with code : %d\n", r);
-		return -2;
-	}else {
-		printf("UPNP_DeletePortMapping() returned : %d\n", r);
-	}
-	return 0;
-}
-
-static int
-RemoveRedirectRange(struct UPNPUrls * urls,
-		    struct IGDdatas * data,
-		    const char * ePortStart, char const * ePortEnd,
-		    const char * proto, const char * manage)
-{
-	int r;
-
-	if (!manage)
-		manage = "0";
-
-	if(!proto || !ePortStart || !ePortEnd)
-	{
-		fprintf(stderr, "invalid arguments\n");
-		return -1;
-	}
-	proto = protofix(proto);
-	if(!proto)
-	{
-		fprintf(stderr, "protocol invalid\n");
-		return -1;
-	}
-	r = UPNP_DeletePortMappingRange(urls->controlURL, data->first.servicetype, ePortStart, ePortEnd, proto, manage);
-	if(r!=UPNPCOMMAND_SUCCESS) {
-		printf("UPNP_DeletePortMappingRange() failed with code : %d\n", r);
-		return -2;
-	}else {
-		printf("UPNP_DeletePortMappingRange() returned : %d\n", r);
-	}
-	return 0;
-}
-
-/* IGD:2, functions for service WANIPv6FirewallControl:1 */
-static void GetFirewallStatus(struct UPNPUrls * urls, struct IGDdatas * data)
-{
-	unsigned int bytessent, bytesreceived, packetsreceived, packetssent;
-	int firewallEnabled = 0, inboundPinholeAllowed = 0;
-
-	UPNP_GetFirewallStatus(urls->controlURL_6FC, data->IPv6FC.servicetype, &firewallEnabled, &inboundPinholeAllowed);
-	printf("FirewallEnabled: %d & Inbound Pinhole Allowed: %d\n", firewallEnabled, inboundPinholeAllowed);
-	printf("GetFirewallStatus:\n   Firewall Enabled: %s\n   Inbound Pinhole Allowed: %s\n", (firewallEnabled)? "Yes":"No", (inboundPinholeAllowed)? "Yes":"No");
-
-	bytessent = UPNP_GetTotalBytesSent(urls->controlURL_CIF, data->CIF.servicetype);
-	bytesreceived = UPNP_GetTotalBytesReceived(urls->controlURL_CIF, data->CIF.servicetype);
-	packetssent = UPNP_GetTotalPacketsSent(urls->controlURL_CIF, data->CIF.servicetype);
-	packetsreceived = UPNP_GetTotalPacketsReceived(urls->controlURL_CIF, data->CIF.servicetype);
-	printf("Bytes:   Sent: %8u\tRecv: %8u\n", bytessent, bytesreceived);
-	printf("Packets: Sent: %8u\tRecv: %8u\n", packetssent, packetsreceived);
-}
-
-/* Test function
- * 1 - Add pinhole
- * 2 - Check if pinhole is working from the IGD side */
-static void SetPinholeAndTest(struct UPNPUrls * urls, struct IGDdatas * data,
-					const char * remoteaddr, const char * eport,
-					const char * intaddr, const char * iport,
-					const char * proto, const char * lease_time)
-{
-	char uniqueID[8];
-	/*int isWorking = 0;*/
-	int r;
-	char proto_tmp[8];
-
-	if(!intaddr || !remoteaddr || !iport || !eport || !proto || !lease_time)
-	{
-		fprintf(stderr, "Wrong arguments\n");
-		return;
-	}
-	if(atoi(proto) == 0)
-	{
-		const char * protocol;
-		protocol = protofix(proto);
-		if(protocol && (strcmp("TCP", protocol) == 0))
-		{
-			snprintf(proto_tmp, sizeof(proto_tmp), "%d", IPPROTO_TCP);
-			proto = proto_tmp;
-		}
-		else if(protocol && (strcmp("UDP", protocol) == 0))
-		{
-			snprintf(proto_tmp, sizeof(proto_tmp), "%d", IPPROTO_UDP);
-			proto = proto_tmp;
-		}
-		else
-		{
-			fprintf(stderr, "invalid protocol\n");
-			return;
-		}
-	}
-	r = UPNP_AddPinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, remoteaddr, eport, intaddr, iport, proto, lease_time, uniqueID);
-	if(r!=UPNPCOMMAND_SUCCESS)
-		printf("AddPinhole([%s]:%s -> [%s]:%s) failed with code %d (%s)\n",
-		       remoteaddr, eport, intaddr, iport, r, strupnperror(r));
-	else
-	{
-		printf("AddPinhole: ([%s]:%s -> [%s]:%s) / Pinhole ID = %s\n",
-		       remoteaddr, eport, intaddr, iport, uniqueID);
-		/*r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->servicetype_6FC, uniqueID, &isWorking);
-		if(r!=UPNPCOMMAND_SUCCESS)
-			printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r));
-		printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No");*/
-	}
-}
-
-/* Test function
- * 1 - Check if pinhole is working from the IGD side
- * 2 - Update pinhole */
-static void GetPinholeAndUpdate(struct UPNPUrls * urls, struct IGDdatas * data,
-					const char * uniqueID, const char * lease_time)
-{
-	int isWorking = 0;
-	int r;
-
-	if(!uniqueID || !lease_time)
-	{
-		fprintf(stderr, "Wrong arguments\n");
-		return;
-	}
-	r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &isWorking);
-	printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No");
-	if(r!=UPNPCOMMAND_SUCCESS)
-		printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r));
-	if(isWorking || r==709)
-	{
-		r = UPNP_UpdatePinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, lease_time);
-		printf("UpdatePinhole: Pinhole ID = %s with Lease Time: %s\n", uniqueID, lease_time);
-		if(r!=UPNPCOMMAND_SUCCESS)
-			printf("UpdatePinhole: ID (%s) failed with code %d (%s)\n", uniqueID, r, strupnperror(r));
-	}
-}
-
-/* Test function
- * Get pinhole timeout
- */
-static void GetPinholeOutboundTimeout(struct UPNPUrls * urls, struct IGDdatas * data,
-					const char * remoteaddr, const char * eport,
-					const char * intaddr, const char * iport,
-					const char * proto)
-{
-	int timeout = 0;
-	int r;
-
-	if(!intaddr || !remoteaddr || !iport || !eport || !proto)
-	{
-		fprintf(stderr, "Wrong arguments\n");
-		return;
-	}
-
-	r = UPNP_GetOutboundPinholeTimeout(urls->controlURL_6FC, data->IPv6FC.servicetype, remoteaddr, eport, intaddr, iport, proto, &timeout);
-	if(r!=UPNPCOMMAND_SUCCESS)
-		printf("GetOutboundPinholeTimeout([%s]:%s -> [%s]:%s) failed with code %d (%s)\n",
-		       intaddr, iport, remoteaddr, eport, r, strupnperror(r));
-	else
-		printf("GetOutboundPinholeTimeout: ([%s]:%s -> [%s]:%s) / Timeout = %d\n", intaddr, iport, remoteaddr, eport, timeout);
-}
-
-static void
-GetPinholePackets(struct UPNPUrls * urls,
-               struct IGDdatas * data, const char * uniqueID)
-{
-	int r, pinholePackets = 0;
-	if(!uniqueID)
-	{
-		fprintf(stderr, "invalid arguments\n");
-		return;
-	}
-	r = UPNP_GetPinholePackets(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &pinholePackets);
-	if(r!=UPNPCOMMAND_SUCCESS)
-		printf("GetPinholePackets() failed with code %d (%s)\n", r, strupnperror(r));
-	else
-		printf("GetPinholePackets: Pinhole ID = %s / PinholePackets = %d\n", uniqueID, pinholePackets);
-}
-
-static void
-CheckPinhole(struct UPNPUrls * urls,
-               struct IGDdatas * data, const char * uniqueID)
-{
-	int r, isWorking = 0;
-	if(!uniqueID)
-	{
-		fprintf(stderr, "invalid arguments\n");
-		return;
-	}
-	r = UPNP_CheckPinholeWorking(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID, &isWorking);
-	if(r!=UPNPCOMMAND_SUCCESS)
-		printf("CheckPinholeWorking() failed with code %d (%s)\n", r, strupnperror(r));
-	else
-		printf("CheckPinholeWorking: Pinhole ID = %s / IsWorking = %s\n", uniqueID, (isWorking)? "Yes":"No");
-}
-
-static void
-RemovePinhole(struct UPNPUrls * urls,
-               struct IGDdatas * data, const char * uniqueID)
-{
-	int r;
-	if(!uniqueID)
-	{
-		fprintf(stderr, "invalid arguments\n");
-		return;
-	}
-	r = UPNP_DeletePinhole(urls->controlURL_6FC, data->IPv6FC.servicetype, uniqueID);
-	printf("UPNP_DeletePinhole() returned : %d\n", r);
-}
-
-
-/* sample upnp client program */
-int main(int argc, char ** argv)
-{
-	char command = 0;
-	char ** commandargv = 0;
-	int commandargc = 0;
-	struct UPNPDev * devlist = 0;
-	char lanaddr[64] = "unset";	/* my ip address on the LAN */
-	int i;
-	const char * rootdescurl = 0;
-	const char * multicastif = 0;
-	const char * minissdpdpath = 0;
-	int localport = UPNP_LOCAL_PORT_ANY;
-	int retcode = 0;
-	int error = 0;
-	int ipv6 = 0;
-	unsigned char ttl = 2;	/* defaulting to 2 */
-	const char * description = 0;
-
-#ifdef _WIN32
-	WSADATA wsaData;
-	int nResult = WSAStartup(MAKEWORD(2,2), &wsaData);
-	if(nResult != NO_ERROR)
-	{
-		fprintf(stderr, "WSAStartup() failed.\n");
-		return -1;
-	}
-#endif
-    printf("upnpc : miniupnpc library test client, version %s.\n", MINIUPNPC_VERSION_STRING);
-	printf(" (c) 2005-2017 Thomas Bernard.\n");
-    printf("Go to http://miniupnp.free.fr/ or https://miniupnp.tuxfamily.org/\n"
-	       "for more information.\n");
-	/* command line processing */
-	for(i=1; i<argc; i++)
-	{
-		if(0 == strcmp(argv[i], "--help") || 0 == strcmp(argv[i], "-h"))
-		{
-			command = 0;
-			break;
-		}
-		if(argv[i][0] == '-')
-		{
-			if(argv[i][1] == 'u')
-				rootdescurl = argv[++i];
-			else if(argv[i][1] == 'm')
-				multicastif = argv[++i];
-			else if(argv[i][1] == 'z')
-			{
-				char junk;
-				if(sscanf(argv[++i], "%d%c", &localport, &junk)!=1 ||
-					localport<0 || localport>65535 ||
-				   (localport >1 && localport < 1024))
-				{
-					fprintf(stderr, "Invalid localport '%s'\n", argv[i]);
-					localport = UPNP_LOCAL_PORT_ANY;
-					break;
-				}
-			}
-			else if(argv[i][1] == 'p')
-				minissdpdpath = argv[++i];
-			else if(argv[i][1] == '6')
-				ipv6 = 1;
-			else if(argv[i][1] == 'e')
-				description = argv[++i];
-			else if(argv[i][1] == 't')
-				ttl = (unsigned char)atoi(argv[++i]);
-			else
-			{
-				command = argv[i][1];
-				i++;
-				commandargv = argv + i;
-				commandargc = argc - i;
-				break;
-			}
-		}
-		else
-		{
-			fprintf(stderr, "option '%s' invalid\n", argv[i]);
-		}
-	}
-
-	if(!command
-	   || (command == 'a' && commandargc<4)
-	   || (command == 'd' && argc<2)
-	   || (command == 'r' && argc<2)
-	   || (command == 'A' && commandargc<6)
-	   || (command == 'U' && commandargc<2)
-	   || (command == 'D' && commandargc<1))
-	{
-		fprintf(stderr, "Usage :\t%s [options] -a ip port external_port protocol [duration]\n\t\tAdd port redirection\n", argv[0]);
-		fprintf(stderr, "       \t%s [options] -d external_port protocol <remote host>\n\t\tDelete port redirection\n", argv[0]);
-		fprintf(stderr, "       \t%s [options] -s\n\t\tGet Connection status\n", argv[0]);
-		fprintf(stderr, "       \t%s [options] -l\n\t\tList redirections\n", argv[0]);
-		fprintf(stderr, "       \t%s [options] -L\n\t\tList redirections (using GetListOfPortMappings (for IGD:2 only)\n", argv[0]);
-		fprintf(stderr, "       \t%s [options] -n ip port external_port protocol [duration]\n\t\tAdd (any) port redirection allowing IGD to use alternative external_port (for IGD:2 only)\n", argv[0]);
-		fprintf(stderr, "       \t%s [options] -N external_port_start external_port_end protocol [manage]\n\t\tDelete range of port redirections (for IGD:2 only)\n", argv[0]);
-		fprintf(stderr, "       \t%s [options] -r port1 [external_port1] protocol1 [port2 [external_port2] protocol2] [...]\n\t\tAdd all redirections to the current host\n", argv[0]);
-		fprintf(stderr, "       \t%s [options] -A remote_ip remote_port internal_ip internal_port protocol lease_time\n\t\tAdd Pinhole (for IGD:2 only)\n", argv[0]);
-		fprintf(stderr, "       \t%s [options] -U uniqueID new_lease_time\n\t\tUpdate Pinhole (for IGD:2 only)\n", argv[0]);
-		fprintf(stderr, "       \t%s [options] -C uniqueID\n\t\tCheck if Pinhole is Working (for IGD:2 only)\n", argv[0]);
-		fprintf(stderr, "       \t%s [options] -K uniqueID\n\t\tGet Number of packets going through the rule (for IGD:2 only)\n", argv[0]);
-		fprintf(stderr, "       \t%s [options] -D uniqueID\n\t\tDelete Pinhole (for IGD:2 only)\n", argv[0]);
-		fprintf(stderr, "       \t%s [options] -S\n\t\tGet Firewall status (for IGD:2 only)\n", argv[0]);
-		fprintf(stderr, "       \t%s [options] -G remote_ip remote_port internal_ip internal_port protocol\n\t\tGet Outbound Pinhole Timeout (for IGD:2 only)\n", argv[0]);
-		fprintf(stderr, "       \t%s [options] -P\n\t\tGet Presentation url\n", argv[0]);
-		fprintf(stderr, "\nprotocol is UDP or TCP\n");
-		fprintf(stderr, "Options:\n");
-		fprintf(stderr, "  -e description : set description for port mapping.\n");
-		fprintf(stderr, "  -6 : use ip v6 instead of ip v4.\n");
-		fprintf(stderr, "  -u url : bypass discovery process by providing the XML root description url.\n");
-		fprintf(stderr, "  -m address/interface : provide ip address (ip v4) or interface name (ip v4 or v6) to use for sending SSDP multicast packets.\n");
-		fprintf(stderr, "  -z localport : SSDP packets local (source) port (1024-65535).\n");
-		fprintf(stderr, "  -p path : use this path for MiniSSDPd socket.\n");
-		fprintf(stderr, "  -t ttl : set multicast TTL. Default value is 2.\n");
-		return 1;
-	}
-
-	if( rootdescurl
-	  || (devlist = upnpDiscover(2000, multicastif, minissdpdpath,
-	                             localport, ipv6, ttl, &error)))
-	{
-		struct UPNPDev * device;
-		struct UPNPUrls urls;
-		struct IGDdatas data;
-		if(devlist)
-		{
-			printf("List of UPNP devices found on the network :\n");
-			for(device = devlist; device; device = device->pNext)
-			{
-				printf(" desc: %s\n st: %s\n\n",
-					   device->descURL, device->st);
-			}
-		}
-		else if(!rootdescurl)
-		{
-			printf("upnpDiscover() error code=%d\n", error);
-		}
-		i = 1;
-		if( (rootdescurl && UPNP_GetIGDFromUrl(rootdescurl, &urls, &data, lanaddr, sizeof(lanaddr)))
-		  || (i = UPNP_GetValidIGD(devlist, &urls, &data, lanaddr, sizeof(lanaddr))))
-		{
-			switch(i) {
-			case 1:
-				printf("Found valid IGD : %s\n", urls.controlURL);
-				break;
-			case 2:
-				printf("Found a (not connected?) IGD : %s\n", urls.controlURL);
-				printf("Trying to continue anyway\n");
-				break;
-			case 3:
-				printf("UPnP device found. Is it an IGD ? : %s\n", urls.controlURL);
-				printf("Trying to continue anyway\n");
-				break;
-			default:
-				printf("Found device (igd ?) : %s\n", urls.controlURL);
-				printf("Trying to continue anyway\n");
-			}
-			printf("Local LAN ip address : %s\n", lanaddr);
-			#if 0
-			printf("getting \"%s\"\n", urls.ipcondescURL);
-			descXML = miniwget(urls.ipcondescURL, &descXMLsize);
-			if(descXML)
-			{
-				/*fwrite(descXML, 1, descXMLsize, stdout);*/
-				free(descXML); descXML = NULL;
-			}
-			#endif
-
-			switch(command)
-			{
-			case 'l':
-				DisplayInfos(&urls, &data);
-				ListRedirections(&urls, &data);
-				break;
-			case 'L':
-				NewListRedirections(&urls, &data);
-				break;
-			case 'a':
-				if (SetRedirectAndTest(&urls, &data,
-						   commandargv[0], commandargv[1],
-						   commandargv[2], commandargv[3],
-						   (commandargc > 4)?commandargv[4]:"0",
-						   description, 0) < 0)
-					retcode = 2;
-				break;
-			case 'd':
-				if (RemoveRedirect(&urls, &data, commandargv[0], commandargv[1],
-				               commandargc > 2 ? commandargv[2] : NULL) < 0)
-					retcode = 2;
-				break;
-			case 'n':	/* aNy */
-				if (SetRedirectAndTest(&urls, &data,
-						   commandargv[0], commandargv[1],
-						   commandargv[2], commandargv[3],
-						   (commandargc > 4)?commandargv[4]:"0",
-						   description, 1) < 0)
-					retcode = 2;
-				break;
-			case 'N':
-				if (commandargc < 3)
-					fprintf(stderr, "too few arguments\n");
-
-				if (RemoveRedirectRange(&urls, &data, commandargv[0], commandargv[1], commandargv[2],
-						    commandargc > 3 ? commandargv[3] : NULL) < 0)
-					retcode = 2;
-				break;
-			case 's':
-				GetConnectionStatus(&urls, &data);
-				break;
-			case 'r':
-				i = 0;
-				while(i<commandargc)
-				{
-					if(!is_int(commandargv[i])) {
-						/* 1st parameter not an integer : error */
-						fprintf(stderr, "command -r : %s is not an port number\n", commandargv[i]);
-						retcode = 1;
-						break;
-					} else if(is_int(commandargv[i+1])){
-						/* 2nd parameter is an integer : <port> <external_port> <protocol> */
-						if (SetRedirectAndTest(&urls, &data,
-								   lanaddr, commandargv[i],
-								   commandargv[i+1], commandargv[i+2], "0",
-								   description, 0) < 0)
-							retcode = 2;
-						i+=3;	/* 3 parameters parsed */
-					} else {
-						/* 2nd parameter not an integer : <port> <protocol> */
-						if (SetRedirectAndTest(&urls, &data,
-								   lanaddr, commandargv[i],
-								   commandargv[i], commandargv[i+1], "0",
-								   description, 0) < 0)
-							retcode = 2;
-						i+=2;	/* 2 parameters parsed */
-					}
-				}
-				break;
-			case 'A':
-				SetPinholeAndTest(&urls, &data,
-				                  commandargv[0], commandargv[1],
-				                  commandargv[2], commandargv[3],
-				                  commandargv[4], commandargv[5]);
-				break;
-			case 'U':
-				GetPinholeAndUpdate(&urls, &data,
-				                   commandargv[0], commandargv[1]);
-				break;
-			case 'C':
-				for(i=0; i<commandargc; i++)
-				{
-					CheckPinhole(&urls, &data, commandargv[i]);
-				}
-				break;
-			case 'K':
-				for(i=0; i<commandargc; i++)
-				{
-					GetPinholePackets(&urls, &data, commandargv[i]);
-				}
-				break;
-			case 'D':
-				for(i=0; i<commandargc; i++)
-				{
-					RemovePinhole(&urls, &data, commandargv[i]);
-				}
-				break;
-			case 'S':
-				GetFirewallStatus(&urls, &data);
-				break;
-			case 'G':
-				GetPinholeOutboundTimeout(&urls, &data,
-							commandargv[0], commandargv[1],
-							commandargv[2], commandargv[3],
-							commandargv[4]);
-				break;
-			case 'P':
-				printf("Presentation URL found:\n");
-				printf("            %s\n", data.presentationurl);
-				break;
-			default:
-				fprintf(stderr, "Unknown switch -%c\n", command);
-				retcode = 1;
-			}
-
-			FreeUPNPUrls(&urls);
-		}
-		else
-		{
-			fprintf(stderr, "No valid UPNP Internet Gateway Device found.\n");
-			retcode = 1;
-		}
-		freeUPNPDevlist(devlist); devlist = 0;
-	}
-	else
-	{
-		fprintf(stderr, "No IGD UPnP Device found on the network !\n");
-		retcode = 1;
-	}
-#ifdef _WIN32
-	nResult = WSACleanup();
-	if(nResult != NO_ERROR) {
-		fprintf(stderr, "WSACleanup() failed.\n");
-	}
-#endif /* _WIN32 */
-	return retcode;
-}
-

+ 0 - 1240
ext/miniupnpc/upnpcommands.c

@@ -1,1240 +0,0 @@
-/* $Id: upnpcommands.c,v 1.48 2017/04/21 10:22:40 nanard Exp $ */
-/* vim: tabstop=4 shiftwidth=4 noexpandtab
- * Project : miniupnp
- * Author : Thomas Bernard
- * Copyright (c) 2005-2017 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided in this distribution.
- * */
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include "upnpcommands.h"
-#include "miniupnpc.h"
-#include "portlistingparse.h"
-
-static UNSIGNED_INTEGER
-my_atoui(const char * s)
-{
-	return s ? ((UNSIGNED_INTEGER)STRTOUI(s, NULL, 0)) : 0;
-}
-
-/*
- * */
-MINIUPNP_LIBSPEC UNSIGNED_INTEGER
-UPNP_GetTotalBytesSent(const char * controlURL,
-					const char * servicetype)
-{
-	struct NameValueParserData pdata;
-	char * buffer;
-	int bufsize;
-	unsigned int r = 0;
-	char * p;
-	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                                "GetTotalBytesSent", 0, &bufsize))) {
-		return UPNPCOMMAND_HTTP_ERROR;
-	}
-	ParseNameValue(buffer, bufsize, &pdata);
-	/*DisplayNameValueList(buffer, bufsize);*/
-	free(buffer); buffer = NULL;
-	p = GetValueFromNameValueList(&pdata, "NewTotalBytesSent");
-	r = my_atoui(p);
-	ClearNameValueList(&pdata);
-	return r;
-}
-
-/*
- * */
-MINIUPNP_LIBSPEC UNSIGNED_INTEGER
-UPNP_GetTotalBytesReceived(const char * controlURL,
-						const char * servicetype)
-{
-	struct NameValueParserData pdata;
-	char * buffer;
-	int bufsize;
-	unsigned int r = 0;
-	char * p;
-	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                                "GetTotalBytesReceived", 0, &bufsize))) {
-		return UPNPCOMMAND_HTTP_ERROR;
-	}
-	ParseNameValue(buffer, bufsize, &pdata);
-	/*DisplayNameValueList(buffer, bufsize);*/
-	free(buffer); buffer = NULL;
-	p = GetValueFromNameValueList(&pdata, "NewTotalBytesReceived");
-	r = my_atoui(p);
-	ClearNameValueList(&pdata);
-	return r;
-}
-
-/*
- * */
-MINIUPNP_LIBSPEC UNSIGNED_INTEGER
-UPNP_GetTotalPacketsSent(const char * controlURL,
-						const char * servicetype)
-{
-	struct NameValueParserData pdata;
-	char * buffer;
-	int bufsize;
-	unsigned int r = 0;
-	char * p;
-	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                                "GetTotalPacketsSent", 0, &bufsize))) {
-		return UPNPCOMMAND_HTTP_ERROR;
-	}
-	ParseNameValue(buffer, bufsize, &pdata);
-	/*DisplayNameValueList(buffer, bufsize);*/
-	free(buffer); buffer = NULL;
-	p = GetValueFromNameValueList(&pdata, "NewTotalPacketsSent");
-	r = my_atoui(p);
-	ClearNameValueList(&pdata);
-	return r;
-}
-
-/*
- * */
-MINIUPNP_LIBSPEC UNSIGNED_INTEGER
-UPNP_GetTotalPacketsReceived(const char * controlURL,
-						const char * servicetype)
-{
-	struct NameValueParserData pdata;
-	char * buffer;
-	int bufsize;
-	unsigned int r = 0;
-	char * p;
-	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                                "GetTotalPacketsReceived", 0, &bufsize))) {
-		return UPNPCOMMAND_HTTP_ERROR;
-	}
-	ParseNameValue(buffer, bufsize, &pdata);
-	/*DisplayNameValueList(buffer, bufsize);*/
-	free(buffer); buffer = NULL;
-	p = GetValueFromNameValueList(&pdata, "NewTotalPacketsReceived");
-	r = my_atoui(p);
-	ClearNameValueList(&pdata);
-	return r;
-}
-
-/* UPNP_GetStatusInfo() call the corresponding UPNP method
- * returns the current status and uptime */
-MINIUPNP_LIBSPEC int
-UPNP_GetStatusInfo(const char * controlURL,
-				const char * servicetype,
-				char * status,
-				unsigned int * uptime,
-				char * lastconnerror)
-{
-	struct NameValueParserData pdata;
-	char * buffer;
-	int bufsize;
-	char * p;
-	char * up;
-	char * err;
-	int ret = UPNPCOMMAND_UNKNOWN_ERROR;
-
-	if(!status && !uptime)
-		return UPNPCOMMAND_INVALID_ARGS;
-
-	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                                "GetStatusInfo", 0, &bufsize))) {
-		return UPNPCOMMAND_HTTP_ERROR;
-	}
-	ParseNameValue(buffer, bufsize, &pdata);
-	/*DisplayNameValueList(buffer, bufsize);*/
-	free(buffer); buffer = NULL;
-	up = GetValueFromNameValueList(&pdata, "NewUptime");
-	p = GetValueFromNameValueList(&pdata, "NewConnectionStatus");
-	err = GetValueFromNameValueList(&pdata, "NewLastConnectionError");
-	if(p && up)
-	  ret = UPNPCOMMAND_SUCCESS;
-
-	if(status) {
-		if(p){
-			strncpy(status, p, 64 );
-			status[63] = '\0';
-		}else
-			status[0]= '\0';
-	}
-
-	if(uptime) {
-		if(up)
-			sscanf(up,"%u",uptime);
-		else
-			*uptime = 0;
-	}
-
-	if(lastconnerror) {
-		if(err) {
-			strncpy(lastconnerror, err, 64 );
-			lastconnerror[63] = '\0';
-		} else
-			lastconnerror[0] = '\0';
-	}
-
-	p = GetValueFromNameValueList(&pdata, "errorCode");
-	if(p) {
-		ret = UPNPCOMMAND_UNKNOWN_ERROR;
-		sscanf(p, "%d", &ret);
-	}
-	ClearNameValueList(&pdata);
-	return ret;
-}
-
-/* UPNP_GetConnectionTypeInfo() call the corresponding UPNP method
- * returns the connection type */
-MINIUPNP_LIBSPEC int
-UPNP_GetConnectionTypeInfo(const char * controlURL,
-                           const char * servicetype,
-                           char * connectionType)
-{
-	struct NameValueParserData pdata;
-	char * buffer;
-	int bufsize;
-	char * p;
-	int ret = UPNPCOMMAND_UNKNOWN_ERROR;
-
-	if(!connectionType)
-		return UPNPCOMMAND_INVALID_ARGS;
-
-	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                                "GetConnectionTypeInfo", 0, &bufsize))) {
-		return UPNPCOMMAND_HTTP_ERROR;
-	}
-	ParseNameValue(buffer, bufsize, &pdata);
-	free(buffer); buffer = NULL;
-	p = GetValueFromNameValueList(&pdata, "NewConnectionType");
-	/*p = GetValueFromNameValueList(&pdata, "NewPossibleConnectionTypes");*/
-	/* PossibleConnectionTypes will have several values.... */
-	if(p) {
-		strncpy(connectionType, p, 64 );
-		connectionType[63] = '\0';
-		ret = UPNPCOMMAND_SUCCESS;
-	} else
-		connectionType[0] = '\0';
-	p = GetValueFromNameValueList(&pdata, "errorCode");
-	if(p) {
-		ret = UPNPCOMMAND_UNKNOWN_ERROR;
-		sscanf(p, "%d", &ret);
-	}
-	ClearNameValueList(&pdata);
-	return ret;
-}
-
-/* UPNP_GetLinkLayerMaxBitRate() call the corresponding UPNP method.
- * Returns 2 values: Downloadlink bandwidth and Uplink bandwidth.
- * One of the values can be null
- * Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only
- * We can use the GetCommonLinkProperties from WANCommonInterfaceConfig:1 */
-MINIUPNP_LIBSPEC int
-UPNP_GetLinkLayerMaxBitRates(const char * controlURL,
-                             const char * servicetype,
-                             unsigned int * bitrateDown,
-                             unsigned int * bitrateUp)
-{
-	struct NameValueParserData pdata;
-	char * buffer;
-	int bufsize;
-	int ret = UPNPCOMMAND_UNKNOWN_ERROR;
-	char * down;
-	char * up;
-	char * p;
-
-	if(!bitrateDown && !bitrateUp)
-		return UPNPCOMMAND_INVALID_ARGS;
-
-	/* shouldn't we use GetCommonLinkProperties ? */
-	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                                "GetCommonLinkProperties", 0, &bufsize))) {
-	                              /*"GetLinkLayerMaxBitRates", 0, &bufsize);*/
-		return UPNPCOMMAND_HTTP_ERROR;
-	}
-	/*DisplayNameValueList(buffer, bufsize);*/
-	ParseNameValue(buffer, bufsize, &pdata);
-	free(buffer); buffer = NULL;
-	/*down = GetValueFromNameValueList(&pdata, "NewDownstreamMaxBitRate");*/
-	/*up = GetValueFromNameValueList(&pdata, "NewUpstreamMaxBitRate");*/
-	down = GetValueFromNameValueList(&pdata, "NewLayer1DownstreamMaxBitRate");
-	up = GetValueFromNameValueList(&pdata, "NewLayer1UpstreamMaxBitRate");
-	/*GetValueFromNameValueList(&pdata, "NewWANAccessType");*/
-	/*GetValueFromNameValueList(&pdata, "NewPhysicalLinkStatus");*/
-	if(down && up)
-		ret = UPNPCOMMAND_SUCCESS;
-
-	if(bitrateDown) {
-		if(down)
-			sscanf(down,"%u",bitrateDown);
-		else
-			*bitrateDown = 0;
-	}
-
-	if(bitrateUp) {
-		if(up)
-			sscanf(up,"%u",bitrateUp);
-		else
-			*bitrateUp = 0;
-	}
-	p = GetValueFromNameValueList(&pdata, "errorCode");
-	if(p) {
-		ret = UPNPCOMMAND_UNKNOWN_ERROR;
-		sscanf(p, "%d", &ret);
-	}
-	ClearNameValueList(&pdata);
-	return ret;
-}
-
-
-/* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
- * if the third arg is not null the value is copied to it.
- * at least 16 bytes must be available
- *
- * Return values :
- * 0 : SUCCESS
- * NON ZERO : ERROR Either an UPnP error code or an unknown error.
- *
- * 402 Invalid Args - See UPnP Device Architecture section on Control.
- * 501 Action Failed - See UPnP Device Architecture section on Control.
- */
-MINIUPNP_LIBSPEC int
-UPNP_GetExternalIPAddress(const char * controlURL,
-                          const char * servicetype,
-                          char * extIpAdd)
-{
-	struct NameValueParserData pdata;
-	char * buffer;
-	int bufsize;
-	char * p;
-	int ret = UPNPCOMMAND_UNKNOWN_ERROR;
-
-	if(!extIpAdd || !controlURL || !servicetype)
-		return UPNPCOMMAND_INVALID_ARGS;
-
-	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                                "GetExternalIPAddress", 0, &bufsize))) {
-		return UPNPCOMMAND_HTTP_ERROR;
-	}
-	/*DisplayNameValueList(buffer, bufsize);*/
-	ParseNameValue(buffer, bufsize, &pdata);
-	free(buffer); buffer = NULL;
-	/*printf("external ip = %s\n", GetValueFromNameValueList(&pdata, "NewExternalIPAddress") );*/
-	p = GetValueFromNameValueList(&pdata, "NewExternalIPAddress");
-	if(p) {
-		strncpy(extIpAdd, p, 16 );
-		extIpAdd[15] = '\0';
-		ret = UPNPCOMMAND_SUCCESS;
-	} else
-		extIpAdd[0] = '\0';
-
-	p = GetValueFromNameValueList(&pdata, "errorCode");
-	if(p) {
-		ret = UPNPCOMMAND_UNKNOWN_ERROR;
-		sscanf(p, "%d", &ret);
-	}
-
-	ClearNameValueList(&pdata);
-	return ret;
-}
-
-MINIUPNP_LIBSPEC int
-UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
-		    const char * extPort,
-		    const char * inPort,
-		    const char * inClient,
-		    const char * desc,
-		    const char * proto,
-		    const char * remoteHost,
-		    const char * leaseDuration)
-{
-	struct UPNParg * AddPortMappingArgs;
-	char * buffer;
-	int bufsize;
-	struct NameValueParserData pdata;
-	const char * resVal;
-	int ret;
-
-	if(!inPort || !inClient || !proto || !extPort)
-		return UPNPCOMMAND_INVALID_ARGS;
-
-	AddPortMappingArgs = calloc(9, sizeof(struct UPNParg));
-	if(AddPortMappingArgs == NULL)
-		return UPNPCOMMAND_MEM_ALLOC_ERROR;
-	AddPortMappingArgs[0].elt = "NewRemoteHost";
-	AddPortMappingArgs[0].val = remoteHost;
-	AddPortMappingArgs[1].elt = "NewExternalPort";
-	AddPortMappingArgs[1].val = extPort;
-	AddPortMappingArgs[2].elt = "NewProtocol";
-	AddPortMappingArgs[2].val = proto;
-	AddPortMappingArgs[3].elt = "NewInternalPort";
-	AddPortMappingArgs[3].val = inPort;
-	AddPortMappingArgs[4].elt = "NewInternalClient";
-	AddPortMappingArgs[4].val = inClient;
-	AddPortMappingArgs[5].elt = "NewEnabled";
-	AddPortMappingArgs[5].val = "1";
-	AddPortMappingArgs[6].elt = "NewPortMappingDescription";
-	AddPortMappingArgs[6].val = desc?desc:"libminiupnpc";
-	AddPortMappingArgs[7].elt = "NewLeaseDuration";
-	AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0";
-	buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                           "AddPortMapping", AddPortMappingArgs,
-	                           &bufsize);
-	free(AddPortMappingArgs);
-	if(!buffer) {
-		return UPNPCOMMAND_HTTP_ERROR;
-	}
-	/*DisplayNameValueList(buffer, bufsize);*/
-	/*buffer[bufsize] = '\0';*/
-	/*puts(buffer);*/
-	ParseNameValue(buffer, bufsize, &pdata);
-	free(buffer); buffer = NULL;
-	resVal = GetValueFromNameValueList(&pdata, "errorCode");
-	if(resVal) {
-		/*printf("AddPortMapping errorCode = '%s'\n", resVal); */
-		ret = UPNPCOMMAND_UNKNOWN_ERROR;
-		sscanf(resVal, "%d", &ret);
-	} else {
-		ret = UPNPCOMMAND_SUCCESS;
-	}
-	ClearNameValueList(&pdata);
-	return ret;
-}
-
-MINIUPNP_LIBSPEC int
-UPNP_AddAnyPortMapping(const char * controlURL, const char * servicetype,
-		       const char * extPort,
-		       const char * inPort,
-		       const char * inClient,
-		       const char * desc,
-		       const char * proto,
-		       const char * remoteHost,
-		       const char * leaseDuration,
-		       char * reservedPort)
-{
-	struct UPNParg * AddPortMappingArgs;
-	char * buffer;
-	int bufsize;
-	struct NameValueParserData pdata;
-	const char * resVal;
-	int ret;
-
-	if(!inPort || !inClient || !proto || !extPort)
-		return UPNPCOMMAND_INVALID_ARGS;
-
-	AddPortMappingArgs = calloc(9, sizeof(struct UPNParg));
-	if(AddPortMappingArgs == NULL)
-		return UPNPCOMMAND_MEM_ALLOC_ERROR;
-	AddPortMappingArgs[0].elt = "NewRemoteHost";
-	AddPortMappingArgs[0].val = remoteHost;
-	AddPortMappingArgs[1].elt = "NewExternalPort";
-	AddPortMappingArgs[1].val = extPort;
-	AddPortMappingArgs[2].elt = "NewProtocol";
-	AddPortMappingArgs[2].val = proto;
-	AddPortMappingArgs[3].elt = "NewInternalPort";
-	AddPortMappingArgs[3].val = inPort;
-	AddPortMappingArgs[4].elt = "NewInternalClient";
-	AddPortMappingArgs[4].val = inClient;
-	AddPortMappingArgs[5].elt = "NewEnabled";
-	AddPortMappingArgs[5].val = "1";
-	AddPortMappingArgs[6].elt = "NewPortMappingDescription";
-	AddPortMappingArgs[6].val = desc?desc:"libminiupnpc";
-	AddPortMappingArgs[7].elt = "NewLeaseDuration";
-	AddPortMappingArgs[7].val = leaseDuration?leaseDuration:"0";
-	buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                           "AddAnyPortMapping", AddPortMappingArgs,
-	                           &bufsize);
-	free(AddPortMappingArgs);
-	if(!buffer) {
-		return UPNPCOMMAND_HTTP_ERROR;
-	}
-	ParseNameValue(buffer, bufsize, &pdata);
-	free(buffer); buffer = NULL;
-	resVal = GetValueFromNameValueList(&pdata, "errorCode");
-	if(resVal) {
-		ret = UPNPCOMMAND_UNKNOWN_ERROR;
-		sscanf(resVal, "%d", &ret);
-	} else {
-		char *p;
-
-		p = GetValueFromNameValueList(&pdata, "NewReservedPort");
-		if(p) {
-			strncpy(reservedPort, p, 6);
-			reservedPort[5] = '\0';
-			ret = UPNPCOMMAND_SUCCESS;
-		} else {
-			ret = UPNPCOMMAND_INVALID_RESPONSE;
-		}
-	}
-	ClearNameValueList(&pdata);
-	return ret;
-}
-
-MINIUPNP_LIBSPEC int
-UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
-                       const char * extPort, const char * proto,
-                       const char * remoteHost)
-{
-	/*struct NameValueParserData pdata;*/
-	struct UPNParg * DeletePortMappingArgs;
-	char * buffer;
-	int bufsize;
-	struct NameValueParserData pdata;
-	const char * resVal;
-	int ret;
-
-	if(!extPort || !proto)
-		return UPNPCOMMAND_INVALID_ARGS;
-
-	DeletePortMappingArgs = calloc(4, sizeof(struct UPNParg));
-	if(DeletePortMappingArgs == NULL)
-		return UPNPCOMMAND_MEM_ALLOC_ERROR;
-	DeletePortMappingArgs[0].elt = "NewRemoteHost";
-	DeletePortMappingArgs[0].val = remoteHost;
-	DeletePortMappingArgs[1].elt = "NewExternalPort";
-	DeletePortMappingArgs[1].val = extPort;
-	DeletePortMappingArgs[2].elt = "NewProtocol";
-	DeletePortMappingArgs[2].val = proto;
-	buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                          "DeletePortMapping",
-	                          DeletePortMappingArgs, &bufsize);
-	free(DeletePortMappingArgs);
-	if(!buffer) {
-		return UPNPCOMMAND_HTTP_ERROR;
-	}
-	/*DisplayNameValueList(buffer, bufsize);*/
-	ParseNameValue(buffer, bufsize, &pdata);
-	free(buffer); buffer = NULL;
-	resVal = GetValueFromNameValueList(&pdata, "errorCode");
-	if(resVal) {
-		ret = UPNPCOMMAND_UNKNOWN_ERROR;
-		sscanf(resVal, "%d", &ret);
-	} else {
-		ret = UPNPCOMMAND_SUCCESS;
-	}
-	ClearNameValueList(&pdata);
-	return ret;
-}
-
-MINIUPNP_LIBSPEC int
-UPNP_DeletePortMappingRange(const char * controlURL, const char * servicetype,
-        		    const char * extPortStart, const char * extPortEnd,
-        		    const char * proto,
-			    const char * manage)
-{
-	struct UPNParg * DeletePortMappingArgs;
-	char * buffer;
-	int bufsize;
-	struct NameValueParserData pdata;
-	const char * resVal;
-	int ret;
-
-	if(!extPortStart || !extPortEnd || !proto || !manage)
-		return UPNPCOMMAND_INVALID_ARGS;
-
-	DeletePortMappingArgs = calloc(5, sizeof(struct UPNParg));
-	if(DeletePortMappingArgs == NULL)
-		return UPNPCOMMAND_MEM_ALLOC_ERROR;
-	DeletePortMappingArgs[0].elt = "NewStartPort";
-	DeletePortMappingArgs[0].val = extPortStart;
-	DeletePortMappingArgs[1].elt = "NewEndPort";
-	DeletePortMappingArgs[1].val = extPortEnd;
-	DeletePortMappingArgs[2].elt = "NewProtocol";
-	DeletePortMappingArgs[2].val = proto;
-	DeletePortMappingArgs[3].elt = "NewManage";
-	DeletePortMappingArgs[3].val = manage;
-
-	buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                           "DeletePortMappingRange",
-	                           DeletePortMappingArgs, &bufsize);
-	free(DeletePortMappingArgs);
-	if(!buffer) {
-		return UPNPCOMMAND_HTTP_ERROR;
-	}
-	ParseNameValue(buffer, bufsize, &pdata);
-	free(buffer); buffer = NULL;
-	resVal = GetValueFromNameValueList(&pdata, "errorCode");
-	if(resVal) {
-		ret = UPNPCOMMAND_UNKNOWN_ERROR;
-		sscanf(resVal, "%d", &ret);
-	} else {
-		ret = UPNPCOMMAND_SUCCESS;
-	}
-	ClearNameValueList(&pdata);
-	return ret;
-}
-
-MINIUPNP_LIBSPEC int
-UPNP_GetGenericPortMappingEntry(const char * controlURL,
-                                const char * servicetype,
-							 const char * index,
-							 char * extPort,
-							 char * intClient,
-							 char * intPort,
-							 char * protocol,
-							 char * desc,
-							 char * enabled,
-							 char * rHost,
-							 char * duration)
-{
-	struct NameValueParserData pdata;
-	struct UPNParg * GetPortMappingArgs;
-	char * buffer;
-	int bufsize;
-	char * p;
-	int r = UPNPCOMMAND_UNKNOWN_ERROR;
-	if(!index)
-		return UPNPCOMMAND_INVALID_ARGS;
-	intClient[0] = '\0';
-	intPort[0] = '\0';
-	GetPortMappingArgs = calloc(2, sizeof(struct UPNParg));
-	if(GetPortMappingArgs == NULL)
-		return UPNPCOMMAND_MEM_ALLOC_ERROR;
-	GetPortMappingArgs[0].elt = "NewPortMappingIndex";
-	GetPortMappingArgs[0].val = index;
-	buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                           "GetGenericPortMappingEntry",
-	                           GetPortMappingArgs, &bufsize);
-	free(GetPortMappingArgs);
-	if(!buffer) {
-		return UPNPCOMMAND_HTTP_ERROR;
-	}
-	ParseNameValue(buffer, bufsize, &pdata);
-	free(buffer); buffer = NULL;
-
-	p = GetValueFromNameValueList(&pdata, "NewRemoteHost");
-	if(p && rHost)
-	{
-		strncpy(rHost, p, 64);
-		rHost[63] = '\0';
-	}
-	p = GetValueFromNameValueList(&pdata, "NewExternalPort");
-	if(p && extPort)
-	{
-		strncpy(extPort, p, 6);
-		extPort[5] = '\0';
-		r = UPNPCOMMAND_SUCCESS;
-	}
-	p = GetValueFromNameValueList(&pdata, "NewProtocol");
-	if(p && protocol)
-	{
-		strncpy(protocol, p, 4);
-		protocol[3] = '\0';
-	}
-	p = GetValueFromNameValueList(&pdata, "NewInternalClient");
-	if(p)
-	{
-		strncpy(intClient, p, 16);
-		intClient[15] = '\0';
-		r = 0;
-	}
-	p = GetValueFromNameValueList(&pdata, "NewInternalPort");
-	if(p)
-	{
-		strncpy(intPort, p, 6);
-		intPort[5] = '\0';
-	}
-	p = GetValueFromNameValueList(&pdata, "NewEnabled");
-	if(p && enabled)
-	{
-		strncpy(enabled, p, 4);
-		enabled[3] = '\0';
-	}
-	p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
-	if(p && desc)
-	{
-		strncpy(desc, p, 80);
-		desc[79] = '\0';
-	}
-	p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
-	if(p && duration)
-	{
-		strncpy(duration, p, 16);
-		duration[15] = '\0';
-	}
-	p = GetValueFromNameValueList(&pdata, "errorCode");
-	if(p) {
-		r = UPNPCOMMAND_UNKNOWN_ERROR;
-		sscanf(p, "%d", &r);
-	}
-	ClearNameValueList(&pdata);
-	return r;
-}
-
-MINIUPNP_LIBSPEC int
-UPNP_GetPortMappingNumberOfEntries(const char * controlURL,
-                                   const char * servicetype,
-                                   unsigned int * numEntries)
-{
- 	struct NameValueParserData pdata;
- 	char * buffer;
- 	int bufsize;
- 	char* p;
-	int ret = UPNPCOMMAND_UNKNOWN_ERROR;
- 	if(!(buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                                "GetPortMappingNumberOfEntries", 0,
-	                                &bufsize))) {
-		return UPNPCOMMAND_HTTP_ERROR;
-	}
-#ifdef DEBUG
-	DisplayNameValueList(buffer, bufsize);
-#endif
- 	ParseNameValue(buffer, bufsize, &pdata);
-	free(buffer); buffer = NULL;
-
- 	p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries");
- 	if(numEntries && p) {
-		*numEntries = 0;
- 		sscanf(p, "%u", numEntries);
-		ret = UPNPCOMMAND_SUCCESS;
- 	}
-
-	p = GetValueFromNameValueList(&pdata, "errorCode");
-	if(p) {
-		ret = UPNPCOMMAND_UNKNOWN_ERROR;
-		sscanf(p, "%d", &ret);
-	}
-
- 	ClearNameValueList(&pdata);
-	return ret;
-}
-
-/* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping
- * the result is returned in the intClient and intPort strings
- * please provide 16 and 6 bytes of data */
-MINIUPNP_LIBSPEC int
-UPNP_GetSpecificPortMappingEntry(const char * controlURL,
-                                 const char * servicetype,
-                                 const char * extPort,
-                                 const char * proto,
-                                 const char * remoteHost,
-                                 char * intClient,
-                                 char * intPort,
-                                 char * desc,
-                                 char * enabled,
-                                 char * leaseDuration)
-{
-	struct NameValueParserData pdata;
-	struct UPNParg * GetPortMappingArgs;
-	char * buffer;
-	int bufsize;
-	char * p;
-	int ret = UPNPCOMMAND_UNKNOWN_ERROR;
-
-	if(!intPort || !intClient || !extPort || !proto)
-		return UPNPCOMMAND_INVALID_ARGS;
-
-	GetPortMappingArgs = calloc(4, sizeof(struct UPNParg));
-	if(GetPortMappingArgs == NULL)
-		return UPNPCOMMAND_MEM_ALLOC_ERROR;
-	GetPortMappingArgs[0].elt = "NewRemoteHost";
-	GetPortMappingArgs[0].val = remoteHost;
-	GetPortMappingArgs[1].elt = "NewExternalPort";
-	GetPortMappingArgs[1].val = extPort;
-	GetPortMappingArgs[2].elt = "NewProtocol";
-	GetPortMappingArgs[2].val = proto;
-	buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                           "GetSpecificPortMappingEntry",
-	                           GetPortMappingArgs, &bufsize);
-	free(GetPortMappingArgs);
-	if(!buffer) {
-		return UPNPCOMMAND_HTTP_ERROR;
-	}
-	/*DisplayNameValueList(buffer, bufsize);*/
-	ParseNameValue(buffer, bufsize, &pdata);
-	free(buffer); buffer = NULL;
-
-	p = GetValueFromNameValueList(&pdata, "NewInternalClient");
-	if(p) {
-		strncpy(intClient, p, 16);
-		intClient[15] = '\0';
-		ret = UPNPCOMMAND_SUCCESS;
-	} else
-		intClient[0] = '\0';
-
-	p = GetValueFromNameValueList(&pdata, "NewInternalPort");
-	if(p) {
-		strncpy(intPort, p, 6);
-		intPort[5] = '\0';
-	} else
-		intPort[0] = '\0';
-
-	p = GetValueFromNameValueList(&pdata, "NewEnabled");
-	if(p && enabled) {
-		strncpy(enabled, p, 4);
-		enabled[3] = '\0';
-	}
-
-	p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
-	if(p && desc) {
-		strncpy(desc, p, 80);
-		desc[79] = '\0';
-	}
-
-	p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
-	if(p && leaseDuration)
-	{
-		strncpy(leaseDuration, p, 16);
-		leaseDuration[15] = '\0';
-	}
-
-	p = GetValueFromNameValueList(&pdata, "errorCode");
-	if(p) {
-		ret = UPNPCOMMAND_UNKNOWN_ERROR;
-		sscanf(p, "%d", &ret);
-	}
-
-	ClearNameValueList(&pdata);
-	return ret;
-}
-
-/* UPNP_GetListOfPortMappings()
- *
- * Possible UPNP Error codes :
- * 606 Action not Authorized
- * 730 PortMappingNotFound - no port mapping is found in the specified range.
- * 733 InconsistantParameters - NewStartPort and NewEndPort values are not
- *                              consistent.
- */
-MINIUPNP_LIBSPEC int
-UPNP_GetListOfPortMappings(const char * controlURL,
-                           const char * servicetype,
-                           const char * startPort,
-                           const char * endPort,
-                           const char * protocol,
-                           const char * numberOfPorts,
-                           struct PortMappingParserData * data)
-{
-	struct NameValueParserData pdata;
-	struct UPNParg * GetListOfPortMappingsArgs;
-	const char * p;
-	char * buffer;
-	int bufsize;
-	int ret = UPNPCOMMAND_UNKNOWN_ERROR;
-
-	if(!startPort || !endPort || !protocol)
-		return UPNPCOMMAND_INVALID_ARGS;
-
-	GetListOfPortMappingsArgs = calloc(6, sizeof(struct UPNParg));
-	if(GetListOfPortMappingsArgs == NULL)
-		return UPNPCOMMAND_MEM_ALLOC_ERROR;
-	GetListOfPortMappingsArgs[0].elt = "NewStartPort";
-	GetListOfPortMappingsArgs[0].val = startPort;
-	GetListOfPortMappingsArgs[1].elt = "NewEndPort";
-	GetListOfPortMappingsArgs[1].val = endPort;
-	GetListOfPortMappingsArgs[2].elt = "NewProtocol";
-	GetListOfPortMappingsArgs[2].val = protocol;
-	GetListOfPortMappingsArgs[3].elt = "NewManage";
-	GetListOfPortMappingsArgs[3].val = "1";
-	GetListOfPortMappingsArgs[4].elt = "NewNumberOfPorts";
-	GetListOfPortMappingsArgs[4].val = numberOfPorts?numberOfPorts:"1000";
-
-	buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                           "GetListOfPortMappings",
-	                           GetListOfPortMappingsArgs, &bufsize);
-	free(GetListOfPortMappingsArgs);
-	if(!buffer) {
-		return UPNPCOMMAND_HTTP_ERROR;
-	}
-
-	/*DisplayNameValueList(buffer, bufsize);*/
-	ParseNameValue(buffer, bufsize, &pdata);
-	free(buffer); buffer = NULL;
-
-	/*p = GetValueFromNameValueList(&pdata, "NewPortListing");*/
-	/*if(p) {
-		printf("NewPortListing : %s\n", p);
-	}*/
-	/*printf("NewPortListing(%d chars) : %s\n",
-	       pdata.portListingLength, pdata.portListing);*/
-	if(pdata.portListing)
-	{
-		/*struct PortMapping * pm;
-		int i = 0;*/
-		ParsePortListing(pdata.portListing, pdata.portListingLength,
-		                 data);
-		ret = UPNPCOMMAND_SUCCESS;
-		/*
-		for(pm = data->head.lh_first; pm != NULL; pm = pm->entries.le_next)
-		{
-			printf("%2d %s %5hu->%s:%-5hu '%s' '%s'\n",
-			       i, pm->protocol, pm->externalPort, pm->internalClient,
-			       pm->internalPort,
-			       pm->description, pm->remoteHost);
-			i++;
-		}
-		*/
-		/*FreePortListing(&data);*/
-	}
-
-	p = GetValueFromNameValueList(&pdata, "errorCode");
-	if(p) {
-		ret = UPNPCOMMAND_UNKNOWN_ERROR;
-		sscanf(p, "%d", &ret);
-	}
-	ClearNameValueList(&pdata);
-
-	/*printf("%.*s", bufsize, buffer);*/
-
-	return ret;
-}
-
-/* IGD:2, functions for service WANIPv6FirewallControl:1 */
-MINIUPNP_LIBSPEC int
-UPNP_GetFirewallStatus(const char * controlURL,
-				const char * servicetype,
-				int * firewallEnabled,
-				int * inboundPinholeAllowed)
-{
-	struct NameValueParserData pdata;
-	char * buffer;
-	int bufsize;
-	char * fe, *ipa, *p;
-	int ret = UPNPCOMMAND_UNKNOWN_ERROR;
-
-	if(!firewallEnabled || !inboundPinholeAllowed)
-		return UPNPCOMMAND_INVALID_ARGS;
-
-	buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                           "GetFirewallStatus", 0, &bufsize);
-	if(!buffer) {
-		return UPNPCOMMAND_HTTP_ERROR;
-	}
-	ParseNameValue(buffer, bufsize, &pdata);
-	free(buffer); buffer = NULL;
-	fe = GetValueFromNameValueList(&pdata, "FirewallEnabled");
-	ipa = GetValueFromNameValueList(&pdata, "InboundPinholeAllowed");
-	if(ipa && fe)
-		ret = UPNPCOMMAND_SUCCESS;
-	if(fe)
-		*firewallEnabled = my_atoui(fe);
-	/*else
-		*firewallEnabled = 0;*/
-	if(ipa)
-		*inboundPinholeAllowed = my_atoui(ipa);
-	/*else
-		*inboundPinholeAllowed = 0;*/
-	p = GetValueFromNameValueList(&pdata, "errorCode");
-	if(p)
-	{
-		ret = UPNPCOMMAND_UNKNOWN_ERROR;
-		sscanf(p, "%d", &ret);
-	}
-	ClearNameValueList(&pdata);
-	return ret;
-}
-
-MINIUPNP_LIBSPEC int
-UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype,
-                    const char * remoteHost,
-                    const char * remotePort,
-                    const char * intClient,
-                    const char * intPort,
-                    const char * proto,
-                    int * opTimeout)
-{
-	struct UPNParg * GetOutboundPinholeTimeoutArgs;
-	char * buffer;
-	int bufsize;
-	struct NameValueParserData pdata;
-	const char * resVal;
-	char * p;
-	int ret;
-
-	if(!intPort || !intClient || !proto || !remotePort || !remoteHost)
-		return UPNPCOMMAND_INVALID_ARGS;
-
-	GetOutboundPinholeTimeoutArgs = calloc(6, sizeof(struct UPNParg));
-	if(GetOutboundPinholeTimeoutArgs == NULL)
-		return UPNPCOMMAND_MEM_ALLOC_ERROR;
-	GetOutboundPinholeTimeoutArgs[0].elt = "RemoteHost";
-	GetOutboundPinholeTimeoutArgs[0].val = remoteHost;
-	GetOutboundPinholeTimeoutArgs[1].elt = "RemotePort";
-	GetOutboundPinholeTimeoutArgs[1].val = remotePort;
-	GetOutboundPinholeTimeoutArgs[2].elt = "Protocol";
-	GetOutboundPinholeTimeoutArgs[2].val = proto;
-	GetOutboundPinholeTimeoutArgs[3].elt = "InternalPort";
-	GetOutboundPinholeTimeoutArgs[3].val = intPort;
-	GetOutboundPinholeTimeoutArgs[4].elt = "InternalClient";
-	GetOutboundPinholeTimeoutArgs[4].val = intClient;
-	buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                           "GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs, &bufsize);
-	free(GetOutboundPinholeTimeoutArgs);
-	if(!buffer)
-		return UPNPCOMMAND_HTTP_ERROR;
-	ParseNameValue(buffer, bufsize, &pdata);
-	free(buffer); buffer = NULL;
-	resVal = GetValueFromNameValueList(&pdata, "errorCode");
-	if(resVal)
-	{
-		ret = UPNPCOMMAND_UNKNOWN_ERROR;
-		sscanf(resVal, "%d", &ret);
-	}
-	else
-	{
-		ret = UPNPCOMMAND_SUCCESS;
-		p = GetValueFromNameValueList(&pdata, "OutboundPinholeTimeout");
-		if(p)
-			*opTimeout = my_atoui(p);
-	}
-	ClearNameValueList(&pdata);
-	return ret;
-}
-
-MINIUPNP_LIBSPEC int
-UPNP_AddPinhole(const char * controlURL, const char * servicetype,
-                    const char * remoteHost,
-                    const char * remotePort,
-                    const char * intClient,
-                    const char * intPort,
-                    const char * proto,
-                    const char * leaseTime,
-                    char * uniqueID)
-{
-	struct UPNParg * AddPinholeArgs;
-	char * buffer;
-	int bufsize;
-	struct NameValueParserData pdata;
-	const char * resVal;
-	char * p;
-	int ret;
-
-	if(!intPort || !intClient || !proto || !remoteHost || !remotePort || !leaseTime)
-		return UPNPCOMMAND_INVALID_ARGS;
-
-	AddPinholeArgs = calloc(7, sizeof(struct UPNParg));
-	if(AddPinholeArgs == NULL)
-		return UPNPCOMMAND_MEM_ALLOC_ERROR;
-	/* RemoteHost can be wilcarded */
-	if(strncmp(remoteHost, "empty", 5)==0)
-	{
-		AddPinholeArgs[0].elt = "RemoteHost";
-		AddPinholeArgs[0].val = "";
-	}
-	else
-	{
-		AddPinholeArgs[0].elt = "RemoteHost";
-		AddPinholeArgs[0].val = remoteHost;
-	}
-	AddPinholeArgs[1].elt = "RemotePort";
-	AddPinholeArgs[1].val = remotePort;
-	AddPinholeArgs[2].elt = "Protocol";
-	AddPinholeArgs[2].val = proto;
-	AddPinholeArgs[3].elt = "InternalPort";
-	AddPinholeArgs[3].val = intPort;
-	if(strncmp(intClient, "empty", 5)==0)
-	{
-		AddPinholeArgs[4].elt = "InternalClient";
-		AddPinholeArgs[4].val = "";
-	}
-	else
-	{
-		AddPinholeArgs[4].elt = "InternalClient";
-		AddPinholeArgs[4].val = intClient;
-	}
-	AddPinholeArgs[5].elt = "LeaseTime";
-	AddPinholeArgs[5].val = leaseTime;
-	buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                           "AddPinhole", AddPinholeArgs, &bufsize);
-	free(AddPinholeArgs);
-	if(!buffer)
-		return UPNPCOMMAND_HTTP_ERROR;
-	ParseNameValue(buffer, bufsize, &pdata);
-	free(buffer); buffer = NULL;
-	p = GetValueFromNameValueList(&pdata, "UniqueID");
-	if(p)
-	{
-		strncpy(uniqueID, p, 8);
-		uniqueID[7] = '\0';
-	}
-	resVal = GetValueFromNameValueList(&pdata, "errorCode");
-	if(resVal)
-	{
-		/*printf("AddPortMapping errorCode = '%s'\n", resVal);*/
-		ret = UPNPCOMMAND_UNKNOWN_ERROR;
-		sscanf(resVal, "%d", &ret);
-	}
-	else
-	{
-		ret = UPNPCOMMAND_SUCCESS;
-	}
-	ClearNameValueList(&pdata);
-	return ret;
-}
-
-MINIUPNP_LIBSPEC int
-UPNP_UpdatePinhole(const char * controlURL, const char * servicetype,
-                    const char * uniqueID,
-                    const char * leaseTime)
-{
-	struct UPNParg * UpdatePinholeArgs;
-	char * buffer;
-	int bufsize;
-	struct NameValueParserData pdata;
-	const char * resVal;
-	int ret;
-
-	if(!uniqueID || !leaseTime)
-		return UPNPCOMMAND_INVALID_ARGS;
-
-	UpdatePinholeArgs = calloc(3, sizeof(struct UPNParg));
-	if(UpdatePinholeArgs == NULL)
-		return UPNPCOMMAND_MEM_ALLOC_ERROR;
-	UpdatePinholeArgs[0].elt = "UniqueID";
-	UpdatePinholeArgs[0].val = uniqueID;
-	UpdatePinholeArgs[1].elt = "NewLeaseTime";
-	UpdatePinholeArgs[1].val = leaseTime;
-	buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                           "UpdatePinhole", UpdatePinholeArgs, &bufsize);
-	free(UpdatePinholeArgs);
-	if(!buffer)
-		return UPNPCOMMAND_HTTP_ERROR;
-	ParseNameValue(buffer, bufsize, &pdata);
-	free(buffer); buffer = NULL;
-	resVal = GetValueFromNameValueList(&pdata, "errorCode");
-	if(resVal)
-	{
-		/*printf("AddPortMapping errorCode = '%s'\n", resVal); */
-		ret = UPNPCOMMAND_UNKNOWN_ERROR;
-		sscanf(resVal, "%d", &ret);
-	}
-	else
-	{
-		ret = UPNPCOMMAND_SUCCESS;
-	}
-	ClearNameValueList(&pdata);
-	return ret;
-}
-
-MINIUPNP_LIBSPEC int
-UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID)
-{
-	/*struct NameValueParserData pdata;*/
-	struct UPNParg * DeletePinholeArgs;
-	char * buffer;
-	int bufsize;
-	struct NameValueParserData pdata;
-	const char * resVal;
-	int ret;
-
-	if(!uniqueID)
-		return UPNPCOMMAND_INVALID_ARGS;
-
-	DeletePinholeArgs = calloc(2, sizeof(struct UPNParg));
-	if(DeletePinholeArgs == NULL)
-		return UPNPCOMMAND_MEM_ALLOC_ERROR;
-	DeletePinholeArgs[0].elt = "UniqueID";
-	DeletePinholeArgs[0].val = uniqueID;
-	buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                           "DeletePinhole", DeletePinholeArgs, &bufsize);
-	free(DeletePinholeArgs);
-	if(!buffer)
-		return UPNPCOMMAND_HTTP_ERROR;
-	/*DisplayNameValueList(buffer, bufsize);*/
-	ParseNameValue(buffer, bufsize, &pdata);
-	free(buffer); buffer = NULL;
-	resVal = GetValueFromNameValueList(&pdata, "errorCode");
-	if(resVal)
-	{
-		ret = UPNPCOMMAND_UNKNOWN_ERROR;
-		sscanf(resVal, "%d", &ret);
-	}
-	else
-	{
-		ret = UPNPCOMMAND_SUCCESS;
-	}
-	ClearNameValueList(&pdata);
-	return ret;
-}
-
-MINIUPNP_LIBSPEC int
-UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype,
-                                 const char * uniqueID, int * isWorking)
-{
-	struct NameValueParserData pdata;
-	struct UPNParg * CheckPinholeWorkingArgs;
-	char * buffer;
-	int bufsize;
-	char * p;
-	int ret = UPNPCOMMAND_UNKNOWN_ERROR;
-
-	if(!uniqueID)
-		return UPNPCOMMAND_INVALID_ARGS;
-
-	CheckPinholeWorkingArgs = calloc(4, sizeof(struct UPNParg));
-	if(CheckPinholeWorkingArgs == NULL)
-		return UPNPCOMMAND_MEM_ALLOC_ERROR;
-	CheckPinholeWorkingArgs[0].elt = "UniqueID";
-	CheckPinholeWorkingArgs[0].val = uniqueID;
-	buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                           "CheckPinholeWorking", CheckPinholeWorkingArgs, &bufsize);
-	free(CheckPinholeWorkingArgs);
-	if(!buffer)
-	{
-		return UPNPCOMMAND_HTTP_ERROR;
-	}
-	ParseNameValue(buffer, bufsize, &pdata);
-	free(buffer); buffer = NULL;
-
-	p = GetValueFromNameValueList(&pdata, "IsWorking");
-	if(p)
-	{
-		*isWorking=my_atoui(p);
-		ret = UPNPCOMMAND_SUCCESS;
-	}
-	else
-		*isWorking = 0;
-
-	p = GetValueFromNameValueList(&pdata, "errorCode");
-	if(p)
-	{
-		ret = UPNPCOMMAND_UNKNOWN_ERROR;
-		sscanf(p, "%d", &ret);
-	}
-
-	ClearNameValueList(&pdata);
-	return ret;
-}
-
-MINIUPNP_LIBSPEC int
-UPNP_GetPinholePackets(const char * controlURL, const char * servicetype,
-                                 const char * uniqueID, int * packets)
-{
-	struct NameValueParserData pdata;
-	struct UPNParg * GetPinholePacketsArgs;
-	char * buffer;
-	int bufsize;
-	char * p;
-	int ret = UPNPCOMMAND_UNKNOWN_ERROR;
-
-	if(!uniqueID)
-		return UPNPCOMMAND_INVALID_ARGS;
-
-	GetPinholePacketsArgs = calloc(4, sizeof(struct UPNParg));
-	if(GetPinholePacketsArgs == NULL)
-		return UPNPCOMMAND_MEM_ALLOC_ERROR;
-	GetPinholePacketsArgs[0].elt = "UniqueID";
-	GetPinholePacketsArgs[0].val = uniqueID;
-	buffer = simpleUPnPcommand(-1, controlURL, servicetype,
-	                           "GetPinholePackets", GetPinholePacketsArgs, &bufsize);
-	free(GetPinholePacketsArgs);
-	if(!buffer)
-		return UPNPCOMMAND_HTTP_ERROR;
-	ParseNameValue(buffer, bufsize, &pdata);
-	free(buffer); buffer = NULL;
-
-	p = GetValueFromNameValueList(&pdata, "PinholePackets");
-	if(p)
-	{
-		*packets=my_atoui(p);
-		ret = UPNPCOMMAND_SUCCESS;
-	}
-
-	p = GetValueFromNameValueList(&pdata, "errorCode");
-	if(p)
-	{
-		ret = UPNPCOMMAND_UNKNOWN_ERROR;
-		sscanf(p, "%d", &ret);
-	}
-
-	ClearNameValueList(&pdata);
-	return ret;
-}
-
-

+ 0 - 348
ext/miniupnpc/upnpcommands.h

@@ -1,348 +0,0 @@
-/* $Id: upnpcommands.h,v 1.31 2015/07/21 13:16:55 nanard Exp $ */
-/* Miniupnp project : http://miniupnp.free.fr/
- * Author : Thomas Bernard
- * Copyright (c) 2005-2015 Thomas Bernard
- * This software is subject to the conditions detailed in the
- * LICENCE file provided within this distribution */
-#ifndef UPNPCOMMANDS_H_INCLUDED
-#define UPNPCOMMANDS_H_INCLUDED
-
-#include "upnpreplyparse.h"
-#include "portlistingparse.h"
-#include "miniupnpc_declspec.h"
-#include "miniupnpctypes.h"
-
-/* MiniUPnPc return codes : */
-#define UPNPCOMMAND_SUCCESS (0)
-#define UPNPCOMMAND_UNKNOWN_ERROR (-1)
-#define UPNPCOMMAND_INVALID_ARGS (-2)
-#define UPNPCOMMAND_HTTP_ERROR (-3)
-#define UPNPCOMMAND_INVALID_RESPONSE (-4)
-#define UPNPCOMMAND_MEM_ALLOC_ERROR (-5)
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-MINIUPNP_LIBSPEC UNSIGNED_INTEGER
-UPNP_GetTotalBytesSent(const char * controlURL,
-					const char * servicetype);
-
-MINIUPNP_LIBSPEC UNSIGNED_INTEGER
-UPNP_GetTotalBytesReceived(const char * controlURL,
-						const char * servicetype);
-
-MINIUPNP_LIBSPEC UNSIGNED_INTEGER
-UPNP_GetTotalPacketsSent(const char * controlURL,
-					const char * servicetype);
-
-MINIUPNP_LIBSPEC UNSIGNED_INTEGER
-UPNP_GetTotalPacketsReceived(const char * controlURL,
-					const char * servicetype);
-
-/* UPNP_GetStatusInfo()
- * status and lastconnerror are 64 byte buffers
- * Return values :
- * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
- * or a UPnP Error code */
-MINIUPNP_LIBSPEC int
-UPNP_GetStatusInfo(const char * controlURL,
-			       const char * servicetype,
-				   char * status,
-				   unsigned int * uptime,
-                   char * lastconnerror);
-
-/* UPNP_GetConnectionTypeInfo()
- * argument connectionType is a 64 character buffer
- * Return Values :
- * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
- * or a UPnP Error code */
-MINIUPNP_LIBSPEC int
-UPNP_GetConnectionTypeInfo(const char * controlURL,
-                           const char * servicetype,
-						   char * connectionType);
-
-/* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
- * if the third arg is not null the value is copied to it.
- * at least 16 bytes must be available
- *
- * Return values :
- * 0 : SUCCESS
- * NON ZERO : ERROR Either an UPnP error code or an unknown error.
- *
- * possible UPnP Errors :
- * 402 Invalid Args - See UPnP Device Architecture section on Control.
- * 501 Action Failed - See UPnP Device Architecture section on Control. */
-MINIUPNP_LIBSPEC int
-UPNP_GetExternalIPAddress(const char * controlURL,
-                          const char * servicetype,
-                          char * extIpAdd);
-
-/* UPNP_GetLinkLayerMaxBitRates()
- * call WANCommonInterfaceConfig:1#GetCommonLinkProperties
- *
- * return values :
- * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
- * or a UPnP Error Code. */
-MINIUPNP_LIBSPEC int
-UPNP_GetLinkLayerMaxBitRates(const char* controlURL,
-							const char* servicetype,
-							unsigned int * bitrateDown,
-							unsigned int * bitrateUp);
-
-/* UPNP_AddPortMapping()
- * if desc is NULL, it will be defaulted to "libminiupnpc"
- * remoteHost is usually NULL because IGD don't support it.
- *
- * Return values :
- * 0 : SUCCESS
- * NON ZERO : ERROR. Either an UPnP error code or an unknown error.
- *
- * List of possible UPnP errors for AddPortMapping :
- * errorCode errorDescription (short) - Description (long)
- * 402 Invalid Args - See UPnP Device Architecture section on Control.
- * 501 Action Failed - See UPnP Device Architecture section on Control.
- * 606 Action not authorized - The action requested REQUIRES authorization and
- *                             the sender was not authorized.
- * 715 WildCardNotPermittedInSrcIP - The source IP address cannot be
- *                                   wild-carded
- * 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded
- * 718 ConflictInMappingEntry - The port mapping entry specified conflicts
- *                     with a mapping assigned previously to another client
- * 724 SamePortValuesRequired - Internal and External port values
- *                              must be the same
- * 725 OnlyPermanentLeasesSupported - The NAT implementation only supports
- *                  permanent lease times on port mappings
- * 726 RemoteHostOnlySupportsWildcard - RemoteHost must be a wildcard
- *                             and cannot be a specific IP address or DNS name
- * 727 ExternalPortOnlySupportsWildcard - ExternalPort must be a wildcard and
- *                                        cannot be a specific port value
- * 728 NoPortMapsAvailable - There are not enough free ports available to
- *                           complete port mapping.
- * 729 ConflictWithOtherMechanisms - Attempted port mapping is not allowed
- *                                   due to conflict with other mechanisms.
- * 732 WildCardNotPermittedInIntPort - The internal port cannot be wild-carded
- */
-MINIUPNP_LIBSPEC int
-UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
-		    const char * extPort,
-		    const char * inPort,
-		    const char * inClient,
-		    const char * desc,
-		    const char * proto,
-		    const char * remoteHost,
-		    const char * leaseDuration);
-
-/* UPNP_AddAnyPortMapping()
- * if desc is NULL, it will be defaulted to "libminiupnpc"
- * remoteHost is usually NULL because IGD don't support it.
- *
- * Return values :
- * 0 : SUCCESS
- * NON ZERO : ERROR. Either an UPnP error code or an unknown error.
- *
- * List of possible UPnP errors for AddPortMapping :
- * errorCode errorDescription (short) - Description (long)
- * 402 Invalid Args - See UPnP Device Architecture section on Control.
- * 501 Action Failed - See UPnP Device Architecture section on Control.
- * 606 Action not authorized - The action requested REQUIRES authorization and
- *                             the sender was not authorized.
- * 715 WildCardNotPermittedInSrcIP - The source IP address cannot be
- *                                   wild-carded
- * 716 WildCardNotPermittedInExtPort - The external port cannot be wild-carded
- * 728 NoPortMapsAvailable - There are not enough free ports available to
- *                           complete port mapping.
- * 729 ConflictWithOtherMechanisms - Attempted port mapping is not allowed
- *                                   due to conflict with other mechanisms.
- * 732 WildCardNotPermittedInIntPort - The internal port cannot be wild-carded
- */
-MINIUPNP_LIBSPEC int
-UPNP_AddAnyPortMapping(const char * controlURL, const char * servicetype,
-		       const char * extPort,
-		       const char * inPort,
-		       const char * inClient,
-		       const char * desc,
-		       const char * proto,
-		       const char * remoteHost,
-		       const char * leaseDuration,
-		       char * reservedPort);
-
-/* UPNP_DeletePortMapping()
- * Use same argument values as what was used for AddPortMapping().
- * remoteHost is usually NULL because IGD don't support it.
- * Return Values :
- * 0 : SUCCESS
- * NON ZERO : error. Either an UPnP error code or an undefined error.
- *
- * List of possible UPnP errors for DeletePortMapping :
- * 402 Invalid Args - See UPnP Device Architecture section on Control.
- * 606 Action not authorized - The action requested REQUIRES authorization
- *                             and the sender was not authorized.
- * 714 NoSuchEntryInArray - The specified value does not exist in the array */
-MINIUPNP_LIBSPEC int
-UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
-		       const char * extPort, const char * proto,
-		       const char * remoteHost);
-
-/* UPNP_DeletePortRangeMapping()
- * Use same argument values as what was used for AddPortMapping().
- * remoteHost is usually NULL because IGD don't support it.
- * Return Values :
- * 0 : SUCCESS
- * NON ZERO : error. Either an UPnP error code or an undefined error.
- *
- * List of possible UPnP errors for DeletePortMapping :
- * 606 Action not authorized - The action requested REQUIRES authorization
- *                             and the sender was not authorized.
- * 730 PortMappingNotFound - This error message is returned if no port
- *			     mapping is found in the specified range.
- * 733 InconsistentParameters - NewStartPort and NewEndPort values are not consistent. */
-MINIUPNP_LIBSPEC int
-UPNP_DeletePortMappingRange(const char * controlURL, const char * servicetype,
-        		    const char * extPortStart, const char * extPortEnd,
-        		    const char * proto,
-        		    const char * manage);
-
-/* UPNP_GetPortMappingNumberOfEntries()
- * not supported by all routers */
-MINIUPNP_LIBSPEC int
-UPNP_GetPortMappingNumberOfEntries(const char* controlURL,
-                                   const char* servicetype,
-                                   unsigned int * num);
-
-/* UPNP_GetSpecificPortMappingEntry()
- *    retrieves an existing port mapping
- * params :
- *  in   extPort
- *  in   proto
- *  in   remoteHost
- *  out  intClient (16 bytes)
- *  out  intPort (6 bytes)
- *  out  desc (80 bytes)
- *  out  enabled (4 bytes)
- *  out  leaseDuration (16 bytes)
- *
- * return value :
- * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
- * or a UPnP Error Code.
- *
- * List of possible UPnP errors for _GetSpecificPortMappingEntry :
- * 402 Invalid Args - See UPnP Device Architecture section on Control.
- * 501 Action Failed - See UPnP Device Architecture section on Control.
- * 606 Action not authorized - The action requested REQUIRES authorization
- *                             and the sender was not authorized.
- * 714 NoSuchEntryInArray - The specified value does not exist in the array.
- */
-MINIUPNP_LIBSPEC int
-UPNP_GetSpecificPortMappingEntry(const char * controlURL,
-                                 const char * servicetype,
-                                 const char * extPort,
-                                 const char * proto,
-                                 const char * remoteHost,
-                                 char * intClient,
-                                 char * intPort,
-                                 char * desc,
-                                 char * enabled,
-                                 char * leaseDuration);
-
-/* UPNP_GetGenericPortMappingEntry()
- * params :
- *  in   index
- *  out  extPort (6 bytes)
- *  out  intClient (16 bytes)
- *  out  intPort (6 bytes)
- *  out  protocol (4 bytes)
- *  out  desc (80 bytes)
- *  out  enabled (4 bytes)
- *  out  rHost (64 bytes)
- *  out  duration (16 bytes)
- *
- * return value :
- * UPNPCOMMAND_SUCCESS, UPNPCOMMAND_INVALID_ARGS, UPNPCOMMAND_UNKNOWN_ERROR
- * or a UPnP Error Code.
- *
- * Possible UPNP Error codes :
- * 402 Invalid Args - See UPnP Device Architecture section on Control.
- * 606 Action not authorized - The action requested REQUIRES authorization
- *                             and the sender was not authorized.
- * 713 SpecifiedArrayIndexInvalid - The specified array index is out of bounds
- */
-MINIUPNP_LIBSPEC int
-UPNP_GetGenericPortMappingEntry(const char * controlURL,
-                                const char * servicetype,
-								const char * index,
-								char * extPort,
-								char * intClient,
-								char * intPort,
-								char * protocol,
-								char * desc,
-								char * enabled,
-								char * rHost,
-								char * duration);
-
-/* UPNP_GetListOfPortMappings()      Available in IGD v2
- *
- *
- * Possible UPNP Error codes :
- * 606 Action not Authorized
- * 730 PortMappingNotFound - no port mapping is found in the specified range.
- * 733 InconsistantParameters - NewStartPort and NewEndPort values are not
- *                              consistent.
- */
-MINIUPNP_LIBSPEC int
-UPNP_GetListOfPortMappings(const char * controlURL,
-                           const char * servicetype,
-                           const char * startPort,
-                           const char * endPort,
-                           const char * protocol,
-                           const char * numberOfPorts,
-                           struct PortMappingParserData * data);
-
-/* IGD:2, functions for service WANIPv6FirewallControl:1 */
-MINIUPNP_LIBSPEC int
-UPNP_GetFirewallStatus(const char * controlURL,
-				const char * servicetype,
-				int * firewallEnabled,
-				int * inboundPinholeAllowed);
-
-MINIUPNP_LIBSPEC int
-UPNP_GetOutboundPinholeTimeout(const char * controlURL, const char * servicetype,
-                    const char * remoteHost,
-                    const char * remotePort,
-                    const char * intClient,
-                    const char * intPort,
-                    const char * proto,
-                    int * opTimeout);
-
-MINIUPNP_LIBSPEC int
-UPNP_AddPinhole(const char * controlURL, const char * servicetype,
-                    const char * remoteHost,
-                    const char * remotePort,
-                    const char * intClient,
-                    const char * intPort,
-                    const char * proto,
-                    const char * leaseTime,
-                    char * uniqueID);
-
-MINIUPNP_LIBSPEC int
-UPNP_UpdatePinhole(const char * controlURL, const char * servicetype,
-                    const char * uniqueID,
-                    const char * leaseTime);
-
-MINIUPNP_LIBSPEC int
-UPNP_DeletePinhole(const char * controlURL, const char * servicetype, const char * uniqueID);
-
-MINIUPNP_LIBSPEC int
-UPNP_CheckPinholeWorking(const char * controlURL, const char * servicetype,
-                                 const char * uniqueID, int * isWorking);
-
-MINIUPNP_LIBSPEC int
-UPNP_GetPinholePackets(const char * controlURL, const char * servicetype,
-                                 const char * uniqueID, int * packets);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-

+ 0 - 23
ext/miniupnpc/upnpdev.c

@@ -1,23 +0,0 @@
-/* $Id: upnpdev.c,v 1.1 2015/08/28 12:14:19 nanard Exp $ */
-/* Project : miniupnp
- * Web : http://miniupnp.free.fr/
- * Author : Thomas BERNARD
- * copyright (c) 2005-2015 Thomas Bernard
- * This software is subjet to the conditions detailed in the
- * provided LICENSE file. */
-#include <stdlib.h>
-#include "upnpdev.h"
-
-/* freeUPNPDevlist() should be used to
- * free the chained list returned by upnpDiscover() */
-void freeUPNPDevlist(struct UPNPDev * devlist)
-{
-	struct UPNPDev * next;
-	while(devlist)
-	{
-		next = devlist->pNext;
-		free(devlist);
-		devlist = next;
-	}
-}
-

+ 0 - 36
ext/miniupnpc/upnpdev.h

@@ -1,36 +0,0 @@
-/* $Id: upnpdev.h,v 1.1 2015/08/28 12:14:19 nanard Exp $ */
-/* Project : miniupnp
- * Web : http://miniupnp.free.fr/
- * Author : Thomas BERNARD
- * copyright (c) 2005-2015 Thomas Bernard
- * This software is subjet to the conditions detailed in the
- * provided LICENSE file. */
-#ifndef UPNPDEV_H_INCLUDED
-#define UPNPDEV_H_INCLUDED
-
-#include "miniupnpc_declspec.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct UPNPDev {
-	struct UPNPDev * pNext;
-	char * descURL;
-	char * st;
-	unsigned int scope_id;
-	char * usn;
-	char buffer[3];
-};
-
-/* freeUPNPDevlist()
- * free list returned by upnpDiscover() */
-MINIUPNP_LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif /* UPNPDEV_H_INCLUDED */

+ 0 - 107
ext/miniupnpc/upnperrors.c

@@ -1,107 +0,0 @@
-/* $Id: upnperrors.c,v 1.8 2014/06/10 09:41:48 nanard Exp $ */
-/* Project : miniupnp
- * Author : Thomas BERNARD
- * copyright (c) 2007 Thomas Bernard
- * All Right reserved.
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * This software is subjet to the conditions detailed in the
- * provided LICENCE file. */
-#include <string.h>
-#include "upnperrors.h"
-#include "upnpcommands.h"
-#include "miniupnpc.h"
-
-const char * strupnperror(int err)
-{
-	const char * s = NULL;
-	switch(err) {
-	case UPNPCOMMAND_SUCCESS:
-		s = "Success";
-		break;
-	case UPNPCOMMAND_UNKNOWN_ERROR:
-		s = "Miniupnpc Unknown Error";
-		break;
-	case UPNPCOMMAND_INVALID_ARGS:
-		s = "Miniupnpc Invalid Arguments";
-		break;
-	case UPNPCOMMAND_INVALID_RESPONSE:
-		s = "Miniupnpc Invalid response";
-		break;
-	case UPNPDISCOVER_SOCKET_ERROR:
-		s = "Miniupnpc Socket error";
-		break;
-	case UPNPDISCOVER_MEMORY_ERROR:
-		s = "Miniupnpc Memory allocation error";
-		break;
-	case 401:
-		s = "Invalid Action";
-		break;
-	case 402:
-		s = "Invalid Args";
-		break;
-	case 501:
-		s = "Action Failed";
-		break;
-	case 606:
-		s = "Action not authorized";
-		break;
-	case 701:
-		s = "PinholeSpaceExhausted";
-		break;
-	case 702:
-		s = "FirewallDisabled";
-		break;
-	case 703:
-		s = "InboundPinholeNotAllowed";
-		break;
-	case 704:
-		s = "NoSuchEntry";
-		break;
-	case 705:
-		s = "ProtocolNotSupported";
-		break;
-	case 706:
-		s = "InternalPortWildcardingNotAllowed";
-		break;
-	case 707:
-		s = "ProtocolWildcardingNotAllowed";
-		break;
-	case 708:
-		s = "WildcardNotPermittedInSrcIP";
-		break;
-	case 709:
-		s = "NoPacketSent";
-		break;
-	case 713:
-		s = "SpecifiedArrayIndexInvalid";
-		break;
-	case 714:
-		s = "NoSuchEntryInArray";
-		break;
-	case 715:
-		s = "WildCardNotPermittedInSrcIP";
-		break;
-	case 716:
-		s = "WildCardNotPermittedInExtPort";
-		break;
-	case 718:
-		s = "ConflictInMappingEntry";
-		break;
-	case 724:
-		s = "SamePortValuesRequired";
-		break;
-	case 725:
-		s = "OnlyPermanentLeasesSupported";
-		break;
-	case 726:
-		s = "RemoteHostOnlySupportsWildcard";
-		break;
-	case 727:
-		s = "ExternalPortOnlySupportsWildcard";
-		break;
-	default:
-		s = "UnknownError";
-		break;
-	}
-	return s;
-}

+ 0 - 26
ext/miniupnpc/upnperrors.h

@@ -1,26 +0,0 @@
-/* $Id: upnperrors.h,v 1.6 2015/07/21 13:16:55 nanard Exp $ */
-/* (c) 2007-2015 Thomas Bernard
- * All rights reserved.
- * MiniUPnP Project.
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * This software is subjet to the conditions detailed in the
- * provided LICENCE file. */
-#ifndef UPNPERRORS_H_INCLUDED
-#define UPNPERRORS_H_INCLUDED
-
-#include "miniupnpc_declspec.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* strupnperror()
- * Return a string description of the UPnP error code
- * or NULL for undefinded errors */
-MINIUPNP_LIBSPEC const char * strupnperror(int err);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif

+ 0 - 196
ext/miniupnpc/upnpreplyparse.c

@@ -1,196 +0,0 @@
-/* $Id: upnpreplyparse.c,v 1.20 2017/12/12 11:26:25 nanard Exp $ */
-/* vim: tabstop=4 shiftwidth=4 noexpandtab
- * MiniUPnP project
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * (c) 2006-2017 Thomas Bernard
- * This software is subject to the conditions detailed
- * in the LICENCE file provided within the distribution */
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-
-#include "upnpreplyparse.h"
-#include "minixml.h"
-
-static void
-NameValueParserStartElt(void * d, const char * name, int l)
-{
-	struct NameValueParserData * data = (struct NameValueParserData *)d;
-	data->topelt = 1;
-    if(l>63)
-        l = 63;
-    memcpy(data->curelt, name, l);
-    data->curelt[l] = '\0';
-	data->cdata = NULL;
-	data->cdatalen = 0;
-}
-
-static void
-NameValueParserEndElt(void * d, const char * name, int namelen)
-{
-    struct NameValueParserData * data = (struct NameValueParserData *)d;
-    struct NameValue * nv;
-	(void)name;
-	(void)namelen;
-	if(!data->topelt)
-		return;
-	if(strcmp(data->curelt, "NewPortListing") != 0)
-	{
-		int l;
-		/* standard case. Limited to n chars strings */
-		l = data->cdatalen;
-	    nv = malloc(sizeof(struct NameValue));
-		if(nv == NULL)
-		{
-			/* malloc error */
-#ifdef DEBUG
-			fprintf(stderr, "%s: error allocating memory",
-			        "NameValueParserEndElt");
-#endif /* DEBUG */
-			return;
-		}
-	    if(l>=(int)sizeof(nv->value))
-	        l = sizeof(nv->value) - 1;
-	    strncpy(nv->name, data->curelt, 64);
-		nv->name[63] = '\0';
-		if(data->cdata != NULL)
-		{
-			memcpy(nv->value, data->cdata, l);
-			nv->value[l] = '\0';
-		}
-		else
-		{
-			nv->value[0] = '\0';
-		}
-		nv->l_next = data->l_head;	/* insert in list */
-		data->l_head = nv;
-	}
-	data->cdata = NULL;
-	data->cdatalen = 0;
-	data->topelt = 0;
-}
-
-static void
-NameValueParserGetData(void * d, const char * datas, int l)
-{
-    struct NameValueParserData * data = (struct NameValueParserData *)d;
-	if(strcmp(data->curelt, "NewPortListing") == 0)
-	{
-		/* specific case for NewPortListing which is a XML Document */
-		data->portListing = malloc(l + 1);
-		if(!data->portListing)
-		{
-			/* malloc error */
-#ifdef DEBUG
-			fprintf(stderr, "%s: error allocating memory",
-			        "NameValueParserGetData");
-#endif /* DEBUG */
-			return;
-		}
-		memcpy(data->portListing, datas, l);
-		data->portListing[l] = '\0';
-		data->portListingLength = l;
-	}
-	else
-	{
-		/* standard case. */
-		data->cdata = datas;
-		data->cdatalen = l;
-	}
-}
-
-void
-ParseNameValue(const char * buffer, int bufsize,
-               struct NameValueParserData * data)
-{
-	struct xmlparser parser;
-	memset(data, 0, sizeof(struct NameValueParserData));
-	/* init xmlparser object */
-	parser.xmlstart = buffer;
-	parser.xmlsize = bufsize;
-	parser.data = data;
-	parser.starteltfunc = NameValueParserStartElt;
-	parser.endeltfunc = NameValueParserEndElt;
-	parser.datafunc = NameValueParserGetData;
-	parser.attfunc = 0;
-	parsexml(&parser);
-}
-
-void
-ClearNameValueList(struct NameValueParserData * pdata)
-{
-    struct NameValue * nv;
-	if(pdata->portListing)
-	{
-		free(pdata->portListing);
-		pdata->portListing = NULL;
-		pdata->portListingLength = 0;
-	}
-    while((nv = pdata->l_head) != NULL)
-    {
-		pdata->l_head = nv->l_next;
-        free(nv);
-    }
-}
-
-char *
-GetValueFromNameValueList(struct NameValueParserData * pdata,
-                          const char * Name)
-{
-    struct NameValue * nv;
-    char * p = NULL;
-    for(nv = pdata->l_head;
-        (nv != NULL) && (p == NULL);
-        nv = nv->l_next)
-    {
-        if(strcmp(nv->name, Name) == 0)
-            p = nv->value;
-    }
-    return p;
-}
-
-#if 0
-/* useless now that minixml ignores namespaces by itself */
-char *
-GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata,
-                                  const char * Name)
-{
-	struct NameValue * nv;
-	char * p = NULL;
-	char * pname;
-	for(nv = pdata->head.lh_first;
-	    (nv != NULL) && (p == NULL);
-		nv = nv->entries.le_next)
-	{
-		pname = strrchr(nv->name, ':');
-		if(pname)
-			pname++;
-		else
-			pname = nv->name;
-		if(strcmp(pname, Name)==0)
-			p = nv->value;
-	}
-	return p;
-}
-#endif
-
-/* debug all-in-one function
- * do parsing then display to stdout */
-#ifdef DEBUG
-void
-DisplayNameValueList(char * buffer, int bufsize)
-{
-    struct NameValueParserData pdata;
-    struct NameValue * nv;
-    ParseNameValue(buffer, bufsize, &pdata);
-    for(nv = pdata.l_head;
-        nv != NULL;
-        nv = nv->l_next)
-    {
-        printf("%s = %s\n", nv->name, nv->value);
-    }
-    ClearNameValueList(&pdata);
-}
-#endif /* DEBUG */
-

+ 0 - 63
ext/miniupnpc/upnpreplyparse.h

@@ -1,63 +0,0 @@
-/* $Id: upnpreplyparse.h,v 1.19 2014/10/27 16:33:19 nanard Exp $ */
-/* MiniUPnP project
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * (c) 2006-2013 Thomas Bernard
- * This software is subject to the conditions detailed
- * in the LICENCE file provided within the distribution */
-
-#ifndef UPNPREPLYPARSE_H_INCLUDED
-#define UPNPREPLYPARSE_H_INCLUDED
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-struct NameValue {
-	struct NameValue * l_next;
-	char name[64];
-	char value[128];
-};
-
-struct NameValueParserData {
-	struct NameValue * l_head;
-	char curelt[64];
-	char * portListing;
-	int portListingLength;
-	int topelt;
-	const char * cdata;
-	int cdatalen;
-};
-
-/* ParseNameValue() */
-void
-ParseNameValue(const char * buffer, int bufsize,
-               struct NameValueParserData * data);
-
-/* ClearNameValueList() */
-void
-ClearNameValueList(struct NameValueParserData * pdata);
-
-/* GetValueFromNameValueList() */
-char *
-GetValueFromNameValueList(struct NameValueParserData * pdata,
-                          const char * Name);
-
-#if 0
-/* GetValueFromNameValueListIgnoreNS() */
-char *
-GetValueFromNameValueListIgnoreNS(struct NameValueParserData * pdata,
-                                  const char * Name);
-#endif
-
-/* DisplayNameValueList() */
-#ifdef DEBUG
-void
-DisplayNameValueList(char * buffer, int bufsize);
-#endif
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
-

+ 0 - 83
ext/miniupnpc/wingenminiupnpcstrings.c

@@ -1,83 +0,0 @@
-/* $Id: wingenminiupnpcstrings.c,v 1.4 2015/02/08 08:46:06 nanard Exp $ */
-/* Project: miniupnp
- * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
- * Author: Thomas Bernard
- * Copyright (c) 2005-2015 Thomas Bernard
- * This software is subjects to the conditions detailed
- * in the LICENSE file provided within this distribution */
-#include <stdio.h>
-#include <windows.h>
-
-/* This program display the Windows version and is used to
- * generate the miniupnpcstrings.h
- * wingenminiupnpcstrings miniupnpcstrings.h.in miniupnpcstrings.h
- */
-int main(int argc, char * * argv) {
-	char buffer[256];
-	OSVERSIONINFO osvi;
-	FILE * fin;
-	FILE * fout;
-	int n;
-	char miniupnpcVersion[32];
-	/* dwMajorVersion :
-       The major version number of the operating system. For more information, see Remarks.
-     dwMinorVersion :
-       The minor version number of the operating system. For more information, see Remarks.
-     dwBuildNumber :
-       The build number of the operating system.
-     dwPlatformId
-       The operating system platform. This member can be the following value.
-     szCSDVersion
-       A null-terminated string, such as "Service Pack 3", that indicates the
-       latest Service Pack installed on the system. If no Service Pack has
-       been installed, the string is empty.
-   */
-  ZeroMemory(&osvi, sizeof(OSVERSIONINFO));
-  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
-
-  GetVersionEx(&osvi);
-
-	printf("Windows %lu.%lu Build %lu %s\n",
-	       osvi.dwMajorVersion, osvi.dwMinorVersion,
-	       osvi.dwBuildNumber, (const char *)&(osvi.szCSDVersion));
-
-	fin = fopen("VERSION", "r");
-	fgets(miniupnpcVersion, sizeof(miniupnpcVersion), fin);
-	fclose(fin);
-	for(n = 0; n < sizeof(miniupnpcVersion); n++) {
-		if(miniupnpcVersion[n] < ' ')
-			miniupnpcVersion[n] = '\0';
-	}
-	printf("MiniUPnPc version %s\n", miniupnpcVersion);
-
-	if(argc >= 3) {
-		fin = fopen(argv[1], "r");
-		if(!fin) {
-			fprintf(stderr, "Cannot open %s for reading.\n", argv[1]);
-			return 1;
-		}
-		fout = fopen(argv[2], "w");
-		if(!fout) {
-			fprintf(stderr, "Cannot open %s for writing.\n", argv[2]);
-			fclose(fin);
-			return 1;
-		}
-		n = 0;
-		while(fgets(buffer, sizeof(buffer), fin)) {
-			if(0 == memcmp(buffer, "#define OS_STRING \"OS/version\"", 30)) {
-				sprintf(buffer, "#define OS_STRING \"MSWindows/%ld.%ld.%ld\"\n",
-				        osvi.dwMajorVersion, osvi.dwMinorVersion, osvi.dwBuildNumber);
-			} else if(0 == memcmp(buffer, "#define MINIUPNPC_VERSION_STRING \"version\"", 42)) {
-				sprintf(buffer, "#define MINIUPNPC_VERSION_STRING \"%s\"\n",
-				        miniupnpcVersion);
-			}
-			/*fputs(buffer, stdout);*/
-			fputs(buffer, fout);
-			n++;
-		}
-		fclose(fin);
-		fclose(fout);
-		printf("%d lines written to %s.\n", n, argv[2]);
-	}
-  return 0;
-}

+ 4 - 1
go/pkg/zerotier/node.go

@@ -67,7 +67,10 @@ const (
 	// PlatformDefaultHomePath is the default location of ZeroTier's working path on this system
 	// PlatformDefaultHomePath is the default location of ZeroTier's working path on this system
 	PlatformDefaultHomePath string = C.GoString(C.ZT_PLATFORM_DEFAULT_HOMEPATH)
 	PlatformDefaultHomePath string = C.GoString(C.ZT_PLATFORM_DEFAULT_HOMEPATH)
 
 
-	AFInet  = C.AF_INET
+	// AFInet is the address family for IPv4
+	AFInet = C.AF_INET
+
+	// AFInet6 is the address family for IPv6
 	AFInet6 = C.AF_INET6
 	AFInet6 = C.AF_INET6
 
 
 	defaultVirtualNetworkMTU = C.ZT_DEFAULT_MTU
 	defaultVirtualNetworkMTU = C.ZT_DEFAULT_MTU