Пример #1
0
static u_long
ngx_http_geoip_addr(ngx_http_request_t *r, ngx_http_geoip_conf_t *gcf)
{
    ngx_addr_t           addr;
    ngx_array_t         *xfwd;
    struct sockaddr_in  *sin;

    addr.sockaddr = r->connection->sockaddr;
    addr.socklen = r->connection->socklen;
    /* addr.name = r->connection->addr_text; */

    xfwd = &r->headers_in.x_forwarded_for;

    if (xfwd->nelts > 0 && gcf->proxies != NULL) {
        (void) ngx_http_get_forwarded_addr(r, &addr, xfwd, NULL,
                                           gcf->proxies, gcf->proxy_recursive);
    }

#if (NGX_HAVE_INET6)

    if (addr.sockaddr->sa_family == AF_INET6) {
        u_char           *p;
        in_addr_t         inaddr;
        struct in6_addr  *inaddr6;

        inaddr6 = &((struct sockaddr_in6 *) addr.sockaddr)->sin6_addr;

        if (IN6_IS_ADDR_V4MAPPED(inaddr6)) {
            p = inaddr6->s6_addr;

            inaddr = p[12] << 24;
            inaddr += p[13] << 16;
            inaddr += p[14] << 8;
            inaddr += p[15];

            return inaddr;
        }
    }

#endif

    if (addr.sockaddr->sa_family != AF_INET) {
        return INADDR_NONE;
    }

    sin = (struct sockaddr_in *) addr.sockaddr;
    return ntohl(sin->sin_addr.s_addr);
}
Пример #2
0
char *
sockaddr_to_string(const struct sockaddr *sa, size_t length, GError **error)
{
#if defined(HAVE_IPV6) && defined(IN6_IS_ADDR_V4MAPPED)
	const struct sockaddr_in6 *a6 = (const struct sockaddr_in6 *)sa;
	struct sockaddr_in a4;
#endif
	int ret;
	char host[NI_MAXHOST], serv[NI_MAXSERV];

#if defined(HAVE_IPV6) && defined(IN6_IS_ADDR_V4MAPPED)
	if (sa->sa_family == AF_INET6 &&
	    IN6_IS_ADDR_V4MAPPED(&a6->sin6_addr)) {
		/* convert "::ffff:127.0.0.1" to "127.0.0.1" */

		memset(&a4, 0, sizeof(a4));
		a4.sin_family = AF_INET;
		memcpy(&a4.sin_addr, ((const char *)&a6->sin6_addr) + 12,
		       sizeof(a4.sin_addr));
		a4.sin_port = a6->sin6_port;

		sa = (const struct sockaddr *)&a4;
		length = sizeof(a4);
	}
#endif

	ret = getnameinfo(sa, length, host, sizeof(host), serv, sizeof(serv),
			  NI_NUMERICHOST|NI_NUMERICSERV);
	if (ret != 0) {
		g_set_error(error, g_quark_from_static_string("netdb"), ret,
			    "%s", gai_strerror(ret));
		return NULL;
	}

#ifdef HAVE_UN
	if (sa->sa_family == AF_UNIX)
		/* "serv" contains corrupt information with unix
		   sockets */
		return g_strdup(host);
#endif

#ifdef HAVE_IPV6
	if (strchr(host, ':') != NULL)
		return g_strconcat("[", host, "]:", serv, NULL);
#endif

	return g_strconcat(host, ":", serv, NULL);
}
Пример #3
0
static void
udp6_connect(netmsg_t msg)
{
	struct socket *so = msg->connect.base.nm_so;
	struct sockaddr *nam = msg->connect.nm_nam;
	struct thread *td = msg->connect.nm_td;
	struct sockaddr_in6 *sin6_p;
	struct inpcb *inp;
	int error;

	inp = so->so_pcb;
	if (inp == NULL) {
		error = EINVAL;
		goto out;
	}

	sin6_p = (struct sockaddr_in6 *)nam;
	if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
		error = EADDRNOTAVAIL;
		goto out;
	}

	if (!IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) {
		error = EISCONN;
		goto out;
	}
	if (inp->inp_flags & INP_WILDCARD)
		in_pcbremwildcardhash(inp);
	if (!prison_remote_ip(td, nam)) {
		error = EAFNOSUPPORT; /* IPv4 only jail */
		goto out;
	}
	error = in6_pcbconnect(inp, nam, td);
	if (error == 0) {
		soisconnected(so);
	} else if (error == EAFNOSUPPORT) {	/* connection dissolved */
		/*
		 * Follow traditional BSD behavior and retain
		 * the local port binding.  But, fix the old misbehavior
		 * of overwriting any previously bound local address.
		 */
		if (!(inp->inp_flags & INP_WASBOUND_NOTANY))
			inp->in6p_laddr = kin6addr_any;
		in_pcbinswildcardhash(inp);
	}
