Example #1
0
/* 
 * Adds address to the list of addresses maintained for interface.
 */
void
add_address(struct preflist *pl, struct interface *ifp)
{
	/* 
	 * Note: The first address of link local list is always used
	 * as the * source address of a packet if no address is
	 * specified through * Interface configuration.
	 */
	if (IN6_IS_ADDR_LINKLOCAL(&(pl->pl_pref.prf_addr))) {
		if (ifp->if_lladdr) {
			pl->pl_next = ifp->if_lladdr->pl_next;
			ifp->if_lladdr->pl_next = pl;
		} else {
			pl->pl_next = ifp->if_lladdr;
			ifp->if_lladdr = pl;
		}
	} else if (IN6_IS_ADDR_SITELOCAL(&(pl->pl_pref.prf_addr))) {
		pl->pl_next = ifp->if_sladdr;
		ifp->if_sladdr = pl;
	} else {		/* never a multicast address. already checked 
				 * in get_address() */
		if (ifp->if_ip6addr) {
			pl->pl_next = ifp->if_ip6addr->pl_next;
			ifp->if_ip6addr->pl_next = pl;
		} else {
			pl->pl_next = ifp->if_ip6addr;
			ifp->if_ip6addr = pl;
		}
	}
	return;
}
Example #2
0
/** 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;
}
Example #3
0
int get_host_addr(void *addr, unsigned int addrlen, const char *host, unsigned short port)
{
	struct addrinfo hint = {0};
	struct addrinfo *addrlink = NULL;
	struct addrinfo *tmp = NULL;
	unsigned short *lpport = (unsigned short *)((char*)addr + 1 + sizeof(unsigned short));
	hint.ai_flags = AI_CANONNAME;

	if(getaddrinfo(host, NULL, &hint, &addrlink) != 0) {
		return -1;
	}

	for(tmp = addrlink; tmp != NULL; tmp = tmp->ai_next) {
		if(tmp->ai_family == AF_INET6) {
			if(IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)tmp->ai_addr)->sin6_addr)
				|| IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)tmp->ai_addr)->sin6_addr)
				|| IN6_IS_ADDR_SITELOCAL(&((struct sockaddr_in6 *)tmp->ai_addr)->sin6_addr)
				|| IN6_IS_ADDR_V4MAPPED(&((struct sockaddr_in6 *)tmp->ai_addr)->sin6_addr)
				|| IN6_IS_ADDR_V4COMPAT(&((struct sockaddr_in6 *)tmp->ai_addr)->sin6_addr) ) {
				continue;
			}
		} 

		((char*)addr)[0] = (char)(tmp->ai_addrlen > addrlen ? addrlen : tmp->ai_addrlen);
		memcpy((char*)addr+1, tmp->ai_addr, ((char*)addr)[0]);
		*lpport = htons(port);
		break;
	}

	freeaddrinfo(addrlink);
	return 0;
}
Example #4
0
bool sockaddr_isAddrSiteLocal(const struct sockaddr * sa)
{
    if (sa->sa_family == AF_INET) {
        return false;
    }else if (sa->sa_family == AF_INET6) {
        return IN6_IS_ADDR_SITELOCAL(&((struct sockaddr_in6*)sa)->sin6_addr);
    }
    return false;
}
Example #5
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 #6
0
bool
BNetworkAddress::IsSiteLocal() const
{
	switch (fAddress.ss_family) {
		case AF_INET6:
			return IN6_IS_ADDR_SITELOCAL(&((sockaddr_in6&)fAddress).sin6_addr);

		default:
			return false;
	}
}
Example #7
0
int sock_send(int fd, char * addr, char * buf, int buflen, int port,int iface)
{	
    struct 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];

	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);

#if 0
/*	if (IN6_IS_ADDR_MULTICAST((IN6_ADDR*)addr))
	{
		ipmreq.ipv6mr_interface=4;
		memcpy(&ipmreq.ipv6mr_multiaddr,addr,16);
		if(setsockopt(fd,IPPROTO_IPV6,IPV6_ADD_MEMBERSHIP,(char*)&ipmreq,sizeof(ipmreq)))
			return -1; //WSAGetLastError();
		//int hops=8;
		//if(setsockopt(fd,IPPROTO_IPV6,IPV6_MULTICAST_HOPS,(char*)&hops,sizeof(hops)))
		//	return -1; //WSAGetLastError();
	}*/
#endif
	
	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;
	if (i=sendto(fd,buf,buflen,0,remote->ai_addr,remote->ai_addrlen))
	{
		freeaddrinfo(remote);
    	if (i<0) displayError(WSAGetLastError());
		return 0;
	}
/*	if((setsockopt(fd,IPPROTO_IPV6,IPV6_DROP_MEMBERSHIP,(char*)&ipmreq,sizeof(ipmreq))))
		return WSAGetLastError();*/
	freeaddrinfo(remote);
	return i;
}
Example #8
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 #9
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;
}
Example #10
0
/* 
 * Find the interface with address addr.
 */
struct interface *
if_ifwithaddr(struct preflist *addr, struct interface *ifp)
{
	register struct interface *inf;
	register struct preflist *pl = NULL;

#define equal( a1, a2 ) \
	((bcmp((char *)&a1->pl_pref.prf_addr, (char *)&a2->pl_pref.prf_addr, \
	       sizeof(struct in6_addr)) == 0) && \
	 (a1->pl_pref.prf_len == a2->pl_pref.prf_len))

	for (inf = ifnet; inf; inf = inf->if_next) {
		if (inf->if_flag & IFF_POINTOPOINT)
			continue;	/* ignore */

		if (IN6_IS_ADDR_LINKLOCAL(&addr->pl_pref.prf_addr))
			pl = inf->if_lladdr;
		else if (IN6_IS_ADDR_GLOBAL(&addr->pl_pref.prf_addr))
			pl = inf->if_ip6addr;
		else if (IN6_IS_ADDR_SITELOCAL(&addr->pl_pref.prf_addr))
			pl = inf->if_sladdr;
		/* else ? */

		for (; pl; pl = pl->pl_next) {
			if (equal(pl, addr)) {
				if (inf == ifp) {
					pl->pl_flag = PL_OLDADDR;
					return (inf);
				} else if (pl->pl_flag == PL_DELADDR)
					continue;
				/* duplicated address, ignore */
				if (!IN6_IS_ADDR_LINKLOCAL(&addr->pl_pref.prf_addr))
					return (inf);
			}
		}
	}
	return ((struct interface *)NULL);
}
Example #11
0
/* 
 * Find the point-to-point interface with destination address addr.
 */
