Example #1
0
BOOL CProtocolBridge::IsLocalCall(IHttpContext* ctx)
{
	PSOCKADDR src = ctx->GetRequest()->GetRemoteAddress();
	PSOCKADDR dest = ctx->GetRequest()->GetLocalAddress();

	if (AF_INET == src->sa_family && AF_INET == dest->sa_family)
	{
        DWORD srcAddress = ntohl(((PSOCKADDR_IN)src)->sin_addr.s_addr);
		DWORD destAddress = ntohl(((PSOCKADDR_IN)dest)->sin_addr.s_addr);

		return srcAddress == destAddress || LOCAL127 == srcAddress || LOCAL127 == destAddress;
	}
	else if (AF_INET6 == src->sa_family && AF_INET6 == dest->sa_family)
	{
        IN6_ADDR* srcAddress = &((PSOCKADDR_IN6)src)->sin6_addr;
		IN6_ADDR* destAddress = &((PSOCKADDR_IN6)dest)->sin6_addr;

		if (0 == memcmp(srcAddress, destAddress, sizeof IN6_ADDR))
		{
			return TRUE;
		}

		if (IN6_IS_ADDR_LOOPBACK(srcAddress) || IN6_IS_ADDR_LOOPBACK(destAddress))
		{
			return TRUE;
		}
	}

	return FALSE;
}
Example #2
0
int pr_netaddr_is_loopback(const pr_netaddr_t *na) {
  if (!na) {
    errno = EINVAL;
    return -1;
  }

  switch (pr_netaddr_get_family(na)) {
    case AF_INET:
      return IN_IS_ADDR_LOOPBACK(
        (struct in_addr *) pr_netaddr_get_inaddr(na));

#ifdef PR_USE_IPV6
    case AF_INET6:
      /* XXX *sigh* Different platforms implement the IN6_IS_ADDR macros
       * differently.  For example, on Linux, those macros expect to operate
       * on s6_addr32, while on Solaris, the macros operate on struct in6_addr.
       * Certain Drafts define the macros to work on struct in6_addr *, as
       * Solaris does, so Linux may have it wrong.  Tentative research on
       * Google shows some BSD netinet6/in6.h headers that define these
       * macros in terms of struct in6_addr *, so I'll go with that for now.
       * Joy. =P
       */
# ifndef LINUX
      return IN6_IS_ADDR_LOOPBACK(
        (struct in6_addr *) pr_netaddr_get_inaddr(na));
# else
      return IN6_IS_ADDR_LOOPBACK(
        ((struct in6_addr *) pr_netaddr_get_inaddr(na))->s6_addr32);
# endif
#endif /* PR_USE_IPV6 */
  }

  return FALSE;
}
void mh_send_be(struct in6_addr *dst, struct in6_addr *hoa,
		struct in6_addr *src, uint8_t status, int iif)
{
	struct ip6_mh_binding_error *be;
	struct iovec iov;
	struct in6_addr_bundle out;

	if (IN6_IS_ADDR_UNSPECIFIED(dst) ||
	    IN6_IS_ADDR_LOOPBACK(dst) ||
	    IN6_IS_ADDR_MULTICAST(dst)) {
		MDBG("Omit BE for non-unicast "
		     "%x:%x:%x:%x:%x:%x:%x:%x\n", NIP6ADDR(dst));
		return;
	}

	out.remote_coa = NULL;
	out.local_coa = NULL;
	be = mh_create(&iov, IP6_MH_TYPE_BERROR);
	if (!be)
		return;
	be->ip6mhbe_status = status;
	out.src = src;
	out.dst = dst;
	if (hoa)
		be->ip6mhbe_homeaddr = *hoa;
	out.dst = dst;

