/**
 * @brief Checks if a buffer points to a valid short range-expressed network.
 * "192.168.11.1-50" is valid, "192.168.1.1-50e" and "192.168.1.1-300" are not.
 *
 * @param   str String to check in.
 *
 * @return 1 if str points to a valid short range-network, 0 otherwise.
 */
static int
is_short_range_network (const char *str)
{
  long end;
  char *ip_str, *end_str, *p;

  ip_str = g_strdup (str);
  end_str = strchr (ip_str, '-');
  if (end_str == NULL)
    {
      g_free (ip_str);
      return 0;
    }

  /* Separate the addreses. */
  *end_str = '\0';
  end_str++;

  if (!is_ipv4_address (ip_str) || !isdigit (*end_str))
    {
      g_free (ip_str);
      return 0;
    }

  p = NULL;
  end = strtol (end_str, &p, 10);
  g_free (ip_str);

  if (*p || end < 0 || end > 255)
    return 0;

  return 1;
}
/**
 * @brief Checks if a buffer points to an IPv4 CIDR-exprpessed block.
 * "192.168.12.3/24" is valid, "192.168.1.3/31" is not.
 *
 * @param[in]   str Buffer to check in.
 *
 * @return 1 if valid CIDR-expressed block, 0 otherwise.
 */
static int
is_cidr_block (const char *str)
{
  long block;
  char *addr_str, *block_str, *p;

  addr_str = g_strdup (str);
  block_str = strchr (addr_str, '/');
  if (block_str == NULL)
    {
      g_free (addr_str);
      return 0;
    }

  /* Separate the address from the block value. */
  *block_str = '\0';
  block_str++;

  if (!is_ipv4_address (addr_str) || !isdigit (*block_str))
    {
      g_free (addr_str);
      return 0;
    }

  p = NULL;
  block = strtol (block_str, &p, 10);
  g_free (addr_str);

  if (*p || block <= 0 || block > 30)
    return 0;

  return 1;
}
Exemple #3
0
static char *get_domain_mask(char *host)
{
	char *ptr;

	if (strchr(host, '.') == NULL) {
                /* no dots - toplevel domain or IPv6 address */
		ptr = strrchr(host, ':');
		if (ptr != NULL) {
			/* IPv6 address, ban the last 64k addresses */
			if (ptr[1] != '\0') strcpy(ptr+1, "*");
		}

		return host;
	}

        if (is_ipv4_address(host)) {
		/* it's an IP address, change last digit to * */
		ptr = strrchr(host, '.');
		if (ptr != NULL && isdigit(ptr[1]))
			strcpy(ptr+1, "*");
	} else {
		/* if more than one dot, skip the first
		   (dyn123.blah.net -> *.blah.net) */
		ptr = strchr(host, '.');
		if (ptr != NULL && strchr(ptr+1, '.') != NULL) {
			host = ptr-1;
                        host[0] = '*';
		}
	}

	return host;
}
/**
 * @brief Determines the host type in a buffer.
 *
 * @param[in] str   Buffer that contains host definition, could a be hostname,
 *                  single IPv4 or IPv6, CIDR-expressed block etc,.
 *
 * @return Host_TYPE_*, -1 if error.
 */