struct interface *
if_ifwithdstaddr(struct preflist *addr, struct interface *ifp)
{
	register struct interface *inf;
	register struct preflist *pl = NULL;

	/* Unknown Address of the other side */
	if (IN6_IS_ADDR_UNSPECIFIED(&addr->pl_dest))
		return (struct interface *)NULL;

	for (inf = ifnet; inf; inf = inf->if_next) {
		if ((inf->if_flag & IFF_POINTOPOINT) == 0)
			continue;

		if (IN6_IS_ADDR_LINKLOCAL(&addr->pl_pref.prf_addr))
			pl = inf->if_lladdr;
		else if (IN6_IS_ADDR_GLOBAL(&addr->pl_pref.prf_addr))
			pl = inf->if_ip6addr;
		else if (IN6_IS_ADDR_SITELOCAL(&addr->pl_pref.prf_addr))
			pl = inf->if_sladdr;
		/* else ? */

		for (; pl; pl = pl->pl_next) {
			if (IN6_ARE_ADDR_EQUAL(&pl->pl_dest, &addr->pl_dest)) {
				if ((inf == ifp) && (equal(pl, addr))) {
					pl->pl_flag = PL_OLDADDR;
					return (inf);
				} else if (pl->pl_flag == PL_DELADDR)
					continue;
				/* duplicated address, ignore */
				if (!IN6_IS_ADDR_LINKLOCAL(&addr->pl_pref.prf_addr))
					return (inf);
			}
		}
	}
	return ((struct interface *)NULL);
}
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;
}
Example #13
0
int
_load_v6(netsnmp_container *container, int idx_offset)
{
    FILE           *in;
    char            line[80], addr[33], if_name[IFNAMSIZ];
    u_char          *buf;
    int             if_index, pfx_len, scope, flags, rc = 0;
    size_t          in_len, out_len;
    netsnmp_ipaddress_entry *entry;
    _ioctl_extras           *extras;
    static int      log_open_err = 1;
    
    netsnmp_assert(NULL != container);

#define PROCFILE "/proc/net/if_inet6"
    if (!(in = fopen(PROCFILE, "r"))) {
        if (1 == log_open_err) {
            snmp_log(LOG_ERR,"could not open " PROCFILE "\n");
            log_open_err = 0;
        }
        return -2;
    }
    /*
     * if we hadn't been able to open file and turned of err logging,
     * turn it back on now that we opened the file.
     */
    if (0 == log_open_err)
        log_open_err = 1;

    /*
     * address index prefix_len scope status if_name
     */
    while (fgets(line, sizeof(line), in)) {
        /*
         * fe800000000000000200e8fffe5b5c93 05 40 20 80 eth0
         *             A                    D  P  S  F  I
         * A: address
         * D: device number
         * P: prefix len
         * S: scope (see include/net/ipv6.h, net/ipv6/addrconf.c)
         * F: flags (see include/linux/rtnetlink.h, net/ipv6/addrconf.c)
         * I: interface
         */
        rc = sscanf(line, "%32s %02x %02x %02x %02x %8s\n",
                    addr, &if_index, &pfx_len, &scope, &flags, if_name);
        if( 6 != rc ) {
            snmp_log(LOG_ERR, PROCFILE " data format error (%d!=6), line ==|%s|\n",
                     rc, line);
            continue;
        }
        DEBUGMSGTL(("access:ipaddress:container",
                    "addr %s, index %d, pfx %d, scope %d, flags 0x%X, name %s\n",
                    addr, if_index, pfx_len, scope, flags, if_name));
        /*
         */
        entry = netsnmp_access_ipaddress_entry_create();
        if(NULL == entry) {
            rc = -3;
            break;
        }

        in_len = entry->ia_address_len = sizeof(entry->ia_address);
        netsnmp_assert(16 == in_len);
        out_len = 0;
        buf = entry->ia_address;
        if(1 != snmp_hex_to_binary(&buf,
                                   &in_len, &out_len, 0, addr)) {
            snmp_log(LOG_ERR,"error parsing '%s', skipping\n",
                     entry->ia_address);
            netsnmp_access_ipaddress_entry_free(entry);
            continue;
        }
        netsnmp_assert(16 == out_len);
        entry->ia_address_len = out_len;

        entry->ns_ia_index = ++idx_offset;

        /*
         * save if name
         */
        extras = netsnmp_ioctl_ipaddress_extras_get(entry);
        memcpy(extras->name, if_name, sizeof(extras->name));
        extras->flags = flags;

        /*
         * yyy-rks: optimization: create a socket outside the loop and use
         * netsnmp_access_interface_ioctl_ifindex_get() here, since
         * netsnmp_access_interface_index_find will open/close a socket
         * every time it is called.
         */
        entry->if_index = netsnmp_access_interface_index_find(if_name);

        /*
          #define IPADDRESSSTATUSTC_PREFERRED  1
          #define IPADDRESSSTATUSTC_DEPRECATED  2
          #define IPADDRESSSTATUSTC_INVALID  3
          #define IPADDRESSSTATUSTC_INACCESSIBLE  4
          #define IPADDRESSSTATUSTC_UNKNOWN  5
          #define IPADDRESSSTATUSTC_TENTATIVE  6
          #define IPADDRESSSTATUSTC_DUPLICATE  7
        */
        if(flags & IFA_F_PERMANENT)
            entry->ia_status = IPADDRESSSTATUSTC_PREFERRED; /* ?? */
        else if(flags & IFA_F_DEPRECATED)
            entry->ia_status = IPADDRESSSTATUSTC_DEPRECATED;
        else if(flags & IFA_F_TENTATIVE)
            entry->ia_status = IPADDRESSSTATUSTC_TENTATIVE;
        else {
            entry->ia_status = IPADDRESSSTATUSTC_UNKNOWN;
            DEBUGMSGTL(("access:ipaddress:ipv6",
                        "unknown flags 0x%x\n", flags));
        }

        /*
         * if it's not multi, it must be uni.
         *  (an ipv6 address is never broadcast)
         */
        if (IN6_IS_ADDR_MULTICAST(entry->ia_address))
            entry->ia_type = IPADDRESSTYPE_ANYCAST;
        else
            entry->ia_type = IPADDRESSTYPE_UNICAST;


        entry->ia_prefix_len = pfx_len;

        /*
         * can we figure out if an address is from DHCP?
         * use manual until then...
         *
         *#define IPADDRESSORIGINTC_OTHER  1
         *#define IPADDRESSORIGINTC_MANUAL  2
         *#define IPADDRESSORIGINTC_DHCP  4
         *#define IPADDRESSORIGINTC_LINKLAYER  5
         *#define IPADDRESSORIGINTC_RANDOM  6
         *
         * are 'local' address assigned by link layer??
         */
        if (IN6_IS_ADDR_LINKLOCAL(entry->ia_address) ||
            IN6_IS_ADDR_SITELOCAL(entry->ia_address))
            entry->ia_origin = IPADDRESSORIGINTC_LINKLAYER;
        else
            entry->ia_origin = IPADDRESSORIGINTC_MANUAL;

        /* xxx-rks: what can we do with scope? */

        /*
         * add entry to container
         */
        CONTAINER_INSERT(container, entry);
    }

    fclose(in);

    if(rc<0)
        return rc;

    return idx_offset;
}
Example #14
0
int get_destination_ip( struct task_details *plan)

