Пример #1
0
int
find_ipv6_addr(const char * ifname,
               char * dst, int n)
{
	struct ifaddrs * ifap;
	struct ifaddrs * ife;
	const struct sockaddr_in6 * addr;
	char buf[64];
	int r = 0;

	if(!dst)
		return -1;

	if(getifaddrs(&ifap)<0)
	{
		syslog(LOG_ERR, "getifaddrs: %m");
		return -1;
	}
	for(ife = ifap; ife; ife = ife->ifa_next)
	{
		/* skip other interfaces if one was specified */
		if(ifname && (0 != strcmp(ifname, ife->ifa_name)))
			continue;
		if(ife->ifa_addr == NULL)
			continue;
		if(ife->ifa_addr->sa_family == AF_INET6)
		{
			addr = (const struct sockaddr_in6 *)ife->ifa_addr;
			if(!IN6_IS_ADDR_LOOPBACK(&addr->sin6_addr)
			   && !IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr))
			{
				inet_ntop(ife->ifa_addr->sa_family,
				          &addr->sin6_addr,
				          buf, sizeof(buf));
				/* add brackets */
				snprintf(dst, n, "[%s]", buf);
				r = 1;
			}
		}
	}
	freeifaddrs(ifap);
	return r;
}
Пример #2
0
/* Performs a non-blocking connect().  */
enum connect_result sockunion_connect(int fd, const union sockunion *peersu,
				      unsigned short port, ifindex_t ifindex)
{
	int ret;
	union sockunion su;

	memcpy(&su, peersu, sizeof(union sockunion));

	switch (su.sa.sa_family) {
	case AF_INET:
		su.sin.sin_port = port;
		break;
	case AF_INET6:
		su.sin6.sin6_port = port;
#ifdef KAME
		if (IN6_IS_ADDR_LINKLOCAL(&su.sin6.sin6_addr) && ifindex) {
			su.sin6.sin6_scope_id = ifindex;
			SET_IN6_LINKLOCAL_IFINDEX(su.sin6.sin6_addr, ifindex);
		}
#endif /* KAME */
		break;
	}

	/* Call connect function. */
	ret = connect(fd, (struct sockaddr *)&su, sockunion_sizeof(&su));

	/* Immediate success */
	if (ret == 0)
		return connect_success;

	/* If connect is in progress then return 1 else it's real error. */
	if (ret < 0) {
		if (errno != EINPROGRESS) {
			char str[SU_ADDRSTRLEN];
			zlog_info("can't connect to %s fd %d : %s",
				  sockunion_log(&su, str, sizeof str), fd,
				  safe_strerror(errno));
			return connect_error;
		}
	}

	return connect_in_progress;
}
Пример #3
0
Файл: send.c Проект: corny/fastd
/** Adds packet info to ancillary control messages */
static inline void add_pktinfo(struct msghdr *msg, const fastd_peer_address_t *local_addr) {
#ifdef __ANDROID__
	/* PKTINFO will mess with Android VpnService.protect(socket) */
	if (conf.android_integration)
		return;
#endif
	if (!local_addr)
		return;

	struct cmsghdr *cmsg = (struct cmsghdr *)((char *)msg->msg_control + msg->msg_controllen);

#ifdef USE_PKTINFO
	if (local_addr->sa.sa_family == AF_INET) {
		cmsg->cmsg_level = IPPROTO_IP;
		cmsg->cmsg_type = IP_PKTINFO;
		cmsg->cmsg_len = CMSG_LEN(sizeof(struct in_pktinfo));

		msg->msg_controllen += cmsg->cmsg_len;

		struct in_pktinfo pktinfo = {};
		pktinfo.ipi_spec_dst = local_addr->in.sin_addr;
		memcpy(CMSG_DATA(cmsg), &pktinfo, sizeof(pktinfo));
		return;
	}
#endif

	if (local_addr->sa.sa_family == AF_INET6) {
		cmsg->cmsg_level = IPPROTO_IPV6;
		cmsg->cmsg_type = IPV6_PKTINFO;
		cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));

		msg->msg_controllen += cmsg->cmsg_len;

		struct in6_pktinfo pktinfo = {};
		pktinfo.ipi6_addr = local_addr->in6.sin6_addr;

		if (IN6_IS_ADDR_LINKLOCAL(&local_addr->in6.sin6_addr))
			pktinfo.ipi6_ifindex = local_addr->in6.sin6_scope_id;

		memcpy(CMSG_DATA(cmsg), &pktinfo, sizeof(pktinfo));
	}
}
Пример #4
0
static char *
ip6_addr_to_string (const struct in6_addr *addr, const char *iface)
{
	char *buf, *p;

	/* allocate enough space for the address + interface name */
	buf = g_malloc0 (IP6_ADDR_BUFLEN + 1);

	/* 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, IP6_ADDR_BUFLEN))
			goto error;
		return buf;
	}

	if (!inet_ntop (AF_INET6, addr, buf, IP6_ADDR_BUFLEN))
		goto error;

	/* In the case of addr being a link-local address, inet_ntop can either
	 * return an address with scope identifier already in place (like
	 * fe80::202:b3ff:fe8d:7aaf%wlan0) or it returns an address without
	 * scope identifier at all (like fe80::202:b3ff:fe8d:7aaf)
	 */
	p = strchr (buf, '%');
	if (p) {
		/* If we got a scope identifier, we need to replace the '%'
		 * with '@', since dnsmasq supports '%' in server= addresses
		 * only since version 2.58 and up
		 */
		*p = '@';
	} else if (IN6_IS_ADDR_LINKLOCAL (addr)) {
		/* If we got no scope identifier at all append the interface name */
		strncat (buf, "@", IP6_ADDR_BUFLEN - strlen (buf));
		strncat (buf, iface, IP6_ADDR_BUFLEN - strlen (buf));
	}

	return buf;

error:
	g_free (buf);
	return NULL;
}
Пример #5
0
static int
if_get_ipv6_local (struct interface *ifp, struct in6_addr *addr)
{
  struct listnode *cnode;
  struct connected *connected;
  struct prefix *cp; 
  
  for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, connected))
    {
      cp = connected->address;
	    
      if (cp->family == AF_INET6)
	if (IN6_IS_ADDR_LINKLOCAL (&cp->u.prefix6))
	  {
	    memcpy (addr, &cp->u.prefix6, IPV6_MAX_BYTELEN);
	    return 1;
	  }
    }
  return 0;
}
Пример #6
0
static char *
ip6_addr_to_string (const struct in6_addr *addr, const char *iface)
{
	char buf[NM_UTILS_INET_ADDRSTRLEN];

	if (IN6_IS_ADDR_V4MAPPED (addr))
		nm_utils_inet4_ntop (addr->s6_addr32[3], buf);
	else
		nm_utils_inet6_ntop (addr, buf);

	/* Need to scope link-local addresses with %<zone-id>. Before dnsmasq 2.58,
	 * only '@' was supported as delimiter. Since 2.58, '@' and '%' are
	 * supported. Due to a bug, since 2.73 only '%' works properly as "server"
	 * address.
	 */
	return g_strdup_printf ("%s%c%s",
	                        buf,
	                        IN6_IS_ADDR_LINKLOCAL (addr) ? '%' : '@',
	                        iface);
}
Пример #7
0
Файл: if.c Проект: yellowman/nsh
void
ipv6ll_db_store(struct sockaddr_in6 *sin6, struct sockaddr_in6 *sin6mask,
    int dbflag, char *ifname)
{
	/*
	 * If linklocal, store a version that will match conf output
	 * with no scope id, ifname in separate database field
	 */
	if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) ||
	    IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr) ||
	    IN6_IS_ADDR_MC_INTFACELOCAL(&sin6->sin6_addr)) {
		sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0;
		sin6->sin6_scope_id = 0;
		db_delete_flag_x_ctl_data("ipv6linklocal", ifname,
		    netname6(sin6, sin6mask));
		if (dbflag != DB_X_REMOVE)
			db_insert_flag_x("ipv6linklocal", ifname, 0,
			    dbflag, netname6(sin6, sin6mask));
	}
}
Пример #8
0
static struct in6_addr *
ospf6_interface_get_linklocal_address (struct interface *ifp)
{
  struct listnode *n;
  struct connected *c;
  struct in6_addr *l = (struct in6_addr *) NULL;

  /* for each connected address */
  for (ALL_LIST_ELEMENTS_RO (ifp->connected, n, c))
    {
      /* if family not AF_INET6, ignore */
      if (c->address->family != AF_INET6)
        continue;

      /* linklocal scope check */
      if (IN6_IS_ADDR_LINKLOCAL (&c->address->u.prefix6))
        l = &c->address->u.prefix6;
    }
  return l;
}
Пример #9
0
struct connected *
if_lookup_linklocal (struct interface *ifp)
{
#ifdef HAVE_IPV6
  struct listnode *node;
  struct connected *ifc;

  if (ifp == NULL)
    return NULL;

  for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc))
    {
      if ((ifc->address->family == AF_INET6) &&
          (IN6_IS_ADDR_LINKLOCAL (&ifc->address->u.prefix6)))
        return ifc;
    }
