コード例 #1
0
ファイル: slp_net.c プロジェクト: Distrotech/openslp
/** Determines the IPv6 scope of a specified address.
 *
 * @param[in] v6Addr - The IPv6 address to be checked.
 *
 * @return The ipv6 scope of the address.
 *
 * @remarks The @p v6Addr parameter must be pointer to a 16-byte IPv6 
 *    address in binary form.
 * 
 * @internal
 */
static int setScopeFromAddress(const struct in6_addr * v6Addr)
{
   if (IN6_IS_ADDR_MULTICAST(v6Addr))
   {
      if (IN6_IS_ADDR_MC_GLOBAL(v6Addr))
         return SLP_SCOPE_GLOBAL;

      if (IN6_IS_ADDR_MC_ORGLOCAL(v6Addr))
         return SLP_SCOPE_ORG_LOCAL;

      if (IN6_IS_ADDR_MC_SITELOCAL(v6Addr))
         return SLP_SCOPE_SITE_LOCAL;

      if (IN6_IS_ADDR_MC_NODELOCAL(v6Addr))
         return SLP_SCOPE_NODE_LOCAL;

      if (IN6_IS_ADDR_MC_LINKLOCAL(v6Addr))
         return SLP_SCOPE_LINK_LOCAL;
   }
   if (IN6_IS_ADDR_SITELOCAL(v6Addr))
      return SLP_SCOPE_SITE_LOCAL;

   if (SLP_IN6_IS_ADDR_LOOPBACK(v6Addr))
      return SLP_SCOPE_NODE_LOCAL;

   if (IN6_IS_ADDR_LINKLOCAL(v6Addr))
      return SLP_SCOPE_LINK_LOCAL;

   return 0;
}
コード例 #2
0
ファイル: NetworkAddress.cpp プロジェクト: looncraz/haiku
bool
BNetworkAddress::IsMulticastNodeLocal() const
{
	switch (fAddress.ss_family) {
		case AF_INET6:
			return IN6_IS_ADDR_MC_NODELOCAL(
				&((sockaddr_in6&)fAddress).sin6_addr);

		default:
			return false;
	}
}
コード例 #3
0
ファイル: mld_router.cpp プロジェクト: Distrotech/mrd6
void mld_interface::handle_mldv1_membership_reduction(const in6_addr &src,
						      mldv1 *mldhdr) {
	m_stats.counter(ReductionCount, RX)++;
	mld->stats().counter(ReductionCount, RX)++;

	if (!IN6_IS_ADDR_MULTICAST(&mldhdr->mcaddr)) {
		m_stats.counter(ReductionCount, Bad)++;
		mld->stats().counter(ReductionCount, Bad)++;
		return;
	}

	if (IN6_IS_ADDR_MC_NODELOCAL(&mldhdr->mcaddr)
	    || IN6_IS_ADDR_MC_LINKLOCAL(&mldhdr->mcaddr))
		return;

	handle_mode_change_for_group(1, src, mldhdr->mcaddr,
				     MLD_SSM_CHANGE_TO_INCLUDE, address_set());
}
コード例 #4
0
ファイル: mld_router.cpp プロジェクト: Distrotech/mrd6
void mld_interface::handle_mldv2_membership_report(const in6_addr &src,
						   mldv2_report *mldhdr,
						   int len) {
	m_stats.counter(ReportV2Count, RX)++;
	mld->stats().counter(ReportV2Count, RX)++;

	mldv2_mrec *mrec = mldhdr->mrecs();
	int clen = 0;

	int reccount = ntoh(mldhdr->nmrecs());

	for (int i = 0; i < reccount && clen < len; i++, mrec = mrec->next()) {
		clen += sizeof(mldv2_mrec);
		if (clen <= len)
			clen += sizeof(in6_addr) * ntoh(mrec->nsrcs);
	}

	if (clen > len) {
		if (should_log(MESSAGE_ERR))
			log().writeline("Dropped badly formed MLDv2 Membership");

		m_stats.counter(ReportV2Count, Bad)++;
		mld->stats().counter(ReportV2Count, Bad)++;
		return;
	}

	mrec = mldhdr->mrecs();
	for (int i = 0; i < reccount; i++, mrec = mrec->next()) {
		if (!IN6_IS_ADDR_MULTICAST(&mrec->mca) ||
		     IN6_IS_ADDR_MC_NODELOCAL(&mrec->mca) ||
		     IN6_IS_ADDR_MC_LINKLOCAL(&mrec->mca))
			continue;

		address_set sources;
		in6_addr *srcs = mrec->sources();
		for (uint16_t j = 0; j < ntoh(mrec->nsrcs); j++)
			sources += srcs[j];

		handle_mode_change_for_group(2, src, mrec->mca, mrec->type, sources);
	}
}
コード例 #5
0
ファイル: getnameinfo_async.c プロジェクト: bocal/libasr
/*
 * Write the numeric address
 */
