Пример #1
0
int
main(int argc, char *argv[])
{
    struct ovs_cmdl_context ctx = { .argc = 0, };
    set_program_name(argv[0]);
    vlog_set_levels(NULL, VLF_ANY_DESTINATION, VLL_EMER);
    parse_options(argc, argv);
    ctx.argc = argc - optind;
    ctx.argv = argv + optind;
    ovs_cmdl_run_command(&ctx, get_all_commands());
    return 0;
}

static void
parse_target(const char *s_, struct in_addr *addr,
             unsigned short int *min, unsigned short int *max)
{
    char *s = xstrdup(s_);
    char *colon;
    int error;

    colon = strchr(s, ':');
    if (colon) {
        *colon = '\0';
    }

    if (*s != '\0') {
        error = lookup_hostname(s, addr);
        if (error) {
            ovs_fatal(error, "failed to look up IP address for \"%s\"", s_);
        }
    } else {
        addr->s_addr = htonl(INADDR_ANY);
    }

    *min = *max = 0;
    if (colon && colon[1] != '\0') {
        const char *ports = colon + 1;
        if (ovs_scan(ports, "%hu-%hu", min, max)) {
            if (*min > *max) {
                ovs_fatal(0, "%s: minimum is greater than maximum", s_);
            }
        } else if (ovs_scan(ports, "%hu", min)) {
            *max = *min;
        } else {
            ovs_fatal(0, "%s: number or range expected", s_);
        }
    }

    free(s);
}
Пример #2
0
/* Parses 'str' as an Ethernet address into 'mac'.
 *
 * Returns NULL if successful, otherwise a malloc()'d string describing the
 * error.  The caller is responsible for freeing the returned string. */
char * OVS_WARN_UNUSED_RESULT
str_to_mac(const char *str, struct eth_addr *mac)
{
    if (!ovs_scan(str, ETH_ADDR_SCAN_FMT, ETH_ADDR_SCAN_ARGS(*mac))) {
        return xasprintf("invalid mac address %s", str);
    }
    return NULL;
}
Пример #3
0
/* Returns true if specified address specifies a dynamic address,
 * supporting the following formats:
 *
 *    "dynamic":
 *        Both MAC and IP are to be allocated dynamically.
 *
 *    "xx:xx:xx:xx:xx:xx dynamic":
 *        Use specified MAC address, but allocate an IP address
 *        dynamically.
 */