out:
	lwkt_replymsg(&msg->connect.base.lmsg, error);
}
unsigned int
isc_sockaddr_hash(const isc_sockaddr_t *sockaddr, isc_boolean_t address_only) {
	unsigned int length = 0;
	const unsigned char *s = NULL;
	unsigned int h = 0;
	unsigned int g;
	unsigned int p = 0;
	const struct in6_addr *in6;

	REQUIRE(sockaddr != NULL);

	switch (sockaddr->type.sa.sa_family) {
	case AF_INET:
		s = (const unsigned char *)&sockaddr->type.sin.sin_addr;
		p = ntohs(sockaddr->type.sin.sin_port);
		length = sizeof(sockaddr->type.sin.sin_addr.s_addr);
		break;
	case AF_INET6:
		in6 = &sockaddr->type.sin6.sin6_addr;
		s = (const unsigned char *)in6;
		if (IN6_IS_ADDR_V4MAPPED(in6)) {
			s += 12;
			length = sizeof(sockaddr->type.sin.sin_addr.s_addr);
		} else
			length = sizeof(sockaddr->type.sin6.sin6_addr);
		p = ntohs(sockaddr->type.sin6.sin6_port);
		break;
	default:
		UNEXPECTED_ERROR(__FILE__, __LINE__,
				 isc_msgcat_get(isc_msgcat,
						ISC_MSGSET_SOCKADDR,
						ISC_MSG_UNKNOWNFAMILY,
						"unknown address family: %d"),
					     (int)sockaddr->type.sa.sa_family);
		s = (const unsigned char *)&sockaddr->type;
		length = sockaddr->length;
		p = 0;
	}

	h = isc_hash_calc(s, length, ISC_TRUE);
	if (!address_only) {
		g = isc_hash_calc((const unsigned char *)&p, sizeof(p),
				  ISC_TRUE);
		h = h ^ g; /* XXX: we should concatenate h and p first */
	}

	return (h);
}
Пример #5
0
/** Return IPv6 address scope */
static int
li_scope6(struct in6_addr const *ip6)
{
  if (IN6_IS_ADDR_V4MAPPED(ip6) || IN6_IS_ADDR_V4COMPAT(ip6)) {
    uint32_t ip4 = *(uint32_t *)(ip6->s6_addr + 12);
    return li_scope4(ip4);
  }
  else if (IN6_IS_ADDR_LOOPBACK(ip6))
    return LI_SCOPE_HOST;
  else if (IN6_IS_ADDR_LINKLOCAL(ip6))
    return LI_SCOPE_LINK;
  else if (IN6_IS_ADDR_SITELOCAL(ip6))
    return LI_SCOPE_SITE;
  else
    return LI_SCOPE_GLOBAL;
}
Пример #6
0
/*
 * Opening a UDP socket is a little more tricky, since
 * UDP works in a way which is different from TCP...
 *
 * Our goal is to hide this difference for the end-user
 */