{
    int rc = RC_NORMAL, sysrc, errlen;
    struct addrinfo hints, *host_recs = 0, *walk, *match4 = 0, *match6 = 0, *next_host_rec = 0, *dup_list = 0;
    struct sockaddr_in *sa4 = 0;
    struct sockaddr_in6 *sa6 = 0;

    /* --- */

    plan->dest6.sin6_family = AF_INET6;
    plan->dest6.sin6_port = 0;
    plan->dest6.sin6_flowinfo = 0;
    plan->dest6.sin6_addr = in6addr_loopback;
    plan->dest6.sin6_scope_id = SCOPE_LINK;

    plan->dest4.sin_family = AF_INET;
    plan->dest4.sin_port = 0;
    plan->dest4.sin_addr.s_addr = 0;

    /* --- */

    sysrc = inet_pton( AF_INET, plan->target_host, &plan->dest4.sin_addr);
    if( sysrc == 1)
    {
        plan->found_family = AF_INET;
        if( plan->debug >= DEBUG_MEDIUM) fprintf( stderr, "Found '%s' is a V4 IP address.\n", plan->target_host);
    }
    else if( sysrc) rc = ERR_OPT_CONFIG;
    else
    {
        sysrc = inet_pton( AF_INET6, plan->target_host, &plan->dest6.sin6_addr);
        if( sysrc == 1)
        {
            plan->found_family = AF_INET6;
            if( plan->debug >= DEBUG_MEDIUM) fprintf( stderr, "Found '%s' is a V6 IP address.\n", plan->target_host);
	}
        else if( sysrc) rc = ERR_OPT_CONFIG;
        else
        {
            if( plan->debug >= DEBUG_MEDIUM) fprintf( stderr, "Looks like a hostname, need to look it up.\n");
            hints.ai_flags = AI_CANONNAME;
            if( (plan->use_ip & DO_IPV4) && (plan->use_ip & DO_IPV6)) hints.ai_family = AF_UNSPEC;
            else if( plan->use_ip & DO_IPV6) hints.ai_family = AF_INET6;
            else hints.ai_family = AF_INET;
            hints.ai_socktype = 0;
            hints.ai_protocol = 0;
            hints.ai_addrlen = 0;
            hints.ai_addr = 0;
            hints.ai_canonname = 0;
            hints.ai_next = 0;

            sysrc = getaddrinfo( plan->target_host, 0, &hints, &host_recs);
            if( !sysrc)
            {
                if( plan->debug >= DEBUG_HIGH) fprintf( stderr, "...getaddrinfo() call worked, scan the host records to find the one we want...\n");
                match4 = match6 = 0;

                for( walk = host_recs; rc == RC_NORMAL && walk; walk = walk->ai_next)
                {
                    next_host_rec = (struct addrinfo *) malloc( sizeof *next_host_rec);

                    if( !next_host_rec) rc = ERR_MALLOC_FAILED;
                    else
                    {
                        if( !dup_list) dup_list = next_host_rec;
                        else dup_list->ai_next = next_host_rec;

                        next_host_rec->ai_flags = walk->ai_flags;
                        next_host_rec->ai_family = walk->ai_family;
                        next_host_rec->ai_socktype = walk->ai_socktype;
                        next_host_rec->ai_protocol = walk->ai_protocol;
                        next_host_rec->ai_addrlen = walk->ai_addrlen;
                        next_host_rec->ai_addr = (struct sockaddr *) malloc( next_host_rec->ai_addrlen);
                        if( next_host_rec->ai_addr) memcpy( walk->ai_addr, next_host_rec->ai_addr,
                          next_host_rec->ai_addrlen);
                        next_host_rec->ai_canonname = strdup( walk->ai_canonname);
                        next_host_rec->ai_next = 0;

                        if( !next_host_rec->ai_canonname || !next_host_rec->ai_addr)
                          rc = ERR_MALLOC_FAILED;
		    }
		}

                if( rc == RC_NORMAL)
                {
                    freeaddrinfo( host_recs);
                    host_recs = dup_list;

                    for( walk = host_recs; walk; )
                    {
                        if( plan->debug >= DEBUG_NOISY) fprintf( stderr, "hr --> %x %x/%x/%x %x %x %d %s\n",
                          walk->ai_flags, walk->ai_family, AF_INET, AF_INET6, walk->ai_socktype, 
                          walk->ai_protocol, walk->ai_addrlen, walk->ai_canonname);

                        if( !match4 && walk->ai_family == AF_INET) match4 = walk;
                        if( !match6 && walk->ai_family == AF_INET6) match6 = walk;
                        if( match4 && match6) walk = 0;
                        else walk = walk->ai_next;
                    }

                    if( (plan->use_ip & DO_IPV4) && match4)
                    {
                        sa4 = (struct sockaddr_in *) match4->ai_addr;
                        plan->dest4.sin_addr = sa4->sin_addr;
                        plan->found_family = AF_INET;
                    }
                    else if( (plan->use_ip & DO_IPV6) && match6)
                    {
                        sa6 = (struct sockaddr_in6 *) match6->ai_addr;
                        plan->dest6.sin6_addr = sa6->sin6_addr;
                        plan->found_family = AF_INET6;
                        plan->dest6.sin6_scope_id = sa6->sin6_scope_id;
                    }
                    if( plan->debug >= DEBUG_NOISY) fprintf( stderr, "match4:%d/%d match6:%d/%d\n", !!match4, !!sa4, !!match6, !!sa6);
                }
                else
                {
                    if( sysrc == EAI_MEMORY) rc = ERR_MALLOC_FAILED;
                    else rc = ERR_GETHOST_FAILED;
                }
            }
	}
    }

    if( !strcmp( plan->target_host, IPV6_LOOPBACK_ADDRESS)) plan->dest6.sin6_scope_id = SCOPE_LOOP;
    else if( IN6_IS_ADDR_LINKLOCAL( &plan->dest6.sin6_addr)) plan->dest6.sin6_scope_id = SCOPE_LINK;
    else if( IN6_IS_ADDR_SITELOCAL( &plan->dest6.sin6_addr)) plan->dest6.sin6_scope_id = SCOPE_SITE;
    else plan->dest6.sin6_scope_id = SCOPE_GLOBAL;

    if( rc == ERR_GETHOST_FAILED)
    {
        errlen = strlen( ERRMSG_GETHOST_FAILED) + strlen( plan->target_host);
        plan->err_msg = (char *) malloc( errlen);
        if( !plan->err_msg) rc = ERR_MALLOC_FAILED;
        else snprintf( plan->err_msg, errlen, ERRMSG_GETHOST_FAILED, plan->target_host);
    }
    else if( rc == ERR_OPT_CONFIG)
    {
        errlen = strlen( ERRMSG_INET_PTON) + strlen( plan->target_host);
        plan->err_msg = (char *) malloc( errlen);
        if( !plan->err_msg) rc = ERR_MALLOC_FAILED;
        else snprintf( plan->err_msg, errlen, ERRMSG_INET_PTON, plan->target_host);
    }

    return( rc);
}
Example #15
0
  /**
   * Query device driver for information
   */
  bool network::query(bool accumulate) {
    struct ifaddrs* ifaddr;
    if (getifaddrs(&ifaddr) == -1 || ifaddr == nullptr) {
      return false;
    }

    m_status.previous = m_status.current;
    m_status.current.transmitted = 0;
    m_status.current.received = 0;
    m_status.current.time = std::chrono::system_clock::now();
    m_status.ip6 = NO_IP6;

    for (auto ifa = ifaddr; ifa != nullptr; ifa = ifa->ifa_next) {
      if (ifa->ifa_addr == nullptr) {
        continue;
      }

      if (m_interface.compare(0, m_interface.length(), ifa->ifa_name) != 0) {
        if (!accumulate || (ifa->ifa_data == nullptr && ifa->ifa_addr->sa_family != AF_PACKET)) {
          continue;
        }
      }

      struct sockaddr_in6* sa6;

      switch (ifa->ifa_addr->sa_family) {
        case AF_INET:
          char ip_buffer[NI_MAXHOST];
          getnameinfo(ifa->ifa_addr, sizeof(sockaddr_in), ip_buffer, NI_MAXHOST, nullptr, 0, NI_NUMERICHOST);
          m_status.ip = string{ip_buffer};
          break;

        case AF_INET6:
          char ip6_buffer[INET_ADDRSTRLEN];
          sa6 = reinterpret_cast<decltype(sa6)>(ifa->ifa_addr);
          if (IN6_IS_ADDR_LINKLOCAL(&sa6->sin6_addr)) {
              continue;
          }
          if (IN6_IS_ADDR_SITELOCAL(&sa6->sin6_addr)) {
              continue;
          }
          if ((((unsigned char*)sa6->sin6_addr.s6_addr)[0] & 0xFE) == 0xFC) {
              /* Skip Unique Local Addresses (fc00::/7) */
              continue;
          }
          if (inet_ntop(AF_INET6, &sa6->sin6_addr, ip6_buffer, NI_MAXHOST) == 0) {
              m_log.warn("inet_ntop() " + string(strerror(errno)));
              continue;
          }
          m_status.ip6 = string{ip6_buffer};
          break;

        case AF_PACKET:
          if (ifa->ifa_data == nullptr) {
            continue;
          }
          struct rtnl_link_stats* link_state = reinterpret_cast<decltype(link_state)>(ifa->ifa_data);
          if (link_state == nullptr) {
            continue;
          }
          m_status.current.transmitted += link_state->tx_bytes;
          m_status.current.received += link_state->rx_bytes;
          break;
      }
    }

    freeifaddrs(ifaddr);

    return true;
  }