static int
determine_host_type (const gchar *str_stripped)
{
  /*
   * We have a single element with no leading or trailing
   * white spaces. This element could represent different host
   * definitions: single IPs, host names, CIDR-expressed blocks,
   * range-expressed networks, IPv6 addresses.
   */

  /* Null or empty string. */
  if (str_stripped == NULL || *str_stripped == '\0')
    return -1;

  /* Check for regular single IPv4 address. */
  if (is_ipv4_address (str_stripped))
    return HOST_TYPE_IPV4;

  /* Check for regular single IPv6 address. */
  if (is_ipv6_address (str_stripped))
    return HOST_TYPE_IPV6;

  /* Check for regular IPv4 CIDR-expressed block like "192.168.12.0/24" */
  if (is_cidr_block (str_stripped))
    return HOST_TYPE_CIDR_BLOCK;

  /* Check for short range-expressed networks "192.168.12.5-40" */
  if (is_short_range_network (str_stripped))
    return HOST_TYPE_RANGE_SHORT;

  /* Check for long range-expressed networks "192.168.1.0-192.168.3.44" */
  if (is_long_range_network (str_stripped))
    return HOST_TYPE_RANGE_LONG;

  /* Check for regular IPv6 CIDR-expressed block like "2620:0:2d0:200::7/120" */
  if (is_cidr6_block (str_stripped))
    return HOST_TYPE_CIDR6_BLOCK;

  /* Check for short range-expressed networks "::1-ef12" */
  if (is_short_range6_network (str_stripped))
    return HOST_TYPE_RANGE6_SHORT;

  /* Check for long IPv6 range-expressed networks like "::1:20:7-::1:25:3" */
  if (is_long_range6_network (str_stripped))
    return HOST_TYPE_RANGE6_LONG;

  /* Check for hostname. */
  if (is_hostname (str_stripped))
    return HOST_TYPE_NAME;

  /* @todo: If everything else fails, fallback to hostname ? */
  return -1;
}
Exemple #5
0
/* Start listening for incoming connections */
GIOChannel *dcc_listen(GIOChannel *iface, IPADDR *ip, int *port)
{
        GIOChannel *handle;
	IPADDR *listen_ip = NULL;
	const char *dcc_port, *p, *own_ip;
	int first, last;

	if (net_getsockname(iface, ip, NULL) == -1)
		return NULL;

	/* figure out if we want to listen in IPv4 address or in "any" address,
	   which may mean IPv4+IPv6 or just IPv6 depending on OS. */
	own_ip = settings_get_str("dcc_own_ip");
	if (*own_ip != '\0') {
		if (is_ipv4_address(own_ip))
			listen_ip = &ip4_any;
	} else {
		if (!IPADDR_IS_V6(ip))
			listen_ip = &ip4_any;
	}

        /* get first port */
	dcc_port = settings_get_str("dcc_port");
	first = atoi(dcc_port);
	if (first == 0) {
                /* random port */
		*port = 0;
		return net_listen(listen_ip, port);
	}

        /* get last port */
	p = strchr(dcc_port, ' ');
	if (p == NULL) p = strchr(dcc_port, '-');

	dcc_port = p;
	if (dcc_port == NULL)
		last = first;
	else {
		last = atoi(dcc_port+1);
		if (last == 0)
			last = first;
	}

        /* use the first available port */
	for (*port = first; *port <= last; (*port)++) {
		handle = net_listen(listen_ip, port);
		if (handle != NULL)
                        return handle;
	}

        return NULL;
}
/**
 * @brief Checks if a buffer points to a valid long range-expressed network.
 * "192.168.12.1-192.168.13.50" is valid.
 *
 * @param[in]   str Buffer to check in.
 *
 * @return 1 if valid long range-expressed network, 0 otherwise.
 */
static int
is_long_range_network (const char *str)
{
  char *first_str, *second_str;
  int ret;

  first_str = g_strdup (str);
  second_str = strchr (first_str, '-');
  if (second_str == NULL)
    {
      g_free (first_str);
      return 0;
    }

  /* Separate the addresses. */
  *second_str = '\0';
  second_str++;

  ret = is_ipv4_address (first_str) && is_ipv4_address (second_str);
  g_free (first_str);

  return ret;
}
int main( int narg, char **opts)

{
    int result;

    if( narg < 2) printf( "Give an IP address string to test on the command line.\n");
    else
    {
        result = is_ipv4_address( opts[ 1]);
        printf( "Is '%s' an IPV4 address?  rc=%d\n", opts[ 1], result);
    }

    exit( 0);
}
struct url_breakout *parse_url_string( char *url)

