Miniupnpd: update from 1.8 (20140422) to 1.9 (20141209)
[tomato.git] / release / src / router / miniupnpd / upnpdescgen.c
blob4f45fbf767ba77ec6337ef343c6de0070f03d8a9
1 /* $Id: upnpdescgen.c,v 1.78 2014/10/21 14:08:35 nanard Exp $ */
2 /* MiniUPnP project
3 * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
4 * (c) 2006-2014 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 #ifdef ENABLE_MANUFACTURER_INFO_CONFIGURATION
149 {"/friendlyName", friendly_name/*ROOTDEV_FRIENDLYNAME*/}, /* required */
150 {"/manufacturer", manufacturer_name/*ROOTDEV_MANUFACTURER*/}, /* required */
151 /* 8 */
152 {"/manufacturerURL", manufacturer_url/*ROOTDEV_MANUFACTURERURL*/}, /* optional */
153 {"/modelDescription", model_description/*ROOTDEV_MODELDESCRIPTION*/}, /* recommended */
154 {"/modelName", model_name/*ROOTDEV_MODELNAME*/}, /* required */
155 {"/modelNumber", modelnumber},
156 {"/modelURL", model_url/*ROOTDEV_MODELURL*/},
157 #else
158 {"/friendlyName", ROOTDEV_FRIENDLYNAME}, /* required */
159 {"/manufacturer", ROOTDEV_MANUFACTURER}, /* required */
160 /* 8 */
161 {"/manufacturerURL", ROOTDEV_MANUFACTURERURL}, /* optional */
162 {"/modelDescription", ROOTDEV_MODELDESCRIPTION}, /* recommended */
163 {"/modelName", ROOTDEV_MODELNAME}, /* required */
164 {"/modelNumber", modelnumber},
165 {"/modelURL", ROOTDEV_MODELURL},
166 #endif
167 {"/serialNumber", serialnumber},
168 {"/UDN", uuidvalue_igd}, /* required */
169 /* see if /UPC is needed. */
170 #ifdef ENABLE_6FC_SERVICE
171 #define SERVICES_OFFSET 63
172 #else
173 #define SERVICES_OFFSET 58
174 #endif
175 #if defined(ENABLE_L3F_SERVICE) || defined(HAS_DUMMY_SERVICE) || defined(ENABLE_DP_SERVICE)
176 /* here we dening Services for the root device :
177 * L3F and DUMMY and DeviceProtection */
178 #ifdef ENABLE_L3F_SERVICE
179 #define NSERVICES1 1
180 #else
181 #define NSERVICES1 0
182 #endif
183 #ifdef HAS_DUMMY_SERVICE
184 #define NSERVICES2 1
185 #else
186 #define NSERVICES2 0
187 #endif
188 #ifdef ENABLE_DP_SERVICE
189 #define NSERVICES3 1
190 #else
191 #define NSERVICES3 0
192 #endif
193 #define NSERVICES (NSERVICES1+NSERVICES2+NSERVICES3)
194 {"serviceList", INITHELPER(SERVICES_OFFSET,NSERVICES)},
195 {"deviceList", INITHELPER(18,1)},
196 {"/presentationURL", presentationurl}, /* recommended */
197 #else
198 {"deviceList", INITHELPER(18,1)},
199 {"/presentationURL", presentationurl}, /* recommended */
200 {0,0},
201 #endif
202 /* 18 */
203 {"device", INITHELPER(19,13)},
204 /* 19 */
205 {"/deviceType", DEVICE_TYPE_WAN}, /* required */
206 /* urn:schemas-upnp-org:device:WANDevice:1 or 2 */
207 {"/friendlyName", WANDEV_FRIENDLYNAME},
208 {"/manufacturer", WANDEV_MANUFACTURER},
209 {"/manufacturerURL", WANDEV_MANUFACTURERURL},
210 {"/modelDescription" , WANDEV_MODELDESCRIPTION},
211 {"/modelName", WANDEV_MODELNAME},
212 {"/modelNumber", WANDEV_MODELNUMBER},
213 {"/modelURL", WANDEV_MODELURL},
214 {"/serialNumber", serialnumber},
215 {"/UDN", uuidvalue_wan},
216 {"/UPC", WANDEV_UPC}, /* UPC (=12 digit barcode) is optional */
217 /* 30 */
218 {"serviceList", INITHELPER(32,1)},
219 {"deviceList", INITHELPER(38,1)},
220 /* 32 */
221 {"service", INITHELPER(33,5)},
222 /* 33 */
223 {"/serviceType",
224 "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1"},
225 /*{"/serviceId", "urn:upnp-org:serviceId:WANCommonInterfaceConfig"}, */
226 {"/serviceId", "urn:upnp-org:serviceId:WANCommonIFC1"}, /* required */
227 {"/controlURL", WANCFG_CONTROLURL},
228 {"/eventSubURL", WANCFG_EVENTURL},
229 {"/SCPDURL", WANCFG_PATH},
230 /* 38 */
231 {"device", INITHELPER(39,12)},
232 /* 39 */
233 {"/deviceType", DEVICE_TYPE_WANC},
234 /* urn:schemas-upnp-org:device:WANConnectionDevice:1 or 2 */
235 {"/friendlyName", WANCDEV_FRIENDLYNAME},
236 {"/manufacturer", WANCDEV_MANUFACTURER},
237 {"/manufacturerURL", WANCDEV_MANUFACTURERURL},
238 {"/modelDescription", WANCDEV_MODELDESCRIPTION},
239 {"/modelName", WANCDEV_MODELNAME},
240 {"/modelNumber", WANCDEV_MODELNUMBER},
241 {"/modelURL", WANCDEV_MODELURL},
242 {"/serialNumber", serialnumber},
243 {"/UDN", uuidvalue_wcd},
244 {"/UPC", WANCDEV_UPC}, /* UPC (=12 digit Barcode) is optional */
245 #ifdef ENABLE_6FC_SERVICE
246 {"serviceList", INITHELPER(51,2)},
247 #else
248 {"serviceList", INITHELPER(51,1)},
249 #endif
250 /* 51 */
251 {"service", INITHELPER(53,5)},
252 {"service", INITHELPER(58,5)},
253 /* 53 */
254 {"/serviceType", SERVICE_TYPE_WANIPC},
255 /* urn:schemas-upnp-org:service:WANIPConnection:2 for v2 */
256 {"/serviceId", SERVICE_ID_WANIPC},
257 /* urn:upnp-org:serviceId:WANIPConn1 or 2 */
258 {"/controlURL", WANIPC_CONTROLURL},
259 {"/eventSubURL", WANIPC_EVENTURL},
260 {"/SCPDURL", WANIPC_PATH},
261 #ifdef ENABLE_6FC_SERVICE
262 /* 58 */
263 {"/serviceType", "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1"},
264 {"/serviceId", "urn:upnp-org:serviceId:WANIPv6FC1"},
265 {"/controlURL", WANIP6FC_CONTROLURL},
266 {"/eventSubURL", WANIP6FC_EVENTURL},
267 {"/SCPDURL", WANIP6FC_PATH},
268 #endif
269 /* 58 / 63 = SERVICES_OFFSET*/
270 #if defined(HAS_DUMMY_SERVICE) || defined(ENABLE_L3F_SERVICE) || defined(ENABLE_DP_SERVICE)
271 {"service", INITHELPER(SERVICES_OFFSET+2,5)},
272 {"service", INITHELPER(SERVICES_OFFSET+7,5)},
273 #endif
274 #ifdef HAS_DUMMY_SERVICE
275 /* 60 / 65 = SERVICES_OFFSET+2 */
276 {"/serviceType", "urn:schemas-dummy-com:service:Dummy:1"},
277 {"/serviceId", "urn:dummy-com:serviceId:dummy1"},
278 {"/controlURL", "/dummy"},
279 {"/eventSubURL", "/dummy"},
280 {"/SCPDURL", DUMMY_PATH},
281 #endif
282 #ifdef ENABLE_L3F_SERVICE
283 /* 60 / 65 = SERVICES_OFFSET+2 */
284 {"/serviceType", "urn:schemas-upnp-org:service:Layer3Forwarding:1"},
285 {"/serviceId", "urn:upnp-org:serviceId:Layer3Forwarding1"},
286 {"/controlURL", L3F_CONTROLURL}, /* The Layer3Forwarding service is only */
287 {"/eventSubURL", L3F_EVENTURL}, /* recommended, not mandatory */
288 {"/SCPDURL", L3F_PATH},
289 #endif
290 #ifdef ENABLE_DP_SERVICE
291 /* InternetGatewayDevice v2 :
292 * it is RECOMMEDED that DeviceProtection service is implemented and applied.
293 * If DeviceProtection is not implemented and applied, it is RECOMMENDED
294 * that control points are able to access only actions and parameters defined
295 * as Public role. */
296 /* 65 / 70 = SERVICES_OFFSET+7 */
297 {"/serviceType", "urn:schemas-upnp-org:service:DeviceProtection:1"},
298 {"/serviceId", "urn:upnp-org:serviceId:DeviceProtection1"},
299 {"/controlURL", DP_CONTROLURL},
300 {"/eventSubURL", DP_EVENTURL},
301 {"/SCPDURL", DP_PATH},
302 #endif
303 {0, 0}
306 /* WANIPCn.xml */
307 /* see UPnP_IGD_WANIPConnection 1.0.pdf
308 static struct XMLElt scpdWANIPCn[] =
310 {root_service, {INITHELPER(1,2)}},
311 {0, {0}}
314 static const struct argument AddPortMappingArgs[] =
316 {1, 11}, /* RemoteHost */
317 {1, 12}, /* ExternalPort */
318 {1, 14}, /* PortMappingProtocol */
319 {1, 13}, /* InternalPort */
320 {1, 15}, /* InternalClient */
321 {1, 9}, /* PortMappingEnabled */
322 {1, 16}, /* PortMappingDescription */
323 {1, 10}, /* PortMappingLeaseDuration */
324 {0, 0}
327 #ifdef IGD_V2
328 static const struct argument AddAnyPortMappingArgs[] =
330 {1, 11}, /* RemoteHost */
331 {1, 12}, /* ExternalPort */
332 {1, 14}, /* PortMappingProtocol */
333 {1, 13}, /* InternalPort */
334 {1, 15}, /* InternalClient */
335 {1, 9}, /* PortMappingEnabled */
336 {1, 16}, /* PortMappingDescription */
337 {1, 10}, /* PortMappingLeaseDuration */
338 {2, 12}, /* NewReservedPort / ExternalPort */
339 {0, 0}
342 static const struct argument DeletePortMappingRangeArgs[] =
344 {1|(1<<2), 12}, /* NewStartPort / ExternalPort */
345 {1|(2<<2), 12}, /* NewEndPort / ExternalPort */
346 {1, 14}, /* NewProtocol / PortMappingProtocol */
347 {1, 18}, /* NewManage / A_ARG_TYPE_Manage */
348 {0, 0}
351 static const struct argument GetListOfPortMappingsArgs[] =
353 {1|(1<<2), 12}, /* NewStartPort / ExternalPort */
354 {1|(2<<2), 12}, /* NewEndPort / ExternalPort */
355 {1, 14}, /* NewProtocol / PortMappingProtocol */
356 {1, 18}, /* NewManage / A_ARG_TYPE_Manage */
357 {1, 8}, /* NewNumberOfPorts / PortMappingNumberOfEntries */
358 {2, 19}, /* NewPortListing / A_ARG_TYPE_PortListing */
359 {0, 0}
361 #endif
363 static const struct argument GetExternalIPAddressArgs[] =
365 {2, 7},
366 {0, 0}
369 static const struct argument DeletePortMappingArgs[] =
371 {1, 11}, /* RemoteHost */
372 {1, 12}, /* ExternalPort */
373 {1, 14}, /* PortMappingProtocol */
374 {0, 0}
377 static const struct argument SetConnectionTypeArgs[] =
379 {1, 0},
380 {0, 0}
383 static const struct argument GetConnectionTypeInfoArgs[] =
385 {2, 0},
386 {2, 1},
387 {0, 0}
390 static const struct argument GetStatusInfoArgs[] =
392 {2, 2},
393 {2, 4},
394 {2, 3},
395 {0, 0}
398 static const struct argument GetNATRSIPStatusArgs[] =
400 {2, 5},
401 {2, 6},
402 {0, 0}
405 static const struct argument GetGenericPortMappingEntryArgs[] =
407 {1, 8},
408 {2, 11},
409 {2, 12},
410 {2, 14},
411 {2, 13},
412 {2, 15},
413 {2, 9},
414 {2, 16},
415 {2, 10},
416 {0, 0}
419 static const struct argument GetSpecificPortMappingEntryArgs[] =
421 {1, 11},
422 {1, 12},
423 {1, 14},
424 {2, 13},
425 {2, 15},
426 {2, 9},
427 {2, 16},
428 {2, 10},
429 {0, 0}
432 static const struct action WANIPCnActions[] =
434 {"SetConnectionType", SetConnectionTypeArgs}, /* R */
435 {"GetConnectionTypeInfo", GetConnectionTypeInfoArgs}, /* R */
436 {"RequestConnection", 0}, /* R */
437 /*{"RequestTermination", 0},*/ /* O */
438 {"ForceTermination", 0}, /* R */
439 /*{"SetAutoDisconnectTime", 0},*/ /* O */
440 /*{"SetIdleDisconnectTime", 0},*/ /* O */
441 /*{"SetWarnDisconnectDelay", 0}, */ /* O */
442 {"GetStatusInfo", GetStatusInfoArgs}, /* R */
443 /*GetAutoDisconnectTime*/ /* O */
444 /*GetIdleDisconnectTime*/ /* O */
445 /*GetWarnDisconnectDelay*/ /* O */
446 {"GetNATRSIPStatus", GetNATRSIPStatusArgs}, /* R */
447 {"GetGenericPortMappingEntry", GetGenericPortMappingEntryArgs}, /* R */
448 {"GetSpecificPortMappingEntry", GetSpecificPortMappingEntryArgs}, /* R */
449 {"AddPortMapping", AddPortMappingArgs}, /* R */
450 {"DeletePortMapping", DeletePortMappingArgs}, /* R */
451 {"GetExternalIPAddress", GetExternalIPAddressArgs}, /* R */
452 #ifdef IGD_V2
453 {"DeletePortMappingRange", DeletePortMappingRangeArgs}, /* R, IGD v2 */
454 {"GetListOfPortMappings", GetListOfPortMappingsArgs}, /* R, IGD v2 */
455 {"AddAnyPortMapping", AddAnyPortMappingArgs}, /* R, IGD v2 */
456 #endif
457 #if 0
458 {"AddPortMapping", AddPortMappingArgs}, /* R */
459 {"GetExternalIPAddress", GetExternalIPAddressArgs}, /* R */
460 {"DeletePortMapping", DeletePortMappingArgs}, /* R */
461 {"SetConnectionType", SetConnectionTypeArgs}, /* R */
462 {"GetConnectionTypeInfo", GetConnectionTypeInfoArgs}, /* R */
463 {"RequestConnection", 0}, /* R */
464 {"ForceTermination", 0}, /* R */
465 {"GetStatusInfo", GetStatusInfoArgs}, /* R */
466 {"GetNATRSIPStatus", GetNATRSIPStatusArgs}, /* R */
467 {"GetGenericPortMappingEntry", GetGenericPortMappingEntryArgs}, /* R */
468 {"GetSpecificPortMappingEntry", GetSpecificPortMappingEntryArgs}, /* R */
469 /* added in v2 UPnP-gw-WANIPConnection-v2-Service.pdf */
470 #ifdef IGD_V2
471 {"AddAnyPortMapping", AddAnyPortMappingArgs},
472 {"DeletePortMappingRange", DeletePortMappingRangeArgs},
473 {"GetListOfPortMappings", GetListOfPortMappingsArgs},
474 #endif
475 #endif
476 {0, 0}
478 /* R=Required, O=Optional */
480 /* ignore "warning: missing initializer" */
481 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
483 static const struct stateVar WANIPCnVars[] =
485 /* 0 */
486 #if 0
487 {"ConnectionType", 0, 0/*1*/}, /* required */
488 {"PossibleConnectionTypes", 0|0x80, 0, 14, 15},
489 #endif
490 {"ConnectionType", 0, 1, 14, 15}, /* required */
491 {"PossibleConnectionTypes", 0|0x80, 0, 0, 15},
492 /* Required
493 * Allowed values : Unconfigured / IP_Routed / IP_Bridged */
494 {"ConnectionStatus", 0|0x80, 0/*1*/, 18,
495 CONNECTIONSTATUS_MAGICALVALUE }, /* required */
496 /* Allowed Values : Unconfigured / Connecting(opt) / Connected
497 * PendingDisconnect(opt) / Disconnecting (opt)
498 * Disconnected */
499 {"Uptime", 3, 0}, /* Required */
500 {"LastConnectionError", 0, 0, 25}, /* required : */
501 /* Allowed Values : ERROR_NONE(req) / ERROR_COMMAND_ABORTED(opt)
502 * ERROR_NOT_ENABLED_FOR_INTERNET(opt)
503 * ERROR_USER_DISCONNECT(opt)
504 * ERROR_ISP_DISCONNECT(opt)
505 * ERROR_IDLE_DISCONNECT(opt)
506 * ERROR_FORCED_DISCONNECT(opt)
507 * ERROR_NO_CARRIER(opt)
508 * ERROR_IP_CONFIGURATION(opt)
509 * ERROR_UNKNOWN(opt) */
510 {"RSIPAvailable", 1, 0}, /* required */
511 {"NATEnabled", 1, 0}, /* required */
512 {"ExternalIPAddress", 0|0x80, 0, 0,
513 EXTERNALIPADDRESS_MAGICALVALUE}, /* required. Default : empty string */
514 {"PortMappingNumberOfEntries", 2|0x80, 0, 0,
515 PORTMAPPINGNUMBEROFENTRIES_MAGICALVALUE}, /* required >= 0 */
516 {"PortMappingEnabled", 1, 0}, /* Required */
517 /* 10 */
518 {"PortMappingLeaseDuration", 3, 2, 1}, /* required */
519 /* TODO : for IGD v2 :
520 * <stateVariable sendEvents="no">
521 * <name>PortMappingLeaseDuration</name>
522 * <dataType>ui4</dataType>
523 * <defaultValue>Vendor-defined</defaultValue>
524 * <allowedValueRange>
525 * <minimum>0</minimum>
526 * <maximum>604800</maximum>
527 * </allowedValueRange>
528 * </stateVariable> */
529 {"RemoteHost", 0, 0}, /* required. Default : empty string */
530 {"ExternalPort", 2, 0}, /* required */
531 {"InternalPort", 2, 0, 3}, /* required */
532 {"PortMappingProtocol", 0, 0, 11}, /* required allowedValues: TCP/UDP */
533 {"InternalClient", 0, 0}, /* required */
534 {"PortMappingDescription", 0, 0}, /* required default: empty string */
535 /* added in v2 UPnP-gw-WANIPConnection-v2-Service.pdf */
536 #ifdef IGD_V2
537 {"SystemUpdateID", 3|0x80, 0, 0, SYSTEMUPDATEID_MAGICALVALUE},
538 {"A_ARG_TYPE_Manage", 1, 0},
539 {"A_ARG_TYPE_PortListing", 0, 0},
540 #endif
541 {0, 0}
544 static const struct serviceDesc scpdWANIPCn =
545 { WANIPCnActions, WANIPCnVars };
547 /* WANCfg.xml */
548 /* See UPnP_IGD_WANCommonInterfaceConfig 1.0.pdf */
550 static const struct argument GetCommonLinkPropertiesArgs[] =
552 {2, 0},
553 {2, 1},
554 {2, 2},
555 {2, 3},
556 {0, 0}
559 static const struct argument GetTotalBytesSentArgs[] =
561 {2, 4},
562 {0, 0}
565 static const struct argument GetTotalBytesReceivedArgs[] =
567 {2, 5},
568 {0, 0}
571 static const struct argument GetTotalPacketsSentArgs[] =
573 {2, 6},
574 {0, 0}
577 static const struct argument GetTotalPacketsReceivedArgs[] =
579 {2, 7},
580 {0, 0}
583 static const struct action WANCfgActions[] =
585 {"GetCommonLinkProperties", GetCommonLinkPropertiesArgs}, /* Required */
586 {"GetTotalBytesSent", GetTotalBytesSentArgs}, /* optional */
587 {"GetTotalBytesReceived", GetTotalBytesReceivedArgs}, /* optional */
588 {"GetTotalPacketsSent", GetTotalPacketsSentArgs}, /* optional */
589 {"GetTotalPacketsReceived", GetTotalPacketsReceivedArgs}, /* optional */
590 {0, 0}
593 /* See UPnP_IGD_WANCommonInterfaceConfig 1.0.pdf */
594 static const struct stateVar WANCfgVars[] =
596 {"WANAccessType", 0, 0, 1},
597 /* Allowed Values : DSL / POTS / Cable / Ethernet
598 * Default value : empty string */
599 {"Layer1UpstreamMaxBitRate", 3, 0},
600 {"Layer1DownstreamMaxBitRate", 3, 0},
601 {"PhysicalLinkStatus", 0|0x80, 0, 6, 6},
602 /* allowed values :
603 * Up / Down / Initializing (optional) / Unavailable (optionnal)
604 * no Default value
605 * Evented */
606 {"TotalBytesSent", 3, 0}, /* Optional */
607 {"TotalBytesReceived", 3, 0}, /* Optional */
608 {"TotalPacketsSent", 3, 0}, /* Optional */
609 {"TotalPacketsReceived", 3, 0},/* Optional */
610 /*{"MaximumActiveConnections", 2, 0}, // allowed Range value // OPTIONAL */
611 /*{"WANAccessProvider", 0, 0},*/ /* Optional */
612 {0, 0}
615 static const struct serviceDesc scpdWANCfg =
616 { WANCfgActions, WANCfgVars };
618 #ifdef ENABLE_L3F_SERVICE
619 /* Read UPnP_IGD_Layer3Forwarding_1.0.pdf */
620 static const struct argument SetDefaultConnectionServiceArgs[] =
622 {1, 0}, /* in */
623 {0, 0}
626 static const struct argument GetDefaultConnectionServiceArgs[] =
628 {2, 0}, /* out */
629 {0, 0}
632 static const struct action L3FActions[] =
634 {"SetDefaultConnectionService", SetDefaultConnectionServiceArgs}, /* Req */
635 {"GetDefaultConnectionService", GetDefaultConnectionServiceArgs}, /* Req */
636 {0, 0}
639 static const struct stateVar L3FVars[] =
641 {"DefaultConnectionService", 0|0x80, 0, 0,
642 DEFAULTCONNECTIONSERVICE_MAGICALVALUE}, /* Required */
643 {0, 0}
646 static const struct serviceDesc scpdL3F =
647 { L3FActions, L3FVars };
648 #endif
650 #ifdef ENABLE_6FC_SERVICE
651 /* see UPnP-gw-WANIPv6FirewallControl-v1-Service.pdf */
652 static const struct argument GetFirewallStatusArgs[] =
654 {2|0x80, 0}, /* OUT : FirewallEnabled */
655 {2|0x80, 6}, /* OUT : InboundPinholeAllowed */
656 {0, 0}
659 static const struct argument GetOutboundPinholeTimeoutArgs[] =
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 {2|0x80, 7}, /* OutboundPinholeTimeout OUT A_ARG_TYPE_OutboundPinholeTimeout */
667 {0, 0}
670 static const struct argument AddPinholeArgs[] =
672 {1|0x80|(3<<2), 1}, /* RemoteHost IN A_ARG_TYPE_IPv6Address */
673 {1|0x80|(4<<2), 2}, /* RemotePort IN A_ARG_TYPE_Port */
674 {1|0x80|(5<<2), 1}, /* InternalClient IN A_ARG_TYPE_IPv6Address */
675 {1|0x80|(6<<2), 2}, /* InternalPort IN A_ARG_TYPE_Port */
676 {1|0x80, 3}, /* Protocol IN A_ARG_TYPE_Protocol */
677 {1|0x80, 5}, /* LeaseTime IN A_ARG_TYPE_LeaseTime */
678 {2|0x80, 4}, /* UniqueID OUT A_ARG_TYPE_UniqueID */
679 {0, 0}
682 static const struct argument UpdatePinholeArgs[] =
684 {1|0x80, 4}, /* UniqueID IN A_ARG_TYPE_UniqueID */
685 {1, 5}, /* LeaseTime IN A_ARG_TYPE_LeaseTime */
686 {0, 0}
689 static const struct argument DeletePinholeArgs[] =
691 {1|0x80, 4}, /* UniqueID IN A_ARG_TYPE_UniqueID */
692 {0, 0}
695 static const struct argument GetPinholePacketsArgs[] =
697 {1|0x80, 4}, /* UniqueID IN A_ARG_TYPE_UniqueID */
698 {2|0x80, 9}, /* PinholePackets OUT A_ARG_TYPE_PinholePackets */
699 {0, 0}
702 static const struct argument CheckPinholeWorkingArgs[] =
704 {1|0x80, 4}, /* UniqueID IN A_ARG_TYPE_UniqueID */
705 {2|0x80|(7<<2), 8}, /* IsWorking OUT A_ARG_TYPE_Boolean */
706 {0, 0}
709 static const struct action IPv6FCActions[] =
711 {"GetFirewallStatus", GetFirewallStatusArgs}, /* Req */
712 {"GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs}, /* Opt */
713 {"AddPinhole", AddPinholeArgs}, /* Req */
714 {"UpdatePinhole", UpdatePinholeArgs}, /* Req */
715 {"DeletePinhole", DeletePinholeArgs}, /* Req */
716 {"GetPinholePackets", GetPinholePacketsArgs}, /* Req */
717 {"CheckPinholeWorking", CheckPinholeWorkingArgs}, /* Opt */
718 {0, 0}
721 static const struct stateVar IPv6FCVars[] =
723 {"FirewallEnabled", 1|0x80, 0, 0,
724 FIREWALLENABLED_MAGICALVALUE}, /* Required */
725 {"A_ARG_TYPE_IPv6Address", 0, 0, 0, 0}, /* Required */
726 {"A_ARG_TYPE_Port", 2, 0, 0, 0}, /* Required */
727 {"A_ARG_TYPE_Protocol", 2, 0, 0, 0}, /* Required */
728 /* 4 */
729 {"A_ARG_TYPE_UniqueID", 2, 0, 0, 0}, /* Required */
730 {"A_ARG_TYPE_LeaseTime", 3, 0, 5, 0}, /* Required */
731 {"InboundPinholeAllowed", 1|0x80, 0, 0,
732 INBOUNDPINHOLEALLOWED_MAGICALVALUE}, /* Required */
733 {"A_ARG_TYPE_OutboundPinholeTimeout", 3, 0, 7, 0}, /* Optional */
734 /* 8 */
735 {"A_ARG_TYPE_Boolean", 1, 0, 0, 0}, /* Optional */
736 {"A_ARG_TYPE_PinholePackets", 3, 0, 0, 0}, /* Required */
737 {0, 0}
740 static const struct serviceDesc scpd6FC =
741 { IPv6FCActions, IPv6FCVars };
742 #endif
744 #ifdef ENABLE_DP_SERVICE
745 /* UPnP-gw-DeviceProtection-v1-Service.pdf */
746 static const struct action DPActions[] =
748 {"SendSetupMessage", 0},
749 {"GetSupportedProtocols", 0},
750 {"GetAssignedRoles", 0},
751 {0, 0}
754 static const struct stateVar DPVars[] =
756 {"SetupReady", 1|0x80},
757 {"SupportedProtocols", 0},
758 {"A_ARG_TYPE_ACL", 0},
759 {"A_ARG_TYPE_IdentityList", 0},
760 {"A_ARG_TYPE_Identity", 0},
761 {"A_ARG_TYPE_Base64", 4},
762 {"A_ARG_TYPE_String", 0},
763 {0, 0}
766 static const struct serviceDesc scpdDP =
767 { DPActions, DPVars };
768 #endif
770 /* strcat_str()
771 * concatenate the string and use realloc to increase the
772 * memory buffer if needed. */
773 static char *
774 strcat_str(char * str, int * len, int * tmplen, const char * s2)
776 int s2len;
777 int newlen;
778 char * p;
780 s2len = (int)strlen(s2);
781 if(*tmplen <= (*len + s2len))
783 if(s2len < 256)
784 newlen = *tmplen + 256;
785 else
786 newlen = *tmplen + s2len + 1;
787 p = (char *)realloc(str, newlen);
788 if(p == NULL) /* handle a failure of realloc() */
789 return str;
790 str = p;
791 *tmplen = newlen;
793 /*strcpy(str + *len, s2); */
794 memcpy(str + *len, s2, s2len + 1);
795 *len += s2len;
796 return str;
799 /* strcat_char() :
800 * concatenate a character and use realloc to increase the
801 * size of the memory buffer if needed */
802 static char *
803 strcat_char(char * str, int * len, int * tmplen, char c)
805 char * p;
807 if(*tmplen <= (*len + 1))
809 *tmplen += 256;
810 p = (char *)realloc(str, *tmplen);
811 if(p == NULL) /* handle a failure of realloc() */
813 *tmplen -= 256;
814 return str;
816 str = p;
818 str[*len] = c;
819 (*len)++;
820 return str;
823 /* strcat_int()
824 * concatenate the string representation of the integer.
825 * call strcat_char() */
826 static char *
827 strcat_int(char * str, int * len, int * tmplen, int i)
829 char buf[16];
830 int j;
832 if(i < 0) {
833 str = strcat_char(str, len, tmplen, '-');
834 i = -i;
835 } else if(i == 0) {
836 /* special case for 0 */
837 str = strcat_char(str, len, tmplen, '0');
838 return str;
840 j = 0;
841 while(i && j < (int)sizeof(buf)) {
842 buf[j++] = '0' + (i % 10);
843 i = i / 10;
845 while(j > 0) {
846 str = strcat_char(str, len, tmplen, buf[--j]);
848 return str;
851 /* iterative subroutine using a small stack
852 * This way, the progam stack usage is kept low */
853 static char *
854 genXML(char * str, int * len, int * tmplen,
855 const struct XMLElt * p)
857 unsigned short i, j;
858 unsigned long k;
859 int top;
860 const char * eltname, *s;
861 char c;
862 struct {
863 unsigned short i;
864 unsigned short j;
865 const char * eltname;
866 } pile[16]; /* stack */
867 top = -1;
868 i = 0; /* current node */
869 j = 1; /* i + number of nodes*/
870 for(;;)
872 eltname = p[i].eltname;
873 if(!eltname)
874 return str;
875 if(eltname[0] == '/')
877 if(p[i].data && p[i].data[0])
879 /*printf("<%s>%s<%s>\n", eltname+1, p[i].data, eltname); */
880 str = strcat_char(str, len, tmplen, '<');
881 str = strcat_str(str, len, tmplen, eltname+1);
882 str = strcat_char(str, len, tmplen, '>');
883 str = strcat_str(str, len, tmplen, p[i].data);
884 str = strcat_char(str, len, tmplen, '<');
885 str = strcat_str(str, len, tmplen, eltname);
886 str = strcat_char(str, len, tmplen, '>');
888 for(;;)
890 if(top < 0)
891 return str;
892 i = ++(pile[top].i);
893 j = pile[top].j;
894 /*printf(" pile[%d]\t%d %d\n", top, i, j); */
895 if(i==j)
897 /*printf("</%s>\n", pile[top].eltname); */
898 str = strcat_char(str, len, tmplen, '<');
899 str = strcat_char(str, len, tmplen, '/');
900 s = pile[top].eltname;
901 for(c = *s; c > ' '; c = *(++s))
902 str = strcat_char(str, len, tmplen, c);
903 str = strcat_char(str, len, tmplen, '>');
904 top--;
906 else
907 break;
910 else
912 /*printf("<%s>\n", eltname); */
913 str = strcat_char(str, len, tmplen, '<');
914 str = strcat_str(str, len, tmplen, eltname);
915 str = strcat_char(str, len, tmplen, '>');
916 k = (unsigned long)p[i].data;
917 i = k & 0xffff;
918 j = i + (k >> 16);
919 top++;
920 /*printf(" +pile[%d]\t%d %d\n", top, i, j); */
921 pile[top].i = i;
922 pile[top].j = j;
923 pile[top].eltname = eltname;
928 /* genRootDesc() :
929 * - Generate the root description of the UPnP device.
930 * - the len argument is used to return the length of
931 * the returned string.
932 * - tmp_uuid argument is used to build the uuid string */
933 char *
934 genRootDesc(int * len)
936 char * str;
937 int tmplen;
938 tmplen = 2048;
939 str = (char *)malloc(tmplen);
940 if(str == NULL)
941 return NULL;
942 * len = strlen(xmlver);
943 /*strcpy(str, xmlver); */
944 memcpy(str, xmlver, *len + 1);
945 str = genXML(str, len, &tmplen, rootDesc);
946 str[*len] = '\0';
947 return str;
950 /* genServiceDesc() :
951 * Generate service description with allowed methods and
952 * related variables. */
953 static char *
954 genServiceDesc(int * len, const struct serviceDesc * s)
956 int i, j;
957 const struct action * acts;
958 const struct stateVar * vars;
959 const struct argument * args;
960 const char * p;
961 char * str;
962 int tmplen;
963 tmplen = 2048;
964 str = (char *)malloc(tmplen);
965 if(str == NULL)
966 return NULL;
967 /*strcpy(str, xmlver); */
968 *len = strlen(xmlver);
969 memcpy(str, xmlver, *len + 1);
971 acts = s->actionList;
972 vars = s->serviceStateTable;
974 str = strcat_char(str, len, &tmplen, '<');
975 str = strcat_str(str, len, &tmplen, root_service);
976 str = strcat_char(str, len, &tmplen, '>');
978 str = strcat_str(str, len, &tmplen,
979 "<specVersion><major>1</major><minor>0</minor></specVersion>");
981 i = 0;
982 str = strcat_str(str, len, &tmplen, "<actionList>");
983 while(acts[i].name)
985 str = strcat_str(str, len, &tmplen, "<action><name>");
986 str = strcat_str(str, len, &tmplen, acts[i].name);
987 str = strcat_str(str, len, &tmplen, "</name>");
988 /* argument List */
989 args = acts[i].args;
990 if(args)
992 str = strcat_str(str, len, &tmplen, "<argumentList>");
993 j = 0;
994 while(args[j].dir)
996 str = strcat_str(str, len, &tmplen, "<argument><name>");
997 if((args[j].dir & 0x80) == 0) {
998 str = strcat_str(str, len, &tmplen, "New");
1000 p = vars[args[j].relatedVar].name;
1001 if(args[j].dir & 0x7c) {
1002 /* use magic values ... */
1003 str = strcat_str(str, len, &tmplen, magicargname[(args[j].dir & 0x7c) >> 2]);
1004 } else if(0 == memcmp(p, "PortMapping", 11)
1005 && 0 != memcmp(p + 11, "Description", 11)) {
1006 if(0 == memcmp(p + 11, "NumberOfEntries", 15)) {
1007 /* PortMappingNumberOfEntries */
1008 #ifdef IGD_V2
1009 if(0 == memcmp(acts[i].name, "GetListOfPortMappings", 22)) {
1010 str = strcat_str(str, len, &tmplen, "NumberOfPorts");
1011 } else {
1012 str = strcat_str(str, len, &tmplen, "PortMappingIndex");
1014 #else
1015 str = strcat_str(str, len, &tmplen, "PortMappingIndex");
1016 #endif
1017 } else {
1018 /* PortMappingEnabled
1019 * PortMappingLeaseDuration
1020 * PortMappingProtocol */
1021 str = strcat_str(str, len, &tmplen, p + 11);
1023 #ifdef IGD_V2
1024 } else if(0 == memcmp(p, "A_ARG_TYPE_", 11)) {
1025 str = strcat_str(str, len, &tmplen, p + 11);
1026 } else if(0 == memcmp(p, "ExternalPort", 13)
1027 && args[j].dir == 2
1028 && 0 == memcmp(acts[i].name, "AddAnyPortMapping", 18)) {
1029 str = strcat_str(str, len, &tmplen, "ReservedPort");
1030 #endif
1031 } else {
1032 str = strcat_str(str, len, &tmplen, p);
1034 str = strcat_str(str, len, &tmplen, "</name><direction>");
1035 str = strcat_str(str, len, &tmplen, (args[j].dir&0x03)==1?"in":"out");
1036 str = strcat_str(str, len, &tmplen,
1037 "</direction><relatedStateVariable>");
1038 str = strcat_str(str, len, &tmplen, p);
1039 str = strcat_str(str, len, &tmplen,
1040 "</relatedStateVariable></argument>");
1041 j++;
1043 str = strcat_str(str, len, &tmplen,"</argumentList>");
1045 str = strcat_str(str, len, &tmplen, "</action>");
1046 /*str = strcat_char(str, len, &tmplen, '\n'); // TEMP ! */
1047 i++;
1049 str = strcat_str(str, len, &tmplen, "</actionList><serviceStateTable>");
1050 i = 0;
1051 while(vars[i].name)
1053 str = strcat_str(str, len, &tmplen,
1054 "<stateVariable sendEvents=\"");
1055 #ifdef ENABLE_EVENTS
1056 str = strcat_str(str, len, &tmplen, (vars[i].itype & 0x80)?"yes":"no");
1057 #else
1058 /* for the moment always send no. Wait for SUBSCRIBE implementation
1059 * before setting it to yes */
1060 str = strcat_str(str, len, &tmplen, "no");
1061 #endif
1062 str = strcat_str(str, len, &tmplen, "\"><name>");
1063 str = strcat_str(str, len, &tmplen, vars[i].name);
1064 str = strcat_str(str, len, &tmplen, "</name><dataType>");
1065 str = strcat_str(str, len, &tmplen, upnptypes[vars[i].itype & 0x0f]);
1066 str = strcat_str(str, len, &tmplen, "</dataType>");
1067 if(vars[i].iallowedlist)
1069 if((vars[i].itype & 0x0f) == 0)
1071 /* string */
1072 str = strcat_str(str, len, &tmplen, "<allowedValueList>");
1073 for(j=vars[i].iallowedlist; upnpallowedvalues[j]; j++)
1075 str = strcat_str(str, len, &tmplen, "<allowedValue>");
1076 str = strcat_str(str, len, &tmplen, upnpallowedvalues[j]);
1077 str = strcat_str(str, len, &tmplen, "</allowedValue>");
1079 str = strcat_str(str, len, &tmplen, "</allowedValueList>");
1080 } else {
1081 /* ui2 and ui4 */
1082 str = strcat_str(str, len, &tmplen, "<allowedValueRange><minimum>");
1083 str = strcat_int(str, len, &tmplen, upnpallowedranges[vars[i].iallowedlist]);
1084 str = strcat_str(str, len, &tmplen, "</minimum><maximum>");
1085 str = strcat_int(str, len, &tmplen, upnpallowedranges[vars[i].iallowedlist+1]);
1086 str = strcat_str(str, len, &tmplen, "</maximum></allowedValueRange>");
1089 /*if(vars[i].defaultValue) */
1090 if(vars[i].idefault)
1092 str = strcat_str(str, len, &tmplen, "<defaultValue>");
1093 /*str = strcat_str(str, len, &tmplen, vars[i].defaultValue); */
1094 str = strcat_str(str, len, &tmplen, upnpdefaultvalues[vars[i].idefault]);
1095 str = strcat_str(str, len, &tmplen, "</defaultValue>");
1097 str = strcat_str(str, len, &tmplen, "</stateVariable>");
1098 /*str = strcat_char(str, len, &tmplen, '\n'); // TEMP ! */
1099 i++;
1101 str = strcat_str(str, len, &tmplen, "</serviceStateTable></scpd>");
1102 str[*len] = '\0';
1103 return str;
1106 /* genWANIPCn() :
1107 * Generate the WANIPConnection xml description */
1108 char *
1109 genWANIPCn(int * len)
1111 return genServiceDesc(len, &scpdWANIPCn);
1114 /* genWANCfg() :
1115 * Generate the WANInterfaceConfig xml description. */
1116 char *
1117 genWANCfg(int * len)
1119 return genServiceDesc(len, &scpdWANCfg);
1122 #ifdef ENABLE_L3F_SERVICE
1123 char *
1124 genL3F(int * len)
1126 return genServiceDesc(len, &scpdL3F);
1128 #endif
1130 #ifdef ENABLE_6FC_SERVICE
1131 char *
1132 gen6FC(int * len)
1134 return genServiceDesc(len, &scpd6FC);
1136 #endif
1138 #ifdef ENABLE_DP_SERVICE
1139 char *
1140 genDP(int * len)
1142 return genServiceDesc(len, &scpdDP);
1144 #endif
1146 #ifdef ENABLE_EVENTS
1147 static char *
1148 genEventVars(int * len, const struct serviceDesc * s)
1150 char tmp[16];
1151 const struct stateVar * v;
1152 char * str;
1153 int tmplen;
1154 tmplen = 512;
1155 str = (char *)malloc(tmplen);
1156 if(str == NULL)
1157 return NULL;
1158 *len = 0;
1159 v = s->serviceStateTable;
1160 str = strcat_str(str, len, &tmplen, "<e:propertyset xmlns:e=\"urn:schemas-upnp-org:event-1-0\">");
1161 while(v->name) {
1162 if(v->itype & 0x80) {
1163 str = strcat_str(str, len, &tmplen, "<e:property><");
1164 str = strcat_str(str, len, &tmplen, v->name);
1165 str = strcat_str(str, len, &tmplen, ">");
1166 /*printf("<e:property><%s>", v->name);*/
1167 switch(v->ieventvalue) {
1168 case 0:
1169 break;
1170 case CONNECTIONSTATUS_MAGICALVALUE:
1171 /* or get_wan_connection_status_str(ext_if_name) */
1172 str = strcat_str(str, len, &tmplen,
1173 upnpallowedvalues[18 + get_wan_connection_status(ext_if_name)]);
1174 break;
1175 #ifdef ENABLE_6FC_SERVICE
1176 case FIREWALLENABLED_MAGICALVALUE:
1177 /* see 2.4.2 of UPnP-gw-WANIPv6FirewallControl-v1-Service.pdf */
1178 snprintf(tmp, sizeof(tmp), "%d",
1179 GETFLAG(IPV6FCFWDISABLEDMASK) ? 0 : 1);
1180 str = strcat_str(str, len, &tmplen, tmp);
1181 break;
1182 case INBOUNDPINHOLEALLOWED_MAGICALVALUE:
1183 /* see 2.4.3 of UPnP-gw-WANIPv6FirewallControl-v1-Service.pdf */
1184 snprintf(tmp, sizeof(tmp), "%d",
1185 GETFLAG(IPV6FCINBOUNDDISALLOWEDMASK) ? 0 : 1);
1186 str = strcat_str(str, len, &tmplen, tmp);
1187 break;
1188 #endif
1189 #ifdef IGD_V2
1190 case SYSTEMUPDATEID_MAGICALVALUE:
1191 /* Please read section 2.3.23 SystemUpdateID
1192 * of UPnP-gw-WANIPConnection-v2-Service.pdf */
1193 snprintf(tmp, sizeof(tmp), "%d",
1194 1/* system update id */);
1195 str = strcat_str(str, len, &tmplen, tmp);
1196 break;
1197 #endif
1198 case PORTMAPPINGNUMBEROFENTRIES_MAGICALVALUE:
1199 /* Port mapping number of entries magical value */
1200 snprintf(tmp, sizeof(tmp), "%d",
1201 upnp_get_portmapping_number_of_entries());
1202 str = strcat_str(str, len, &tmplen, tmp);
1203 break;
1204 case EXTERNALIPADDRESS_MAGICALVALUE:
1205 /* External ip address magical value */
1206 if(use_ext_ip_addr)
1207 str = strcat_str(str, len, &tmplen, use_ext_ip_addr);
1208 else {
1209 char ext_ip_addr[INET_ADDRSTRLEN];
1210 if(getifaddr(ext_if_name, ext_ip_addr, INET_ADDRSTRLEN, NULL, NULL) < 0) {
1211 str = strcat_str(str, len, &tmplen, "0.0.0.0");
1212 } else {
1213 str = strcat_str(str, len, &tmplen, ext_ip_addr);
1216 break;
1217 case DEFAULTCONNECTIONSERVICE_MAGICALVALUE:
1218 /* DefaultConnectionService magical value */
1219 str = strcat_str(str, len, &tmplen, uuidvalue_wcd);
1220 #ifdef IGD_V2
1221 str = strcat_str(str, len, &tmplen, ":WANConnectionDevice:2,urn:upnp-org:serviceId:WANIPConn1");
1222 #else
1223 str = strcat_str(str, len, &tmplen, ":WANConnectionDevice:1,urn:upnp-org:serviceId:WANIPConn1");
1224 #endif
1225 break;
1226 default:
1227 str = strcat_str(str, len, &tmplen, upnpallowedvalues[v->ieventvalue]);
1229 str = strcat_str(str, len, &tmplen, "</");
1230 str = strcat_str(str, len, &tmplen, v->name);
1231 str = strcat_str(str, len, &tmplen, "></e:property>");
1232 /*printf("</%s></e:property>\n", v->name);*/
1234 v++;
1236 str = strcat_str(str, len, &tmplen, "</e:propertyset>");
1237 #if 0
1238 printf("</e:propertyset>\n");
1239 printf("\n");
1240 printf("%d\n", tmplen);
1241 #endif
1242 str[*len] = '\0';
1243 return str;
1246 char *
1247 getVarsWANIPCn(int * l)
1249 return genEventVars(l,
1250 &scpdWANIPCn);
1253 char *
1254 getVarsWANCfg(int * l)
1256 return genEventVars(l,
1257 &scpdWANCfg);
1260 #ifdef ENABLE_L3F_SERVICE
1261 char *
1262 getVarsL3F(int * l)
1264 return genEventVars(l,
1265 &scpdL3F);
1267 #endif
1269 #ifdef ENABLE_6FC_SERVICE
1270 char *
1271 getVars6FC(int * l)
1273 return genEventVars(l,
1274 &scpd6FC);
1276 #endif
1278 #ifdef ENABLE_DP_SERVICE
1279 char *
1280 getVarsDP(int * l)
1282 return genEventVars(l,
1283 &scpdDP);
1285 #endif
1287 #endif /* ENABLE_EVENTS */