Example #16
0
static int
get_real_ip(char*nmode, char *ip)
{
	struct ifaddrs *ifap0, *ifap;
	char buf[NI_MAXHOST];
	struct sockaddr_in *addr4;
	struct sockaddr_in6 *addr6;
	int family;
	char *IPV6_FLAG=NULL;
	IPV6_FLAG = cfg_get_param_string(F_CFG_IPV6);

	if (strcmp(IPV6_FLAG, "0") == 0){
		family=AF_INET;
	}else{
		family=AF_INET6;
	}

	if(NULL == ip) {
		//strcpy (ip, "");
		return -1;
	}

	if(getifaddrs(&ifap0)) {
		return -1;
	}

	for(ifap=ifap0;ifap!=NULL;ifap=ifap->ifa_next){
		if(strcmp(nmode, ifap->ifa_name) != 0) continue;

		if(ifap->ifa_addr == NULL) continue;

		if ((ifap->ifa_flags & IFF_UP) == 0) continue;

		if(family != ifap->ifa_addr->sa_family) continue;

		if(AF_INET == ifap->ifa_addr->sa_family) {
			addr4 = (struct sockaddr_in *)ifap->ifa_addr;
			if ( NULL != inet_ntop(ifap->ifa_addr->sa_family,
			(void *)&(addr4->sin_addr), buf, NI_MAXHOST) ){
			strcpy(ip, buf);
			cfg_debug ("iface %s's ipaddress is %s\n", nmode, ip);
			freeifaddrs(ifap0);
			return 0;
			}
			else break;
		}else if(AF_INET6 == ifap->ifa_addr->sa_family) {
			addr6 = (struct sockaddr_in6 *)ifap->ifa_addr;

			if(IN6_IS_ADDR_MULTICAST(&addr6->sin6_addr)){
			continue;
			}
			if(IN6_IS_ADDR_LINKLOCAL(&addr6->sin6_addr)){
			continue;
			}
			if(IN6_IS_ADDR_LOOPBACK(&addr6->sin6_addr)){
			continue;
			}
			if(IN6_IS_ADDR_UNSPECIFIED(&addr6->sin6_addr)){
			continue;
			}
			if(IN6_IS_ADDR_SITELOCAL(&addr6->sin6_addr)){
			continue;
			}

			if(NULL != inet_ntop(ifap->ifa_addr->sa_family,
				(void *)&(addr6->sin6_addr), buf, NI_MAXHOST)){
				strcpy(ip, buf);
				cfg_debug ("iface %s's ipaddress is %s\n", nmode, ip);
				freeifaddrs(ifap0);
				return 0;
			}
				else break;
		}
	}

	freeifaddrs(ifap0);
	return -1;
}
Example #17
0
int util_my_ip_address(char *buf, size_t buflen, int all)
{
    int ret = -1;
    char tmp[INET6_ADDRSTRLEN + 1];
#if defined(_WIN32) || defined(__CYGWIN__)
    PIP_ADAPTER_ADDRESSES pAdapterAddresses = NULL, pInfo = NULL;
    ULONG ulBufferLength = 0;
    DWORD dwRet;
    PIP_ADAPTER_UNICAST_ADDRESS pUniAddr;

    buf[0] = '\0';

    do {
        dwRet = GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, NULL,
                                     pAdapterAddresses, &ulBufferLength);
        if (dwRet == ERROR_BUFFER_OVERFLOW) {
            if (pAdapterAddresses)
                free(pAdapterAddresses);
            pAdapterAddresses = malloc(ulBufferLength);
            if (!pAdapterAddresses) {
                return -1;
            }
        }
    } while (dwRet == ERROR_BUFFER_OVERFLOW);

    if (dwRet != ERROR_SUCCESS && dwRet != ERROR_NO_DATA) {
        if (pAdapterAddresses)
            free(pAdapterAddresses);
        return -1;
    }

    int break_out = 0;
    for (pInfo = pAdapterAddresses; pInfo; pInfo = pInfo->Next) {
        for (pUniAddr = pInfo->FirstUnicastAddress; pUniAddr;
             pUniAddr = pUniAddr->Next) {
            DWORD dwLen = sizeof(tmp);
            int rc = WSAAddressToString(pUniAddr->Address.lpSockaddr,
                                        pUniAddr->Address.iSockaddrLength,
                                        NULL, (LPTSTR)tmp, &dwLen);
            if (rc)
                continue;

            char *percent = strchr(tmp, '%');
            if (percent)
                *percent = '\0';

            /* First check if there's enough space in buf. */
            if (strlen(tmp) + strlen(buf) + 2 > buflen) {
                /* Buffer too small. Try next address and see if it fits. */
                continue;
            }

            /* There's enough space to hold the address plus the semicolon. */
            if (strlen(buf) > 0)
                strcat(buf, ";");
            strcat(buf, tmp);

            ret = 0;

            if (!all) {
                break_out = 1;
                break;
            }
        }

        if (break_out)
            break;
    }

    free(pAdapterAddresses);
