Exemplo n.º 1
0
bool
IpAddr::isValid(const std::string &address, pj_uint16_t family)
{
    pj_str_t pjstring;
    pj_cstr(&pjstring, address.c_str());
    pj_str_t ret_str;
    pj_uint16_t ret_port;
    int ret_family;
    auto status = pj_sockaddr_parse2(pj_AF_UNSPEC(), 0, &pjstring, &ret_str, &ret_port, &ret_family);
    if (status != PJ_SUCCESS || (family != pj_AF_UNSPEC() && ret_family != family))
        return false;

    char buf[PJ_INET6_ADDRSTRLEN];
    pj_str_t addr_with_null = {buf, 0};
    pj_strncpy_with_null(&addr_with_null, &ret_str, sizeof(buf));
    struct sockaddr sa;
    return inet_pton(ret_family==pj_AF_INET6()?AF_INET6:AF_INET, buf, &(sa.sa_data)) == 1;
}
Exemplo n.º 2
0
/*
 * Parse address
 */
PJ_DEF(pj_status_t) pj_sockaddr_parse( int af, unsigned options,
				       const pj_str_t *str,
				       pj_sockaddr *addr)
{
    pj_str_t hostpart;
    pj_uint16_t port;
    pj_status_t status;

    PJ_ASSERT_RETURN(addr, PJ_EINVAL);
    PJ_ASSERT_RETURN(af==PJ_AF_UNSPEC ||
		     af==PJ_AF_INET ||
		     af==PJ_AF_INET6, PJ_EINVAL);
    PJ_ASSERT_RETURN(options == 0, PJ_EINVAL);

    status = pj_sockaddr_parse2(af, options, str, &hostpart, &port, &af);
    if (status != PJ_SUCCESS)
	return status;
    
#if !defined(PJ_HAS_IPV6) || !PJ_HAS_IPV6
    if (af==PJ_AF_INET6)
	return PJ_EIPV6NOTSUP;
#endif

    status = pj_sockaddr_init(af, addr, &hostpart, port);
#if defined(PJ_HAS_IPV6) && PJ_HAS_IPV6
    if (status != PJ_SUCCESS && af == PJ_AF_INET6) {
	/* Parsing does not yield valid address. Try to treat the last 
	 * portion after the colon as port number.
	 */
	const char *last_colon_pos=NULL, *p;
	const char *end = str->ptr + str->slen;
	unsigned long long_port;
	pj_str_t port_part;
	int i;

	/* Parse as IPv6:port */
	for (p=str->ptr; p!=end; ++p) {
	    if (*p == ':')
		last_colon_pos = p;
	}

	if (last_colon_pos == NULL)
	    return status;

	hostpart.ptr = (char*)str->ptr;
	hostpart.slen = last_colon_pos - str->ptr;

	port_part.ptr = (char*)last_colon_pos + 1;
	port_part.slen = end - port_part.ptr;

	/* Make sure port number is valid */
	for (i=0; i<port_part.slen; ++i) {
	    if (!pj_isdigit(port_part.ptr[i]))
		return status;
	}
	long_port = pj_strtoul(&port_part);
	if (long_port > 65535)
	    return status;

	port = (pj_uint16_t)long_port;

	status = pj_sockaddr_init(PJ_AF_INET6, addr, &hostpart, port);
    }
#endif
    
    return status;
}