static bool parse_args(int argc, char* argv[])
{
    const char x1s[] = "h";      const char* x1l[] = { "help", 0 };
    const char x21s[] = "l";     const char* x21l[] = { "nabtolog", 0 };
    const char x30s[] = "";      const char* x30l[] = { "rangestart", 0 };
    const char x31s[] = "";      const char* x31l[] = { "rangeend", 0 };
    const char x32s[] = "";      const char* x32l[] = { "basename", 0 };
    const char x33s[] = "";      const char* x33l[] = { "random-local-address", 0 };
    
    const char *option;

    const struct { int k; int f; const char *s; const char*const* l; } opts[] = {
        { OPTION_HELP, GOPT_NOARG,           x1s,  x1l  },
        { OPTION_LOG,  GOPT_REPEAT|GOPT_ARG, x21s, x21l },
        { OPTION_RANGE_START, GOPT_ARG, x30s, x30l},
        { OPTION_RANGE_END, GOPT_ARG, x31s, x31l},
        { OPTION_BASENAME, GOPT_ARG, x32s, x32l},
        { OPTION_RANDOM_LOCAL_ADDRESS, GOPT_NOARG, x33s, x33l },
        {0,0,0,0}
    };
    
    void *options = gopt_sort( & argc, (const char**)argv, opts);
    
    if (gopt(options, OPTION_HELP)) {
        help();
        exit(0);
    }
    
    if (gopt_arg( options, OPTION_BASENAME, &base_name)) {
        
    }
    
    if (gopt_arg(options, OPTION_RANGE_START, &option)) {
        range_start = atoi(option);
    }
    
    if (gopt_arg(options, OPTION_RANGE_END, &option)) {
        range_end = atoi(option);
    }
    
    { 
        const char* optionString;
        size_t optionsLength = gopt(options, OPTION_LOG);
        int i;
        if (optionsLength > 0) {
            for (i = 0; i < optionsLength; i++) {
                optionString = gopt_arg_i(options, OPTION_LOG, i);
                if (!unabto_log_system_enable_stdout_pattern(optionString)) {
                    NABTO_LOG_FATAL(("Logstring %s is not a valid logsetting", optionString));
                }
            }
        } else {
            unabto_log_system_enable_stdout_pattern("*.info");
        }
        
    }

    if (gopt(options, OPTION_RANDOM_LOCAL_ADDRESS)) {
        random_local_address = true;
    }
    
    return true;
}
Exemple #2
0
static bool tunnel_parse_args(int argc, char* argv[], nabto_main_setup* nms) {

    const char *tunnel_port_str;

    const char x1s[] = "h";      const char* x1l[] = { "help", 0 };
    const char x2s[] = "V";      const char* x2l[] = { "version", 0 };
    const char x3s[] = "C";      const char* x3l[] = { "config", 0 };
    const char x4s[] = "S";      const char* x4l[] = { "size", 0 };
    const char x9s[] = "d";      const char* x9l[] = { "device_name", 0 };
    const char x10s[] = "H";     const char* x10l[] = { "tunnel_default_host", 0 }; // only used together with the tunnel.
    const char x11s[] = "P";     const char* x11l[] = { "tunnel_default_port", 0 };
    const char x12s[] = "s";     const char* x12l[] = { "use_encryption", 0 };
    const char x13s[] = "k";     const char* x13l[] = { "encryption_key", 0 };
    const char x14s[] = "p";     const char* x14l[] = { "localport", 0 };
    const char x15s[] = "a";     const char* x15l[] = { "check_acl", 0 };
    const char x16s[] = "";      const char* x16l[] = { "allow_port", 0};
    const char x17s[] = "";      const char* x17l[] = { "allow_host", 0};
    const char x18s[] = "x";     const char* x18l[] = { "nice_exit", 0};
    const char x19s[] = "";      const char* x19l[] = { "allow_all_ports", 0};
    const char x21s[] = "l";     const char* x21l[] = { "nabtolog", 0 };
    const char x22s[] = "A";     const char* x22l[] = { "controller", 0 };
    const char x23s[] = "";      const char* x23l[] = { "disable_tcp_fb", 0 };
    const char x24s[] = "";      const char* x24l[] = { "controller_port", 0 };
#if NABTO_ENABLE_EPOLL
    const char x25s[] = "";      const char* x25l[] = { "select_based", 0 };
#endif

    const char x26s[] = "";      const char* x26l[] = { "tunnels", 0 };
    const char x27s[] = "";      const char* x27l[] = { "stream_window_size",0 };
    const char x28s[] = "";      const char* x28l[] = { "connections", 0 };
    const char x29s[] = "";      const char* x29l[] = { "disable_extended_rendezvous_multiple_sockets", 0 };
// uart options
    const char x30s[] = "";      const char* x30l[] = { "uart_device", 0 }; 

    const struct { int k; int f; const char *s; const char*const* l; } opts[] = {
        { 'h', GOPT_NOARG,   x1s, x1l },
        { 'V', GOPT_NOARG,   x2s, x2l },
        { 'C', GOPT_NOARG,   x3s, x3l },
        { 'S', GOPT_NOARG,   x4s, x4l },
        { 'd', GOPT_ARG,     x9s, x9l },
        { 'H', GOPT_ARG,     x10s, x10l },
        { 'P', GOPT_ARG,     x11s, x11l },
        { 's', GOPT_NOARG,   x12s, x12l },
        { 'k', GOPT_ARG,     x13s, x13l },
        { 'p', GOPT_ARG,     x14s, x14l },
        { 'a', GOPT_NOARG,   x15s, x15l },
        { ALLOW_PORT_OPTION, GOPT_REPEAT|GOPT_ARG, x16s, x16l },
        { ALLOW_HOST_OPTION, GOPT_REPEAT|GOPT_ARG, x17s, x17l },
        { 'x', GOPT_NOARG, x18s, x18l },
        { ALLOW_ALL_PORTS_OPTION, GOPT_NOARG, x19s, x19l },
        { 'l', GOPT_REPEAT|GOPT_ARG,  x21s, x21l },
        { 'A', GOPT_ARG, x22s, x22l },
        { DISABLE_TCP_FALLBACK_OPTION, GOPT_NOARG, x23s, x23l },
        { CONTROLLER_PORT_OPTION, GOPT_ARG, x24s, x24l },
#if NABTO_ENABLE_EPOLL
        { SELECT_BASED_OPTION, GOPT_NOARG, x25s, x25l },
#endif
#if NABTO_ENABLE_DYNAMIC_MEMORY
        { TUNNELS_OPTION, GOPT_ARG, x26s, x26l },
        { STREAM_WINDOW_SIZE_OPTION, GOPT_ARG, x27s, x27l },
        { CONNECTIONS_SIZE_OPTION, GOPT_ARG, x28s, x28l },
#endif
#if NABTO_ENABLE_EXTENDED_RENDEZVOUS_MULTIPLE_SOCKETS
        { DISABLE_EXTENDED_RENDEZVOUS_MULTIPLE_SOCKETS, GOPT_NOARG, x29s, x29l },
#endif
        { UART_DEVICE_OPTION, GOPT_ARG, x30s, x30l },
        { 0,0,0,0 }
    };

    void *options = gopt_sort( & argc, (const char**)argv, opts);

    const char * h;
    int p;
    const char* localPortStr;
    const char* optionString;
    const char* basestationAddress;
    const char* controllerPort;
    const char* tunnelsOption;
    const char* streamWindowSizeOption;
    const char* connectionsOption;
    const char* uartDevice = 0;
    uint32_t addr;


    if (gopt(options, 'h')) {
        printf("Usage: unabto_tunnel [options] -d devicename\n");
        printf("  -h, --help                  Print this help.\n");
        printf("  -V, --version               Print version.\n");
        printf("  -C, --config                Print configuration (unabto_config.h).\n");
        printf("  -S, --size                  Print size (in bytes) of memory usage.\n");
        printf("  -l, --nabtolog              Speficy log level such as *.trace.\n");
        printf("  -d, --device_name           Specify name of this device.\n");
        printf("  -H, --tunnel_default_host   Set default host name for tunnel (%s).\n", UNABTO_TUNNEL_TCP_DEFAULT_HOST);
        printf("  -P, --tunnel_default_port   Set default port for tunnel (%u).\n", UNABTO_TUNNEL_TCP_DEFAULT_PORT);
        printf("  -s, --use_encryption        Encrypt communication.\n");
        printf("  -k, --encryption_key        Specify encryption key.\n");
        printf("  -p, --localport             Specify port for local connections.\n");
        printf("  -A, --controller            Specify controller address\n");
        printf("      --controller_port       sets the controller port number.\n");
        printf("  -a, --check_acl             Perform ACL check when establishing connection.\n");
        printf("      --allow_all_ports       Allow connections to all port numbers.\n");
        printf("      --allow_port            Ports that are allowed. Requires -a.\n");
        printf("      --allow_host            Hostnames that are allowed. Requires -a.\n");
        printf("      --uart_device           Sets the uart device\n");
        printf("  -x, --nice_exit             Close the tunnels nicely when pressing Ctrl+C.\n");
#if NABTO_ENABLE_TCP_FALLBACK
        printf("      --disable_tcp_fb        Disable tcp fallback.\n");
#endif
#if NABTO_ENABLE_EPOLL
        printf("      --select_based          Use select instead of epoll.\n");
#endif
#if NABTO_ENABLE_DYNAMIC_MEMORY
        printf("      --tunnels               Specify how many concurrent tcp streams should be possible.\n");
        printf("      --stream_window_size    Specify the stream window size, the larger the value the more memory the aplication will use, but higher throughput will be possible.\n");
        printf("      --connections           Specify the maximum number of allowed concurrent connections.\n");
#endif
#if NABTO_ENABLE_EXTENDED_RENDEZVOUS_MULTIPLE_SOCKETS
        printf("      --disable_extended_rendezvous_multiple_sockets     Disable multiple sockets in extended rendezvous.\n");
#endif
        exit(0);
    }

    if (gopt(options, 'V')) {
        printf("%d.%d\n", RELEASE_MAJOR, RELEASE_MINOR);
        exit(0);
    }

    if (gopt(options, 'C')) {
        unabto_printf_unabto_config(stdout, "unabto_tunnel");
        exit(0);
    }

    if (gopt(options, 'S')) {
        unabto_printf_memory_sizes(stdout, "unabto_tunnel");
        exit(0);
    }
    
    { 
        size_t optionsLength = gopt(options, 'l');
        int i;
        if (optionsLength > 0) {
            for (i = 0; i < optionsLength; i++) {
                optionString = gopt_arg_i(options, 'l', i);
                if (!unabto_log_system_enable_stdout_pattern(optionString)) {
                    NABTO_LOG_FATAL(("Logstring %s is not a valid logsetting", optionString));
                }
            }
        } else {
            unabto_log_system_enable_stdout_pattern("*.info");
        }
        
    } 
    

    if (!gopt_arg( options, 'd', &nms->id)) {
        NABTO_LOG_FATAL(("Specify a serverId with -d. Try -h for help."));
    }

    if(gopt_arg(options, 'H', &h)) {
        unabto_tunnel_tcp_set_default_host(h);
    }

    if (gopt_arg(options, 'P', &tunnel_port_str)) {
        if(1 != sscanf(tunnel_port_str, "%d", &p)) {
            NABTO_LOG_TRACE(("Reading of port parameter failed."));
        } else {
            unabto_tunnel_tcp_set_default_port(p);
        }
    }
     
    if( gopt_arg( options, 'p', &localPortStr) ){
        int localPort = atoi(localPortStr);
        nms->localPort = localPort;
    }


    if (gopt(options, 's')) {
        const char* preSharedKey;
        uint8_t key[16];
        memset(key, 0, 16);
        if ( gopt_arg( options, 'k', &preSharedKey)) {
            size_t i;
            size_t pskLen = strlen(preSharedKey);
            // read the pre shared key as a hexadecimal string.
            for (i = 0; i < pskLen/2 && i < 16; i++) {
                sscanf(preSharedKey+(2*i), "%02hhx", &key[i]);
            }
        }
        memcpy(nms->presharedKey,key,16);
        nms->cryptoSuite = CRYPT_W_AES_CBC_HMAC_SHA256;
        nms->secureAttach = true;
        nms->secureData = true;
    }

    if (gopt(options, 'a')) {
        check_acl = true;
    }

    if( gopt_arg( options, 'A', & basestationAddress ) ){
        addr = inet_addr(basestationAddress);
        if (addr == INADDR_NONE) {
            NABTO_LOG_FATAL(("Invalid basestation address"));
        }
        nms->controllerArg.addr = htonl(addr);
    }

    if (gopt(options, 'x')) {
        nice_exit = true;
    }
    
    ports_length = gopt(options, ALLOW_PORT_OPTION);
    if (ports_length > 0) {
        size_t i;
        ports = (uint16_t*) malloc(ports_length*sizeof(uint16_t));
        memset(ports,0,ports_length*sizeof(uint16_t));
        for (i = 0; i < ports_length; i++) {
            const char* opt = gopt_arg_i(options, ALLOW_PORT_OPTION, i);
            ports[i] = atoi(opt);
        }
    }
    
    hosts_length = gopt(options, ALLOW_HOST_OPTION);
    if (hosts_length > 0) {
        size_t i;
        hosts = (char**) malloc(hosts_length*sizeof(char*));
        for (i = 0; i < hosts_length; i++) {
            const char* opt = gopt_arg_i(options, ALLOW_HOST_OPTION, i);
            hosts[i] = strdup(opt);
        }
    }

    if (gopt(options, ALLOW_ALL_PORTS_OPTION)) {
        allow_all_ports = true;
    }

    if(gopt_arg(options, UART_DEVICE_OPTION, &uartDevice)) {
        uart_tunnel_set_default_device(uartDevice);
    } else {
        NABTO_LOG_TRACE(("Missing uart device option."));
        uartDevice = 0;
    }
    
#if NABTO_ENABLE_TCP_FALLBACK
    if (gopt(options, DISABLE_TCP_FALLBACK_OPTION)) {
        nms->enableTcpFallback = false;
    }
#endif

    if (gopt_arg(options, CONTROLLER_PORT_OPTION, &controllerPort)) {
        nms->controllerArg.port = atoi(controllerPort);
    }

#if NABTO_ENABLE_EPOLL
    if (gopt(options, SELECT_BASED_OPTION)) {
        useSelectBased = true;
    }
#endif

#if NABTO_ENABLE_DYNAMIC_MEMORY
    if (gopt_arg(options, TUNNELS_OPTION, &tunnelsOption)) {
        nms->streamMaxStreams = atoi(tunnelsOption);
    }

    if (gopt_arg(options, STREAM_WINDOW_SIZE_OPTION, &streamWindowSizeOption)) {
        uint16_t windowSize = atoi(streamWindowSizeOption);
        nms->streamReceiveWindowSize = windowSize;
        nms->streamSendWindowSize = windowSize;
    }

    if (gopt_arg(options, CONNECTIONS_SIZE_OPTION, &connectionsOption)) {
        nms->connectionsSize = atoi(connectionsOption);
    }
#endif

#if NABTO_ENABLE_EXTENDED_RENDEZVOUS_MULTIPLE_SOCKETS
    if (gopt(options, DISABLE_EXTENDED_RENDEZVOUS_MULTIPLE_SOCKETS)) {
        nms->enableExtendedRendezvousMultipleSockets = false;
    }
#endif

    return true;
}
static bool tunnel_parse_args(int argc, char* argv[], nabto_main_setup* nms) {

    const char *tunnel_port_str;

    const char x1s[] = "h";      const char* x1l[] = { "help", 0 };
    const char x2s[] = "V";      const char* x2l[] = { "version", 0 };
    const char x3s[] = "C";      const char* x3l[] = { "config", 0 };
    const char x4s[] = "S";      const char* x4l[] = { "size", 0 };
    const char x9s[] = "d";      const char* x9l[] = { "deviceName", 0 };
    const char x10s[] = "H";     const char* x10l[] = { "tunnel_default_host", 0 }; // only used together with the tunnel.
    const char x11s[] = "P";     const char* x11l[] = { "tunnel_default_port", 0 };
    const char x12s[] = "s";     const char* x12l[] = { "use_encryption", 0 };
    const char x13s[] = "k";     const char* x13l[] = { "encryption_key", 0 };
    const char x14s[] = "p";     const char* x14l[] = { "localport", 0 };
    const char x15s[] = "a";     const char* x15l[] = { "check_acl", 0 };
    const char x16s[] = "";      const char* x16l[] = { "allow_port", 0};
    const char x17s[] = "";      const char* x17l[] = { "allow_host", 0};
    const char x18s[] = "x";     const char* x18l[] = { "nice_exit", 0};
    const char x19s[] = "";      const char* x19l[] = { "allow_all_ports", 0};
    const char x20s[] = "";      const char* x20l[] = { "test_webserver", 0};
    const char x21s[] = "l";     const char* x21l[] = { "nabtolog", 0 };
    const char x22s[] = "A";     const char* x22l[] = { "controller", 0 };
    const char x23s[] = "";      const char* x23l[] = { "disable-tcp-fb", 0 };
    const char x24s[] = "";      const char* x24l[] = { "controller-port", 0 };

    const struct { int k; int f; const char *s; const char*const* l; } opts[] = {
        { 'h', GOPT_NOARG,   x1s, x1l },
        { 'V', GOPT_NOARG,   x2s, x2l },
        { 'C', GOPT_NOARG,   x3s, x3l },
        { 'S', GOPT_NOARG,   x4s, x4l },
        { 'd', GOPT_ARG,     x9s, x9l },
        { 'H', GOPT_ARG,     x10s, x10l },
        { 'P', GOPT_ARG,     x11s, x11l },
        { 's', GOPT_NOARG,   x12s, x12l },
        { 'k', GOPT_ARG,     x13s, x13l },
        { 'p', GOPT_ARG,     x14s, x14l },
        { 'a', GOPT_NOARG,   x15s, x15l },
        { ALLOW_PORT_OPTION, GOPT_REPEAT|GOPT_ARG, x16s, x16l },
        { ALLOW_HOST_OPTION, GOPT_REPEAT|GOPT_ARG, x17s, x17l },
        { 'x', GOPT_NOARG, x18s, x18l },
        { ALLOW_ALL_PORTS_OPTION, GOPT_NOARG, x19s, x19l },
        { TEST_WEBSERVER_OPTION, GOPT_ARG, x20s, x20l },
        { 'l', GOPT_REPEAT|GOPT_ARG,  x21s, x21l },
        { 'A', GOPT_ARG, x22s, x22l },
        { DISABLE_TCP_FALLBACK_OPTION, GOPT_NOARG, x23s, x23l },
        { CONTROLLER_PORT_OPTION, GOPT_ARG, x24s, x24l },
        { 0,0,0,0 }
    };

    void *options = gopt_sort( & argc, (const char**)argv, opts);

    const char * h;
    int p;
    const char* localPortStr;
    const char* optionString;
    const char* basestationAddress;
    const char* controllerPort;
    uint32_t addr;


    if (gopt(options, 'h')) {
        printf("Usage: unabto_tunnel [options] -d devicename\n");
        printf("  -h, --help                  Print this help.\n");
        printf("  -V, --version               Print version.\n");
        printf("  -C, --config                Print configuration (unabto_config.h).\n");
        printf("  -S, --size                  Print size (in bytes) of memory usage.\n");
        printf("  -l, --nabtolog              Speficy log level such as *.trace");
        printf("  -d, --deviceName            Specify name of this device.\n");
        printf("  -H, --tunnel_default_host   Set default host name for tunnel (%s).\n", DEFAULT_HOST);
        printf("  -P, --tunnel_default_port   Set default port for tunnel (%u).\n", DEFAULT_PORT);
        printf("  -s, --use_encryption        Encrypt communication (use CRYPTO).\n");
        printf("  -k, --encryption_key        Specify encryption key.\n");
        printf("  -p, --localport             Specify port for local connections.\n");
        printf("  -A, --controller            Specify controller address\n");
        printf("      --controller-port       sets the controller port number");
        printf("  -a, --check_acl             Perform ACL check when establishing connection.\n");
        printf("      --allow_all_ports       Allow connections to all port numbers.\n");
        printf("      --allow_port            Ports that are allowed. Requires -a.\n");
        printf("      --allow_host            Hostnames that are allowed. Requires -a.\n");
        printf("  -x, --nice_exit             Close the tunnels nicely when pressing Ctrl+C.\n");
#if USE_TEST_WEBSERVER
        printf("      --test_webserver        Specify port of test webserver and enable it\n");
#endif
        printf("      --disable-tcp-fb        disable tcp fallback");
        exit(0);
    }

    if (gopt(options, 'V')) {
        printf("%d.%d\n", RELEASE_MAJOR, RELEASE_MINOR);
        exit(0);
    }

    if (gopt(options, 'C')) {
        unabto_printf_unabto_config(stdout, "unabto_tunnel");
        exit(0);
    }

    if (gopt(options, 'S')) {
        unabto_printf_memory_sizes(stdout, "unabto_tunnel");
        exit(0);
    }
    
    { 
        size_t optionsLength = gopt(options, 'l');
        int i;
        if (optionsLength > 0) {
            for (i = 0; i < optionsLength; i++) {
                optionString = gopt_arg_i(options, 'l', i);
                if (!unabto_log_system_enable_stdout_pattern(optionString)) {
                    NABTO_LOG_FATAL(("Logstring %s is not a valid logsetting", optionString));
                }
            }
        } else {
            unabto_log_system_enable_stdout_pattern("*.info");
        }
        
    } 
    

    if (!gopt_arg( options, 'd', &nms->id)) {
        NABTO_LOG_FATAL(("Specify a serverId with -d. Try -h for help."));
    }

    if(gopt_arg(options, 'H', &h)) {
        tunnel_set_default_host(h);
    }

    if (gopt_arg(options, 'P', &tunnel_port_str)) {
        if(1 != sscanf(tunnel_port_str, "%d", &p)) {
            NABTO_LOG_FATAL(("Reading of port parameter failed."));
        } else {
            tunnel_set_default_port(p);
        }
    }
     
    if( gopt_arg( options, 'p', &localPortStr) ){
        int localPort = atoi(localPortStr);
        nms->localPort = localPort;
    }


    if (gopt(options, 's')) {
        const char* preSharedKey;
        uint8_t key[16];
        memset(key, 0, 16);
        if ( gopt_arg( options, 'k', &preSharedKey)) {
            size_t i;
            size_t pskLen = strlen(preSharedKey);
            // read the pre shared key as a hexadecimal string.
            for (i = 0; i < pskLen/2 && i < 16; i++) {
                sscanf(preSharedKey+(2*i), "%02hhx", &key[i]);
            }
        }
        memcpy(nms->presharedKey,key,16);
        nms->cryptoSuite = CRYPT_W_AES_CBC_HMAC_SHA256;
        nms->secureAttach = true;
        nms->secureData = true;
    }

    if (gopt(options, 'a')) {
        check_acl = true;
    }

    if( gopt_arg( options, 'A', & basestationAddress ) ){
        addr = inet_addr(basestationAddress);
        if (addr == INADDR_NONE) {
            NABTO_LOG_FATAL(("Invalid basestation address"));
        }
        nms->controllerArg.addr = htonl(addr);
    }

    if (gopt(options, 'x')) {
        nice_exit = true;
    }

    ports_length = gopt(options, ALLOW_PORT_OPTION);
    if (ports_length > 0) {
        size_t i;
        ports = (uint16_t*) malloc(ports_length*sizeof(uint16_t));
        memset(ports,0,ports_length*sizeof(uint16_t));
        for (i = 0; i < ports_length; i++) {
            const char* opt = gopt_arg_i(options, ALLOW_PORT_OPTION, i);
            ports[i] = atoi(opt);
        }
    }
    
    hosts_length = gopt(options, ALLOW_HOST_OPTION);
    if (hosts_length > 0) {
        size_t i;
        hosts = (char**) malloc(hosts_length*sizeof(char*));
        for (i = 0; i < hosts_length; i++) {
            const char* opt = gopt_arg_i(options, ALLOW_HOST_OPTION, i);
            hosts[i] = strdup(opt);
        }
    }

    if (gopt(options, ALLOW_ALL_PORTS_OPTION)) {
        allow_all_ports = true;
    }

#if USE_TEST_WEBSERVER
    if (gopt_arg(options, TEST_WEBSERVER_OPTION, &testWebserverPortStr)) {
        testWebserver = true;
    }
#endif

#if NABTO_ENABLE_TCP_FALLBACK
    if (gopt(options, DISABLE_TCP_FALLBACK_OPTION)) {
        nms->enableTcpFallback = false;
    }
#endif

    if (gopt_arg(options, CONTROLLER_PORT_OPTION, &controllerPort)) {
        nms->controllerArg.port = atoi(controllerPort);
    }

    return true;
}