#else
    struct ifaddrs *addrs, *a;
    struct sockaddr_in *sin;
    struct sockaddr_in6 *sin6;
    uint32_t x;

    buf[0] = '\0';

    if (getifaddrs(&addrs)) {
        perror("getifaddrs() failed");
        return -1;
    }

    for (a = addrs; a; a = a->ifa_next) {
        if (!a->ifa_addr)
            continue;

        if (a->ifa_addr->sa_family == AF_INET) {
            sin = (struct sockaddr_in *)a->ifa_addr;
            x = ntohl(sin->sin_addr.s_addr);
            if (IN_MULTICAST(x) ||
                INADDR_ANY == x ||
                INADDR_NONE == x ||
                ((x & 0xff000000) == 0x7f000000) ||
                (((x & 0xff000000) == 0xa9000000) &&
                 ((x & 0x00ff0000) == 0x00fe0000))) {
                continue;
            }

            if (util_inet_ntop(sin->sin_family, a->ifa_addr, tmp,
                               sizeof(tmp))) {
                break;
            }
        } else if (a->ifa_addr->sa_family == AF_INET6) {
            sin6 = (struct sockaddr_in6 *)a->ifa_addr;
            if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
                IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr) ||
                IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) ||
                IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) ||
                IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
                continue;
            }

            if (util_inet_ntop(sin6->sin6_family, a->ifa_addr, tmp,
                               sizeof(tmp))) {
                break;
            }
        } else {
            continue;
        }

        if (strlen(tmp) + strlen(buf) + 2 > buflen)
            break;

        if (buf[0] != '\0')
            strcat(buf, ";");
        strcat(buf, tmp);

        ret = 0;

        if (!all)
            break;
    }

    if (addrs)
        freeifaddrs(addrs);
#endif

    return ret;
}
Example #18
0
HRESULT RefreshIPv6CfgDialog(HWND hwndDlg)
{
    HRESULT             hr = S_OK;
    ULONG               ulBufferSize = 0;
    DWORD               dwRetVal;

    TCHAR               szAddr[INET6_ADDRSTRLEN];
    TCHAR               szAddrNotAvail[INET6_ADDRSTRLEN];
    BOOL                bDefaultGateway = FALSE;
    BOOL                bPrefGlobal = FALSE;
    BOOL                bPrefLinkLocal = FALSE;
    BOOL                bPrefSiteLocal = FALSE;
    BOOL                b6to4 = FALSE;
    BOOL                bAuto1 = FALSE;
    BOOL                bAuto2 = FALSE;
    BOOL                bAuto3 = FALSE;

    PIP_ADAPTER_ADDRESSES pAdapterAddresses = NULL, pThisAdapterAddresses;
    PIP_ADAPTER_UNICAST_ADDRESS pUnicastAddresses;
    char                szAdapterName[MAX_ADAPTERNAME_STR];

    // Get IP address info
    dwRetVal = GetAdaptersAddresses(AF_INET6,GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST,
                                    NULL,NULL,&ulBufferSize);

    if (dwRetVal != ERROR_BUFFER_OVERFLOW) {
        DEBUGMSG(ZONE_ERROR, (TEXT("NETUIQC: Error from GetAdaptersAddresses():%u"),dwRetVal));
        hr = E_FAIL;
        goto exit;
    }

    pAdapterAddresses = (PIP_ADAPTER_ADDRESSES)malloc(ulBufferSize);
    if (pAdapterAddresses == NULL) {
        hr = E_FAIL;
        goto exit;
    }

    dwRetVal = GetAdaptersAddresses(AF_INET6,GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST,
                                    NULL,pAdapterAddresses,&ulBufferSize);
    if (dwRetVal != ERROR_SUCCESS) {
        DEBUGMSG(ZONE_ERROR, (TEXT("NETUIQC: Error from GetAdaptersAddresses():%u"),dwRetVal));
        hr = E_FAIL;
        goto exit;
    }
    // Get our adapter name
    if (GetAdapterNameA(hwndDlg,szAdapterName,sizeof(szAdapterName)) != S_OK) {
        DEBUGMSG(ZONE_ERROR, (TEXT("Error getting adapter name")));
        hr = E_FAIL;
        goto exit;
    }

    // Walk adapter list
    for (pThisAdapterAddresses = pAdapterAddresses; 
        pThisAdapterAddresses;
        pThisAdapterAddresses = pThisAdapterAddresses->Next) {

        BOOL bCurrentAdapter;

        DEBUGMSG(ZONE_MISC,(TEXT("GetAdaptersAddresses adapter <%s>\n"),pThisAdapterAddresses->FriendlyName));

        if (! strcmp(szAdapterName,pThisAdapterAddresses->AdapterName)) {

            // IPv6 stack will return address info even if media disconnected.  Don't display
            // addresses in this case.
            if (!(pThisAdapterAddresses->OperStatus & IfOperStatusUp)) {
                DEBUGMSG(ZONE_MISC,(TEXT("GetAdaptersAddresses -- Media Disconnected\n")));
                break;
            }

            bCurrentAdapter = TRUE;
            if (GetIPv6DefaultGateway(pThisAdapterAddresses, szAddr)) {
                UpdateIPv6AddressField(hwndDlg, IDC_V6GATEWAY_LBL_INF, szAddr);
                bDefaultGateway = TRUE;
            }
        }
        else {
            bCurrentAdapter = FALSE;
            if (pThisAdapterAddresses->IfType != IF_TYPE_TUNNEL) {
                // Skip other non tunneling adapters 
                continue;
            }
            // TBD - For tunneling interfaces, we want to choose the one matching the v4 address on this interface

        }

        for (pUnicastAddresses = pThisAdapterAddresses->FirstUnicastAddress ;
            pUnicastAddresses;
            pUnicastAddresses = pUnicastAddresses->Next) {
            PSOCKADDR_IN6 pSA = (PSOCKADDR_IN6)pUnicastAddresses->Address.lpSockaddr;
            ULONG AddrFieldLbl;

            GetIPv6AddressString(szAddr, pSA);

            DEBUGMSG(ZONE_MISC,(TEXT("   GetAdaptersAddresses return addr <%s>\n"),szAddr));

            AddrFieldLbl = 0;

            if (IN6_IS_ADDR_SITELOCAL(&pSA->sin6_addr)) {
                if (bCurrentAdapter) {
                    AddrFieldLbl = IDC_V6PREFSITEADDR_LBL_INF;
                    bPrefSiteLocal = TRUE;
                } else if (IN6_IS_ADDR_ISATAP(&pSA->sin6_addr)) {
                    AddrFieldLbl = IDC_V6TUNNELADDR_LBL_INF2;
                    bAuto2 = TRUE;
                }
            } else if (IN6_IS_ADDR_LINKLOCAL(&pSA->sin6_addr)) {
                if (bCurrentAdapter) {
                    AddrFieldLbl = IDC_V6PREFLINKADDR_LBL_INF;
                    bPrefLinkLocal = TRUE;
                } else if (IN6_IS_ADDR_ISATAP(&pSA->sin6_addr)) {
                    AddrFieldLbl = IDC_V6TUNNELADDR_LBL_INF3;
                    bAuto3 = TRUE;
                }
            } else {
                if (bCurrentAdapter) {
                    AddrFieldLbl = IDC_V6PREFGLOBADDR_LBL_INF;
                    bPrefGlobal = TRUE;
                } else if (IN6_IS_ADDR_6TO4(&pSA->sin6_addr)) {
                    AddrFieldLbl = IDC_V66TO4ADDR_LBL_INF;
                    b6to4 = TRUE;
                } else if (IN6_IS_ADDR_ISATAP(&pSA->sin6_addr)) {
                    AddrFieldLbl = IDC_V6TUNNELADDR_LBL_INF1;
                    bAuto1 = TRUE;
                }
            }

            if (AddrFieldLbl)
                UpdateIPv6AddressField(hwndDlg, AddrFieldLbl, szAddr);
        }

    }


    exit:
    // Display address not available for fields we couldn't populate

    LoadString(v_hInst, IDS_QC_V6_ADDR_UNAVAIL, szAddrNotAvail, INET6_ADDRSTRLEN);
    if (!bDefaultGateway)
        UpdateIPv6AddressField(hwndDlg, IDC_V6GATEWAY_LBL_INF, szAddrNotAvail);
    if (!bPrefGlobal)
        UpdateIPv6AddressField(hwndDlg, IDC_V6PREFGLOBADDR_LBL_INF, szAddrNotAvail);
    if (!bPrefSiteLocal)
        UpdateIPv6AddressField(hwndDlg, IDC_V6PREFSITEADDR_LBL_INF, szAddrNotAvail);
    if (!bPrefLinkLocal)
        UpdateIPv6AddressField(hwndDlg, IDC_V6PREFLINKADDR_LBL_INF, szAddrNotAvail);
    if (!b6to4)
        UpdateIPv6AddressField(hwndDlg, IDC_V66TO4ADDR_LBL_INF, szAddrNotAvail);
    if (!bAuto1)
        UpdateIPv6AddressField(hwndDlg, IDC_V6TUNNELADDR_LBL_INF1, szAddrNotAvail);
    if (!bAuto2)
        UpdateIPv6AddressField(hwndDlg, IDC_V6TUNNELADDR_LBL_INF2, szAddrNotAvail);
    if (!bAuto3)
        UpdateIPv6AddressField(hwndDlg, IDC_V6TUNNELADDR_LBL_INF3, szAddrNotAvail);

    if (pAdapterAddresses) {
        free(pAdapterAddresses);
    }
    return hr;
}
Example #19
0
/*
 * Reads a linux sockaddr and does any necessary translation.
 * Linux sockaddrs don't have a length field, only a family.
 * Copy the osockaddr structure pointed to by osa to kernel, adjust
 * family and convert to sockaddr.
 */