	mh_send(&out, &iov, 1, NULL, iif);
	free_iov_data(&iov, 1);
}
Example #4
0
// We can't statically say much about what network interfaces are available, but we can be pretty
// sure there's a loopback interface, and that it has IPv4, IPv6, and AF_PACKET entries.
TEST(ifaddrs, getifaddrs_lo) {
  ifaddrs* addrs = nullptr;

  ASSERT_EQ(0, getifaddrs(&addrs));
  ASSERT_TRUE(addrs != nullptr);

  ifaddrs* lo_inet4 = nullptr;
  ifaddrs* lo_inet6 = nullptr;
  ifaddrs* lo_packet = nullptr;
  for (ifaddrs* addr = addrs; addr != nullptr; addr = addr->ifa_next) {
    if (addr->ifa_name && strcmp(addr->ifa_name, "lo") == 0) {
      if (addr->ifa_addr && addr->ifa_addr->sa_family == AF_INET) lo_inet4 = addr;
      else if (addr->ifa_addr && addr->ifa_addr->sa_family == AF_INET6) lo_inet6 = addr;
      else if (addr->ifa_addr && addr->ifa_addr->sa_family == AF_PACKET) lo_packet = addr;
    }
  }

  // Does the IPv4 entry look right?
  ASSERT_TRUE(lo_inet4 != nullptr);
  const sockaddr_in* sa_inet4 = reinterpret_cast<const sockaddr_in*>(lo_inet4->ifa_addr);
  ASSERT_TRUE(ntohl(sa_inet4->sin_addr.s_addr) == INADDR_LOOPBACK);

  // Does the IPv6 entry look right?
  ASSERT_TRUE(lo_inet6 != nullptr);
  const sockaddr_in6* sa_inet6 = reinterpret_cast<const sockaddr_in6*>(lo_inet6->ifa_addr);
  ASSERT_TRUE(IN6_IS_ADDR_LOOPBACK(&sa_inet6->sin6_addr));

  // Does the AF_PACKET entry look right?
  ASSERT_TRUE(lo_packet != nullptr);
  const sockaddr_ll* sa_ll = reinterpret_cast<const sockaddr_ll*>(lo_packet->ifa_addr);
  ASSERT_EQ(6, sa_ll->sll_halen);

  freeifaddrs(addrs);
}
Example #5
0
static inline int
check_if_local_address6(struct sockaddr_in6 *addr)
{
	struct ifaddrs *ifaddrs;
	int local = IN6_IS_ADDR_LOOPBACK(&(addr->sin6_addr));

	if (!local && !getifaddrs(&ifaddrs)) {
		struct ifaddrs *ifa;

		for (ifa = ifaddrs; ifa; ifa = ifa->ifa_next) {
			if (!ifa->ifa_addr)
				continue;

			if (ifa->ifa_addr->sa_family == AF_INET6
			    && !memcmp(&addr->sin6_addr.s6_addr,
			    &((struct sockaddr_in6 *) ifa->ifa_addr)->sin6_addr.s6_addr,
			    sizeof(addr->sin6_addr.s6_addr))) {
				local = 1;
				break;
			}

			if (ifa->ifa_addr->sa_family == AF_INET
			    && !memcmp(&((struct sockaddr_in *) &addr)->sin_addr.s_addr,
				&((struct sockaddr_in *) ifa->ifa_addr)->sin_addr.s_addr,
				sizeof(((struct sockaddr_in *) &addr)->sin_addr.s_addr))) {
					local = 1;
					break;
			}
		}

		freeifaddrs(ifaddrs);
	}

	return local;
}
Example #6
0
/*
 * Determine the appropriate scope zone ID for in6 and ifp.  If ret_id is
 * non NULL, it is set to the zone ID.  If the zone ID needs to be embedded
 * in the in6_addr structure, in6 will be modified. 
 *
 * ret_id - unnecessary?
 */