tree_cell *
nasl_open_sock_udp (lex_ctxt * lexic)
{
  int soc;
  tree_cell *retc;
  int port;
  struct sockaddr_in soca;
  struct sockaddr_in6 soca6;
  struct arglist *script_infos = lexic->script_infos;
  struct in6_addr *ia;

  port = get_int_var_by_num (lexic, 0, -1);
  if (port < 0)
    return NULL;

  ia = plug_get_host_ip (script_infos);
  if (ia == NULL)
    return NULL;
  if (IN6_IS_ADDR_V4MAPPED (ia))
    {
      bzero (&soca, sizeof (soca));
      soca.sin_addr.s_addr = ia->s6_addr32[3];
      soca.sin_port = htons (port);
      soca.sin_family = AF_INET;

      soc = socket (AF_INET, SOCK_DGRAM, 0);
      openvas_source_set_socket (soc, 0, AF_INET);
      connect (soc, (struct sockaddr *) &soca, sizeof (soca));
    }
  else
    {
      bzero (&soca6, sizeof (soca6));
      memcpy (&soca6.sin6_addr, ia, sizeof (struct in6_addr));
      soca6.sin6_port = htons (port);
      soca6.sin6_family = AF_INET6;

      soc = socket (AF_INET6, SOCK_DGRAM, 0);
      openvas_source_set_socket (soc, 0, AF_INET6);
      connect (soc, (struct sockaddr *) &soca6, sizeof (soca6));
    }


  retc = alloc_tree_cell (0, NULL);
  retc->type = CONST_INT;
  retc->x.i_val = soc < 0 ? 0 : soc;
  return retc;
}
Пример #7
0
/* Convert IPv4 compatible IPv6 address to IPv4 address. */
static void
sockunion_normalise_mapped (union sockunion *su)
{
  struct sockaddr_in sin;
  
#ifdef HAVE_IPV6
  if (su->sa.sa_family == AF_INET6 
      && IN6_IS_ADDR_V4MAPPED (&su->sin6.sin6_addr))
    {
      memset (&sin, 0, sizeof (struct sockaddr_in));
      sin.sin_family = AF_INET;
      sin.sin_port = su->sin6.sin6_port;
      memcpy (&sin.sin_addr, ((char *)&su->sin6.sin6_addr) + 12, 4);
      memcpy (su, &sin, sizeof (struct sockaddr_in));
    }
#endif /* HAVE_IPV6 */
}
Пример #8
0
void mappedtov4(union sockunion *sa)
{
  struct sockaddr_in sin;
  struct sockaddr_in6 *sin6 = &sa->sa6;

  byte_zero(&sin, sizeof(sin));
  if (sin6->sin6_family == AF_INET6 &&
    IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) ) {
      byte_copy(&sin.sin_addr, sizeof(sin.sin_addr), sin6->sin6_addr.s6_addr+12);
      sin.sin_port = sin6->sin6_port;
      sin.sin_family = AF_INET;
#ifdef HASSALEN
      sin.sin_len = sizeof(sin);
#endif
      byte_copy(&sa->sa4, sizeof(sin), &sin);
  }
}
Пример #9
0
static sockaddr_union *
unmap_v4mapped(
    sockaddr_union *sa,
    sockaddr_union *tmp)
{
    if (SU_GET_FAMILY(sa) == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&sa->sin6.sin6_addr)) {
	SU_INIT(tmp, AF_INET);
	SU_SET_PORT(tmp, SU_GET_PORT(sa));
	/* extract the v4 address from byte 12 of the v6 address */
	memcpy(&tmp->sin.sin_addr.s_addr,
	       &sa->sin6.sin6_addr.s6_addr[12],
	       sizeof(struct in_addr));
	return tmp;
    }

    return sa;
}
Пример #10
0
uint32_t addrConvert(struct sockaddr *pAddr)
{
    uint32_t ipv4;
    if (AF_INET6 == pAddr->sa_family)
    {
        if (IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)pAddr)->sin6_addr))
            ipv4 = ((Addr6 *) & ((struct sockaddr_in6 *)pAddr)->sin6_addr)->m_addrs[3];
        else
        {
            Addr6 *a6 = (Addr6 *) & ((struct sockaddr_in6 *)pAddr)->sin6_addr;
            ipv4 = a6->m_addrs[0] ^ a6->m_addrs[1] ^ a6->m_addrs[2] ^ a6->m_addrs[3];
        }
    }
    else
        ipv4 = ((struct sockaddr_in *)pAddr)->sin_addr.s_addr;
    return ipv4;
}
Пример #11
0
static apr_status_t parse_ip(apr_ipsubnet_t *ipsub, const char *ipstr, int network_allowed)
{
    /* supported flavors of IP:
     *
     * . IPv6 numeric address string (e.g., "fe80::1")
     * 
     *   IMPORTANT: Don't store IPv4-mapped IPv6 address as an IPv6 address.
     *
     * . IPv4 numeric address string (e.g., "127.0.0.1")
     *
     * . IPv4 network string (e.g., "9.67")
     *
     *   IMPORTANT: This network form is only allowed if network_allowed is on.
     */
    int rc;

#if APR_HAVE_IPV6
    rc = apr_inet_pton(AF_INET6, ipstr, ipsub->sub);
    if (rc == 1) {
        if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)ipsub->sub)) {
            /* apr_ipsubnet_test() assumes that we don't create IPv4-mapped IPv6
             * addresses; this of course forces the user to specify IPv4 addresses
             * in a.b.c.d style instead of ::ffff:a.b.c.d style.
             */
            return APR_EBADIP;
        }
        ipsub->family = AF_INET6;
    }
    else
