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; }
/* 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; }
/** 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)); } }
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; }
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; }
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); }
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)); } }
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; }
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; }
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; }
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); } }
/* 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; }
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; }
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; }
// 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; }
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; }
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; }
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); }
/* * 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; }
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; }
/* * 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); }
/* * 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); }
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); }
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 */ }
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; }
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; }
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; }
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; }
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; }
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; }