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>