mupnp 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README +13 -0
- data/Rakefile +80 -0
- data/ext/Changelog.txt +188 -0
- data/ext/LICENSE +27 -0
- data/ext/README +53 -0
- data/ext/declspec.h +15 -0
- data/ext/extconf.rb +5 -0
- data/ext/igd_desc_parse.c +115 -0
- data/ext/igd_desc_parse.h +38 -0
- data/ext/minisoap.c +112 -0
- data/ext/minisoap.h +15 -0
- data/ext/minissdpc.c +107 -0
- data/ext/minissdpc.h +15 -0
- data/ext/miniupnpc.c +751 -0
- data/ext/miniupnpc.h +108 -0
- data/ext/miniwget.c +219 -0
- data/ext/miniwget.h +28 -0
- data/ext/minixml.c +191 -0
- data/ext/minixml.h +37 -0
- data/ext/upnp.i +13 -0
- data/ext/upnp_wrap.c +5207 -0
- data/ext/upnpcommands.c +569 -0
- data/ext/upnpcommands.h +179 -0
- data/ext/upnperrors.c +55 -0
- data/ext/upnperrors.h +16 -0
- data/ext/upnpreplyparse.c +127 -0
- data/ext/upnpreplyparse.h +62 -0
- data/lib/UPnP.rb +400 -0
- data/test/UPnP/tc_upnp.rb +20 -0
- metadata +83 -0
data/ext/upnpcommands.c
ADDED
@@ -0,0 +1,569 @@
|
|
1
|
+
/* $Id: upnpcommands.c,v 1.19 2008/02/18 13: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
|
+
#include <stdlib.h>
|
9
|
+
#include <stdio.h>
|
10
|
+
#include <string.h>
|
11
|
+
#include "upnpcommands.h"
|
12
|
+
#include "miniupnpc.h"
|
13
|
+
|
14
|
+
static unsigned int
|
15
|
+
my_atoui(const char * s)
|
16
|
+
{
|
17
|
+
return s ? ((unsigned int)strtoul(s, NULL, 0)) : 0;
|
18
|
+
}
|
19
|
+
|
20
|
+
/*
|
21
|
+
* */
|
22
|
+
unsigned int
|
23
|
+
UPNP_GetTotalBytesSent(const char * controlURL,
|
24
|
+
const char * servicetype)
|
25
|
+
{
|
26
|
+
struct NameValueParserData pdata;
|
27
|
+
char buffer[4096];
|
28
|
+
int bufsize = 4096;
|
29
|
+
unsigned int r = 0;
|
30
|
+
char * p;
|
31
|
+
simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalBytesSent", 0, buffer, &bufsize);
|
32
|
+
ParseNameValue(buffer, bufsize, &pdata);
|
33
|
+
/*DisplayNameValueList(buffer, bufsize);*/
|
34
|
+
p = GetValueFromNameValueList(&pdata, "NewTotalBytesSent");
|
35
|
+
r = my_atoui(p);
|
36
|
+
ClearNameValueList(&pdata);
|
37
|
+
return r;
|
38
|
+
}
|
39
|
+
|
40
|
+
/*
|
41
|
+
* */
|
42
|
+
unsigned int
|
43
|
+
UPNP_GetTotalBytesReceived(const char * controlURL,
|
44
|
+
const char * servicetype)
|
45
|
+
{
|
46
|
+
struct NameValueParserData pdata;
|
47
|
+
char buffer[4096];
|
48
|
+
int bufsize = 4096;
|
49
|
+
unsigned int r = 0;
|
50
|
+
char * p;
|
51
|
+
simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalBytesReceived", 0, buffer, &bufsize);
|
52
|
+
ParseNameValue(buffer, bufsize, &pdata);
|
53
|
+
/*DisplayNameValueList(buffer, bufsize);*/
|
54
|
+
p = GetValueFromNameValueList(&pdata, "NewTotalBytesReceived");
|
55
|
+
r = my_atoui(p);
|
56
|
+
ClearNameValueList(&pdata);
|
57
|
+
return r;
|
58
|
+
}
|
59
|
+
|
60
|
+
/*
|
61
|
+
* */
|
62
|
+
unsigned int
|
63
|
+
UPNP_GetTotalPacketsSent(const char * controlURL,
|
64
|
+
const char * servicetype)
|
65
|
+
{
|
66
|
+
struct NameValueParserData pdata;
|
67
|
+
char buffer[4096];
|
68
|
+
int bufsize = 4096;
|
69
|
+
unsigned int r = 0;
|
70
|
+
char * p;
|
71
|
+
simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalPacketsSent", 0, buffer, &bufsize);
|
72
|
+
ParseNameValue(buffer, bufsize, &pdata);
|
73
|
+
/*DisplayNameValueList(buffer, bufsize);*/
|
74
|
+
p = GetValueFromNameValueList(&pdata, "NewTotalPacketsSent");
|
75
|
+
r = my_atoui(p);
|
76
|
+
ClearNameValueList(&pdata);
|
77
|
+
return r;
|
78
|
+
}
|
79
|
+
|
80
|
+
/*
|
81
|
+
* */
|
82
|
+
unsigned int
|
83
|
+
UPNP_GetTotalPacketsReceived(const char * controlURL,
|
84
|
+
const char * servicetype)
|
85
|
+
{
|
86
|
+
struct NameValueParserData pdata;
|
87
|
+
char buffer[4096];
|
88
|
+
int bufsize = 4096;
|
89
|
+
unsigned int r = 0;
|
90
|
+
char * p;
|
91
|
+
simpleUPnPcommand(-1, controlURL, servicetype, "GetTotalPacketsReceived", 0, buffer, &bufsize);
|
92
|
+
ParseNameValue(buffer, bufsize, &pdata);
|
93
|
+
/*DisplayNameValueList(buffer, bufsize);*/
|
94
|
+
p = GetValueFromNameValueList(&pdata, "NewTotalPacketsReceived");
|
95
|
+
r = my_atoui(p);
|
96
|
+
ClearNameValueList(&pdata);
|
97
|
+
return r;
|
98
|
+
}
|
99
|
+
|
100
|
+
/* UPNP_GetStatusInfo() call the corresponding UPNP method
|
101
|
+
* returns the current status and uptime */
|
102
|
+
int UPNP_GetStatusInfo(const char * controlURL,
|
103
|
+
const char * servicetype,
|
104
|
+
char * status,
|
105
|
+
unsigned int * uptime,
|
106
|
+
char * lastconnerror)
|
107
|
+
{
|
108
|
+
struct NameValueParserData pdata;
|
109
|
+
char buffer[4096];
|
110
|
+
int bufsize = 4096;
|
111
|
+
char * p;
|
112
|
+
char * up;
|
113
|
+
char * err;
|
114
|
+
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
115
|
+
|
116
|
+
if(!status && !uptime)
|
117
|
+
return UPNPCOMMAND_INVALID_ARGS;
|
118
|
+
|
119
|
+
simpleUPnPcommand(-1, controlURL, servicetype, "GetStatusInfo", 0, buffer, &bufsize);
|
120
|
+
ParseNameValue(buffer, bufsize, &pdata);
|
121
|
+
/*DisplayNameValueList(buffer, bufsize);*/
|
122
|
+
up = GetValueFromNameValueList(&pdata, "NewUptime");
|
123
|
+
p = GetValueFromNameValueList(&pdata, "NewConnectionStatus");
|
124
|
+
err = GetValueFromNameValueList(&pdata, "NewLastConnectionError");
|
125
|
+
if(p && up)
|
126
|
+
ret = UPNPCOMMAND_SUCCESS;
|
127
|
+
|
128
|
+
if(status) {
|
129
|
+
if(p){
|
130
|
+
strncpy(status, p, 64 );
|
131
|
+
status[63] = '\0';
|
132
|
+
}else
|
133
|
+
status[0]= '\0';
|
134
|
+
}
|
135
|
+
|
136
|
+
if(uptime) {
|
137
|
+
if(up)
|
138
|
+
sscanf(up,"%u",uptime);
|
139
|
+
else
|
140
|
+
uptime = 0;
|
141
|
+
}
|
142
|
+
|
143
|
+
if(lastconnerror) {
|
144
|
+
if(err) {
|
145
|
+
strncpy(lastconnerror, err, 64 );
|
146
|
+
lastconnerror[63] = '\0';
|
147
|
+
} else
|
148
|
+
lastconnerror[0] = '\0';
|
149
|
+
}
|
150
|
+
|
151
|
+
p = GetValueFromNameValueList(&pdata, "errorCode");
|
152
|
+
if(p) {
|
153
|
+
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
154
|
+
sscanf(p, "%d", &ret);
|
155
|
+
}
|
156
|
+
ClearNameValueList(&pdata);
|
157
|
+
return ret;
|
158
|
+
}
|
159
|
+
|
160
|
+
/* UPNP_GetConnectionTypeInfo() call the corresponding UPNP method
|
161
|
+
* returns the connection type */
|
162
|
+
int UPNP_GetConnectionTypeInfo(const char * controlURL,
|
163
|
+
const char * servicetype,
|
164
|
+
char * connectionType)
|
165
|
+
{
|
166
|
+
struct NameValueParserData pdata;
|
167
|
+
char buffer[4096];
|
168
|
+
int bufsize = 4096;
|
169
|
+
char * p;
|
170
|
+
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
171
|
+
|
172
|
+
if(!connectionType)
|
173
|
+
return UPNPCOMMAND_INVALID_ARGS;
|
174
|
+
|
175
|
+
simpleUPnPcommand(-1, controlURL, servicetype,
|
176
|
+
"GetConnectionTypeInfo", 0, buffer, &bufsize);
|
177
|
+
ParseNameValue(buffer, bufsize, &pdata);
|
178
|
+
p = GetValueFromNameValueList(&pdata, "NewConnectionType");
|
179
|
+
/*p = GetValueFromNameValueList(&pdata, "NewPossibleConnectionTypes");*/
|
180
|
+
/* PossibleConnectionTypes will have several values.... */
|
181
|
+
if(p) {
|
182
|
+
strncpy(connectionType, p, 64 );
|
183
|
+
connectionType[63] = '\0';
|
184
|
+
ret = UPNPCOMMAND_SUCCESS;
|
185
|
+
} else
|
186
|
+
connectionType[0] = '\0';
|
187
|
+
p = GetValueFromNameValueList(&pdata, "errorCode");
|
188
|
+
if(p) {
|
189
|
+
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
190
|
+
sscanf(p, "%d", &ret);
|
191
|
+
}
|
192
|
+
ClearNameValueList(&pdata);
|
193
|
+
return ret;
|
194
|
+
}
|
195
|
+
|
196
|
+
/* UPNP_GetLinkLayerMaxBitRate() call the corresponding UPNP method.
|
197
|
+
* Returns 2 values: Downloadlink bandwidth and Uplink bandwidth.
|
198
|
+
* One of the values can be null
|
199
|
+
* Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only
|
200
|
+
* We can use the GetCommonLinkProperties from WANCommonInterfaceConfig:1 */
|
201
|
+
int UPNP_GetLinkLayerMaxBitRates(const char * controlURL, const char * servicetype, unsigned int * bitrateDown, unsigned int* bitrateUp)
|
202
|
+
{
|
203
|
+
struct NameValueParserData pdata;
|
204
|
+
char buffer[4096];
|
205
|
+
int bufsize = 4096;
|
206
|
+
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
207
|
+
char * down;
|
208
|
+
char * up;
|
209
|
+
char * p;
|
210
|
+
|
211
|
+
if(!bitrateDown && !bitrateUp)
|
212
|
+
return UPNPCOMMAND_INVALID_ARGS;
|
213
|
+
|
214
|
+
/* shouldn't we use GetCommonLinkProperties ? */
|
215
|
+
simpleUPnPcommand(-1, controlURL, servicetype,
|
216
|
+
"GetCommonLinkProperties", 0, buffer, &bufsize);
|
217
|
+
/*"GetLinkLayerMaxBitRates", 0, buffer, &bufsize);*/
|
218
|
+
/*DisplayNameValueList(buffer, bufsize);*/
|
219
|
+
ParseNameValue(buffer, bufsize, &pdata);
|
220
|
+
/*down = GetValueFromNameValueList(&pdata, "NewDownstreamMaxBitRate");*/
|
221
|
+
/*up = GetValueFromNameValueList(&pdata, "NewUpstreamMaxBitRate");*/
|
222
|
+
down = GetValueFromNameValueList(&pdata, "NewLayer1DownstreamMaxBitRate");
|
223
|
+
up = GetValueFromNameValueList(&pdata, "NewLayer1UpstreamMaxBitRate");
|
224
|
+
/*GetValueFromNameValueList(&pdata, "NewWANAccessType");*/
|
225
|
+
/*GetValueFromNameValueList(&pdata, "NewPhysicalLinkSatus");*/
|
226
|
+
if(down && up)
|
227
|
+
ret = UPNPCOMMAND_SUCCESS;
|
228
|
+
|
229
|
+
if(bitrateDown)
|
230
|
+
{
|
231
|
+
if(down)
|
232
|
+
sscanf(down,"%u",bitrateDown);
|
233
|
+
else
|
234
|
+
*bitrateDown = 0;
|
235
|
+
}
|
236
|
+
|
237
|
+
if(bitrateUp)
|
238
|
+
{
|
239
|
+
if(up)
|
240
|
+
sscanf(up,"%u",bitrateUp);
|
241
|
+
else
|
242
|
+
*bitrateUp = 0;
|
243
|
+
}
|
244
|
+
p = GetValueFromNameValueList(&pdata, "errorCode");
|
245
|
+
if(p) {
|
246
|
+
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
247
|
+
sscanf(p, "%d", &ret);
|
248
|
+
}
|
249
|
+
ClearNameValueList(&pdata);
|
250
|
+
return ret;
|
251
|
+
}
|
252
|
+
|
253
|
+
|
254
|
+
/* UPNP_GetExternalIPAddress() call the corresponding UPNP method.
|
255
|
+
* if the third arg is not null the value is copied to it.
|
256
|
+
* at least 16 bytes must be available
|
257
|
+
*
|
258
|
+
* Return values :
|
259
|
+
* 0 : SUCCESS
|
260
|
+
* NON ZERO : ERROR Either an UPnP error code or an unknown error.
|
261
|
+
*
|
262
|
+
* 402 Invalid Args - See UPnP Device Architecture section on Control.
|
263
|
+
* 501 Action Failed - See UPnP Device Architecture section on Control.
|
264
|
+
*/
|
265
|
+
int UPNP_GetExternalIPAddress(const char * controlURL,
|
266
|
+
const char * servicetype,
|
267
|
+
char * extIpAdd)
|
268
|
+
{
|
269
|
+
struct NameValueParserData pdata;
|
270
|
+
char buffer[4096];
|
271
|
+
int bufsize = 4096;
|
272
|
+
char * p;
|
273
|
+
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
274
|
+
|
275
|
+
if(!extIpAdd || !controlURL || !servicetype)
|
276
|
+
return UPNPCOMMAND_INVALID_ARGS;
|
277
|
+
|
278
|
+
simpleUPnPcommand(-1, controlURL, servicetype, "GetExternalIPAddress", 0, buffer, &bufsize);
|
279
|
+
/*DisplayNameValueList(buffer, bufsize);*/
|
280
|
+
ParseNameValue(buffer, bufsize, &pdata);
|
281
|
+
/*printf("external ip = %s\n", GetValueFromNameValueList(&pdata, "NewExternalIPAddress") );*/
|
282
|
+
p = GetValueFromNameValueList(&pdata, "NewExternalIPAddress");
|
283
|
+
if(p) {
|
284
|
+
strncpy(extIpAdd, p, 16 );
|
285
|
+
extIpAdd[15] = '\0';
|
286
|
+
ret = UPNPCOMMAND_SUCCESS;
|
287
|
+
} else
|
288
|
+
extIpAdd[0] = '\0';
|
289
|
+
|
290
|
+
p = GetValueFromNameValueList(&pdata, "errorCode");
|
291
|
+
if(p) {
|
292
|
+
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
293
|
+
sscanf(p, "%d", &ret);
|
294
|
+
}
|
295
|
+
|
296
|
+
ClearNameValueList(&pdata);
|
297
|
+
return ret;
|
298
|
+
}
|
299
|
+
|
300
|
+
int
|
301
|
+
UPNP_AddPortMapping(const char * controlURL, const char * servicetype,
|
302
|
+
const char * extPort,
|
303
|
+
const char * inPort,
|
304
|
+
const char * inClient,
|
305
|
+
const char * desc,
|
306
|
+
const char * proto)
|
307
|
+
{
|
308
|
+
struct UPNParg * AddPortMappingArgs;
|
309
|
+
char buffer[4096];
|
310
|
+
int bufsize = 4096;
|
311
|
+
struct NameValueParserData pdata;
|
312
|
+
const char * resVal;
|
313
|
+
int ret;
|
314
|
+
|
315
|
+
if(!inPort || !inClient || !proto || !extPort)
|
316
|
+
return UPNPCOMMAND_INVALID_ARGS;
|
317
|
+
|
318
|
+
AddPortMappingArgs = calloc(9, sizeof(struct UPNParg));
|
319
|
+
AddPortMappingArgs[0].elt = "NewRemoteHost";
|
320
|
+
AddPortMappingArgs[1].elt = "NewExternalPort";
|
321
|
+
AddPortMappingArgs[1].val = extPort;
|
322
|
+
AddPortMappingArgs[2].elt = "NewProtocol";
|
323
|
+
AddPortMappingArgs[2].val = proto;
|
324
|
+
AddPortMappingArgs[3].elt = "NewInternalPort";
|
325
|
+
AddPortMappingArgs[3].val = inPort;
|
326
|
+
AddPortMappingArgs[4].elt = "NewInternalClient";
|
327
|
+
AddPortMappingArgs[4].val = inClient;
|
328
|
+
AddPortMappingArgs[5].elt = "NewEnabled";
|
329
|
+
AddPortMappingArgs[5].val = "1";
|
330
|
+
AddPortMappingArgs[6].elt = "NewPortMappingDescription";
|
331
|
+
AddPortMappingArgs[6].val = desc?desc:"libminiupnpc";
|
332
|
+
AddPortMappingArgs[7].elt = "NewLeaseDuration";
|
333
|
+
AddPortMappingArgs[7].val = "0";
|
334
|
+
simpleUPnPcommand(-1, controlURL, servicetype, "AddPortMapping", AddPortMappingArgs, buffer, &bufsize);
|
335
|
+
/*DisplayNameValueList(buffer, bufsize);*/
|
336
|
+
/*buffer[bufsize] = '\0';*/
|
337
|
+
/*puts(buffer);*/
|
338
|
+
ParseNameValue(buffer, bufsize, &pdata);
|
339
|
+
resVal = GetValueFromNameValueList(&pdata, "errorCode");
|
340
|
+
if(resVal) {
|
341
|
+
/*printf("AddPortMapping errorCode = '%s'\n", resVal); */
|
342
|
+
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
343
|
+
sscanf(resVal, "%d", &ret);
|
344
|
+
} else {
|
345
|
+
ret = UPNPCOMMAND_SUCCESS;
|
346
|
+
}
|
347
|
+
ClearNameValueList(&pdata);
|
348
|
+
free(AddPortMappingArgs);
|
349
|
+
return ret;
|
350
|
+
}
|
351
|
+
|
352
|
+
int
|
353
|
+
UPNP_DeletePortMapping(const char * controlURL, const char * servicetype,
|
354
|
+
const char * extPort, const char * proto)
|
355
|
+
{
|
356
|
+
/*struct NameValueParserData pdata;*/
|
357
|
+
struct UPNParg * DeletePortMappingArgs;
|
358
|
+
char buffer[4096];
|
359
|
+
int bufsize = 4096;
|
360
|
+
struct NameValueParserData pdata;
|
361
|
+
const char * resVal;
|
362
|
+
int ret;
|
363
|
+
|
364
|
+
if(!extPort || !proto)
|
365
|
+
return UPNPCOMMAND_INVALID_ARGS;
|
366
|
+
|
367
|
+
DeletePortMappingArgs = calloc(4, sizeof(struct UPNParg));
|
368
|
+
DeletePortMappingArgs[0].elt = "NewRemoteHost";
|
369
|
+
DeletePortMappingArgs[1].elt = "NewExternalPort";
|
370
|
+
DeletePortMappingArgs[1].val = extPort;
|
371
|
+
DeletePortMappingArgs[2].elt = "NewProtocol";
|
372
|
+
DeletePortMappingArgs[2].val = proto;
|
373
|
+
simpleUPnPcommand(-1, controlURL, servicetype,
|
374
|
+
"DeletePortMapping",
|
375
|
+
DeletePortMappingArgs, buffer, &bufsize);
|
376
|
+
/*DisplayNameValueList(buffer, bufsize);*/
|
377
|
+
ParseNameValue(buffer, bufsize, &pdata);
|
378
|
+
resVal = GetValueFromNameValueList(&pdata, "errorCode");
|
379
|
+
if(resVal) {
|
380
|
+
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
381
|
+
sscanf(resVal, "%d", &ret);
|
382
|
+
} else {
|
383
|
+
ret = UPNPCOMMAND_SUCCESS;
|
384
|
+
}
|
385
|
+
ClearNameValueList(&pdata);
|
386
|
+
free(DeletePortMappingArgs);
|
387
|
+
return ret;
|
388
|
+
}
|
389
|
+
|
390
|
+
int UPNP_GetGenericPortMappingEntry(const char * controlURL,
|
391
|
+
const char * servicetype,
|
392
|
+
const char * index,
|
393
|
+
char * extPort,
|
394
|
+
char * intClient,
|
395
|
+
char * intPort,
|
396
|
+
char * protocol,
|
397
|
+
char * desc,
|
398
|
+
char * enabled,
|
399
|
+
char * rHost,
|
400
|
+
char * duration)
|
401
|
+
{
|
402
|
+
struct NameValueParserData pdata;
|
403
|
+
struct UPNParg * GetPortMappingArgs;
|
404
|
+
char buffer[4096];
|
405
|
+
int bufsize = 4096;
|
406
|
+
char * p;
|
407
|
+
int r = UPNPCOMMAND_UNKNOWN_ERROR;
|
408
|
+
if(!index)
|
409
|
+
return UPNPCOMMAND_INVALID_ARGS;
|
410
|
+
intClient[0] = '\0';
|
411
|
+
intPort[0] = '\0';
|
412
|
+
GetPortMappingArgs = calloc(2, sizeof(struct UPNParg));
|
413
|
+
GetPortMappingArgs[0].elt = "NewPortMappingIndex";
|
414
|
+
GetPortMappingArgs[0].val = index;
|
415
|
+
simpleUPnPcommand(-1, controlURL, servicetype,
|
416
|
+
"GetGenericPortMappingEntry",
|
417
|
+
GetPortMappingArgs, buffer, &bufsize);
|
418
|
+
ParseNameValue(buffer, bufsize, &pdata);
|
419
|
+
p = GetValueFromNameValueList(&pdata, "NewRemoteHost");
|
420
|
+
if(p && rHost)
|
421
|
+
{
|
422
|
+
strncpy(rHost, p, 64);
|
423
|
+
rHost[63] = '\0';
|
424
|
+
}
|
425
|
+
p = GetValueFromNameValueList(&pdata, "NewExternalPort");
|
426
|
+
if(p && extPort)
|
427
|
+
{
|
428
|
+
strncpy(extPort, p, 6);
|
429
|
+
extPort[5] = '\0';
|
430
|
+
r = UPNPCOMMAND_SUCCESS;
|
431
|
+
}
|
432
|
+
p = GetValueFromNameValueList(&pdata, "NewProtocol");
|
433
|
+
if(p && protocol)
|
434
|
+
{
|
435
|
+
strncpy(protocol, p, 4);
|
436
|
+
protocol[3] = '\0';
|
437
|
+
}
|
438
|
+
p = GetValueFromNameValueList(&pdata, "NewInternalClient");
|
439
|
+
if(p && intClient)
|
440
|
+
{
|
441
|
+
strncpy(intClient, p, 16);
|
442
|
+
intClient[15] = '\0';
|
443
|
+
r = 0;
|
444
|
+
}
|
445
|
+
p = GetValueFromNameValueList(&pdata, "NewInternalPort");
|
446
|
+
if(p && intPort)
|
447
|
+
{
|
448
|
+
strncpy(intPort, p, 6);
|
449
|
+
intPort[5] = '\0';
|
450
|
+
}
|
451
|
+
p = GetValueFromNameValueList(&pdata, "NewEnabled");
|
452
|
+
if(p && enabled)
|
453
|
+
{
|
454
|
+
strncpy(enabled, p, 4);
|
455
|
+
enabled[3] = '\0';
|
456
|
+
}
|
457
|
+
p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription");
|
458
|
+
if(p && desc)
|
459
|
+
{
|
460
|
+
strncpy(desc, p, 80);
|
461
|
+
desc[79] = '\0';
|
462
|
+
}
|
463
|
+
p = GetValueFromNameValueList(&pdata, "NewLeaseDuration");
|
464
|
+
if(p && duration)
|
465
|
+
{
|
466
|
+
strncpy(duration, p, 16);
|
467
|
+
duration[15] = '\0';
|
468
|
+
}
|
469
|
+
p = GetValueFromNameValueList(&pdata, "errorCode");
|
470
|
+
if(p) {
|
471
|
+
r = UPNPCOMMAND_UNKNOWN_ERROR;
|
472
|
+
sscanf(p, "%d", &r);
|
473
|
+
}
|
474
|
+
ClearNameValueList(&pdata);
|
475
|
+
free(GetPortMappingArgs);
|
476
|
+
return r;
|
477
|
+
}
|
478
|
+
|
479
|
+
int UPNP_GetPortMappingNumberOfEntries(const char * controlURL, const char * servicetype, unsigned int * numEntries)
|
480
|
+
{
|
481
|
+
struct NameValueParserData pdata;
|
482
|
+
char buffer[4096];
|
483
|
+
int bufsize = 4096;
|
484
|
+
char* p;
|
485
|
+
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
486
|
+
simpleUPnPcommand(-1, controlURL, servicetype, "GetPortMappingNumberOfEntries", 0, buffer, &bufsize);
|
487
|
+
#ifndef NDEBUG
|
488
|
+
DisplayNameValueList(buffer, bufsize);
|
489
|
+
#endif
|
490
|
+
ParseNameValue(buffer, bufsize, &pdata);
|
491
|
+
|
492
|
+
p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries");
|
493
|
+
if(numEntries && p) {
|
494
|
+
*numEntries = 0;
|
495
|
+
sscanf(p, "%u", numEntries);
|
496
|
+
ret = UPNPCOMMAND_SUCCESS;
|
497
|
+
}
|
498
|
+
|
499
|
+
p = GetValueFromNameValueList(&pdata, "errorCode");
|
500
|
+
if(p) {
|
501
|
+
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
502
|
+
sscanf(p, "%d", &ret);
|
503
|
+
}
|
504
|
+
|
505
|
+
ClearNameValueList(&pdata);
|
506
|
+
return ret;
|
507
|
+
}
|
508
|
+
|
509
|
+
/* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping
|
510
|
+
* the result is returned in the intClient and intPort strings
|
511
|
+
* please provide 16 and 6 bytes of data */
|
512
|
+
int
|
513
|
+
UPNP_GetSpecificPortMappingEntry(const char * controlURL,
|
514
|
+
const char * servicetype,
|
515
|
+
const char * extPort,
|
516
|
+
const char * proto,
|
517
|
+
char * intClient,
|
518
|
+
char * intPort)
|
519
|
+
{
|
520
|
+
struct NameValueParserData pdata;
|
521
|
+
struct UPNParg * GetPortMappingArgs;
|
522
|
+
char buffer[4096];
|
523
|
+
int bufsize = 4096;
|
524
|
+
char * p;
|
525
|
+
int ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
526
|
+
|
527
|
+
if(!intPort || !intClient || !extPort || !proto)
|
528
|
+
return UPNPCOMMAND_INVALID_ARGS;
|
529
|
+
|
530
|
+
GetPortMappingArgs = calloc(4, sizeof(struct UPNParg));
|
531
|
+
GetPortMappingArgs[0].elt = "NewRemoteHost";
|
532
|
+
GetPortMappingArgs[1].elt = "NewExternalPort";
|
533
|
+
GetPortMappingArgs[1].val = extPort;
|
534
|
+
GetPortMappingArgs[2].elt = "NewProtocol";
|
535
|
+
GetPortMappingArgs[2].val = proto;
|
536
|
+
simpleUPnPcommand(-1, controlURL, servicetype,
|
537
|
+
"GetSpecificPortMappingEntry",
|
538
|
+
GetPortMappingArgs, buffer, &bufsize);
|
539
|
+
/*fd = simpleUPnPcommand(fd, controlURL, data.servicetype, "GetSpecificPortMappingEntry", AddPortMappingArgs, buffer, &bufsize); */
|
540
|
+
/*DisplayNameValueList(buffer, bufsize);*/
|
541
|
+
ParseNameValue(buffer, bufsize, &pdata);
|
542
|
+
|
543
|
+
p = GetValueFromNameValueList(&pdata, "NewInternalClient");
|
544
|
+
if(p) {
|
545
|
+
strncpy(intClient, p, 16);
|
546
|
+
intClient[15] = '\0';
|
547
|
+
ret = UPNPCOMMAND_SUCCESS;
|
548
|
+
} else
|
549
|
+
intClient[0] = '\0';
|
550
|
+
|
551
|
+
p = GetValueFromNameValueList(&pdata, "NewInternalPort");
|
552
|
+
if(p) {
|
553
|
+
strncpy(intPort, p, 6);
|
554
|
+
intPort[5] = '\0';
|
555
|
+
} else
|
556
|
+
intPort[0] = '\0';
|
557
|
+
|
558
|
+
p = GetValueFromNameValueList(&pdata, "errorCode");
|
559
|
+
if(p) {
|
560
|
+
ret = UPNPCOMMAND_UNKNOWN_ERROR;
|
561
|
+
sscanf(p, "%d", &ret);
|
562
|
+
}
|
563
|
+
|
564
|
+
ClearNameValueList(&pdata);
|
565
|
+
free(GetPortMappingArgs);
|
566
|
+
return ret;
|
567
|
+
}
|
568
|
+
|
569
|
+
|