#endif
    {
        rc = apr_inet_pton(AF_INET, ipstr, ipsub->sub);
        if (rc == 1) {
            ipsub->family = AF_INET;
        }
    }
    if (rc != 1) {
        if (network_allowed) {
            return parse_network(ipsub, ipstr);
        }
        else {
            return APR_EBADIP;
        }
    }
    return APR_SUCCESS;
}
static ngx_int_t
ngx_limit_tcp_find(ngx_connection_t *c)
{
    struct sockaddr_in    *sin;
    ngx_limit_tcp_conf_t  *ltcf;
#if (NGX_HAVE_INET6)
    u_char                *p;
    in_addr_t              addr;
    struct sockaddr_in6   *sin6;
#endif

    ltcf = (ngx_limit_tcp_conf_t *) ngx_get_conf(ngx_cycle->conf_ctx,
                                                 ngx_limit_tcp_module);
    switch (c->sockaddr->sa_family) {

    case AF_INET:
        if (ltcf->rules) {
            sin = (struct sockaddr_in *) c->sockaddr;
            return ngx_limit_tcp_inet(c, ltcf, sin->sin_addr.s_addr);
        }
        break;

#if (NGX_HAVE_INET6)

    case AF_INET6:
        sin6 = (struct sockaddr_in6 *) c->sockaddr;
        p = sin6->sin6_addr.s6_addr;

        if (ltcf->rules && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
            addr = p[12] << 24;
            addr += p[13] << 16;
            addr += p[14] << 8;
            addr += p[15];
            return ngx_limit_tcp_inet(c, ltcf, htonl(addr));
        }

        if (ltcf->rules6) {
            return ngx_limit_tcp_inet6(c, ltcf, p);
        }

#endif
    }

    return NGX_OK;
}
Пример #13
0
static void
tcp6_usr_connect(netmsg_t msg)
{
	struct socket *so = msg->connect.base.nm_so;
	struct sockaddr *nam = msg->connect.nm_nam;
	struct thread *td = msg->connect.nm_td;
	int error = 0;
	struct inpcb *inp;
	struct tcpcb *tp;
	struct sockaddr_in6 *sin6p;

	COMMON_START(so, inp, 0);

	/*
	 * Must disallow TCP ``connections'' to multicast addresses.
	 */
	sin6p = (struct sockaddr_in6 *)nam;
	if (sin6p->sin6_family == AF_INET6
	    && IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr)) {
		error = EAFNOSUPPORT;
		goto out;
	}

	if (!prison_remote_ip(td, nam)) {
		error = EAFNOSUPPORT; /* IPv4 only jail */
		goto out;
	}

	/* Reject v4-mapped address */
	if (IN6_IS_ADDR_V4MAPPED(&sin6p->sin6_addr)) {
		error = EADDRNOTAVAIL;
		goto out;
	}

	inp->inp_inc.inc_isipv6 = 1;
	tcp6_connect(msg);
	/* msg is invalid now */
	return;
out:
	if (msg->connect.nm_m) {
		m_freem(msg->connect.nm_m);
		msg->connect.nm_m = NULL;
	}
	lwkt_replymsg(&msg->lmsg, error);
}
Пример #14
0
static ngx_int_t
ngx_http_access_handler(ngx_http_request_t *r)
{
    struct sockaddr_in          *sin;
    ngx_http_access_loc_conf_t  *alcf;
#if (NGX_HAVE_INET6)
    u_char                      *p;
    in_addr_t                    addr;
    struct sockaddr_in6         *sin6;
#endif

    alcf = ngx_http_get_module_loc_conf(r, ngx_http_access_module);

    switch (r->connection->sockaddr->sa_family) {

    case AF_INET:
        if (alcf->rules) {
            sin = (struct sockaddr_in *) r->connection->sockaddr;
            return ngx_http_access_inet(r, alcf, sin->sin_addr.s_addr);
        }
        break;

#if (NGX_HAVE_INET6)

    case AF_INET6:
        sin6 = (struct sockaddr_in6 *) r->connection->sockaddr;
        p = sin6->sin6_addr.s6_addr;

        if (alcf->rules && IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
            addr = p[12] << 24;
            addr += p[13] << 16;
            addr += p[14] << 8;
            addr += p[15];
            return ngx_http_access_inet(r, alcf, htonl(addr));
        }

        if (alcf->rules6) {
            return ngx_http_access_inet6(r, alcf, p);
        }

#endif
    }

    return NGX_DECLINED;
}
Пример #15
0
/*  return 0 if ip is a LAN ip.
 *  return -1 if it is not.
 */
int LAN_ip(IP ip)
{
    if (ip.family == AF_INET) {
        IP4 ip4 = ip.ip4;

        /* Loopback. */
        if (ip4.uint8[0] == 127)
            return 0;

        /* 10.0.0.0 to 10.255.255.255 range. */
        if (ip4.uint8[0] == 10)
            return 0;

        /* 172.16.0.0 to 172.31.255.255 range. */
        if (ip4.uint8[0] == 172 && ip4.uint8[1] >= 16 && ip4.uint8[1] <= 31)
            return 0;

        /* 192.168.0.0 to 192.168.255.255 range. */
        if (ip4.uint8[0] == 192 && ip4.uint8[1] == 168)
            return 0;

        /* 169.254.1.0 to 169.254.254.255 range. */
        if (ip4.uint8[0] == 169 && ip4.uint8[1] == 254 && ip4.uint8[2] != 0
                && ip4.uint8[2] != 255)
            return 0;

    } else if (ip.family == AF_INET6) {

        /* autogenerated for each interface: FE80::* (up to FEBF::*)
           FF02::1 is - according to RFC 4291 - multicast all-nodes link-local */
        if (((ip.ip6.uint8[0] == 0xFF) && (ip.ip6.uint8[1] < 3) && (ip.ip6.uint8[15] == 1)) ||
                ((ip.ip6.uint8[0] == 0xFE) && ((ip.ip6.uint8[1] & 0xC0) == 0x80)))
            return 0;

        /* embedded IPv4-in-IPv6 */
        if (IN6_IS_ADDR_V4MAPPED(&ip.ip6.in6_addr)) {
            IP ip4;
            ip4.family = AF_INET;
            ip4.ip4.uint32 = ip.ip6.uint32[3];
            return LAN_ip(ip4);
        }
    }

    return -1;
}
Пример #16
0
int HttpListener::checkAccess( struct conn_data * pData )
{
    struct sockaddr * pPeer = ( struct sockaddr *) pData->achPeerAddr;
    if (( AF_INET6 == pPeer->sa_family )&&
        ( IN6_IS_ADDR_V4MAPPED( &((struct sockaddr_in6 *)pPeer)->sin6_addr )) )
    {
        pPeer->sa_family = AF_INET;
        ((struct sockaddr_in *)pPeer)->sin_addr.s_addr = *((in_addr_t *)&pData->achPeerAddr[20]);
    }
    ClientInfo * pInfo = HttpGlobals::getClientCache()->getClientInfo( pPeer );
    pData->pInfo = pInfo;

    if ( D_ENABLED( DL_MORE ))
        LOG_D(( "[%s] New connection from %s:%d.", getAddrStr(),
                    pInfo->getAddrString(), ntohs( ((struct sockaddr_in*)pPeer)->sin_port) ));

    return pInfo->checkAccess();
}
Пример #17
0
/*
 * NAME:	conn->accept6()
 * DESCRIPTION:	accept a new ipv6 connection
 */
