1: /* $Id: upnpdescgen.c,v 1.1.1.3 2013/07/22 00:32:35 misho Exp $ */
2: /* MiniUPnP project
3: * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
4: * (c) 2006-2012 Thomas Bernard
5: * This software is subject to the conditions detailed
6: * in the LICENCE file provided within the distribution */
7:
8: #include <stdio.h>
9: #include <stdlib.h>
10: #include <string.h>
11:
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"
23:
24:
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)
33:
34:
35: static const char * const upnptypes[] =
36: {
37: "string",
38: "boolean",
39: "ui2",
40: "ui4",
41: "bin.base64"
42: };
43:
44: static const char * const upnpdefaultvalues[] =
45: {
46: 0,
47: "IP_Routed"/*"Unconfigured"*/, /* 1 default value for ConnectionType */
48: "3600", /* 2 default value for PortMappingLeaseDuration */
49: };
50:
51: static const char * const upnpallowedvalues[] =
52: {
53: 0, /* 0 */
54: "DSL", /* 1 */
55: "POTS",
56: "Cable",
57: "Ethernet",
58: 0,
59: "Up", /* 6 */
60: "Down",
61: "Initializing",
62: "Unavailable",
63: 0,
64: "TCP", /* 11 */
65: "UDP",
66: 0,
67: "Unconfigured", /* 14 */
68: "IP_Routed",
69: "IP_Bridged",
70: 0,
71: "Unconfigured", /* 18 */
72: "Connecting",
73: "Connected",
74: "PendingDisconnect",
75: "Disconnecting",
76: "Disconnected",
77: 0,
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 */
89: 0,
90: "", /* 27 */
91: 0
92: };
93:
94: static const int upnpallowedranges[] = {
95: 0,
96: /* 1 PortMappingLeaseDuration */
97: 0,
98: 604800,
99: /* 3 InternalPort */
100: 1,
101: 65535,
102: /* 5 LeaseTime */
103: 1,
104: 86400,
105: /* 7 OutboundPinholeTimeout */
106: 100,
107: 200,
108: };
109:
110: static const char * magicargname[] = {
111: 0,
112: "StartPort",
113: "EndPort",
114: "RemoteHost",
115: "RemotePort",
116: "InternalClient",
117: "InternalPort",
118: "IsWorking"
119: };
120:
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\"";
127:
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[] =
134: {
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}
293: };
294:
295: /* WANIPCn.xml */
296: /* see UPnP_IGD_WANIPConnection 1.0.pdf
297: static struct XMLElt scpdWANIPCn[] =
298: {
299: {root_service, {INITHELPER(1,2)}},
300: {0, {0}}
301: };
302: */
303: static const struct argument AddPortMappingArgs[] =
304: {
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}
314: };
315:
316: #ifdef IGD_V2
317: static const struct argument AddAnyPortMappingArgs[] =
318: {
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}
329: };
330:
331: static const struct argument DeletePortMappingRangeArgs[] =
332: {
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}
338: };
339:
340: static const struct argument GetListOfPortMappingsArgs[] =
341: {
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}
349: };
350: #endif
351:
352: static const struct argument GetExternalIPAddressArgs[] =
353: {
354: {2, 7},
355: {0, 0}
356: };
357:
358: static const struct argument DeletePortMappingArgs[] =
359: {
360: {1, 11},
361: {1, 12},
362: {1, 14},
363: {0, 0}
364: };
365:
366: static const struct argument SetConnectionTypeArgs[] =
367: {
368: {1, 0},
369: {0, 0}
370: };
371:
372: static const struct argument GetConnectionTypeInfoArgs[] =
373: {
374: {2, 0},
375: {2, 1},
376: {0, 0}
377: };
378:
379: static const struct argument GetStatusInfoArgs[] =
380: {
381: {2, 2},
382: {2, 4},
383: {2, 3},
384: {0, 0}
385: };
386:
387: static const struct argument GetNATRSIPStatusArgs[] =
388: {
389: {2, 5},
390: {2, 6},
391: {0, 0}
392: };
393:
394: static const struct argument GetGenericPortMappingEntryArgs[] =
395: {
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}
406: };
407:
408: static const struct argument GetSpecificPortMappingEntryArgs[] =
409: {
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}
419: };
420:
421: static const struct action WANIPCnActions[] =
422: {
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}
466: };
467: /* R=Required, O=Optional */
468:
469: /* ignore "warning: missing initializer" */
470: #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
471:
472: static const struct stateVar WANIPCnVars[] =
473: {
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}
531: };
532:
533: static const struct serviceDesc scpdWANIPCn =
534: { WANIPCnActions, WANIPCnVars };
535:
536: /* WANCfg.xml */
537: /* See UPnP_IGD_WANCommonInterfaceConfig 1.0.pdf */
538:
539: static const struct argument GetCommonLinkPropertiesArgs[] =
540: {
541: {2, 0},
542: {2, 1},
543: {2, 2},
544: {2, 3},
545: {0, 0}
546: };
547:
548: static const struct argument GetTotalBytesSentArgs[] =
549: {
550: {2, 4},
551: {0, 0}
552: };
553:
554: static const struct argument GetTotalBytesReceivedArgs[] =
555: {
556: {2, 5},
557: {0, 0}
558: };
559:
560: static const struct argument GetTotalPacketsSentArgs[] =
561: {
562: {2, 6},
563: {0, 0}
564: };
565:
566: static const struct argument GetTotalPacketsReceivedArgs[] =
567: {
568: {2, 7},
569: {0, 0}
570: };
571:
572: static const struct action WANCfgActions[] =
573: {
574: {"GetCommonLinkProperties", GetCommonLinkPropertiesArgs}, /* Required */
575: {"GetTotalBytesSent", GetTotalBytesSentArgs}, /* optional */
576: {"GetTotalBytesReceived", GetTotalBytesReceivedArgs}, /* optional */
577: {"GetTotalPacketsSent", GetTotalPacketsSentArgs}, /* optional */
578: {"GetTotalPacketsReceived", GetTotalPacketsReceivedArgs}, /* optional */
579: {0, 0}
580: };
581:
582: /* See UPnP_IGD_WANCommonInterfaceConfig 1.0.pdf */
583: static const struct stateVar WANCfgVars[] =
584: {
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}
602: };
603:
604: static const struct serviceDesc scpdWANCfg =
605: { WANCfgActions, WANCfgVars };
606:
607: #ifdef ENABLE_L3F_SERVICE
608: /* Read UPnP_IGD_Layer3Forwarding_1.0.pdf */
609: static const struct argument SetDefaultConnectionServiceArgs[] =
610: {
611: {1, 0}, /* in */
612: {0, 0}
613: };
614:
615: static const struct argument GetDefaultConnectionServiceArgs[] =
616: {
617: {2, 0}, /* out */
618: {0, 0}
619: };
620:
621: static const struct action L3FActions[] =
622: {
623: {"SetDefaultConnectionService", SetDefaultConnectionServiceArgs}, /* Req */
624: {"GetDefaultConnectionService", GetDefaultConnectionServiceArgs}, /* Req */
625: {0, 0}
626: };
627:
628: static const struct stateVar L3FVars[] =
629: {
630: {"DefaultConnectionService", 0|0x80, 0, 0,
631: DEFAULTCONNECTIONSERVICE_MAGICALVALUE}, /* Required */
632: {0, 0}
633: };
634:
635: static const struct serviceDesc scpdL3F =
636: { L3FActions, L3FVars };
637: #endif
638:
639: #ifdef ENABLE_6FC_SERVICE
640: /* see UPnP-gw-WANIPv6FirewallControl-v1-Service.pdf */
641: static const struct argument GetFirewallStatusArgs[] =
642: {
643: {2|0x80, 0}, /* OUT : FirewallEnabled */
644: {2|0x80, 6}, /* OUT : InboundPinholeAllowed */
645: {0, 0}
646: };
647:
648: static const struct argument GetOutboundPinholeTimeoutArgs[] =
649: {
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}
657: };
658:
659: static const struct argument AddPinholeArgs[] =
660: {
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}
669: };
670:
671: static const struct argument UpdatePinholeArgs[] =
672: {
673: {1|0x80, 4}, /* UniqueID IN A_ARG_TYPE_UniqueID */
674: {1, 5}, /* LeaseTime IN A_ARG_TYPE_LeaseTime */
675: {0, 0}
676: };
677:
678: static const struct argument DeletePinholeArgs[] =
679: {
680: {1|0x80, 4}, /* UniqueID IN A_ARG_TYPE_UniqueID */
681: {0, 0}
682: };
683:
684: static const struct argument GetPinholePacketsArgs[] =
685: {
686: {1|0x80, 4}, /* UniqueID IN A_ARG_TYPE_UniqueID */
687: {2|0x80, 9}, /* PinholePackets OUT A_ARG_TYPE_PinholePackets */
688: {0, 0}
689: };
690:
691: static const struct argument CheckPinholeWorkingArgs[] =
692: {
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}
696: };
697:
698: static const struct action IPv6FCActions[] =
699: {
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}
708: };
709:
710: static const struct stateVar IPv6FCVars[] =
711: {
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}
727: };
728:
729: static const struct serviceDesc scpd6FC =
730: { IPv6FCActions, IPv6FCVars };
731: #endif
732:
733: #ifdef ENABLE_DP_SERVICE
734: /* UPnP-gw-DeviceProtection-v1-Service.pdf */
735: static const struct action DPActions[] =
736: {
737: {"SendSetupMessage", 0},
738: {"GetSupportedProtocols", 0},
739: {"GetAssignedRoles", 0},
740: {0, 0}
741: };
742:
743: static const struct stateVar DPVars[] =
744: {
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}
753: };
754:
755: static const struct serviceDesc scpdDP =
756: { DPActions, DPVars };
757: #endif
758:
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)
764: {
765: int s2len;
766: int newlen;
767: char * p;
768:
769: s2len = (int)strlen(s2);
770: if(*tmplen <= (*len + s2len))
771: {
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;
781: }
782: /*strcpy(str + *len, s2); */
783: memcpy(str + *len, s2, s2len + 1);
784: *len += s2len;
785: return str;
786: }
787:
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)
793: {
794: char * p;
795:
796: if(*tmplen <= (*len + 1))
797: {
798: *tmplen += 256;
799: p = (char *)realloc(str, *tmplen);
800: if(p == NULL) /* handle a failure of realloc() */
801: {
802: *tmplen -= 256;
803: return str;
804: }
805: str = p;
806: }
807: str[*len] = c;
808: (*len)++;
809: return str;
810: }
811:
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)
817: {
818: char buf[16];
819: int j;
820:
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;
828: }
829: j = 0;
830: while(i && j < (int)sizeof(buf)) {
831: buf[j++] = '0' + (i % 10);
832: i = i / 10;
833: }
834: while(j > 0) {
835: str = strcat_char(str, len, tmplen, buf[--j]);
836: }
837: return str;
838: }
839:
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)
845: {
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(;;)
860: {
861: eltname = p[i].eltname;
862: if(!eltname)
863: return str;
864: if(eltname[0] == '/')
865: {
866: if(p[i].data && p[i].data[0])
867: {
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, '>');
876: }
877: for(;;)
878: {
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)
885: {
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--;
894: }
895: else
896: break;
897: }
898: }
899: else
900: {
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;
913: }
914: }
915: }
916:
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)
924: {
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;
937: }
938:
939: /* genServiceDesc() :
940: * Generate service description with allowed methods and
941: * related variables. */
942: static char *
943: genServiceDesc(int * len, const struct serviceDesc * s)
944: {
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);
959:
960: acts = s->actionList;
961: vars = s->serviceStateTable;
962:
963: str = strcat_char(str, len, &tmplen, '<');
964: str = strcat_str(str, len, &tmplen, root_service);
965: str = strcat_char(str, len, &tmplen, '>');
966:
967: str = strcat_str(str, len, &tmplen,
968: "<specVersion><major>1</major><minor>0</minor></specVersion>");
969:
970: i = 0;
971: str = strcat_str(str, len, &tmplen, "<actionList>");
972: while(acts[i].name)
973: {
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)
980: {
981: str = strcat_str(str, len, &tmplen, "<argumentList>");
982: j = 0;
983: while(args[j].dir)
984: {
985: str = strcat_str(str, len, &tmplen, "<argument><name>");
986: if((args[j].dir & 0x80) == 0) {
987: str = strcat_str(str, len, &tmplen, "New");
988: }
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");
1002: }
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);
1011: }
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);
1022: }
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++;
1031: }
1032: str = strcat_str(str, len, &tmplen,"</argumentList>");
1033: }
1034: str = strcat_str(str, len, &tmplen, "</action>");
1035: /*str = strcat_char(str, len, &tmplen, '\n'); // TEMP ! */
1036: i++;
1037: }
1038: str = strcat_str(str, len, &tmplen, "</actionList><serviceStateTable>");
1039: i = 0;
1040: while(vars[i].name)
1041: {
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)
1057: {
1058: if((vars[i].itype & 0x0f) == 0)
1059: {
1060: /* string */
1061: str = strcat_str(str, len, &tmplen, "<allowedValueList>");
1062: for(j=vars[i].iallowedlist; upnpallowedvalues[j]; j++)
1063: {
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>");
1067: }
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>");
1076: }
1077: }
1078: /*if(vars[i].defaultValue) */
1079: if(vars[i].idefault)
1080: {
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>");
1085: }
1086: str = strcat_str(str, len, &tmplen, "</stateVariable>");
1087: /*str = strcat_char(str, len, &tmplen, '\n'); // TEMP ! */
1088: i++;
1089: }
1090: str = strcat_str(str, len, &tmplen, "</serviceStateTable></scpd>");
1091: str[*len] = '\0';
1092: return str;
1093: }
1094:
1095: /* genWANIPCn() :
1096: * Generate the WANIPConnection xml description */
1097: char *
1098: genWANIPCn(int * len)
1099: {
1100: return genServiceDesc(len, &scpdWANIPCn);
1101: }
1102:
1103: /* genWANCfg() :
1104: * Generate the WANInterfaceConfig xml description. */
1105: char *
1106: genWANCfg(int * len)
1107: {
1108: return genServiceDesc(len, &scpdWANCfg);
1109: }
1110:
1111: #ifdef ENABLE_L3F_SERVICE
1112: char *
1113: genL3F(int * len)
1114: {
1115: return genServiceDesc(len, &scpdL3F);
1116: }
1117: #endif
1118:
1119: #ifdef ENABLE_6FC_SERVICE
1120: char *
1121: gen6FC(int * len)
1122: {
1123: return genServiceDesc(len, &scpd6FC);
1124: }
1125: #endif
1126:
1127: #ifdef ENABLE_DP_SERVICE
1128: char *
1129: genDP(int * len)
1130: {
1131: return genServiceDesc(len, &scpdDP);
1132: }
1133: #endif
1134:
1135: #ifdef ENABLE_EVENTS
1136: static char *
1137: genEventVars(int * len, const struct serviceDesc * s, const char * servns)
1138: {
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) < 0) {
1202: str = strcat_str(str, len, &tmplen, "0.0.0.0");
1203: } else {
1204: str = strcat_str(str, len, &tmplen, ext_ip_addr);
1205: }
1206: }
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]);
1219: }
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);*/
1224: }
1225: v++;
1226: }
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;
1235: }
1236:
1237: char *
1238: getVarsWANIPCn(int * l)
1239: {
1240: return genEventVars(l,
1241: &scpdWANIPCn,
1242: SERVICE_TYPE_WANIPC);
1243: }
1244:
1245: char *
1246: getVarsWANCfg(int * l)
1247: {
1248: return genEventVars(l,
1249: &scpdWANCfg,
1250: "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1");
1251: }
1252:
1253: #ifdef ENABLE_L3F_SERVICE
1254: char *
1255: getVarsL3F(int * l)
1256: {
1257: return genEventVars(l,
1258: &scpdL3F,
1259: "urn:schemas-upnp-org:service:Layer3Forwarding:1");
1260: }
1261: #endif
1262:
1263: #ifdef ENABLE_6FC_SERVICE
1264: char *
1265: getVars6FC(int * l)
1266: {
1267: return genEventVars(l,
1268: &scpd6FC,
1269: "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1");
1270: }
1271: #endif
1272:
1273: #ifdef ENABLE_DP_SERVICE
1274: char *
1275: getVarsDP(int * l)
1276: {
1277: return genEventVars(l,
1278: &scpdDP,
1279: "urn:schemas-upnp-org:service:DeviceProtection:1");
1280: }
1281: #endif
1282:
1283: #endif /* ENABLE_EVENTS */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>