static int
linux_getsockaddr(struct sockaddr **sap, const struct osockaddr *osa, int salen)
{
	struct sockaddr *sa;
	struct osockaddr *kosa;
#ifdef INET6
	struct sockaddr_in6 *sin6;
	int oldv6size;
#endif
	char *name;
	int bdom, error, hdrlen, namelen;

	if (salen < 2 || salen > UCHAR_MAX || !osa)
		return (EINVAL);

#ifdef INET6
	oldv6size = 0;
	/*
	 * Check for old (pre-RFC2553) sockaddr_in6. We may accept it
	 * if it's a v4-mapped address, so reserve the proper space
	 * for it.
	 */
	if (salen == sizeof(struct sockaddr_in6) - sizeof(uint32_t)) {
		salen += sizeof(uint32_t);
		oldv6size = 1;
	}
#endif

	kosa = malloc(salen, M_SONAME, M_WAITOK);

	if ((error = copyin(osa, kosa, salen)))
		goto out;

	bdom = linux_to_bsd_domain(kosa->sa_family);
	if (bdom == -1) {
		error = EAFNOSUPPORT;
		goto out;
	}

#ifdef INET6
	/*
	 * Older Linux IPv6 code uses obsolete RFC2133 struct sockaddr_in6,
	 * which lacks the scope id compared with RFC2553 one. If we detect
	 * the situation, reject the address and write a message to system log.
	 *
	 * Still accept addresses for which the scope id is not used.
	 */
	if (oldv6size) {
		if (bdom == AF_INET6) {
			sin6 = (struct sockaddr_in6 *)kosa;
			if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) ||
			    (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) &&
			     !IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) &&
			     !IN6_IS_ADDR_V4COMPAT(&sin6->sin6_addr) &&
			     !IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) &&
			     !IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))) {
				sin6->sin6_scope_id = 0;
			} else {
				log(LOG_DEBUG,
				    "obsolete pre-RFC2553 sockaddr_in6 rejected\n");
				error = EINVAL;
				goto out;
			}
		} else
			salen -= sizeof(uint32_t);
	}
#endif
	if (bdom == AF_INET) {
		if (salen < sizeof(struct sockaddr_in)) {
			error = EINVAL;
			goto out;
		}
		salen = sizeof(struct sockaddr_in);
	}

	if (bdom == AF_LOCAL && salen > sizeof(struct sockaddr_un)) {
		hdrlen = offsetof(struct sockaddr_un, sun_path);
		name = ((struct sockaddr_un *)kosa)->sun_path;
		if (*name == '\0') {
			/*
		 	 * Linux abstract namespace starts with a NULL byte.
			 * XXX We do not support abstract namespace yet.
			 */
			namelen = strnlen(name + 1, salen - hdrlen - 1) + 1;
		} else
			namelen = strnlen(name, salen - hdrlen);
		salen = hdrlen + namelen;
		if (salen > sizeof(struct sockaddr_un)) {
			error = ENAMETOOLONG;
			goto out;
		}
	}
Example #20
0
/*
 * Copy the osockaddr structure pointed to by osa to kernel, adjust
 * family and convert to sockaddr.
 */
static int
do_sa_get(struct sockaddr **sap, const struct osockaddr *osa, int *osalen,
    struct malloc_type *mtype)
{
	int error=0, bdom;
	struct sockaddr *sa;
	struct osockaddr *kosa;
	int alloclen;
#ifdef INET6
	int oldv6size;
	struct sockaddr_in6 *sin6;
#endif

	if (*osalen < 2 || *osalen > UCHAR_MAX || !osa)
		return (EINVAL);