static connection *conn_accept6(int portfd, int port)
{
    int fd;
    unsigned int len;
    struct sockaddr_in6 sin6;
    in46addr addr;
    connection *conn;

    if (!FD_ISSET(portfd, &readfds)) {
	return (connection *) NULL;
    }
    len = sizeof(sin6);
    fd = accept(portfd, (struct sockaddr *) &sin6, &len);
    if (fd < 0) {
	FD_CLR(portfd, &readfds);
	return (connection *) NULL;
    }
    fcntl(fd, F_SETFL, FNDELAY);

    conn = flist;
    flist = (connection *) conn->chain.next;
    conn->chain.name = (char *) NULL;
    conn->fd = fd;
    conn->udpbuf = (char *) NULL;
    if (IN6_IS_ADDR_V4MAPPED(&sin6.sin6_addr)) {
	/* convert to IPv4 address */
	addr.in.addr = *(struct in_addr *) &sin6.sin6_addr.s6_addr[12];
	addr.ipv6 = FALSE;
    } else {
	addr.in.addr6 = sin6.sin6_addr;
	addr.ipv6 = TRUE;
    }
    conn->addr = ipa_new(&addr);
    conn->at = port;
    FD_SET(fd, &infds);
    FD_SET(fd, &outfds);
    FD_CLR(fd, &readfds);
    FD_SET(fd, &writefds);
    if (fd > maxfd) {
	maxfd = fd;
    }

    return conn;
}
Пример #18
0
/*  
    Return a numerical IP address and port for the given socket info
 */
PUBLIC int socketAddress(struct sockaddr *addr, int addrlen, char *ip, int ipLen, int *port)
{
#if (ME_UNIX_LIKE || WINDOWS)
    char    service[NI_MAXSERV];

#ifdef IN6_IS_ADDR_V4MAPPED
    if (addr->sa_family == AF_INET6) {
        struct sockaddr_in6* addr6 = (struct sockaddr_in6*) addr;
        if (IN6_IS_ADDR_V4MAPPED(&addr6->sin6_addr)) {
            struct sockaddr_in addr4;
            memset(&addr4, 0, sizeof(addr4));
            addr4.sin_family = AF_INET;
            addr4.sin_port = addr6->sin6_port;
            memcpy(&addr4.sin_addr.s_addr, addr6->sin6_addr.s6_addr + 12, sizeof(addr4.sin_addr.s_addr));
            memcpy(addr, &addr4, sizeof(addr4));
            addrlen = sizeof(addr4);
        }
    }
#endif
    if (getnameinfo(addr, addrlen, ip, ipLen, service, sizeof(service), NI_NUMERICHOST | NI_NUMERICSERV | NI_NOFQDN)) {
        return -1;
    }
    if (port) {
        *port = atoi(service);
    }

#else
    struct sockaddr_in  *sa;

#if HAVE_NTOA_R
    sa = (struct sockaddr_in*) addr;
    inet_ntoa_r(sa->sin_addr, ip, ipLen);
#else
    uchar   *cp;
    sa = (struct sockaddr_in*) addr;
    cp = (uchar*) &sa->sin_addr;
    fmt(ip, ipLen, "%d.%d.%d.%d", cp[0], cp[1], cp[2], cp[3]);
#endif
    if (port) {
        *port = ntohs(sa->sin_port);
    }
#endif
    return 0;
}
Пример #19
0
int
is_loopback(struct netbuf *nbuf)
{
	struct sockaddr *addr = (struct sockaddr *)nbuf->buf;
	struct sockaddr_in *sin;
#ifdef INET6
	struct sockaddr_in6 *sin6;
#endif

	switch (addr->sa_family) {
	case AF_INET:
		if (!oldstyle_local)
			return 0;
		sin = (struct sockaddr_in *)addr;
#ifdef RPCBIND_DEBUG
		if (debugging)
			  fprintf(stderr,
				  "Checking caller's adress (port = %d)\n",
				  ntohs(sin->sin_port));
#endif
	       	return (sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK));
#ifdef INET6
	case AF_INET6:
		if (!oldstyle_local)
			return 0;
		sin6 = (struct sockaddr_in6 *)addr;
#ifdef RPCBIND_DEBUG
		if (debugging)
			  fprintf(stderr,
				  "Checking caller's adress (port = %d)\n",
				  ntohs(sin6->sin6_port));
#endif
		return (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) ||
			 (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) &&
			  sin6->sin6_addr.s6_addr32[3] == htonl(INADDR_LOOPBACK)));
