1 | /* $Id: upnpcommands.c,v 1.22 2008/12/18 17:45:18 nanard Exp $ */ |
---|
2 | /* Project : miniupnp |
---|
3 | * Author : Thomas Bernard |
---|
4 | * Copyright (c) 2005-2008 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 | const char * remoteHost) |
---|
308 | { |
---|
309 | struct UPNParg * AddPortMappingArgs; |
---|
310 | char buffer[4096]; |
---|
311 | int bufsize = 4096; |
---|
312 | struct NameValueParserData pdata; |
---|
313 | const char * resVal; |
---|
314 | int ret; |
---|
315 | |
---|
316 | if(!inPort || !inClient || !proto || !extPort) |
---|
317 | return UPNPCOMMAND_INVALID_ARGS; |
---|
318 | |
---|
319 | AddPortMappingArgs = calloc(9, sizeof(struct UPNParg)); |
---|
320 | AddPortMappingArgs[0].elt = "NewRemoteHost"; |
---|
321 | AddPortMappingArgs[0].val = remoteHost; |
---|
322 | AddPortMappingArgs[1].elt = "NewExternalPort"; |
---|
323 | AddPortMappingArgs[1].val = extPort; |
---|
324 | AddPortMappingArgs[2].elt = "NewProtocol"; |
---|
325 | AddPortMappingArgs[2].val = proto; |
---|
326 | AddPortMappingArgs[3].elt = "NewInternalPort"; |
---|
327 | AddPortMappingArgs[3].val = inPort; |
---|
328 | AddPortMappingArgs[4].elt = "NewInternalClient"; |
---|
329 | AddPortMappingArgs[4].val = inClient; |
---|
330 | AddPortMappingArgs[5].elt = "NewEnabled"; |
---|
331 | AddPortMappingArgs[5].val = "1"; |
---|
332 | AddPortMappingArgs[6].elt = "NewPortMappingDescription"; |
---|
333 | AddPortMappingArgs[6].val = desc?desc:"libminiupnpc"; |
---|
334 | AddPortMappingArgs[7].elt = "NewLeaseDuration"; |
---|
335 | AddPortMappingArgs[7].val = "0"; |
---|
336 | simpleUPnPcommand(-1, controlURL, servicetype, "AddPortMapping", AddPortMappingArgs, buffer, &bufsize); |
---|
337 | /*DisplayNameValueList(buffer, bufsize);*/ |
---|
338 | /*buffer[bufsize] = '\0';*/ |
---|
339 | /*puts(buffer);*/ |
---|
340 | ParseNameValue(buffer, bufsize, &pdata); |
---|
341 | resVal = GetValueFromNameValueList(&pdata, "errorCode"); |
---|
342 | if(resVal) { |
---|
343 | /*printf("AddPortMapping errorCode = '%s'\n", resVal); */ |
---|
344 | ret = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
345 | sscanf(resVal, "%d", &ret); |
---|
346 | } else { |
---|
347 | ret = UPNPCOMMAND_SUCCESS; |
---|
348 | } |
---|
349 | ClearNameValueList(&pdata); |
---|
350 | free(AddPortMappingArgs); |
---|
351 | return ret; |
---|
352 | } |
---|
353 | |
---|
354 | int |
---|
355 | UPNP_DeletePortMapping(const char * controlURL, const char * servicetype, |
---|
356 | const char * extPort, const char * proto, |
---|
357 | const char * remoteHost) |
---|
358 | { |
---|
359 | /*struct NameValueParserData pdata;*/ |
---|
360 | struct UPNParg * DeletePortMappingArgs; |
---|
361 | char buffer[4096]; |
---|
362 | int bufsize = 4096; |
---|
363 | struct NameValueParserData pdata; |
---|
364 | const char * resVal; |
---|
365 | int ret; |
---|
366 | |
---|
367 | if(!extPort || !proto) |
---|
368 | return UPNPCOMMAND_INVALID_ARGS; |
---|
369 | |
---|
370 | DeletePortMappingArgs = calloc(4, sizeof(struct UPNParg)); |
---|
371 | DeletePortMappingArgs[0].elt = "NewRemoteHost"; |
---|
372 | DeletePortMappingArgs[0].val = remoteHost; |
---|
373 | DeletePortMappingArgs[1].elt = "NewExternalPort"; |
---|
374 | DeletePortMappingArgs[1].val = extPort; |
---|
375 | DeletePortMappingArgs[2].elt = "NewProtocol"; |
---|
376 | DeletePortMappingArgs[2].val = proto; |
---|
377 | simpleUPnPcommand(-1, controlURL, servicetype, |
---|
378 | "DeletePortMapping", |
---|
379 | DeletePortMappingArgs, buffer, &bufsize); |
---|
380 | /*DisplayNameValueList(buffer, bufsize);*/ |
---|
381 | ParseNameValue(buffer, bufsize, &pdata); |
---|
382 | resVal = GetValueFromNameValueList(&pdata, "errorCode"); |
---|
383 | if(resVal) { |
---|
384 | ret = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
385 | sscanf(resVal, "%d", &ret); |
---|
386 | } else { |
---|
387 | ret = UPNPCOMMAND_SUCCESS; |
---|
388 | } |
---|
389 | ClearNameValueList(&pdata); |
---|
390 | free(DeletePortMappingArgs); |
---|
391 | return ret; |
---|
392 | } |
---|
393 | |
---|
394 | int UPNP_GetGenericPortMappingEntry(const char * controlURL, |
---|
395 | const char * servicetype, |
---|
396 | const char * index, |
---|
397 | char * extPort, |
---|
398 | char * intClient, |
---|
399 | char * intPort, |
---|
400 | char * protocol, |
---|
401 | char * desc, |
---|
402 | char * enabled, |
---|
403 | char * rHost, |
---|
404 | char * duration) |
---|
405 | { |
---|
406 | struct NameValueParserData pdata; |
---|
407 | struct UPNParg * GetPortMappingArgs; |
---|
408 | char buffer[4096]; |
---|
409 | int bufsize = 4096; |
---|
410 | char * p; |
---|
411 | int r = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
412 | if(!index) |
---|
413 | return UPNPCOMMAND_INVALID_ARGS; |
---|
414 | intClient[0] = '\0'; |
---|
415 | intPort[0] = '\0'; |
---|
416 | GetPortMappingArgs = calloc(2, sizeof(struct UPNParg)); |
---|
417 | GetPortMappingArgs[0].elt = "NewPortMappingIndex"; |
---|
418 | GetPortMappingArgs[0].val = index; |
---|
419 | simpleUPnPcommand(-1, controlURL, servicetype, |
---|
420 | "GetGenericPortMappingEntry", |
---|
421 | GetPortMappingArgs, buffer, &bufsize); |
---|
422 | ParseNameValue(buffer, bufsize, &pdata); |
---|
423 | p = GetValueFromNameValueList(&pdata, "NewRemoteHost"); |
---|
424 | if(p && rHost) |
---|
425 | { |
---|
426 | strncpy(rHost, p, 64); |
---|
427 | rHost[63] = '\0'; |
---|
428 | } |
---|
429 | p = GetValueFromNameValueList(&pdata, "NewExternalPort"); |
---|
430 | if(p && extPort) |
---|
431 | { |
---|
432 | strncpy(extPort, p, 6); |
---|
433 | extPort[5] = '\0'; |
---|
434 | r = UPNPCOMMAND_SUCCESS; |
---|
435 | } |
---|
436 | p = GetValueFromNameValueList(&pdata, "NewProtocol"); |
---|
437 | if(p && protocol) |
---|
438 | { |
---|
439 | strncpy(protocol, p, 4); |
---|
440 | protocol[3] = '\0'; |
---|
441 | } |
---|
442 | p = GetValueFromNameValueList(&pdata, "NewInternalClient"); |
---|
443 | if(p && intClient) |
---|
444 | { |
---|
445 | strncpy(intClient, p, 16); |
---|
446 | intClient[15] = '\0'; |
---|
447 | r = 0; |
---|
448 | } |
---|
449 | p = GetValueFromNameValueList(&pdata, "NewInternalPort"); |
---|
450 | if(p && intPort) |
---|
451 | { |
---|
452 | strncpy(intPort, p, 6); |
---|
453 | intPort[5] = '\0'; |
---|
454 | } |
---|
455 | p = GetValueFromNameValueList(&pdata, "NewEnabled"); |
---|
456 | if(p && enabled) |
---|
457 | { |
---|
458 | strncpy(enabled, p, 4); |
---|
459 | enabled[3] = '\0'; |
---|
460 | } |
---|
461 | p = GetValueFromNameValueList(&pdata, "NewPortMappingDescription"); |
---|
462 | if(p && desc) |
---|
463 | { |
---|
464 | strncpy(desc, p, 80); |
---|
465 | desc[79] = '\0'; |
---|
466 | } |
---|
467 | p = GetValueFromNameValueList(&pdata, "NewLeaseDuration"); |
---|
468 | if(p && duration) |
---|
469 | { |
---|
470 | strncpy(duration, p, 16); |
---|
471 | duration[15] = '\0'; |
---|
472 | } |
---|
473 | p = GetValueFromNameValueList(&pdata, "errorCode"); |
---|
474 | if(p) { |
---|
475 | r = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
476 | sscanf(p, "%d", &r); |
---|
477 | } |
---|
478 | ClearNameValueList(&pdata); |
---|
479 | free(GetPortMappingArgs); |
---|
480 | return r; |
---|
481 | } |
---|
482 | |
---|
483 | int UPNP_GetPortMappingNumberOfEntries(const char * controlURL, const char * servicetype, unsigned int * numEntries) |
---|
484 | { |
---|
485 | struct NameValueParserData pdata; |
---|
486 | char buffer[4096]; |
---|
487 | int bufsize = 4096; |
---|
488 | char* p; |
---|
489 | int ret = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
490 | simpleUPnPcommand(-1, controlURL, servicetype, "GetPortMappingNumberOfEntries", 0, buffer, &bufsize); |
---|
491 | #ifdef DEBUG |
---|
492 | DisplayNameValueList(buffer, bufsize); |
---|
493 | #endif |
---|
494 | ParseNameValue(buffer, bufsize, &pdata); |
---|
495 | |
---|
496 | p = GetValueFromNameValueList(&pdata, "NewPortMappingNumberOfEntries"); |
---|
497 | if(numEntries && p) { |
---|
498 | *numEntries = 0; |
---|
499 | sscanf(p, "%u", numEntries); |
---|
500 | ret = UPNPCOMMAND_SUCCESS; |
---|
501 | } |
---|
502 | |
---|
503 | p = GetValueFromNameValueList(&pdata, "errorCode"); |
---|
504 | if(p) { |
---|
505 | ret = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
506 | sscanf(p, "%d", &ret); |
---|
507 | } |
---|
508 | |
---|
509 | ClearNameValueList(&pdata); |
---|
510 | return ret; |
---|
511 | } |
---|
512 | |
---|
513 | /* UPNP_GetSpecificPortMappingEntry retrieves an existing port mapping |
---|
514 | * the result is returned in the intClient and intPort strings |
---|
515 | * please provide 16 and 6 bytes of data */ |
---|
516 | int |
---|
517 | UPNP_GetSpecificPortMappingEntry(const char * controlURL, |
---|
518 | const char * servicetype, |
---|
519 | const char * extPort, |
---|
520 | const char * proto, |
---|
521 | char * intClient, |
---|
522 | char * intPort) |
---|
523 | { |
---|
524 | struct NameValueParserData pdata; |
---|
525 | struct UPNParg * GetPortMappingArgs; |
---|
526 | char buffer[4096]; |
---|
527 | int bufsize = 4096; |
---|
528 | char * p; |
---|
529 | int ret = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
530 | |
---|
531 | if(!intPort || !intClient || !extPort || !proto) |
---|
532 | return UPNPCOMMAND_INVALID_ARGS; |
---|
533 | |
---|
534 | GetPortMappingArgs = calloc(4, sizeof(struct UPNParg)); |
---|
535 | GetPortMappingArgs[0].elt = "NewRemoteHost"; |
---|
536 | GetPortMappingArgs[1].elt = "NewExternalPort"; |
---|
537 | GetPortMappingArgs[1].val = extPort; |
---|
538 | GetPortMappingArgs[2].elt = "NewProtocol"; |
---|
539 | GetPortMappingArgs[2].val = proto; |
---|
540 | simpleUPnPcommand(-1, controlURL, servicetype, |
---|
541 | "GetSpecificPortMappingEntry", |
---|
542 | GetPortMappingArgs, buffer, &bufsize); |
---|
543 | /*fd = simpleUPnPcommand(fd, controlURL, data.servicetype, "GetSpecificPortMappingEntry", AddPortMappingArgs, buffer, &bufsize); */ |
---|
544 | /*DisplayNameValueList(buffer, bufsize);*/ |
---|
545 | ParseNameValue(buffer, bufsize, &pdata); |
---|
546 | |
---|
547 | p = GetValueFromNameValueList(&pdata, "NewInternalClient"); |
---|
548 | if(p) { |
---|
549 | strncpy(intClient, p, 16); |
---|
550 | intClient[15] = '\0'; |
---|
551 | ret = UPNPCOMMAND_SUCCESS; |
---|
552 | } else |
---|
553 | intClient[0] = '\0'; |
---|
554 | |
---|
555 | p = GetValueFromNameValueList(&pdata, "NewInternalPort"); |
---|
556 | if(p) { |
---|
557 | strncpy(intPort, p, 6); |
---|
558 | intPort[5] = '\0'; |
---|
559 | } else |
---|
560 | intPort[0] = '\0'; |
---|
561 | |
---|
562 | p = GetValueFromNameValueList(&pdata, "errorCode"); |
---|
563 | if(p) { |
---|
564 | ret = UPNPCOMMAND_UNKNOWN_ERROR; |
---|
565 | sscanf(p, "%d", &ret); |
---|
566 | } |
---|
567 | |
---|
568 | ClearNameValueList(&pdata); |
---|
569 | free(GetPortMappingArgs); |
---|
570 | return ret; |
---|
571 | } |
---|
572 | |
---|
573 | |
---|