static int
_numerichost(struct asr_query *as)
{
	unsigned int	ifidx;
	char		scope[IF_NAMESIZE + 1], *ifname;
	void		*addr;
	char		*buf = as->as.ni.hostname;
	size_t		 buflen = as->as.ni.hostnamelen;

	if (as->as.ni.sa.sa.sa_family == AF_INET)
		addr = &as->as.ni.sa.sain.sin_addr;
	else
		addr = &as->as.ni.sa.sain6.sin6_addr;

	if (inet_ntop(as->as.ni.sa.sa.sa_family, addr, buf, buflen) == NULL)
		return (-1); /* errno set */

	if (as->as.ni.sa.sa.sa_family == AF_INET6 &&
	    as->as.ni.sa.sain6.sin6_scope_id) {

		scope[0] = SCOPE_DELIMITER;
		scope[1] = '\0';

		ifidx = as->as.ni.sa.sain6.sin6_scope_id;
		ifname = NULL;

		if (IN6_IS_ADDR_LINKLOCAL(&as->as.ni.sa.sain6.sin6_addr) ||
		    IN6_IS_ADDR_MC_LINKLOCAL(&as->as.ni.sa.sain6.sin6_addr) ||
		    IN6_IS_ADDR_MC_NODELOCAL(&as->as.ni.sa.sain6.sin6_addr))
			ifname = if_indextoname(ifidx, scope + 1);

		if (ifname == NULL)
			snprintf(scope + 1, sizeof(scope) - 1, "%u", ifidx);

		strlcat(buf, scope, buflen);
	}

	return (0);
}
コード例 #6
0
ファイル: route.c プロジェクト: MarginC/kame
static const char *
fmt_sockaddr(struct sockaddr *sa, struct sockaddr *mask, int flags)
{
	static char workbuf[128];
	const char *cp;

	switch(sa->sa_family) {
	case AF_INET:
	    {
		struct sockaddr_in *sockin = (struct sockaddr_in *)sa;

		if ((sockin->sin_addr.s_addr == INADDR_ANY) &&
			mask &&
			ntohl(((struct sockaddr_in *)mask)->sin_addr.s_addr)
				==0L)
				cp = "default" ;
		else if (flags & RTF_HOST)
			cp = routename(sockin->sin_addr.s_addr);
		else if (mask)
			cp = netname(sockin->sin_addr.s_addr,
				     ntohl(((struct sockaddr_in *)mask)
					   ->sin_addr.s_addr));
		else
			cp = netname(sockin->sin_addr.s_addr, 0L);
		break;
	    }

#ifdef INET6
	case AF_INET6:
	    {
		struct sockaddr_in6 *sa6 = (struct sockaddr_in6 *)sa;
		struct in6_addr *in6 = &sa6->sin6_addr;

		/*
		 * XXX: This is a special workaround for KAME kernels.
		 * sin6_scope_id field of SA should be set in the future.
		 */
		if (IN6_IS_ADDR_LINKLOCAL(in6) ||
		    IN6_IS_ADDR_MC_LINKLOCAL(in6) ||
		    IN6_IS_ADDR_MC_NODELOCAL(in6)) {
		    /* XXX: override is ok? */
		    sa6->sin6_scope_id = (u_int32_t)ntohs(*(u_short *)&in6->s6_addr[2]);
		    *(u_short *)&in6->s6_addr[2] = 0;
		}

		if (flags & RTF_HOST)
		    cp = routename6(sa6);
		else if (mask)
		    cp = netname6(sa6,
				  &((struct sockaddr_in6 *)mask)->sin6_addr);
		else {
		    cp = netname6(sa6, NULL);
		}
		break;
	    }
#endif /*INET6*/

	case AF_IPX:
	    {
		struct ipx_addr work = ((struct sockaddr_ipx *)sa)->sipx_addr;
		if (ipx_nullnet(satoipx_addr(work)))
			cp = "default";
		else
			cp = ipx_print(sa);
		break;
	    }
	case AF_APPLETALK:
	    {
		if (!(flags & RTF_HOST) && mask)
			cp = atalk_print2(sa,mask,9);
		else
			cp = atalk_print(sa,11);
		break;
	    }
	case AF_NETGRAPH:
	    {
		printf("%s", ((struct sockaddr_ng *)sa)->sg_data);
		break;
	    }

	case AF_LINK:
	    {
		struct sockaddr_dl *sdl = (struct sockaddr_dl *)sa;

		if (sdl->sdl_nlen == 0 && sdl->sdl_alen == 0 &&
		    sdl->sdl_slen == 0) {
			(void) sprintf(workbuf, "link#%d", sdl->sdl_index);
			cp = workbuf;
		} else
			switch (sdl->sdl_type) {

			case IFT_ETHER:
			case IFT_L2VLAN:
				if (sdl->sdl_alen == ETHER_ADDR_LEN) {
					cp = ether_ntoa((struct ether_addr *)
					    (sdl->sdl_data + sdl->sdl_nlen));
					break;
				}
				/* FALLTHROUGH */
			default:
				cp = link_ntoa(sdl);
				break;
			}
		break;
	    }

	default:
	    {
		u_char *s = (u_char *)sa->sa_data, *slim;
		char *cq, *cqlim;

		cq = workbuf;
		slim =  sa->sa_len + (u_char *) sa;
		cqlim = cq + sizeof(workbuf) - 6;
		cq += sprintf(cq, "(%d)", sa->sa_family);
		while (s < slim && cq < cqlim) {
			cq += sprintf(cq, " %02x", *s++);
			if (s < slim)
			    cq += sprintf(cq, "%02x", *s++);
		}
		cp = workbuf;
	    }
	}

	return (cp);
}
コード例 #7
0
ファイル: input.c プロジェクト: kimel/improxy
static int imp_verify_multicast_addr(pi_addr *p_pia)
{

    if(p_pia->ss.ss_family == AF_INET6) {

        if (!IN6_IS_ADDR_MULTICAST(p_pia->v6.sin6_addr.s6_addr)) {

            IMP_LOG_ERROR("Address %s isn't multicast address\n",
                           imp_pi_ntoa(p_pia));
            return -1;
        }
        /* Interface-Local scope spans only a single interface on a node
         * and is useful only for loopback transmission of multicast.
         *
         * Link-Local multicast scope spans the same topological region as
         * the corresponding unicast scope.
         * [RFC 4291 section 2.7]
         */

        if (IN6_IS_ADDR_MC_LINKLOCAL(p_pia->v6.sin6_addr.s6_addr) ||
            IN6_IS_ADDR_MC_NODELOCAL(p_pia->v6.sin6_addr.s6_addr)) {

            IMP_LOG_WARNING("Group address %s is link-local multicast address\n",
                           imp_pi_ntoa(p_pia));
            return -1;
        }
        /*
         * Nodes must not originate a packet to a multicast address whose scop
         * field contains the reserved value 0; if such a packet is received, it
         * must be silently dropped.  Nodes should not originate a packet to a
         * multicast address whose scop field contains the reserved value F; if
         * such a packet is sent or received, it must be treated the same as
         * packets destined to a global (scop E) multicast address.
         * [RFC 4291 section 2.7]
         */
         if ((p_pia->v6.sin6_addr.s6_addr[1] & 0x0f) == 0) {

            IMP_LOG_WARNING("group address %s's scope is 0, Ignore it.\n",
                             imp_pi_ntoa(p_pia));
            return -1;
        }
    } else if(p_pia->ss.ss_family == AF_INET) {

        if (!IN_MULTICAST(p_pia->v4.sin_addr.s_addr)) {

            IMP_LOG_ERROR("group address %s isn't multicast adddress\n",
                          imp_pi_ntoa(p_pia));
            return -1;
        }

        /*
         *    Address Range                 Size       Designation
         *    -------------                 ----       -----------
         *    224.0.0.0 - 224.0.0.255       (/24)      Local Network Control Block
         *
         *    Addresses in the Local Network Control Block are used for protocol
         *    control traffic that is not forwarded off link.
         *    [RFC 5771 section 4]
         */
        if (IN_LOCAL_CONTROL_BLOCK(p_pia->v4.sin_addr.s_addr)) {

            IMP_LOG_INFO("Group address %s is Local Network Control Block\n",
                          imp_pi_ntoa(p_pia));
            return -1;
        }

	/* 239.255.0.0/16 is defined to be the IPv4 Local Scope.
	 * [RFC 2365 section 6.1]
	 */

        if (IN_LOCAL_SCOPE_BLOCK(p_pia->v4.sin_addr.s_addr)) {

            IMP_LOG_INFO("Group address %s belongs to IPv4 Local Scope.\n",
                          imp_pi_ntoa(p_pia));
            return -1;
        }


    }else
        return -1;

    return 0;
}
コード例 #8
0
ファイル: si_getaddrinfo.c プロジェクト: apportable/lookup
/*
 * getnameinfo
 *
 * We handle some "trival" cases locally.  If the caller passes
 * NI_NUMERICHOST (only), then this call turns into a getservbyport
 * to get the service name + inet_pton() to create a host string.
 * If the caller passes NI_NUMERICSERV (only), then we zero out the port
 * number, complete the getnameinfo, and use printf() to create a service
 * string.  If the caller specifies both NI_NUMERICHOST and NI_NUMERICSERV,
 * we inet_ntop() and printf() and return the results.
 */
