static int netPfStrPortParse(char *pszRaw, int cbRaw, uint16_t *pu16Port)
{
    char *pszEndOfPort = NULL;
    uint16_t u16Port = 0;
    int idxRaw = 1; /* we increment pszRaw after checks. */
    int cbRest = 0;
    size_t cbPort = 0;

    AssertPtrReturn(pszRaw, -1);
    AssertPtrReturn(pu16Port, -1);
    AssertReturn(pszRaw[0] == PF_FIELD_SEPARATOR, -1);

    pszRaw++; /* skip line separator */
    cbRaw --;

    pszEndOfPort = RTStrStr(pszRaw, ":");
    if (!pszEndOfPort)
    {
        cbRest = strlen(pszRaw);

        Assert(cbRaw == cbRest);

        /* XXX: Assumption that if string is too big, it will be reported by
         * RTStrToUint16.
         */
        if (cbRest > 0)
        {
            pszEndOfPort = pszRaw + cbRest;
            cbPort = cbRest;
        }
        else
            return -1;
    }
    else
        cbPort = pszEndOfPort - pszRaw;


    idxRaw += cbPort;

    Assert(cbRest || pszRaw[idxRaw - 1] == PF_FIELD_SEPARATOR); /* we are 1 char ahead */

    char szPort[10];
    RT_ZERO(szPort);

    Assert(idxRaw > 0);
    RTStrCopy(szPort, RT_MIN(sizeof(szPort), (size_t)(cbPort) + 1), pszRaw);

    if (!(u16Port = RTStrToUInt16(szPort)))
        return -1;

    *pu16Port = u16Port;

     return idxRaw;
}
Beispiel #2
0
/**
 * portexpr ::= 'port' [0-9]+
 */
static enum RCP_TOKEN rcp_parse_port(struct rcp_parser *parser)
{
    struct rcp_state *st;
    enum RCP_TOKEN tok = rcp_get_token(parser); /* eats 'port' */

    Assert(parser->rcpp_state);
    st = parser->rcpp_state;

    if (   tok != tok_number
        || tok == tok_eof)
        return tok_error;

    st->rcps_port = RTStrToUInt16(parser->rcpp_str_buffer);

    if (st->rcps_port == 0)
        return tok_error;

    return rcp_get_token(parser);
}
Beispiel #3
0
/**
 * nameserverexpr ::= 'nameserver' ip+
 * @note: resolver(5) ip ::= (ipv4|ipv6)(.number)?
 */
static enum RCP_TOKEN rcp_parse_nameserver(struct rcp_parser *parser)
{
    enum RCP_TOKEN tok = rcp_get_token(parser); /* eats 'nameserver' */

    if (  (   tok != tok_ipv4
           && tok != tok_ipv4_port
           && tok != tok_ipv6
           && tok != tok_ipv6_port)
        || tok == EOF)
        return tok_error;

    while (   tok == tok_ipv4
           || tok == tok_ipv4_port
           || tok == tok_ipv6
           || tok == tok_ipv6_port)
    {
        struct rcp_state *st;
        RTNETADDR *address;
        char *str_address;

        Assert(parser->rcpp_state);

        st = parser->rcpp_state;

        /* It's still valid resolv.conf file, just rest of the nameservers should be ignored */
        if (st->rcps_num_nameserver >= RCPS_MAX_NAMESERVERS)
            return rcp_get_token(parser);

        address = &st->rcps_nameserver[st->rcps_num_nameserver];
        str_address = &st->rcps_nameserver_str_buffer[st->rcps_num_nameserver * RCPS_IPVX_SIZE];
#ifdef RT_OS_DARWIN
        if (   tok == tok_ipv4_port
            || (   tok == tok_ipv6_port
                && (st->rcps_flags & RCPSF_IGNORE_IPV6) == 0))
        {
            char *ptr = &parser->rcpp_str_buffer[strlen(parser->rcpp_str_buffer)];
            while (*(--ptr) != '.');
            *ptr = '\0';
            address->uPort = RTStrToUInt16(ptr + 1);

            if (address->uPort == 0) return tok_error;
        }
#endif
        /**
         * if we on Darwin upper code will cut off port if it's.
         */
        if ((st->rcps_flags & RCPSF_NO_STR2IPCONV) != 0)
        {
            if (strlen(parser->rcpp_str_buffer) > RCPS_IPVX_SIZE)
                return tok_error;

            strcpy(str_address, parser->rcpp_str_buffer);

            st->rcps_str_nameserver[st->rcps_num_nameserver] = str_address;

            goto loop_prolog;
        }

        switch (tok)
        {
            case tok_ipv4:
            case tok_ipv4_port:
                {
                    int rc = RTNetStrToIPv4Addr(parser->rcpp_str_buffer, &address->uAddr.IPv4);
                    if (RT_FAILURE(rc)) return tok_error;

                    address->enmType = RTNETADDRTYPE_IPV4;
                }

                break;
            case tok_ipv6:
            case tok_ipv6_port:
                {
                    int rc;

                    if ((st->rcps_flags & RCPSF_IGNORE_IPV6) != 0)
                        return rcp_get_token(parser);

                    rc = inet_pton(AF_INET6, parser->rcpp_str_buffer,
                                       &address->uAddr.IPv6);
                    if (rc == -1)
                        return tok_error;

                    address->enmType = RTNETADDRTYPE_IPV6;
                }

                break;
            default: /* loop condition doesn't let enter enything */
                AssertMsgFailed(("shouldn't ever happen tok:%d, %s", tok,
                                 isprint(tok) ? parser->rcpp_str_buffer : "#"));
                break;
        }

    loop_prolog:
        st->rcps_num_nameserver++;
        tok = rcp_get_token(parser);
    }
    return tok;
}