{
    int rc = RC_NORMAL, stlen, port_number = NO_PORT;
    char *copy = 0, *protocol = 0, *user = 0, *domain = 0, *port = 0,
      *uri = 0, *query = 0, *pos = 0, *en_protocol = 0, *en_user = 0, 
      *en_domain = 0, *st_port = 0, *st_query = 0, *next = 0, *scan_from = 0,
      *st_ipv6_port = 0, hold;
    struct url_breakout *parts = 0;

    copy = strdup( url);
    if( !copy) rc = ERR_MALLOC_FAILED;

    if( rc == RC_NORMAL)
    {
        parts = alloc_url_breakout();
        if( !parts) rc = ERR_MALLOC_FAILED;
    }

    if( rc == RC_NORMAL)
    {
        scan_from = pos = copy;
        next = copy + strlen( copy);

        en_protocol = strstr( scan_from, PROTOCOL_DELIM);
        if( en_protocol)
        {
            scan_from = en_protocol + strlen( PROTOCOL_DELIM);
            next = en_protocol;
	}

        en_user = strstr( scan_from, USER_DELIM);
        en_domain = strstr( scan_from, DOMAIN_DELIM);

        if( en_user)
        {
            if( !en_domain) scan_from = en_user + 1;
            else if( en_user < en_domain) scan_from = en_user + 1;
	}

        st_port = strstr( scan_from, PORT_DELIM);
        st_query = strstr( scan_from, QUERY_DELIM);

        st_ipv6_port = strstr( scan_from, IPV6_PORT_DELIM);
        if( st_ipv6_port)
        {
            if( en_domain)
            {
/* fixes the case:  http://2601:9:5480:7d:59a8:fa5e:a8d2:c72d#8080/something.html */
/* also allows:     http://www.foo.com#8080/something.html */
                if( st_ipv6_port < en_domain) st_port = st_ipv6_port;
	    }
            else if( st_query)
            {
/* fixes the case:  http://2601:9:5480:7d:59a8:fa5e:a8d2:c72d#8080?data=some */
/* also allows:     http://www.foo.com#8080?data=some */
                if( st_ipv6_port < st_query) st_port = st_ipv6_port;
	    }
/* fixes the case:  http://2601:9:5480:7d:59a8:fa5e:a8d2:c72d#8080 */
/* also allows:     http://www.foo.com#8080 */
            else st_port = st_ipv6_port;
	}

        if( en_user) if( en_user < next) next = en_user;
        if( en_domain) if( en_domain < next) next = en_domain;
        if( st_port) if( st_port < next) next = st_port;
	if( st_query) if( st_query < next) next = st_query;

    }

    if( rc == RC_NORMAL && next == en_protocol)
    {
        hold = *en_protocol;
        *en_protocol = '\0';
        protocol = strdup( pos);
        *en_protocol = hold;
        if( !protocol) rc = ERR_MALLOC_FAILED;
        else
        {
            pos = en_protocol + strlen( PROTOCOL_DELIM);

            next = pos + strlen( pos);
            if( en_user) if( en_user < next) next = en_user;
            if( en_domain) if( en_domain < next) next = en_domain;
            if( st_port) if( st_port < next) next = st_port;
            if( st_query) if( st_query < next) next = st_query;
        }
    }

    if( rc == RC_NORMAL && next == en_user)
    {
        hold = *en_user;
        *en_user = '******';
        user = strdup( pos);
        *en_user = hold;
        if( !user) rc = ERR_MALLOC_FAILED;
        pos = en_user + 1;

        next = next + strlen( next);
        if( st_port) if( st_port < next) next = st_port;
        if( en_domain) if( en_domain < next) next = en_domain;
        if( st_query) if( st_query < next) next = st_query;
    }

