42 changed files with 146 additions and 2071 deletions
@ -1,5 +0,0 @@ |
|||||||
include README |
|
||||||
include miniupnpcmodule.c |
|
||||||
include setup.py |
|
||||||
include *.h |
|
||||||
include libminiupnpc.a |
|
||||||
@ -1,172 +0,0 @@ |
|||||||
$Id: apiversions.txt,v 1.9 2016/01/24 17:24:36 nanard Exp $ |
|
||||||
|
|
||||||
Differences in API between miniUPnPc versions |
|
||||||
|
|
||||||
API version 16 |
|
||||||
added "status_code" argument to getHTTPResponse(), miniwget() and miniwget_getaddr() |
|
||||||
updated macro : |
|
||||||
#define MINIUPNPC_API_VERSION 16 |
|
||||||
|
|
||||||
API version 15 |
|
||||||
changed "sameport" argument of upnpDiscover() upnpDiscoverAll() upnpDiscoverDevice() |
|
||||||
to "localport". When 0 or 1, behaviour is not changed, but it can take |
|
||||||
any other value between 2 and 65535 |
|
||||||
Existing programs should be compatible |
|
||||||
updated macro : |
|
||||||
#define MINIUPNPC_API_VERSION 15 |
|
||||||
|
|
||||||
API version 14 |
|
||||||
miniupnpc.h |
|
||||||
add ttl argument to upnpDiscover() upnpDiscoverAll() upnpDiscoverDevice() |
|
||||||
upnpDiscoverDevices() |
|
||||||
getDevicesFromMiniSSDPD() : |
|
||||||
connectToMiniSSDPD() / disconnectFromMiniSSDPD() |
|
||||||
requestDevicesFromMiniSSDPD() / receiveDevicesFromMiniSSDPD() |
|
||||||
updated macro : |
|
||||||
#define MINIUPNPC_API_VERSION 14 |
|
||||||
|
|
||||||
API version 13 |
|
||||||
miniupnpc.h: |
|
||||||
add searchalltype param to upnpDiscoverDevices() function |
|
||||||
updated macro : |
|
||||||
#define MINIUPNPC_API_VERSION 13 |
|
||||||
|
|
||||||
API version 12 |
|
||||||
miniupnpc.h : |
|
||||||
add upnpDiscoverAll() / upnpDiscoverDevice() / upnpDiscoverDevices() |
|
||||||
functions |
|
||||||
updated macros : |
|
||||||
#define MINIUPNPC_API_VERSION 12 |
|
||||||
|
|
||||||
API version 11 |
|
||||||
|
|
||||||
upnpreplyparse.h / portlistingparse.h : |
|
||||||
removed usage of sys/queue.h / bsdqueue.h |
|
||||||
|
|
||||||
miniupnpc.h: |
|
||||||
updated macros : |
|
||||||
#define MINIUPNPC_API_VERSION 11 |
|
||||||
|
|
||||||
====================== miniUPnPc version 1.9 ====================== |
|
||||||
API version 10 |
|
||||||
|
|
||||||
upnpcommands.h: |
|
||||||
added argument remoteHost to UPNP_GetSpecificPortMappingEntry() |
|
||||||
|
|
||||||
miniupnpc.h: |
|
||||||
updated macros : |
|
||||||
#define MINIUPNPC_VERSION "1.9" |
|
||||||
#define MINIUPNPC_API_VERSION 10 |
|
||||||
|
|
||||||
====================== miniUPnPc version 1.8 ====================== |
|
||||||
API version 9 |
|
||||||
|
|
||||||
miniupnpc.h: |
|
||||||
updated macros : |
|
||||||
#define MINIUPNPC_VERSION "1.8" |
|
||||||
#define MINIUPNPC_API_VERSION 9 |
|
||||||
added "unsigned int scope_id;" to struct UPNPDev |
|
||||||
added scope_id argument to GetUPNPUrls() |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
====================== miniUPnPc version 1.7 ====================== |
|
||||||
API version 8 |
|
||||||
|
|
||||||
miniupnpc.h : |
|
||||||
add new macros : |
|
||||||
#define MINIUPNPC_VERSION "1.7" |
|
||||||
#define MINIUPNPC_API_VERSION 8 |
|
||||||
add rootdescURL to struct UPNPUrls |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
====================== miniUPnPc version 1.6 ====================== |
|
||||||
API version 8 |
|
||||||
|
|
||||||
Adding support for IPv6. |
|
||||||
igd_desc_parse.h : |
|
||||||
struct IGDdatas_service : |
|
||||||
add char presentationurl[MINIUPNPC_URL_MAXSIZE]; |
|
||||||
struct IGDdatas : |
|
||||||
add struct IGDdatas_service IPv6FC; |
|
||||||
miniupnpc.h : |
|
||||||
new macros : |
|
||||||
#define UPNPDISCOVER_SUCCESS (0) |
|
||||||
#define UPNPDISCOVER_UNKNOWN_ERROR (-1) |
|
||||||
#define UPNPDISCOVER_SOCKET_ERROR (-101) |
|
||||||
#define UPNPDISCOVER_MEMORY_ERROR (-102) |
|
||||||
simpleUPnPcommand() prototype changed (but is normaly not used by API users) |
|
||||||
add arguments ipv6 and error to upnpDiscover() : |
|
||||||
struct UPNPDev * |
|
||||||
upnpDiscover(int delay, const char * multicastif, |
|
||||||
const char * minissdpdsock, int sameport, |
|
||||||
int ipv6, |
|
||||||
int * error); |
|
||||||
add controlURL_6FC member to struct UPNPUrls : |
|
||||||
struct UPNPUrls { |
|
||||||
char * controlURL; |
|
||||||
char * ipcondescURL; |
|
||||||
char * controlURL_CIF; |
|
||||||
char * controlURL_6FC; |
|
||||||
}; |
|
||||||
|
|
||||||
upnpcommands.h : |
|
||||||
add leaseDuration argument to UPNP_AddPortMapping() |
|
||||||
add desc, enabled and leaseDuration arguments to UPNP_GetSpecificPortMappingEntry() |
|
||||||
add UPNP_GetListOfPortMappings() function (IGDv2) |
|
||||||
add IGDv2 IPv6 related functions : |
|
||||||
UPNP_GetFirewallStatus() |
|
||||||
UPNP_GetOutboundPinholeTimeout() |
|
||||||
UPNP_AddPinhole() |
|
||||||
UPNP_UpdatePinhole() |
|
||||||
UPNP_DeletePinhole() |
|
||||||
UPNP_CheckPinholeWorking() |
|
||||||
UPNP_GetPinholePackets() |
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
====================== miniUPnPc version 1.5 ====================== |
|
||||||
API version 5 |
|
||||||
|
|
||||||
new function : |
|
||||||
int UPNPIGD_IsConnected(struct UPNPUrls *, struct IGDdatas *); |
|
||||||
new macro in upnpcommands.h : |
|
||||||
#define UPNPCOMMAND_HTTP_ERROR |
|
||||||
|
|
||||||
====================== miniUPnPc version 1.4 ====================== |
|
||||||
Same API as version 1.3 |
|
||||||
|
|
||||||
====================== miniUPnPc version 1.3 ====================== |
|
||||||
API version 4 |
|
||||||
|
|
||||||
Use UNSIGNED_INTEGER type for |
|
||||||
UPNP_GetTotalBytesSent(), UPNP_GetTotalBytesReceived(), |
|
||||||
UPNP_GetTotalPacketsSent(), UPNP_GetTotalPacketsReceived() |
|
||||||
Add remoteHost argument to UPNP_AddPortMapping() and UPNP_DeletePortMapping() |
|
||||||
|
|
||||||
====================== miniUPnPc version 1.2 ====================== |
|
||||||
API version 3 |
|
||||||
|
|
||||||
added sameport argument to upnpDiscover() |
|
||||||
struct UPNPDev * |
|
||||||
upnpDiscover(int delay, const char * multicastif, |
|
||||||
const char * minissdpdsock, int sameport); |
|
||||||
|
|
||||||
====================== miniUPnPc Version 1.1 ====================== |
|
||||||
Same API as 1.0 |
|
||||||
|
|
||||||
|
|
||||||
====================== miniUPnPc Version 1.0 ====================== |
|
||||||
API version 2 |
|
||||||
|
|
||||||
|
|
||||||
struct UPNPDev { |
|
||||||
struct UPNPDev * pNext; |
|
||||||
char * descURL; |
|
||||||
char * st; |
|
||||||
char buffer[2]; |
|
||||||
}; |
|
||||||
struct UPNPDev * upnpDiscover(int delay, const char * multicastif, |
|
||||||
const char * minissdpdsock); |
|
||||||
|
|
||||||
@ -1,4 +0,0 @@ |
|||||||
#!/bin/sh |
|
||||||
# $Id: external-ip.sh,v 1.1 2010/08/05 12:57:41 nanard Exp $ |
|
||||||
# (c) 2010 Reuben Hawkins |
|
||||||
upnpc -s | grep ExternalIPAddress | sed 's/[^0-9\.]//g' |
|
||||||
@ -1,659 +0,0 @@ |
|||||||
/* $Id: minihttptestserver.c,v 1.20 2016/12/16 08:54:55 nanard Exp $ */ |
|
||||||
/* Project : miniUPnP
|
|
||||||
* Author : Thomas Bernard |
|
||||||
* Copyright (c) 2011-2016 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 <unistd.h> |
|
||||||
#include <sys/types.h> |
|
||||||
#include <sys/socket.h> |
|
||||||
#include <sys/wait.h> |
|
||||||
#include <arpa/inet.h> |
|
||||||
#include <netinet/in.h> |
|
||||||
#include <signal.h> |
|
||||||
#include <time.h> |
|
||||||
#include <errno.h> |
|
||||||
|
|
||||||
#ifndef INADDR_LOOPBACK |
|
||||||
#define INADDR_LOOPBACK 0x7f000001 |
|
||||||
#endif |
|
||||||
|
|
||||||
#define CRAP_LENGTH (2048) |
|
||||||
|
|
||||||
volatile sig_atomic_t quit = 0; |
|
||||||
volatile sig_atomic_t child_to_wait_for = 0; |
|
||||||
|
|
||||||
/**
|
|
||||||
* signal handler for SIGCHLD (child status has changed) |
|
||||||
*/ |
|
||||||
void handle_signal_chld(int sig) |
|
||||||
{ |
|
||||||
(void)sig; |
|
||||||
/* printf("handle_signal_chld(%d)\n", sig); */ |
|
||||||
++child_to_wait_for; |
|
||||||
} |
|
||||||
|
|
||||||
/**
|
|
||||||
* signal handler for SIGINT (CRTL C) |
|
||||||
*/ |
|
||||||
void handle_signal_int(int sig) |
|
||||||
{ |
|
||||||
(void)sig; |
|
||||||
/* printf("handle_signal_int(%d)\n", sig); */ |
|
||||||
quit = 1; |
|
||||||
} |
|
||||||
|
|
||||||
/**
|
|
||||||
* build a text/plain content of the specified length |
|
||||||
*/ |
|
||||||
void build_content(char * p, int n) |
|
||||||
{ |
|
||||||
char line_buffer[80]; |
|
||||||
int k; |
|
||||||
int i = 0; |
|
||||||
|
|
||||||
while(n > 0) { |
|
||||||
k = snprintf(line_buffer, sizeof(line_buffer), |
|
||||||
"%04d_ABCDEFGHIJKL_This_line_is_64_bytes_long_ABCDEFGHIJKL_%04d\r\n", |
|
||||||
i, i); |
|
||||||
if(k != 64) { |
|
||||||
fprintf(stderr, "snprintf() returned %d in build_content()\n", k); |
|
||||||
} |
|
||||||
++i; |
|
||||||
if(n >= 64) { |
|
||||||
memcpy(p, line_buffer, 64); |
|
||||||
p += 64; |
|
||||||
n -= 64; |
|
||||||
} else { |
|
||||||
memcpy(p, line_buffer, n); |
|
||||||
p += n; |
|
||||||
n = 0; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/**
|
|
||||||
* build crappy content |
|
||||||
*/ |
|
||||||
void build_crap(char * p, int n) |
|
||||||
{ |
|
||||||
static const char crap[] = "_CRAP_\r\n"; |
|
||||||
int i; |
|
||||||
|
|
||||||
while(n > 0) { |
|
||||||
i = sizeof(crap) - 1; |
|
||||||
if(i > n) |
|
||||||
i = n; |
|
||||||
memcpy(p, crap, i); |
|
||||||
p += i; |
|
||||||
n -= i; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/**
|
|
||||||
* build chunked response. |
|
||||||
* return a malloc'ed buffer |
|
||||||
*/ |
|
||||||
char * build_chunked_response(int content_length, int * response_len) |
|
||||||
{ |
|
||||||
char * response_buffer; |
|
||||||
char * content_buffer; |
|
||||||
int buffer_length; |
|
||||||
int i, n; |
|
||||||
|
|
||||||
/* allocate to have some margin */ |
|
||||||
buffer_length = 256 + content_length + (content_length >> 4); |
|
||||||
response_buffer = malloc(buffer_length); |
|
||||||
if(response_buffer == NULL) |
|
||||||
return NULL; |
|
||||||
*response_len = snprintf(response_buffer, buffer_length, |
|
||||||
"HTTP/1.1 200 OK\r\n" |
|
||||||
"Content-Type: text/plain\r\n" |
|
||||||
"Transfer-Encoding: chunked\r\n" |
|
||||||
"\r\n"); |
|
||||||
|
|
||||||
/* build the content */ |
|
||||||
content_buffer = malloc(content_length); |
|
||||||
if(content_buffer == NULL) { |
|
||||||
free(response_buffer); |
|
||||||
return NULL; |
|
||||||
} |
|
||||||
build_content(content_buffer, content_length); |
|
||||||
|
|
||||||
/* chunk it */ |
|
||||||
i = 0; |
|
||||||
while(i < content_length) { |
|
||||||
n = (rand() % 199) + 1; |
|
||||||
if(i + n > content_length) { |
|
||||||
n = content_length - i; |
|
||||||
} |
|
||||||
/* TODO : check buffer size ! */ |
|
||||||
*response_len += snprintf(response_buffer + *response_len, |
|
||||||
buffer_length - *response_len, |
|
||||||
"%x\r\n", n); |
|
||||||
memcpy(response_buffer + *response_len, content_buffer + i, n); |
|
||||||
*response_len += n; |
|
||||||
i += n; |
|
||||||
response_buffer[(*response_len)++] = '\r'; |
|
||||||
response_buffer[(*response_len)++] = '\n'; |
|
||||||
} |
|
||||||
/* the last chunk : "0\r\n" a empty body and then
|
|
||||||
* the final "\r\n" */ |
|
||||||
memcpy(response_buffer + *response_len, "0\r\n\r\n", 5); |
|
||||||
*response_len += 5; |
|
||||||
free(content_buffer); |
|
||||||
|
|
||||||
printf("resp_length=%d buffer_length=%d content_length=%d\n", |
|
||||||
*response_len, buffer_length, content_length); |
|
||||||
return response_buffer; |
|
||||||
} |
|
||||||
|
|
||||||
/* favicon.ico generator */ |
|
||||||
#ifdef OLD_HEADER |
|
||||||
#define FAVICON_LENGTH (6 + 16 + 12 + 8 + 32 * 4) |
|
||||||
#else |
|
||||||
#define FAVICON_LENGTH (6 + 16 + 40 + 8 + 32 * 4) |
|
||||||
#endif |
|
||||||
void build_favicon_content(char * p, int n) |
|
||||||
{ |
|
||||||
int i; |
|
||||||
if(n < FAVICON_LENGTH) |
|
||||||
return; |
|
||||||
/* header : 6 bytes */ |
|
||||||
*p++ = 0; |
|
||||||
*p++ = 0; |
|
||||||
*p++ = 1; /* type : ICO */ |
|
||||||
*p++ = 0; |
|
||||||
*p++ = 1; /* number of images in file */ |
|
||||||
*p++ = 0; |
|
||||||
/* image directory (1 entry) : 16 bytes */ |
|
||||||
*p++ = 16; /* width */ |
|
||||||
*p++ = 16; /* height */ |
|
||||||
*p++ = 2; /* number of colors in the palette. 0 = no palette */ |
|
||||||
*p++ = 0; /* reserved */ |
|
||||||
*p++ = 1; /* color planes */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 1; /* bpp */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
#ifdef OLD_HEADER |
|
||||||
*p++ = 12 + 8 + 32 * 4; /* bmp size */ |
|
||||||
#else |
|
||||||
*p++ = 40 + 8 + 32 * 4; /* bmp size */ |
|
||||||
#endif |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 6 + 16; /* bmp offset */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
/* BMP */ |
|
||||||
#ifdef OLD_HEADER |
|
||||||
/* BITMAPCOREHEADER */ |
|
||||||
*p++ = 12; /* size of this header */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 16; /* width */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 16 * 2; /* height x 2 ! */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 1; /* color planes */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 1; /* bpp */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
#else |
|
||||||
/* BITMAPINFOHEADER */ |
|
||||||
*p++ = 40; /* size of this header */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 16; /* width */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 16 * 2; /* height x 2 ! */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 1; /* color planes */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
*p++ = 1; /* bpp */ |
|
||||||
*p++ = 0; /* " */ |
|
||||||
/* compression method, image size, ppm x, ppm y */ |
|
||||||
/* colors in the palette ? */ |
|
||||||
/* important colors */ |
|
||||||
for(i = 4 * 6; i > 0; --i) |
|
||||||
*p++ = 0; |
|
||||||
#endif |
|
||||||
/* palette */ |
|
||||||
*p++ = 0; /* b */ |
|
||||||
*p++ = 0; /* g */ |
|
||||||
*p++ = 0; /* r */ |
|
||||||
*p++ = 0; /* reserved */ |
|
||||||
*p++ = 255; /* b */ |
|
||||||
*p++ = 255; /* g */ |
|
||||||
*p++ = 255; /* r */ |
|
||||||
*p++ = 0; /* reserved */ |
|
||||||
/* pixel data */ |
|
||||||
for(i = 16; i > 0; --i) { |
|
||||||
if(i & 1) { |
|
||||||
*p++ = 0125; |
|
||||||
*p++ = 0125; |
|
||||||
} else { |
|
||||||
*p++ = 0252; |
|
||||||
*p++ = 0252; |
|
||||||
} |
|
||||||
*p++ = 0; |
|
||||||
*p++ = 0; |
|
||||||
} |
|
||||||
/* Opacity MASK */ |
|
||||||
for(i = 16 * 4; i > 0; --i) { |
|
||||||
*p++ = 0; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
enum modes { |
|
||||||
MODE_INVALID, MODE_CHUNKED, MODE_ADDCRAP, MODE_NORMAL, MODE_FAVICON |
|
||||||
}; |
|
||||||
|
|
||||||
const struct { |
|
||||||
const enum modes mode; |
|
||||||
const char * text; |
|
||||||
} modes_array[] = { |
|
||||||
{MODE_CHUNKED, "chunked"}, |
|
||||||
{MODE_ADDCRAP, "addcrap"}, |
|
||||||
{MODE_NORMAL, "normal"}, |
|
||||||
{MODE_FAVICON, "favicon.ico"}, |
|
||||||
{MODE_INVALID, NULL} |
|
||||||
}; |
|
||||||
|
|
||||||
/**
|
|
||||||
* write the response with random behaviour ! |
|
||||||
*/ |
|
||||||
void send_response(int c, const char * buffer, int len) |
|
||||||
{ |
|
||||||
int n; |
|
||||||
while(len > 0) { |
|
||||||
n = (rand() % 99) + 1; |
|
||||||
if(n > len) |
|
||||||
n = len; |
|
||||||
n = write(c, buffer, n); |
|
||||||
if(n < 0) { |
|
||||||
if(errno != EINTR) { |
|
||||||
perror("write"); |
|
||||||
return; |
|
||||||
} |
|
||||||
/* if errno == EINTR, try again */ |
|
||||||
} else { |
|
||||||
len -= n; |
|
||||||
buffer += n; |
|
||||||
} |
|
||||||
usleep(10000); /* 10ms */ |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/**
|
|
||||||
* handle the HTTP connection |
|
||||||
*/ |
|
||||||
void handle_http_connection(int c) |
|
||||||
{ |
|
||||||
char request_buffer[2048]; |
|
||||||
int request_len = 0; |
|
||||||
int headers_found = 0; |
|
||||||
int n, i; |
|
||||||
char request_method[16]; |
|
||||||
char request_uri[256]; |
|
||||||
char http_version[16]; |
|
||||||
char * p; |
|
||||||
char * response_buffer; |
|
||||||
int response_len; |
|
||||||
enum modes mode; |
|
||||||
int content_length = 16*1024; |
|
||||||
|
|
||||||
/* read the request */ |
|
||||||
while(request_len < (int)sizeof(request_buffer) && !headers_found) { |
|
||||||
n = read(c, |
|
||||||
request_buffer + request_len, |
|
||||||
sizeof(request_buffer) - request_len); |
|
||||||
if(n < 0) { |
|
||||||
if(errno == EINTR) |
|
||||||
continue; |
|
||||||
perror("read"); |
|
||||||
return; |
|
||||||
} else if(n==0) { |
|
||||||
/* remote host closed the connection */ |
|
||||||
break; |
|
||||||
} else { |
|
||||||
request_len += n; |
|
||||||
for(i = 0; i < request_len - 3; i++) { |
|
||||||
if(0 == memcmp(request_buffer + i, "\r\n\r\n", 4)) { |
|
||||||
/* found the end of headers */ |
|
||||||
headers_found = 1; |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
if(!headers_found) { |
|
||||||
/* error */ |
|
||||||
printf("no HTTP header found in the request\n"); |
|
||||||
return; |
|
||||||
} |
|
||||||
printf("headers :\n%.*s", request_len, request_buffer); |
|
||||||
/* the request have been received, now parse the request line */ |
|
||||||
p = request_buffer; |
|
||||||
for(i = 0; i < (int)sizeof(request_method) - 1; i++) { |
|
||||||
if(*p == ' ' || *p == '\r') |
|
||||||
break; |
|
||||||
request_method[i] = *p; |
|
||||||
++p; |
|
||||||
} |
|
||||||
request_method[i] = '\0'; |
|
||||||
while(*p == ' ') |
|
||||||
p++; |
|
||||||
for(i = 0; i < (int)sizeof(request_uri) - 1; i++) { |
|
||||||
if(*p == ' ' || *p == '\r') |
|
||||||
break; |
|
||||||
request_uri[i] = *p; |
|
||||||
++p; |
|
||||||
} |
|
||||||
request_uri[i] = '\0'; |
|
||||||
while(*p == ' ') |
|
||||||
p++; |
|
||||||
for(i = 0; i < (int)sizeof(http_version) - 1; i++) { |
|
||||||
if(*p == ' ' || *p == '\r') |
|
||||||
break; |
|
||||||
http_version[i] = *p; |
|
||||||
++p; |
|
||||||
} |
|
||||||
http_version[i] = '\0'; |
|
||||||
printf("Method = %s, URI = %s, %s\n", |
|
||||||
request_method, request_uri, http_version); |
|
||||||
/* check if the request method is allowed */ |
|
||||||
if(0 != strcmp(request_method, "GET")) { |
|
||||||
const char response405[] = "HTTP/1.1 405 Method Not Allowed\r\n" |
|
||||||
"Allow: GET\r\n\r\n"; |
|
||||||
const char * pc; |
|
||||||
/* 405 Method Not Allowed */ |
|
||||||
/* The response MUST include an Allow header containing a list
|
|
||||||
* of valid methods for the requested resource. */ |
|
||||||
n = sizeof(response405) - 1; |
|
||||||
pc = response405; |
|
||||||
while(n > 0) { |
|
||||||
i = write(c, pc, n); |
|
||||||
if(i<0) { |
|
||||||
if(errno != EINTR) { |
|
||||||
perror("write"); |
|
||||||
return; |
|
||||||
} |
|
||||||
} else { |
|
||||||
n -= i; |
|
||||||
pc += i; |
|
||||||
} |
|
||||||
} |
|
||||||
return; |
|
||||||
} |
|
||||||
|
|
||||||
mode = MODE_INVALID; |
|
||||||
/* use the request URI to know what to do */ |
|
||||||
for(i = 0; modes_array[i].mode != MODE_INVALID; i++) { |
|
||||||
if(strstr(request_uri, modes_array[i].text)) { |
|
||||||
mode = modes_array[i].mode; /* found */ |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
switch(mode) { |
|
||||||
case MODE_CHUNKED: |
|
||||||
response_buffer = build_chunked_response(content_length, &response_len); |
|
||||||
break; |
|
||||||
case MODE_ADDCRAP: |
|
||||||
response_len = content_length+256; |
|
||||||
response_buffer = malloc(response_len); |
|
||||||
if(!response_buffer) |
|
||||||
break; |
|
||||||
n = snprintf(response_buffer, response_len, |
|
||||||
"HTTP/1.1 200 OK\r\n" |
|
||||||
"Server: minihttptestserver\r\n" |
|
||||||
"Content-Type: text/plain\r\n" |
|
||||||
"Content-Length: %d\r\n" |
|
||||||
"\r\n", content_length); |
|
||||||
response_len = content_length+n+CRAP_LENGTH; |
|
||||||
p = realloc(response_buffer, response_len); |
|
||||||
if(p == NULL) { |
|
||||||
/* error 500 */ |
|
||||||
free(response_buffer); |
|
||||||
response_buffer = NULL; |
|
||||||
break; |
|
||||||
} |
|
||||||
response_buffer = p; |
|
||||||
build_content(response_buffer + n, content_length); |
|
||||||
build_crap(response_buffer + n + content_length, CRAP_LENGTH); |
|
||||||
break; |
|
||||||
case MODE_FAVICON: |
|
||||||
content_length = FAVICON_LENGTH; |
|
||||||
response_len = content_length + 256; |
|
||||||
response_buffer = malloc(response_len); |
|
||||||
if(!response_buffer) |
|
||||||
break; |
|
||||||
n = snprintf(response_buffer, response_len, |
|
||||||
"HTTP/1.1 200 OK\r\n" |
|
||||||
"Server: minihttptestserver\r\n" |
|
||||||
"Content-Type: image/vnd.microsoft.icon\r\n" |
|
||||||
"Content-Length: %d\r\n" |
|
||||||
"\r\n", content_length); |
|
||||||
/* image/x-icon */ |
|
||||||
build_favicon_content(response_buffer + n, content_length); |
|
||||||
response_len = content_length + n; |
|
||||||
break; |
|
||||||
default: |
|
||||||
response_len = content_length+256; |
|
||||||
response_buffer = malloc(response_len); |
|
||||||
if(!response_buffer) |
|
||||||
break; |
|
||||||
n = snprintf(response_buffer, response_len, |
|
||||||
"HTTP/1.1 200 OK\r\n" |
|
||||||
"Server: minihttptestserver\r\n" |
|
||||||
"Content-Type: text/plain\r\n" |
|
||||||
"\r\n"); |
|
||||||
response_len = content_length+n; |
|
||||||
p = realloc(response_buffer, response_len); |
|
||||||
if(p == NULL) { |
|
||||||
/* Error 500 */ |
|
||||||
free(response_buffer); |
|
||||||
response_buffer = NULL; |
|
||||||
break; |
|
||||||
} |
|
||||||
response_buffer = p; |
|
||||||
build_content(response_buffer + n, response_len - n); |
|
||||||
} |
|
||||||
|
|
||||||
if(response_buffer) { |
|
||||||
send_response(c, response_buffer, response_len); |
|
||||||
free(response_buffer); |
|
||||||
} else { |
|
||||||
/* Error 500 */ |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/**
|
|
||||||
*/ |
|
||||||
int main(int argc, char * * argv) { |
|
||||||
int ipv6 = 0; |
|
||||||
int s, c, i; |
|
||||||
unsigned short port = 0; |
|
||||||
struct sockaddr_storage server_addr; |
|
||||||
socklen_t server_addrlen; |
|
||||||
struct sockaddr_storage client_addr; |
|
||||||
socklen_t client_addrlen; |
|
||||||
pid_t pid; |
|
||||||
int child = 0; |
|
||||||
int status; |
|
||||||
const char * expected_file_name = NULL; |
|
||||||
struct sigaction sa; |
|
||||||
|
|
||||||
for(i = 1; i < argc; i++) { |
|
||||||
if(argv[i][0] == '-') { |
|
||||||
switch(argv[i][1]) { |
|
||||||
case '6': |
|
||||||
ipv6 = 1; |
|
||||||
break; |
|
||||||
case 'e': |
|
||||||
/* write expected file ! */ |
|
||||||
expected_file_name = argv[++i]; |
|
||||||
break; |
|
||||||
case 'p': |
|
||||||
/* port */ |
|
||||||
if(++i < argc) { |
|
||||||
port = (unsigned short)atoi(argv[i]); |
|
||||||
} |
|
||||||
break; |
|
||||||
default: |
|
||||||
fprintf(stderr, "unknown command line switch '%s'\n", argv[i]); |
|
||||||
} |
|
||||||
} else { |
|
||||||
fprintf(stderr, "unkown command line argument '%s'\n", argv[i]); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
srand(time(NULL)); |
|
||||||
|
|
||||||
memset(&sa, 0, sizeof(struct sigaction)); |
|
||||||
|
|
||||||
/*signal(SIGCHLD, handle_signal_chld);*/ |
|
||||||
sa.sa_handler = handle_signal_chld; |
|
||||||
if(sigaction(SIGCHLD, &sa, NULL) < 0) { |
|
||||||
perror("sigaction"); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
/*signal(SIGINT, handle_signal_int);*/ |
|
||||||
sa.sa_handler = handle_signal_int; |
|
||||||
if(sigaction(SIGINT, &sa, NULL) < 0) { |
|
||||||
perror("sigaction"); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
|
|
||||||
s = socket(ipv6 ? AF_INET6 : AF_INET, SOCK_STREAM, 0); |
|
||||||
if(s < 0) { |
|
||||||
perror("socket"); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
memset(&server_addr, 0, sizeof(struct sockaddr_storage)); |
|
||||||
memset(&client_addr, 0, sizeof(struct sockaddr_storage)); |
|
||||||
if(ipv6) { |
|
||||||
struct sockaddr_in6 * addr = (struct sockaddr_in6 *)&server_addr; |
|
||||||
addr->sin6_family = AF_INET6; |
|
||||||
addr->sin6_port = htons(port); |
|
||||||
addr->sin6_addr = in6addr_loopback; |
|
||||||
} else { |
|
||||||
struct sockaddr_in * addr = (struct sockaddr_in *)&server_addr; |
|
||||||
addr->sin_family = AF_INET; |
|
||||||
addr->sin_port = htons(port); |
|
||||||
addr->sin_addr.s_addr = htonl(INADDR_LOOPBACK); |
|
||||||
} |
|
||||||
if(bind(s, (struct sockaddr *)&server_addr, |
|
||||||
ipv6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) < 0) { |
|
||||||
perror("bind"); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
if(listen(s, 5) < 0) { |
|
||||||
perror("listen"); |
|
||||||
} |
|
||||||
if(port == 0) { |
|
||||||
server_addrlen = sizeof(struct sockaddr_storage); |
|
||||||
if(getsockname(s, (struct sockaddr *)&server_addr, &server_addrlen) < 0) { |
|
||||||
perror("getsockname"); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
if(ipv6) { |
|
||||||
struct sockaddr_in6 * addr = (struct sockaddr_in6 *)&server_addr; |
|
||||||
port = ntohs(addr->sin6_port); |
|
||||||
} else { |
|
||||||
struct sockaddr_in * addr = (struct sockaddr_in *)&server_addr; |
|
||||||
port = ntohs(addr->sin_port); |
|
||||||
} |
|
||||||
printf("Listening on port %hu\n", port); |
|
||||||
fflush(stdout); |
|
||||||
} |
|
||||||
|
|
||||||
/* write expected file */ |
|
||||||
if(expected_file_name) { |
|
||||||
FILE * f; |
|
||||||
f = fopen(expected_file_name, "wb"); |
|
||||||
if(f) { |
|
||||||
char * buffer; |
|
||||||
buffer = malloc(16*1024); |
|
||||||
if(buffer == NULL) { |
|
||||||
fprintf(stderr, "memory allocation error\n"); |
|
||||||
} else { |
|
||||||
build_content(buffer, 16*1024); |
|
||||||
i = fwrite(buffer, 1, 16*1024, f); |
|
||||||
if(i != 16*1024) { |
|
||||||
fprintf(stderr, "error writing to file %s : %dbytes written (out of %d)\n", expected_file_name, i, 16*1024); |
|
||||||
} |
|
||||||
free(buffer); |
|
||||||
} |
|
||||||
fclose(f); |
|
||||||
} else { |
|
||||||
fprintf(stderr, "error opening file %s for writing\n", expected_file_name); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
/* fork() loop */ |
|
||||||
while(!child && !quit) { |
|
||||||
while(child_to_wait_for > 0) { |
|
||||||
pid = wait(&status); |
|
||||||
if(pid < 0) { |
|
||||||
perror("wait"); |
|
||||||
} else { |
|
||||||
printf("child(%d) terminated with status %d\n", (int)pid, status); |
|
||||||
} |
|
||||||
--child_to_wait_for; |
|
||||||
} |
|
||||||
client_addrlen = sizeof(struct sockaddr_storage); |
|
||||||
c = accept(s, (struct sockaddr *)&client_addr, |
|
||||||
&client_addrlen); |
|
||||||
if(c < 0) { |
|
||||||
if(errno == EAGAIN || errno == EWOULDBLOCK || errno == EINTR) |
|
||||||
continue; |
|
||||||
perror("accept"); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
printf("accept...\n"); |
|
||||||
pid = fork(); |
|
||||||
if(pid < 0) { |
|
||||||
perror("fork"); |
|
||||||
return 1; |
|
||||||
} else if(pid == 0) { |
|
||||||
/* child */ |
|
||||||
child = 1; |
|
||||||
close(s); |
|
||||||
s = -1; |
|
||||||
handle_http_connection(c); |
|
||||||
} |
|
||||||
close(c); |
|
||||||
} |
|
||||||
if(s >= 0) { |
|
||||||
close(s); |
|
||||||
s = -1; |
|
||||||
} |
|
||||||
if(!child) { |
|
||||||
while(child_to_wait_for > 0) { |
|
||||||
pid = wait(&status); |
|
||||||
if(pid < 0) { |
|
||||||
perror("wait"); |
|
||||||
} else { |
|
||||||
printf("child(%d) terminated with status %d\n", (int)pid, status); |
|
||||||
} |
|
||||||
--child_to_wait_for; |
|
||||||
} |
|
||||||
printf("Bye...\n"); |
|
||||||
} |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
@ -1,88 +0,0 @@ |
|||||||
#! /usr/bin/python |
|
||||||
# vim: tabstop=2 shiftwidth=2 expandtab |
|
||||||
# MiniUPnP project |
|
||||||
# Author : Thomas Bernard |
|
||||||
# This Sample code is public domain. |
|
||||||
# website : http://miniupnp.tuxfamily.org/ |
|
||||||
|
|
||||||
# import the python miniupnpc module |
|
||||||
import miniupnpc |
|
||||||
import sys |
|
||||||
|
|
||||||
try: |
|
||||||
import argparse |
|
||||||
parser = argparse.ArgumentParser() |
|
||||||
parser.add_argument('-m', '--multicastif') |
|
||||||
parser.add_argument('-p', '--minissdpdsocket') |
|
||||||
parser.add_argument('-d', '--discoverdelay', type=int, default=200) |
|
||||||
parser.add_argument('-z', '--localport', type=int, default=0) |
|
||||||
# create the object |
|
||||||
u = miniupnpc.UPnP(**vars(parser.parse_args())) |
|
||||||
except: |
|
||||||
print 'argparse not available' |
|
||||||
i = 1 |
|
||||||
multicastif = None |
|
||||||
minissdpdsocket = None |
|
||||||
discoverdelay = 200 |
|
||||||
localport = 0 |
|
||||||
while i < len(sys.argv): |
|
||||||
print sys.argv[i] |
|
||||||
if sys.argv[i] == '-m' or sys.argv[i] == '--multicastif': |
|
||||||
multicastif = sys.argv[i+1] |
|
||||||
elif sys.argv[i] == '-p' or sys.argv[i] == '--minissdpdsocket': |
|
||||||
minissdpdsocket = sys.argv[i+1] |
|
||||||
elif sys.argv[i] == '-d' or sys.argv[i] == '--discoverdelay': |
|
||||||
discoverdelay = int(sys.argv[i+1]) |
|
||||||
elif sys.argv[i] == '-z' or sys.argv[i] == '--localport': |
|
||||||
localport = int(sys.argv[i+1]) |
|
||||||
else: |
|
||||||
raise Exception('invalid argument %s' % sys.argv[i]) |
|
||||||
i += 2 |
|
||||||
# create the object |
|
||||||
u = miniupnpc.UPnP(multicastif, minissdpdsocket, discoverdelay, localport) |
|
||||||
|
|
||||||
print 'inital(default) values :' |
|
||||||
print ' discoverdelay', u.discoverdelay |
|
||||||
print ' lanaddr', u.lanaddr |
|
||||||
print ' multicastif', u.multicastif |
|
||||||
print ' minissdpdsocket', u.minissdpdsocket |
|
||||||
#u.minissdpdsocket = '../minissdpd/minissdpd.sock' |
|
||||||
# discovery process, it usualy takes several seconds (2 seconds or more) |
|
||||||
print 'Discovering... delay=%ums' % u.discoverdelay |
|
||||||
print u.discover(), 'device(s) detected' |
|
||||||
# select an igd |
|
||||||
try: |
|
||||||
u.selectigd() |
|
||||||
except Exception, e: |
|
||||||
print 'Exception :', e |
|
||||||
sys.exit(1) |
|
||||||
# display information about the IGD and the internet connection |
|
||||||
print 'local ip address :', u.lanaddr |
|
||||||
print 'external ip address :', u.externalipaddress() |
|
||||||
print u.statusinfo(), u.connectiontype() |
|
||||||
print 'total bytes : sent', u.totalbytesent(), 'received', u.totalbytereceived() |
|
||||||
print 'total packets : sent', u.totalpacketsent(), 'received', u.totalpacketreceived() |
|
||||||
|
|
||||||
#print u.addportmapping(64000, 'TCP', |
|
||||||
# '192.168.1.166', 63000, 'port mapping test', '') |
|
||||||
#print u.deleteportmapping(64000, 'TCP') |
|
||||||
|
|
||||||
port = 0 |
|
||||||
proto = 'UDP' |
|
||||||
# list the redirections : |
|
||||||
i = 0 |
|
||||||
while True: |
|
||||||
p = u.getgenericportmapping(i) |
|
||||||
if p==None: |
|
||||||
break |
|
||||||
print i, p |
|
||||||
(port, proto, (ihost,iport), desc, c, d, e) = p |
|
||||||
#print port, desc |
|
||||||
i = i + 1 |
|
||||||
|
|
||||||
print u.getspecificportmapping(port, proto) |
|
||||||
try: |
|
||||||
print u.getportmappingnumberofentries() |
|
||||||
except Exception, e: |
|
||||||
print 'GetPortMappingNumberOfEntries() is not supported :', e |
|
||||||
|
|
||||||
@ -1,14 +0,0 @@ |
|||||||
# values for linksys_WAG200G_desc.xml |
|
||||||
|
|
||||||
CIF: |
|
||||||
servicetype = urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1 |
|
||||||
controlurl = /upnp/control/WANCommonIFC1 |
|
||||||
eventsuburl = /upnp/event/WANCommonIFC1 |
|
||||||
scpdurl = /cmnicfg.xml |
|
||||||
|
|
||||||
first: |
|
||||||
servicetype = urn:schemas-upnp-org:service:WANPPPConnection:1 |
|
||||||
controlurl = /upnp/control/WANPPPConn1 |
|
||||||
eventsuburl = /upnp/event/WANPPPConn1 |
|
||||||
scpdurl = /pppcfg.xml |
|
||||||
|
|
||||||
@ -1,110 +0,0 @@ |
|||||||
<?xml version="1.0"?> |
|
||||||
<root xmlns="urn:schemas-upnp-org:device-1-0"> |
|
||||||
<specVersion> |
|
||||||
<major>1</major> |
|
||||||
<minor>0</minor> |
|
||||||
</specVersion> |
|
||||||
<URLBase>http://192.168.1.1:49152</URLBase> |
|
||||||
<device> |
|
||||||
<deviceType>urn:schemas-upnp-org:device:InternetGatewayDevice:1</deviceType> |
|
||||||
<friendlyName>LINKSYS WAG200G Gateway</friendlyName> |
|
||||||
<manufacturer>LINKSYS</manufacturer> |
|
||||||
<manufacturerURL>http://www.linksys.com</manufacturerURL> |
|
||||||
<modelDescription>LINKSYS WAG200G Gateway</modelDescription> |
|
||||||
<modelName>Wireless-G ADSL Home Gateway</modelName> |
|
||||||
<modelNumber>WAG200G</modelNumber> |
|
||||||
<modelURL>http://www.linksys.com</modelURL> |
|
||||||
<serialNumber>123456789</serialNumber> |
|
||||||
<UDN>uuid:8ca2eb37-1dd2-11b2-86f1-001a709b5aa8</UDN> |
|
||||||
<UPC>WAG200G</UPC> |
|
||||||
<serviceList> |
|
||||||
<service> |
|
||||||
<serviceType>urn:schemas-upnp-org:service:Layer3Forwarding:1</serviceType> |
|
||||||
<serviceId>urn:upnp-org:serviceId:L3Forwarding1</serviceId> |
|
||||||
<controlURL>/upnp/control/L3Forwarding1</controlURL> |
|
||||||
<eventSubURL>/upnp/event/L3Forwarding1</eventSubURL> |
|
||||||
<SCPDURL>/l3frwd.xml</SCPDURL> |
|
||||||
</service> |
|
||||||
</serviceList> |
|
||||||
<deviceList> |
|
||||||
<device> |
|
||||||
<deviceType>urn:schemas-upnp-org:device:WANDevice:1</deviceType> |
|
||||||
<friendlyName>WANDevice</friendlyName> |
|
||||||
<manufacturer>LINKSYS</manufacturer> |
|
||||||
<manufacturerURL>http://www.linksys.com/</manufacturerURL> |
|
||||||
<modelDescription>Residential Gateway</modelDescription> |
|
||||||
<modelName>Internet Connection Sharing</modelName> |
|
||||||
<modelNumber>1</modelNumber> |
|
||||||
<modelURL>http://www.linksys.com/</modelURL> |
|
||||||
<serialNumber>0000001</serialNumber> |
|
||||||
<UDN>uuid:8ca2eb36-1dd2-11b2-86f1-001a709b5aa8</UDN> |
|
||||||
<UPC>WAG200G</UPC> |
|
||||||
<serviceList> |
|
||||||
<service> |
|
||||||
<serviceType>urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1</serviceType> |
|
||||||
<serviceId>urn:upnp-org:serviceId:WANCommonIFC1</serviceId> |
|
||||||
<controlURL>/upnp/control/WANCommonIFC1</controlURL> |
|
||||||
<eventSubURL>/upnp/event/WANCommonIFC1</eventSubURL> |
|
||||||
<SCPDURL>/cmnicfg.xml</SCPDURL> |
|
||||||
</service> |
|
||||||
</serviceList> |
|
||||||
<deviceList> |
|
||||||
<device> |
|
||||||
<deviceType>urn:schemas-upnp-org:device:WANConnectionDevice:1</deviceType> |
|
||||||
<friendlyName>WANConnectionDevice</friendlyName> |
|
||||||
<manufacturer>LINKSYS</manufacturer> |
|
||||||
<manufacturerURL>http://www.linksys.com/</manufacturerURL> |
|
||||||
<modelDescription>Residential Gateway</modelDescription> |
|
||||||
<modelName>Internet Connection Sharing</modelName> |
|
||||||
<modelNumber>1</modelNumber> |
|
||||||
<modelURL>http://www.linksys.com/</modelURL> |
|
||||||
<serialNumber>0000001</serialNumber> |
|
||||||
<UDN>uuid:8ca2eb37-1dd2-11b2-86f0-001a709b5aa8</UDN> |
|
||||||
<UPC>WAG200G</UPC> |
|
||||||
<serviceList> |
|
||||||
<service> |
|
||||||
<serviceType>urn:schemas-upnp-org:service:WANEthernetLinkConfig:1</serviceType> |
|
||||||
<serviceId>urn:upnp-org:serviceId:WANEthLinkC1</serviceId> |
|
||||||
<controlURL>/upnp/control/WANEthLinkC1</controlURL> |
|
||||||
<eventSubURL>/upnp/event/WANEthLinkC1</eventSubURL> |
|
||||||
<SCPDURL>/wanelcfg.xml</SCPDURL> |
|
||||||
</service> |
|
||||||
<service> |
|
||||||
<serviceType>urn:schemas-upnp-org:service:WANPPPConnection:1</serviceType> |
|
||||||
<serviceId>urn:upnp-org:serviceId:WANPPPConn1</serviceId> |
|
||||||
<controlURL>/upnp/control/WANPPPConn1</controlURL> |
|
||||||
<eventSubURL>/upnp/event/WANPPPConn1</eventSubURL> |
|
||||||
<SCPDURL>/pppcfg.xml</SCPDURL> |
|
||||||
</service> |
|
||||||
</serviceList> |
|
||||||
</device> |
|
||||||
</deviceList> |
|
||||||
</device> |
|
||||||
<device> |
|
||||||
<deviceType>urn:schemas-upnp-org:device:LANDevice:1</deviceType> |
|
||||||
<friendlyName>LANDevice</friendlyName> |
|
||||||
<manufacturer>LINKSYS</manufacturer> |
|
||||||
<manufacturerURL>http://www.linksys.com/</manufacturerURL> |
|
||||||
<modelDescription>Residential Gateway</modelDescription> |
|
||||||
<modelName>Residential Gateway</modelName> |
|
||||||
<modelNumber>1</modelNumber> |
|
||||||
<modelURL>http://www.linksys.com/</modelURL> |
|
||||||
<serialNumber>0000001</serialNumber> |
|
||||||
<UDN>uuid:8ca2eb36-1dd2-11b2-86f0-001a709b5aa |
|
||||||
8</UDN> |
|
||||||
<UPC>WAG200G</UPC> |
|
||||||
<serviceList> |
|
||||||
<service> |
|
||||||
<serviceType>urn:schemas-upnp-org:service:LANHostConfigManagement:1</serviceType> |
|
||||||
<serviceId>urn:upnp-org:serviceId:LANHostCfg1</serviceId> |
|
||||||
<controlURL>/upnp/control/LANHostCfg1</controlURL> |
|
||||||
<eventSubURL>/upnp/event/LANHostCfg1</eventSubURL> |
|
||||||
<SCPDURL>/lanhostc.xml</SCPDURL> |
|
||||||
</service> |
|
||||||
</serviceList> |
|
||||||
</device> |
|
||||||
</deviceList> |
|
||||||
<presentationURL>http://192.168.1.1/index.htm</presentationURL> |
|
||||||
</device> |
|
||||||
</root> |
|
||||||
|
|
||||||
@ -1,20 +0,0 @@ |
|||||||
# values for new_LiveBox_desc.xml |
|
||||||
|
|
||||||
CIF: |
|
||||||
servicetype = urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1 |
|
||||||
controlurl = /87895a19/upnp/control/WANCommonIFC1 |
|
||||||
eventsuburl = /87895a19/upnp/control/WANCommonIFC1 |
|
||||||
scpdurl = /87895a19/gateicfgSCPD.xml |
|
||||||
|
|
||||||
first: |
|
||||||
servicetype = urn:schemas-upnp-org:service:WANPPPConnection:2 |
|
||||||
controlurl = /87895a19/upnp/control/WANIPConn1 |
|
||||||
eventsuburl = /87895a19/upnp/control/WANIPConn1 |
|
||||||
scpdurl = /87895a19/gateconnSCPD_PPP.xml |
|
||||||
|
|
||||||
IPv6FC: |
|
||||||
servicetype = urn:schemas-upnp-org:service:WANIPv6FirewallControl:1 |
|
||||||
controlurl = /87895a19/upnp/control/WANIPv6FwCtrl1 |
|
||||||
eventsuburl = /87895a19/upnp/control/WANIPv6FwCtrl1 |
|
||||||
scpdurl = /87895a19/wanipv6fwctrlSCPD.xml |
|
||||||
|
|
||||||
@ -1,90 +0,0 @@ |
|||||||
<?xml version="1.0"?> |
|
||||||
<root xmlns="urn:schemas-upnp-org:device-1-0"> |
|
||||||
<specVersion> |
|
||||||
<major>1</major> |
|
||||||
<minor>0</minor> |
|
||||||
</specVersion> |
|
||||||
<device> |
|
||||||
<pnpx:X_hardwareId xmlns:pnpx="http://schemas.microsoft.com/windows/pnpx/2005/11">VEN_0129&DEV_0000&SUBSYS_03&REV_250417</pnpx:X_hardwareId> |
|
||||||
<pnpx:X_compatibleId xmlns:pnpx="http://schemas.microsoft.com/windows/pnpx/2005/11">GenericUmPass</pnpx:X_compatibleId> |
|
||||||
<pnpx:X_deviceCategory xmlns:pnpx="http://schemas.microsoft.com/windows/pnpx/2005/11">NetworkInfrastructure.Gateway</pnpx:X_deviceCategory> |
|
||||||
<df:X_deviceCategory xmlns:df="http://schemas.microsoft.com/windows/2008/09/devicefoundation">Network.Gateway</df:X_deviceCategory> |
|
||||||
<deviceType>urn:schemas-upnp-org:device:InternetGatewayDevice:2</deviceType> |
|
||||||
<friendlyName>Orange Livebox</friendlyName> |
|
||||||
<manufacturer>Sagemcom</manufacturer> |
|
||||||
<manufacturerURL>http://www.sagemcom.com/</manufacturerURL> |
|
||||||
<modelName>Residential Livebox,(DSL,WAN Ethernet)</modelName> |
|
||||||
<UDN>uuid:87895a19-50f9-3736-a87f-115c230155f8</UDN> |
|
||||||
<modelDescription>Sagemcom,fr,SG30_sip-fr-4.28.35.1</modelDescription> |
|
||||||
<modelNumber>3</modelNumber> |
|
||||||
<serialNumber>LK14129DP441489</serialNumber> |
|
||||||
<presentationURL>http://192.168.1.1</presentationURL> |
|
||||||
<UPC></UPC> |
|
||||||
<iconList> |
|
||||||
<icon> |
|
||||||
<mimetype>image/png</mimetype> |
|
||||||
<width>16</width> |
|
||||||
<height>16</height> |
|
||||||
<depth>8</depth> |
|
||||||
<url>/87895a19/ligd.png</url> |
|
||||||
</icon> |
|
||||||
</iconList> |
|
||||||
<deviceList> |
|
||||||
<device> |
|
||||||
<deviceType>urn:schemas-upnp-org:device:WANDevice:2</deviceType> |
|
||||||
<friendlyName>WANDevice</friendlyName> |
|
||||||
<manufacturer>Sagemcom</manufacturer> |
|
||||||
<manufacturerURL>http://www.sagemcom.com/</manufacturerURL> |
|
||||||
<modelDescription>WAN Device on Sagemcom,fr,SG30_sip-fr-4.28.35.1</modelDescription> |
|
||||||
<modelName>Residential Livebox,(DSL,WAN Ethernet)</modelName> |
|
||||||
<modelNumber>3</modelNumber> |
|
||||||
<modelURL>http://www.sagemcom.com/</modelURL> |
|
||||||
<serialNumber>LK14129DP441489</serialNumber> |
|
||||||
<presentationURL>http://192.168.1.1</presentationURL> |
|
||||||
<UDN>uuid:e2397374-53d8-3fc6-8306-593ba1a34625</UDN> |
|
||||||
<UPC></UPC> |
|
||||||
<serviceList> |
|
||||||
<service> |
|
||||||
<serviceType>urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1</serviceType> |
|
||||||
<serviceId>urn:upnp-org:serviceId:WANCommonIFC1</serviceId> |
|
||||||
<controlURL>/87895a19/upnp/control/WANCommonIFC1</controlURL> |
|
||||||
<eventSubURL>/87895a19/upnp/control/WANCommonIFC1</eventSubURL> |
|
||||||
<SCPDURL>/87895a19/gateicfgSCPD.xml</SCPDURL> |
|
||||||
</service> |
|
||||||
</serviceList> |
|
||||||
<deviceList> |
|
||||||
<device> |
|
||||||
<deviceType>urn:schemas-upnp-org:device:WANConnectionDevice:2</deviceType> |
|
||||||
<friendlyName>WANConnectionDevice</friendlyName> |
|
||||||
<manufacturer>Sagemcom</manufacturer> |
|
||||||
<manufacturerURL>http://www.sagemcom.com/</manufacturerURL> |
|
||||||
<modelDescription>WanConnectionDevice on Sagemcom,fr,SG30_sip-fr-4.28.35.1</modelDescription> |
|
||||||
<modelName>Residential Livebox,(DSL,WAN Ethernet)</modelName> |
|
||||||
<modelNumber>3</modelNumber> |
|
||||||
<modelURL>http://www.sagemcom.com/</modelURL> |
|
||||||
<serialNumber>LK14129DP441489</serialNumber> |
|
||||||
<presentationURL>http://192.168.1.1</presentationURL> |
|
||||||
<UDN>uuid:44598a08-288e-32c9-8a4d-d3c008ede331</UDN> |
|
||||||
<UPC></UPC> |
|
||||||
<serviceList> |
|
||||||
<service> |
|
||||||
<serviceType>urn:schemas-upnp-org:service:WANPPPConnection:2</serviceType> |
|
||||||
<serviceId>urn:upnp-org:serviceId:WANIPConn1</serviceId> |
|
||||||
<controlURL>/87895a19/upnp/control/WANIPConn1</controlURL> |
|
||||||
<eventSubURL>/87895a19/upnp/control/WANIPConn1</eventSubURL> |
|
||||||
<SCPDURL>/87895a19/gateconnSCPD_PPP.xml</SCPDURL> |
|
||||||
</service> |
|
||||||
<service> |
|
||||||
<serviceType>urn:schemas-upnp-org:service:WANIPv6FirewallControl:1</serviceType> |
|
||||||
<serviceId>urn:upnp-org:serviceId:WANIPv6FwCtrl1</serviceId> |
|
||||||
<controlURL>/87895a19/upnp/control/WANIPv6FwCtrl1</controlURL> |
|
||||||
<eventSubURL>/87895a19/upnp/control/WANIPv6FwCtrl1</eventSubURL> |
|
||||||
<SCPDURL>/87895a19/wanipv6fwctrlSCPD.xml</SCPDURL> |
|
||||||
</service> |
|
||||||
</serviceList> |
|
||||||
</device> |
|
||||||
</deviceList> |
|
||||||
</device> |
|
||||||
</deviceList> |
|
||||||
</device> |
|
||||||
</root> |
|
||||||
@ -1,187 +0,0 @@ |
|||||||
/* $Id: testigddescparse.c,v 1.10 2015/08/06 09:55:24 nanard Exp $ */ |
|
||||||
/* Project : miniupnp
|
|
||||||
* http://miniupnp.free.fr/
|
|
||||||
* Author : Thomas Bernard |
|
||||||
* Copyright (c) 2008-2015 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 "igd_desc_parse.h" |
|
||||||
#include "minixml.h" |
|
||||||
#include "miniupnpc.h" |
|
||||||
|
|
||||||
/* count number of differences */ |
|
||||||
int compare_service(struct IGDdatas_service * s, FILE * f) |
|
||||||
{ |
|
||||||
int n = 0; |
|
||||||
char line[1024]; |
|
||||||
|
|
||||||
while(fgets(line, sizeof(line), f)) { |
|
||||||
char * value; |
|
||||||
char * equal; |
|
||||||
char * name; |
|
||||||
char * parsedvalue; |
|
||||||
int l; |
|
||||||
l = strlen(line); |
|
||||||
while((l > 0) && ((line[l-1] == '\r') || (line[l-1] == '\n') || (line[l-1] == ' '))) |
|
||||||
line[--l] = '\0'; |
|
||||||
if(l == 0) |
|
||||||
break; /* end on blank line */ |
|
||||||
if(line[0] == '#') |
|
||||||
continue; /* skip comments */ |
|
||||||
equal = strchr(line, '='); |
|
||||||
if(equal == NULL) { |
|
||||||
fprintf(stderr, "Warning, line does not contain '=' : %s\n", line); |
|
||||||
continue; |
|
||||||
} |
|
||||||
*equal = '\0'; |
|
||||||
name = line; |
|
||||||
while(*name == ' ' || *name == '\t') |
|
||||||
name++; |
|
||||||
l = strlen(name); |
|
||||||
while((l > 0) && (name[l-1] == ' ' || name[l-1] == '\t')) |
|
||||||
name[--l] = '\0'; |
|
||||||
value = equal + 1; |
|
||||||
while(*value == ' ' || *value == '\t') |
|
||||||
value++; |
|
||||||
if(strcmp(name, "controlurl") == 0) |
|
||||||
parsedvalue = s->controlurl; |
|
||||||
else if(strcmp(name, "eventsuburl") == 0) |
|
||||||
parsedvalue = s->eventsuburl; |
|
||||||
else if(strcmp(name, "scpdurl") == 0) |
|
||||||
parsedvalue = s->scpdurl; |
|
||||||
else if(strcmp(name, "servicetype") == 0) |
|
||||||
parsedvalue = s->servicetype; |
|
||||||
else { |
|
||||||
fprintf(stderr, "unknown field '%s'\n", name); |
|
||||||
continue; |
|
||||||
} |
|
||||||
if(0 != strcmp(parsedvalue, value)) { |
|
||||||
fprintf(stderr, "difference : '%s' != '%s'\n", parsedvalue, value); |
|
||||||
n++; |
|
||||||
} |
|
||||||
} |
|
||||||
return n; |
|
||||||
} |
|
||||||
|
|
||||||
int compare_igd(struct IGDdatas * p, FILE * f) |
|
||||||
{ |
|
||||||
int n = 0; |
|
||||||
char line[1024]; |
|
||||||
struct IGDdatas_service * s; |
|
||||||
|
|
||||||
while(fgets(line, sizeof(line), f)) { |
|
||||||
char * colon; |
|
||||||
int l = (int)strlen(line); |
|
||||||
while((l > 0) && (line[l-1] == '\r' || (line[l-1] == '\n'))) |
|
||||||
line[--l] = '\0'; |
|
||||||
if(l == 0 || line[0] == '#') |
|
||||||
continue; /* skip blank lines and comments */ |
|
||||||
colon = strchr(line, ':'); |
|
||||||
if(colon == NULL) { |
|
||||||
fprintf(stderr, "Warning, no ':' : %s\n", line); |
|
||||||
continue; |
|
||||||
} |
|
||||||
s = NULL; |
|
||||||
*colon = '\0'; |
|
||||||
if(strcmp(line, "CIF") == 0) |
|
||||||
s = &p->CIF; |
|
||||||
else if(strcmp(line, "first") == 0) |
|
||||||
s = &p->first; |
|
||||||
else if(strcmp(line, "second") == 0) |
|
||||||
s = &p->second; |
|
||||||
else if(strcmp(line, "IPv6FC") == 0) |
|
||||||
s = &p->IPv6FC; |
|
||||||
else { |
|
||||||
s = NULL; |
|
||||||
fprintf(stderr, "*** unknown service '%s' ***\n", line); |
|
||||||
n++; |
|
||||||
continue; |
|
||||||
} |
|
||||||
n += compare_service(s, f); |
|
||||||
} |
|
||||||
if(n > 0) |
|
||||||
fprintf(stderr, "*** %d difference%s ***\n", n, (n > 1) ? "s" : ""); |
|
||||||
return n; |
|
||||||
} |
|
||||||
|
|
||||||
int test_igd_desc_parse(char * buffer, int len, FILE * f) |
|
||||||
{ |
|
||||||
int n; |
|
||||||
struct IGDdatas igd; |
|
||||||
struct xmlparser parser; |
|
||||||
struct UPNPUrls urls; |
|
||||||
|
|
||||||
memset(&igd, 0, sizeof(struct IGDdatas)); |
|
||||||
memset(&parser, 0, sizeof(struct xmlparser)); |
|
||||||
parser.xmlstart = buffer; |
|
||||||
parser.xmlsize = len; |
|
||||||
parser.data = &igd; |
|
||||||
parser.starteltfunc = IGDstartelt; |
|
||||||
parser.endeltfunc = IGDendelt; |
|
||||||
parser.datafunc = IGDdata; |
|
||||||
parsexml(&parser); |
|
||||||
#ifdef DEBUG |
|
||||||
printIGD(&igd); |
|
||||||
#endif /* DEBUG */ |
|
||||||
GetUPNPUrls(&urls, &igd, "http://fake/desc/url/file.xml", 0); |
|
||||||
printf("ipcondescURL='%s'\n", urls.ipcondescURL); |
|
||||||
printf("controlURL='%s'\n", urls.controlURL); |
|
||||||
printf("controlURL_CIF='%s'\n", urls.controlURL_CIF); |
|
||||||
n = f ? compare_igd(&igd, f) : 0; |
|
||||||
FreeUPNPUrls(&urls); |
|
||||||
return n; |
|
||||||
} |
|
||||||
|
|
||||||
int main(int argc, char * * argv) |
|
||||||
{ |
|
||||||
FILE * f; |
|
||||||
char * buffer; |
|
||||||
int len; |
|
||||||
int r; |
|
||||||
if(argc<2) { |
|
||||||
fprintf(stderr, "Usage: %s file.xml [file.values]\n", argv[0]); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
f = fopen(argv[1], "r"); |
|
||||||
if(!f) { |
|
||||||
fprintf(stderr, "Cannot open %s for reading.\n", argv[1]); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
fseek(f, 0, SEEK_END); |
|
||||||
len = ftell(f); |
|
||||||
fseek(f, 0, SEEK_SET); |
|
||||||
buffer = malloc(len); |
|
||||||
if(!buffer) { |
|
||||||
fprintf(stderr, "Memory allocation error.\n"); |
|
||||||
fclose(f); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
r = (int)fread(buffer, 1, len, f); |
|
||||||
if(r != len) { |
|
||||||
fprintf(stderr, "Failed to read file %s. %d out of %d bytes.\n", |
|
||||||
argv[1], r, len); |
|
||||||
fclose(f); |
|
||||||
free(buffer); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
fclose(f); |
|
||||||
f = NULL; |
|
||||||
if(argc > 2) { |
|
||||||
f = fopen(argv[2], "r"); |
|
||||||
if(!f) { |
|
||||||
fprintf(stderr, "Cannot open %s for reading.\n", argv[2]); |
|
||||||
free(buffer); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
} |
|
||||||
r = test_igd_desc_parse(buffer, len, f); |
|
||||||
free(buffer); |
|
||||||
if(f) |
|
||||||
fclose(f); |
|
||||||
return r; |
|
||||||
} |
|
||||||
|
|
||||||
@ -1,55 +0,0 @@ |
|||||||
/* $Id: testminiwget.c,v 1.5 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. |
|
||||||
* */ |
|
||||||
#include <stdio.h> |
|
||||||
#include <stdlib.h> |
|
||||||
#include "miniwget.h" |
|
||||||
|
|
||||||
/**
|
|
||||||
* This program uses the miniwget / miniwget_getaddr function |
|
||||||
* from miniwget.c in order to retreive a web ressource using |
|
||||||
* a GET HTTP method, and store it in a file. |
|
||||||
*/ |
|
||||||
int main(int argc, char * * argv) |
|
||||||
{ |
|
||||||
void * data; |
|
||||||
int size, writtensize; |
|
||||||
FILE *f; |
|
||||||
char addr[64]; |
|
||||||
int status_code = -1; |
|
||||||
|
|
||||||
if(argc < 3) { |
|
||||||
fprintf(stderr, "Usage:\t%s url file\n", argv[0]); |
|
||||||
fprintf(stderr, "Example:\t%s http://www.google.com/ out.html\n", argv[0]); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
data = miniwget_getaddr(argv[1], &size, addr, sizeof(addr), 0, &status_code); |
|
||||||
if(!data || (status_code != 200)) { |
|
||||||
if(data) free(data); |
|
||||||
fprintf(stderr, "Error %d fetching %s\n", status_code, argv[1]); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
printf("local address : %s\n", addr); |
|
||||||
printf("got %d bytes\n", size); |
|
||||||
f = fopen(argv[2], "wb"); |
|
||||||
if(!f) { |
|
||||||
fprintf(stderr, "Cannot open file %s for writing\n", argv[2]); |
|
||||||
free(data); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
writtensize = fwrite(data, 1, size, f); |
|
||||||
if(writtensize != size) { |
|
||||||
fprintf(stderr, "Could only write %d bytes out of %d to %s\n", |
|
||||||
writtensize, size, argv[2]); |
|
||||||
} else { |
|
||||||
printf("%d bytes written to %s\n", writtensize, argv[2]); |
|
||||||
} |
|
||||||
fclose(f); |
|
||||||
free(data); |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
@ -1,96 +0,0 @@ |
|||||||
#!/bin/sh |
|
||||||
# $Id: testminiwget.sh,v 1.13 2015/09/03 17:57:44 nanard Exp $ |
|
||||||
# project miniupnp : http://miniupnp.free.fr/ |
|
||||||
# (c) 2011-2015 Thomas Bernard |
|
||||||
# |
|
||||||
# test program for miniwget.c |
|
||||||
# is usually invoked by "make check" |
|
||||||
# |
|
||||||
# This test program : |
|
||||||
# 1 - launches a local HTTP server (minihttptestserver) |
|
||||||
# 2 - uses testminiwget to retreive data from this server |
|
||||||
# 3 - compares served and received data |
|
||||||
# 4 - kills the local HTTP server and exits |
|
||||||
# |
|
||||||
# The script was tested and works with ksh, bash |
|
||||||
# it should now also run with dash |
|
||||||
|
|
||||||
TMPD=`mktemp -d -t miniwgetXXXXXXXXXX` |
|
||||||
HTTPSERVEROUT="${TMPD}/httpserverout" |
|
||||||
EXPECTEDFILE="${TMPD}/expectedfile" |
|
||||||
DOWNLOADEDFILE="${TMPD}/downloadedfile" |
|
||||||
PORT= |
|
||||||
RET=0 |
|
||||||
|
|
||||||
case "$HAVE_IPV6" in |
|
||||||
n|no|0) |
|
||||||
ADDR=localhost |
|
||||||
SERVERARGS="" |
|
||||||
;; |
|
||||||
*) |
|
||||||
ADDR="[::1]" |
|
||||||
SERVERARGS="-6" |
|
||||||
;; |
|
||||||
|
|
||||||
esac |
|
||||||
|
|
||||||
#make minihttptestserver |
|
||||||
#make testminiwget |
|
||||||
|
|
||||||
# launching the test HTTP server |
|
||||||
./minihttptestserver $SERVERARGS -e $EXPECTEDFILE > $HTTPSERVEROUT & |
|
||||||
SERVERPID=$! |
|
||||||
while [ -z "$PORT" ]; do |
|
||||||
sleep 1 |
|
||||||
PORT=`cat $HTTPSERVEROUT | sed 's/Listening on port \([0-9]*\)/\1/' ` |
|
||||||
done |
|
||||||
echo "Test HTTP server is listening on $PORT" |
|
||||||
|
|
||||||
URL1="http://$ADDR:$PORT/index.html" |
|
||||||
URL2="http://$ADDR:$PORT/chunked" |
|
||||||
URL3="http://$ADDR:$PORT/addcrap" |
|
||||||
|
|
||||||
echo "standard test ..." |
|
||||||
./testminiwget $URL1 "${DOWNLOADEDFILE}.1" |
|
||||||
if cmp $EXPECTEDFILE "${DOWNLOADEDFILE}.1" ; then |
|
||||||
echo "ok" |
|
||||||
else |
|
||||||
echo "standard test FAILED" |
|
||||||
RET=1 |
|
||||||
fi |
|
||||||
|
|
||||||
echo "chunked transfert encoding test ..." |
|
||||||
./testminiwget $URL2 "${DOWNLOADEDFILE}.2" |
|
||||||
if cmp $EXPECTEDFILE "${DOWNLOADEDFILE}.2" ; then |
|
||||||
echo "ok" |
|
||||||
else |
|
||||||
echo "chunked transfert encoding test FAILED" |
|
||||||
RET=1 |
|
||||||
fi |
|
||||||
|
|
||||||
echo "response too long test ..." |
|
||||||
./testminiwget $URL3 "${DOWNLOADEDFILE}.3" |
|
||||||
if cmp $EXPECTEDFILE "${DOWNLOADEDFILE}.3" ; then |
|
||||||
echo "ok" |
|
||||||
else |
|
||||||
echo "response too long test FAILED" |
|
||||||
RET=1 |
|
||||||
fi |
|
||||||
|
|
||||||
# kill the test HTTP server |
|
||||||
kill $SERVERPID |
|
||||||
wait $SERVERPID |
|
||||||
|
|
||||||
# remove temporary files (for success cases) |
|
||||||
if [ $RET -eq 0 ]; then |
|
||||||
rm -f "${DOWNLOADEDFILE}.1" |
|
||||||
rm -f "${DOWNLOADEDFILE}.2" |
|
||||||
rm -f "${DOWNLOADEDFILE}.3" |
|
||||||
rm -f $EXPECTEDFILE $HTTPSERVEROUT |
|
||||||
rmdir ${TMPD} |
|
||||||
else |
|
||||||
echo "at least one of the test FAILED" |
|
||||||
echo "directory ${TMPD} is left intact" |
|
||||||
fi |
|
||||||
exit $RET |
|
||||||
|
|
||||||
@ -1,89 +0,0 @@ |
|||||||
/* $Id: testminixml.c,v 1.10 2014/11/17 17:19:13 nanard Exp $
|
|
||||||
* MiniUPnP project |
|
||||||
* Website : http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
|
||||||
* Author : Thomas Bernard. |
|
||||||
* Copyright (c) 2005-2014 Thomas Bernard |
|
||||||
* |
|
||||||
* testminixml.c |
|
||||||
* test program for the "minixml" functions. |
|
||||||
*/ |
|
||||||
#include <stdlib.h> |
|
||||||
#include <stdio.h> |
|
||||||
#include <string.h> |
|
||||||
#include "minixml.h" |
|
||||||
#include "igd_desc_parse.h" |
|
||||||
|
|
||||||
/* ---------------------------------------------------------------------- */ |
|
||||||
void printeltname1(void * d, const char * name, int l) |
|
||||||
{ |
|
||||||
int i; |
|
||||||
(void)d; |
|
||||||
printf("element "); |
|
||||||
for(i=0;i<l;i++) |
|
||||||
putchar(name[i]); |
|
||||||
} |
|
||||||
void printeltname2(void * d, const char * name, int l) |
|
||||||
{ |
|
||||||
int i; |
|
||||||
(void)d; |
|
||||||
putchar('/'); |
|
||||||
for(i=0;i<l;i++) |
|
||||||
putchar(name[i]); |
|
||||||
putchar('\n'); |
|
||||||
} |
|
||||||
void printdata(void *d, const char * data, int l) |
|
||||||
{ |
|
||||||
int i; |
|
||||||
(void)d; |
|
||||||
printf("data : "); |
|
||||||
for(i=0;i<l;i++) |
|
||||||
putchar(data[i]); |
|
||||||
putchar('\n'); |
|
||||||
} |
|
||||||
|
|
||||||
void burptest(const char * buffer, int bufsize) |
|
||||||
{ |
|
||||||
struct IGDdatas data; |
|
||||||
struct xmlparser parser; |
|
||||||
/*objet IGDdatas */ |
|
||||||
memset(&data, 0, sizeof(struct IGDdatas)); |
|
||||||
/* objet xmlparser */ |
|
||||||
parser.xmlstart = buffer; |
|
||||||
parser.xmlsize = bufsize; |
|
||||||
parser.data = &data; |
|
||||||
/*parser.starteltfunc = printeltname1;
|
|
||||||
parser.endeltfunc = printeltname2; |
|
||||||
parser.datafunc = printdata; */ |
|
||||||
parser.starteltfunc = IGDstartelt; |
|
||||||
parser.endeltfunc = IGDendelt; |
|
||||||
parser.datafunc = IGDdata; |
|
||||||
parsexml(&parser); |
|
||||||
#ifdef DEBUG |
|
||||||
printIGD(&data); |
|
||||||
#endif /* DEBUG */ |
|
||||||
} |
|
||||||
|
|
||||||
/* ----- main ---- */ |
|
||||||
#define XML_MAX_SIZE (8192) |
|
||||||
int main(int argc, char * * argv) |
|
||||||
{ |
|
||||||
FILE * f; |
|
||||||
char buffer[XML_MAX_SIZE]; |
|
||||||
int bufsize; |
|
||||||
if(argc<2) |
|
||||||
{ |
|
||||||
printf("usage:\t%s file.xml\n", argv[0]); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
f = fopen(argv[1], "r"); |
|
||||||
if(!f) |
|
||||||
{ |
|
||||||
printf("cannot open file %s\n", argv[1]); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
bufsize = (int)fread(buffer, 1, XML_MAX_SIZE, f); |
|
||||||
fclose(f); |
|
||||||
burptest(buffer, bufsize); |
|
||||||
return 0; |
|
||||||
} |
|
||||||
|
|
||||||
@ -1,151 +0,0 @@ |
|||||||
/* $Id: testportlistingparse.c,v 1.2 2014/11/01 10:37:32 nanard Exp $ */ |
|
||||||
/* Project : miniupnp
|
|
||||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
|
||||||
* Author : Thomas Bernard |
|
||||||
* Copyright (c) 2014 Thomas Bernard |
|
||||||
* This software is subject to the conditions detailed in the |
|
||||||
* LICENCE file provided in this distribution. |
|
||||||
* */ |
|
||||||
|
|
||||||
#include <string.h> |
|
||||||
#include <stdio.h> |
|
||||||
#include "portlistingparse.h" |
|
||||||
|
|
||||||
struct port_mapping { |
|
||||||
unsigned int leasetime; |
|
||||||
unsigned short externalport; |
|
||||||
unsigned short internalport; |
|
||||||
const char * remotehost; |
|
||||||
const char * client; |
|
||||||
const char * proto; |
|
||||||
const char * desc; |
|
||||||
unsigned char enabled; |
|
||||||
}; |
|
||||||
|
|
||||||
/* return the number of differences */ |
|
||||||
int test(const char * portListingXml, int portListingXmlLen, |
|
||||||
const struct port_mapping * ref, int count) |
|
||||||
{ |
|
||||||
int i; |
|
||||||
int r = 0; |
|
||||||
struct PortMappingParserData data; |
|
||||||
struct PortMapping * pm; |
|
||||||
|
|
||||||
memset(&data, 0, sizeof(data)); |
|
||||||
ParsePortListing(portListingXml, portListingXmlLen, &data); |
|
||||||
for(i = 0, pm = data.l_head; |
|
||||||
(pm != NULL) && (i < count); |
|
||||||
i++, 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); |
|
||||||
if(0 != strcmp(pm->protocol, ref[i].proto)) { |
|
||||||
printf("protocol : '%s' != '%s'\n", pm->protocol, ref[i].proto); |
|
||||||
r++; |
|
||||||
} |
|
||||||
if(pm->externalPort != ref[i].externalport) { |
|
||||||
printf("externalPort : %hu != %hu\n", |
|
||||||
pm->externalPort, ref[i].externalport); |
|
||||||
r++; |
|
||||||
} |
|
||||||
if(0 != strcmp(pm->internalClient, ref[i].client)) { |
|
||||||
printf("client : '%s' != '%s'\n", |
|
||||||
pm->internalClient, ref[i].client); |
|
||||||
r++; |
|
||||||
} |
|
||||||
if(pm->internalPort != ref[i].internalport) { |
|
||||||
printf("internalPort : %hu != %hu\n", |
|
||||||
pm->internalPort, ref[i].internalport); |
|
||||||
r++; |
|
||||||
} |
|
||||||
if(0 != strcmp(pm->description, ref[i].desc)) { |
|
||||||
printf("description : '%s' != '%s'\n", |
|
||||||
pm->description, ref[i].desc); |
|
||||||
r++; |
|
||||||
} |
|
||||||
if(0 != strcmp(pm->remoteHost, ref[i].remotehost)) { |
|
||||||
printf("remoteHost : '%s' != '%s'\n", |
|
||||||
pm->remoteHost, ref[i].remotehost); |
|
||||||
r++; |
|
||||||
} |
|
||||||
if((unsigned)pm->leaseTime != ref[i].leasetime) { |
|
||||||
printf("leaseTime : %u != %u\n", |
|
||||||
(unsigned)pm->leaseTime, ref[i].leasetime); |
|
||||||
r++; |
|
||||||
} |
|
||||||
if(pm->enabled != ref[i].enabled) { |
|
||||||
printf("enabled : %d != %d\n", |
|
||||||
(int)pm->enabled, (int)ref[i].enabled); |
|
||||||
r++; |
|
||||||
} |
|
||||||
} |
|
||||||
if((i != count) || (pm != NULL)) { |
|
||||||
printf("count mismatch : i=%d count=%d pm=%p\n", i, count, pm); |
|
||||||
r++; |
|
||||||
} |
|
||||||
FreePortListing(&data); |
|
||||||
return r; |
|
||||||
} |
|
||||||
|
|
||||||
const char test_document[] = |
|
||||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" |
|
||||||
"<p:PortMappingList xmlns:p=\"urn:schemas-upnp-org:gw:WANIPConnection\"\n" |
|
||||||
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" \n" |
|
||||||
"xsi:schemaLocation=\"urn:schemas-upnp-org:gw:WANIPConnection " |
|
||||||
"http://www.upnp.org/schemas/gw/WANIPConnection-v2.xsd\">\n" |
|
||||||
" <p:PortMappingEntry>\n" |
|
||||||
" <p:NewRemoteHost></p:NewRemoteHost>\n" |
|
||||||
" <p:NewExternalPort>5002</p:NewExternalPort>\n" |
|
||||||
" <p:NewProtocol>UDP</p:NewProtocol>\n" |
|
||||||
" <p:NewInternalPort>4001</p:NewInternalPort>\n" |
|
||||||
" <p:NewInternalClient>192.168.1.123</p:NewInternalClient>\n" |
|
||||||
" <p:NewEnabled>1</p:NewEnabled>\n" |
|
||||||
" <p:NewDescription>xxx</p:NewDescription>\n" |
|
||||||
" <p:NewLeaseTime>0</p:NewLeaseTime>\n" |
|
||||||
" </p:PortMappingEntry>\n" |
|
||||||
" <p:PortMappingEntry>\n" |
|
||||||
" <p:NewRemoteHost>202.233.2.1</p:NewRemoteHost>\n" |
|
||||||
" <p:NewExternalPort>2345</p:NewExternalPort>\n" |
|
||||||
" <p:NewProtocol>TCP</p:NewProtocol>\n" |
|
||||||
" <p:NewInternalPort>2349</p:NewInternalPort>\n" |
|
||||||
" <p:NewInternalClient>192.168.1.137</p:NewInternalClient>\n" |
|
||||||
" <p:NewEnabled>1</p:NewEnabled>\n" |
|
||||||
" <p:NewDescription>dooom</p:NewDescription>\n" |
|
||||||
" <p:NewLeaseTime>346</p:NewLeaseTime>\n" |
|
||||||
" </p:PortMappingEntry>\n" |
|
||||||
" <p:PortMappingEntry>\n" |
|
||||||
" <p:NewRemoteHost>134.231.2.11</p:NewRemoteHost>\n" |
|
||||||
" <p:NewExternalPort>12345</p:NewExternalPort>\n" |
|
||||||
" <p:NewProtocol>TCP</p:NewProtocol>\n" |
|
||||||
" <p:NewInternalPort>12345</p:NewInternalPort>\n" |
|
||||||
" <p:NewInternalClient>192.168.1.137</p:NewInternalClient>\n" |
|
||||||
" <p:NewEnabled>1</p:NewEnabled>\n" |
|
||||||
" <p:NewDescription>dooom A</p:NewDescription>\n" |
|
||||||
" <p:NewLeaseTime>347</p:NewLeaseTime>\n" |
|
||||||
" </p:PortMappingEntry>\n" |
|
||||||
"</p:PortMappingList>"; |
|
||||||
|
|
||||||
#define PORT_MAPPINGS_COUNT 3 |
|
||||||
const struct port_mapping port_mappings[PORT_MAPPINGS_COUNT] = { |
|
||||||
{347, 12345, 12345, "134.231.2.11", "192.168.1.137", "TCP", "dooom A", 1}, |
|
||||||
{346, 2345, 2349, "202.233.2.1", "192.168.1.137", "TCP", "dooom", 1}, |
|
||||||
{0, 5002, 4001, "", "192.168.1.123", "UDP", "xxx", 1} |
|
||||||
}; |
|
||||||
|
|
||||||
/* --- main --- */ |
|
||||||
int main(void) |
|
||||||
{ |
|
||||||
int r; |
|
||||||
r = test(test_document, sizeof(test_document) - 1, |
|
||||||
port_mappings, PORT_MAPPINGS_COUNT); |
|
||||||
if(r == 0) { |
|
||||||
printf("test of portlistingparse OK\n"); |
|
||||||
return 0; |
|
||||||
} else { |
|
||||||
printf("test FAILED (%d differences counted)\n", r); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
@ -1,3 +0,0 @@ |
|||||||
NewRemoteHost= |
|
||||||
NewExternalPort=123 |
|
||||||
NewProtocol=TCP |
|
||||||
@ -1,6 +0,0 @@ |
|||||||
<?xml version="1.0"?> |
|
||||||
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:DeletePortMapping xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"><NewRemoteHost></NewRemoteHost><NewExternalPort>123</NewExternalPort> |
|
||||||
<NewProtocol>TCP</NewProtocol></u:DeletePortMapping></s:Body> |
|
||||||
|
|
||||||
</s:Envelope> |
|
||||||
|
|
||||||
@ -1,2 +0,0 @@ |
|||||||
NewExternalIPAddress=1.2.3.4 |
|
||||||
|
|
||||||
@ -1,2 +0,0 @@ |
|||||||
<?xml version="1.0"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:GetExternalIPAddressResponse xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"><NewExternalIPAddress>1.2.3.4</NewExternalIPAddress></u:GetExternalIPAddressResponse></s:Body></s:Envelope> |
|
||||||
|
|
||||||
@ -1,3 +0,0 @@ |
|||||||
NewProtocol=UDP |
|
||||||
NewExternalPort=12345 |
|
||||||
NewRemoteHost= |
|
||||||
@ -1,3 +0,0 @@ |
|||||||
<?xml version="1.0"?> |
|
||||||
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:GetSpecificPortMappingEntry xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"><NewRemoteHost></NewRemoteHost><NewExternalPort>12345</NewExternalPort><NewProtocol>UDP</NewProtocol></u:GetSpecificPortMappingEntry></s:Body></s:Envelope> |
|
||||||
|
|
||||||
@ -1,5 +0,0 @@ |
|||||||
NewInternalPort=12345 |
|
||||||
NewInternalClient=192.168.10.110 |
|
||||||
NewEnabled=1 |
|
||||||
NewPortMappingDescription=libminiupnpc |
|
||||||
NewLeaseDuration=0 |
|
||||||
@ -1,2 +0,0 @@ |
|||||||
<?xml version="1.0"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:GetSpecificPortMappingEntryResponse xmlns:u="urn:schemas-upnp-org:service:WANIPConnection:1"><NewInternalPort>12345</NewInternalPort><NewInternalClient>192.168.10.110</NewInternalClient><NewEnabled>1</NewEnabled><NewPortMappingDescription>libminiupnpc</NewPortMappingDescription><NewLeaseDuration>0</NewLeaseDuration></u:GetSpecificPortMappingEntryResponse></s:Body></s:Envelope> |
|
||||||
|
|
||||||
@ -1 +0,0 @@ |
|||||||
NewDefaultConnectionService=uuid:c6c05a33-f704-48df-9910-e099b3471d81:WANConnectionDevice:1,INVALID_SERVICE_ID |
|
||||||
@ -1 +0,0 @@ |
|||||||
<?xml version="1.0" encoding="utf-8"?><s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><u:SetDefaultConnectionService xmlns:u="urn:schemas-upnp-org:service:Layer3Forwarding:1"><NewDefaultConnectionService>uuid:c6c05a33-f704-48df-9910-e099b3471d81:WANConnectionDevice:1,INVALID_SERVICE_ID</NewDefaultConnectionService></u:SetDefaultConnectionService></s:Body></s:Envelope> |
|
||||||
@ -1,7 +0,0 @@ |
|||||||
This directory contains files used for validation of upnpreplyparse.c code. |
|
||||||
|
|
||||||
Each .xml file to parse should give the results which are in the .namevalue |
|
||||||
file. |
|
||||||
|
|
||||||
A .namevalue file contain name=value lines. |
|
||||||
|
|
||||||
@ -1,84 +0,0 @@ |
|||||||
#! /usr/bin/python |
|
||||||
# $Id: testupnpigd.py,v 1.4 2008/10/11 10:27:20 nanard Exp $ |
|
||||||
# MiniUPnP project |
|
||||||
# Author : Thomas Bernard |
|
||||||
# This Sample code is public domain. |
|
||||||
# website : http://miniupnp.tuxfamily.org/ |
|
||||||
|
|
||||||
# import the python miniupnpc module |
|
||||||
import miniupnpc |
|
||||||
import socket |
|
||||||
import BaseHTTPServer |
|
||||||
|
|
||||||
# function definition |
|
||||||
def list_redirections(): |
|
||||||
i = 0 |
|
||||||
while True: |
|
||||||
p = u.getgenericportmapping(i) |
|
||||||
if p==None: |
|
||||||
break |
|
||||||
print i, p |
|
||||||
i = i + 1 |
|
||||||
|
|
||||||
#define the handler class for HTTP connections |
|
||||||
class handler_class(BaseHTTPServer.BaseHTTPRequestHandler): |
|
||||||
def do_GET(self): |
|
||||||
self.send_response(200) |
|
||||||
self.end_headers() |
|
||||||
self.wfile.write("OK MON GARS") |
|
||||||
|
|
||||||
# create the object |
|
||||||
u = miniupnpc.UPnP() |
|
||||||
#print 'inital(default) values :' |
|
||||||
#print ' discoverdelay', u.discoverdelay |
|
||||||
#print ' lanaddr', u.lanaddr |
|
||||||
#print ' multicastif', u.multicastif |
|
||||||
#print ' minissdpdsocket', u.minissdpdsocket |
|
||||||
u.discoverdelay = 200; |
|
||||||
|
|
||||||
try: |
|
||||||
print 'Discovering... delay=%ums' % u.discoverdelay |
|
||||||
ndevices = u.discover() |
|
||||||
print ndevices, 'device(s) detected' |
|
||||||
|
|
||||||
# select an igd |
|
||||||
u.selectigd() |
|
||||||
# display information about the IGD and the internet connection |
|
||||||
print 'local ip address :', u.lanaddr |
|
||||||
externalipaddress = u.externalipaddress() |
|
||||||
print 'external ip address :', externalipaddress |
|
||||||
print u.statusinfo(), u.connectiontype() |
|
||||||
|
|
||||||
#instanciate a HTTPd object. The port is assigned by the system. |
|
||||||
httpd = BaseHTTPServer.HTTPServer((u.lanaddr, 0), handler_class) |
|
||||||
eport = httpd.server_port |
|
||||||
|
|
||||||
# find a free port for the redirection |
|
||||||
r = u.getspecificportmapping(eport, 'TCP') |
|
||||||
while r != None and eport < 65536: |
|
||||||
eport = eport + 1 |
|
||||||
r = u.getspecificportmapping(eport, 'TCP') |
|
||||||
|
|
||||||
print 'trying to redirect %s port %u TCP => %s port %u TCP' % (externalipaddress, eport, u.lanaddr, httpd.server_port) |
|
||||||
|
|
||||||
b = u.addportmapping(eport, 'TCP', u.lanaddr, httpd.server_port, |
|
||||||
'UPnP IGD Tester port %u' % eport, '') |
|
||||||
if b: |
|
||||||
print 'Success. Now waiting for some HTTP request on http://%s:%u' % (externalipaddress ,eport) |
|
||||||
try: |
|
||||||
httpd.handle_request() |
|
||||||
httpd.server_close() |
|
||||||
except KeyboardInterrupt, details: |
|
||||||
print "CTRL-C exception!", details |
|
||||||
b = u.deleteportmapping(eport, 'TCP') |
|
||||||
if b: |
|
||||||
print 'Successfully deleted port mapping' |
|
||||||
else: |
|
||||||
print 'Failed to remove port mapping' |
|
||||||
else: |
|
||||||
print 'Failed' |
|
||||||
|
|
||||||
httpd.server_close() |
|
||||||
|
|
||||||
except Exception, e: |
|
||||||
print 'Exception :', e |
|
||||||
@ -1,96 +0,0 @@ |
|||||||
/* $Id: testupnpreplyparse.c,v 1.4 2014/01/27 11:45:19 nanard Exp $ */ |
|
||||||
/* MiniUPnP project
|
|
||||||
* http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
|
|
||||||
* (c) 2006-2014 Thomas Bernard |
|
||||||
* This software is subject to the conditions detailed |
|
||||||
* in the LICENCE file provided within the distribution */ |
|
||||||
#include <stdio.h> |
|
||||||
#include <string.h> |
|
||||||
#include <stdlib.h> |
|
||||||
#include "upnpreplyparse.h" |
|
||||||
|
|
||||||
int |
|
||||||
test_parsing(const char * buf, int len, FILE * f) |
|
||||||
{ |
|
||||||
char line[1024]; |
|
||||||
struct NameValueParserData pdata; |
|
||||||
int ok = 1; |
|
||||||
ParseNameValue(buf, len, &pdata); |
|
||||||
/* check result */ |
|
||||||
if(f != NULL) |
|
||||||
{ |
|
||||||
while(fgets(line, sizeof(line), f)) |
|
||||||
{ |
|
||||||
char * value; |
|
||||||
char * equal; |
|
||||||
char * parsedvalue; |
|
||||||
int l; |
|
||||||
l = strlen(line); |
|
||||||
while((l > 0) && ((line[l-1] == '\r') || (line[l-1] == '\n'))) |
|
||||||
line[--l] = '\0'; |
|
||||||
/* skip empty lines */ |
|
||||||
if(l == 0) |
|
||||||
continue; |
|
||||||
equal = strchr(line, '='); |
|
||||||
if(equal == NULL) |
|
||||||
{ |
|
||||||
fprintf(stderr, "Warning, line does not contain '=' : %s\n", line); |
|
||||||
continue; |
|
||||||
} |
|
||||||
*equal = '\0'; |
|
||||||
value = equal + 1; |
|
||||||
parsedvalue = GetValueFromNameValueList(&pdata, line); |
|
||||||
if((parsedvalue == NULL) || (strcmp(parsedvalue, value) != 0)) |
|
||||||
{ |
|
||||||
fprintf(stderr, "Element <%s> : expecting value '%s', got '%s'\n", |
|
||||||
line, value, parsedvalue ? parsedvalue : "<null string>"); |
|
||||||
ok = 0; |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
ClearNameValueList(&pdata); |
|
||||||
return ok; |
|
||||||
} |
|
||||||
|
|
||||||
int main(int argc, char * * argv) |
|
||||||
{ |
|
||||||
FILE * f; |
|
||||||
char buffer[4096]; |
|
||||||
int l; |
|
||||||
int ok; |
|
||||||
|
|
||||||
if(argc<2) |
|
||||||
{ |
|
||||||
fprintf(stderr, "Usage: %s file.xml [file.namevalues]\n", argv[0]); |
|
||||||
return 1; |
|
||||||
} |
|
||||||
f = fopen(argv[1], "r"); |
|
||||||
if(!f) |
|
||||||
{ |
|
||||||
fprintf(stderr, "Error : can not open file %s\n", argv[1]); |
|
||||||
return 2; |
|
||||||
} |
|
||||||
l = fread(buffer, 1, sizeof(buffer)-1, f); |
|
||||||
fclose(f); |
|
||||||
f = NULL; |
|
||||||
buffer[l] = '\0'; |
|
||||||
if(argc > 2) |
|
||||||
{ |
|
||||||
f = fopen(argv[2], "r"); |
|
||||||
if(!f) |
|
||||||
{ |
|
||||||
fprintf(stderr, "Error : can not open file %s\n", argv[2]); |
|
||||||
return 2; |
|
||||||
} |
|
||||||
} |
|
||||||
#ifdef DEBUG |
|
||||||
DisplayNameValueList(buffer, l); |
|
||||||
#endif |
|
||||||
ok = test_parsing(buffer, l, f); |
|
||||||
if(f) |
|
||||||
{ |
|
||||||
fclose(f); |
|
||||||
} |
|
||||||
return ok ? 0 : 3; |
|
||||||
} |
|
||||||
|
|
||||||
@ -1,14 +0,0 @@ |
|||||||
#!/bin/sh |
|
||||||
|
|
||||||
for f in testreplyparse/*.xml ; do |
|
||||||
bf="`dirname $f`/`basename $f .xml`" |
|
||||||
if ./testupnpreplyparse $f $bf.namevalue ; then |
|
||||||
echo "$f : passed" |
|
||||||
else |
|
||||||
echo "$f : FAILED" |
|
||||||
exit 1 |
|
||||||
fi |
|
||||||
done |
|
||||||
|
|
||||||
exit 0 |
|
||||||
|
|
||||||
Loading…
Reference in new issue