	alloclen = *osalen;
#ifdef INET6
	oldv6size = 0;
	/*
	 * Check for old (pre-RFC2553) sockaddr_in6. We may accept it
	 * if it's a v4-mapped address, so reserve the proper space
	 * for it.
	 */
	if (alloclen == sizeof (struct sockaddr_in6) - sizeof (u_int32_t)) {
		alloclen = sizeof (struct sockaddr_in6);
		oldv6size = 1;
	}
#endif

	kosa = malloc(alloclen, mtype, M_WAITOK);

	if ((error = copyin(osa, kosa, *osalen)))
		goto out;

	bdom = linux_to_bsd_domain(kosa->sa_family);
	if (bdom == -1) {
		error = EAFNOSUPPORT;
		goto out;
	}

#ifdef INET6
	/*
	 * Older Linux IPv6 code uses obsolete RFC2133 struct sockaddr_in6,
	 * which lacks the scope id compared with RFC2553 one. If we detect
	 * the situation, reject the address and write a message to system log.
	 *
	 * Still accept addresses for which the scope id is not used.
	 */
	if (oldv6size && bdom == AF_INET6) {
		sin6 = (struct sockaddr_in6 *)kosa;
		if (IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr) ||
		    (!IN6_IS_ADDR_LINKLOCAL(&sin6->sin6_addr) &&
		     !IN6_IS_ADDR_SITELOCAL(&sin6->sin6_addr) &&
		     !IN6_IS_ADDR_V4COMPAT(&sin6->sin6_addr) &&
		     !IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) &&
		     !IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr))) {
			sin6->sin6_scope_id = 0;
		} else {
			log(LOG_DEBUG,
			    "obsolete pre-RFC2553 sockaddr_in6 rejected\n");
			error = EINVAL;
			goto out;
		}
	} else
#endif
	if (bdom == AF_INET) {
		alloclen = sizeof(struct sockaddr_in);
		if (*osalen < alloclen) {
			error = EINVAL;
			goto out;
		}
	}

	sa = (struct sockaddr *) kosa;
	sa->sa_family = bdom;
	sa->sa_len = alloclen;

	*sap = sa;
	*osalen = alloclen;
	return (0);

out:
	free(kosa, mtype);
	return (error);
}
Example #21
0
/*Look if the source ip address is local to the subnet*/
int watch_bogon(char* buffer, uint16_t vlan_id, struct ether_header* eptr, struct ip6_hdr* ipptr)
{

	struct ether_addr* eth_addr = (struct ether_addr*) eptr->ether_shost;
	struct in6_addr* ip_addr = &ipptr->ip6_src;
	char str_ip[IP6_STR_SIZE];

	router_list_t *tmp = routers;
	int find = 0;

	ipv6_ntoa(str_ip, *ip_addr);

	while( tmp != NULL)
	{
		prefix_t *ptmp = tmp->prefixes;
		while(ptmp != NULL)
		{
			if(IN6_ARE_PRE_EQUAL(ip_addr, &(ptmp->prefix)))
				find = 1;

			ptmp = ptmp->next;
		}
		tmp = tmp->next;
	}

	if (!find && !IN6_IS_ADDR_UNSPECIFIED(ip_addr)&&!IN6_IS_ADDR_LINKLOCAL(ip_addr)&&!IN6_IS_ADDR_MULTICAST(ip_addr)&&!IN6_IS_ADDR_SITELOCAL(ip_addr))
	{
		snprintf (buffer, NOTIFY_BUFFER_SIZE, "VLAN%d: bogon %s %s",vlan_id,ether_ntoa(eth_addr),str_ip);
		notify(1, buffer, "bogon", eth_addr, str_ip, NULL);
		return 1;
	}
	else
		return 0;
}
Example #22
0
/* 
 * Forms the packet according to mode of operation.
 */
