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; }
/** * 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); }
/** * 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; }