int
in6_setscope(struct in6_addr *in6, struct ifnet *ifp, u_int32_t *ret_id)
{
	int scope;
	u_int32_t zoneid = 0;
	struct scope6_id *sid = SID(ifp);

#ifdef DIAGNOSTIC
	if (sid == NULL) { /* should not happen */
		panic("in6_setscope: scope array is NULL");
		/* NOTREACHED */
	}
#endif

	/*
	 * special case: the loopback address can only belong to a loopback
	 * interface.
	 */
	if (IN6_IS_ADDR_LOOPBACK(in6)) {
		if (!(ifp->if_flags & IFF_LOOPBACK))
			return (EINVAL);
		else {
			if (ret_id != NULL)
				*ret_id = 0; /* there's no ambiguity */
			return (0);
		}
	}

	scope = in6_addrscope(in6);

	switch (scope) {
	case IPV6_ADDR_SCOPE_INTFACELOCAL: /* should be interface index */
		zoneid = sid->s6id_list[IPV6_ADDR_SCOPE_INTFACELOCAL];
		break;

	case IPV6_ADDR_SCOPE_LINKLOCAL:
		zoneid = sid->s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL];
		break;

	case IPV6_ADDR_SCOPE_SITELOCAL:
		zoneid = sid->s6id_list[IPV6_ADDR_SCOPE_SITELOCAL];
		break;

	case IPV6_ADDR_SCOPE_ORGLOCAL:
		zoneid = sid->s6id_list[IPV6_ADDR_SCOPE_ORGLOCAL];
		break;

	default:
		zoneid = 0;	/* XXX: treat as global. */
		break;
	}

	if (ret_id != NULL)
		*ret_id = zoneid;

	if (IN6_IS_SCOPE_LINKLOCAL(in6) || IN6_IS_ADDR_MC_INTFACELOCAL(in6))
		in6->s6_addr16[1] = htons(zoneid & 0xffff); /* XXX */

	return (0);
}
Example #7
0
/*
 * Rewrite destination address in case we will connect to loopback address.
 *
 * Returns 0 on success, EAFNOSUPPORT if the jail doesn't allow IPv6.
 */
int
prison_remote_ip6(struct ucred *cred, struct in6_addr *ia6)
{
	struct prison *pr;

	KASSERT(cred != NULL, ("%s: cred is NULL", __func__));
	KASSERT(ia6 != NULL, ("%s: ia6 is NULL", __func__));

	pr = cred->cr_prison;
	if (!(pr->pr_flags & PR_IP6))
		return (0);
	mtx_lock(&pr->pr_mtx);
	if (!(pr->pr_flags & PR_IP6)) {
		mtx_unlock(&pr->pr_mtx);
		return (0);
	}
	if (pr->pr_ip6 == NULL) {
		mtx_unlock(&pr->pr_mtx);
		return (EAFNOSUPPORT);
	}

	if (IN6_IS_ADDR_LOOPBACK(ia6)) {
		bcopy(&pr->pr_ip6[0], ia6, sizeof(struct in6_addr));
		mtx_unlock(&pr->pr_mtx);
		return (0);
	}

	/*
	 * Return success because nothing had to be changed.
	 */
	mtx_unlock(&pr->pr_mtx);
	return (0);
}
Example #8
0
File: net.c Project: anandhis/ompi
bool
opal_net_islocalhost(const struct sockaddr *addr)
{
    switch (addr->sa_family) {
    case AF_INET:
        {
            const struct sockaddr_in *inaddr = (struct sockaddr_in*) addr;
            /* if it's in the 127. domain, it shouldn't be routed
               (0x7f == 127) */
            if (0x7F000000 == (0x7F000000 & ntohl(inaddr->sin_addr.s_addr))) {
                return true;
            }
            return false;
        }
        break;
#if OPAL_ENABLE_IPV6
    case AF_INET6:
        {
            const struct sockaddr_in6 *inaddr = (struct sockaddr_in6*) addr;
            if (IN6_IS_ADDR_LOOPBACK (&inaddr->sin6_addr)) {
               return true; /* Bug, FIXME: check for 127.0.0.1/8 */
            }
            return false;
        }
        break;
#endif

    default:
        opal_output(0, "unhandled sa_family %d passed to opal_net_islocalhost",
                    addr->sa_family);
        return false;
        break;
    }
}
Example #9
0
/*
 * For IPv4/v6, this is exactly the same as is_loopback for now.
 * The difference is that this returns false for other transports.
 */
int
is_localroot(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;
		return ((sin->sin_addr.s_addr == htonl(INADDR_LOOPBACK)) &&
		    (ntohs(sin->sin_port) < IPPORT_RESERVED));
#ifdef INET6
	case AF_INET6:
		if (!oldstyle_local)
			return 0;
		sin6 = (struct sockaddr_in6 *)addr;
		return ((IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) ||
			 (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) &&
			  sin6->sin6_addr.s6_addr32[3] == htonl(INADDR_LOOPBACK))) &&
		        (ntohs(sin6->sin6_port) < IPV6PORT_RESERVED));
#endif
	default:
		break;
	}

	return 0;
}
Example #10
0
/*
 * Called via isc_radix_walk() to find IP table nodes that are
 * insecure.
 */
