1 | /* $Id: upnpcommands.c,v 1.25 2009/07/09 16:00:42 nanard Exp $ */ |
---|
2 | /* Project : miniupnp |
---|
3 | * Author : Thomas Bernard |
---|
4 | * Copyright (c) 2005-2009 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_INTEGER |
---|
15 | my_atoui(const char * s) |
---|
16 | { |
---|
17 | return s ? ((UNSIGNED_INTEGER)STRTOUI(s, NULL, 0)) : 0; |
---|
18 | } |
---|
19 | |
---|
20 | /* |
---|
21 | * */ |
---|
22 | LIBSPEC UNSIGNED_INTEGER |
---|
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 | LIBSPEC UNSIGNED_INTEGER |
---|
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 | LIBSPEC UNSIGNED_INTEGER |
---|
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 | LIBSPEC UNSIGNED_INTEGER |
---|
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 | LIBSPEC int |
---|
103 | UPNP_GetStatusInfo(const char * controlURL, |
---|
104 | const char * servicetype, |
---|
105 | char * status, |
---|
106 | unsigned int * uptime, |
---|
107 | char * lastconnerror) |
---|
108 | { |
---|
109 | struct NameValueParserData pdata; |
---|
110 | char buffer[4096]; |
---|
111 | int bufsize = 4096; |
---|
112 | char * p; |
---|
113 | char * up; |
---|
114 | char * err; |
---|
115 | int ret = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
116 | |
---|
117 | if(!status && !uptime) |
---|
118 | return UPNPCOMMAND_INVALID_ARGS; |
---|
119 | |
---|
120 | simpleUPnPcommand(-1, controlURL, servicetype, "GetStatusInfo", 0, buffer, &bufsize); |
---|
121 | ParseNameValue(buffer, bufsize, &pdata); |
---|
122 | /*DisplayNameValueList(buffer, bufsize);*/ |
---|
123 | up = GetValueFromNameValueList(&pdata, "NewUptime"); |
---|
124 | p = GetValueFromNameValueList(&pdata, "NewConnectionStatus"); |
---|
125 | err = GetValueFromNameValueList(&pdata, "NewLastConnectionError"); |
---|
126 | if(p && up) |
---|
127 | ret = UPNPCOMMAND_SUCCESS; |
---|
128 | |
---|
129 | if(status) { |
---|
130 | if(p){ |
---|
131 | strncpy(status, p, 64 ); |
---|
132 | status[63] = '\0'; |
---|
133 | }else |
---|
134 | status[0]= '\0'; |
---|
135 | } |
---|
136 | |
---|
137 | if(uptime) { |
---|
138 | if(up) |
---|
139 | sscanf(up,"%u",uptime); |
---|
140 | else |
---|
141 | uptime = 0; |
---|
142 | } |
---|
143 | |
---|
144 | if(lastconnerror) { |
---|
145 | if(err) { |
---|
146 | strncpy(lastconnerror, err, 64 ); |
---|
147 | lastconnerror[63] = '\0'; |
---|
148 | } else |
---|
149 | lastconnerror[0] = '\0'; |
---|
150 | } |
---|
151 | |
---|
152 | p = GetValueFromNameValueList(&pdata, "errorCode"); |
---|
153 | if(p) { |
---|
154 | ret = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
155 | sscanf(p, "%d", &ret); |
---|
156 | } |
---|
157 | ClearNameValueList(&pdata); |
---|
158 | return ret; |
---|
159 | } |
---|
160 | |
---|
161 | /* UPNP_GetConnectionTypeInfo() call the corresponding UPNP method |
---|
162 | * returns the connection type */ |
---|
163 | LIBSPEC int |
---|
164 | UPNP_GetConnectionTypeInfo(const char * controlURL, |
---|
165 | const char * servicetype, |
---|
166 | char * connectionType) |
---|
167 | { |
---|
168 | struct NameValueParserData pdata; |
---|
169 | char buffer[4096]; |
---|
170 | int bufsize = 4096; |
---|
171 | char * p; |
---|
172 | int ret = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
173 | |
---|
174 | if(!connectionType) |
---|
175 | return UPNPCOMMAND_INVALID_ARGS; |
---|
176 | |
---|
177 | simpleUPnPcommand(-1, controlURL, servicetype, |
---|
178 | "GetConnectionTypeInfo", 0, buffer, &bufsize); |
---|
179 | ParseNameValue(buffer, bufsize, &pdata); |
---|
180 | p = GetValueFromNameValueList(&pdata, "NewConnectionType"); |
---|
181 | /*p = GetValueFromNameValueList(&pdata, "NewPossibleConnectionTypes");*/ |
---|
182 | /* PossibleConnectionTypes will have several values.... */ |
---|
183 | if(p) { |
---|
184 | strncpy(connectionType, p, 64 ); |
---|
185 | connectionType[63] = '\0'; |
---|
186 | ret = UPNPCOMMAND_SUCCESS; |
---|
187 | } else |
---|
188 | connectionType[0] = '\0'; |
---|
189 | p = GetValueFromNameValueList(&pdata, "errorCode"); |
---|
190 | if(p) { |
---|
191 | ret = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
192 | sscanf(p, "%d", &ret); |
---|
193 | } |
---|
194 | ClearNameValueList(&pdata); |
---|
195 | return ret; |
---|
196 | } |
---|
197 | |
---|
198 | /* UPNP_GetLinkLayerMaxBitRate() call the corresponding UPNP method. |
---|
199 | * Returns 2 values: Downloadlink bandwidth and Uplink bandwidth. |
---|
200 | * One of the values can be null |
---|
201 | * Note : GetLinkLayerMaxBitRates belongs to WANPPPConnection:1 only |
---|
202 | * We can use the GetCommonLinkProperties from WANCommonInterfaceConfig:1 */ |
---|
203 | LIBSPEC int |
---|
204 | UPNP_GetLinkLayerMaxBitRates(const char * controlURL, |
---|
205 | const char * servicetype, |
---|
206 | unsigned int * bitrateDown, |
---|
207 | unsigned int* bitrateUp) |
---|
208 | { |
---|
209 | struct NameValueParserData pdata; |
---|
210 | char buffer[4096]; |
---|
211 | int bufsize = 4096; |
---|
212 | int ret = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
213 | char * down; |
---|
214 | char * up; |
---|
215 | char * p; |
---|
216 | |
---|
217 | if(!bitrateDown && !bitrateUp) |
---|
218 | return UPNPCOMMAND_INVALID_ARGS; |
---|
219 | |
---|
220 | /* shouldn't we use GetCommonLinkProperties ? */ |
---|
221 | simpleUPnPcommand(-1, controlURL, servicetype, |
---|
222 | "GetCommonLinkProperties", 0, buffer, &bufsize); |
---|
223 | /*"GetLinkLayerMaxBitRates", 0, buffer, &bufsize);*/ |
---|
224 | /*DisplayNameValueList(buffer, bufsize);*/ |
---|
225 | ParseNameValue(buffer, bufsize, &pdata); |
---|
226 | /*down = GetValueFromNameValueList(&pdata, "NewDownstreamMaxBitRate");*/ |
---|
227 | /*up = GetValueFromNameValueList(&pdata, "NewUpstreamMaxBitRate");*/ |
---|
228 | down = GetValueFromNameValueList(&pdata, "NewLayer1DownstreamMaxBitRate"); |
---|
229 | up = GetValueFromNameValueList(&pdata, "NewLayer1UpstreamMaxBitRate"); |
---|
230 | /*GetValueFromNameValueList(&pdata, "NewWANAccessType");*/ |
---|
231 | /*GetValueFromNameValueList(&pdata, "NewPhysicalLinkSatus");*/ |
---|
232 | if(down && up) |
---|
233 | ret = UPNPCOMMAND_SUCCESS; |
---|
234 | |
---|
235 | if(bitrateDown) { |
---|
236 | if(down) |
---|
237 | sscanf(down,"%u",bitrateDown); |
---|
238 | else |
---|
239 | *bitrateDown = 0; |
---|
240 | } |
---|
241 | |
---|
242 | if(bitrateUp) { |
---|
243 | if(up) |
---|
244 | sscanf(up,"%u",bitrateUp); |
---|
245 | else |
---|
246 | *bitrateUp = 0; |
---|
247 | } |
---|
248 | p = GetValueFromNameValueList(&pdata, "errorCode"); |
---|
249 | if(p) { |
---|
250 | ret = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
251 | sscanf(p, "%d", &ret); |
---|
252 | } |
---|
253 | ClearNameValueList(&pdata); |
---|
254 | return ret; |
---|
255 | } |
---|
256 | |
---|
257 | |
---|
258 | /* UPNP_GetExternalIPAddress() call the corresponding UPNP method. |
---|
259 | * if the third arg is not null the value is copied to it. |
---|
260 | * at least 16 bytes must be available |
---|
261 | * |
---|
262 | * Return values : |
---|
263 | * 0 : SUCCESS |
---|
264 | * NON ZERO : ERROR Either an UPnP error code or an unknown error. |
---|
265 | * |
---|
266 | * 402 Invalid Args - See UPnP Device Architecture section on Control. |
---|
267 | * 501 Action Failed - See UPnP Device Architecture section on Control. |
---|
268 | */ |
---|
269 | LIBSPEC int |
---|
270 | UPNP_GetExternalIPAddress(const char * controlURL, |
---|
271 | const char * servicetype, |
---|
272 | char * extIpAdd) |
---|
273 | { |
---|
274 | struct NameValueParserData pdata; |
---|
275 | char buffer[4096]; |
---|
276 | int bufsize = 4096; |
---|
277 | char * p; |
---|
278 | int ret = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
279 | |
---|
280 | if(!extIpAdd || !controlURL || !servicetype) |
---|
281 | return UPNPCOMMAND_INVALID_ARGS; |
---|
282 | |
---|
283 | simpleUPnPcommand(-1, controlURL, servicetype, "GetExternalIPAddress", 0, buffer, &bufsize); |
---|
284 | /*DisplayNameValueList(buffer, bufsize);*/ |
---|
285 | ParseNameValue(buffer, bufsize, &pdata); |
---|
286 | /*printf("external ip = %s\n", GetValueFromNameValueList(&pdata, "NewExternalIPAddress") );*/ |
---|
287 | p = GetValueFromNameValueList(&pdata, "NewExternalIPAddress"); |
---|
288 | if(p) { |
---|
289 | strncpy(extIpAdd, p, 16 ); |
---|
290 | extIpAdd[15] = '\0'; |
---|
291 | ret = UPNPCOMMAND_SUCCESS; |
---|
292 | } else |
---|
293 | extIpAdd[0] = '\0'; |
---|
294 | |
---|
295 | p = GetValueFromNameValueList(&pdata, "errorCode"); |
---|
296 | if(p) { |
---|
297 | ret = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
298 | sscanf(p, "%d", &ret); |
---|
299 | } |
---|
300 | |
---|
301 | ClearNameValueList(&pdata); |
---|
302 | return ret; |
---|
303 | } |
---|
304 | |
---|
305 | LIBSPEC int |
---|
306 | UPNP_AddPortMapping(const char * controlURL, const char * servicetype, |
---|
307 | const char * extPort, |
---|
308 | const char * inPort, |
---|
309 | const char * inClient, |
---|
310 | const char * desc, |
---|
311 | const char * proto, |
---|
312 | const char * remoteHost) |
---|
313 | { |
---|
314 | struct UPNParg * AddPortMappingArgs; |
---|
315 | char buffer[4096]; |
---|
316 | int bufsize = 4096; |
---|
317 | struct NameValueParserData pdata; |
---|
318 | const char * resVal; |
---|
319 | int ret; |
---|
320 | |
---|
321 | if(!inPort || !inClient || !proto || !extPort) |
---|
322 | return UPNPCOMMAND_INVALID_ARGS; |
---|
323 | |
---|
324 | AddPortMappingArgs = calloc(9, sizeof(struct UPNParg)); |
---|
325 | AddPortMappingArgs[0].elt = "NewRemoteHost"; |
---|
326 | AddPortMappingArgs[0].val = remoteHost; |
---|
327 | AddPortMappingArgs[1].elt = "NewExternalPort"; |
---|
328 | AddPortMappingArgs[1].val = extPort; |
---|
329 | AddPortMappingArgs[2].elt = "NewProtocol"; |
---|
330 | AddPortMappingArgs[2].val = proto; |
---|
331 | AddPortMappingArgs[3].elt = "NewInternalPort"; |
---|
332 | AddPortMappingArgs[3].val = inPort; |
---|
333 | AddPortMappingArgs[4].elt = "NewInternalClient"; |
---|
334 | AddPortMappingArgs[4].val = inClient; |
---|
335 | AddPortMappingArgs[5].elt = "NewEnabled"; |
---|
336 | AddPortMappingArgs[5].val = "1"; |
---|
337 | AddPortMappingArgs[6].elt = "NewPortMappingDescription"; |
---|
338 | AddPortMappingArgs[6].val = desc?desc:"libminiupnpc"; |
---|
339 | AddPortMappingArgs[7].elt = "NewLeaseDuration"; |
---|
340 | AddPortMappingArgs[7].val = "0"; |
---|
341 | simpleUPnPcommand(-1, controlURL, servicetype, "AddPortMapping", AddPortMappingArgs, buffer, &bufsize); |
---|
342 | /*DisplayNameValueList(buffer, bufsize);*/ |
---|
343 | /*buffer[bufsize] = '\0';*/ |
---|
344 | /*puts(buffer);*/ |
---|
345 | ParseNameValue(buffer, bufsize, &pdata); |
---|
346 | resVal = GetValueFromNameValueList(&pdata, "errorCode"); |
---|
347 | if(resVal) { |
---|
348 | /*printf("AddPortMapping errorCode = '%s'\n", resVal); */ |
---|
349 | ret = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
350 | sscanf(resVal, "%d", &ret); |
---|
351 | } else { |
---|
352 | ret = UPNPCOMMAND_SUCCESS; |
---|
353 | } |
---|
354 | ClearNameValueList(&pdata); |
---|
355 | free(AddPortMappingArgs); |
---|
356 | return ret; |
---|
357 | } |
---|
358 | |
---|
359 | LIBSPEC int |
---|
360 | UPNP_DeletePortMapping(const char * controlURL, const char * servicetype, |
---|
361 | const char * extPort, const char * proto, |
---|
362 | const char * remoteHost) |
---|
363 | { |
---|
364 | /*struct NameValueParserData pdata;*/ |
---|
365 | struct UPNParg * DeletePortMappingArgs; |
---|
366 | char buffer[4096]; |
---|
367 | int bufsize = 4096; |
---|
368 | struct NameValueParserData pdata; |
---|
369 | const char * resVal; |
---|
370 | int ret; |
---|
371 | |
---|
372 | if(!extPort || !proto) |
---|
373 | return UPNPCOMMAND_INVALID_ARGS; |
---|
374 | |
---|
375 | DeletePortMappingArgs = calloc(4, sizeof(struct UPNParg)); |
---|
376 | DeletePortMappingArgs[0].elt = "NewRemoteHost"; |
---|
377 | DeletePortMappingArgs[0].val = remoteHost; |
---|
378 | DeletePortMappingArgs[1].elt = "NewExternalPort"; |
---|
379 | DeletePortMappingArgs[1].val = extPort; |
---|
380 | DeletePortMappingArgs[2].elt = "NewProtocol"; |
---|
381 | DeletePortMappingArgs[2].val = proto; |
---|
382 | simpleUPnPcommand(-1, controlURL, servicetype, |
---|
383 | "DeletePortMapping", |
---|
384 | DeletePortMappingArgs, buffer, &bufsize); |
---|
385 | /*DisplayNameValueList(buffer, bufsize);*/ |
---|
386 | ParseNameValue(buffer, bufsize, &pdata); |
---|
387 | resVal = GetValueFromNameValueList(&pdata, "errorCode"); |
---|
388 | if(resVal) { |
---|
389 | ret = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
390 | sscanf(resVal, "%d", &ret); |
---|
391 | } else { |
---|
392 | ret = UPNPCOMMAND_SUCCESS; |
---|
393 | } |
---|
394 | ClearNameValueList(&pdata); |
---|
395 | free(DeletePortMappingArgs); |
---|
396 | return ret; |
---|
397 | } |
---|
398 | |
---|
399 | LIBSPEC int |
---|
400 | UPNP_GetGenericPortMappingEntry(const char * controlURL, |
---|
401 | const char * servicetype, |
---|
402 | const char * index, |
---|
403 | char * extPort, |
---|
404 | char * intClient, |
---|
405 | char * intPort, |
---|
406 | char * protocol, |
---|
407 | char * desc, |
---|
408 | char * enabled, |
---|
409 | char * rHost, |
---|
410 | char * duration) |
---|
411 | { |
---|
412 | struct NameValueParserData pdata; |
---|
413 | struct UPNParg * GetPortMappingArgs; |
---|
414 | char buffer[4096]; |
---|
415 | int bufsize = 4096; |
---|
416 | char * p; |
---|
417 | int r = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
418 | if(!index) |
---|
419 | return UPNPCOMMAND_INVALID_ARGS; |
---|
420 | intClient[0] = '\0'; |
---|
421 | intPort[0] = '\0'; |
---|
422 | GetPortMappingArgs = calloc(2, sizeof(struct UPNParg)); |
---|
423 | GetPortMappingArgs[0].elt = "NewPortMappingIndex"; |
---|
424 | GetPortMappingArgs[0].val = index; |
---|
425 | simpleUPnPcommand(-1, controlURL, servicetype, |
---|
426 | "GetGenericPortMappingEntry", |
---|
427 | GetPortMappingArgs, buffer, &bufsize); |
---|
428 | ParseNameValue(buffer, bufsize, &pdata); |
---|
429 | p = GetValueFromNameValueList(&pdata, "NewRemoteHost"); |
---|
430 | if(p && rHost) |
---|
431 | { |
---|
432 | strncpy(rHost, p, 64); |
---|
433 | rHost[63] = '\0'; |
---|
434 | } |
---|
435 | p = GetValueFromNameValueList(&pdata, "NewExternalPort"); |
---|
436 | if(p && extPort) |
---|
437 | { |
---|
438 | strncpy(extPort, p, 6); |
---|
439 | extPort[5] = '\0'; |
---|
440 | r = UPNPCOMMAND_SUCCESS; |
---|
441 | } |
---|
442 | p = GetValueFromNameValueList(&pdata, "NewProtocol"); |
---|
443 | if(p && protocol) |
---|
444 | { |
---|
445 | strncpy(protocol, p, 4); |
---|
446 | protocol[3] = '\0'; |
---|
447 | } |
---|
448 | p = GetValueFromNameValueList(&pdata, "NewInternalClient"); |
---|
449 | if(p && intClient) |
---|
450 | { |
---|
451 | strncpy(intClient, p, 16); |
---|
452 | intClient[15] = '\0'; |
---|
453 | r = 0; |
---|
454 | } |
---|
455 | p = GetValueFromNameValueList(&pdata, "NewInternalPort"); |
---|
456 | if(p && intPort) |
---|
457 | { |
---|
458 | strncpy(intPort, p, 6); |
---|
459 | intPort[5] = '\0'; |
---|
460 | } |
---|
461 | p = GetValueFromNameValueList(&pdata, "NewEnabled"); |
---|
462 | if(p && enabled) |
---|
463 | { |
---|
464 | strncpy(enabled, p, 4); |
---|
465 | enabled[3] = '\0'; |
---|
466 | } |
---|
467 | p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription"); |
---|
468 | if(p && desc) |
---|
469 | { |
---|
470 | strncpy(desc, p, 80); |
---|
471 | desc[79] = '\0'; |
---|
472 | } |
---|
473 | p = GetValueFromNameValueList(&pdata, "NewLeaseDuration"); |
---|
474 | if(p && duration) |
---|
475 | { |
---|
476 | strncpy(duration, p, 16); |
---|
477 | duration[15] = '\0'; |
---|
478 | } |
---|
479 | p = GetValueFromNameValueList(&pdata, "errorCode"); |
---|
480 | if(p) { |
---|
481 | r = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
482 | sscanf(p, "%d", &r); |
---|
483 | } |
---|
484 | ClearNameValueList(&pdata); |
---|
485 | free(GetPortMappingArgs); |
---|
486 | return r; |
---|
487 | } |
---|
488 | |
---|
489 | LIBSPEC int |
---|
490 | UPNP_GetPortMappingNumberOfEntries(const char * controlURL, |
---|
491 | const char * servicetype, |
---|
492 | unsigned int * numEntries) |
---|
493 | { |
---|
494 | struct NameValueParserData pdata; |
---|
495 | char buffer[4096]; |
---|
496 | int bufsize = 4096; |
---|
497 | char* p; |
---|
498 | int ret = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
499 | simpleUPnPcommand(-1, controlURL, servicetype, "GetPortMappingNumberOfEntries", 0, buffer, &bufsize); |
---|
500 | #ifdef DEBUG |
---|
501 | DisplayNameValueList(buffer, bufsize); |
---|
502 | #endif |
---|
503 | ParseNameValue(buffer, bufsize, &pdata); |
---|
504 | |
---|
505 | p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries"); |
---|
506 | if(numEntries && p) { |
---|
507 | *numEntries = 0; |
---|
508 | sscanf(p, "%u", numEntries); |
---|
509 | ret = UPNPCOMMAND_SUCCESS; |
---|
510 | } |
---|
511 | |
---|
512 | p = GetValueFromNameValueList(&pdata, "errorCode"); |
---|
513 | if(p) { |
---|
514 | ret = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
515 | sscanf(p, "%d", &ret); |
---|
516 | } |
---|
517 | |
---|
518 | ClearNameValueList(&pdata); |
---|
519 | return ret; |
---|
520 | } |
---|
521 | |
---|
522 | /* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping |
---|
523 | * the result is returned in the intClient and intPort strings |
---|
524 | * please provide 16 and 6 bytes of data */ |
---|
525 | LIBSPEC int |
---|
526 | UPNP_GetSpecificPortMappingEntry(const char * controlURL, |
---|
527 | const char * servicetype, |
---|
528 | const char * extPort, |
---|
529 | const char * proto, |
---|
530 | char * intClient, |
---|
531 | char * intPort) |
---|
532 | { |
---|
533 | struct NameValueParserData pdata; |
---|
534 | struct UPNParg * GetPortMappingArgs; |
---|
535 | char buffer[4096]; |
---|
536 | int bufsize = 4096; |
---|
537 | char * p; |
---|
538 | int ret = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
539 | |
---|
540 | if(!intPort || !intClient || !extPort || !proto) |
---|
541 | return UPNPCOMMAND_INVALID_ARGS; |
---|
542 | |
---|
543 | GetPortMappingArgs = calloc(4, sizeof(struct UPNParg)); |
---|
544 | GetPortMappingArgs[0].elt = "NewRemoteHost"; |
---|
545 | GetPortMappingArgs[1].elt = "NewExternalPort"; |
---|
546 | GetPortMappingArgs[1].val = extPort; |
---|
547 | GetPortMappingArgs[2].elt = "NewProtocol"; |
---|
548 | GetPortMappingArgs[2].val = proto; |
---|
549 | simpleUPnPcommand(-1, controlURL, servicetype, |
---|
550 | "GetSpecificPortMappingEntry", |
---|
551 | GetPortMappingArgs, buffer, &bufsize); |
---|
552 | /*fd = simpleUPnPcommand(fd, controlURL, data.servicetype, "GetSpecificPortMappingEntry", AddPortMappingArgs, buffer, &bufsize); */ |
---|
553 | /*DisplayNameValueList(buffer, bufsize);*/ |
---|
554 | ParseNameValue(buffer, bufsize, &pdata); |
---|
555 | |
---|
556 | p = GetValueFromNameValueList(&pdata, "NewInternalClient"); |
---|
557 | if(p) { |
---|
558 | strncpy(intClient, p, 16); |
---|
559 | intClient[15] = '\0'; |
---|
560 | ret = UPNPCOMMAND_SUCCESS; |
---|
561 | } else |
---|
562 | intClient[0] = '\0'; |
---|
563 | |
---|
564 | p = GetValueFromNameValueList(&pdata, "NewInternalPort"); |
---|
565 | if(p) { |
---|
566 | strncpy(intPort, p, 6); |
---|
567 | intPort[5] = '\0'; |
---|
568 | } else |
---|
569 | intPort[0] = '\0'; |
---|
570 | |
---|
571 | p = GetValueFromNameValueList(&pdata, "errorCode"); |
---|
572 | if(p) { |
---|
573 | ret = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
574 | sscanf(p, "%d", &ret); |
---|
575 | } |
---|
576 | |
---|
577 | ClearNameValueList(&pdata); |
---|
578 | free(GetPortMappingArgs); |
---|
579 | return ret; |
---|
580 | } |
---|
581 | |
---|
582 | |
---|