Annotation of embedaddon/miniupnpd/upnpdescgen.c, revision 1.1.1.3

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>