static void
is_insecure(isc_prefix_t *prefix, void **data) {
	isc_boolean_t secure;
	int bitlen, family;

	bitlen = prefix->bitlen;
	family = prefix->family;

	/* Negated entries are always secure. */
	secure = * (isc_boolean_t *)data[ISC_IS6(family)];
	if (!secure) {
		return;
	}

	/* If loopback prefix found, return */
	switch (family) {
	case AF_INET:
		if (bitlen == 32 &&
		    htonl(prefix->add.sin.s_addr) == INADDR_LOOPBACK)
			return;
		break;
	case AF_INET6:
		if (bitlen == 128 && IN6_IS_ADDR_LOOPBACK(&prefix->add.sin6))
			return;
		break;
	default:
		break;
	}

	/* Non-negated, non-loopback */
	insecure_prefix_found = ISC_TRUE;	/* LOCKED */
	return;
}
Example #11
0
static int
__ni_rtevent_process_rdnss_info(ni_netdev_t *dev, const struct nd_opt_hdr *opt,
				size_t len)
{
	const struct ni_nd_opt_rdnss_info_p *ropt;
	char buf[INET6_ADDRSTRLEN+1] = {'\0'};
	const struct in6_addr* addr;
	ni_ipv6_devinfo_t *ipv6;
	unsigned int lifetime;
	struct timeval acquired;
	ni_bool_t emit = FALSE;
	const char *server;

	if (opt == NULL || len < (sizeof(*ropt) + sizeof(*addr))) {
		ni_error("%s: unable to parse ipv6 rdnss info event data -- too short",
				dev->name);
		return -1;
	}

	ipv6 = ni_netdev_get_ipv6(dev);
	if (!ipv6) {
		ni_error("%s: unable to allocate device ipv6 structure: %m",
				dev->name);
		return -1;
	}

	ropt = (const struct ni_nd_opt_rdnss_info_p *)opt;

	ni_timer_get_time(&acquired);
	lifetime = ntohl(ropt->nd_opt_rdnss_lifetime);
	len -= sizeof(*ropt);
	addr = &ropt->nd_opt_rdnss_addr[0];
	for ( ; len >= sizeof(*addr); len -= sizeof(*addr), ++addr) {
		if (IN6_IS_ADDR_LOOPBACK(addr) || IN6_IS_ADDR_UNSPECIFIED(addr)) {
			server = inet_ntop(AF_INET6, addr, buf, sizeof(buf));
			ni_debug_verbose(NI_LOG_DEBUG2, NI_TRACE_IPV6|NI_TRACE_EVENTS,
					"%s: ignoring invalid rdnss server address %s",
					dev->name, server);
			continue;
		}

		if (!ni_ipv6_ra_rdnss_list_update(&ipv6->radv.rdnss, addr,
					lifetime, &acquired)) {
			server = inet_ntop(AF_INET6, addr, buf, sizeof(buf));
			ni_debug_verbose(NI_LOG_DEBUG, NI_TRACE_IPV6|NI_TRACE_EVENTS,
					"%s: failed to track ipv6 rnssl server %s",
					dev->name, server);
			continue;
		}

		emit = TRUE;
	}

	if (emit)
		__ni_netdev_nduseropt_event(dev, NI_EVENT_RDNSS_UPDATE);
	return 0;
}
Example #12
0
bool condor_sockaddr::is_loopback() const
{
	if (is_ipv4()) {
    	return ((v4.sin_addr.s_addr & 0xFF) == 0x7F); // 127/8
	}
	else {
		return IN6_IS_ADDR_LOOPBACK( &v6.sin6_addr );
	}
}
Example #13
0
bool sockaddr_isAddrLoopBack(const struct sockaddr * sa)
{
    if (sa->sa_family == AF_INET) {
        return ( ((struct sockaddr_in*)sa)->sin_addr.s_addr == htonl(INADDR_LOOPBACK) );
    }else if (sa->sa_family == AF_INET6) {
        return IN6_IS_ADDR_LOOPBACK(&((struct sockaddr_in6*)sa)->sin6_addr);
    }
    return false;
}
Example #14
0
bool SocketAddress::isLoopback(void) const
{
	if (AF_INET6 == data_.base_.sa_family)
	{
		return IN6_IS_ADDR_LOOPBACK(&data_.in6_.sin6_addr);
	}
	return ((ntohl(data_.in4_.sin_addr.s_addr) & 0XFF000000)
			== (INADDR_LOOPBACK & 0XFF000000));
}
Example #15
0
static Xauth *get_authptr(struct sockaddr *sockname, int display)
{
    char *addr = 0;
    int addrlen = 0;
    unsigned short family;
    char hostnamebuf[256];   /* big enough for max hostname */
    char dispbuf[40];   /* big enough to hold more than 2^64 base 10 */
    int dispbuflen;

    family = FamilyLocal; /* 256 */
    switch(sockname->sa_family)
    {
#ifdef AF_INET6
    case AF_INET6:
        addr = (char *) SIN6_ADDR(sockname);
        addrlen = sizeof(*SIN6_ADDR(sockname));
        if(!IN6_IS_ADDR_V4MAPPED(SIN6_ADDR(sockname)))
        {
            if(!IN6_IS_ADDR_LOOPBACK(SIN6_ADDR(sockname)))
                family = XCB_FAMILY_INTERNET_6;
            break;
        }
        addr += 12;
        /* if v4-mapped, fall through. */
#endif
    case AF_INET:
        if(!addr)
            addr = (char *) &((struct sockaddr_in *)sockname)->sin_addr;
        addrlen = sizeof(((struct sockaddr_in *)sockname)->sin_addr);
        if(*(in_addr_t *) addr != htonl(INADDR_LOOPBACK))
            family = XCB_FAMILY_INTERNET;
        break;
    case AF_UNIX:
        break;
    default:
        return 0;   /* cannot authenticate this family */
    }

    dispbuflen = snprintf(dispbuf, sizeof(dispbuf), "%d", display);
    if(dispbuflen < 0)
        return 0;
    /* snprintf may have truncate our text */
    dispbuflen = MIN(dispbuflen, sizeof(dispbuf) - 1);

    if (family == FamilyLocal) {
        if (gethostname(hostnamebuf, sizeof(hostnamebuf)) == -1)
            return 0;   /* do not know own hostname */
        addr = hostnamebuf;
        addrlen = strlen(addr);
    }

    return XauGetBestAuthByAddr (family,
                                 (unsigned short) addrlen, addr,
                                 (unsigned short) dispbuflen, dispbuf,
                                 N_AUTH_PROTOS, authnames, authnameslen);
}
Example #16
0
enum ip_addr_type get_ipv6_addr_type(const struct sockaddr_in6 *ip)
{
    if (IN6_IS_ADDR_LOOPBACK(ip)) {
        return ADDR_TYPE_IPV6_LOOPBACK;
    } else if (IN6_IS_ADDR_SITELOCAL(ip)) {
        return ADDR_TYPE_IPV6_SITE_LOCAL;
    } else {
        return ADDR_TYPE_IPV6_OTHER;
    }
}
Example #17
0
/*
 * Search a interface address list (returned from getifaddrs(3)) for an
 * address that matches the desired address family on the specified interface.
 * Returns 0 and fills in *resultp and *rlenp on success. Returns -1 on failure.
 */