#endif /* HAVE_IPV6 */

  return NULL;
}
Пример #10
0
int sock_send(int fd, char * addr, char * buf, int buflen, int port,int iface)
{	
    ADDRINFO inforemote,*remote;
    char addrStr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")+5];
    char portStr[10];
    int i;
    char packaddr[16];
    char ifaceStr[10];

    memset(addrStr,  0, sizeof(addrStr));
    memset(portStr,  0, sizeof(portStr));
    memset(packaddr, 0, sizeof(packaddr));
    memset(ifaceStr, 0, sizeof(ifaceStr));
    
    strcpy(addrStr,addr);
    itoa(port,portStr,10);
    itoa(iface,ifaceStr,10);
    inet_pton6(addrStr,packaddr);
    
    if(IN6_IS_ADDR_LINKLOCAL((struct in6_addr*)packaddr)
       ||IN6_IS_ADDR_SITELOCAL((struct in6_addr*)packaddr))
	strcat(strcat(addrStr,"%"),ifaceStr);
      
    memset(&inforemote, 0, sizeof(inforemote));
    inforemote.ai_flags=AI_NUMERICHOST;
    inforemote.ai_family=PF_INET6;
    inforemote.ai_socktype=SOCK_DGRAM;
    inforemote.ai_protocol=IPPROTO_IPV6;
    //inet_ntop6(addr,addrStr);
    if(getaddrinfo(addrStr,portStr,&inforemote,&remote))
	return 0;
    i=sendto(fd,buf,buflen,0,remote->ai_addr,remote->ai_addrlen);
	freeaddrinfo(remote);
	if (i==SOCKET_ERROR)
    {
		error_message_set(WSAGetLastError());
        return LOWLEVEL_ERROR_UNSPEC;
    }

    return LOWLEVEL_NO_ERROR;
}
Пример #11
0
int svx_inetaddr_get_ipport(svx_inetaddr_t *self, char *ip, size_t ip_len, uint16_t *port)
{
    size_t len;

    if(NULL == self || ((NULL == ip || ip_len < SVX_INETADDR_STR_IP_LEN) && NULL == port))
        SVX_LOG_ERRNO_RETURN_ERR(SVX_ERRNO_INVAL, "self:%p, ip:%p, ip_len:%zu, port:%p\n", self, ip, ip_len, port);
    
    switch(self->storage.addr.sa_family)
    {
    case AF_INET:
        if(NULL != ip && ip_len >= SVX_INETADDR_STR_IP_LEN)
        {
            memset(ip, 0, ip_len);
            if(NULL == inet_ntop(AF_INET, &(self->storage.addr4.sin_addr), ip, (socklen_t)ip_len))
                SVX_LOG_ERRNO_RETURN_ERR(errno, NULL);
        }
        if(NULL != port) *port = ntohs(self->storage.addr4.sin_port);
        return 0;
    case AF_INET6:
        if(NULL != ip && ip_len >= SVX_INETADDR_STR_IP_LEN)
        {
            memset(ip, 0, ip_len);
            if(NULL == inet_ntop(AF_INET6, &(self->storage.addr6.sin6_addr), ip, (socklen_t)ip_len))
                SVX_LOG_ERRNO_RETURN_ERR(errno, NULL);
            
            /* append IPv6 link-local address interface name */
            if(IN6_IS_ADDR_LINKLOCAL(&(self->storage.addr6.sin6_addr)) || 
               IN6_IS_ADDR_MC_LINKLOCAL(&(self->storage.addr6.sin6_addr)))
            {
                len = strlen(ip);
                ip[len++] = '%';
                if(NULL == if_indextoname(self->storage.addr6.sin6_scope_id, ip + len))
                    SVX_LOG_ERRNO_RETURN_ERR(errno, NULL);
            }
        }
        if(NULL != port) *port = ntohs(self->storage.addr6.sin6_port);
        return 0;
    default:
        SVX_LOG_ERRNO_RETURN_ERR(SVX_ERRNO_NOTSPT, "family:%u\n", self->storage.addr.sa_family);
    }
}
Пример #12
0
/* If nexthop exists on connected network return 1. */
int
bgp_nexthop_onlink (afi_t afi, struct attr *attr)
{
  struct bgp_node *rn;
  
  /* If zebra is not enabled return */
  if (zlookup->sock < 0)
    return 1;
  
  /* Lookup the address is onlink or not. */
  if (afi == AFI_IP)
    {
      rn = bgp_node_match_ipv4 (bgp_connected_table[AFI_IP], &attr->nexthop);
      if (rn)
	{
	  bgp_unlock_node (rn);
	  return 1;
	}
    }
#ifdef HAVE_IPV6
  else if (afi == AFI_IP6)
    {
      if (attr->extra->mp_nexthop_len == 32)
	return 1;
      else if (attr->extra->mp_nexthop_len == 16)
	{
	  if (IN6_IS_ADDR_LINKLOCAL (&attr->extra->mp_nexthop_global))
	    return 1;

	  rn = bgp_node_match_ipv6 (bgp_connected_table[AFI_IP6],
				      &attr->extra->mp_nexthop_global);
	  if (rn)
	    {
	      bgp_unlock_node (rn);
	      return 1;
	    }
	}
    }
#endif /* HAVE_IPV6 */
  return 0;
}
Пример #13
0
static char *
ip6_addr_to_string (const struct in6_addr *addr, const char *iface)
{
	char *buf;

	if (IN6_IS_ADDR_V4MAPPED (addr)) {
		/* inet_ntop is probably supposed to do this for us, but it doesn't */
		buf = g_malloc (INET_ADDRSTRLEN);
		nm_utils_inet4_ntop (addr->s6_addr32[3], buf);
	} else if (!iface || !iface[0] || !IN6_IS_ADDR_LINKLOCAL (addr)) {
		buf = g_malloc (INET6_ADDRSTRLEN);
		nm_utils_inet6_ntop (addr, buf);
	} else {
		/* If we got a scope identifier, we need use '%' instead of
		 * '@', since dnsmasq supports '%' in server= addresses
		 * only since version 2.58 and up
		 */
		buf = g_strconcat (nm_utils_inet6_ntop (addr, NULL), "@", iface, NULL);
	}
	return buf;
}
Пример #14
0
static char *
ip6_addr_to_string (const struct in6_addr *addr, const char *iface)
{
	char *buf;

	if (IN6_IS_ADDR_V4MAPPED (addr)) {
		buf = g_malloc (INET_ADDRSTRLEN);
		nm_utils_inet4_ntop (addr->s6_addr32[3], buf);
	} else if (!iface || !iface[0] || !IN6_IS_ADDR_LINKLOCAL (addr)) {
		buf = g_malloc (INET6_ADDRSTRLEN);
		nm_utils_inet6_ntop (addr, buf);
	} else {
		/* Need to scope the address with %<zone-id>. Before dnsmasq 2.58,
		 * only '@' was supported as delimiter. Since 2.58, '@' and '%'
		 * are supported. Due to a bug, since 2.73 only '%' works properly
		 * as "server" address.
		 */
		buf = g_strconcat (nm_utils_inet6_ntop (addr, NULL), "%", iface, NULL);
	}
	return buf;
}
Пример #15
0
// Forwards a packet on a specific interface
ssize_t relayd_forward_packet(int socket, struct sockaddr_in6 *dest,
		struct iovec *iov, size_t iov_len,
		const struct relayd_interface *iface)
{
	// Construct headers
	uint8_t cmsg_buf[CMSG_SPACE(sizeof(struct in6_pktinfo))] = {0};
	struct msghdr msg = {(void*)dest, sizeof(*dest), iov, iov_len,
				cmsg_buf, sizeof(cmsg_buf), 0};

	// Set control data (define destination interface)
	struct cmsghdr *chdr = CMSG_FIRSTHDR(&msg);
	chdr->cmsg_level = IPPROTO_IPV6;
	chdr->cmsg_type = IPV6_PKTINFO;
	chdr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
	struct in6_pktinfo *pktinfo = (struct in6_pktinfo*)CMSG_DATA(chdr);
	pktinfo->ipi6_ifindex = iface->ifindex;

	// Also set scope ID if link-local
	if (IN6_IS_ADDR_LINKLOCAL(&dest->sin6_addr)
			|| IN6_IS_ADDR_MC_LINKLOCAL(&dest->sin6_addr))
		dest->sin6_scope_id = iface->ifindex;

	// IPV6_PKTINFO doesn't really work for IPv6-raw sockets (bug?)
	if (dest->sin6_port == 0) {
		msg.msg_control = NULL;
		msg.msg_controllen = 0;
	}

	char ipbuf[INET6_ADDRSTRLEN];
	inet_ntop(AF_INET6, &dest->sin6_addr, ipbuf, sizeof(ipbuf));

	ssize_t sent = sendmsg(socket, &msg, MSG_DONTWAIT);
	if (sent < 0)
		syslog(LOG_WARNING, "Failed to relay to %s%%%s (%s)",
				ipbuf, iface->ifname, strerror(errno));
	else
		syslog(LOG_NOTICE, "Relayed %li bytes to %s%%%s",
				(long)sent, ipbuf, iface->ifname);
	return sent;
}
Пример #16
0
int Socket::BindToAddr(const std::string& addr, const std::string& port)
{
    char str[INET6_ADDRSTRLEN];
    bool success = false;

    struct addrinfo *AddrInfo, *AI;

    AddrInfo = toAddrinfo( addr, port, true );

    for ( AI = AddrInfo; AI != NULL; AI = AI->ai_next )
    {
        struct sockaddr_in6 bindAddr;

        toIpv6( AI, &bindAddr );

        if ( ( IN6_IS_ADDR_LINKLOCAL((struct in6_addr *) &bindAddr.sin6_addr) ) &&
             ( bindAddr.sin6_scope_id == 0) )
        {
            log(LOG_WARN) << "IPv6 link local addresses should specify a scope ID!";
        }

        inet_ntop( AF_INET6, &bindAddr.sin6_addr, str, sizeof(str));
        log(LOG_NOTICE) << "attempting bind to \"" << addr << "\" -> ip " << str << " port " << ntohs(bindAddr.sin6_port);

        if ( bind( socket_->fd, (struct sockaddr*) &bindAddr, sizeof(bindAddr) ) < 0 )
        {
            log(LOG_EMERG) << "bind attempt failed with error " << strerror(errno);
        }
        else
        {
            success = true;
            break;
        }
    }

    if ( AddrInfo )
        freeaddrinfo( AddrInfo );

    return success ? 0 : -1;
}
Пример #17
0
const char *getifaddr(char *ifname, int family, int linklocal)
{
	static char buf[INET6_ADDRSTRLEN];
	void *addr = NULL;
	struct ifaddrs *ifap, *ifa;

	if (getifaddrs(&ifap) != 0) {
		_dprintf("getifaddrs failed: %s\n", strerror(errno));
		return NULL;
	}

	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
		if ((ifa->ifa_addr == NULL) ||
		    (strncmp(ifa->ifa_name, ifname, IFNAMSIZ) != 0) ||
		    (ifa->ifa_addr->sa_family != family))
			continue;

#ifdef TCONFIG_IPV6
		if (ifa->ifa_addr->sa_family == AF_INET6) {
			struct sockaddr_in6 *s6 = (struct sockaddr_in6 *)(ifa->ifa_addr);
			if (IN6_IS_ADDR_LINKLOCAL(&s6->sin6_addr) ^ linklocal)
				continue;
			addr = (void *)&(s6->sin6_addr);
		}
		else
#endif
		{
			struct sockaddr_in *s = (struct sockaddr_in *)(ifa->ifa_addr);
			addr = (void *)&(s->sin_addr);
		}

		if ((addr) && inet_ntop(ifa->ifa_addr->sa_family, addr, buf, sizeof(buf)) != NULL) {
			freeifaddrs(ifap);
			return buf;
		}
	}

	freeifaddrs(ifap);
	return NULL;
}
Пример #18
0
static int really_send(int sock, struct in6_addr const *dest, struct properties const *props, struct safe_buffer const *sb)
{
	struct sockaddr_in6 addr;
	memset((void *)&addr, 0, sizeof(addr));
	addr.sin6_family = AF_INET6;
	addr.sin6_port = htons(IPPROTO_ICMPV6);
	memcpy(&addr.sin6_addr, dest, sizeof(struct in6_addr));

	struct iovec iov;
	iov.iov_len = sb->used;
	iov.iov_base = (caddr_t)sb->buffer;

	char __attribute__ ((aligned(8))) chdr[CMSG_SPACE(sizeof(struct in6_pktinfo))];
	memset(chdr, 0, sizeof(chdr));
	struct cmsghdr *cmsg = (struct cmsghdr *)chdr;

	cmsg->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
	cmsg->cmsg_level = IPPROTO_IPV6;
	cmsg->cmsg_type = IPV6_PKTINFO;

	struct in6_pktinfo *pkt_info = (struct in6_pktinfo *)CMSG_DATA(cmsg);
	pkt_info->ipi6_ifindex = props->if_index;
	memcpy(&pkt_info->ipi6_addr, &props->if_addr, sizeof(struct in6_addr));

#ifdef HAVE_SIN6_SCOPE_ID
	if (IN6_IS_ADDR_LINKLOCAL(&addr.sin6_addr) || IN6_IS_ADDR_MC_LINKLOCAL(&addr.sin6_addr))
		addr.sin6_scope_id = props->if_index;
#endif

	struct msghdr mhdr;
	memset(&mhdr, 0, sizeof(mhdr));
	mhdr.msg_name = (caddr_t) & addr;
	mhdr.msg_namelen = sizeof(struct sockaddr_in6);
	mhdr.msg_iov = &iov;
	mhdr.msg_iovlen = 1;
	mhdr.msg_control = (void *)cmsg;
	mhdr.msg_controllen = sizeof(chdr);

	return sendmsg(sock, &mhdr, 0);
}
Пример #19
0
/*
 * Probe if each router in the default router list is still alive. 
 */