#endif
	case AF_LOCAL:
		return 1;
	default:
		break;
	}
	
	return 0;
}
Пример #20
0
static int
udp6_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
{
	struct inpcb *inp;
	struct inpcbinfo *pcbinfo;
	int error;

	pcbinfo = udp_get_inpcbinfo(so->so_proto->pr_protocol);
	inp = sotoinpcb(so);
	KASSERT(inp != NULL, ("udp6_bind: inp == NULL"));

	INP_WLOCK(inp);
	INP_HASH_WLOCK(pcbinfo);
	inp->inp_vflag &= ~INP_IPV4;
	inp->inp_vflag |= INP_IPV6;
	if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
		struct sockaddr_in6 *sin6_p;

		sin6_p = (struct sockaddr_in6 *)nam;

		if (IN6_IS_ADDR_UNSPECIFIED(&sin6_p->sin6_addr))
			inp->inp_vflag |= INP_IPV4;
#ifdef INET
		else if (IN6_IS_ADDR_V4MAPPED(&sin6_p->sin6_addr)) {
			struct sockaddr_in sin;

			in6_sin6_2_sin(&sin, sin6_p);
			inp->inp_vflag |= INP_IPV4;
			inp->inp_vflag &= ~INP_IPV6;
			error = in_pcbbind(inp, (struct sockaddr *)&sin,
			    td->td_ucred);
			goto out;
		}
#endif
	}

	error = in6_pcbbind(inp, nam, td->td_ucred);