static int
check_ifaddrs(const char *ifname, int af, const struct ifaddrs *ifaddrs,
    struct sockaddr_storage *resultp, socklen_t *rlenp)
{
	struct sockaddr_in6 *sa6;
	struct sockaddr_in *sa;
	struct in6_addr *v6addr;
	const struct ifaddrs *ifa;
	int allow_local;

	/*
	 * Prefer addresses that are not loopback or linklocal, but use them
	 * if nothing else matches.
	 */
	for (allow_local = 0; allow_local < 2; allow_local++) {
		for (ifa = ifaddrs; ifa != NULL; ifa = ifa->ifa_next) {
			if (ifa->ifa_addr == NULL || ifa->ifa_name == NULL ||
			    (ifa->ifa_flags & IFF_UP) == 0 ||
			    ifa->ifa_addr->sa_family != af ||
			    strcmp(ifa->ifa_name, options.bind_interface) != 0)
				continue;
			switch (ifa->ifa_addr->sa_family) {
			case AF_INET:
				sa = (struct sockaddr_in *)ifa->ifa_addr;
				if (!allow_local && sa->sin_addr.s_addr ==
				    htonl(INADDR_LOOPBACK))
					continue;
				if (*rlenp < sizeof(struct sockaddr_in)) {
					error("%s: v4 addr doesn't fit",
					    __func__);
					return -1;
				}
				*rlenp = sizeof(struct sockaddr_in);
				memcpy(resultp, sa, *rlenp);
				return 0;
			case AF_INET6:
				sa6 = (struct sockaddr_in6 *)ifa->ifa_addr;
				v6addr = &sa6->sin6_addr;
				if (!allow_local &&
				    (IN6_IS_ADDR_LINKLOCAL(v6addr) ||
				    IN6_IS_ADDR_LOOPBACK(v6addr)))
					continue;
				if (*rlenp < sizeof(struct sockaddr_in6)) {
					error("%s: v6 addr doesn't fit",
					    __func__);
					return -1;
				}
				*rlenp = sizeof(struct sockaddr_in6);
				memcpy(resultp, sa6, *rlenp);
				return 0;
			}
		}
	}
	return -1;
}
char *
GSI_SOCKET_get_peer_hostname(GSI_SOCKET *self)
{
    struct sockaddr_storage addr;
    socklen_t			addr_len = sizeof(addr);
    char host			[NI_MAXHOST];
    int					loopback=0;

    if (getpeername(self->sock, (struct sockaddr *) &addr,
		    &addr_len) < 0) {
        self->error_number = errno;
        GSI_SOCKET_set_error_string(self, "Could not get peer address");
        return NULL;
    }

    if (getnameinfo((struct sockaddr *) &addr, addr_len,
                    host, sizeof(host),
                    NULL, 0, NI_NAMEREQD)) {
        self->error_number = errno;
        GSI_SOCKET_set_error_string(self, "Could not get peer hostname");
        return NULL;
    }

    /* check for localhost / loopback */
    if (addr.ss_family == AF_INET) {
        struct sockaddr_in sadder;

        memcpy(&sadder, &addr, sizeof(sadder));
        if (ntohl(sadder.sin_addr.s_addr) == INADDR_LOOPBACK) {
            loopback = 1;
        }
    }
#ifdef AF_INET6
    else if (addr.ss_family == AF_INET6) {
        struct sockaddr_in6 saddr6;

        memcpy(&saddr6, &addr, sizeof(saddr6));
        if (IN6_IS_ADDR_LOOPBACK(&saddr6.sin6_addr)) {
            loopback = 1;
        }
    }
#endif

    if (loopback) {
        char buf[MAXHOSTNAMELEN];
        if (gethostname(buf, sizeof(buf)) < 0) {
            self->error_number = errno;
            GSI_SOCKET_set_error_string(self, "gethostname() failed");
            return NULL;
        }
        return strdup(buf);
    }

    return strdup(host);
}
Example #19
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;

        /* RFC 6598: 100.64.0.0 to 100.127.255.255 (100.64.0.0/10)
         * (shared address space to stack another layer of NAT) */
        if ((ip4.uint8[0] == 100) && ((ip4.uint8[1] & 0xC0) == 0x40))
            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);
        }

        /* localhost in IPv6 (::1) */
        if (IN6_IS_ADDR_LOOPBACK(&ip.ip6.in6_addr))
            return 0;
    }

    return -1;
}
Example #20
0
/*
 * Determine the appropriate scope zone ID for in6 and ifp.  If ret_id is
 * non NULL, it is set to the zone ID.  If the zone ID needs to be embedded
 * in the in6_addr structure, in6 will be modified. 
 */