    if( rc == RC_NORMAL && next == st_port)
    {
        /* This is annoying, but we need to see if the ":" we found was part
         * of an IPV6 address and not a ":port" suffixs on a domain or IPV4
         * address.
         */
        if( en_domain)
        {
            hold = *en_domain;
            *en_domain = '\0';
	}

        if( is_ipv6_address( pos))
        {
            st_port = 0;

            domain = strdup( pos);
            if( !domain) rc = ERR_MALLOC_FAILED;

            if( en_domain)
            {
                *en_domain = hold;
                pos = en_domain;
	    }
            else pos = pos + strlen( pos);

            next = pos;
	}
        else
        {
            if( en_domain) *en_domain = hold;

            hold = *st_port;
            *st_port = '\0';
            domain = strdup( pos);
            *st_port = hold;
            if( !domain) rc = ERR_MALLOC_FAILED;
            else
            {
                stlen = strlen( PORT_DELIM);
                pos = st_port + stlen;

                next = next + strlen( next);
                if( en_domain) if( en_domain < next) next = en_domain;
                if( st_query) if( st_query < next) next = st_query;

                hold = *next;
                *next = '\0';
                port = strdup( pos);
                *next = hold;
                if( !port) rc = ERR_MALLOC_FAILED;

                pos = next;
            }
	}
    }

    if( rc == RC_NORMAL && next == en_domain)
    {
        if( !domain)
        {
            hold = *en_domain;
            *en_domain = '\0';
            domain = strdup( pos);
            *en_domain = hold;
            if( !domain) rc = ERR_MALLOC_FAILED;
            pos = en_domain;
        }

        if( rc == RC_NORMAL)
        {
            if( !st_query)
            {
                uri = strdup( pos);
                pos = pos + strlen( pos);
                next = pos;
	    }
            else
            {
                hold = *st_query;
                *st_query = '\0';
                uri = strdup( pos);
                *st_query = hold;
                next = pos = st_query;
	    }

            if( !uri) rc = ERR_MALLOC_FAILED;
	}
    }
            
    if( rc == RC_NORMAL && next == st_query)
    {
        if( !domain)
        {
            hold = *st_query;
            *st_query = '\0';
            domain = strdup( pos);
            *st_query = hold;
            if( !domain) rc = ERR_MALLOC_FAILED;
	}

        if( rc == RC_NORMAL)
        {
            query = strdup( st_query + 1);
            if( !query) rc = ERR_MALLOC_FAILED;
            pos = pos + strlen( pos);
            next = pos;
	}
    }

    if( rc == RC_NORMAL && !domain && !*next && *pos)
    {
        domain = strdup( pos);
        if( !domain) rc = ERR_MALLOC_FAILED;
        pos = next;
    }

    if( rc == RC_NORMAL && port)
    {
        if( !isdigit( *port)) rc = ERR_INVALID_DATA;
        else
        {
            errno = 0;
            port_number = strtoul( port, &pos, BASE10);
            if( errno) rc = ERR_INVALID_DATA;
            else if( *pos) rc = ERR_INVALID_DATA;
	}
    }

    if( rc == RC_NORMAL && domain)
    {
        pos = strdup( domain);
        if( !pos) rc = ERR_MALLOC_FAILED;
        else if( is_ipv4_address( domain)) parts->ip4 = pos;
        else if( is_ipv6_address( domain)) parts->ip6 = pos;
        else parts->host = pos;
    }

    if( rc == RC_NORMAL)
    {
        if( !domain) parts->status = URL_ERROR;
        else if( !*domain) parts->status = URL_ERROR;
        else
        {
            parts->status = URL_VALID;
            parts->port = port_number;
            parts->protocol = protocol;
            parts->user = user;
            parts->target = domain;
            parts->uri = uri;
            parts->query = query;
            if( protocol) parts->use_ssl = !strcasecmp( protocol, SSL_PROT_PREFIX);

            protocol = user = domain = uri = query = 0;
	}
    }
    else if( parts)
    {
        parts->status = URL_ERROR;
    }

    if( protocol) free( protocol);
    if( user) free( user);
    if( domain) free( domain);
    if( uri) free( uri);
    if( query) free( query);
    if( port) free( port);
    if( copy) free( copy);

    return( parts);
}