mupnp 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/ext/miniupnpc.h ADDED
@@ -0,0 +1,108 @@
1
+ /* $Id: miniupnpc.h,v 1.17 2007/12/19 14:58:54 nanard Exp $ */
2
+ /* Project: miniupnp
3
+ * http://miniupnp.free.fr/
4
+ * Author: Thomas Bernard
5
+ * Copyright (c) 2005-2006 Thomas Bernard
6
+ * This software is subjects to the conditions detailed
7
+ * in the LICENCE file provided within this distribution */
8
+ #ifndef __MINIUPNPC_H__
9
+ #define __MINIUPNPC_H__
10
+
11
+ #include "declspec.h"
12
+ #include "igd_desc_parse.h"
13
+
14
+ #ifdef __cplusplus
15
+ extern "C" {
16
+ #endif
17
+
18
+ /* Structures definitions : */
19
+ struct UPNParg { char * elt; char * val; };
20
+
21
+ int simpleUPnPcommand(int, const char *, const char *,
22
+ const char *, struct UPNParg *,
23
+ char *, int *);
24
+
25
+ struct UPNPDev {
26
+ struct UPNPDev * pNext;
27
+ char * descURL;
28
+ char * st;
29
+ char buffer[2];
30
+ };
31
+
32
+ /* upnpDiscover()
33
+ * discover UPnP devices on the network.
34
+ * The discovered devices are returned as a chained list.
35
+ * It is up to the caller to free the list with freeUPNPDevlist().
36
+ * delay (in millisecond) is the maximum time for waiting any device
37
+ * response.
38
+ * If available, device list will be obtained from MiniSSDPd.
39
+ * Default path for minissdpd socket will be used if minissdpdsock argument
40
+ * is NULL.
41
+ * If multicastif is not NULL, it will be used instead of the default
42
+ * multicast interface for sending SSDP discover packets. */
43
+ LIBSPEC struct UPNPDev * upnpDiscover(int delay, const char * multicastif,
44
+ const char * minissdpdsock);
45
+ /* freeUPNPDevlist()
46
+ * free list returned by upnpDiscover() */
47
+ LIBSPEC void freeUPNPDevlist(struct UPNPDev * devlist);
48
+
49
+ /* parserootdesc() :
50
+ * parse root XML description of a UPnP device and fill the IGDdatas
51
+ * structure. */
52
+ LIBSPEC void parserootdesc(const char *, int, struct IGDdatas *);
53
+
54
+ /* structure used to get fast access to urls
55
+ * controlURL: controlURL of the WANIPConnection
56
+ * ipcondescURL: url of the description of the WANIPConnection
57
+ * controlURL_CIF: controlURL of the WANCommonInterfaceConfig
58
+ */
59
+ struct UPNPUrls {
60
+ char * controlURL;
61
+ char * ipcondescURL;
62
+ char * controlURL_CIF;
63
+ };
64
+
65
+ /* UPNP_GetValidIGD() :
66
+ * return values :
67
+ * 0 = NO IGD found
68
+ * 1 = A valid connected IGD has been found
69
+ * 2 = A valid IGD has been found but it reported as
70
+ * not connected
71
+ * 3 = an UPnP device has been found but was not recognized as an IGD
72
+ *
73
+ * In any non zero return case, the urls and data structures
74
+ * passed as parameters are set. Donc forget to call FreeUPNPUrls(urls) to
75
+ * free allocated memory.
76
+ */
77
+ LIBSPEC int
78
+ UPNP_GetValidIGD(struct UPNPDev * devlist,
79
+ struct UPNPUrls * urls,
80
+ struct IGDdatas * data,
81
+ char * lanaddr, int lanaddrlen);
82
+
83
+ /* UPNP_GetIGDFromUrl()
84
+ * Used when skipping the discovery process.
85
+ * return value :
86
+ * 0 - Not ok
87
+ * 1 - OK */
88
+ LIBSPEC int
89
+ UPNP_GetIGDFromUrl(const char * rootdescurl,
90
+ struct UPNPUrls * urls,
91
+ struct IGDdatas * data,
92
+ char * lanaddr, int lanaddrlen);
93
+
94
+ LIBSPEC void GetUPNPUrls(struct UPNPUrls *, struct IGDdatas *, const char *);
95
+
96
+ LIBSPEC void FreeUPNPUrls(struct UPNPUrls *);
97
+
98
+ /* Reads data from the specified socket.
99
+ * Returns the number of bytes read if successful, zero if no bytes were
100
+ * read or if we timed out. Returns negative if there was an error. */
101
+ int ReceiveData(int socket, char * data, int length, int timeout);
102
+
103
+ #ifdef __cplusplus
104
+ }
105
+ #endif
106
+
107
+ #endif
108
+
data/ext/miniwget.c ADDED
@@ -0,0 +1,219 @@
1
+ /* $Id: miniwget.c,v 1.19 2007/11/02 14:16:19 nanard Exp $ */
2
+ /* Project : miniupnp
3
+ * Author : Thomas Bernard
4
+ * Copyright (c) 2005 Thomas Bernard
5
+ * This software is subject to the conditions detailed in the
6
+ * LICENCE file provided in this distribution.
7
+ * */
8
+ #include <stdio.h>
9
+ #include <stdlib.h>
10
+ #include <string.h>
11
+ #include "miniupnpc.h"
12
+ #ifdef WIN32
13
+ #include <winsock2.h>
14
+ #include <io.h>
15
+ #define MAXHOSTNAMELEN 64
16
+ #define MIN(x,y) (((x)<(y))?(x):(y))
17
+ #define snprintf _snprintf
18
+ #define herror
19
+ #define socklen_t int
20
+ #else
21
+ #include <unistd.h>
22
+ #include <sys/param.h>
23
+ #include <sys/socket.h>
24
+ #include <netdb.h>
25
+ #include <netinet/in.h>
26
+ #include <arpa/inet.h>
27
+ #define closesocket close
28
+ #endif
29
+ /* for MIN() macro : */
30
+ #if defined(__sun) || defined(sun)
31
+ #include <utility.h>
32
+ #endif
33
+
34
+ /* miniwget2() :
35
+ * */
36
+ static void *
37
+ miniwget2(const char * url, const char * host,
38
+ unsigned short port, const char * path,
39
+ int * size, char * addr_str, int addr_str_len)
40
+ {
41
+ char buf[2048];
42
+ int s;
43
+ struct sockaddr_in dest;
44
+ struct hostent *hp;
45
+ *size = 0;
46
+ hp = gethostbyname(host);
47
+ if(hp==NULL)
48
+ {
49
+ herror(host);
50
+ return NULL;
51
+ }
52
+ /* memcpy((char *)&dest.sin_addr, hp->h_addr, hp->h_length); */
53
+ memcpy(&dest.sin_addr, hp->h_addr, sizeof(dest.sin_addr));
54
+ memset(dest.sin_zero, 0, sizeof(dest.sin_zero));
55
+ s = socket(PF_INET, SOCK_STREAM, 0);
56
+ if(s < 0)
57
+ {
58
+ perror("socket");
59
+ return NULL;
60
+ }
61
+ dest.sin_family = AF_INET;
62
+ dest.sin_port = htons(port);
63
+ if(connect(s, (struct sockaddr *)&dest, sizeof(struct sockaddr_in))<0)
64
+ {
65
+ perror("connect");
66
+ closesocket(s);
67
+ return NULL;
68
+ }
69
+
70
+ /* get address for caller ! */
71
+ if(addr_str)
72
+ {
73
+ struct sockaddr_in saddr;
74
+ socklen_t len;
75
+
76
+ len = sizeof(saddr);
77
+ getsockname(s, (struct sockaddr *)&saddr, &len);
78
+ #ifndef WIN32
79
+ inet_ntop(AF_INET, &saddr.sin_addr, addr_str, addr_str_len);
80
+ #else
81
+ /* using INT WINAPI WSAAddressToStringA(LPSOCKADDR, DWORD, LPWSAPROTOCOL_INFOA, LPSTR, LPDWORD);
82
+ * But his function make a string with the port : nn.nn.nn.nn:port */
83
+ /* if(WSAAddressToStringA((SOCKADDR *)&saddr, sizeof(saddr),
84
+ NULL, addr_str, (DWORD *)&addr_str_len))
85
+ {
86
+ printf("WSAAddressToStringA() failed : %d\n", WSAGetLastError());
87
+ }*/
88
+ strncpy(addr_str, inet_ntoa(saddr.sin_addr), addr_str_len);
89
+ #endif
90
+ #ifdef DEBUG
91
+ printf("address miniwget : %s\n", addr_str);
92
+ #endif
93
+ }
94
+
95
+ snprintf(buf, sizeof(buf),
96
+ "GET %s HTTP/1.1\r\n"
97
+ "Host: %s:%d\r\n"
98
+ "Connection: Close\r\n"
99
+ "\r\n",
100
+ path, host, port);
101
+ /*write(s, buf, strlen(buf));*/
102
+ send(s, buf, strlen(buf), 0);
103
+ {
104
+ int n, headers=1;
105
+ char * respbuffer = NULL;
106
+ int allreadyread = 0;
107
+ /*while((n = recv(s, buf, 2048, 0)) > 0)*/
108
+ while((n = ReceiveData(s, buf, 2048, 5000)) > 0)
109
+ {
110
+ if(headers)
111
+ {
112
+ int i=0;
113
+ while(i<n-3)
114
+ {
115
+ if(buf[i]=='\r' && buf[i+1]=='\n'
116
+ && buf[i+2]=='\r' && buf[i+3]=='\n')
117
+ {
118
+ headers = 0; /* end */
119
+ if(i<n-4)
120
+ {
121
+ respbuffer = (char *)realloc((void *)respbuffer,
122
+ allreadyread+(n-i-4));
123
+ memcpy(respbuffer+allreadyread, buf + i + 4, n-i-4);
124
+ allreadyread += (n-i-4);
125
+ }
126
+ break;
127
+ }
128
+ i++;
129
+ }
130
+ }
131
+ else
132
+ {
133
+ respbuffer = (char *)realloc((void *)respbuffer,
134
+ allreadyread+n);
135
+ memcpy(respbuffer+allreadyread, buf, n);
136
+ allreadyread += n;
137
+ }
138
+ }
139
+ *size = allreadyread;
140
+ #ifndef NDEBUG
141
+ printf("%d bytes read\n", *size);
142
+ #endif
143
+ closesocket(s);
144
+ return respbuffer;
145
+ }
146
+ }
147
+
148
+ /* parseURL()
149
+ * arguments :
150
+ * url : source string not modified
151
+ * hostname : hostname destination string (size of MAXHOSTNAMELEN+1)
152
+ * port : port (destination)
153
+ * path : pointer to the path part of the URL
154
+ *
155
+ * Return values :
156
+ * 0 - Failure
157
+ * 1 - Success */
158
+ int parseURL(const char * url, char * hostname, unsigned short * port, char * * path)
159
+ {
160
+ char * p1, *p2, *p3;
161
+ p1 = strstr(url, "://");
162
+ if(!p1)
163
+ return 0;
164
+ p1 += 3;
165
+ if( (url[0]!='h') || (url[1]!='t')
166
+ ||(url[2]!='t') || (url[3]!='p'))
167
+ return 0;
168
+ p2 = strchr(p1, ':');
169
+ p3 = strchr(p1, '/');
170
+ if(!p3)
171
+ return 0;
172
+ memset(hostname, 0, MAXHOSTNAMELEN + 1);
173
+ if(!p2 || (p2>p3))
174
+ {
175
+ strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p3-p1)));
176
+ *port = 80;
177
+ }
178
+ else
179
+ {
180
+ strncpy(hostname, p1, MIN(MAXHOSTNAMELEN, (int)(p2-p1)));
181
+ *port = 0;
182
+ p2++;
183
+ while( (*p2 >= '0') && (*p2 <= '9'))
184
+ {
185
+ *port *= 10;
186
+ *port += (unsigned short)(*p2 - '0');
187
+ p2++;
188
+ }
189
+ }
190
+ *path = p3;
191
+ return 1;
192
+ }
193
+
194
+ void * miniwget(const char * url, int * size)
195
+ {
196
+ unsigned short port;
197
+ char * path;
198
+ /* protocol://host:port/chemin */
199
+ char hostname[MAXHOSTNAMELEN+1];
200
+ *size = 0;
201
+ if(!parseURL(url, hostname, &port, &path))
202
+ return NULL;
203
+ return miniwget2(url, hostname, port, path, size, 0, 0);
204
+ }
205
+
206
+ void * miniwget_getaddr(const char * url, int * size, char * addr, int addrlen)
207
+ {
208
+ unsigned short port;
209
+ char * path;
210
+ /* protocol://host:port/chemin */
211
+ char hostname[MAXHOSTNAMELEN+1];
212
+ *size = 0;
213
+ if(addr)
214
+ addr[0] = '\0';
215
+ if(!parseURL(url, hostname, &port, &path))
216
+ return NULL;
217
+ return miniwget2(url, hostname, port, path, size, addr, addrlen);
218
+ }
219
+
data/ext/miniwget.h ADDED
@@ -0,0 +1,28 @@
1
+ /* $Id: miniwget.h,v 1.5 2007/01/29 20:27:23 nanard Exp $ */
2
+ /* Project : miniupnp
3
+ * Author : Thomas Bernard
4
+ * Copyright (c) 2005 Thomas Bernard
5
+ * This software is subject to the conditions detailed in the
6
+ * LICENCE file provided in this distribution.
7
+ * */
8
+ #ifndef __MINIWGET_H__
9
+ #define __MINIWGET_H__
10
+
11
+ #include "declspec.h"
12
+
13
+ #ifdef __cplusplus
14
+ extern "C" {
15
+ #endif
16
+
17
+ LIBSPEC void * miniwget(const char *, int *);
18
+
19
+ LIBSPEC void * miniwget_getaddr(const char *, int *, char *, int);
20
+
21
+ int parseURL(const char *, char *, unsigned short *, char * *);
22
+
23
+ #ifdef __cplusplus
24
+ }
25
+ #endif
26
+
27
+ #endif
28
+
data/ext/minixml.c ADDED
@@ -0,0 +1,191 @@
1
+ /* $Id: minixml.c,v 1.6 2007/05/15 18:14:08 nanard Exp $ */
2
+ /* minixml.c : the minimum size a xml parser can be ! */
3
+ /* Project : miniupnp
4
+ * webpage: http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
5
+ * Author : Thomas Bernard
6
+
7
+ Copyright (c) 2005-2007, Thomas BERNARD
8
+ All rights reserved.
9
+
10
+ Redistribution and use in source and binary forms, with or without
11
+ modification, are permitted provided that the following conditions are met:
12
+
13
+ * Redistributions of source code must retain the above copyright notice,
14
+ this list of conditions and the following disclaimer.
15
+ * Redistributions in binary form must reproduce the above copyright notice,
16
+ this list of conditions and the following disclaimer in the documentation
17
+ and/or other materials provided with the distribution.
18
+ * The name of the author may not be used to endorse or promote products
19
+ derived from this software without specific prior written permission.
20
+
21
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22
+ AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
25
+ LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31
+ POSSIBILITY OF SUCH DAMAGE.
32
+ */
33
+ #include "minixml.h"
34
+
35
+ /* parseatt : used to parse the argument list
36
+ * return 0 (false) in case of success and -1 (true) if the end
37
+ * of the xmlbuffer is reached. */
38
+ int parseatt(struct xmlparser * p)
39
+ {
40
+ const char * attname;
41
+ int attnamelen;
42
+ const char * attvalue;
43
+ int attvaluelen;
44
+ while(p->xml < p->xmlend)
45
+ {
46
+ if(*p->xml=='/' || *p->xml=='>')
47
+ return 0;
48
+ if( !IS_WHITE_SPACE(*p->xml) )
49
+ {
50
+ char sep;
51
+ attname = p->xml;
52
+ attnamelen = 0;
53
+ while(*p->xml!='=' && !IS_WHITE_SPACE(*p->xml) )
54
+ {
55
+ attnamelen++; p->xml++;
56
+ if(p->xml >= p->xmlend)
57
+ return -1;
58
+ }
59
+ while(*(p->xml++) != '=')
60
+ {
61
+ if(p->xml >= p->xmlend)
62
+ return -1;
63
+ }
64
+ while(IS_WHITE_SPACE(*p->xml))
65
+ {
66
+ p->xml++;
67
+ if(p->xml >= p->xmlend)
68
+ return -1;
69
+ }
70
+ sep = *p->xml;
71
+ if(sep=='\'' || sep=='\"')
72
+ {
73
+ p->xml++;
74
+ if(p->xml >= p->xmlend)
75
+ return -1;
76
+ attvalue = p->xml;
77
+ attvaluelen = 0;
78
+ while(*p->xml != sep)
79
+ {
80
+ attvaluelen++; p->xml++;
81
+ if(p->xml >= p->xmlend)
82
+ return -1;
83
+ }
84
+ }
85
+ else
86
+ {
87
+ attvalue = p->xml;
88
+ attvaluelen = 0;
89
+ while( !IS_WHITE_SPACE(*p->xml)
90
+ && *p->xml != '>' && *p->xml != '/')
91
+ {
92
+ attvaluelen++; p->xml++;
93
+ if(p->xml >= p->xmlend)
94
+ return -1;
95
+ }
96
+ }
97
+ /*printf("%.*s='%.*s'\n",
98
+ attnamelen, attname, attvaluelen, attvalue);*/
99
+ if(p->attfunc)
100
+ p->attfunc(p->data, attname, attnamelen, attvalue, attvaluelen);
101
+ }
102
+ p->xml++;
103
+ }
104
+ return -1;
105
+ }
106
+
107
+ /* parseelt parse the xml stream and
108
+ * call the callback functions when needed... */
109
+ void parseelt(struct xmlparser * p)
110
+ {
111
+ int i;
112
+ const char * elementname;
113
+ while(p->xml < (p->xmlend - 1))
114
+ {
115
+ if((p->xml)[0]=='<' && (p->xml)[1]!='?')
116
+ {
117
+ i = 0; elementname = ++p->xml;
118
+ while( !IS_WHITE_SPACE(*p->xml)
119
+ && (*p->xml!='>') && (*p->xml!='/')
120
+ )
121
+ {
122
+ i++; p->xml++;
123
+ if (p->xml >= p->xmlend)
124
+ return;
125
+ /* to ignore namespace : */
126
+ if(*p->xml==':')
127
+ {
128
+ i = 0;
129
+ elementname = ++p->xml;
130
+ }
131
+ }
132
+ if(i>0)
133
+ {
134
+ if(p->starteltfunc)
135
+ p->starteltfunc(p->data, elementname, i);
136
+ if(parseatt(p))
137
+ return;
138
+ if(*p->xml!='/')
139
+ {
140
+ const char * data;
141
+ i = 0; data = ++p->xml;
142
+ if (p->xml >= p->xmlend)
143
+ return;
144
+ while( IS_WHITE_SPACE(*p->xml) )
145
+ {
146
+ p->xml++;
147
+ if (p->xml >= p->xmlend)
148
+ return;
149
+ }
150
+ while(*p->xml!='<')
151
+ {
152
+ i++; p->xml++;
153
+ if (p->xml >= p->xmlend)
154
+ return;
155
+ }
156
+ if(i>0 && p->datafunc)
157
+ p->datafunc(p->data, data, i);
158
+ }
159
+ }
160
+ else if(*p->xml == '/')
161
+ {
162
+ i = 0; elementname = ++p->xml;
163
+ if (p->xml >= p->xmlend)
164
+ return;
165
+ while((*p->xml != '>'))
166
+ {
167
+ i++; p->xml++;
168
+ if (p->xml >= p->xmlend)
169
+ return;
170
+ }
171
+ if(p->endeltfunc)
172
+ p->endeltfunc(p->data, elementname, i);
173
+ p->xml++;
174
+ }
175
+ }
176
+ else
177
+ {
178
+ p->xml++;
179
+ }
180
+ }
181
+ }
182
+
183
+ /* the parser must be initialized before calling this function */
184
+ void parsexml(struct xmlparser * parser)
185
+ {
186
+ parser->xml = parser->xmlstart;
187
+ parser->xmlend = parser->xmlstart + parser->xmlsize;
188
+ parseelt(parser);
189
+ }
190
+
191
+