int
in6_setscope(struct in6_addr *in6, const struct ifnet *ifp, uint32_t *ret_id)
{
	int scope;
	uint32_t zoneid = 0;
	const struct scope6_id *sid = SID(ifp);

	if (sid == NULL)
		return EINVAL;

	/*
	 * special case: the loopback address can only belong to a loopback
	 * interface.
	 */
	if (IN6_IS_ADDR_LOOPBACK(in6)) {
		if (!(ifp->if_flags & IFF_LOOPBACK))
			return (EINVAL);
		else {
			if (ret_id != NULL)
				*ret_id = 0; /* there's no ambiguity */
			return (0);
		}
	}

	scope = in6_addrscope(in6);

	switch (scope) {
	case IPV6_ADDR_SCOPE_INTFACELOCAL: /* should be interface index */
		zoneid = sid->s6id_list[IPV6_ADDR_SCOPE_INTFACELOCAL];
		break;

	case IPV6_ADDR_SCOPE_LINKLOCAL:
		zoneid = sid->s6id_list[IPV6_ADDR_SCOPE_LINKLOCAL];
		break;

	case IPV6_ADDR_SCOPE_SITELOCAL:
		zoneid = sid->s6id_list[IPV6_ADDR_SCOPE_SITELOCAL];
		break;

	case IPV6_ADDR_SCOPE_ORGLOCAL:
		zoneid = sid->s6id_list[IPV6_ADDR_SCOPE_ORGLOCAL];
		break;

	default:
		zoneid = 0;	/* XXX: treat as global. */
		break;
	}

	if (ret_id != NULL)
		*ret_id = zoneid;

	return in6_setzoneid(in6, zoneid);
}
Example #21
0
u_int32_t
scope6_addr2default(struct in6_addr *addr)
{

	/*
	 * special case: The loopback address should be considered as
	 * link-local, but there's no ambiguity in the syntax.
	 */
	if (IN6_IS_ADDR_LOOPBACK(addr))
		return (0);

	return (sid_default.s6id_list[in6_addrscope(addr)]);
}
Example #22
0
 // Constructs an address corresponding to 'ss' that's compatible with 'fd'.
 CompatibleSocketAddress(int fd, const sockaddr_storage& ss, bool mapUnspecified) {
     const int desiredFamily = getSocketAddressFamily(fd);
     if (ss.ss_family == AF_INET6) {
         if (desiredFamily == AF_INET6) {
             // Nothing to do.
             mCompatibleAddress = reinterpret_cast<const sockaddr*>(&ss);
         } else {
             sockaddr_in* sin = reinterpret_cast<sockaddr_in*>(&mTmp);
             const sockaddr_in6* sin6 = reinterpret_cast<const sockaddr_in6*>(&ss);
             memset(sin, 0, sizeof(*sin));
             sin->sin_family = AF_INET;
             sin->sin_port = sin6->sin6_port;
             if (IN6_IS_ADDR_V4COMPAT(&sin6->sin6_addr)) {
                 // We have an IPv6-mapped IPv4 address, but need plain old IPv4.
                 // Unmap the mapped address in ss into an IPv6 address in mTmp.
                 memcpy(&sin->sin_addr.s_addr, &sin6->sin6_addr.s6_addr[12], 4);
                 mCompatibleAddress = reinterpret_cast<const sockaddr*>(&mTmp);
             } else if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr)) {
                 // Translate the IPv6 loopback address to the IPv4 one.
                 sin->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
                 mCompatibleAddress = reinterpret_cast<const sockaddr*>(&mTmp);
             } else {
                 // We can't help you. We return what you gave us, and assume you'll
                 // get a sensible error when you use the address.
                 mCompatibleAddress = reinterpret_cast<const sockaddr*>(&ss);
             }
         }
     } else /* ss.ss_family == AF_INET */ {
         if (desiredFamily == AF_INET) {
             // Nothing to do.
             mCompatibleAddress = reinterpret_cast<const sockaddr*>(&ss);
         } else {
             // We have IPv4 and need IPv6.
             // Map the IPv4 address in ss into an IPv6 address in mTmp.
             const sockaddr_in* sin = reinterpret_cast<const sockaddr_in*>(&ss);
             sockaddr_in6* sin6 = reinterpret_cast<sockaddr_in6*>(&mTmp);
             memset(sin6, 0, sizeof(*sin6));
             sin6->sin6_family = AF_INET6;
             sin6->sin6_port = sin->sin_port;
             // TODO: mapUnspecified was introduced because kernels < 2.6.31 don't allow
             // you to bind to ::ffff:0.0.0.0. When we move to something >= 2.6.31, we
             // should make the code behave as if mapUnspecified were always true, and
             // remove the parameter.
             if (sin->sin_addr.s_addr != 0 || mapUnspecified) {
                 memset(&(sin6->sin6_addr.s6_addr[10]), 0xff, 2);
             }
             memcpy(&sin6->sin6_addr.s6_addr[12], &sin->sin_addr.s_addr, 4);
             mCompatibleAddress = reinterpret_cast<const sockaddr*>(&mTmp);
         }
     }
 }
