Annotation of embedaddon/miniupnpd/upnpdescgen.c, revision 1.1.1.2
1.1.1.2 ! misho 1: /* $Id: upnpdescgen.c,v 1.63 2011/05/27 21:36:50 nanard Exp $ */
1.1 misho 2: /* MiniUPnP project
3: * http://miniupnp.free.fr/ or http://miniupnp.tuxfamily.org/
1.1.1.2 ! misho 4: * (c) 2006-2011 Thomas Bernard
1.1 misho 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"
1.1.1.2 ! misho 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:
1.1 misho 34:
35: static const char * const upnptypes[] =
36: {
37: "string",
38: "boolean",
39: "ui2",
1.1.1.2 ! misho 40: "ui4",
! 41: "bin.base64"
1.1 misho 42: };
43:
44: static const char * const upnpdefaultvalues[] =
45: {
46: 0,
1.1.1.2 ! misho 47: "IP_Routed"/*"Unconfigured"*/, /* 1 default value for ConnectionType */
! 48: "3600", /* 2 default value for PortMappingLeaseDuration */
1.1 misho 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 */
1.1.1.2 ! misho 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 */
1.1 misho 89: 0,
90: "", /* 27 */
91: 0
92: };
93:
1.1.1.2 ! misho 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:
1.1 misho 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
1.1.1.2 ! misho 130: * Needs to be checked with UPnP-gw-InternetGatewayDevice-v2-Device.pdf
1.1 misho 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)},
1.1.1.2 ! misho 138: #if defined(ENABLE_L3F_SERVICE) || defined(HAS_DUMMY_SERVICE) || defined(ENABLE_DP_SERVICE)
1.1 misho 139: {"device", INITHELPER(5,13)},
140: #else
141: {"device", INITHELPER(5,12)},
142: #endif
143: {"/major", "1"},
144: {"/minor", "0"},
145: /* 5 */
1.1.1.2 ! misho 146: {"/deviceType", DEVICE_TYPE_IGD},
! 147: /* urn:schemas-upnp-org:device:InternetGatewayDevice:1 or 2 */
1.1 misho 148: {"/friendlyName", 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 */
1.1.1.2 ! misho 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)},
1.1 misho 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 */
1.1.1.2 ! misho 194: {"/deviceType", DEVICE_TYPE_WAN}, /* required */
! 195: /* urn:schemas-upnp-org:device:WANDevice:1 or 2 */
1.1 misho 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},
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 */
1.1.1.2 ! misho 222: {"/deviceType", DEVICE_TYPE_WANC},
! 223: /* urn:schemas-upnp-org:device:WANConnectionDevice:1 or 2 */
1.1 misho 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},
1.1.1.2 ! misho 234: #ifdef ENABLE_6FC_SERVICE
! 235: {"serviceList", INITHELPER(51,2)},
! 236: #else
1.1 misho 237: {"serviceList", INITHELPER(51,1)},
1.1.1.2 ! misho 238: #endif
1.1 misho 239: /* 51 */
1.1.1.2 ! misho 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 */
1.1 misho 247: {"/controlURL", WANIPC_CONTROLURL},
248: {"/eventSubURL", WANIPC_EVENTURL},
249: {"/SCPDURL", WANIPC_PATH},
1.1.1.2 ! misho 250: #ifdef ENABLE_6FC_SERVICE
1.1 misho 251: /* 58 */
1.1.1.2 ! misho 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 */
1.1 misho 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
1.1.1.2 ! misho 272: /* 60 / 65 = SERVICES_OFFSET+2 */
1.1 misho 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
1.1.1.2 ! misho 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
1.1 misho 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: {
1.1.1.2 ! misho 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 */
1.1 misho 337: {0, 0}
338: };
339:
1.1.1.2 ! misho 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:
1.1 misho 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: {
1.1.1.2 ! misho 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*/
! 433: /*GetIdleDisconnectTime*/
! 434: /*GetWarnDisconnectDelay*/
! 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
1.1 misho 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 */
1.1.1.2 ! misho 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
1.1 misho 465: {0, 0}
466: };
467: /* R=Required, O=Optional */
468:
469: static const struct stateVar WANIPCnVars[] =
470: {
471: /* 0 */
1.1.1.2 ! misho 472: #if 0
1.1 misho 473: {"ConnectionType", 0, 0/*1*/}, /* required */
474: {"PossibleConnectionTypes", 0|0x80, 0, 14, 15},
1.1.1.2 ! misho 475: #endif
! 476: {"ConnectionType", 0, 1, 14, 15}, /* required */
! 477: {"PossibleConnectionTypes", 0|0x80, 0, 0, 15},
1.1 misho 478: /* Required
479: * Allowed values : Unconfigured / IP_Routed / IP_Bridged */
1.1.1.2 ! misho 480: {"ConnectionStatus", 0|0x80, 0/*1*/, 18,
! 481: CONNECTIONSTATUS_MAGICALVALUE }, /* required */
1.1 misho 482: /* Allowed Values : Unconfigured / Connecting(opt) / Connected
483: * PendingDisconnect(opt) / Disconnecting (opt)
484: * Disconnected */
485: {"Uptime", 3, 0}, /* Required */
486: {"LastConnectionError", 0, 0, 25}, /* required : */
487: /* Allowed Values : ERROR_NONE(req) / ERROR_COMMAND_ABORTED(opt)
488: * ERROR_NOT_ENABLED_FOR_INTERNET(opt)
489: * ERROR_USER_DISCONNECT(opt)
490: * ERROR_ISP_DISCONNECT(opt)
491: * ERROR_IDLE_DISCONNECT(opt)
492: * ERROR_FORCED_DISCONNECT(opt)
493: * ERROR_NO_CARRIER(opt)
494: * ERROR_IP_CONFIGURATION(opt)
495: * ERROR_UNKNOWN(opt) */
496: {"RSIPAvailable", 1, 0}, /* required */
497: {"NATEnabled", 1, 0}, /* required */
1.1.1.2 ! misho 498: {"ExternalIPAddress", 0|0x80, 0, 0,
! 499: EXTERNALIPADDRESS_MAGICALVALUE}, /* required. Default : empty string */
! 500: {"PortMappingNumberOfEntries", 2|0x80, 0, 0,
! 501: PORTMAPPINGNUMBEROFENTRIES_MAGICALVALUE}, /* required >= 0 */
1.1 misho 502: {"PortMappingEnabled", 1, 0}, /* Required */
1.1.1.2 ! misho 503: /* 10 */
! 504: {"PortMappingLeaseDuration", 3, 2, 1}, /* required */
! 505: /* TODO : for IGD v2 :
! 506: * <stateVariable sendEvents="no">
! 507: * <name>PortMappingLeaseDuration</name>
! 508: * <dataType>ui4</dataType>
! 509: * <defaultValue>Vendor-defined</defaultValue>
! 510: * <allowedValueRange>
! 511: * <minimum>0</minimum>
! 512: * <maximum>604800</maximum>
! 513: * </allowedValueRange>
! 514: * </stateVariable> */
1.1 misho 515: {"RemoteHost", 0, 0}, /* required. Default : empty string */
516: {"ExternalPort", 2, 0}, /* required */
1.1.1.2 ! misho 517: {"InternalPort", 2, 0, 3}, /* required */
1.1 misho 518: {"PortMappingProtocol", 0, 0, 11}, /* required allowedValues: TCP/UDP */
519: {"InternalClient", 0, 0}, /* required */
520: {"PortMappingDescription", 0, 0}, /* required default: empty string */
1.1.1.2 ! misho 521: /* added in v2 UPnP-gw-WANIPConnection-v2-Service.pdf */
! 522: #ifdef IGD_V2
! 523: {"SystemUpdateID", 3|0x80, 0, 0, SYSTEMUPDATEID_MAGICALVALUE},
! 524: {"A_ARG_TYPE_Manage", 1, 0},
! 525: {"A_ARG_TYPE_PortListing", 0, 0},
! 526: #endif
1.1 misho 527: {0, 0}
528: };
529:
530: static const struct serviceDesc scpdWANIPCn =
531: { WANIPCnActions, WANIPCnVars };
532:
533: /* WANCfg.xml */
534: /* See UPnP_IGD_WANCommonInterfaceConfig 1.0.pdf */
535:
536: static const struct argument GetCommonLinkPropertiesArgs[] =
537: {
538: {2, 0},
539: {2, 1},
540: {2, 2},
541: {2, 3},
542: {0, 0}
543: };
544:
545: static const struct argument GetTotalBytesSentArgs[] =
546: {
547: {2, 4},
548: {0, 0}
549: };
550:
551: static const struct argument GetTotalBytesReceivedArgs[] =
552: {
553: {2, 5},
554: {0, 0}
555: };
556:
557: static const struct argument GetTotalPacketsSentArgs[] =
558: {
559: {2, 6},
560: {0, 0}
561: };
562:
563: static const struct argument GetTotalPacketsReceivedArgs[] =
564: {
565: {2, 7},
566: {0, 0}
567: };
568:
569: static const struct action WANCfgActions[] =
570: {
571: {"GetCommonLinkProperties", GetCommonLinkPropertiesArgs}, /* Required */
572: {"GetTotalBytesSent", GetTotalBytesSentArgs}, /* optional */
573: {"GetTotalBytesReceived", GetTotalBytesReceivedArgs}, /* optional */
574: {"GetTotalPacketsSent", GetTotalPacketsSentArgs}, /* optional */
575: {"GetTotalPacketsReceived", GetTotalPacketsReceivedArgs}, /* optional */
576: {0, 0}
577: };
578:
579: /* See UPnP_IGD_WANCommonInterfaceConfig 1.0.pdf */
580: static const struct stateVar WANCfgVars[] =
581: {
582: {"WANAccessType", 0, 0, 1},
583: /* Allowed Values : DSL / POTS / Cable / Ethernet
584: * Default value : empty string */
585: {"Layer1UpstreamMaxBitRate", 3, 0},
586: {"Layer1DownstreamMaxBitRate", 3, 0},
587: {"PhysicalLinkStatus", 0|0x80, 0, 6, 6},
588: /* allowed values :
589: * Up / Down / Initializing (optional) / Unavailable (optionnal)
590: * no Default value
591: * Evented */
592: {"TotalBytesSent", 3, 0}, /* Optional */
593: {"TotalBytesReceived", 3, 0}, /* Optional */
594: {"TotalPacketsSent", 3, 0}, /* Optional */
595: {"TotalPacketsReceived", 3, 0},/* Optional */
596: /*{"MaximumActiveConnections", 2, 0}, // allowed Range value // OPTIONAL */
1.1.1.2 ! misho 597: /*{"WANAccessProvider", 0, 0},*/ /* Optional */
1.1 misho 598: {0, 0}
599: };
600:
601: static const struct serviceDesc scpdWANCfg =
602: { WANCfgActions, WANCfgVars };
603:
604: #ifdef ENABLE_L3F_SERVICE
605: /* Read UPnP_IGD_Layer3Forwarding_1.0.pdf */
606: static const struct argument SetDefaultConnectionServiceArgs[] =
607: {
608: {1, 0}, /* in */
609: {0, 0}
610: };
611:
612: static const struct argument GetDefaultConnectionServiceArgs[] =
613: {
614: {2, 0}, /* out */
615: {0, 0}
616: };
617:
618: static const struct action L3FActions[] =
619: {
620: {"SetDefaultConnectionService", SetDefaultConnectionServiceArgs}, /* Req */
621: {"GetDefaultConnectionService", GetDefaultConnectionServiceArgs}, /* Req */
622: {0, 0}
623: };
624:
625: static const struct stateVar L3FVars[] =
626: {
1.1.1.2 ! misho 627: {"DefaultConnectionService", 0|0x80, 0, 0,
! 628: DEFAULTCONNECTIONSERVICE_MAGICALVALUE}, /* Required */
1.1 misho 629: {0, 0}
630: };
631:
632: static const struct serviceDesc scpdL3F =
633: { L3FActions, L3FVars };
634: #endif
635:
1.1.1.2 ! misho 636: #ifdef ENABLE_6FC_SERVICE
! 637: /* see UPnP-gw-WANIPv6FirewallControl-v1-Service.pdf */
! 638: static const struct argument GetFirewallStatusArgs[] =
! 639: {
! 640: {2|0x80, 0}, /* OUT : FirewallEnabled */
! 641: {2|0x80, 6}, /* OUT : InboundPinholeAllowed */
! 642: {0, 0}
! 643: };
! 644:
! 645: static const struct argument GetOutboundPinholeTimeoutArgs[] =
! 646: {
! 647: {1|0x80|(3<<2), 1}, /* RemoteHost IN A_ARG_TYPE_IPv6Address */
! 648: {1|0x80|(4<<2), 2}, /* RemotePort IN A_ARG_TYPE_Port */
! 649: {1|0x80|(5<<2), 1}, /* InternalClient IN A_ARG_TYPE_IPv6Address */
! 650: {1|0x80|(6<<2), 2}, /* InternalPort IN A_ARG_TYPE_Port */
! 651: {1|0x80, 3}, /* Protocol IN A_ARG_TYPE_Protocol */
! 652: {2|0x80, 7}, /* OutboundPinholeTimeout OUT A_ARG_TYPE_OutboundPinholeTimeout */
! 653: {0, 0}
! 654: };
! 655:
! 656: static const struct argument AddPinholeArgs[] =
! 657: {
! 658: {1|0x80|(3<<2), 1}, /* RemoteHost IN A_ARG_TYPE_IPv6Address */
! 659: {1|0x80|(4<<2), 2}, /* RemotePort IN A_ARG_TYPE_Port */
! 660: {1|0x80|(5<<2), 1}, /* InternalClient IN A_ARG_TYPE_IPv6Address */
! 661: {1|0x80|(6<<2), 2}, /* InternalPort IN A_ARG_TYPE_Port */
! 662: {1|0x80, 3}, /* Protocol IN A_ARG_TYPE_Protocol */
! 663: {1|0x80, 5}, /* LeaseTime IN A_ARG_TYPE_LeaseTime */
! 664: {2|0x80, 4}, /* UniqueID OUT A_ARG_TYPE_UniqueID */
! 665: {0, 0}
! 666: };
! 667:
! 668: static const struct argument UpdatePinholeArgs[] =
! 669: {
! 670: {1|0x80, 4}, /* UniqueID IN A_ARG_TYPE_UniqueID */
! 671: {1, 5}, /* LeaseTime IN A_ARG_TYPE_LeaseTime */
! 672: {0, 0}
! 673: };
! 674:
! 675: static const struct argument DeletePinholeArgs[] =
! 676: {
! 677: {1|0x80, 4}, /* UniqueID IN A_ARG_TYPE_UniqueID */
! 678: {0, 0}
! 679: };
! 680:
! 681: static const struct argument GetPinholePacketsArgs[] =
! 682: {
! 683: {1|0x80, 4}, /* UniqueID IN A_ARG_TYPE_UniqueID */
! 684: {2|0x80, 9}, /* PinholePackets OUT A_ARG_TYPE_PinholePackets */
! 685: {0, 0}
! 686: };
! 687:
! 688: static const struct argument CheckPinholeWorkingArgs[] =
! 689: {
! 690: {1|0x80, 4}, /* UniqueID IN A_ARG_TYPE_UniqueID */
! 691: {2|0x80|(7<<2), 8}, /* IsWorking OUT A_ARG_TYPE_Boolean */
! 692: {0, 0}
! 693: };
! 694:
! 695: static const struct action IPv6FCActions[] =
! 696: {
! 697: {"GetFirewallStatus", GetFirewallStatusArgs}, /* Req */
! 698: {"GetOutboundPinholeTimeout", GetOutboundPinholeTimeoutArgs}, /* Opt */
! 699: {"AddPinhole", AddPinholeArgs}, /* Req */
! 700: {"UpdatePinhole", UpdatePinholeArgs}, /* Req */
! 701: {"DeletePinhole", DeletePinholeArgs}, /* Req */
! 702: {"GetPinholePackets", GetPinholePacketsArgs}, /* Req */
! 703: {"CheckPinholeWorking", CheckPinholeWorkingArgs}, /* Opt */
! 704: {0, 0}
! 705: };
! 706:
! 707: static const struct stateVar IPv6FCVars[] =
! 708: {
! 709: {"FirewallEnabled", 1|0x80, 0, 0,
! 710: FIREWALLENABLED_MAGICALVALUE}, /* Required */
! 711: {"A_ARG_TYPE_IPv6Address", 0, 0, 0, 0}, /* Required */
! 712: {"A_ARG_TYPE_Port", 2, 0, 0, 0}, /* Required */
! 713: {"A_ARG_TYPE_Protocol", 2, 0, 0, 0}, /* Required */
! 714: /* 4 */
! 715: {"A_ARG_TYPE_UniqueID", 2, 0, 0, 0}, /* Required */
! 716: {"A_ARG_TYPE_LeaseTime", 3, 0, 5, 0}, /* Required */
! 717: {"InboundPinholeAllowed", 1|0x80, 0, 0,
! 718: INBOUNDPINHOLEALLOWED_MAGICALVALUE}, /* Required */
! 719: {"A_ARG_TYPE_OutboundPinholeTimeout", 3, 0, 7, 0}, /* Optional */
! 720: /* 8 */
! 721: {"A_ARG_TYPE_Boolean", 1, 0, 0, 0}, /* Optional */
! 722: {"A_ARG_TYPE_PinholePackets", 3, 0, 0, 0}, /* Required */
! 723: {0, 0}
! 724: };
! 725:
! 726: static const struct serviceDesc scpd6FC =
! 727: { IPv6FCActions, IPv6FCVars };
! 728: #endif
! 729:
! 730: #ifdef ENABLE_DP_SERVICE
! 731: /* UPnP-gw-DeviceProtection-v1-Service.pdf */
! 732: static const struct action DPActions[] =
! 733: {
! 734: {"SendSetupMessage", 0},
! 735: {"GetSupportedProtocols", 0},
! 736: {"GetAssignedRoles", 0},
! 737: {0, 0}
! 738: };
! 739:
! 740: static const struct stateVar DPVars[] =
! 741: {
! 742: {"SetupReady", 1|0x80},
! 743: {"SupportedProtocols", 0},
! 744: {"A_ARG_TYPE_ACL", 0},
! 745: {"A_ARG_TYPE_IdentityList", 0},
! 746: {"A_ARG_TYPE_Identity", 0},
! 747: {"A_ARG_TYPE_Base64", 4},
! 748: {"A_ARG_TYPE_String", 0},
! 749: {0, 0}
! 750: };
! 751:
! 752: static const struct serviceDesc scpdDP =
! 753: { DPActions, DPVars };
! 754: #endif
! 755:
1.1 misho 756: /* strcat_str()
757: * concatenate the string and use realloc to increase the
758: * memory buffer if needed. */
759: static char *
760: strcat_str(char * str, int * len, int * tmplen, const char * s2)
761: {
762: int s2len;
1.1.1.2 ! misho 763: int newlen;
! 764: char * p;
! 765:
1.1 misho 766: s2len = (int)strlen(s2);
767: if(*tmplen <= (*len + s2len))
768: {
769: if(s2len < 256)
1.1.1.2 ! misho 770: newlen = *tmplen + 256;
1.1 misho 771: else
1.1.1.2 ! misho 772: newlen = *tmplen + s2len + 1;
! 773: p = (char *)realloc(str, newlen);
! 774: if(p == NULL) /* handle a failure of realloc() */
! 775: return str;
! 776: str = p;
! 777: *tmplen = newlen;
1.1 misho 778: }
779: /*strcpy(str + *len, s2); */
780: memcpy(str + *len, s2, s2len + 1);
781: *len += s2len;
782: return str;
783: }
784:
785: /* strcat_char() :
786: * concatenate a character and use realloc to increase the
787: * size of the memory buffer if needed */
788: static char *
789: strcat_char(char * str, int * len, int * tmplen, char c)
790: {
1.1.1.2 ! misho 791: char * p;
! 792:
1.1 misho 793: if(*tmplen <= (*len + 1))
794: {
795: *tmplen += 256;
1.1.1.2 ! misho 796: p = (char *)realloc(str, *tmplen);
! 797: if(p == NULL) /* handle a failure of realloc() */
! 798: {
! 799: *tmplen -= 256;
! 800: return str;
! 801: }
! 802: str = p;
1.1 misho 803: }
804: str[*len] = c;
805: (*len)++;
806: return str;
807: }
808:
1.1.1.2 ! misho 809: /* strcat_int()
! 810: * concatenate the string representation of the integer.
! 811: * call strcat_char() */
! 812: static char *
! 813: strcat_int(char * str, int * len, int * tmplen, int i)
! 814: {
! 815: char buf[16];
! 816: int j;
! 817:
! 818: if(i < 0) {
! 819: str = strcat_char(str, len, tmplen, '-');
! 820: i = -i;
! 821: } else if(i == 0) {
! 822: /* special case for 0 */
! 823: str = strcat_char(str, len, tmplen, '0');
! 824: return str;
! 825: }
! 826: j = 0;
! 827: while(i && j < sizeof(buf)) {
! 828: buf[j++] = '0' + (i % 10);
! 829: i = i / 10;
! 830: }
! 831: while(j > 0) {
! 832: str = strcat_char(str, len, tmplen, buf[--j]);
! 833: }
! 834: return str;
! 835: }
! 836:
1.1 misho 837: /* iterative subroutine using a small stack
838: * This way, the progam stack usage is kept low */
839: static char *
840: genXML(char * str, int * len, int * tmplen,
841: const struct XMLElt * p)
842: {
843: unsigned short i, j;
844: unsigned long k;
845: int top;
846: const char * eltname, *s;
847: char c;
848: struct {
849: unsigned short i;
850: unsigned short j;
851: const char * eltname;
852: } pile[16]; /* stack */
853: top = -1;
854: i = 0; /* current node */
855: j = 1; /* i + number of nodes*/
856: for(;;)
857: {
858: eltname = p[i].eltname;
859: if(!eltname)
860: return str;
861: if(eltname[0] == '/')
862: {
863: if(p[i].data && p[i].data[0])
864: {
865: /*printf("<%s>%s<%s>\n", eltname+1, p[i].data, eltname); */
866: str = strcat_char(str, len, tmplen, '<');
867: str = strcat_str(str, len, tmplen, eltname+1);
868: str = strcat_char(str, len, tmplen, '>');
869: str = strcat_str(str, len, tmplen, p[i].data);
870: str = strcat_char(str, len, tmplen, '<');
871: str = strcat_str(str, len, tmplen, eltname);
872: str = strcat_char(str, len, tmplen, '>');
873: }
874: for(;;)
875: {
876: if(top < 0)
877: return str;
878: i = ++(pile[top].i);
879: j = pile[top].j;
880: /*printf(" pile[%d]\t%d %d\n", top, i, j); */
881: if(i==j)
882: {
883: /*printf("</%s>\n", pile[top].eltname); */
884: str = strcat_char(str, len, tmplen, '<');
885: str = strcat_char(str, len, tmplen, '/');
886: s = pile[top].eltname;
887: for(c = *s; c > ' '; c = *(++s))
888: str = strcat_char(str, len, tmplen, c);
889: str = strcat_char(str, len, tmplen, '>');
890: top--;
891: }
892: else
893: break;
894: }
895: }
896: else
897: {
898: /*printf("<%s>\n", eltname); */
899: str = strcat_char(str, len, tmplen, '<');
900: str = strcat_str(str, len, tmplen, eltname);
901: str = strcat_char(str, len, tmplen, '>');
902: k = (unsigned long)p[i].data;
903: i = k & 0xffff;
904: j = i + (k >> 16);
905: top++;
906: /*printf(" +pile[%d]\t%d %d\n", top, i, j); */
907: pile[top].i = i;
908: pile[top].j = j;
909: pile[top].eltname = eltname;
910: }
911: }
912: }
913:
914: /* genRootDesc() :
915: * - Generate the root description of the UPnP device.
916: * - the len argument is used to return the length of
917: * the returned string.
918: * - tmp_uuid argument is used to build the uuid string */
919: char *
920: genRootDesc(int * len)
921: {
922: char * str;
923: int tmplen;
924: tmplen = 2048;
925: str = (char *)malloc(tmplen);
926: if(str == NULL)
927: return NULL;
928: * len = strlen(xmlver);
929: /*strcpy(str, xmlver); */
930: memcpy(str, xmlver, *len + 1);
931: str = genXML(str, len, &tmplen, rootDesc);
932: str[*len] = '\0';
933: return str;
934: }
935:
936: /* genServiceDesc() :
937: * Generate service description with allowed methods and
938: * related variables. */
939: static char *
940: genServiceDesc(int * len, const struct serviceDesc * s)
941: {
942: int i, j;
943: const struct action * acts;
944: const struct stateVar * vars;
945: const struct argument * args;
946: const char * p;
947: char * str;
948: int tmplen;
949: tmplen = 2048;
950: str = (char *)malloc(tmplen);
951: if(str == NULL)
952: return NULL;
953: /*strcpy(str, xmlver); */
954: *len = strlen(xmlver);
955: memcpy(str, xmlver, *len + 1);
956:
957: acts = s->actionList;
958: vars = s->serviceStateTable;
959:
960: str = strcat_char(str, len, &tmplen, '<');
961: str = strcat_str(str, len, &tmplen, root_service);
962: str = strcat_char(str, len, &tmplen, '>');
963:
964: str = strcat_str(str, len, &tmplen,
965: "<specVersion><major>1</major><minor>0</minor></specVersion>");
966:
967: i = 0;
968: str = strcat_str(str, len, &tmplen, "<actionList>");
969: while(acts[i].name)
970: {
971: str = strcat_str(str, len, &tmplen, "<action><name>");
972: str = strcat_str(str, len, &tmplen, acts[i].name);
973: str = strcat_str(str, len, &tmplen, "</name>");
974: /* argument List */
975: args = acts[i].args;
976: if(args)
977: {
978: str = strcat_str(str, len, &tmplen, "<argumentList>");
979: j = 0;
980: while(args[j].dir)
981: {
1.1.1.2 ! misho 982: str = strcat_str(str, len, &tmplen, "<argument><name>");
! 983: if((args[j].dir & 0x80) == 0) {
! 984: str = strcat_str(str, len, &tmplen, "New");
! 985: }
1.1 misho 986: p = vars[args[j].relatedVar].name;
1.1.1.2 ! misho 987: if(args[j].dir & 0x7c) {
! 988: /* use magic values ... */
! 989: str = strcat_str(str, len, &tmplen, magicargname[(args[j].dir & 0x7c) >> 2]);
! 990: } else if(0 == memcmp(p, "PortMapping", 11)
1.1 misho 991: && 0 != memcmp(p + 11, "Description", 11)) {
1.1.1.2 ! misho 992: if(0 == memcmp(p + 11, "NumberOfEntries", 15)) {
! 993: /* PortMappingNumberOfEntries */
! 994: #ifdef IGD_V2
! 995: if(0 == memcmp(acts[i].name, "GetListOfPortMappings", 22)) {
! 996: str = strcat_str(str, len, &tmplen, "NumberOfPorts");
! 997: } else {
! 998: str = strcat_str(str, len, &tmplen, "PortMappingIndex");
! 999: }
! 1000: #else
1.1 misho 1001: str = strcat_str(str, len, &tmplen, "PortMappingIndex");
1.1.1.2 ! misho 1002: #endif
! 1003: } else {
! 1004: /* PortMappingEnabled
! 1005: * PortMappingLeaseDuration
! 1006: * PortMappingProtocol */
1.1 misho 1007: str = strcat_str(str, len, &tmplen, p + 11);
1.1.1.2 ! misho 1008: }
! 1009: #ifdef IGD_V2
! 1010: } else if(0 == memcmp(p, "A_ARG_TYPE_", 11)) {
! 1011: str = strcat_str(str, len, &tmplen, p + 11);
! 1012: } else if(0 == memcmp(p, "ExternalPort", 13)
! 1013: && args[j].dir == 2
! 1014: && 0 == memcmp(acts[i].name, "AddAnyPortMapping", 18)) {
! 1015: str = strcat_str(str, len, &tmplen, "ReservedPort");
! 1016: #endif
1.1 misho 1017: } else {
1018: str = strcat_str(str, len, &tmplen, p);
1019: }
1020: str = strcat_str(str, len, &tmplen, "</name><direction>");
1.1.1.2 ! misho 1021: str = strcat_str(str, len, &tmplen, (args[j].dir&0x03)==1?"in":"out");
1.1 misho 1022: str = strcat_str(str, len, &tmplen,
1023: "</direction><relatedStateVariable>");
1024: str = strcat_str(str, len, &tmplen, p);
1025: str = strcat_str(str, len, &tmplen,
1026: "</relatedStateVariable></argument>");
1027: j++;
1028: }
1029: str = strcat_str(str, len, &tmplen,"</argumentList>");
1030: }
1031: str = strcat_str(str, len, &tmplen, "</action>");
1032: /*str = strcat_char(str, len, &tmplen, '\n'); // TEMP ! */
1033: i++;
1034: }
1035: str = strcat_str(str, len, &tmplen, "</actionList><serviceStateTable>");
1036: i = 0;
1037: while(vars[i].name)
1038: {
1039: str = strcat_str(str, len, &tmplen,
1040: "<stateVariable sendEvents=\"");
1041: #ifdef ENABLE_EVENTS
1042: str = strcat_str(str, len, &tmplen, (vars[i].itype & 0x80)?"yes":"no");
1043: #else
1.1.1.2 ! misho 1044: /* for the moment always send no. Wait for SUBSCRIBE implementation
1.1 misho 1045: * before setting it to yes */
1046: str = strcat_str(str, len, &tmplen, "no");
1047: #endif
1048: str = strcat_str(str, len, &tmplen, "\"><name>");
1049: str = strcat_str(str, len, &tmplen, vars[i].name);
1050: str = strcat_str(str, len, &tmplen, "</name><dataType>");
1051: str = strcat_str(str, len, &tmplen, upnptypes[vars[i].itype & 0x0f]);
1052: str = strcat_str(str, len, &tmplen, "</dataType>");
1053: if(vars[i].iallowedlist)
1054: {
1.1.1.2 ! misho 1055: if((vars[i].itype & 0x0f) == 0)
1.1 misho 1056: {
1.1.1.2 ! misho 1057: /* string */
! 1058: str = strcat_str(str, len, &tmplen, "<allowedValueList>");
! 1059: for(j=vars[i].iallowedlist; upnpallowedvalues[j]; j++)
! 1060: {
! 1061: str = strcat_str(str, len, &tmplen, "<allowedValue>");
! 1062: str = strcat_str(str, len, &tmplen, upnpallowedvalues[j]);
! 1063: str = strcat_str(str, len, &tmplen, "</allowedValue>");
! 1064: }
! 1065: str = strcat_str(str, len, &tmplen, "</allowedValueList>");
! 1066: } else {
! 1067: /* ui2 and ui4 */
! 1068: str = strcat_str(str, len, &tmplen, "<allowedValueRange><minimum>");
! 1069: str = strcat_int(str, len, &tmplen, upnpallowedranges[vars[i].iallowedlist]);
! 1070: str = strcat_str(str, len, &tmplen, "</minimum><maximum>");
! 1071: str = strcat_int(str, len, &tmplen, upnpallowedranges[vars[i].iallowedlist+1]);
! 1072: str = strcat_str(str, len, &tmplen, "</maximum></allowedValueRange>");
1.1 misho 1073: }
1074: }
1075: /*if(vars[i].defaultValue) */
1076: if(vars[i].idefault)
1077: {
1078: str = strcat_str(str, len, &tmplen, "<defaultValue>");
1079: /*str = strcat_str(str, len, &tmplen, vars[i].defaultValue); */
1080: str = strcat_str(str, len, &tmplen, upnpdefaultvalues[vars[i].idefault]);
1081: str = strcat_str(str, len, &tmplen, "</defaultValue>");
1082: }
1083: str = strcat_str(str, len, &tmplen, "</stateVariable>");
1084: /*str = strcat_char(str, len, &tmplen, '\n'); // TEMP ! */
1085: i++;
1086: }
1087: str = strcat_str(str, len, &tmplen, "</serviceStateTable></scpd>");
1088: str[*len] = '\0';
1089: return str;
1090: }
1091:
1092: /* genWANIPCn() :
1093: * Generate the WANIPConnection xml description */
1094: char *
1095: genWANIPCn(int * len)
1096: {
1097: return genServiceDesc(len, &scpdWANIPCn);
1098: }
1099:
1100: /* genWANCfg() :
1101: * Generate the WANInterfaceConfig xml description. */
1102: char *
1103: genWANCfg(int * len)
1104: {
1105: return genServiceDesc(len, &scpdWANCfg);
1106: }
1107:
1108: #ifdef ENABLE_L3F_SERVICE
1109: char *
1110: genL3F(int * len)
1111: {
1112: return genServiceDesc(len, &scpdL3F);
1113: }
1114: #endif
1115:
1.1.1.2 ! misho 1116: #ifdef ENABLE_6FC_SERVICE
! 1117: char *
! 1118: gen6FC(int * len)
! 1119: {
! 1120: return genServiceDesc(len, &scpd6FC);
! 1121: }
! 1122: #endif
! 1123:
! 1124: #ifdef ENABLE_DP_SERVICE
! 1125: char *
! 1126: genDP(int * len)
! 1127: {
! 1128: return genServiceDesc(len, &scpdDP);
! 1129: }
! 1130: #endif
! 1131:
1.1 misho 1132: #ifdef ENABLE_EVENTS
1133: static char *
1134: genEventVars(int * len, const struct serviceDesc * s, const char * servns)
1135: {
1136: char tmp[16];
1137: const struct stateVar * v;
1138: char * str;
1139: int tmplen;
1140: tmplen = 512;
1141: str = (char *)malloc(tmplen);
1142: if(str == NULL)
1143: return NULL;
1144: *len = 0;
1145: v = s->serviceStateTable;
1146: str = strcat_str(str, len, &tmplen, "<e:propertyset xmlns:e=\"urn:schemas-upnp-org:event-1-0\" xmlns:s=\"");
1147: str = strcat_str(str, len, &tmplen, servns);
1148: str = strcat_str(str, len, &tmplen, "\">");
1149: while(v->name) {
1150: if(v->itype & 0x80) {
1151: str = strcat_str(str, len, &tmplen, "<e:property><s:");
1152: str = strcat_str(str, len, &tmplen, v->name);
1153: str = strcat_str(str, len, &tmplen, ">");
1154: //printf("<e:property><s:%s>", v->name);
1155: switch(v->ieventvalue) {
1156: case 0:
1157: break;
1.1.1.2 ! misho 1158: case CONNECTIONSTATUS_MAGICALVALUE:
! 1159: /* or get_wan_connection_status_str(ext_if_name) */
! 1160: str = strcat_str(str, len, &tmplen,
! 1161: upnpallowedvalues[18 + get_wan_connection_status(ext_if_name)]);
! 1162: break;
! 1163: #ifdef ENABLE_6FC_SERVICE
! 1164: case FIREWALLENABLED_MAGICALVALUE:
! 1165: /* see 2.4.2 of UPnP-gw-WANIPv6FirewallControl-v1-Service.pdf */
! 1166: snprintf(tmp, sizeof(tmp), "%d",
! 1167: ipv6fc_firewall_enabled);
1.1 misho 1168: str = strcat_str(str, len, &tmplen, tmp);
1169: break;
1.1.1.2 ! misho 1170: case INBOUNDPINHOLEALLOWED_MAGICALVALUE:
! 1171: /* see 2.4.3 of UPnP-gw-WANIPv6FirewallControl-v1-Service.pdf */
! 1172: snprintf(tmp, sizeof(tmp), "%d",
! 1173: ipv6fc_inbound_pinhole_allowed);
! 1174: str = strcat_str(str, len, &tmplen, tmp);
! 1175: break;
! 1176: #endif
! 1177: #ifdef IGD_V2
! 1178: case SYSTEMUPDATEID_MAGICALVALUE:
! 1179: /* Please read section 2.3.23 SystemUpdateID
! 1180: * of UPnP-gw-WANIPConnection-v2-Service.pdf */
! 1181: snprintf(tmp, sizeof(tmp), "%d",
! 1182: 1/* system update id */);
! 1183: str = strcat_str(str, len, &tmplen, tmp);
! 1184: break;
! 1185: #endif
! 1186: case PORTMAPPINGNUMBEROFENTRIES_MAGICALVALUE:
! 1187: /* Port mapping number of entries magical value */
! 1188: snprintf(tmp, sizeof(tmp), "%d",
! 1189: upnp_get_portmapping_number_of_entries());
! 1190: str = strcat_str(str, len, &tmplen, tmp);
! 1191: break;
! 1192: case EXTERNALIPADDRESS_MAGICALVALUE:
! 1193: /* External ip address magical value */
1.1 misho 1194: if(use_ext_ip_addr)
1195: str = strcat_str(str, len, &tmplen, use_ext_ip_addr);
1196: else {
1197: char ext_ip_addr[INET_ADDRSTRLEN];
1198: if(getifaddr(ext_if_name, ext_ip_addr, INET_ADDRSTRLEN) < 0) {
1199: str = strcat_str(str, len, &tmplen, "0.0.0.0");
1200: } else {
1201: str = strcat_str(str, len, &tmplen, ext_ip_addr);
1202: }
1203: }
1204: break;
1.1.1.2 ! misho 1205: case DEFAULTCONNECTIONSERVICE_MAGICALVALUE:
! 1206: /* DefaultConnectionService magical value */
1.1 misho 1207: str = strcat_str(str, len, &tmplen, uuidvalue);
1208: str = strcat_str(str, len, &tmplen, ":WANConnectionDevice:1,urn:upnp-org:serviceId:WANIPConn1");
1209: break;
1210: default:
1211: str = strcat_str(str, len, &tmplen, upnpallowedvalues[v->ieventvalue]);
1212: }
1213: str = strcat_str(str, len, &tmplen, "</s:");
1214: str = strcat_str(str, len, &tmplen, v->name);
1215: str = strcat_str(str, len, &tmplen, "></e:property>");
1216: //printf("</s:%s></e:property>\n", v->name);
1217: }
1218: v++;
1219: }
1220: str = strcat_str(str, len, &tmplen, "</e:propertyset>");
1221: //printf("</e:propertyset>\n");
1222: //printf("\n");
1223: //printf("%d\n", tmplen);
1224: str[*len] = '\0';
1225: return str;
1226: }
1227:
1228: char *
1229: getVarsWANIPCn(int * l)
1230: {
1231: return genEventVars(l,
1232: &scpdWANIPCn,
1.1.1.2 ! misho 1233: SERVICE_TYPE_WANIPC);
1.1 misho 1234: }
1235:
1236: char *
1237: getVarsWANCfg(int * l)
1238: {
1239: return genEventVars(l,
1240: &scpdWANCfg,
1241: "urn:schemas-upnp-org:service:WANCommonInterfaceConfig:1");
1242: }
1243:
1244: #ifdef ENABLE_L3F_SERVICE
1245: char *
1246: getVarsL3F(int * l)
1247: {
1248: return genEventVars(l,
1249: &scpdL3F,
1250: "urn:schemas-upnp-org:service:Layer3Forwarding:1");
1251: }
1252: #endif
1.1.1.2 ! misho 1253:
! 1254: #ifdef ENABLE_6FC_SERVICE
! 1255: char *
! 1256: getVars6FC(int * l)
! 1257: {
! 1258: return genEventVars(l,
! 1259: &scpd6FC,
! 1260: "urn:schemas-upnp-org:service:WANIPv6FirewallControl:1");
! 1261: }
! 1262: #endif
! 1263:
! 1264: #ifdef ENABLE_DP_SERVICE
! 1265: char *
! 1266: getVarsDP(int * l)
! 1267: {
! 1268: return genEventVars(l,
! 1269: &scpdDP,
! 1270: "urn:schemas-upnp-org:service:DeviceProtection:1");
! 1271: }
1.1 misho 1272: #endif
1.1.1.2 ! misho 1273:
! 1274: #endif /* ENABLE_EVENTS */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>