mupnp 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+