bool
is_dynamic_lsp_address(const char *address)
{
    struct eth_addr ea;
    int n;
    return (!strcmp(address, "dynamic")
            || (ovs_scan(address, ETH_ADDR_SCAN_FMT" dynamic%n",
                         ETH_ADDR_SCAN_ARGS(ea), &n) && address[n] == '\0'));
}
Пример #4
0
Файл: lex.c Проект: l8huang/ovs
static const char *
lex_parse_integer__(const char *p, struct lex_token *token)
{
    lex_token_init(token);
    token->type = LEX_T_INTEGER;
    memset(&token->value, 0, sizeof token->value);
    const char *start = p;
    const char *end = start;
    while (isalnum((unsigned char) *end) || *end == ':'
           || (*end == '.' && end[1] != '.')) {
        end++;
    }
    size_t len = end - start;

    int n;
    struct eth_addr mac;

    if (!len) {
        lex_error(token, "Integer constant expected.");
    } else if (len == 17
               && ovs_scan(start, ETH_ADDR_SCAN_FMT"%n",
                           ETH_ADDR_SCAN_ARGS(mac), &n)
               && n == len) {
        token->value.mac = mac;
        token->format = LEX_F_ETHERNET;
    } else if (start + strspn(start, "0123456789") == end) {
        if (p[0] == '0' && len > 1) {
            lex_error(token, "Decimal constants must not have leading zeros.");
        } else {
            unsigned long long int integer;
            char *tail;

            errno = 0;
            integer = strtoull(p, &tail, 10);
            if (tail != end || errno == ERANGE) {
                lex_error(token, "Decimal constants must be less than 2**64.");
            } else {
                token->value.integer = htonll(integer);
                token->format = LEX_F_DECIMAL;
            }
        }
    } else if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
        if (len > 2) {
            lex_parse_hex_integer(start + 2, len - 2, token);
        } else {
            lex_error(token, "Hex digits expected following 0%c.", p[1]);
        }
    } else if (len < INET6_ADDRSTRLEN) {
        char copy[INET6_ADDRSTRLEN];
        memcpy(copy, p, len);
        copy[len] = '\0';

        if (ip_parse(copy, &token->value.ipv4)) {
            token->format = LEX_F_IPV4;
        } else if (ipv6_parse(copy, &token->value.ipv6)) {
            token->format = LEX_F_IPV6;
        } else {
            lex_error(token, "Invalid numeric constant.");
        }
    } else {
        lex_error(token, "Invalid numeric constant.");
    }

    ovs_assert(token->type == LEX_T_INTEGER || token->type == LEX_T_ERROR);
    return end;
}
Пример #5
0
Файл: lex.c Проект: ALutzG/ovs
static const char *
lex_parse_integer__(const char *p, struct lex_token *token)
{
    lex_token_init(token);
    token->type = LEX_T_INTEGER;
    memset(&token->value, 0, sizeof token->value);

    /* Find the extent of an "integer" token, which can be in decimal or
     * hexadecimal, or an Ethernet address or IPv4 or IPv6 address, as 'start'
     * through 'end'.
     *
     * Special cases we handle here are:
     *
     *     - The ellipsis token "..", used as e.g. 123..456.  A doubled dot
     *       is never valid syntax as part of an "integer", so we stop if
     *       we encounter two dots in a row.
     *
     *     - Syntax like 1.2.3.4:1234 to indicate an IPv4 address followed by a
     *       port number should be considered three tokens: 1.2.3.4 : 1234.
     *       The obvious approach is to allow just dots or just colons within a
     *       given integer, but that would disallow IPv4-mapped IPv6 addresses,
     *       e.g. ::ffff:192.0.2.128.  However, even in those addresses, a
     *       colon never follows a dot, so we stop if we encounter a colon
     *       after a dot.
     *
     *       (There is no corresponding way to parse an IPv6 address followed
     *       by a port number: ::1:2:3:4:1234 is unavoidably ambiguous.)
     */
    const char *start = p;
    const char *end = start;
    bool saw_dot = false;
    while (isalnum((unsigned char) *end)
           || (*end == ':' && !saw_dot)
           || (*end == '.' && end[1] != '.')) {
        if (*end == '.') {
            saw_dot = true;
        }
        end++;
    }
    size_t len = end - start;

    int n;
    struct eth_addr mac;

    if (!len) {
        lex_error(token, "Integer constant expected.");
    } else if (len == 17
               && ovs_scan(start, ETH_ADDR_SCAN_FMT"%n",
                           ETH_ADDR_SCAN_ARGS(mac), &n)
               && n == len) {
        token->value.mac = mac;
        token->format = LEX_F_ETHERNET;
    } else if (start + strspn(start, "0123456789") == end) {
        if (p[0] == '0' && len > 1) {
            lex_error(token, "Decimal constants must not have leading zeros.");
        } else {
            unsigned long long int integer;
            char *tail;

            errno = 0;
            integer = strtoull(p, &tail, 10);
            if (tail != end || errno == ERANGE) {
                lex_error(token, "Decimal constants must be less than 2**64.");
            } else {
                token->value.integer = htonll(integer);
                token->format = LEX_F_DECIMAL;
            }
        }
    } else if (p[0] == '0' && (p[1] == 'x' || p[1] == 'X')) {
        if (len > 2) {
            lex_parse_hex_integer(start + 2, len - 2, token);
        } else {
            lex_error(token, "Hex digits expected following 0%c.", p[1]);
        }
    } else if (len < INET6_ADDRSTRLEN) {
        char copy[INET6_ADDRSTRLEN];
        memcpy(copy, p, len);
        copy[len] = '\0';

        if (ip_parse(copy, &token->value.ipv4)) {
            token->format = LEX_F_IPV4;
        } else if (ipv6_parse(copy, &token->value.ipv6)) {
            token->format = LEX_F_IPV6;
        } else {
            lex_error(token, "Invalid numeric constant.");
        }
    } else {
        lex_error(token, "Invalid numeric constant.");
    }

    ovs_assert(token->type == LEX_T_INTEGER || token->type == LEX_T_ERROR);
    return end;
}