Example #23
0
bool
IpAddr::isLoopback() const
{
    switch (addr.addr.sa_family) {
    case AF_INET: {
        uint8_t b1 = (uint8_t)(addr.ipv4.sin_addr.s_addr >> 24);
        return b1 == 127;
    }
    case AF_INET6:
        return IN6_IS_ADDR_LOOPBACK(reinterpret_cast<const in6_addr*>(&addr.ipv6.sin6_addr));
    default:
        return false;
    }
}
Example #24
0
static int
sockaddr_is_local(struct sockaddr *hostaddr)
{
	switch (hostaddr->sa_family) {
	case AF_INET:
		return (ntohl(((struct sockaddr_in *)hostaddr)->
		    sin_addr.s_addr) >> 24) == IN_LOOPBACKNET;
	case AF_INET6:
		return IN6_IS_ADDR_LOOPBACK(
		    &(((struct sockaddr_in6 *)hostaddr)->sin6_addr));
	default:
		return 0;
	}
}
Example #25
0
/**
 * Check if a struct sockaddr is the loopback address.
 */
bool is_loopback_addr(const struct sockaddr *pss)
{
#if defined(HAVE_IPV6)
	if (pss->sa_family == AF_INET6) {
		const struct in6_addr *pin6 =
			&((const struct sockaddr_in6 *)pss)->sin6_addr;
		return IN6_IS_ADDR_LOOPBACK(pin6);
	}
#endif
	if (pss->sa_family == AF_INET) {
		const struct in_addr *pin = &((const struct sockaddr_in *)pss)->sin_addr;
		return is_loopback_ip_v4(*pin);
	}
	return false;
}
Example #26
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;
}
Example #27
0
bool IPAddress::IsLoopback() const
{
  if (family == IPFamily::IPv4)
  {
    return data.in4.s_addr == htonl(INADDR_LOOPBACK);
  }
  else
  if (IsMappedv4())
  {
    return ToUnmappedv4().IsLoopback();
  }
  else
  {
    return IN6_IS_ADDR_LOOPBACK(&data.in6);
  }
}
Example #28
0
static int
is_loopback_address(struct sockaddr *sa)
{
    switch (sa->sa_family) {
    case AF_INET: {
        struct sockaddr_in *s4 = sa2sin(sa);
        return s4->sin_addr.s_addr == htonl(INADDR_LOOPBACK);
    }
    case AF_INET6: {
        struct sockaddr_in6 *s6 = sa2sin6(sa);
        return IN6_IS_ADDR_LOOPBACK(&s6->sin6_addr);
    }
    default:
        return 0;
    }
}
Example #29
0
static isc_boolean_t
is_loopback(dns_aclipprefix_t *p) {
	switch (p->address.family) {
	case AF_INET:
		if (p->prefixlen == 32 &&
		    htonl(p->address.type.in.s_addr) == INADDR_LOOPBACK)
			return (ISC_TRUE);
		break;
	case AF_INET6:
		if (p->prefixlen == 128 &&
		    IN6_IS_ADDR_LOOPBACK(&p->address.type.in6))
			return (ISC_TRUE);
		break;
	default:
		break;
	}
	return (ISC_FALSE);
}
Example #30
0
/** Determines if the specified address is on the local host.
 *
 * @param[in] addr - The address to be checked.
 *
 * @return A boolean value; True (1) if @p addr is a local host
 *    address, or False (0) if not.
 */
int SLPNetIsLocal(const void * addr)
{
   const struct sockaddr * a = (const struct sockaddr *)addr;

   if (a->sa_family == AF_INET)
   {
      struct sockaddr_in * v4 = (struct sockaddr_in *)addr;
      if ((ntohl(v4->sin_addr.s_addr) & 0xff000000) == 0x7f000000)
         return 1;
      return 0;
   }
   if (a->sa_family == AF_INET6)
   {
      struct sockaddr_in6 * v6 = (struct sockaddr_in6 *)addr;
      return IN6_IS_ADDR_LOOPBACK(&v6->sin6_addr);
   }
   return 0;
}