#ifdef INET
out:
#endif
	INP_HASH_WUNLOCK(pcbinfo);
	INP_WUNLOCK(inp);
	return (error);
}
Пример #21
0
void bctbx_sockaddr_remove_v4_mapping(const struct sockaddr *v6, struct sockaddr *result, socklen_t *result_len) {
	if (v6->sa_family == AF_INET6) {
		struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)v6;

		if (IN6_IS_ADDR_V4MAPPED(&in6->sin6_addr)) {
			struct sockaddr_in *in = (struct sockaddr_in *)result;
			result->sa_family = AF_INET;
			in->sin_addr.s_addr = IN6_GET_ADDR_V4MAPPED(&in6->sin6_addr);
			in->sin_port = in6->sin6_port;
			*result_len = sizeof(struct sockaddr_in);
		} else {
			if (v6 != result) memcpy(result, v6, sizeof(struct sockaddr_in6));
			*result_len = sizeof(struct sockaddr_in6);
		}
	} else {
		*result_len = sizeof(struct sockaddr_in);
		if (v6 != result) memcpy(result, v6, sizeof(struct sockaddr_in));
	}
}
Пример #22
0
/* translate IPv4 mapped IPv6 address to IPv4 address */
void
unmappedaddr(struct sockaddr_in6 *sin6)
{
	struct sockaddr_in *sin4;
	u_int32_t addr;
	int port;

	if (sin6->sin6_family != AF_INET6 ||
	    !IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr))
		return;
	sin4 = (struct sockaddr_in *)sin6;
	memcpy(&addr, &sin6->sin6_addr.s6_addr[12], sizeof(addr));
	port = sin6->sin6_port;
	memset(sin4, 0, sizeof(struct sockaddr_in));
	sin4->sin_addr.s_addr = addr;
	sin4->sin_port = port;
	sin4->sin_family = AF_INET;
	sin4->sin_len = sizeof(struct sockaddr_in);
}
Пример #23
0
static int
tcp6_usr_connect(struct socket *so, struct sockaddr *nam, struct proc *p)
{
	int s = splnet();
	int error = 0;
	struct inpcb *inp = sotoinpcb(so);
	struct tcpcb *tp;
	struct sockaddr_in6 *sin6p;

	COMMON_START();

	/*
	 * Must disallow TCP ``connections'' to multicast addresses.
	 */
	sin6p = (struct sockaddr_in6 *)nam;
	if (sin6p->sin6_family == AF_INET6
	    && IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr)) {
		error = EAFNOSUPPORT;
		goto out;
	}

	if (IN6_IS_ADDR_V4MAPPED(&sin6p->sin6_addr)) {
		struct sockaddr_in sin;

		if (!ip6_mapped_addr_on ||
		    (inp->inp_flags & IN6P_IPV6_V6ONLY))
			return(EINVAL);

		in6_sin6_2_sin(&sin, sin6p);
		inp->inp_vflag |= INP_IPV4;
		inp->inp_vflag &= ~INP_IPV6;
		if ((error = tcp_connect(tp, (struct sockaddr *)&sin, p)) != 0)
			goto out;
		error = tcp_output(tp);
		goto out;
	}
	inp->inp_vflag &= ~INP_IPV4;
	inp->inp_vflag |= INP_IPV6;
	if ((error = tcp6_connect(tp, nam, p)) != 0)
		goto out;
	error = tcp_output(tp);
	COMMON_END(PRU_CONNECT);
}
Пример #24
0
static void
merge_one_ip6_config (NMResolvConfData *rc, NMIP6Config *src, const char *iface)
{
    guint32 num, i;

    num = nm_ip6_config_get_num_nameservers (src);
    for (i = 0; i < num; i++) {
        const struct in6_addr *addr;
        char buf[INET6_ADDRSTRLEN];

        addr = nm_ip6_config_get_nameserver (src, i);

        /* inet_ntop is probably supposed to do this for us, but it doesn't */
        if (IN6_IS_ADDR_V4MAPPED (addr)) {
            if (inet_ntop (AF_INET, &(addr->s6_addr32[3]), buf, INET_ADDRSTRLEN) > 0)
                add_string_item (rc->nameservers, buf);
        } else {
            if (inet_ntop (AF_INET6, addr, buf, INET6_ADDRSTRLEN) > 0) {
                if (IN6_IS_ADDR_LINKLOCAL (addr) && strchr (buf, '%') == NULL) {
                    char *tmp;
                    tmp = g_strdup_printf ("%s%%%s", buf, iface);
                    add_string_item (rc->nameservers, tmp);
                    g_free (tmp);
                } else
                    add_string_item (rc->nameservers, buf);
            }
        }
    }

    num = nm_ip6_config_get_num_domains (src);
    for (i = 0; i < num; i++) {
        const char *domain;

        domain = nm_ip6_config_get_domain (src, i);
        if (!rc->domain)
            rc->domain = domain;
        add_string_item (rc->searches, domain);
    }

    num = nm_ip6_config_get_num_searches (src);
    for (i = 0; i < num; i++)
        add_string_item (rc->searches, nm_ip6_config_get_search (src, i));
}
Пример #25
0
/*
 * This is called for the -h option, initializes cxt->{hostname,hostaddress}.
 */
static void init_remote_info(struct login_context *cxt, char *remotehost)
{
	const char *domain;
	char *p;
	struct addrinfo hints, *info = NULL;

	cxt->remote = 1;

	get_thishost(cxt, &domain);

	if (domain && (p = strchr(remotehost, '.')) &&
	    strcasecmp(p + 1, domain) == 0)
		*p = '\0';

	cxt->hostname = xstrdup(remotehost);

	memset(&hints, 0, sizeof(hints));
	hints.ai_flags = AI_ADDRCONFIG;
	cxt->hostaddress[0] = 0;

	if (getaddrinfo(cxt->hostname, NULL, &hints, &info) == 0 && info) {
		if (info->ai_family == AF_INET) {
			struct sockaddr_in *sa =
				    (struct sockaddr_in *) info->ai_addr;

			memcpy(cxt->hostaddress, &(sa->sin_addr), sizeof(sa->sin_addr));

		} else if (info->ai_family == AF_INET6) {
			struct sockaddr_in6 *sa =
				     (struct sockaddr_in6 *) info->ai_addr;
#ifdef IN6_IS_ADDR_V4MAPPED
			if (IN6_IS_ADDR_V4MAPPED(&sa->sin6_addr)) {
				const uint8_t *bytes = sa->sin6_addr.s6_addr;
				struct in_addr addr = { *(const in_addr_t *) (bytes + 12) };

				memcpy(cxt->hostaddress, &addr, sizeof(struct in_addr));
			} else
#endif
				memcpy(cxt->hostaddress, &(sa->sin6_addr), sizeof(sa->sin6_addr));
		}
		freeaddrinfo(info);
	}
}
Пример #26
0
/*
 * Taken from inetd.c
 * This is a wrapper function for inet_ntop(). In case the af is AF_INET6
 * and the address pointed by src is a IPv4-mapped IPv6 address, it
 * returns printable IPv4 address, not IPv4-mapped IPv6 address. In other cases
 * it behaves just like inet_ntop().
 */