void
defrouter_probe(int ifindex)
{
	struct in6_drlist dr;
	int s, i;
	u_char ntopbuf[INET6_ADDRSTRLEN];

	if ((s = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
		warnmsg(LOG_ERR, __FUNCTION__, "socket: %s", strerror(errno));
		return;
	}
	bzero(&dr, sizeof(dr));
	strlcpy(dr.ifname, "lo0", sizeof(dr.ifname)); /* dummy interface */
	if (ioctl(s, SIOCGDRLST_IN6, (caddr_t)&dr) < 0) {
		warnmsg(LOG_ERR, __FUNCTION__, "ioctl(SIOCGDRLST_IN6): %s",
		       strerror(errno));
		goto closeandend;
	}

	for(i = 0; dr.defrouter[i].if_index && i < PRLSTSIZ; i++) {
		if (ifindex && dr.defrouter[i].if_index == ifindex) {
			/* sanity check */
			if (!IN6_IS_ADDR_LINKLOCAL(&dr.defrouter[i].rtaddr)) {
				warnmsg(LOG_ERR, __FUNCTION__,
					"default router list contains a "
					"non-linklocal address(%s)",
				       inet_ntop(AF_INET6,
						 &dr.defrouter[i].rtaddr,
						 (char *)ntopbuf, INET6_ADDRSTRLEN));
				continue; /* ignore the address */
			}
			sendprobe(&dr.defrouter[i].rtaddr,
				  dr.defrouter[i].if_index);
		}
	}

  closeandend:
	close(s);
	return;
}
Пример #20
0
bool is_linklocal_addr(const struct sockaddr_storage *pss)
{
#ifdef HAVE_IPV6
	if (pss->ss_family == AF_INET6) {
		const struct in6_addr *pin6 =
			&((const struct sockaddr_in6 *)pss)->sin6_addr;
		return IN6_IS_ADDR_LINKLOCAL(pin6);
	}
#endif
	if (pss->ss_family == AF_INET) {
		const struct in_addr *pin =
			&((const struct sockaddr_in *)pss)->sin_addr;
		struct in_addr ll_addr;
		struct in_addr mask_addr;

		/* 169.254.0.0/16, is link local, see RFC 3927 */
		ll_addr.s_addr = 0xa9fe0000;
		mask_addr.s_addr = 0xffff0000;
		return same_net_v4(*pin, ll_addr, mask_addr);
	}
	return false;
}
Пример #21
0
/*
 * Process a received prefix option.
 * Unless addrconf is turned off we process both the addrconf and the
 * onlink aspects of the prefix option.
 *
 * Note that when a flag (onlink or auto) is turned off we do nothing -
 * the prefix will time out.
 */
static void
incoming_prefix_opt(struct phyint *pi, uchar_t *opt,
    struct sockaddr_in6 *from, boolean_t loopback)
{
	struct nd_opt_prefix_info *po = (struct nd_opt_prefix_info *)opt;
	boolean_t	good_prefix = _B_TRUE;

	if (8 * po->nd_opt_pi_len != sizeof (*po)) {
		char abuf[INET6_ADDRSTRLEN];

		(void) inet_ntop(AF_INET6, (void *)&from->sin6_addr,
		    abuf, sizeof (abuf));
		logmsg(LOG_INFO, "prefix option from %s on %s wrong size "
		    "(%d bytes)\n",
		    abuf, pi->pi_name,
		    8 * (int)po->nd_opt_pi_len);
		return;
	}
	if (IN6_IS_ADDR_LINKLOCAL(&po->nd_opt_pi_prefix)) {
		char abuf[INET6_ADDRSTRLEN];

		(void) inet_ntop(AF_INET6, (void *)&from->sin6_addr,
		    abuf, sizeof (abuf));
		logmsg(LOG_INFO, "RA from %s on %s contains link-local prefix "
		    "- ignored\n",
		    abuf, pi->pi_name);
		return;
	}
	if ((po->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_AUTO) &&
	    pi->pi_stateless && pi->pi_autoconf) {
		good_prefix = incoming_prefix_addrconf(pi, opt, from, loopback);
	}
	if ((po->nd_opt_pi_flags_reserved & ND_OPT_PI_FLAG_ONLINK) &&
	    good_prefix) {
		incoming_prefix_onlink(pi, opt);
	}
	if (pi->pi_stateful && pi->pi_autoconf)
		incoming_prefix_stateful(pi, opt);
}
Пример #22
0
/*
 * 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);
}
Пример #23
0
static void append_scopeid(struct sockaddr_in6 *addr6, unsigned int flags,
                           char *buf, size_t buflen)
{
#ifdef HAVE_IF_INDEXTONAME
  int is_ll, is_mcll;
#endif
  static const char fmt_u[] = "%u";
  static const char fmt_lu[] = "%lu";
  char tmpbuf[IF_NAMESIZE + 2];
  size_t bufl;
  const char *fmt = (sizeof(addr6->sin6_scope_id) > sizeof(unsigned int))?
    fmt_lu:fmt_u;

  tmpbuf[0] = '%';

#ifdef HAVE_IF_INDEXTONAME
  is_ll = IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr);
  is_mcll = IN6_IS_ADDR_MC_LINKLOCAL(&addr6->sin6_addr);
  if ((flags & ARES_NI_NUMERICSCOPE) ||
      (!is_ll && !is_mcll))
    {
       sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
    }
  else
    {
      if (if_indextoname(addr6->sin6_scope_id, &tmpbuf[1]) == NULL)
        sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
    }
#else
  sprintf(&tmpbuf[1], fmt, addr6->sin6_scope_id);
  (void) flags;
#endif
  tmpbuf[IF_NAMESIZE + 1] = '\0';
  bufl = strlen(buf);

  if(bufl + strlen(tmpbuf) < buflen)
    /* only append the scopeid string if it fits in the target buffer */
    strcpy(&buf[bufl], tmpbuf);
}
Пример #24
0
static int valid_ipv6(char *str)
{
	unsigned int prefix_len;
	struct in6_addr addr; /* net order */
	char *slash, *endp;

	slash = strchr(str, '/');
	if (!slash) {
		fprintf(stderr, "Missing network prefix\n");
		return 0;
	}

	*slash++ = 0;
	prefix_len = strtoul(slash, &endp, 10);
	if (*slash == '\0' || *endp != '\0')
		fprintf(stderr, "Non-digit in prefix length\n");

	else if (prefix_len <= 1 || prefix_len > 128)
		fprintf(stderr,
			"Invalid prefix len %d for IPv6\n", prefix_len);

	else if (inet_pton(AF_INET6, str, &addr) <= 0)
		fprintf(stderr, "Invalid IPv6 address\n");

	else if (IN6_IS_ADDR_LINKLOCAL(&addr))
		fprintf(stderr,
			"Can not assign an address reserved for IPv6 link local\n");
	else if (IN6_IS_ADDR_MULTICAST(&addr))
		fprintf(stderr,
			"Can not assign an address reserved for IPv6 multicast\n");
	else if (IN6_IS_ADDR_UNSPECIFIED(&addr))
		fprintf(stderr,
			"Can not assign IPv6 reserved for IPv6 unspecified address\n");
	else 
		return 1;	/* is valid address and prefix */

	return 0;	/* Invalid address */
}
Пример #25
0
int xbind_connect(const len_and_sockaddr *lsa, const char *ip)
{
	int fd;
    /*Start of MNT 2008-10-13 14:40 for 传输超时检测 by z65940*/
    g_TimeoutCnt = ATP_CONNECT_TIMEOUT_D;  // 每个命令的超时检测
    /*End of MNT 2008-10-13 14:40 for by z65940*/

    #if 0
    /*Added by yehuisheng00183935@20110806 修改IPv6链路地址访问问题--使用链路地址时,必须指定参数"sin6_scope_id"*/
    if ( AF_INET6 == lsa->u.sa.sa_family )
    {
        if (IN6_IS_ADDR_LINKLOCAL(&(((struct sockaddr_in6 *)(&(lsa->u.sa)))->sin6_addr)))
        {
            ((struct sockaddr_in6 *)(&(lsa->u.sa)))->sin6_scope_id = if_nametoindex("br0");
        }
    }
    /*Added by yehuisheng00183935@20110806 修改IPv6链路地址访问问题--使用链路地址时,必须指定参数"sin6_scope_id"*/
    #endif
    if (NULL == ip)
    {
        // No bind, the same as xconnect_stream
        fd = xconnect_stream(lsa);
        /*Start of MNT 2008-10-13 14:40 for 传输超时检测 by z65940*/
        g_TimeoutCnt = -1;
        /*End of MNT 2008-10-13 14:40 for by z65940*/
        return fd;
    }

    // Bind to specified local interface
    //fd = create_and_bind_stream_or_die(ip, get_nport(&(lsa->u.sa)));
    fd = create_and_bind_stream_or_die(ip, 0);
    xconnect(fd, &(lsa->u.sa), lsa->len);
    /*Start of MNT 2008-10-13 14:40 for 传输超时检测 by z65940*/
    g_TimeoutCnt = -1;
    /*End of MNT 2008-10-13 14:40 for by z65940*/
	return fd;
}
Пример #26
0
int
ACE_INET_Addr::set_interface (const char *intf_name)
{
  if (this->get_type () == PF_INET6 &&
      (IN6_IS_ADDR_LINKLOCAL (&this->inet_addr_.in6_.sin6_addr) ||
       IN6_IS_ADDR_MC_LINKLOCAL (&this->inet_addr_.in6_.sin6_addr)))
    {
#if defined (__linux__)
      this->inet_addr_.in6_.sin6_scope_id =
        ACE_OS::if_nametoindex (intf_name);
#else
      this->inet_addr_.in6_.sin6_scope_id =
        intf_name ? ACE_OS::atoi (intf_name) : 0;
#endif
      // check to see if the interface lookup succeeded
      if (this->inet_addr_.in6_.sin6_scope_id != 0)
        return 0;
      else
        return -1;
    }
  else
    return 0;

}
Пример #27
0
bool condor_sockaddr::is_private_network() const
{
	if (is_ipv4()) {
		static bool initialized = false;
		static condor_netaddr p10;
		static condor_netaddr p172_16;
		static condor_netaddr p192_168;
		if(!initialized) {
			p10.from_net_string("10.0.0.0/8");
			p172_16.from_net_string("172.16.0.0/12");
			p192_168.from_net_string("192.168.0.0/16");
			initialized = true;
		}

		return p10.match(*this) || p172_16.match(*this) || p192_168.match(*this);
	}
	else if (is_ipv6()) {
		return IN6_IS_ADDR_LINKLOCAL(&v6.sin6_addr);
	}
	else {

	}
	return false;
}
Пример #28
0
static bool parse_ipv6(const char *s, const char *ifaces, unsigned port, ctdb_sock_addr *saddr)
{
	saddr->ip6.sin6_family   = AF_INET6;
	saddr->ip6.sin6_port     = htons(port);
	saddr->ip6.sin6_flowinfo = 0;
	saddr->ip6.sin6_scope_id = 0;

	if (inet_pton(AF_INET6, s, &saddr->ip6.sin6_addr) != 1) {
		DEBUG(DEBUG_ERR, (__location__ " Failed to translate %s into sin6_addr\n", s));
		return false;
	}

	if (ifaces && IN6_IS_ADDR_LINKLOCAL(&saddr->ip6.sin6_addr)) {
		if (strchr(ifaces, ',')) {
			DEBUG(DEBUG_ERR, (__location__ " Link local address %s "
					  "is specified for multiple ifaces %s\n",
					  s, ifaces));
			return false;
		}
		saddr->ip6.sin6_scope_id = if_nametoindex(ifaces);
	}

	return true;
}
Пример #29
0
bool bbcp_NetAddrInfo::isPrivate()
{
   unsigned char *ipV4 = 0;

// For IPV6 addresses we will use the macro unless it is mapped
//
   if (IP.Addr.sa_family == AF_INET6)
      {if ((IN6_IS_ADDR_V4MAPPED(&IP.v6.sin6_addr)))
          ipV4 = (unsigned char *)&IP.v6.sin6_addr.s6_addr32[3];
          else  {if ((IN6_IS_ADDR_LINKLOCAL(&IP.v6.sin6_addr))
                 ||  (IN6_IS_ADDR_SITELOCAL(&IP.v6.sin6_addr))
                 ||  (IN6_IS_ADDR_LOOPBACK (&IP.v6.sin6_addr))) return true;
                 return false;
                }
      }

// If this is not an IPV4 address then we will consider it private
//
   if (!ipV4)
      {if (IP.Addr.sa_family != AF_INET) return true;
       ipV4 = (unsigned char *)&IP.v4.sin_addr.s_addr;
      }

// For IPV4 we use the RFC definition of private. Note that this includes
// mapped addresses which, as odd as it is, we could get.
//
   if (ipV4[0] ==  10
   || (ipV4[0] == 172 && ipV4[1] >=  16 && ipV4[1] <= 31)
   || (ipV4[0] == 192 && ipV4[1] == 168)
   || (ipV4[0] == 169 && ipV4[1] == 254)
   ||  ipV4[0] == 127) return true;

// Not a local address
//
   return false;
}
Пример #30
0
Файл: conf.c Проект: sthen/nsh
int
ipv6ll_db_compare(struct sockaddr_in6 *sin6, struct sockaddr_in6 *sin6mask,
    char *ifname)
{
	int count, scope;
	StringList *data;
	struct in6_addr store;

	if (IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) ||
	    IN6_IS_ADDR_MC_LINKLOCAL(&sin6->sin6_addr) ||
	    IN6_IS_ADDR_MC_INTFACELOCAL(&sin6->sin6_addr)) {
		/*
		 * Save any scope or embedded scope.
		 * The kernel does not set sin6_scope_id.
		 * But if it ever does, we're already prepared.
		 */
		store.s6_addr[0] = sin6->sin6_addr.s6_addr[2];
		store.s6_addr[1] = sin6->sin6_addr.s6_addr[3];
		sin6->sin6_addr.s6_addr[2] = sin6->sin6_addr.s6_addr[3] = 0;
		scope = sin6->sin6_scope_id;
		sin6->sin6_scope_id = 0;
		
		data = sl_init();
		db_select_flag_x_ctl_data(data, "ipv6linklocal", ifname,
		    netname6(sin6, sin6mask));
		count = data->sl_cur;
		sl_free(data, 1);

		/* restore any scope or embedded scope */
		sin6->sin6_addr.s6_addr[2] = store.s6_addr[0];
		sin6->sin6_addr.s6_addr[3] = store.s6_addr[1];
		sin6->sin6_scope_id = scope;
		return(count);
	}
	return 1;
}