BCM WL 6.30.102.9 (r366174)
[tomato.git] / release / src / router / miniupnpd / upnpdescgen.c
blob754e06ddd2855bc00e6da411bb47bb3004db1483
1 /* $Id: upnpdescgen.c,v 1.72 2013/03/23 10:46:55 nanard Exp $ */
2 /* MiniUPnP project
3 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
4 * (c) 2006-2013 Thomas Bernard
5 * This software is subject to the conditions detailed
6 * in the LICENCE file provided within the distribution */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <string.h>
12 #include "config.h"
13 #ifdef ENABLE_EVENTS
14 #include "getifaddr.h"
15 #include "upnpredirect.h"
16 #endif
17 #include "upnpdescgen.h"
18 #include "miniupnpdpath.h"
19 #include "upnpglobalvars.h"
20 #include "upnpdescstrings.h"
21 #include "upnpurns.h"
22 #include "getconnstatus.h"
25 /* Event magical values codes */
26 #define CONNECTIONSTATUS_MAGICALVALUE (249)
27 #define FIREWALLENABLED_MAGICALVALUE (250)
28 #define INBOUNDPINHOLEALLOWED_MAGICALVALUE (251)
29 #define SYSTEMUPDATEID_MAGICALVALUE (252)
30 #define PORTMAPPINGNUMBEROFENTRIES_MAGICALVALUE (253)
31 #define EXTERNALIPADDRESS_MAGICALVALUE (254)
32 #define DEFAULTCONNECTIONSERVICE_MAGICALVALUE (255)
35 static const char * const upnptypes[] =
37 "string",
38 "boolean",
39 "ui2",
40 "ui4",
41 "bin.base64"
44 static const char * const upnpdefaultvalues[] =
47 "IP_Routed"/*"Unconfigured"*/, /* 1 default value for ConnectionType */
48 "3600", /* 2 default value for PortMappingLeaseDuration */
51 static const char * const upnpallowedvalues[] =
53 0, /* 0 */
54 "DSL", /* 1 */
55 "POTS",
56 "Cable",
57 "Ethernet",
59 "Up", /* 6 */
60 "Down",
61 "Initializing",
62 "Unavailable",
64 "TCP", /* 11 */
65 "UDP",
67 "Unconfigured", /* 14 */
68 "IP_Routed",
69 "IP_Bridged",
71 "Unconfigured", /* 18 */
72 "Connecting",
73 "Connected",
74 "PendingDisconnect",
75 "Disconnecting",
76 "Disconnected",
78 "ERROR_NONE", /* 25 */
79 /* Optionals values :
80 * ERROR_COMMAND_ABORTED
81 * ERROR_NOT_ENABLED_FOR_INTERNET
82 * ERROR_USER_DISCONNECT
83 * ERROR_ISP_DISCONNECT
84 * ERROR_IDLE_DISCONNECT
85 * ERROR_FORCED_DISCONNECT
86 * ERROR_NO_CARRIER
87 * ERROR_IP_CONFIGURATION
88 * ERROR_UNKNOWN */
90 "", /* 27 */
94 static const int upnpallowedranges[] = {
96 /* 1 PortMappingLeaseDuration */
98 604800,
99 /* 3 InternalPort */
101 65535,
102 /* 5 LeaseTime */
104 86400,
105 /* 7 OutboundPinholeTimeout */
106 100,
107 200,
110 static const char * magicargname[] = {
112 "StartPort",
113 "EndPort",
114 "RemoteHost",
115 "RemotePort",
116 "InternalClient",
117 "InternalPort",
118 "IsWorking"
121 static const char xmlver[] =
122 "<?xml version=\"1.0\"?>\r\n";
123 static const char root_service[] =
124 "scpd xmlns=\"urn:schemas-upnp-org:service-1-0\"";
125 static const char root_device[] =
126 "root xmlns=\"urn:schemas-upnp-org:device-1-0\"";
128 /* root Description of the UPnP Device
129 * fixed to match UPnP_IGD_InternetGatewayDevice 1.0.pdf
130 * Needs to be checked with UPnP-gw-InternetGatewayDevice-v2-Device.pdf
131 * presentationURL is only "recommended" but the router doesn't appears
132 * in "Network connections" in Windows XP if it is not present. */
133 static const struct XMLElt rootDesc[] =
135 /* 0 */
136 {root_device, INITHELPER(1,2)},
137 {"specVersion", INITHELPER(3,2)},
138 #if defined(ENABLE_L3F_SERVICE) || defined(HAS_DUMMY_SERVICE) || defined(ENABLE_DP_SERVICE)
139 {"device", INITHELPER(5,13)},
140 #else
141 {"device", INITHELPER(5,12)},
142 #endif
143 {"/major", "1"},
144 {"/minor", "0"},
145 /* 5 */
146 {"/deviceType", DEVICE_TYPE_IGD},
147 /* urn:schemas-upnp-org:device:InternetGatewayDevice:1 or 2 */
148 {"/friendlyName", friendly_name/*ROOTDEV_FRIENDLYNAME*/}, /* required */
149 {"/manufacturer", ROOTDEV_MANUFACTURER}, /* required */
150 /* 8 */
151 {"/manufacturerURL", ROOTDEV_MANUFACTURERURL}, /* optional */
152 {"/modelDescription", ROOTDEV_MODELDESCRIPTION}, /* recommended */
153 {"/modelName", ROOTDEV_MODELNAME}, /* required */
154 {"/modelNumber", modelnumber},
155 {"/modelURL", ROOTDEV_MODELURL},
156 {"/serialNumber", serialnumber},
157 {"/UDN", uuidvalue}, /* required */
158 /* see if /UPC is needed. */
159 #ifdef ENABLE_6FC_SERVICE
160 #define SERVICES_OFFSET 63
161 #else
162 #define SERVICES_OFFSET 58
163 #endif
164 #if defined(ENABLE_L3F_SERVICE) || defined(HAS_DUMMY_SERVICE) || defined(ENABLE_DP_SERVICE)
165 /* here we dening Services for the root device :
166 * L3F and DUMMY and DeviceProtection */
167 #ifdef ENABLE_L3F_SERVICE
168 #define NSERVICES1 1
169 #else
170 #define NSERVICES1 0
171 #endif
172 #ifdef HAS_DUMMY_SERVICE
173 #define NSERVICES2 1
174 #else
175 #define NSERVICES2 0
176 #endif
177 #ifdef ENABLE_DP_SERVICE
178 #define NSERVICES3 1
179 #else
180 #define NSERVICES3 0
181 #endif
182 #define NSERVICES (NSERVICES1+NSERVICES2+NSERVICES3)
183 {"serviceList", INITHELPER(SERVICES_OFFSET,NSERVICES)},
184 {"deviceList", INITHELPER(18,1)},
185 {"/presentationURL", presentationurl}, /* recommended */
186 #else
187 {"deviceList", INITHELPER(18,1)},
188 {"/presentationURL", presentationurl}, /* recommended */
189 {0,0},
190 #endif
191 /* 18 */
192 {"device", INITHELPER(19,13)},
193 /* 19 */
194 {"/deviceType", DEVICE_TYPE_WAN}, /* required */
195 /* urn:schemas-upnp-org:device:WANDevice:1 or 2 */
196 {"/friendlyName", WANDEV_FRIENDLYNAME},
197 {"/manufacturer", WANDEV_MANUFACTURER},
198 {"/manufacturerURL", WANDEV_MANUFACTURERURL},
199 {"/modelDescription" , WANDEV_MODELDESCRIPTION},
200 {"/modelName", WANDEV_MODELNAME},
201 {"/modelNumber", WANDEV_MODELNUMBER},
202 {"/modelURL", WANDEV_MODELURL},
203 {"/serialNumber", serialnumber},
204 {"/UDN", uuidvalue},
205 {"/UPC", WANDEV_UPC}, /* UPC (=12 digit barcode) is optional */
206 /* 30 */
207 {"serviceList", INITHELPER(32,1)},
208 {"deviceList", INITHELPER(38,1)},
209 /* 32 */
210 {"service", INITHELPER(33,5)},
211 /* 33 */
212 {"/serviceType",
213 "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1"},
214 /*{"/serviceId", "urn:upnp-org:serviceId:WANCommonInterfaceConfig"}, */
215 {"/serviceId", "urn:upnp-org:serviceId:WANCommonIFC1"}, /* required */
216 {"/controlURL", WANCFG_CONTROLURL},
217 {"/eventSubURL", WANCFG_EVENTURL},
218 {"/SCPDURL", WANCFG_PATH},
219 /* 38 */
220 {"device", INITHELPER(39,12)},
221 /* 39 */
222 {"/deviceType", DEVICE_TYPE_WANC},
223 /* urn:schemas-upnp-org:device:WANConnectionDevice:1 or 2 */
224 {"/friendlyName", WANCDEV_FRIENDLYNAME},
225 {"/manufacturer", WANCDEV_MANUFACTURER},
226 {"/manufacturerURL", WANCDEV_MANUFACTURERURL},
227 {"/modelDescription", WANCDEV_MODELDESCRIPTION},
228 {"/modelName", WANCDEV_MODELNAME},
229 {"/modelNumber", WANCDEV_MODELNUMBER},
230 {"/modelURL", WANCDEV_MODELURL},
231 {"/serialNumber", serialnumber},
232 {"/UDN", uuidvalue},
233 {"/UPC", WANCDEV_UPC}, /* UPC (=12 digit Barcode) is optional */
234 #ifdef ENABLE_6FC_SERVICE
235 {"serviceList", INITHELPER(51,2)},
236 #else
237 {"serviceList", INITHELPER(51,1)},
238 #endif
239 /* 51 */
240 {"service", INITHELPER(53,5)},
241 {"service", INITHELPER(58,5)},
242 /* 53 */
243 {"/serviceType", SERVICE_TYPE_WANIPC},
244 /* urn:schemas-upnp-org:service:WANIPConnection:2 for v2 */
245 {"/serviceId", SERVICE_ID_WANIPC},
246 /* urn:upnp-org:serviceId:WANIPConn1 or 2 */
247 {"/controlURL", WANIPC_CONTROLURL},
248 {"/eventSubURL", WANIPC_EVENTURL},
249 {"/SCPDURL", WANIPC_PATH},
250 #ifdef ENABLE_6FC_SERVICE
251 /* 58 */
252 {"/serviceType", "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1"},
253 {"/serviceId", "urn:upnp-org:serviceId:WANIPv6FC1"},
254 {"/controlURL", WANIP6FC_CONTROLURL},
255 {"/eventSubURL", WANIP6FC_EVENTURL},
256 {"/SCPDURL", WANIP6FC_PATH},
257 #endif
258 /* 58 / 63 = SERVICES_OFFSET*/
259 #if defined(HAS_DUMMY_SERVICE) || defined(ENABLE_L3F_SERVICE) || defined(ENABLE_DP_SERVICE)
260 {"service", INITHELPER(SERVICES_OFFSET+2,5)},
261 {"service", INITHELPER(SERVICES_OFFSET+7,5)},
262 #endif
263 #ifdef HAS_DUMMY_SERVICE
264 /* 60 / 65 = SERVICES_OFFSET+2 */
265 {"/serviceType", "urn:schemas-dummy-com:service:Dummy:1"},
266 {"/serviceId", "urn:dummy-com:serviceId:dummy1"},
267 {"/controlURL", "/dummy"},
268 {"/eventSubURL", "/dummy"},
269 {"/SCPDURL", DUMMY_PATH},
270 #endif
271 #ifdef ENABLE_L3F_SERVICE
272 /* 60 / 65 = SERVICES_OFFSET+2 */
273 {"/serviceType", "urn:schemas-upnp-org:service:Layer3Forwarding:1"},
274 {"/serviceId", "urn:upnp-org:serviceId:Layer3Forwarding1"},
275 {"/controlURL", L3F_CONTROLURL}, /* The Layer3Forwarding service is only */
276 {"/eventSubURL", L3F_EVENTURL}, /* recommended, not mandatory */
277 {"/SCPDURL", L3F_PATH},
278 #endif
279 #ifdef ENABLE_DP_SERVICE
280 /* InternetGatewayDevice v2 :
281 * it is RECOMMEDED that DeviceProtection service is implemented and applied.
282 * If DeviceProtection is not implemented and applied, it is RECOMMENDED
283 * that control points are able to access only actions and parameters defined
284 * as Public role. */
285 /* 65 / 70 = SERVICES_OFFSET+7 */
286 {"/serviceType", "urn:schemas-upnp-org:service:DeviceProtection:1"},
287 {"/serviceId", "urn:upnp-org:serviceId:DeviceProtection1"},
288 {"/controlURL", DP_CONTROLURL},
289 {"/eventSubURL", DP_EVENTURL},
290 {"/SCPDURL", DP_PATH},
291 #endif
292 {0, 0}
295 /* WANIPCn.xml */
296 /* see UPnP_IGD_WANIPConnection 1.0.pdf
297 static struct XMLElt scpdWANIPCn[] =
299 {root_service, {INITHELPER(1,2)}},
300 {0, {0}}
303 static const struct argument AddPortMappingArgs[] =
305 {1, 11}, /* RemoteHost */
306 {1, 12}, /* ExternalPort */
307 {1, 14}, /* PortMappingProtocol */
308 {1, 13}, /* InternalPort */
309 {1, 15}, /* InternalClient */
310 {1, 9}, /* PortMappingEnabled */
311 {1, 16}, /* PortMappingDescription */
312 {1, 10}, /* PortMappingLeaseDuration */
313 {0, 0}
316 #ifdef IGD_V2
317 static const struct argument AddAnyPortMappingArgs[] =
319 {1, 11}, /* RemoteHost */
320 {1, 12}, /* ExternalPort */
321 {1, 14}, /* PortMappingProtocol */
322 {1, 13}, /* InternalPort */
323 {1, 15}, /* InternalClient */
324 {1, 9}, /* PortMappingEnabled */
325 {1, 16}, /* PortMappingDescription */
326 {1, 10}, /* PortMappingLeaseDuration */
327 {2, 12}, /* NewReservedPort / ExternalPort */
328 {0, 0}
331 static const struct argument DeletePortMappingRangeArgs[] =
333 {1|(1<<2), 12}, /* NewStartPort / ExternalPort */
334 {1|(2<<2), 12}, /* NewEndPort / ExternalPort */
335 {1, 14}, /* NewProtocol / PortMappingProtocol */
336 {1, 18}, /* NewManage / A_ARG_TYPE_Manage */
337 {0, 0}
340 static const struct argument GetListOfPortMappingsArgs[] =
342 {1|(1<<2), 12}, /* NewStartPort / ExternalPort */
343 {1|(2<<2), 12}, /* NewEndPort / ExternalPort */
344 {1, 14}, /* NewProtocol / PortMappingProtocol */
345 {1, 18}, /* NewManage / A_ARG_TYPE_Manage */
346 {1, 8}, /* NewNumberOfPorts / PortMappingNumberOfEntries */
347 {2, 19}, /* NewPortListing / A_ARG_TYPE_PortListing */
348 {0, 0}
350 #endif
352 static const struct argument GetExternalIPAddressArgs[] =
354 {2, 7},
355 {0, 0}
358 static const struct argument DeletePortMappingArgs[] =
360 {1, 11},
361 {1, 12},
362 {1, 14},
363 {0, 0}
366 static const struct argument SetConnectionTypeArgs[] =
368 {1, 0},
369 {0, 0}
372 static const struct argument GetConnectionTypeInfoArgs[] =
374 {2, 0},
375 {2, 1},
376 {0, 0}
379 static const struct argument GetStatusInfoArgs[] =
381 {2, 2},
382 {2, 4},
383 {2, 3},
384 {0, 0}
387 static const struct argument GetNATRSIPStatusArgs[] =
389 {2, 5},
390 {2, 6},
391 {0, 0}
394 static const struct argument GetGenericPortMappingEntryArgs[] =
396 {1, 8},
397 {2, 11},
398 {2, 12},
399 {2, 14},
400 {2, 13},
401 {2, 15},
402 {2, 9},
403 {2, 16},
404 {2, 10},
405 {0, 0}
408 static const struct argument GetSpecificPortMappingEntryArgs[] =
410 {1, 11},
411 {1, 12},
412 {1, 14},
413 {2, 13},
414 {2, 15},
415 {2, 9},
416 {2, 16},
417 {2, 10},
418 {0, 0}
421 static const struct action WANIPCnActions[] =
423 {"SetConnectionType", SetConnectionTypeArgs}, /* R */
424 {"GetConnectionTypeInfo", GetConnectionTypeInfoArgs}, /* R */
425 {"RequestConnection", 0}, /* R */
426 /*{"RequestTermination", 0},*/ /* O */
427 {"ForceTermination", 0}, /* R */
428 /*{"SetAutoDisconnectTime", 0},*/ /* O */
429 /*{"SetIdleDisconnectTime", 0},*/ /* O */
430 /*{"SetWarnDisconnectDelay", 0}, */ /* O */
431 {"GetStatusInfo", GetStatusInfoArgs}, /* R */
432 /*GetAutoDisconnectTime*/ /* O */
433 /*GetIdleDisconnectTime*/ /* O */
434 /*GetWarnDisconnectDelay*/ /* O */
435 {"GetNATRSIPStatus", GetNATRSIPStatusArgs}, /* R */
436 {"GetGenericPortMappingEntry", GetGenericPortMappingEntryArgs}, /* R */
437 {"GetSpecificPortMappingEntry", GetSpecificPortMappingEntryArgs}, /* R */
438 {"AddPortMapping", AddPortMappingArgs}, /* R */
439 {"DeletePortMapping", DeletePortMappingArgs}, /* R */
440 {"GetExternalIPAddress", GetExternalIPAddressArgs}, /* R */
441 #ifdef IGD_V2
442 {"DeletePortMappingRange", DeletePortMappingRangeArgs}, /* R, IGD v2 */
443 {"GetListOfPortMappings", GetListOfPortMappingsArgs}, /* R, IGD v2 */
444 {"AddAnyPortMapping", AddAnyPortMappingArgs}, /* R, IGD v2 */
445 #endif
446 #if 0
447 {"AddPortMapping", AddPortMappingArgs}, /* R */
448 {"GetExternalIPAddress", GetExternalIPAddressArgs}, /* R */
449 {"DeletePortMapping", DeletePortMappingArgs}, /* R */
450 {"SetConnectionType", SetConnectionTypeArgs}, /* R */
451 {"GetConnectionTypeInfo", GetConnectionTypeInfoArgs}, /* R */
452 {"RequestConnection", 0}, /* R */
453 {"ForceTermination", 0}, /* R */
454 {"GetStatusInfo", GetStatusInfoArgs}, /* R */
455 {"GetNATRSIPStatus", GetNATRSIPStatusArgs}, /* R */
456 {"GetGenericPortMappingEntry", GetGenericPortMappingEntryArgs}, /* R */
457 {"GetSpecificPortMappingEntry", GetSpecificPortMappingEntryArgs}, /* R */
458 /* added in v2 UPnP-gw-WANIPConnection-v2-Service.pdf */
459 #ifdef IGD_V2
460 {"AddAnyPortMapping", AddAnyPortMappingArgs},
461 {"DeletePortMappingRange", DeletePortMappingRangeArgs},
462 {"GetListOfPortMappings", GetListOfPortMappingsArgs},
463 #endif
464 #endif
465 {0, 0}
467 /* R=Required, O=Optional */
469 /* ignore "warning: missing initializer" */
470 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
472 static const struct stateVar WANIPCnVars[] =
474 /* 0 */
475 #if 0
476 {"ConnectionType", 0, 0/*1*/}, /* required */
477 {"PossibleConnectionTypes", 0|0x80, 0, 14, 15},
478 #endif
479 {"ConnectionType", 0, 1, 14, 15}, /* required */
480 {"PossibleConnectionTypes", 0|0x80, 0, 0, 15},
481 /* Required
482 * Allowed values : Unconfigured / IP_Routed / IP_Bridged */
483 {"ConnectionStatus", 0|0x80, 0/*1*/, 18,
484 CONNECTIONSTATUS_MAGICALVALUE }, /* required */
485 /* Allowed Values : Unconfigured / Connecting(opt) / Connected
486 * PendingDisconnect(opt) / Disconnecting (opt)
487 * Disconnected */
488 {"Uptime", 3, 0}, /* Required */
489 {"LastConnectionError", 0, 0, 25}, /* required : */
490 /* Allowed Values : ERROR_NONE(req) / ERROR_COMMAND_ABORTED(opt)
491 * ERROR_NOT_ENABLED_FOR_INTERNET(opt)
492 * ERROR_USER_DISCONNECT(opt)
493 * ERROR_ISP_DISCONNECT(opt)
494 * ERROR_IDLE_DISCONNECT(opt)
495 * ERROR_FORCED_DISCONNECT(opt)
496 * ERROR_NO_CARRIER(opt)
497 * ERROR_IP_CONFIGURATION(opt)
498 * ERROR_UNKNOWN(opt) */
499 {"RSIPAvailable", 1, 0}, /* required */
500 {"NATEnabled", 1, 0}, /* required */
501 {"ExternalIPAddress", 0|0x80, 0, 0,
502 EXTERNALIPADDRESS_MAGICALVALUE}, /* required. Default : empty string */
503 {"PortMappingNumberOfEntries", 2|0x80, 0, 0,
504 PORTMAPPINGNUMBEROFENTRIES_MAGICALVALUE}, /* required >= 0 */
505 {"PortMappingEnabled", 1, 0}, /* Required */
506 /* 10 */
507 {"PortMappingLeaseDuration", 3, 2, 1}, /* required */
508 /* TODO : for IGD v2 :
509 * <stateVariable sendEvents="no">
510 * <name>PortMappingLeaseDuration</name>
511 * <dataType>ui4</dataType>
512 * <defaultValue>Vendor-defined</defaultValue>
513 * <allowedValueRange>
514 * <minimum>0</minimum>
515 * <maximum>604800</maximum>
516 * </allowedValueRange>
517 * </stateVariable> */
518 {"RemoteHost", 0, 0}, /* required. Default : empty string */
519 {"ExternalPort", 2, 0}, /* required */
520 {"InternalPort", 2, 0, 3}, /* required */
521 {"PortMappingProtocol", 0, 0, 11}, /* required allowedValues: TCP/UDP */
522 {"InternalClient", 0, 0}, /* required */
523 {"PortMappingDescription", 0, 0}, /* required default: empty string */
524 /* added in v2 UPnP-gw-WANIPConnection-v2-Service.pdf */
525 #ifdef IGD_V2
526 {"SystemUpdateID", 3|0x80, 0, 0, SYSTEMUPDATEID_MAGICALVALUE},
527 {"A_ARG_TYPE_Manage", 1, 0},
528 {"A_ARG_TYPE_PortListing", 0, 0},
529 #endif
530 {0, 0}
533 static const struct serviceDesc scpdWANIPCn =
534 { WANIPCnActions, WANIPCnVars };
536 /* WANCfg.xml */
537 /* See UPnP_IGD_WANCommonInterfaceConfig 1.0.pdf */
539 static const struct argument GetCommonLinkPropertiesArgs[] =
541 {2, 0},
542 {2, 1},
543 {2, 2},
544 {2, 3},
545 {0, 0}
548 static const struct argument GetTotalBytesSentArgs[] =
550 {2, 4},
551 {0, 0}
554 static const struct argument GetTotalBytesReceivedArgs[] =
556 {2, 5},
557 {0, 0}
560 static const struct argument GetTotalPacketsSentArgs[] =
562 {2, 6},
563 {0, 0}
566 static const struct argument GetTotalPacketsReceivedArgs[] =
568 {2, 7},
569 {0, 0}
572 static const struct action WANCfgActions[] =
574 {"GetCommonLinkProperties", GetCommonLinkPropertiesArgs}, /* Required */
575 {"GetTotalBytesSent", GetTotalBytesSentArgs}, /* optional */
576 {"GetTotalBytesReceived", GetTotalBytesReceivedArgs}, /* optional */
577 {"GetTotalPacketsSent", GetTotalPacketsSentArgs}, /* optional */
578 {"GetTotalPacketsReceived", GetTotalPacketsReceivedArgs}, /* optional */
579 {0, 0}
582 /* See UPnP_IGD_WANCommonInterfaceConfig 1.0.pdf */
583 static const struct stateVar WANCfgVars[] =
585 {"WANAccessType", 0, 0, 1},
586 /* Allowed Values : DSL / POTS / Cable / Ethernet
587 * Default value : empty string */
588 {"Layer1UpstreamMaxBitRate", 3, 0},
589 {"Layer1DownstreamMaxBitRate", 3, 0},
590 {"PhysicalLinkStatus", 0|0x80, 0, 6, 6},
591 /* allowed values :
592 * Up / Down / Initializing (optional) / Unavailable (optionnal)
593 * no Default value
594 * Evented */
595 {"TotalBytesSent", 3, 0}, /* Optional */
596 {"TotalBytesReceived", 3, 0}, /* Optional */
597 {"TotalPacketsSent", 3, 0}, /* Optional */
598 {"TotalPacketsReceived", 3, 0},/* Optional */
599 /*{"MaximumActiveConnections", 2, 0}, // allowed Range value // OPTIONAL */
600 /*{"WANAccessProvider", 0, 0},*/ /* Optional */
601 {0, 0}
604 static const struct serviceDesc scpdWANCfg =
605 { WANCfgActions, WANCfgVars };
607 #ifdef ENABLE_L3F_SERVICE
608 /* Read UPnP_IGD_Layer3Forwarding_1.0.pdf */
609 static const struct argument SetDefaultConnectionServiceArgs[] =
611 {1, 0}, /* in */
612 {0, 0}
615 static const struct argument GetDefaultConnectionServiceArgs[] =
617 {2, 0}, /* out */
618 {0, 0}
621 static const struct action L3FActions[] =
623 {"SetDefaultConnectionService", SetDefaultConnectionServiceArgs}, /* Req */
624 {"GetDefaultConnectionService", GetDefaultConnectionServiceArgs}, /* Req */
625 {0, 0}
628 static const struct stateVar L3FVars[] =
630 {"DefaultConnectionService", 0|0x80, 0, 0,
631 DEFAULTCONNECTIONSERVICE_MAGICALVALUE}, /* Required */
632 {0, 0}
635 static const struct serviceDesc scpdL3F =
636 { L3FActions, L3FVars };
637 #endif
639 #ifdef ENABLE_6FC_SERVICE
640 /* see UPnP-gw-WANIPv6FirewallControl-v1-Service.pdf */
641 static const struct argument GetFirewallStatusArgs[] =
643 {2|0x80, 0}, /* OUT : FirewallEnabled */
644 {2|0x80, 6}, /* OUT : InboundPinholeAllowed */
645 {0, 0}
648 static const struct argument GetOutboundPinholeTimeoutArgs[] =
650 {1|0x80|(3<<2), 1}, /* RemoteHost IN A_ARG_TYPE_IPv6Address */
651 {1|0x80|(4<<2), 2}, /* RemotePort IN A_ARG_TYPE_Port */
652 {1|0x80|(5<<2), 1}, /* InternalClient IN A_ARG_TYPE_IPv6Address */
653 {1|0x80|(6<<2), 2}, /* InternalPort IN A_ARG_TYPE_Port */
654 {1|0x80, 3}, /* Protocol IN A_ARG_TYPE_Protocol */
655 {2|0x80, 7}, /* OutboundPinholeTimeout OUT A_ARG_TYPE_OutboundPinholeTimeout */
656 {0, 0}
659 static const struct argument AddPinholeArgs[] =
661 {1|0x80|(3<<2), 1}, /* RemoteHost IN A_ARG_TYPE_IPv6Address */
662 {1|0x80|(4<<2), 2}, /* RemotePort IN A_ARG_TYPE_Port */
663 {1|0x80|(5<<2), 1}, /* InternalClient IN A_ARG_TYPE_IPv6Address */
664 {1|0x80|(6<<2), 2}, /* InternalPort IN A_ARG_TYPE_Port */
665 {1|0x80, 3}, /* Protocol IN A_ARG_TYPE_Protocol */
666 {1|0x80, 5}, /* LeaseTime IN A_ARG_TYPE_LeaseTime */
667 {2|0x80, 4}, /* UniqueID OUT A_ARG_TYPE_UniqueID */
668 {0, 0}
671 static const struct argument UpdatePinholeArgs[] =
673 {1|0x80, 4}, /* UniqueID IN A_ARG_TYPE_UniqueID */
674 {1, 5}, /* LeaseTime IN A_ARG_TYPE_LeaseTime */
675 {0, 0}
678 static const struct argument DeletePinholeArgs[] =
680 {1|0x80, 4}, /* UniqueID IN A_ARG_TYPE_UniqueID */
681 {0, 0}
684 static const struct argument GetPinholePacketsArgs[] =
686 {1|0x80, 4}, /* UniqueID IN A_ARG_TYPE_UniqueID */
687 {2|0x80, 9}, /* PinholePackets OUT A_ARG_TYPE_PinholePackets */
688 {0, 0}
691 static const struct argument CheckPinholeWorkingArgs[] =
693 {1|0x80, 4}, /* UniqueID IN A_ARG_TYPE_UniqueID */
694 {2|0x80|(7<<2), 8}, /* IsWorking OUT A_ARG_TYPE_Boolean */
695 {0, 0}
698 static const struct action IPv6FCActions[] =
700 {"GetFirewallStatus", GetFirewallStatusArgs}, /* Req */
701 {"GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs}, /* Opt */
702 {"AddPinhole", AddPinholeArgs}, /* Req */
703 {"UpdatePinhole", UpdatePinholeArgs}, /* Req */
704 {"DeletePinhole", DeletePinholeArgs}, /* Req */
705 {"GetPinholePackets", GetPinholePacketsArgs}, /* Req */
706 {"CheckPinholeWorking", CheckPinholeWorkingArgs}, /* Opt */
707 {0, 0}
710 static const struct stateVar IPv6FCVars[] =
712 {"FirewallEnabled", 1|0x80, 0, 0,
713 FIREWALLENABLED_MAGICALVALUE}, /* Required */
714 {"A_ARG_TYPE_IPv6Address", 0, 0, 0, 0}, /* Required */
715 {"A_ARG_TYPE_Port", 2, 0, 0, 0}, /* Required */
716 {"A_ARG_TYPE_Protocol", 2, 0, 0, 0}, /* Required */
717 /* 4 */
718 {"A_ARG_TYPE_UniqueID", 2, 0, 0, 0}, /* Required */
719 {"A_ARG_TYPE_LeaseTime", 3, 0, 5, 0}, /* Required */
720 {"InboundPinholeAllowed", 1|0x80, 0, 0,
721 INBOUNDPINHOLEALLOWED_MAGICALVALUE}, /* Required */
722 {"A_ARG_TYPE_OutboundPinholeTimeout", 3, 0, 7, 0}, /* Optional */
723 /* 8 */
724 {"A_ARG_TYPE_Boolean", 1, 0, 0, 0}, /* Optional */
725 {"A_ARG_TYPE_PinholePackets", 3, 0, 0, 0}, /* Required */
726 {0, 0}
729 static const struct serviceDesc scpd6FC =
730 { IPv6FCActions, IPv6FCVars };
731 #endif
733 #ifdef ENABLE_DP_SERVICE
734 /* UPnP-gw-DeviceProtection-v1-Service.pdf */
735 static const struct action DPActions[] =
737 {"SendSetupMessage", 0},
738 {"GetSupportedProtocols", 0},
739 {"GetAssignedRoles", 0},
740 {0, 0}
743 static const struct stateVar DPVars[] =
745 {"SetupReady", 1|0x80},
746 {"SupportedProtocols", 0},
747 {"A_ARG_TYPE_ACL", 0},
748 {"A_ARG_TYPE_IdentityList", 0},
749 {"A_ARG_TYPE_Identity", 0},
750 {"A_ARG_TYPE_Base64", 4},
751 {"A_ARG_TYPE_String", 0},
752 {0, 0}
755 static const struct serviceDesc scpdDP =
756 { DPActions, DPVars };
757 #endif
759 /* strcat_str()
760 * concatenate the string and use realloc to increase the
761 * memory buffer if needed. */
762 static char *
763 strcat_str(char * str, int * len, int * tmplen, const char * s2)
765 int s2len;
766 int newlen;
767 char * p;
769 s2len = (int)strlen(s2);
770 if(*tmplen <= (*len + s2len))
772 if(s2len < 256)
773 newlen = *tmplen + 256;
774 else
775 newlen = *tmplen + s2len + 1;
776 p = (char *)realloc(str, newlen);
777 if(p == NULL) /* handle a failure of realloc() */
778 return str;
779 str = p;
780 *tmplen = newlen;
782 /*strcpy(str + *len, s2); */
783 memcpy(str + *len, s2, s2len + 1);
784 *len += s2len;
785 return str;
788 /* strcat_char() :
789 * concatenate a character and use realloc to increase the
790 * size of the memory buffer if needed */
791 static char *
792 strcat_char(char * str, int * len, int * tmplen, char c)
794 char * p;
796 if(*tmplen <= (*len + 1))
798 *tmplen += 256;
799 p = (char *)realloc(str, *tmplen);
800 if(p == NULL) /* handle a failure of realloc() */
802 *tmplen -= 256;
803 return str;
805 str = p;
807 str[*len] = c;
808 (*len)++;
809 return str;
812 /* strcat_int()
813 * concatenate the string representation of the integer.
814 * call strcat_char() */
815 static char *
816 strcat_int(char * str, int * len, int * tmplen, int i)
818 char buf[16];
819 int j;
821 if(i < 0) {
822 str = strcat_char(str, len, tmplen, '-');
823 i = -i;
824 } else if(i == 0) {
825 /* special case for 0 */
826 str = strcat_char(str, len, tmplen, '0');
827 return str;
829 j = 0;
830 while(i && j < (int)sizeof(buf)) {
831 buf[j++] = '0' + (i % 10);
832 i = i / 10;
834 while(j > 0) {
835 str = strcat_char(str, len, tmplen, buf[--j]);
837 return str;
840 /* iterative subroutine using a small stack
841 * This way, the progam stack usage is kept low */
842 static char *
843 genXML(char * str, int * len, int * tmplen,
844 const struct XMLElt * p)
846 unsigned short i, j;
847 unsigned long k;
848 int top;
849 const char * eltname, *s;
850 char c;
851 struct {
852 unsigned short i;
853 unsigned short j;
854 const char * eltname;
855 } pile[16]; /* stack */
856 top = -1;
857 i = 0; /* current node */
858 j = 1; /* i + number of nodes*/
859 for(;;)
861 eltname = p[i].eltname;
862 if(!eltname)
863 return str;
864 if(eltname[0] == '/')
866 if(p[i].data && p[i].data[0])
868 /*printf("<%s>%s<%s>\n", eltname+1, p[i].data, eltname); */
869 str = strcat_char(str, len, tmplen, '<');
870 str = strcat_str(str, len, tmplen, eltname+1);
871 str = strcat_char(str, len, tmplen, '>');
872 str = strcat_str(str, len, tmplen, p[i].data);
873 str = strcat_char(str, len, tmplen, '<');
874 str = strcat_str(str, len, tmplen, eltname);
875 str = strcat_char(str, len, tmplen, '>');
877 for(;;)
879 if(top < 0)
880 return str;
881 i = ++(pile[top].i);
882 j = pile[top].j;
883 /*printf(" pile[%d]\t%d %d\n", top, i, j); */
884 if(i==j)
886 /*printf("</%s>\n", pile[top].eltname); */
887 str = strcat_char(str, len, tmplen, '<');
888 str = strcat_char(str, len, tmplen, '/');
889 s = pile[top].eltname;
890 for(c = *s; c > ' '; c = *(++s))
891 str = strcat_char(str, len, tmplen, c);
892 str = strcat_char(str, len, tmplen, '>');
893 top--;
895 else
896 break;
899 else
901 /*printf("<%s>\n", eltname); */
902 str = strcat_char(str, len, tmplen, '<');
903 str = strcat_str(str, len, tmplen, eltname);
904 str = strcat_char(str, len, tmplen, '>');
905 k = (unsigned long)p[i].data;
906 i = k & 0xffff;
907 j = i + (k >> 16);
908 top++;
909 /*printf(" +pile[%d]\t%d %d\n", top, i, j); */
910 pile[top].i = i;
911 pile[top].j = j;
912 pile[top].eltname = eltname;
917 /* genRootDesc() :
918 * - Generate the root description of the UPnP device.
919 * - the len argument is used to return the length of
920 * the returned string.
921 * - tmp_uuid argument is used to build the uuid string */
922 char *
923 genRootDesc(int * len)
925 char * str;
926 int tmplen;
927 tmplen = 2048;
928 str = (char *)malloc(tmplen);
929 if(str == NULL)
930 return NULL;
931 * len = strlen(xmlver);
932 /*strcpy(str, xmlver); */
933 memcpy(str, xmlver, *len + 1);
934 str = genXML(str, len, &tmplen, rootDesc);
935 str[*len] = '\0';
936 return str;
939 /* genServiceDesc() :
940 * Generate service description with allowed methods and
941 * related variables. */
942 static char *
943 genServiceDesc(int * len, const struct serviceDesc * s)
945 int i, j;
946 const struct action * acts;
947 const struct stateVar * vars;
948 const struct argument * args;
949 const char * p;
950 char * str;
951 int tmplen;
952 tmplen = 2048;
953 str = (char *)malloc(tmplen);
954 if(str == NULL)
955 return NULL;
956 /*strcpy(str, xmlver); */
957 *len = strlen(xmlver);
958 memcpy(str, xmlver, *len + 1);
960 acts = s->actionList;
961 vars = s->serviceStateTable;
963 str = strcat_char(str, len, &tmplen, '<');
964 str = strcat_str(str, len, &tmplen, root_service);
965 str = strcat_char(str, len, &tmplen, '>');
967 str = strcat_str(str, len, &tmplen,
968 "<specVersion><major>1</major><minor>0</minor></specVersion>");
970 i = 0;
971 str = strcat_str(str, len, &tmplen, "<actionList>");
972 while(acts[i].name)
974 str = strcat_str(str, len, &tmplen, "<action><name>");
975 str = strcat_str(str, len, &tmplen, acts[i].name);
976 str = strcat_str(str, len, &tmplen, "</name>");
977 /* argument List */
978 args = acts[i].args;
979 if(args)
981 str = strcat_str(str, len, &tmplen, "<argumentList>");
982 j = 0;
983 while(args[j].dir)
985 str = strcat_str(str, len, &tmplen, "<argument><name>");
986 if((args[j].dir & 0x80) == 0) {
987 str = strcat_str(str, len, &tmplen, "New");
989 p = vars[args[j].relatedVar].name;
990 if(args[j].dir & 0x7c) {
991 /* use magic values ... */
992 str = strcat_str(str, len, &tmplen, magicargname[(args[j].dir & 0x7c) >> 2]);
993 } else if(0 == memcmp(p, "PortMapping", 11)
994 && 0 != memcmp(p + 11, "Description", 11)) {
995 if(0 == memcmp(p + 11, "NumberOfEntries", 15)) {
996 /* PortMappingNumberOfEntries */
997 #ifdef IGD_V2
998 if(0 == memcmp(acts[i].name, "GetListOfPortMappings", 22)) {
999 str = strcat_str(str, len, &tmplen, "NumberOfPorts");
1000 } else {
1001 str = strcat_str(str, len, &tmplen, "PortMappingIndex");
1003 #else
1004 str = strcat_str(str, len, &tmplen, "PortMappingIndex");
1005 #endif
1006 } else {
1007 /* PortMappingEnabled
1008 * PortMappingLeaseDuration
1009 * PortMappingProtocol */
1010 str = strcat_str(str, len, &tmplen, p + 11);
1012 #ifdef IGD_V2
1013 } else if(0 == memcmp(p, "A_ARG_TYPE_", 11)) {
1014 str = strcat_str(str, len, &tmplen, p + 11);
1015 } else if(0 == memcmp(p, "ExternalPort", 13)
1016 && args[j].dir == 2
1017 && 0 == memcmp(acts[i].name, "AddAnyPortMapping", 18)) {
1018 str = strcat_str(str, len, &tmplen, "ReservedPort");
1019 #endif
1020 } else {
1021 str = strcat_str(str, len, &tmplen, p);
1023 str = strcat_str(str, len, &tmplen, "</name><direction>");
1024 str = strcat_str(str, len, &tmplen, (args[j].dir&0x03)==1?"in":"out");
1025 str = strcat_str(str, len, &tmplen,
1026 "</direction><relatedStateVariable>");
1027 str = strcat_str(str, len, &tmplen, p);
1028 str = strcat_str(str, len, &tmplen,
1029 "</relatedStateVariable></argument>");
1030 j++;
1032 str = strcat_str(str, len, &tmplen,"</argumentList>");
1034 str = strcat_str(str, len, &tmplen, "</action>");
1035 /*str = strcat_char(str, len, &tmplen, '\n'); // TEMP ! */
1036 i++;
1038 str = strcat_str(str, len, &tmplen, "</actionList><serviceStateTable>");
1039 i = 0;
1040 while(vars[i].name)
1042 str = strcat_str(str, len, &tmplen,
1043 "<stateVariable sendEvents=\"");
1044 #ifdef ENABLE_EVENTS
1045 str = strcat_str(str, len, &tmplen, (vars[i].itype & 0x80)?"yes":"no");
1046 #else
1047 /* for the moment always send no. Wait for SUBSCRIBE implementation
1048 * before setting it to yes */
1049 str = strcat_str(str, len, &tmplen, "no");
1050 #endif
1051 str = strcat_str(str, len, &tmplen, "\"><name>");
1052 str = strcat_str(str, len, &tmplen, vars[i].name);
1053 str = strcat_str(str, len, &tmplen, "</name><dataType>");
1054 str = strcat_str(str, len, &tmplen, upnptypes[vars[i].itype & 0x0f]);
1055 str = strcat_str(str, len, &tmplen, "</dataType>");
1056 if(vars[i].iallowedlist)
1058 if((vars[i].itype & 0x0f) == 0)
1060 /* string */
1061 str = strcat_str(str, len, &tmplen, "<allowedValueList>");
1062 for(j=vars[i].iallowedlist; upnpallowedvalues[j]; j++)
1064 str = strcat_str(str, len, &tmplen, "<allowedValue>");
1065 str = strcat_str(str, len, &tmplen, upnpallowedvalues[j]);
1066 str = strcat_str(str, len, &tmplen, "</allowedValue>");
1068 str = strcat_str(str, len, &tmplen, "</allowedValueList>");
1069 } else {
1070 /* ui2 and ui4 */
1071 str = strcat_str(str, len, &tmplen, "<allowedValueRange><minimum>");
1072 str = strcat_int(str, len, &tmplen, upnpallowedranges[vars[i].iallowedlist]);
1073 str = strcat_str(str, len, &tmplen, "</minimum><maximum>");
1074 str = strcat_int(str, len, &tmplen, upnpallowedranges[vars[i].iallowedlist+1]);
1075 str = strcat_str(str, len, &tmplen, "</maximum></allowedValueRange>");
1078 /*if(vars[i].defaultValue) */
1079 if(vars[i].idefault)
1081 str = strcat_str(str, len, &tmplen, "<defaultValue>");
1082 /*str = strcat_str(str, len, &tmplen, vars[i].defaultValue); */
1083 str = strcat_str(str, len, &tmplen, upnpdefaultvalues[vars[i].idefault]);
1084 str = strcat_str(str, len, &tmplen, "</defaultValue>");
1086 str = strcat_str(str, len, &tmplen, "</stateVariable>");
1087 /*str = strcat_char(str, len, &tmplen, '\n'); // TEMP ! */
1088 i++;
1090 str = strcat_str(str, len, &tmplen, "</serviceStateTable></scpd>");
1091 str[*len] = '\0';
1092 return str;
1095 /* genWANIPCn() :
1096 * Generate the WANIPConnection xml description */
1097 char *
1098 genWANIPCn(int * len)
1100 return genServiceDesc(len, &scpdWANIPCn);
1103 /* genWANCfg() :
1104 * Generate the WANInterfaceConfig xml description. */
1105 char *
1106 genWANCfg(int * len)
1108 return genServiceDesc(len, &scpdWANCfg);
1111 #ifdef ENABLE_L3F_SERVICE
1112 char *
1113 genL3F(int * len)
1115 return genServiceDesc(len, &scpdL3F);
1117 #endif
1119 #ifdef ENABLE_6FC_SERVICE
1120 char *
1121 gen6FC(int * len)
1123 return genServiceDesc(len, &scpd6FC);
1125 #endif
1127 #ifdef ENABLE_DP_SERVICE
1128 char *
1129 genDP(int * len)
1131 return genServiceDesc(len, &scpdDP);
1133 #endif
1135 #ifdef ENABLE_EVENTS
1136 static char *
1137 genEventVars(int * len, const struct serviceDesc * s, const char * servns)
1139 char tmp[16];
1140 const struct stateVar * v;
1141 char * str;
1142 int tmplen;
1143 tmplen = 512;
1144 str = (char *)malloc(tmplen);
1145 if(str == NULL)
1146 return NULL;
1147 *len = 0;
1148 v = s->serviceStateTable;
1149 str = strcat_str(str, len, &tmplen, "<e:propertyset xmlns:e=\"urn:schemas-upnp-org:event-1-0\" xmlns:s=\"");
1150 str = strcat_str(str, len, &tmplen, servns);
1151 str = strcat_str(str, len, &tmplen, "\">");
1152 while(v->name) {
1153 if(v->itype & 0x80) {
1154 str = strcat_str(str, len, &tmplen, "<e:property><s:");
1155 str = strcat_str(str, len, &tmplen, v->name);
1156 str = strcat_str(str, len, &tmplen, ">");
1157 /*printf("<e:property><s:%s>", v->name);*/
1158 switch(v->ieventvalue) {
1159 case 0:
1160 break;
1161 case CONNECTIONSTATUS_MAGICALVALUE:
1162 /* or get_wan_connection_status_str(ext_if_name) */
1163 str = strcat_str(str, len, &tmplen,
1164 upnpallowedvalues[18 + get_wan_connection_status(ext_if_name)]);
1165 break;
1166 #ifdef ENABLE_6FC_SERVICE
1167 case FIREWALLENABLED_MAGICALVALUE:
1168 /* see 2.4.2 of UPnP-gw-WANIPv6FirewallControl-v1-Service.pdf */
1169 snprintf(tmp, sizeof(tmp), "%d",
1170 ipv6fc_firewall_enabled);
1171 str = strcat_str(str, len, &tmplen, tmp);
1172 break;
1173 case INBOUNDPINHOLEALLOWED_MAGICALVALUE:
1174 /* see 2.4.3 of UPnP-gw-WANIPv6FirewallControl-v1-Service.pdf */
1175 snprintf(tmp, sizeof(tmp), "%d",
1176 ipv6fc_inbound_pinhole_allowed);
1177 str = strcat_str(str, len, &tmplen, tmp);
1178 break;
1179 #endif
1180 #ifdef IGD_V2
1181 case SYSTEMUPDATEID_MAGICALVALUE:
1182 /* Please read section 2.3.23 SystemUpdateID
1183 * of UPnP-gw-WANIPConnection-v2-Service.pdf */
1184 snprintf(tmp, sizeof(tmp), "%d",
1185 1/* system update id */);
1186 str = strcat_str(str, len, &tmplen, tmp);
1187 break;
1188 #endif
1189 case PORTMAPPINGNUMBEROFENTRIES_MAGICALVALUE:
1190 /* Port mapping number of entries magical value */
1191 snprintf(tmp, sizeof(tmp), "%d",
1192 upnp_get_portmapping_number_of_entries());
1193 str = strcat_str(str, len, &tmplen, tmp);
1194 break;
1195 case EXTERNALIPADDRESS_MAGICALVALUE:
1196 /* External ip address magical value */
1197 if(use_ext_ip_addr)
1198 str = strcat_str(str, len, &tmplen, use_ext_ip_addr);
1199 else {
1200 char ext_ip_addr[INET_ADDRSTRLEN];
1201 if(getifaddr(ext_if_name, ext_ip_addr, INET_ADDRSTRLEN, NULL, NULL) < 0) {
1202 str = strcat_str(str, len, &tmplen, "0.0.0.0");
1203 } else {
1204 str = strcat_str(str, len, &tmplen, ext_ip_addr);
1207 break;
1208 case DEFAULTCONNECTIONSERVICE_MAGICALVALUE:
1209 /* DefaultConnectionService magical value */
1210 str = strcat_str(str, len, &tmplen, uuidvalue);
1211 #ifdef IGD_V2
1212 str = strcat_str(str, len, &tmplen, ":WANConnectionDevice:2,urn:upnp-org:serviceId:WANIPConn1");
1213 #else
1214 str = strcat_str(str, len, &tmplen, ":WANConnectionDevice:1,urn:upnp-org:serviceId:WANIPConn1");
1215 #endif
1216 break;
1217 default:
1218 str = strcat_str(str, len, &tmplen, upnpallowedvalues[v->ieventvalue]);
1220 str = strcat_str(str, len, &tmplen, "</s:");
1221 str = strcat_str(str, len, &tmplen, v->name);
1222 str = strcat_str(str, len, &tmplen, "></e:property>");
1223 /*printf("</s:%s></e:property>\n", v->name);*/
1225 v++;
1227 str = strcat_str(str, len, &tmplen, "</e:propertyset>");
1228 #if 0
1229 printf("</e:propertyset>\n");
1230 printf("\n");
1231 printf("%d\n", tmplen);
1232 #endif
1233 str[*len] = '\0';
1234 return str;
1237 char *
1238 getVarsWANIPCn(int * l)
1240 return genEventVars(l,
1241 &scpdWANIPCn,
1242 SERVICE_TYPE_WANIPC);
1245 char *
1246 getVarsWANCfg(int * l)
1248 return genEventVars(l,
1249 &scpdWANCfg,
1250 "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1");
1253 #ifdef ENABLE_L3F_SERVICE
1254 char *
1255 getVarsL3F(int * l)
1257 return genEventVars(l,
1258 &scpdL3F,
1259 "urn:schemas-upnp-org:service:Layer3Forwarding:1");
1261 #endif
1263 #ifdef ENABLE_6FC_SERVICE
1264 char *
1265 getVars6FC(int * l)
1267 return genEventVars(l,
1268 &scpd6FC,
1269 "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1");
1271 #endif
1273 #ifdef ENABLE_DP_SERVICE
1274 char *
1275 getVarsDP(int * l)
1277 return genEventVars(l,
1278 &scpdDP,
1279 "urn:schemas-upnp-org:service:DeviceProtection:1");
1281 #endif
1283 #endif /* ENABLE_EVENTS */