void
send_update(struct interface *ifp, struct msghdr *mh, int state, unsigned int agronly)
{
	int max_entries, num_entries;
	int metric_out, poisonf;
	int need_nhp = 0;
	struct in6_addr *addrp, *current_nhp, *new_nhp;
	struct rip6 *pkt;
	struct route_entry *rp;
	struct rt_plen *rtp, *drt;
	struct tree_node *node;
	struct rte_stat *stat;
	struct gateway *gp;
	struct nexthop_rte *nhrp;	/* nexthop list */
	struct aggregate *agp;
	struct route_entry r_tmp;
	const int nohopout = 0;

	if (snd_data == NULL)
		return;
	if (!(ifp->if_flag & IFF_RUNNING))
		return;		/* doesn't have any linklocal */

	if (mh == NULL) {	/* unsolicited */
		mh = &smsgh;
		bzero(mh, sizeof(smsgh));
	}
	mh->msg_iov = &siov;	/* overwrite does no harm */
	mh->msg_iovlen = 1;
	mh->msg_flags = 0;	/* clear */

	mh->msg_iov->iov_base = snd_data;
	pkt = (struct rip6 *)snd_data;

	max_entries = get_max_rte(ifp);
	need_nhp = 0;

	ONCE_FOR_EACH_PACKET;

	/* gendefault: if generate then no other RTE is needed */
	if ((stat = ifp->if_config->int_dstat) != NULL) {
		if (!state) {	/* regular update */
			/* default route cannot be aggregated further */

			bzero((void *)&r_tmp, sizeof(r_tmp));
			r_tmp.rip6_metric = stat->rts_metric +
				ifp->if_config->int_metric_out;
			if (r_tmp.rip6_metric > HOPCOUNT_INFINITY)
				r_tmp.rip6_metric = HOPCOUNT_INFINITY;
			r_tmp.rip6_rtag = htons(stat->rts_tagval);

			new_nhp = current_nhp;
			CHECK_NHOP(r_tmp);
			WRITE_PAIR(r_tmp);
		}
		goto lastone;	/* and return */
	}
	/* init aggregate list */
	for (agp = ifp->if_config->int_aggr; agp; agp = agp->agr_next)
		agp->agr_sent = AGR_NOTSENT;

	/* propagate default */
	if (ifp->if_config->int_propagate &&
	    (drt = locate_local_route(&default_rte, &node)) != NULL &&
	    (drt->rp_state & RTS6_STATIC) == 0 && /* learn from neighbour */
	    (!state || drt->rp_state & state) && !agronly) {
		/* sanity check omitted */
		if (drt->rp_gway->gw_ifp == ifp) {	/* same interface */
			switch (ifp->if_config->int_scheme) {
			case RT6_NOHORZN:	/* no intelligence */
				metric_out = drt->rp_metric +
					ifp->if_config->int_metric_out;
				break;
			case RT6_HORZN:
				goto loop;	/* no need to advertise */
			default:	/* case RT6_POISON: */
				metric_out = HOPCOUNT_INFINITY;
				break;
			}
		} else {	/* other interface */
			metric_out = drt->rp_metric +
				ifp->if_config->int_metric_out;
		}

		CHECK_AGR(&drt->rp_leaf->key);

		/* This is 1st. RTE, any aggregation has not been sent yet */
		if (agp) {
			r_tmp.rip6_prflen = agp->agr_pref.prf_len;
			r_tmp.rip6_addr = agp->agr_pref.prf_addr;
			r_tmp.rip6_metric = agp->agr_stat.rts_metric
				+ ifp->if_config->int_metric_out;
			r_tmp.rip6_rtag = htons(agp->agr_stat.rts_tagval);
			agp->agr_sent = AGR_SENT;
		} else {
			r_tmp.rip6_prflen = 0;	/* DEFAULT ROUTE drt->rp_len */
			r_tmp.rip6_addr = drt->rp_leaf->key;
			r_tmp.rip6_metric = metric_out;
			r_tmp.rip6_rtag = htons(drt->rp_tag);
		}
		if (r_tmp.rip6_metric > HOPCOUNT_INFINITY)
			r_tmp.rip6_metric = HOPCOUNT_INFINITY;
		new_nhp = &ci_info(ifp->if_cinfo).ipi6_addr;
		CHECK_NHOP(r_tmp);
		WRITE_PAIR(r_tmp);
	}	/* end propagate */
 loop:
	for (gp = gway; gp; gp = gp->gw_next) {
		if (!(gp->gw_ifp) || (gp->gw_ifp->if_flag & IFF_UP) == 0)
			continue;

		if (gp->gw_ifp == ifp) {
			switch (ifp->if_config->int_scheme) {
			case RT6_NOHORZN:	/* no intelligence */
				poisonf = 0;
				break;
			case RT6_HORZN:
				continue;
				/* never reached */
			default:	/* case RT6_POISON: */
				poisonf = 1;
				break;
			}
		} else
			poisonf = 0;

		for (rtp = gp->gw_dest; rtp; rtp = rtp->rp_ndst) {
			if (state && (rtp->rp_state & state) == 0)
				continue;

			addrp = &(rtp->rp_leaf->key);
			if (IN6_IS_ADDR_SITELOCAL(addrp) &&
			    !(ifp->if_config->int_site))
				continue;
			if (IN6_IS_ADDR_UNSPECIFIED(addrp) &&
			    rtp->rp_len == MAX_PREFLEN)
				continue;	/* already propagated */

			CHECK_AGR(addrp);
			if (agp) {
				if (agp->agr_sent == AGR_SENT)
					continue;	/* already sent */
				r_tmp.rip6_prflen = agp->agr_pref.prf_len;
				r_tmp.rip6_addr = agp->agr_pref.prf_addr;
				r_tmp.rip6_metric = agp->agr_stat.rts_metric +
					ifp->if_config->int_metric_out;
				r_tmp.rip6_rtag = htons(agp->agr_stat.rts_tagval);
				agp->agr_sent = AGR_SENT;
			} else {
				if (agronly)
					continue; /* send only aggregation */
				r_tmp.rip6_prflen = rtp->rp_len;
				r_tmp.rip6_addr = *addrp;
				r_tmp.rip6_metric = poisonf
					? HOPCOUNT_INFINITY
					: rtp->rp_metric + ifp->if_config->int_metric_out;
				r_tmp.rip6_rtag = htons(rtp->rp_tag);
			}
			if (r_tmp.rip6_metric > HOPCOUNT_INFINITY)
				r_tmp.rip6_metric = HOPCOUNT_INFINITY;

			new_nhp = &ci_info(ifp->if_cinfo).ipi6_addr;
			CHECK_NHOP(r_tmp);
			WRITE_PAIR(r_tmp);
		}		/* for each rtp */
	}			/* for each gateway */

 lastone:
	if (num_entries) {
		mh->msg_iov->iov_len = ((char *)rp - (char *)mh->msg_iov->iov_base);
		send_message(mh, ifp, agronly);
	}
	return;
}
Example #23
0
/*++

Routine Name: 

    GetIPv6DefaultGateway

Routine Description:

    Retrieve the IPv6 default gateway for a given adapter.  This uses the IPv6 IOCTL interface to 
    query the route table.  In future releases, this should be done through IPHLPAPI, since the IOCTL
    interface can change from release to release.  However, v6 compatible routines for retrieving route
    table info have not been defined yet...

Arguments:

    pAA:	  Adapter address struct returned from GetAdaptersAddresses()
    szAddr:	  String buffer to hold address (must be INET6_ADDRSTRLEN chars)

Return Value:

    TRUE if successful, FALSE if default gateway could not be retrieved.

--*/
BOOL
GetIPv6DefaultGateway(PIP_ADAPTER_ADDRESSES pAA, TCHAR *szAddr)
{
    HANDLE                  hIPv6;
    IPV6_QUERY_ROUTE_TABLE  QueryRouteTable, NextQueryRouteTable;
    IPV6_INFO_ROUTE_TABLE   RTE;
    ULONG                   ulBytesReturned;
    SOCKADDR_IN6            Addr;
    BOOL                    bRet = FALSE;


    hIPv6 = CreateFileW(
                       DD_IPV6_DEVICE_NAME,
                       GENERIC_WRITE,                      // access mode
                       FILE_SHARE_READ | FILE_SHARE_WRITE,
                       NULL,                               // security attributes
                       OPEN_EXISTING,
                       0,                                  // flags & attributes
                       NULL);                              // template file

    if (hIPv6 == INVALID_HANDLE_VALUE) {
        DEBUGMSG(ZONE_ERROR,(TEXT("!Error opening IPv6 driver to get default gateway\r\n")));
        return FALSE;
    }

    NextQueryRouteTable.Neighbor.IF.Index = 0;

    for (;;) {
        QueryRouteTable = NextQueryRouteTable;

        if (!DeviceIoControl(
                            hIPv6, 
                            IOCTL_IPV6_QUERY_ROUTE_TABLE,
                            &QueryRouteTable, 
                            sizeof(QueryRouteTable),
                            &RTE, 
                            sizeof(RTE), 
                            &ulBytesReturned,
                            NULL)) {
            DEBUGMSG(ZONE_ERROR,(TEXT("!Error querying IPv6 driver to get default gateway\r\n")));
            break;
        }

        NextQueryRouteTable = RTE.Next;

        if (QueryRouteTable.Neighbor.IF.Index != 0) {
            RTE.This = QueryRouteTable;

            if ((RTE.This.PrefixLength == 0) &&
                (pAA->Ipv6IfIndex == RTE.This.Neighbor.IF.Index)) {
                // Found a valid router
                Addr.sin6_family   = AF_INET6;
                Addr.sin6_addr     = RTE.This.Neighbor.Address;
                Addr.sin6_port     = 0;

                if (IN6_IS_ADDR_LINKLOCAL(&(Addr.sin6_addr))) {
                    Addr.sin6_scope_id = pAA->ZoneIndices[ScopeLevelLink];
                } else
                    if (IN6_IS_ADDR_SITELOCAL(&(Addr.sin6_addr))) {
                    Addr.sin6_scope_id = pAA->ZoneIndices[ScopeLevelSite];
                } else {
                    Addr.sin6_scope_id = 0;
                }

                GetIPv6AddressString(szAddr,&Addr);
                bRet = TRUE;
                break;
            }

        }

        if (NextQueryRouteTable.Neighbor.IF.Index == 0)
            break;
    }

    CloseHandle(hIPv6);
    return bRet;
}