static const char *
inet_ntop_native(int af, const void *src, char *dst, size_t size)
{
	struct in_addr src4;
	const char *result;

	if (af == AF_INET6) {
		if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)src)) {
			IN6_V4MAPPED_TO_INADDR((struct in6_addr *)src, &src4);
			result = inet_ntop(AF_INET, &src4, dst, size);
		} else {
			result = inet_ntop(AF_INET6, src, dst, size);
		}
	} else {
		result = inet_ntop(af, src, dst, size);
	}

	return (result);
}
Пример #27
0
static void
udp6_send(netmsg_t msg)
{
	struct socket *so = msg->send.base.nm_so;
	struct mbuf *m = msg->send.nm_m;
	struct sockaddr *addr = msg->send.nm_addr;
	struct mbuf *control = msg->send.nm_control;
	struct thread *td = msg->send.nm_td;
	struct inpcb *inp;
	int error = 0;

	inp = so->so_pcb;
	if (inp == NULL) {
		error = EINVAL;
		goto bad;
	}

	if (addr) {
		struct sockaddr_in6 *sin6;

		if (addr->sa_len != sizeof(struct sockaddr_in6)) {
			error = EINVAL;
			goto bad;
		}
		if (addr->sa_family != AF_INET6) {
			error = EAFNOSUPPORT;
			goto bad;
		}

		sin6 = (struct sockaddr_in6 *)addr;
		if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) {
			error = EADDRNOTAVAIL;
			goto bad;
		}
	}

	error = udp6_output(inp, m, addr, control, td);
	lwkt_replymsg(&msg->send.base.lmsg, error);
	return;
bad:
	m_freem(m);
	lwkt_replymsg(&msg->send.base.lmsg, error);
}
Пример #28
0
static void
tcp6_usr_bind(netmsg_t msg)
{
	struct socket *so = msg->bind.base.nm_so;
	struct sockaddr *nam = msg->bind.nm_nam;
	struct thread *td = msg->bind.nm_td;
	int error = 0;
	struct inpcb *inp;
	struct tcpcb *tp;
	struct sockaddr_in6 *sin6p;

	COMMON_START(so, inp, 0);

	/*
	 * Must check for multicast addresses and disallow binding
	 * to them.
	 */
	sin6p = (struct sockaddr_in6 *)nam;
	if (sin6p->sin6_family == AF_INET6 &&
	    IN6_IS_ADDR_MULTICAST(&sin6p->sin6_addr)) {
		error = EAFNOSUPPORT;
		goto out;
	}
	inp->inp_vflag &= ~INP_IPV4;
	inp->inp_vflag |= INP_IPV6;
	if ((inp->inp_flags & IN6P_IPV6_V6ONLY) == 0) {
		if (IN6_IS_ADDR_UNSPECIFIED(&sin6p->sin6_addr))
			inp->inp_vflag |= INP_IPV4;
		else if (IN6_IS_ADDR_V4MAPPED(&sin6p->sin6_addr)) {
			struct sockaddr_in sin;

			in6_sin6_2_sin(&sin, sin6p);
			inp->inp_vflag |= INP_IPV4;
			inp->inp_vflag &= ~INP_IPV6;
			error = in_pcbbind(inp, (struct sockaddr *)&sin, td);
			goto out;
		}
	}
	error = in6_pcbbind(inp, nam, td);
	if (error)
		goto out;
	COMMON_END(PRU_BIND);
}
Пример #29
0
void
mangle_mapped_sockaddr(struct sockaddr *in)
{
	struct sockaddr_in6 *in6 = (struct sockaddr_in6 *)in;								

	if(in->sa_family == AF_INET)
		return;

	if(in->sa_family == AF_INET6 && IN6_IS_ADDR_V4MAPPED(&in6->sin6_addr))
	{
		struct sockaddr_in in4;
		memset(&in4, 0, sizeof(struct sockaddr_in));
		in4.sin_family = AF_INET;
		in4.sin_port = in6->sin6_port;
		in4.sin_addr.s_addr = ((uint32_t *)&in6->sin6_addr)[3];
		memcpy(in, &in4, sizeof(struct sockaddr_in)); 		
	}	
	return;
}
Пример #30
0
static void mappedtov4(struct sockaddr *ss)
{
   struct sockaddr_in sin;
   struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)ss;

   debug(DEBUGLEVEL_INFO, "mappedtov4 %p\n", ss);

   if (ss->sa_family == AF_INET6 &&
         IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) ) {
      memcpy(&sin.sin_addr, sin6->sin6_addr.s6_addr+12,
            sizeof(sin.sin_addr));
      sin.sin_port = ((struct sockaddr_in6 *)ss)->sin6_port;
      sin.sin_family = AF_INET;
#ifdef SIN6_LEN
      sin.sin_len = 16;
#endif
      memcpy(ss, &sin, sizeof(sin));
   }
}