si_item_t *
si_nameinfo(si_mod_t *si, const struct sockaddr *sa, int flags, const char *interface, uint32_t *err)
{
	si_item_t *out = NULL;
	const struct sockaddr *lookup_sa;
	struct sockaddr_in s4;
	struct in_addr a4;
	struct in6_addr a6;
	const uint32_t unused = 0;
	void *addr = NULL;
	char *host = NULL;
	char *serv = NULL;
	uint32_t ifnum = 0;
	uint16_t port = 0;

	int do_host_lookup = ((flags & NI_NUMERICHOST) == 0);
	int do_serv_lookup = ((flags & NI_NUMERICSERV) == 0);

	/* check input */
	if ((si == NULL) || (sa == NULL))
	{
		if (err != NULL) *err = SI_STATUS_EAI_FAIL;
		return NULL;
	}

	if (err != NULL) *err = SI_STATUS_NO_ERROR;

	lookup_sa = sa;

	if (sa->sa_family == AF_INET)
	{
		struct sockaddr_in *s4 = (struct sockaddr_in *)sa;
		memcpy(&a4, &s4->sin_addr, sizeof(a4));
		port = s4->sin_port;
		addr = &a4;
	}
	else if (sa->sa_family == AF_INET6)
	{
		struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)sa;
		memcpy(&a6, &s6->sin6_addr, sizeof(a6));
		port = s6->sin6_port;

		/* Look for scope id in IPv6 Link Local, Multicast Node Local, and Multicast Link Local */
		if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr) || IN6_IS_ADDR_MC_NODELOCAL(&s6->sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&s6->sin6_addr))
		{
			ifnum = ntohs(a6.__u6_addr.__u6_addr16[1]);
			if (ifnum == 0)
			{
				ifnum = s6->sin6_scope_id;
				a6.__u6_addr.__u6_addr16[1] = htons(ifnum);
			}

			if ((ifnum != s6->sin6_scope_id) && (s6->sin6_scope_id != 0))
			{
				if (err != NULL) *err = SI_STATUS_EAI_FAIL;
				return NULL;
			}
		}

		/* v4 mapped and compat addresses are converted to plain v4 */
		if (IN6_IS_ADDR_V4MAPPED(&s6->sin6_addr) || IN6_IS_ADDR_V4COMPAT(&s6->sin6_addr))
		{
			memcpy(&a4, &s6->sin6_addr.s6_addr[12], sizeof(a4));
			addr = &a4;
			memset(&s4, 0, sizeof(s4));
			s4.sin_len = sizeof(s4);
			s4.sin_family = AF_INET;
			s4.sin_port = port;
			memcpy(&s4.sin_addr, &a4, sizeof(s4.sin_addr));
			lookup_sa = (const struct sockaddr *)&s4;
		}
		else
		{
			addr = &a6;
		}
	}
	else
	{
		if (err != NULL) *err = SI_STATUS_EAI_FAMILY;
		return NULL;
	}

	if (do_host_lookup == 1)
	{
		si_item_t *item = si_host_byaddr(si, addr, lookup_sa->sa_family, interface, NULL);
		if (item != NULL)
		{
			struct hostent *h;
			h = (struct hostent *)((uintptr_t)item + sizeof(si_item_t));
			host = strdup(h->h_name);
			si_item_release(item);
			if (host == NULL)
			{
				if (err != NULL) *err = SI_STATUS_EAI_MEMORY;
				return NULL;
			}
		}
	}

	if ((do_serv_lookup == 1) && (port != 0))
	{
		si_item_t *item = si_service_byport(si, port, NULL);
		if (item != NULL)
		{
			struct servent *s;
			s = (struct servent *)((uintptr_t)item + sizeof(si_item_t));
			serv = strdup(s->s_name);
			si_item_release(item);
			if (serv == NULL)
			{
				free(host);
				if (err != NULL) *err = SI_STATUS_EAI_MEMORY;
				return NULL;
			}
		}
	}

	/*
	 * Return numeric host name for NI_NUMERICHOST or if lookup failed, but not
	 * if NI_NAMEREQD is specified (so that we later fail with EAI_NONAME).
	 */
	if ((host == NULL) && ((flags & NI_NAMEREQD) == 0))
	{
		char tmp[INET6_ADDRSTRLEN + 1 + IF_NAMESIZE + 1];
		tmp[0] = '\0';
		if (sa->sa_family == AF_INET)
		{
			char buf[INET_ADDRSTRLEN];
			if (inet_ntop(AF_INET, &a4, buf, sizeof(buf)) != 0)
			{
				host = strdup(buf);
			}
		}
		else if (sa->sa_family == AF_INET6)
		{
			char buf[INET6_ADDRSTRLEN];

			/* zero the embedded scope ID */
			if (ifnum != 0)
			{
				a6.__u6_addr.__u6_addr16[1] = 0;
			}

			if (inet_ntop(AF_INET6, &a6, buf, sizeof(buf)) != 0)
			{
				if (ifnum != 0)
				{
					char ifname[IF_NAMESIZE];
					if (if_indextoname(ifnum, ifname) != NULL)
					{
						asprintf(&host, "%s%%%s", buf, ifname);
					}
					else
					{
						/* ENXIO */
						if (err != NULL) *err = SI_STATUS_EAI_FAIL;
						return NULL;
					}
				}
				else
				{
					host = strdup(buf);
				}
			}
		}
	}

	/* Return numeric service name for NI_NUMERICSERV or if lookup failed. */
	if (serv == NULL)
	{
		asprintf(&serv, "%hu", ntohs(port));
	}

	if ((host == NULL) || (serv == NULL))
	{
		if (err != NULL)
		{
			if ((flags & NI_NAMEREQD) != 0)
			{
				*err = SI_STATUS_EAI_NONAME;
			}
			else
			{
				*err = SI_STATUS_EAI_MEMORY;
			}
		}
	}
	else
	{
		out = (si_item_t *)LI_ils_create("L4444ss", (unsigned long)si, CATEGORY_NAMEINFO, 1, unused, unused, host, serv);
	}

	free(host);
	free(serv);
	return out;
}