miniupnpd 1.9 (20160113)
[tomato.git] / release / src / router / miniupnpd / upnpdescgen.c
blob3c9b17cc0c7c8ad017ee198967758d51f728c6ff
1 /* $Id: upnpdescgen.c,v 1.81 2015/12/15 11:09:56 nanard Exp $ */
2 /* vim: tabstop=4 shiftwidth=4 noexpandtab */
3 /* MiniUPnP project
4 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
5 * (c) 2006-2015 Thomas Bernard
6 * This software is subject to the conditions detailed
7 * in the LICENCE file provided within the distribution */
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <string.h>
13 #include "config.h"
14 #ifdef ENABLE_EVENTS
15 #include "getifaddr.h"
16 #include "upnpredirect.h"
17 #endif
18 #include "upnpdescgen.h"
19 #include "miniupnpdpath.h"
20 #include "upnpglobalvars.h"
21 #include "upnpdescstrings.h"
22 #include "upnpurns.h"
23 #include "getconnstatus.h"
26 /* Event magical values codes */
27 #define SETUPREADY_MAGICALVALUE (248)
28 #define CONNECTIONSTATUS_MAGICALVALUE (249)
29 #define FIREWALLENABLED_MAGICALVALUE (250)
30 #define INBOUNDPINHOLEALLOWED_MAGICALVALUE (251)
31 #define SYSTEMUPDATEID_MAGICALVALUE (252)
32 #define PORTMAPPINGNUMBEROFENTRIES_MAGICALVALUE (253)
33 #define EXTERNALIPADDRESS_MAGICALVALUE (254)
34 #define DEFAULTCONNECTIONSERVICE_MAGICALVALUE (255)
37 static const char * const upnptypes[] =
39 "string",
40 "boolean",
41 "ui2",
42 "ui4",
43 "bin.base64"
46 static const char * const upnpdefaultvalues[] =
49 "IP_Routed"/*"Unconfigured"*/, /* 1 default value for ConnectionType */
50 "3600", /* 2 default value for PortMappingLeaseDuration */
51 "Unconfigured", /* 3 default value for ConnectionStatus */
52 "0", /* 4 default value for RSIPAvailable */
53 "1", /* 5 default value for NATEnabled */
54 "ERROR_NONE", /* 6 default value for LastConnectionError */
57 static const char * const upnpallowedvalues[] =
59 0, /* 0 */
60 "DSL", /* 1 */
61 "POTS",
62 "Cable",
63 "Ethernet",
65 "Up", /* 6 */
66 "Down",
67 "Initializing",
68 "Unavailable",
70 "TCP", /* 11 */
71 "UDP",
73 "Unconfigured", /* 14 */
74 "IP_Routed",
75 "IP_Bridged",
77 "Unconfigured", /* 18 */
78 "Connecting",
79 "Connected",
80 "PendingDisconnect",
81 "Disconnecting",
82 "Disconnected",
84 "ERROR_NONE", /* 25 */
85 /* Optionals values :
86 * ERROR_COMMAND_ABORTED
87 * ERROR_NOT_ENABLED_FOR_INTERNET
88 * ERROR_USER_DISCONNECT
89 * ERROR_ISP_DISCONNECT
90 * ERROR_IDLE_DISCONNECT
91 * ERROR_FORCED_DISCONNECT
92 * ERROR_NO_CARRIER
93 * ERROR_IP_CONFIGURATION
94 * ERROR_UNKNOWN */
96 "", /* 27 */
100 static const int upnpallowedranges[] = {
102 /* 1 PortMappingLeaseDuration */
104 604800,
105 /* 3 InternalPort */
107 65535,
108 /* 5 LeaseTime */
110 86400,
111 /* 7 OutboundPinholeTimeout */
112 100,
113 200,
116 static const char * magicargname[] = {
118 "StartPort", /* 1 */
119 "EndPort", /* 2 */
120 "RemoteHost", /* 3 */
121 "RemotePort", /* 4 */
122 "InternalClient", /* 5 */
123 "InternalPort", /* 6 */
124 "IsWorking", /* 7 */
125 #ifdef ENABLE_DP_SERVICE
126 "ProtocolType", /* 8 */
127 "InMessage", /* 9 */
128 "OutMessage", /* 10 */
129 "ProtocolList", /* 11 */
130 "RoleList", /* 12 */
131 #endif /* ENABLE_DP_SERVICE */
134 static const char xmlver[] =
135 "<?xml version=\"1.0\"?>\r\n";
136 static const char root_service[] =
137 "scpd xmlns=\"urn:schemas-upnp-org:service-1-0\"";
138 static const char root_device[] =
139 "root xmlns=\"urn:schemas-upnp-org:device-1-0\"";
141 /* root Description of the UPnP Device
142 * fixed to match UPnP_IGD_InternetGatewayDevice 1.0.pdf
143 * Needs to be checked with UPnP-gw-InternetGatewayDevice-v2-Device.pdf
144 * presentationURL is only "recommended" but the router doesn't appears
145 * in "Network connections" in Windows XP if it is not present. */
146 static const struct XMLElt rootDesc[] =
148 /* 0 */
149 {root_device, INITHELPER(1,2)},
150 {"specVersion", INITHELPER(3,2)},
151 #if defined(ENABLE_L3F_SERVICE) || defined(HAS_DUMMY_SERVICE) || defined(ENABLE_DP_SERVICE)
152 {"device", INITHELPER(5,13)},
153 #else
154 {"device", INITHELPER(5,12)},
155 #endif
156 {"/major", UPNP_VERSION_MAJOR_STR},
157 {"/minor", UPNP_VERSION_MINOR_STR},
158 /* 5 */
159 {"/deviceType", DEVICE_TYPE_IGD},
160 /* urn:schemas-upnp-org:device:InternetGatewayDevice:1 or 2 */
161 #ifdef ENABLE_MANUFACTURER_INFO_CONFIGURATION
162 {"/friendlyName", friendly_name/*ROOTDEV_FRIENDLYNAME*/}, /* required */
163 {"/manufacturer", manufacturer_name/*ROOTDEV_MANUFACTURER*/}, /* required */
164 /* 8 */
165 {"/manufacturerURL", manufacturer_url/*ROOTDEV_MANUFACTURERURL*/}, /* optional */
166 {"/modelDescription", model_description/*ROOTDEV_MODELDESCRIPTION*/}, /* recommended */
167 {"/modelName", model_name/*ROOTDEV_MODELNAME*/}, /* required */
168 {"/modelNumber", modelnumber},
169 {"/modelURL", model_url/*ROOTDEV_MODELURL*/},
170 #else
171 {"/friendlyName", ROOTDEV_FRIENDLYNAME}, /* required */
172 {"/manufacturer", ROOTDEV_MANUFACTURER}, /* required */
173 /* 8 */
174 {"/manufacturerURL", ROOTDEV_MANUFACTURERURL}, /* optional */
175 {"/modelDescription", ROOTDEV_MODELDESCRIPTION}, /* recommended */
176 {"/modelName", ROOTDEV_MODELNAME}, /* required */
177 {"/modelNumber", modelnumber},
178 {"/modelURL", ROOTDEV_MODELURL},
179 #endif
180 {"/serialNumber", serialnumber},
181 {"/UDN", uuidvalue_igd}, /* required */
182 /* see if /UPC is needed. */
183 #ifdef ENABLE_6FC_SERVICE
184 #define SERVICES_OFFSET 63
185 #else
186 #define SERVICES_OFFSET 58
187 #endif
188 #if defined(ENABLE_L3F_SERVICE) || defined(HAS_DUMMY_SERVICE) || defined(ENABLE_DP_SERVICE)
189 /* here we dening Services for the root device :
190 * L3F and DUMMY and DeviceProtection */
191 #ifdef ENABLE_L3F_SERVICE
192 #define NSERVICES1 1
193 #else
194 #define NSERVICES1 0
195 #endif
196 #ifdef HAS_DUMMY_SERVICE
197 #define NSERVICES2 1
198 #else
199 #define NSERVICES2 0
200 #endif
201 #ifdef ENABLE_DP_SERVICE
202 #define NSERVICES3 1
203 #else
204 #define NSERVICES3 0
205 #endif
206 #define NSERVICES (NSERVICES1+NSERVICES2+NSERVICES3)
207 {"serviceList", INITHELPER(SERVICES_OFFSET,NSERVICES)},
208 {"deviceList", INITHELPER(18,1)},
209 {"/presentationURL", presentationurl}, /* recommended */
210 #else
211 {"deviceList", INITHELPER(18,1)},
212 {"/presentationURL", presentationurl}, /* recommended */
213 {0,0},
214 #endif
215 /* 18 */
216 {"device", INITHELPER(19,13)},
217 /* 19 */
218 {"/deviceType", DEVICE_TYPE_WAN}, /* required */
219 /* urn:schemas-upnp-org:device:WANDevice:1 or 2 */
220 {"/friendlyName", WANDEV_FRIENDLYNAME},
221 {"/manufacturer", WANDEV_MANUFACTURER},
222 {"/manufacturerURL", WANDEV_MANUFACTURERURL},
223 {"/modelDescription" , WANDEV_MODELDESCRIPTION},
224 {"/modelName", WANDEV_MODELNAME},
225 {"/modelNumber", WANDEV_MODELNUMBER},
226 {"/modelURL", WANDEV_MODELURL},
227 {"/serialNumber", serialnumber},
228 {"/UDN", uuidvalue_wan},
229 {"/UPC", WANDEV_UPC}, /* UPC (=12 digit barcode) is optional */
230 /* 30 */
231 {"serviceList", INITHELPER(32,1)},
232 {"deviceList", INITHELPER(38,1)},
233 /* 32 */
234 {"service", INITHELPER(33,5)},
235 /* 33 */
236 {"/serviceType",
237 "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1"},
238 /*{"/serviceId", "urn:upnp-org:serviceId:WANCommonInterfaceConfig"}, */
239 {"/serviceId", "urn:upnp-org:serviceId:WANCommonIFC1"}, /* required */
240 {"/controlURL", WANCFG_CONTROLURL},
241 {"/eventSubURL", WANCFG_EVENTURL},
242 {"/SCPDURL", WANCFG_PATH},
243 /* 38 */
244 {"device", INITHELPER(39,12)},
245 /* 39 */
246 {"/deviceType", DEVICE_TYPE_WANC},
247 /* urn:schemas-upnp-org:device:WANConnectionDevice:1 or 2 */
248 {"/friendlyName", WANCDEV_FRIENDLYNAME},
249 {"/manufacturer", WANCDEV_MANUFACTURER},
250 {"/manufacturerURL", WANCDEV_MANUFACTURERURL},
251 {"/modelDescription", WANCDEV_MODELDESCRIPTION},
252 {"/modelName", WANCDEV_MODELNAME},
253 {"/modelNumber", WANCDEV_MODELNUMBER},
254 {"/modelURL", WANCDEV_MODELURL},
255 {"/serialNumber", serialnumber},
256 {"/UDN", uuidvalue_wcd},
257 {"/UPC", WANCDEV_UPC}, /* UPC (=12 digit Barcode) is optional */
258 #ifdef ENABLE_6FC_SERVICE
259 {"serviceList", INITHELPER(51,2)},
260 #else
261 {"serviceList", INITHELPER(51,1)},
262 #endif
263 /* 51 */
264 {"service", INITHELPER(53,5)},
265 {"service", INITHELPER(58,5)},
266 /* 53 */
267 {"/serviceType", SERVICE_TYPE_WANIPC},
268 /* urn:schemas-upnp-org:service:WANIPConnection:2 for v2 */
269 {"/serviceId", SERVICE_ID_WANIPC},
270 /* urn:upnp-org:serviceId:WANIPConn1 or 2 */
271 {"/controlURL", WANIPC_CONTROLURL},
272 {"/eventSubURL", WANIPC_EVENTURL},
273 {"/SCPDURL", WANIPC_PATH},
274 #ifdef ENABLE_6FC_SERVICE
275 /* 58 */
276 {"/serviceType", "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1"},
277 {"/serviceId", "urn:upnp-org:serviceId:WANIPv6Firewall1"},
278 {"/controlURL", WANIP6FC_CONTROLURL},
279 {"/eventSubURL", WANIP6FC_EVENTURL},
280 {"/SCPDURL", WANIP6FC_PATH},
281 #endif
282 /* 58 / 63 = SERVICES_OFFSET*/
283 #if defined(HAS_DUMMY_SERVICE) || defined(ENABLE_L3F_SERVICE) || defined(ENABLE_DP_SERVICE)
284 {"service", INITHELPER(SERVICES_OFFSET+2,5)},
285 {"service", INITHELPER(SERVICES_OFFSET+7,5)},
286 #endif
287 #ifdef HAS_DUMMY_SERVICE
288 /* 60 / 65 = SERVICES_OFFSET+2 */
289 {"/serviceType", "urn:schemas-dummy-com:service:Dummy:1"},
290 {"/serviceId", "urn:dummy-com:serviceId:dummy1"},
291 {"/controlURL", "/dummy"},
292 {"/eventSubURL", "/dummy"},
293 {"/SCPDURL", DUMMY_PATH},
294 #endif
295 #ifdef ENABLE_L3F_SERVICE
296 /* 60 / 65 = SERVICES_OFFSET+2 */
297 {"/serviceType", "urn:schemas-upnp-org:service:Layer3Forwarding:1"},
298 {"/serviceId", "urn:upnp-org:serviceId:L3Forwarding1"},
299 {"/controlURL", L3F_CONTROLURL}, /* The Layer3Forwarding service is only */
300 {"/eventSubURL", L3F_EVENTURL}, /* recommended, not mandatory */
301 {"/SCPDURL", L3F_PATH},
302 #endif
303 #ifdef ENABLE_DP_SERVICE
304 /* InternetGatewayDevice v2 :
305 * it is RECOMMEDED that DeviceProtection service is implemented and applied.
306 * If DeviceProtection is not implemented and applied, it is RECOMMENDED
307 * that control points are able to access only actions and parameters defined
308 * as Public role. */
309 /* 65 / 70 = SERVICES_OFFSET+7 */
310 {"/serviceType", "urn:schemas-upnp-org:service:DeviceProtection:1"},
311 {"/serviceId", "urn:upnp-org:serviceId:DeviceProtection1"},
312 {"/controlURL", DP_CONTROLURL},
313 {"/eventSubURL", DP_EVENTURL},
314 {"/SCPDURL", DP_PATH},
315 #endif
316 {0, 0}
319 /* WANIPCn.xml */
320 /* see UPnP_IGD_WANIPConnection 1.0.pdf
321 static struct XMLElt scpdWANIPCn[] =
323 {root_service, {INITHELPER(1,2)}},
324 {0, {0}}
327 static const struct argument AddPortMappingArgs[] =
329 {1, 11}, /* RemoteHost */
330 {1, 12}, /* ExternalPort */
331 {1, 14}, /* PortMappingProtocol */
332 {1, 13}, /* InternalPort */
333 {1, 15}, /* InternalClient */
334 {1, 9}, /* PortMappingEnabled */
335 {1, 16}, /* PortMappingDescription */
336 {1, 10}, /* PortMappingLeaseDuration */
337 {0, 0}
340 #ifdef IGD_V2
341 static const struct argument AddAnyPortMappingArgs[] =
343 {1, 11}, /* RemoteHost */
344 {1, 12}, /* ExternalPort */
345 {1, 14}, /* PortMappingProtocol */
346 {1, 13}, /* InternalPort */
347 {1, 15}, /* InternalClient */
348 {1, 9}, /* PortMappingEnabled */
349 {1, 16}, /* PortMappingDescription */
350 {1, 10}, /* PortMappingLeaseDuration */
351 {2, 12}, /* NewReservedPort / ExternalPort */
352 {0, 0}
355 static const struct argument DeletePortMappingRangeArgs[] =
357 {1|(1<<2), 12}, /* NewStartPort / ExternalPort */
358 {1|(2<<2), 12}, /* NewEndPort / ExternalPort */
359 {1, 14}, /* NewProtocol / PortMappingProtocol */
360 {1, 18}, /* NewManage / A_ARG_TYPE_Manage */
361 {0, 0}
364 static const struct argument GetListOfPortMappingsArgs[] =
366 {1|(1<<2), 12}, /* NewStartPort / ExternalPort */
367 {1|(2<<2), 12}, /* NewEndPort / ExternalPort */
368 {1, 14}, /* NewProtocol / PortMappingProtocol */
369 {1, 18}, /* NewManage / A_ARG_TYPE_Manage */
370 {1, 8}, /* NewNumberOfPorts / PortMappingNumberOfEntries */
371 {2, 19}, /* NewPortListing / A_ARG_TYPE_PortListing */
372 {0, 0}
374 #endif
376 static const struct argument GetExternalIPAddressArgs[] =
378 {2, 7},
379 {0, 0}
382 static const struct argument DeletePortMappingArgs[] =
384 {1, 11}, /* RemoteHost */
385 {1, 12}, /* ExternalPort */
386 {1, 14}, /* PortMappingProtocol */
387 {0, 0}
390 static const struct argument SetConnectionTypeArgs[] =
392 {1, 0},
393 {0, 0}
396 static const struct argument GetConnectionTypeInfoArgs[] =
398 {2, 0},
399 {2, 1},
400 {0, 0}
403 static const struct argument GetStatusInfoArgs[] =
405 {2, 2},
406 {2, 4},
407 {2, 3},
408 {0, 0}
411 static const struct argument GetNATRSIPStatusArgs[] =
413 {2, 5},
414 {2, 6},
415 {0, 0}
418 static const struct argument GetGenericPortMappingEntryArgs[] =
420 {1, 8},
421 {2, 11},
422 {2, 12},
423 {2, 14},
424 {2, 13},
425 {2, 15},
426 {2, 9},
427 {2, 16},
428 {2, 10},
429 {0, 0}
432 static const struct argument GetSpecificPortMappingEntryArgs[] =
434 {1, 11},
435 {1, 12},
436 {1, 14},
437 {2, 13},
438 {2, 15},
439 {2, 9},
440 {2, 16},
441 {2, 10},
442 {0, 0}
445 static const struct action WANIPCnActions[] =
447 {"SetConnectionType", SetConnectionTypeArgs}, /* R */
448 {"GetConnectionTypeInfo", GetConnectionTypeInfoArgs}, /* R */
449 {"RequestConnection", 0}, /* R */
450 /*{"RequestTermination", 0},*/ /* O */
451 {"ForceTermination", 0}, /* R */
452 /*{"SetAutoDisconnectTime", 0},*/ /* O */
453 /*{"SetIdleDisconnectTime", 0},*/ /* O */
454 /*{"SetWarnDisconnectDelay", 0}, */ /* O */
455 {"GetStatusInfo", GetStatusInfoArgs}, /* R */
456 /*GetAutoDisconnectTime*/ /* O */
457 /*GetIdleDisconnectTime*/ /* O */
458 /*GetWarnDisconnectDelay*/ /* O */
459 {"GetNATRSIPStatus", GetNATRSIPStatusArgs}, /* R */
460 {"GetGenericPortMappingEntry", GetGenericPortMappingEntryArgs}, /* R */
461 {"GetSpecificPortMappingEntry", GetSpecificPortMappingEntryArgs}, /* R */
462 {"AddPortMapping", AddPortMappingArgs}, /* R */
463 {"DeletePortMapping", DeletePortMappingArgs}, /* R */
464 {"GetExternalIPAddress", GetExternalIPAddressArgs}, /* R */
465 #ifdef IGD_V2
466 {"DeletePortMappingRange", DeletePortMappingRangeArgs}, /* R, IGD v2 */
467 {"GetListOfPortMappings", GetListOfPortMappingsArgs}, /* R, IGD v2 */
468 {"AddAnyPortMapping", AddAnyPortMappingArgs}, /* R, IGD v2 */
469 #endif
470 #if 0
471 {"AddPortMapping", AddPortMappingArgs}, /* R */
472 {"GetExternalIPAddress", GetExternalIPAddressArgs}, /* R */
473 {"DeletePortMapping", DeletePortMappingArgs}, /* R */
474 {"SetConnectionType", SetConnectionTypeArgs}, /* R */
475 {"GetConnectionTypeInfo", GetConnectionTypeInfoArgs}, /* R */
476 {"RequestConnection", 0}, /* R */
477 {"ForceTermination", 0}, /* R */
478 {"GetStatusInfo", GetStatusInfoArgs}, /* R */
479 {"GetNATRSIPStatus", GetNATRSIPStatusArgs}, /* R */
480 {"GetGenericPortMappingEntry", GetGenericPortMappingEntryArgs}, /* R */
481 {"GetSpecificPortMappingEntry", GetSpecificPortMappingEntryArgs}, /* R */
482 /* added in v2 UPnP-gw-WANIPConnection-v2-Service.pdf */
483 #ifdef IGD_V2
484 {"AddAnyPortMapping", AddAnyPortMappingArgs},
485 {"DeletePortMappingRange", DeletePortMappingRangeArgs},
486 {"GetListOfPortMappings", GetListOfPortMappingsArgs},
487 #endif
488 #endif
489 {0, 0}
491 /* R=Required, O=Optional */
493 /* ignore "warning: missing initializer" */
494 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
496 /* struct stateVar :
497 * {name, itype(&event), idefault, iallowedlist, ieventvalue} */
498 static const struct stateVar WANIPCnVars[] =
500 /* 0 */
501 #if 0
502 {"ConnectionType", 0, 0/*1*/}, /* required */
503 {"PossibleConnectionTypes", 0|0x80, 0, 14, 15},
504 #elif 0
505 {"ConnectionType", 0, 1, 14, 15}, /* required */
506 {"PossibleConnectionTypes", 0|0x80, 0, 0, 15},
507 #else
508 {"ConnectionType", 0, 1, 0, 15}, /* required */
509 {"PossibleConnectionTypes", 0|0x80, 0, 14, 15},
510 #endif
511 /* Required
512 * Allowed values : Unconfigured / IP_Routed / IP_Bridged */
513 {"ConnectionStatus", 0|0x80, 3, 18,
514 CONNECTIONSTATUS_MAGICALVALUE }, /* required */
515 /* Allowed Values : Unconfigured / Connecting(opt) / Connected
516 * PendingDisconnect(opt) / Disconnecting (opt)
517 * Disconnected */
518 {"Uptime", 3, 0}, /* Required */
519 {"LastConnectionError", 0, 6, 25}, /* required : */
520 /* Allowed Values : ERROR_NONE(req) / ERROR_COMMAND_ABORTED(opt)
521 * ERROR_NOT_ENABLED_FOR_INTERNET(opt)
522 * ERROR_USER_DISCONNECT(opt)
523 * ERROR_ISP_DISCONNECT(opt)
524 * ERROR_IDLE_DISCONNECT(opt)
525 * ERROR_FORCED_DISCONNECT(opt)
526 * ERROR_NO_CARRIER(opt)
527 * ERROR_IP_CONFIGURATION(opt)
528 * ERROR_UNKNOWN(opt) */
529 {"RSIPAvailable", 1, 4}, /* required */
530 {"NATEnabled", 1, 5}, /* required */
531 {"ExternalIPAddress", 0|0x80, 0, 0,
532 EXTERNALIPADDRESS_MAGICALVALUE}, /* required. Default : empty string */
533 {"PortMappingNumberOfEntries", 2|0x80, 0, 0,
534 PORTMAPPINGNUMBEROFENTRIES_MAGICALVALUE}, /* required >= 0 */
535 {"PortMappingEnabled", 1, 0}, /* Required */
536 /* 10 */
537 {"PortMappingLeaseDuration", 3, 2, 1}, /* required */
538 /* TODO : for IGD v2 :
539 * <stateVariable sendEvents="no">
540 * <name>PortMappingLeaseDuration</name>
541 * <dataType>ui4</dataType>
542 * <defaultValue>Vendor-defined</defaultValue>
543 * <allowedValueRange>
544 * <minimum>0</minimum>
545 * <maximum>604800</maximum>
546 * </allowedValueRange>
547 * </stateVariable> */
548 {"RemoteHost", 0, 0}, /* required. Default : empty string */
549 {"ExternalPort", 2, 0}, /* required */
550 {"InternalPort", 2, 0, 3}, /* required */
551 {"PortMappingProtocol", 0, 0, 11}, /* required allowedValues: TCP/UDP */
552 {"InternalClient", 0, 0}, /* required */
553 {"PortMappingDescription", 0, 0}, /* required default: empty string */
554 /* added in v2 UPnP-gw-WANIPConnection-v2-Service.pdf */
555 #ifdef IGD_V2
556 {"SystemUpdateID", 3|0x80, 0, 0, SYSTEMUPDATEID_MAGICALVALUE},
557 {"A_ARG_TYPE_Manage", 1, 0},
558 {"A_ARG_TYPE_PortListing", 0, 0},
559 #endif
560 {0, 0}
563 static const struct serviceDesc scpdWANIPCn =
564 { WANIPCnActions, WANIPCnVars };
566 /* WANCfg.xml */
567 /* See UPnP_IGD_WANCommonInterfaceConfig 1.0.pdf */
569 static const struct argument GetCommonLinkPropertiesArgs[] =
571 {2, 0},
572 {2, 1},
573 {2, 2},
574 {2, 3},
575 {0, 0}
578 static const struct argument GetTotalBytesSentArgs[] =
580 {2, 4},
581 {0, 0}
584 static const struct argument GetTotalBytesReceivedArgs[] =
586 {2, 5},
587 {0, 0}
590 static const struct argument GetTotalPacketsSentArgs[] =
592 {2, 6},
593 {0, 0}
596 static const struct argument GetTotalPacketsReceivedArgs[] =
598 {2, 7},
599 {0, 0}
602 static const struct action WANCfgActions[] =
604 {"GetCommonLinkProperties", GetCommonLinkPropertiesArgs}, /* Required */
605 {"GetTotalBytesSent", GetTotalBytesSentArgs}, /* optional */
606 {"GetTotalBytesReceived", GetTotalBytesReceivedArgs}, /* optional */
607 {"GetTotalPacketsSent", GetTotalPacketsSentArgs}, /* optional */
608 {"GetTotalPacketsReceived", GetTotalPacketsReceivedArgs}, /* optional */
609 {0, 0}
612 /* See UPnP_IGD_WANCommonInterfaceConfig 1.0.pdf */
613 static const struct stateVar WANCfgVars[] =
615 {"WANAccessType", 0, 0, 1},
616 /* Allowed Values : DSL / POTS / Cable / Ethernet
617 * Default value : empty string */
618 {"Layer1UpstreamMaxBitRate", 3, 0},
619 {"Layer1DownstreamMaxBitRate", 3, 0},
620 {"PhysicalLinkStatus", 0|0x80, 0, 6, 6},
621 /* allowed values :
622 * Up / Down / Initializing (optional) / Unavailable (optionnal)
623 * no Default value
624 * Evented */
625 {"TotalBytesSent", 3, 0}, /* Optional */
626 {"TotalBytesReceived", 3, 0}, /* Optional */
627 {"TotalPacketsSent", 3, 0}, /* Optional */
628 {"TotalPacketsReceived", 3, 0},/* Optional */
629 /*{"MaximumActiveConnections", 2, 0}, // allowed Range value // OPTIONAL */
630 /*{"WANAccessProvider", 0, 0},*/ /* Optional */
631 {0, 0}
634 static const struct serviceDesc scpdWANCfg =
635 { WANCfgActions, WANCfgVars };
637 #ifdef ENABLE_L3F_SERVICE
638 /* Read UPnP_IGD_Layer3Forwarding_1.0.pdf */
639 static const struct argument SetDefaultConnectionServiceArgs[] =
641 {1, 0}, /* in */
642 {0, 0}
645 static const struct argument GetDefaultConnectionServiceArgs[] =
647 {2, 0}, /* out */
648 {0, 0}
651 static const struct action L3FActions[] =
653 {"SetDefaultConnectionService", SetDefaultConnectionServiceArgs}, /* Req */
654 {"GetDefaultConnectionService", GetDefaultConnectionServiceArgs}, /* Req */
655 {0, 0}
658 static const struct stateVar L3FVars[] =
660 {"DefaultConnectionService", 0|0x80, 0, 0,
661 DEFAULTCONNECTIONSERVICE_MAGICALVALUE}, /* Required */
662 {0, 0}
665 static const struct serviceDesc scpdL3F =
666 { L3FActions, L3FVars };
667 #endif
669 #ifdef ENABLE_6FC_SERVICE
670 /* see UPnP-gw-WANIPv6FirewallControl-v1-Service.pdf */
671 static const struct argument GetFirewallStatusArgs[] =
673 {2|0x80, 0}, /* OUT : FirewallEnabled */
674 {2|0x80, 6}, /* OUT : InboundPinholeAllowed */
675 {0, 0}
678 static const struct argument GetOutboundPinholeTimeoutArgs[] =
680 {1|0x80|(3<<2), 1}, /* RemoteHost IN A_ARG_TYPE_IPv6Address */
681 {1|0x80|(4<<2), 2}, /* RemotePort IN A_ARG_TYPE_Port */
682 {1|0x80|(5<<2), 1}, /* InternalClient IN A_ARG_TYPE_IPv6Address */
683 {1|0x80|(6<<2), 2}, /* InternalPort IN A_ARG_TYPE_Port */
684 {1|0x80, 3}, /* Protocol IN A_ARG_TYPE_Protocol */
685 {2|0x80, 7}, /* OutboundPinholeTimeout OUT A_ARG_TYPE_OutboundPinholeTimeout */
686 {0, 0}
689 static const struct argument AddPinholeArgs[] =
691 {1|0x80|(3<<2), 1}, /* RemoteHost IN A_ARG_TYPE_IPv6Address */
692 {1|0x80|(4<<2), 2}, /* RemotePort IN A_ARG_TYPE_Port */
693 {1|0x80|(5<<2), 1}, /* InternalClient IN A_ARG_TYPE_IPv6Address */
694 {1|0x80|(6<<2), 2}, /* InternalPort IN A_ARG_TYPE_Port */
695 {1|0x80, 3}, /* Protocol IN A_ARG_TYPE_Protocol */
696 {1|0x80, 5}, /* LeaseTime IN A_ARG_TYPE_LeaseTime */
697 {2|0x80, 4}, /* UniqueID OUT A_ARG_TYPE_UniqueID */
698 {0, 0}
701 static const struct argument UpdatePinholeArgs[] =
703 {1|0x80, 4}, /* UniqueID IN A_ARG_TYPE_UniqueID */
704 {1, 5}, /* LeaseTime IN A_ARG_TYPE_LeaseTime */
705 {0, 0}
708 static const struct argument DeletePinholeArgs[] =
710 {1|0x80, 4}, /* UniqueID IN A_ARG_TYPE_UniqueID */
711 {0, 0}
714 static const struct argument GetPinholePacketsArgs[] =
716 {1|0x80, 4}, /* UniqueID IN A_ARG_TYPE_UniqueID */
717 {2|0x80, 9}, /* PinholePackets OUT A_ARG_TYPE_PinholePackets */
718 {0, 0}
721 static const struct argument CheckPinholeWorkingArgs[] =
723 {1|0x80, 4}, /* UniqueID IN A_ARG_TYPE_UniqueID */
724 {2|0x80|(7<<2), 8}, /* IsWorking OUT A_ARG_TYPE_Boolean */
725 {0, 0}
728 static const struct action IPv6FCActions[] =
730 {"GetFirewallStatus", GetFirewallStatusArgs}, /* Req */
731 {"GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs}, /* Opt */
732 {"AddPinhole", AddPinholeArgs}, /* Req */
733 {"UpdatePinhole", UpdatePinholeArgs}, /* Req */
734 {"DeletePinhole", DeletePinholeArgs}, /* Req */
735 {"GetPinholePackets", GetPinholePacketsArgs}, /* Req */
736 {"CheckPinholeWorking", CheckPinholeWorkingArgs}, /* Opt */
737 {0, 0}
740 static const struct stateVar IPv6FCVars[] =
742 {"FirewallEnabled", 1|0x80, 0, 0,
743 FIREWALLENABLED_MAGICALVALUE}, /* Required */
744 {"A_ARG_TYPE_IPv6Address", 0, 0, 0, 0}, /* Required */
745 {"A_ARG_TYPE_Port", 2, 0, 0, 0}, /* Required */
746 {"A_ARG_TYPE_Protocol", 2, 0, 0, 0}, /* Required */
747 /* 4 */
748 {"A_ARG_TYPE_UniqueID", 2, 0, 0, 0}, /* Required */
749 {"A_ARG_TYPE_LeaseTime", 3, 0, 5, 0}, /* Required */
750 {"InboundPinholeAllowed", 1|0x80, 0, 0,
751 INBOUNDPINHOLEALLOWED_MAGICALVALUE}, /* Required */
752 {"A_ARG_TYPE_OutboundPinholeTimeout", 3, 0, 7, 0}, /* Optional */
753 /* 8 */
754 {"A_ARG_TYPE_Boolean", 1, 0, 0, 0}, /* Optional */
755 {"A_ARG_TYPE_PinholePackets", 3, 0, 0, 0}, /* Required */
756 {0, 0}
759 static const struct serviceDesc scpd6FC =
760 { IPv6FCActions, IPv6FCVars };
761 #endif
763 #ifdef ENABLE_DP_SERVICE
764 /* UPnP-gw-DeviceProtection-v1-Service.pdf */
766 static const struct argument SendSetupMessageArgs[] =
768 {1|0x80|(8<<2), 6}, /* ProtocolType : in ProtocolType / A_ARG_TYPE_String */
769 {1|0x80|(9<<2), 5}, /* InMessage : in InMessage / A_ARG_TYPE_Base64 */
770 {2|0x80|(10<<2), 5}, /* OutMessage : out OutMessage / A_ARG_TYPE_Base64 */
771 {0, 0}
774 static const struct argument GetSupportedProtocolsArgs[] =
776 {2|0x80|(11<<2), 1}, /* ProtocolList : out ProtocolList / SupportedProtocols */
777 {0, 0}
780 static const struct argument GetAssignedRolesArgs[] =
782 {2|0x80|(12<<2), 6}, /* RoleList : out RoleList / A_ARG_TYPE_String */
783 {0, 0}
786 static const struct action DPActions[] =
788 {"SendSetupMessage", SendSetupMessageArgs},
789 {"GetSupportedProtocols", GetSupportedProtocolsArgs},
790 {"GetAssignedRoles", GetAssignedRolesArgs},
791 {0, 0}
794 static const struct stateVar DPVars[] =
796 {"SetupReady", 1|0x80, 0, 0, SETUPREADY_MAGICALVALUE},
797 {"SupportedProtocols", 0},
798 {"A_ARG_TYPE_ACL", 0},
799 {"A_ARG_TYPE_IdentityList", 0},
800 {"A_ARG_TYPE_Identity", 0},
801 {"A_ARG_TYPE_Base64", 4},
802 {"A_ARG_TYPE_String", 0},
803 {0, 0}
806 static const struct serviceDesc scpdDP =
807 { DPActions, DPVars };
808 #endif
810 /* strcat_str()
811 * concatenate the string and use realloc to increase the
812 * memory buffer if needed. */
813 static char *
814 strcat_str(char * str, int * len, int * tmplen, const char * s2)
816 int s2len;
817 int newlen;
818 char * p;
820 s2len = (int)strlen(s2);
821 if(*tmplen <= (*len + s2len))
823 if(s2len < 256)
824 newlen = *tmplen + 256;
825 else
826 newlen = *tmplen + s2len + 1;
827 p = (char *)realloc(str, newlen);
828 if(p == NULL) /* handle a failure of realloc() */
829 return str;
830 str = p;
831 *tmplen = newlen;
833 /*strcpy(str + *len, s2); */
834 memcpy(str + *len, s2, s2len + 1);
835 *len += s2len;
836 return str;
839 /* strcat_char() :
840 * concatenate a character and use realloc to increase the
841 * size of the memory buffer if needed */
842 static char *
843 strcat_char(char * str, int * len, int * tmplen, char c)
845 char * p;
847 if(*tmplen <= (*len + 1))
849 *tmplen += 256;
850 p = (char *)realloc(str, *tmplen);
851 if(p == NULL) /* handle a failure of realloc() */
853 *tmplen -= 256;
854 return str;
856 str = p;
858 str[*len] = c;
859 (*len)++;
860 return str;
863 /* strcat_int()
864 * concatenate the string representation of the integer.
865 * call strcat_char() */
866 static char *
867 strcat_int(char * str, int * len, int * tmplen, int i)
869 char buf[16];
870 int j;
872 if(i < 0) {
873 str = strcat_char(str, len, tmplen, '-');
874 i = -i;
875 } else if(i == 0) {
876 /* special case for 0 */
877 str = strcat_char(str, len, tmplen, '0');
878 return str;
880 j = 0;
881 while(i && j < (int)sizeof(buf)) {
882 buf[j++] = '0' + (i % 10);
883 i = i / 10;
885 while(j > 0) {
886 str = strcat_char(str, len, tmplen, buf[--j]);
888 return str;
891 /* iterative subroutine using a small stack
892 * This way, the progam stack usage is kept low */
893 static char *
894 genXML(char * str, int * len, int * tmplen,
895 const struct XMLElt * p)
897 unsigned short i, j;
898 unsigned long k;
899 int top;
900 const char * eltname, *s;
901 char c;
902 struct {
903 unsigned short i;
904 unsigned short j;
905 const char * eltname;
906 } pile[16]; /* stack */
907 top = -1;
908 i = 0; /* current node */
909 j = 1; /* i + number of nodes*/
910 for(;;)
912 eltname = p[i].eltname;
913 if(!eltname)
914 return str;
915 if(eltname[0] == '/')
917 if(p[i].data && p[i].data[0])
919 /*printf("<%s>%s<%s>\n", eltname+1, p[i].data, eltname); */
920 str = strcat_char(str, len, tmplen, '<');
921 str = strcat_str(str, len, tmplen, eltname+1);
922 str = strcat_char(str, len, tmplen, '>');
923 str = strcat_str(str, len, tmplen, p[i].data);
924 str = strcat_char(str, len, tmplen, '<');
925 str = strcat_str(str, len, tmplen, eltname);
926 str = strcat_char(str, len, tmplen, '>');
928 for(;;)
930 if(top < 0)
931 return str;
932 i = ++(pile[top].i);
933 j = pile[top].j;
934 /*printf(" pile[%d]\t%d %d\n", top, i, j); */
935 if(i==j)
937 /*printf("</%s>\n", pile[top].eltname); */
938 str = strcat_char(str, len, tmplen, '<');
939 str = strcat_char(str, len, tmplen, '/');
940 s = pile[top].eltname;
941 for(c = *s; c > ' '; c = *(++s))
942 str = strcat_char(str, len, tmplen, c);
943 str = strcat_char(str, len, tmplen, '>');
944 top--;
946 else
947 break;
950 else
952 /*printf("<%s>\n", eltname); */
953 str = strcat_char(str, len, tmplen, '<');
954 str = strcat_str(str, len, tmplen, eltname);
955 str = strcat_char(str, len, tmplen, '>');
956 k = (unsigned long)p[i].data;
957 i = k & 0xffff;
958 j = i + (k >> 16);
959 top++;
960 /*printf(" +pile[%d]\t%d %d\n", top, i, j); */
961 pile[top].i = i;
962 pile[top].j = j;
963 pile[top].eltname = eltname;
968 /* genRootDesc() :
969 * - Generate the root description of the UPnP device.
970 * - the len argument is used to return the length of
971 * the returned string.
972 * - tmp_uuid argument is used to build the uuid string */
973 char *
974 genRootDesc(int * len)
976 char * str;
977 int tmplen;
978 tmplen = 2048;
979 str = (char *)malloc(tmplen);
980 if(str == NULL)
981 return NULL;
982 * len = strlen(xmlver);
983 /*strcpy(str, xmlver); */
984 memcpy(str, xmlver, *len + 1);
985 str = genXML(str, len, &tmplen, rootDesc);
986 str[*len] = '\0';
987 return str;
990 /* genServiceDesc() :
991 * Generate service description with allowed methods and
992 * related variables. */
993 static char *
994 genServiceDesc(int * len, const struct serviceDesc * s)
996 int i, j;
997 const struct action * acts;
998 const struct stateVar * vars;
999 const struct argument * args;
1000 const char * p;
1001 char * str;
1002 int tmplen;
1003 tmplen = 2048;
1004 str = (char *)malloc(tmplen);
1005 if(str == NULL)
1006 return NULL;
1007 /*strcpy(str, xmlver); */
1008 *len = strlen(xmlver);
1009 memcpy(str, xmlver, *len + 1);
1011 acts = s->actionList;
1012 vars = s->serviceStateTable;
1014 str = strcat_char(str, len, &tmplen, '<');
1015 str = strcat_str(str, len, &tmplen, root_service);
1016 str = strcat_char(str, len, &tmplen, '>');
1018 str = strcat_str(str, len, &tmplen,
1019 "<specVersion><major>" UPNP_VERSION_MAJOR_STR "</major>"
1020 "<minor>" UPNP_VERSION_MINOR_STR "</minor></specVersion>");
1022 i = 0;
1023 str = strcat_str(str, len, &tmplen, "<actionList>");
1024 while(acts[i].name)
1026 str = strcat_str(str, len, &tmplen, "<action><name>");
1027 str = strcat_str(str, len, &tmplen, acts[i].name);
1028 str = strcat_str(str, len, &tmplen, "</name>");
1029 /* argument List */
1030 args = acts[i].args;
1031 if(args)
1033 str = strcat_str(str, len, &tmplen, "<argumentList>");
1034 j = 0;
1035 while(args[j].dir)
1037 str = strcat_str(str, len, &tmplen, "<argument><name>");
1038 if((args[j].dir & 0x80) == 0) {
1039 str = strcat_str(str, len, &tmplen, "New");
1041 p = vars[args[j].relatedVar].name;
1042 if(args[j].dir & 0x7c) {
1043 /* use magic values ... */
1044 str = strcat_str(str, len, &tmplen, magicargname[(args[j].dir & 0x7c) >> 2]);
1045 } else if(0 == memcmp(p, "PortMapping", 11)
1046 && 0 != memcmp(p + 11, "Description", 11)) {
1047 if(0 == memcmp(p + 11, "NumberOfEntries", 15)) {
1048 /* PortMappingNumberOfEntries */
1049 #ifdef IGD_V2
1050 if(0 == memcmp(acts[i].name, "GetListOfPortMappings", 22)) {
1051 str = strcat_str(str, len, &tmplen, "NumberOfPorts");
1052 } else {
1053 str = strcat_str(str, len, &tmplen, "PortMappingIndex");
1055 #else
1056 str = strcat_str(str, len, &tmplen, "PortMappingIndex");
1057 #endif
1058 } else {
1059 /* PortMappingEnabled
1060 * PortMappingLeaseDuration
1061 * PortMappingProtocol */
1062 str = strcat_str(str, len, &tmplen, p + 11);
1064 #ifdef IGD_V2
1065 } else if(0 == memcmp(p, "A_ARG_TYPE_", 11)) {
1066 str = strcat_str(str, len, &tmplen, p + 11);
1067 } else if(0 == memcmp(p, "ExternalPort", 13)
1068 && args[j].dir == 2
1069 && 0 == memcmp(acts[i].name, "AddAnyPortMapping", 18)) {
1070 str = strcat_str(str, len, &tmplen, "ReservedPort");
1071 #endif
1072 } else {
1073 str = strcat_str(str, len, &tmplen, p);
1075 str = strcat_str(str, len, &tmplen, "</name><direction>");
1076 str = strcat_str(str, len, &tmplen, (args[j].dir&0x03)==1?"in":"out");
1077 str = strcat_str(str, len, &tmplen,
1078 "</direction><relatedStateVariable>");
1079 str = strcat_str(str, len, &tmplen, p);
1080 str = strcat_str(str, len, &tmplen,
1081 "</relatedStateVariable></argument>");
1082 j++;
1084 str = strcat_str(str, len, &tmplen,"</argumentList>");
1086 str = strcat_str(str, len, &tmplen, "</action>");
1087 /*str = strcat_char(str, len, &tmplen, '\n'); // TEMP ! */
1088 i++;
1090 str = strcat_str(str, len, &tmplen, "</actionList><serviceStateTable>");
1091 i = 0;
1092 while(vars[i].name)
1094 str = strcat_str(str, len, &tmplen,
1095 "<stateVariable sendEvents=\"");
1096 #ifdef ENABLE_EVENTS
1097 str = strcat_str(str, len, &tmplen, (vars[i].itype & 0x80)?"yes":"no");
1098 #else
1099 /* for the moment always send no. Wait for SUBSCRIBE implementation
1100 * before setting it to yes */
1101 str = strcat_str(str, len, &tmplen, "no");
1102 #endif
1103 str = strcat_str(str, len, &tmplen, "\"><name>");
1104 str = strcat_str(str, len, &tmplen, vars[i].name);
1105 str = strcat_str(str, len, &tmplen, "</name><dataType>");
1106 str = strcat_str(str, len, &tmplen, upnptypes[vars[i].itype & 0x0f]);
1107 str = strcat_str(str, len, &tmplen, "</dataType>");
1108 if(vars[i].iallowedlist)
1110 if((vars[i].itype & 0x0f) == 0)
1112 /* string */
1113 str = strcat_str(str, len, &tmplen, "<allowedValueList>");
1114 for(j=vars[i].iallowedlist; upnpallowedvalues[j]; j++)
1116 str = strcat_str(str, len, &tmplen, "<allowedValue>");
1117 str = strcat_str(str, len, &tmplen, upnpallowedvalues[j]);
1118 str = strcat_str(str, len, &tmplen, "</allowedValue>");
1120 str = strcat_str(str, len, &tmplen, "</allowedValueList>");
1121 } else {
1122 /* ui2 and ui4 */
1123 str = strcat_str(str, len, &tmplen, "<allowedValueRange><minimum>");
1124 str = strcat_int(str, len, &tmplen, upnpallowedranges[vars[i].iallowedlist]);
1125 str = strcat_str(str, len, &tmplen, "</minimum><maximum>");
1126 str = strcat_int(str, len, &tmplen, upnpallowedranges[vars[i].iallowedlist+1]);
1127 str = strcat_str(str, len, &tmplen, "</maximum></allowedValueRange>");
1130 /*if(vars[i].defaultValue) */
1131 if(vars[i].idefault)
1133 str = strcat_str(str, len, &tmplen, "<defaultValue>");
1134 /*str = strcat_str(str, len, &tmplen, vars[i].defaultValue); */
1135 str = strcat_str(str, len, &tmplen, upnpdefaultvalues[vars[i].idefault]);
1136 str = strcat_str(str, len, &tmplen, "</defaultValue>");
1138 str = strcat_str(str, len, &tmplen, "</stateVariable>");
1139 /*str = strcat_char(str, len, &tmplen, '\n'); // TEMP ! */
1140 i++;
1142 str = strcat_str(str, len, &tmplen, "</serviceStateTable></scpd>");
1143 str[*len] = '\0';
1144 return str;
1147 /* genWANIPCn() :
1148 * Generate the WANIPConnection xml description */
1149 char *
1150 genWANIPCn(int * len)
1152 return genServiceDesc(len, &scpdWANIPCn);
1155 /* genWANCfg() :
1156 * Generate the WANInterfaceConfig xml description. */
1157 char *
1158 genWANCfg(int * len)
1160 return genServiceDesc(len, &scpdWANCfg);
1163 #ifdef ENABLE_L3F_SERVICE
1164 char *
1165 genL3F(int * len)
1167 return genServiceDesc(len, &scpdL3F);
1169 #endif
1171 #ifdef ENABLE_6FC_SERVICE
1172 char *
1173 gen6FC(int * len)
1175 return genServiceDesc(len, &scpd6FC);
1177 #endif
1179 #ifdef ENABLE_DP_SERVICE
1180 char *
1181 genDP(int * len)
1183 return genServiceDesc(len, &scpdDP);
1185 #endif
1187 #ifdef ENABLE_EVENTS
1188 static char *
1189 genEventVars(int * len, const struct serviceDesc * s)
1191 char tmp[16];
1192 const struct stateVar * v;
1193 char * str;
1194 int tmplen;
1195 tmplen = 512;
1196 str = (char *)malloc(tmplen);
1197 if(str == NULL)
1198 return NULL;
1199 *len = 0;
1200 v = s->serviceStateTable;
1201 str = strcat_str(str, len, &tmplen, "<e:propertyset xmlns:e=\"urn:schemas-upnp-org:event-1-0\">");
1202 while(v->name) {
1203 if(v->itype & 0x80) {
1204 str = strcat_str(str, len, &tmplen, "<e:property><");
1205 str = strcat_str(str, len, &tmplen, v->name);
1206 str = strcat_str(str, len, &tmplen, ">");
1207 /*printf("<e:property><%s>", v->name);*/
1208 switch(v->ieventvalue) {
1209 case 0:
1210 break;
1211 #ifdef ENABLE_DP_SERVICE
1212 case SETUPREADY_MAGICALVALUE:
1213 /* always ready for setup */
1214 snprintf(tmp, sizeof(tmp), "%d", 1);
1215 str = strcat_str(str, len, &tmplen, tmp);
1216 break;
1217 #endif
1218 case CONNECTIONSTATUS_MAGICALVALUE:
1219 /* or get_wan_connection_status_str(ext_if_name) */
1220 str = strcat_str(str, len, &tmplen,
1221 upnpallowedvalues[18 + get_wan_connection_status(ext_if_name)]);
1222 break;
1223 #ifdef ENABLE_6FC_SERVICE
1224 case FIREWALLENABLED_MAGICALVALUE:
1225 /* see 2.4.2 of UPnP-gw-WANIPv6FirewallControl-v1-Service.pdf */
1226 snprintf(tmp, sizeof(tmp), "%d",
1227 GETFLAG(IPV6FCFWDISABLEDMASK) ? 0 : 1);
1228 str = strcat_str(str, len, &tmplen, tmp);
1229 break;
1230 case INBOUNDPINHOLEALLOWED_MAGICALVALUE:
1231 /* see 2.4.3 of UPnP-gw-WANIPv6FirewallControl-v1-Service.pdf */
1232 snprintf(tmp, sizeof(tmp), "%d",
1233 GETFLAG(IPV6FCINBOUNDDISALLOWEDMASK) ? 0 : 1);
1234 str = strcat_str(str, len, &tmplen, tmp);
1235 break;
1236 #endif
1237 #ifdef IGD_V2
1238 case SYSTEMUPDATEID_MAGICALVALUE:
1239 /* Please read section 2.3.23 SystemUpdateID
1240 * of UPnP-gw-WANIPConnection-v2-Service.pdf */
1241 snprintf(tmp, sizeof(tmp), "%d",
1242 1/* system update id */);
1243 str = strcat_str(str, len, &tmplen, tmp);
1244 break;
1245 #endif
1246 case PORTMAPPINGNUMBEROFENTRIES_MAGICALVALUE:
1247 /* Port mapping number of entries magical value */
1248 snprintf(tmp, sizeof(tmp), "%d",
1249 upnp_get_portmapping_number_of_entries());
1250 str = strcat_str(str, len, &tmplen, tmp);
1251 break;
1252 case EXTERNALIPADDRESS_MAGICALVALUE:
1253 /* External ip address magical value */
1254 if(use_ext_ip_addr)
1255 str = strcat_str(str, len, &tmplen, use_ext_ip_addr);
1256 else {
1257 char ext_ip_addr[INET_ADDRSTRLEN];
1258 if(getifaddr(ext_if_name, ext_ip_addr, INET_ADDRSTRLEN, NULL, NULL) < 0) {
1259 str = strcat_str(str, len, &tmplen, "0.0.0.0");
1260 } else {
1261 str = strcat_str(str, len, &tmplen, ext_ip_addr);
1264 break;
1265 case DEFAULTCONNECTIONSERVICE_MAGICALVALUE:
1266 /* DefaultConnectionService magical value */
1267 str = strcat_str(str, len, &tmplen, uuidvalue_wcd);
1268 #ifdef IGD_V2
1269 str = strcat_str(str, len, &tmplen, ":WANConnectionDevice:2,urn:upnp-org:serviceId:WANIPConn1");
1270 #else
1271 str = strcat_str(str, len, &tmplen, ":WANConnectionDevice:1,urn:upnp-org:serviceId:WANIPConn1");
1272 #endif
1273 break;
1274 default:
1275 str = strcat_str(str, len, &tmplen, upnpallowedvalues[v->ieventvalue]);
1277 str = strcat_str(str, len, &tmplen, "</");
1278 str = strcat_str(str, len, &tmplen, v->name);
1279 str = strcat_str(str, len, &tmplen, "></e:property>");
1280 /*printf("</%s></e:property>\n", v->name);*/
1282 v++;
1284 str = strcat_str(str, len, &tmplen, "</e:propertyset>");
1285 #if 0
1286 printf("</e:propertyset>\n");
1287 printf("\n");
1288 printf("%d\n", tmplen);
1289 #endif
1290 str[*len] = '\0';
1291 return str;
1294 char *
1295 getVarsWANIPCn(int * l)
1297 return genEventVars(l,
1298 &scpdWANIPCn);
1301 char *
1302 getVarsWANCfg(int * l)
1304 return genEventVars(l,
1305 &scpdWANCfg);
1308 #ifdef ENABLE_L3F_SERVICE
1309 char *
1310 getVarsL3F(int * l)
1312 return genEventVars(l,
1313 &scpdL3F);
1315 #endif
1317 #ifdef ENABLE_6FC_SERVICE
1318 char *
1319 getVars6FC(int * l)
1321 return genEventVars(l,
1322 &scpd6FC);
1324 #endif
1326 #ifdef ENABLE_DP_SERVICE
1327 char *
1328 getVarsDP(int * l)
1330 return genEventVars(l,
1331 &scpdDP);
1333 #endif
1335 #endif /* ENABLE_EVENTS */