Exemplo n.º 1
0
static int
_getifaddrs(int domain, char* buffer, size_t len, struct ifaddrs** previous)
{
	int socket = ::socket(domain, SOCK_DGRAM, 0);
	if (socket < 0)
		return -1;
	FileDescriptorCloser closer(socket);

	// Get interfaces configuration
	ifconf config;
	config.ifc_buf = buffer;
	config.ifc_len = len;
	if (ioctl(socket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0)
		return -1;

	ifreq* interfaces = (ifreq*)buffer;
	ifreq* end = (ifreq*)(buffer + config.ifc_len);

	while (interfaces < end) {
		struct ifaddrs* current = new(std::nothrow) ifaddrs();
		if (current == NULL) {
			errno = B_NO_MEMORY;
			return -1;
		}

		// Chain this interface with the next one
		current->ifa_next = *previous;
		*previous = current;

		current->ifa_name = strdup(interfaces[0].ifr_name);
		current->ifa_addr = copy_address(interfaces[0].ifr_addr);
		current->ifa_netmask = NULL;
		current->ifa_dstaddr = NULL;
		current->ifa_data = NULL;

		ifreq request;
		strlcpy(request.ifr_name, interfaces[0].ifr_name, IF_NAMESIZE);

		if (ioctl(socket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) == 0)
			current->ifa_flags = request.ifr_flags;
		if (ioctl(socket, SIOCGIFNETMASK, &request, sizeof(struct ifreq))
				== 0) {
			current->ifa_netmask = copy_address(request.ifr_mask);
		}
		if (ioctl(socket, SIOCGIFDSTADDR, &request, sizeof(struct ifreq))
				== 0) {
			current->ifa_dstaddr = copy_address(request.ifr_dstaddr);
		}

		// Move on to next interface
		interfaces = (ifreq*)((uint8_t*)interfaces
			+ _SIZEOF_ADDR_IFREQ(interfaces[0]));
	}

	return 0;
}
Exemplo n.º 2
0
status_t
BNetworkRoster::GetNextInterface(uint32* cookie,
                                 BNetworkInterface& interface) const
{
    // TODO: think about caching the interfaces!

    if (cookie == NULL)
        return B_BAD_VALUE;

    // get a list of all interfaces

    int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
    if (socket < 0)
        return errno;

    FileDescriptorCloser closer(socket);

    ifconf config;
    config.ifc_len = sizeof(config.ifc_value);
    if (ioctl(socket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0)
        return errno;

    size_t count = (size_t)config.ifc_value;
    if (count == 0)
        return B_BAD_VALUE;

    char* buffer = (char*)malloc(count * sizeof(struct ifreq));
    if (buffer == NULL)
        return B_NO_MEMORY;

    MemoryDeleter deleter(buffer);

    config.ifc_len = count * sizeof(struct ifreq);
    config.ifc_buf = buffer;
    if (ioctl(socket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0)
        return errno;

    ifreq* interfaces = (ifreq*)buffer;
    ifreq* end = (ifreq*)(buffer + config.ifc_len);

    for (uint32 i = 0; interfaces < end; i++) {
        interface.SetTo(interfaces[0].ifr_name);
        if (i == *cookie) {
            (*cookie)++;
            return B_OK;
        }

        interfaces = (ifreq*)((uint8*)interfaces
                              + _SIZEOF_ADDR_IFREQ(interfaces[0]));
    }

    return B_BAD_VALUE;
}
Exemplo n.º 3
0
static int
GetIfConfig(AG_NetAddrList *nal)
{
#ifdef HAVE_SIOCGIFCONF
    enum ag_net_addr_family af;
    AG_NetAddr *na;
    char buf[4096];
    struct ifconf conf;
    struct ifreq *ifr;
    int sock;

    AG_NetAddrListClear(nal);

    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        AG_SetError("socket: %s", strerror(errno));
        return (-1);
    }
    conf.ifc_len = sizeof(buf);
    conf.ifc_buf = (caddr_t)buf;
    if (ioctl(sock, SIOCGIFCONF, &conf) < 0) {
        AG_SetError("SIOCGIFCONF: %s", strerror(errno));
        goto fail;
    }

#if !defined(_SIZEOF_ADDR_IFREQ)
#define _SIZEOF_ADDR_IFREQ sizeof
#endif
    for (ifr = (struct ifreq *)buf;
            (char *)ifr < &buf[conf.ifc_len];
            ifr = (struct ifreq *)((char *)ifr + _SIZEOF_ADDR_IFREQ(*ifr))) {
        if ((af = GetAddrFamily(ifr->ifr_addr.sa_family)) == 0) {
            continue;
        }
        if ((na = SockAddrToNetAddr(af, &ifr->ifr_addr)) == NULL) {
            goto fail;
        }
        na->port = 0;
        TAILQ_INSERT_TAIL(nal, na, addrs);
    }
    close(sock);
    return (0);
fail:
    close(sock);
    return (-1);
#else
    AG_SetError("GetIfConfig: SIOCGIFCONF unavailable");
    return (-1);
#endif /* !HAVE_SIOCGIFCONF */
}
Exemplo n.º 4
0
Arquivo: test.c Projeto: poojaindi/SFS
int main (int argc, const char* argv[])
{
  // File descriptor for socket
  int socketfd;
  struct ifconf conf;
  char data[4096];
  struct ifreq *ifr;
  char addrbuf[1024];
  int i;

  printf("Opening socket...");
  socketfd = socket(AF_INET, SOCK_DGRAM, 0);
  if (socketfd >= 0) {
    printf(" OK\n");
    conf.ifc_len = sizeof(data);
    conf.ifc_buf = (caddr_t) data;
    if (ioctl(socketfd,SIOCGIFCONF,&conf) < 0) {
      perror("ioctl");
    }

    printf("Discovering interfaces...\n");
    i = 0;
    ifr = (struct ifreq*)data;
    while ((char*)ifr < data+conf.ifc_len) {
      switch (ifr->ifr_addr.sa_family) {
        case AF_INET:
            ++i;
            printf("%d. %s : %s\n", i, ifr->ifr_name, inet_ntop(ifr->ifr_addr.sa_family, &((struct sockaddr_in*)&ifr->ifr_addr)->sin_addr, addrbuf, sizeof(addrbuf)));
            break;
#if 0
        case AF_INET6:
            ++i;
            printf("%d. %s : %s\n", i, ifr->ifr_name, inet_ntop(ifr->ifr_addr.sa_family, &((struct sockaddr_in6*)&ifr->ifr_addr)->sin6_addr, addrbuf, sizeof(addrbuf)));
            break;
#endif
      }
      ifr = (struct ifreq*)((char*)ifr +_SIZEOF_ADDR_IFREQ(*ifr));
    }
    close(socketfd);
  }
  else {
    printf(" Failed!\n");
  }
  return 0;
}
Exemplo n.º 5
0
static int MPIDI_CH3U_GetIPInterface( MPIDU_Sock_ifaddr_t *ifaddr, int *found )
{
    char *buf_ptr, *ptr;
    int buf_len, buf_len_prev;
    int fd;
    MPIDU_Sock_ifaddr_t myifaddr;
    int nfound = 0, foundLocalhost = 0;
    /* We predefine the LSB and MSB localhost addresses */
    unsigned int localhost = 0x0100007f;
#ifdef WORDS_BIGENDIAN
    unsigned int MSBlocalhost = 0x7f000001;
#endif

    if (dbg_ifname < 0) {
	int rc;
	rc = MPL_env2bool( "MPICH_DBG_IFNAME", &dbg_ifname );
	if (rc != 1) dbg_ifname = 0;
    }

    fd = socket(AF_INET, SOCK_DGRAM, 0);
    if (fd < 0) {
	fprintf( stderr, "Unable to open an AF_INET socket\n" );
	return 1;
    }

    /* Use MSB localhost if necessary */
#ifdef WORDS_BIGENDIAN
    localhost = MSBlocalhost;
#endif
    

    /*
     * Obtain the interface information from the operating system
     *
     * Note: much of this code is borrowed from W. Richard Stevens' book
     * entitled "UNIX Network Programming", Volume 1, Second Edition.  See
     * section 16.6 for details.
     */
    buf_len = NUM_IFREQS * sizeof(struct ifreq);
    buf_len_prev = 0;

    for(;;)
    {
	struct ifconf			ifconf;
	int				rc;

	buf_ptr = (char *) MPIU_Malloc(buf_len);
	if (buf_ptr == NULL) {
	    fprintf( stderr, "Unable to allocate %d bytes\n", buf_len );
	    return 1;
	}
	
	ifconf.ifc_buf = buf_ptr;
	ifconf.ifc_len = buf_len;

	rc = ioctl(fd, SIOCGIFCONF, &ifconf);
	if (rc < 0) {
	    if (errno != EINVAL || buf_len_prev != 0) {
		fprintf( stderr, "Error from ioctl = %d\n", errno );
		perror(" Error is: ");
		return 1;
	    }
	}
        else {
	    if (ifconf.ifc_len == buf_len_prev) {
		buf_len = ifconf.ifc_len;
		break;
	    }

	    buf_len_prev = ifconf.ifc_len;
	}
	
	MPIU_Free(buf_ptr);
	buf_len += NUM_IFREQS * sizeof(struct ifreq);
    }
	
    /*
     * Now that we've got the interface information, we need to run through
     * the interfaces and check out the ip addresses.  If we find a
     * unique, non-lcoal host (127.0.0.1) address, return that, otherwise
     * return nothing.
     */
    ptr = buf_ptr;

    while(ptr < buf_ptr + buf_len) {
	struct ifreq *			ifreq;

	ifreq = (struct ifreq *) ptr;

	if (dbg_ifname) {
	    fprintf( stdout, "%10s\t", ifreq->ifr_name ); fflush(stdout);
	}
	
	if (ifreq->ifr_addr.sa_family == AF_INET) {
	    struct in_addr		addr;

	    addr = ((struct sockaddr_in *) &(ifreq->ifr_addr))->sin_addr;
	    if (dbg_ifname) {
		fprintf( stdout, "IPv4 address = %08x (%s)\n", addr.s_addr, 
			 inet_ntoa( addr ) );
	    }

	    if (addr.s_addr == localhost && dbg_ifname) {
		fprintf( stdout, "Found local host\n" );
	    }
	    /* Save localhost if we find it.  Let any new interface 
	       overwrite localhost.  However, if we find more than 
	       one non-localhost interface, then we'll choose none for the 
	       interfaces */
	    if (addr.s_addr == localhost) {
		foundLocalhost = 1;
		if (nfound == 0) {
		    myifaddr.type = AF_INET;
		    myifaddr.len  = 4;
		    MPIU_Memcpy( myifaddr.ifaddr, &addr.s_addr, 4 );
		}
	    }
	    else {
		nfound++;
		myifaddr.type = AF_INET;
		myifaddr.len  = 4;
		MPIU_Memcpy( myifaddr.ifaddr, &addr.s_addr, 4 );
	    }
	}
	else {
	    if (dbg_ifname) {
		fprintf( stdout, "\n" );
	    }
	}

	/*
	 *  Increment pointer to the next ifreq; some adjustment may be
	 *  required if the address is an IPv6 address
	 */
	/* This is needed for MAX OSX */
#ifdef _SIZEOF_ADDR_IFREQ
	ptr += _SIZEOF_ADDR_IFREQ(*ifreq);
#else
	ptr += sizeof(struct ifreq);
	
#	if defined(AF_INET6)
	{
	    if (ifreq->ifr_addr.sa_family == AF_INET6)
	    {
		ptr += sizeof(struct sockaddr_in6) - sizeof(struct sockaddr);
	    }
	}
#	endif
#endif
    }

    MPIU_Free(buf_ptr);
    close(fd);
    
    /* If we found a unique address, use that */
    if (nfound == 1 || (nfound == 0 && foundLocalhost == 1)) {
	*ifaddr = myifaddr;
	*found  = 1;
    }
    else {
	*found  = 0;
    }

    return 0;
}
Exemplo n.º 6
0
/*
 *	First, we find all shaper devices and down them. Then we
 *	down all real interfaces. This is because the comment in the
 *	shaper driver says "if you down the shaper device before the
 *	attached inerface your computer will follow".
 */
int ifdown(void)
{
    char ifr_buf[sizeof(struct ifreq) * MAX_IFS];
    char *ifr_end;
    struct ifconf ifc;
    int fd;
    int shaper;

    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
        fprintf(stderr, "ifdown: ");
        perror("socket");
        return -1;
    }
    ifc.ifc_len = sizeof(ifr_buf);
    ifc.ifc_buf = ifr_buf;

    if (ioctl(fd, SIOCGIFCONF, &ifc) < 0) {
        fprintf(stderr, "ifdown: ");
        perror("SIOCGIFCONF");
        close(fd);
        return -1;
    }
    ifr_end = ifr_buf + ifc.ifc_len;

    for (shaper = 1; shaper >= 0; shaper--) {
        char *ifr_next = ifr_buf;

        while (ifr_next < ifr_end) {
            struct ifreq *ifr;
            int flags;

            ifr = (struct ifreq *)ifr_next;
            ifr_next += _SIZEOF_ADDR_IFREQ(*ifr);

            if ((strncmp(ifr->ifr_name, "shaper", 6) == 0)
                    != shaper) continue;

            if (strncmp(ifr->ifr_name, "lo", 2) == 0)
                continue;
            if (strchr(ifr->ifr_name, ':') != NULL)
                continue;

            /* Read interface flags */
            if (ioctl(fd, SIOCGIFFLAGS, ifr) < 0) {
                fprintf(stderr, "ifdown: shutdown ");
                perror(ifr->ifr_name);
                continue;
            }
            /*
             * Expected in <net/if.h> according to
             * "UNIX Network Programming".
             */
#ifdef ifr_flagshigh
            flags = (ifr->ifr_flags & 0xffff) |
                    (ifr->ifr_flagshigh << 16);
#else
            flags = ifr->ifr_flags;
#endif
            if (flags & IFF_UP) {
                flags &= ~(IFF_UP);
#ifdef ifr_flagshigh
                ifr->ifr_flags = flags & 0xffff;
                ifr->ifr_flagshigh = flags >> 16;
#else
                ifr->ifr_flags = flags;
#endif
                if (ioctl(fd, SIOCSIFFLAGS, ifr) < 0) {
                    fprintf(stderr, "ifdown: shutdown ");
                    perror(ifr->ifr_name);
                }
            }
        }
    }
Exemplo n.º 7
0
/* for when all other options fail, as can happen on Android,
   if the permissions for the socket-based method are broken.
   Down side is that it while it gets the interface name and
   broadcast, it doesn't get the local address for that
   interface. 
*/
int scrapeProcNetRoute()
{
  if (debug & DEBUG_OVERLAYINTERFACES) DEBUG("called");

  FILE *f=fopen("/proc/net/route","r");
  if (!f) return WHY_perror("fopen(\"/proc/net/route\")");

  char line[1024],name[1024],dest[1024],mask[1024];

  /* skip header line */
  line[0]=0; fgets(line,1024,f);

  line[0]=0; fgets(line,1024,f);
  while(line[0]) {
    int r;
    if ((r=sscanf(line,"%s %s %*s %*s %*s %*s %*s %s",name,dest,mask))==3)
      {
	struct in_addr addr = {.s_addr=strtol(dest,NULL,16)};
	struct in_addr netmask = {.s_addr=strtol(mask,NULL,16)};
	
	overlay_interface_register(name,addr,netmask);
      }

    line[0]=0; fgets(line,1024,f);    
  }
  fclose(f);
  return 0;
}
#endif

#ifdef SIOCGIFCONF

/* Not present in Linux */
#ifndef _SIZEOF_ADDR_IFREQ
#define _SIZEOF_ADDR_IFREQ(x) sizeof(struct ifreq)
#endif

int
lsif(void) {
  char            buf[8192];
  struct ifconf   ifc;
  int             sck, nInterfaces, ofs;
  struct ifreq    *ifr;
  struct in_addr  addr, netmask;

  if (debug & DEBUG_OVERLAYINTERFACES) DEBUG("called");

  /* Get a socket handle. */
  sck = socket(PF_INET, SOCK_DGRAM, 0);
  if(sck < 0) {
    WHY_perror("socket");
    return 1;
  }
 
  /* Query available interfaces. */
  ifc.ifc_len = sizeof(buf);
  ifc.ifc_buf = buf;
  if(ioctl(sck, SIOCGIFCONF, &ifc) < 0) {
    WHY_perror("ioctl(SIOCGIFCONF)");
    close(sck);
    return 1;
  }

  /* Iterate through the list of interfaces. */
  nInterfaces = 0;
  ofs = 0;
  
  while (ofs < ifc.ifc_len && ofs < sizeof(buf)) {
    ifr = (struct ifreq *)(ifc.ifc_ifcu.ifcu_buf + ofs);
    ofs += _SIZEOF_ADDR_IFREQ(*ifr);

    /* We're only interested in IPv4 addresses */
    if (ifr->ifr_ifru.ifru_addr.sa_family != AF_INET) {
      if (debug & DEBUG_OVERLAYINTERFACES) DEBUGF("Skipping non-AF_INET address on %s", ifr->ifr_name);
      continue;
    }
  
    addr = ((struct sockaddr_in *)&ifr->ifr_ifru.ifru_addr)->sin_addr;
    
    /* Get interface flags */
    if (ioctl(sck, SIOCGIFFLAGS, ifr) == -1)
      FATAL_perror("ioctl(SIOCGIFFLAGS)");
    
    /* Not broadcast? Not interested.. */
    if ((ifr->ifr_ifru.ifru_flags & IFF_BROADCAST) == 0) {
      if (debug & DEBUG_OVERLAYINTERFACES) DEBUGF("Skipping non-broadcast address on %s", ifr->ifr_name);
      continue;
    }
    
    /* Get netmask */
    if (ioctl(sck, SIOCGIFNETMASK, ifr, sizeof(*ifr)) != 0) {
      WHY_perror("ioctl(SIOCGIFNETMASK)");
      continue;
    }
    netmask = ((struct sockaddr_in *)&ifr->ifr_ifru.ifru_addr)->sin_addr;
    
    overlay_interface_register(ifr->ifr_name, addr, netmask);
    nInterfaces++;
  }
  
  if (debug & DEBUG_OVERLAYINTERFACES) DEBUGF("Examined %d interface addresses", nInterfaces);

  close(sck); 
  return 0;
}

#endif

#ifdef HAVE_IFADDRS_H
int
doifaddrs(void) {
  struct ifaddrs	*ifaddr, *ifa;
  char 			*name;
  struct in_addr	addr, netmask;
  
  if (debug & DEBUG_OVERLAYINTERFACES) DEBUGF("called");
  
  if (getifaddrs(&ifaddr) == -1)
    return WHY_perror("getifaddr()");

  for (ifa = ifaddr; ifa != NULL ; ifa = ifa->ifa_next) {
    /* We're only interested in IPv4 addresses */
    if (ifa->ifa_addr->sa_family != AF_INET) {
      if (debug & DEBUG_OVERLAYINTERFACES) DEBUGF("Skipping non-AF_INET address on %s", ifa->ifa_name);
      continue;
    }
    
    /* Not broadcast? Not interested.. */
    if ((ifa->ifa_flags & IFF_BROADCAST) == 0) {
      if (debug & DEBUG_OVERLAYINTERFACES) DEBUGF("Skipping non-broadcast address on %s", ifa->ifa_name);
      continue;
    }

    name = ifa->ifa_name;
    addr = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr;
    netmask = ((struct sockaddr_in *)ifa->ifa_netmask)->sin_addr;

    overlay_interface_register(name, addr, netmask);
  }
  freeifaddrs(ifaddr);

  return 0;
}
Exemplo n.º 8
0
/* this function returns the total number of interface addresses
** the buffer has to be passed in by the caller
*/
#else /* UKERNEL indirectly, on DARWIN or XBSD */
static int
rx_getAllAddr_internal(afs_uint32 buffer[], int maxSize, int loopbacks)
{
    int s;
    int i, len, count = 0;
    struct ifconf ifc;
    struct ifreq ifs[NIFS], *ifr;
    struct sockaddr_in *a;
    /* can't ever be AFS_DARWIN_ENV or AFS_XBSD_ENV, no? */
#if    defined(AFS_AIX41_ENV) || defined (AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
    char *cp, *cplim, *cpnext;	/* used only for AIX 41 */
#endif

    s = socket(AF_INET, SOCK_DGRAM, 0);
    if (s < 0)
	return 0;
    ifc.ifc_len = sizeof(ifs);
    ifc.ifc_buf = (caddr_t) ifs;
    i = ioctl(s, SIOCGIFCONF, &ifc);
    if (i < 0)
	return 0;
    len = ifc.ifc_len / sizeof(struct ifreq);
    if (len > NIFS)
	len = NIFS;
#if    defined(AFS_AIX41_ENV) || defined (AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
    if (ifc.ifc_len > sizeof(ifs))	/* safety check */
	ifc.ifc_len = sizeof(ifs);
    for (cp = (char *)ifc.ifc_buf, cplim = ifc.ifc_buf + ifc.ifc_len;
	 cp < cplim;
#if defined(AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
	 cp += _SIZEOF_ADDR_IFREQ(*ifr)
#else
#ifdef AFS_AIX51_ENV
	 cp = cpnext
#else
	 cp += sizeof(ifr->ifr_name) + MAX(a->sin_len, sizeof(*a))
#endif
#endif
	) 
#else
    for (i = 0; i < len; ++i) 
#endif
    {
#if    defined(AFS_AIX41_ENV) || defined (AFS_DARWIN_ENV) || defined(AFS_XBSD_ENV)
	ifr = (struct ifreq *)cp;
#else
	ifr = &ifs[i];
#endif
	a = (struct sockaddr_in *)&ifr->ifr_addr;
#ifdef AFS_AIX51_ENV
	cpnext = cp + sizeof(ifr->ifr_name) + MAX(a->sin_len, sizeof(*a));
#endif
	if (a->sin_family != AF_INET)
	    continue;
	if (ioctl(s, SIOCGIFFLAGS, ifr) < 0) {
	    perror("SIOCGIFFLAGS");
	    continue;		/* ignore this address */
	}
	if (a->sin_addr.s_addr != 0) {
            if (!loopbacks) {
                if (a->sin_addr.s_addr == htonl(0x7f000001)) 
		    continue;	/* skip loopback address as well. */
            } else {
                if (ifr->ifr_flags & IFF_LOOPBACK) 
		    continue;	/* skip aliased loopbacks as well. */
	    }
	    if (count >= maxSize)	/* no more space */
		dpf(("Too many interfaces..ignoring 0x%x\n",
		       a->sin_addr.s_addr));
	    else
		buffer[count++] = a->sin_addr.s_addr;
	}
    }
    close(s);
    return count;
}
Exemplo n.º 9
0
//*****************************************************************************
//
NETADDRESS_s NETWORK_GetLocalAddress( void )
{
	char				szBuffer[512];
	struct sockaddr_in	SocketAddress;
	NETADDRESS_s		Address;
	int					iNameLength;

#ifndef __WINE__
	gethostname( szBuffer, 512 );
#endif
	szBuffer[512-1] = 0;

	// Convert the host name to our local 
	bool stringToAddress = NETWORK_StringToAddress( szBuffer, &Address );

	iNameLength = sizeof( SocketAddress );
#ifndef	WIN32
	if ( getsockname ( g_NetworkSocket, (struct sockaddr *)&SocketAddress, (socklen_t *)&iNameLength) == -1 )
#else
	if ( getsockname ( g_NetworkSocket, (struct sockaddr *)&SocketAddress, &iNameLength ) == -1 )
#endif
	{
		Printf( "NETWORK_GetLocalAddress: Error getting socket name: %s", strerror( errno ));
	}

#ifdef unix
	// [BB] The "gethostname -> gethostbyname" trick didn't reveal the local IP.
	// Now we need to resort to something more complicated.
	if ( stringToAddress == false );
	{
#ifndef __FreeBSD__
		unsigned char      *u;
		int                size  = 1;
		struct ifreq       *ifr;
		struct ifconf      ifc;
		struct sockaddr_in sa;
		
		ifc.ifc_len = IFRSIZE;
		ifc.ifc_req = NULL;
		
		do {
			++size;
			/* realloc buffer size until no overflow occurs  */
			if (NULL == (ifc.ifc_req = (ifreq*)realloc(ifc.ifc_req, IFRSIZE)))
			{
				fprintf(stderr, "Out of memory.\n");
				exit(EXIT_FAILURE);
			}
			ifc.ifc_len = IFRSIZE;
			if (ioctl(g_NetworkSocket, SIOCGIFCONF, &ifc))
			{
				perror("ioctl SIOCFIFCONF");
				exit(EXIT_FAILURE);
			}
		} while  (IFRSIZE <= ifc.ifc_len);
		
		ifr = ifc.ifc_req;
		for (;(char *) ifr < (char *) ifc.ifc_req + ifc.ifc_len; ++ifr)
		{
		
			if (ifr->ifr_addr.sa_data == (ifr+1)->ifr_addr.sa_data)
			{
				continue;  /* duplicate, skip it */
			}
		
			if (ioctl(g_NetworkSocket, SIOCGIFFLAGS, ifr))
			{
				continue;  /* failed to get flags, skip it */
			}
		
			Printf("Found interface %s", ifr->ifr_name);
			Printf(" with IP address: %s\n", inet_ntoa(inaddrr(ifr_addr.sa_data)));
			*(int *)&Address.abIP = *(int *)&inaddrr(ifr_addr.sa_data);
			if ( Address.abIP[0] != 127 )
			{
				Printf ( "Using IP address of interface %s as local address.\n", ifr->ifr_name );
				break;
			}
		}
		if ( ifc.ifc_req != NULL )
			free ( ifc.ifc_req );
#else
		struct ifreq       *ifr;
		struct ifconf      ifc;
		bzero(&ifc, sizeof(ifc));
		unsigned int n = 1;
		struct ifreq *lifr;
		ifr = (ifreq*)calloc( ifc.ifc_len, sizeof(*ifr) );
		do
		{
			n *= 2;
			ifr = (ifreq*)realloc( ifr, PAGE_SIZE * n );
			bzero( ifr, PAGE_SIZE * n );
			ifc.ifc_req = ifr;
			ifc.ifc_len = n * PAGE_SIZE;
		} while( ( ioctl( g_NetworkSocket, SIOCGIFCONF, &ifc ) == -1 ) || ( ifc.ifc_len >= ( (n-1) * PAGE_SIZE)) );
		
		lifr = (struct ifreq *)&ifc.ifc_buf[ifc.ifc_len];
		
		while (ifr < lifr)
		{
			struct sockaddr *sa = &ifr->ifr_ifru.ifru_addr;
			if( AF_INET == sa->sa_family )
			{
				struct sockaddr_in dummysa;
				in_addr inAddr = *(struct in_addr *) &ifr->ifr_addr.sa_data[sizeof dummysa.sin_port];
	
				Printf("Found interface %s", ifr->ifr_name);
				Printf(" with IP address: %s\n", inet_ntoa(inAddr));
				*(int *)&Address.abIP = *(int *)&inAddr;
				if ( Address.abIP[0] != 127 )
				{
					Printf ( "Using IP address of interface %s as local address.\n", ifr->ifr_name );
					break;
				}
			 }
	 	ifr = (struct ifreq *)(((char *)ifr) + _SIZEOF_ADDR_IFREQ(*ifr));
 		}
#endif
	}
#endif

	Address.usPort = SocketAddress.sin_port;
	return ( Address );
}
Exemplo n.º 10
0
int
lsif(void) {
  char            buf[8192];
  struct ifconf   ifc;
  int             sck;
  struct ifreq    *ifr;
  struct in_addr  netmask;
  struct socket_address addr, broadcast;
  bzero(&addr, sizeof(addr));
  bzero(&broadcast, sizeof(broadcast));
  
  if (config.debug.overlayinterfaces) DEBUG("called");

  /* Get a socket handle. */
  sck = socket(PF_INET, SOCK_DGRAM, 0);
  if(sck < 0) {
    WHY_perror("socket");
    return 1;
  }
 
  /* Query available interfaces. */
  ifc.ifc_len = sizeof buf;
  ifc.ifc_buf = buf;
  if(ioctl(sck, SIOCGIFCONF, &ifc) < 0) {
    WHY_perror("ioctl(SIOCGIFCONF)");
    close(sck);
    return 1;
  }

  broadcast.addrlen = sizeof(addr.inet);
  broadcast.inet.sin_family = AF_INET;
  
  /* Iterate through the list of interfaces. */
  unsigned nInterfaces = 0;
  unsigned ofs = 0;
  while (ofs < (unsigned)ifc.ifc_len && ofs < sizeof buf) {
    ifr = (struct ifreq *)(ifc.ifc_ifcu.ifcu_buf + ofs);
    ofs += _SIZEOF_ADDR_IFREQ(*ifr);

    /* We're only interested in IPv4 addresses */
    if (ifr->ifr_ifru.ifru_addr.sa_family != AF_INET) {
      if (config.debug.overlayinterfaces) DEBUGF("Skipping non-AF_INET address on %s", ifr->ifr_name);
      continue;
    }
    
    addr.addrlen = sizeof(addr.inet);
    bcopy(&ifr->ifr_ifru.ifru_addr, &addr.addr, addr.addrlen);
    
    /* Get interface flags */
    if (ioctl(sck, SIOCGIFFLAGS, ifr) == -1)
      FATAL_perror("ioctl(SIOCGIFFLAGS)");
    
    /* Not broadcast? Not interested.. */
    if ((ifr->ifr_ifru.ifru_flags & IFF_BROADCAST) == 0) {
      if (config.debug.overlayinterfaces) DEBUGF("Skipping non-broadcast address on %s", ifr->ifr_name);
      continue;
    }
    
    /* Get netmask */
    if (ioctl(sck, SIOCGIFNETMASK, ifr, sizeof(*ifr)) != 0) {
      WHY_perror("ioctl(SIOCGIFNETMASK)");
      continue;
    }
    netmask = ((struct sockaddr_in *)&ifr->ifr_ifru.ifru_addr)->sin_addr;
    
    broadcast.inet.sin_addr.s_addr=addr.inet.sin_addr.s_addr | ~netmask.s_addr;
    
    overlay_interface_register(ifr->ifr_name, &addr, &broadcast);
    nInterfaces++;
  }
  
  if (config.debug.overlayinterfaces) DEBUGF("Examined %u interface addresses", nInterfaces);

  close(sck); 
  return 0;
}
Exemplo n.º 11
0
/*! Returns a chained list of all interfaces.

	We follow BSD semantics, and only return one entry per interface,
	not per address; since this is mainly used by NetBSD's netresolv, it's
	probably what it expects.
*/
int
getifaddrs(struct ifaddrs** _ifaddrs)
{
    if (_ifaddrs == NULL) {
        errno = B_BAD_VALUE;
        return -1;
    }

    int socket = ::socket(AF_INET, SOCK_DGRAM, 0);
    if (socket < 0)
        return -1;

    FileDescriptorCloser closer(socket);

    // Get interface count
    ifconf config;
    config.ifc_len = sizeof(config.ifc_value);
    if (ioctl(socket, SIOCGIFCOUNT, &config, sizeof(struct ifconf)) < 0)
        return -1;

    size_t count = (size_t)config.ifc_value;
    if (count == 0) {
        errno = B_BAD_VALUE;
        return -1;
    }

    // Allocate a buffer for ifreqs for all interfaces
    char* buffer = (char*)malloc(count * sizeof(struct ifreq));
    if (buffer == NULL) {
        errno = B_NO_MEMORY;
        return -1;
    }

    MemoryDeleter deleter(buffer);

    // Get interfaces configuration
    config.ifc_len = count * sizeof(struct ifreq);
    config.ifc_buf = buffer;
    if (ioctl(socket, SIOCGIFCONF, &config, sizeof(struct ifconf)) < 0)
        return -1;

    ifreq* interfaces = (ifreq*)buffer;
    ifreq* end = (ifreq*)(buffer + config.ifc_len);
    struct ifaddrs* previous = NULL;

    for (uint32_t i = 0; interfaces < end; i++) {
        struct ifaddrs* current = new(std::nothrow) ifaddrs();
        if (current == NULL) {
            freeifaddrs(previous);
            errno = B_NO_MEMORY;
            return -1;
        }

        // Chain this interface with the next one
        current->ifa_next = previous;
        previous = current;

        current->ifa_name = strdup(interfaces[0].ifr_name);
        current->ifa_addr = copy_address(interfaces[0].ifr_addr);
        current->ifa_netmask = NULL;
        current->ifa_dstaddr = NULL;
        current->ifa_data = NULL;

        ifreq request;
        strlcpy(request.ifr_name, interfaces[0].ifr_name, IF_NAMESIZE);

        if (ioctl(socket, SIOCGIFFLAGS, &request, sizeof(struct ifreq)) == 0)
            current->ifa_flags = request.ifr_flags;
        if (ioctl(socket, SIOCGIFNETMASK, &request, sizeof(struct ifreq))
                == 0) {
            current->ifa_netmask = copy_address(request.ifr_mask);
        }
        if (ioctl(socket, SIOCGIFDSTADDR, &request, sizeof(struct ifreq))
                == 0) {
            current->ifa_dstaddr = copy_address(request.ifr_dstaddr);
        }

        // Move on to next interface
        interfaces = (ifreq*)((uint8_t*)interfaces
                              + _SIZEOF_ADDR_IFREQ(interfaces[0]));
    }

    *_ifaddrs = previous;
    return 0;
}
Exemplo n.º 12
0
/*
 *  SDL_netx.cpp
 *
 *  Copyright (c) 2001 Woody Zenfell, III.

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

 *  SDL_netx is intended to provide a few capabilities (like broadcast) that
 *  SDL_net seems like it ought to support (but doesn't).
 *
 *  Created by Woody Zenfell, III on Mon Sep 24 2001.
 */
#include "config.h"
#if !defined(DISABLE_NETWORKING)

#ifndef __MWERKS__

#include <sys/types.h>

#if defined(WIN32)
# include <winsock.h>
#elif defined(__BEOS__)
# include <sys/socket.h>
# include <netinet/in.h>
#else
# include <unistd.h>
# include <sys/socket.h>
# include <netinet/in.h>
# include <net/if.h>
# if defined(__svr4__)
#  define BSD_COMP 1 // This is required to get SIOC* under Solaris
# endif
# include <sys/ioctl.h>
#endif

#endif

#include	"SDL_netx.h"

// PREPROCESSOR MACROS
// VC++6 chokes if I don't explicitly cast int* to const char* in setsockopt().
#ifdef WIN32
# define MY_TYPE_CAST (const char*)
#else
# define MY_TYPE_CAST
#endif


// Win32 allows 255.255.255.255 as broadcast, much easier
#if !defined(WIN32) && !defined(__BEOS__) && !(defined(mac) /*&& !defined(TARGET_API_MAC_CARBON)*/)
// FILE-LOCAL (static) CONSTANTS
static const int	kMaxNumBroadcastAddresses	= 8;
static const int	kIFConfigBufferSize		= 1024;	// in bytes

// FILE-LOCAL (static) STORAGE
static	bool	sCollectedBroadcastAddresses = false;			// set to true if we've tried
static	int	sNumberOfBroadcastAddresses = 0;			// set to number of valid addresses
static	long	sBroadcastAddresses[kMaxNumBroadcastAddresses];		// collection of addresses to try
// note that we only store the host-part since the packet the user wants to broadcast will specify the port.

// FILE-LOCAL (static) FUNCTIONS
static	int	SDLNetxint_CollectBroadcastAddresses(UDPsocket inSocket);
#endif

//////// START OF CODE ////////

// EXTERNALLY-VISIBLE FUNCTIONS
int
SDLNetx_EnableBroadcast(UDPsocket inSocket) {
#if !defined(WIN32) && !defined(__BEOS__) && !defined(mac) && !defined(__MWERKS__)/*&& !defined(TARGET_API_MAC_CARBON))*/
    if(!sCollectedBroadcastAddresses)
        SDLNetxint_CollectBroadcastAddresses(inSocket);
#endif

    // This works in Mac OS X and probably other BSD's... and now on Win32 (Win 98, anyway).
    // May need modification for Linux, etc.
    // Absolutely needs modification for "classic" Mac OS (i.e. Open Transport)
    // XXX: this depends on intimate carnal knowledge of the SDL_net struct _UDPsocket
    // if it changes that structure, we are hosed.  (this works with 1.2.2)
    int	theSocketFD = ((int*)inSocket)[1];
    
    // Sanity check
    if(theSocketFD < 0)
        return 0;

#if defined(__BEOS__) || defined(__MWERKS__)
	// Neither possible nor necessary
	return 0;
#else
    // Try to enable broadcast option on underlying socket
    int theOnValue = 1;

    int theResult = setsockopt(theSocketFD, SOL_SOCKET, SO_BROADCAST, MY_TYPE_CAST &theOnValue, sizeof(theOnValue));
    
    if(theResult < 0)
        return 0;
    else
        return theOnValue;
#endif
}


int
SDLNetx_DisableBroadcast(UDPsocket inSocket) {
    // This works in Mac OS X and probably other BSD's... and now in Win32 (Win 98, at least).
    // Might need modification for Linux, etc.
    // Absolutely needs modification for "classic" Mac OS (i.e. Open Transport)
    // XXX: this depends on intimate carnal knowledge of the SDL_net struct _UDPsocket
    // if it changes that structure, we are hosed.
    int	theSocketFD = ((int*)inSocket)[1];
    
    // Sanity check
    if(theSocketFD < 0)
        return 0;
    
#if defined(__BEOS__) || defined(__MWERKS__)
	// Neither possible nor necessary
	return 0;
#else
    // Try to disable broadcast option on underlying socket
    int theOffValue = 0;
    
    int theResult = setsockopt(theSocketFD, SOL_SOCKET, SO_BROADCAST, MY_TYPE_CAST &theOffValue, sizeof(theOffValue));
    
    if(theResult < 0)
        return 0;
    else
        return (theOffValue == 0) ? 1 : 0;
#endif
}


// see simpler function below for Win32
#if !defined(WIN32) && !defined(__BEOS__) && !(defined(mac) /*&& !defined(TARGET_API_MAC_CARBON)*/)
int
SDLNetx_UDP_Broadcast(UDPsocket inSocket, UDPpacket* inPacket) {
    int	theCountOfSuccessfulSends = 0;
    
    // We re-use the packet's destination-address "host" part, but don't want to trample it... so we save it
    Uint32	theSavedHostAddress = inPacket->address.host;
    
    // Write each broadcast address into the packet, in turn, and send it off.
    for(int i = 0; i < sNumberOfBroadcastAddresses; i++) {
        inPacket->address.host = sBroadcastAddresses[i];
        if(SDLNet_UDP_Send(inSocket, -1, inPacket) == 1)
            theCountOfSuccessfulSends++;
    } // for each broadcast address
    
    // restore the saved destination host-part
    inPacket->address.host = theSavedHostAddress;
    
    return theCountOfSuccessfulSends;
}
#else
// Win32 (at least, Win 98) seems to accept 255.255.255.255 as a valid broadcast address.
// I'll live with that for now.
// Also doing that for the BeOS and Mac Classic
int
SDLNetx_UDP_Broadcast(UDPsocket inSocket, UDPpacket* inPacket) {
	Uint32 theSavedHostAddress = inPacket->address.host;
	inPacket->address.host = 0xffffffff;
	int theResult = SDLNet_UDP_Send(inSocket, -1, inPacket);
	inPacket->address.host = theSavedHostAddress;
	return theResult;
}
#endif



// INTERNAL (static) FUNCTIONS
#if !defined(WIN32) && !defined(__BEOS__) && !defined(mac) && !defined(__MWERKS__)/*&& !defined(TARGET_API_MAC_CARBON))*/
int
SDLNetxint_CollectBroadcastAddresses(UDPsocket inSocket) {
    // Win or lose, we played the game.
    sCollectedBroadcastAddresses = true;
    
    // This works in Mac OS X and probably other BSD's.
    // I have no idea whether this is the right way or the best way to do this.
    // Probably needs modification for Win32, Linux, etc.
    // Absolutely needs modification for "classic" Mac OS (i.e. Open Transport)
    // XXX: this depends on intimate carnal knowledge of the SDL_net struct _UDPsocket
    // if it changes that structure, we are hosed.
    int	theSocketFD = ((int*)inSocket)[1];
    
    // Sanity check
    if(theSocketFD < 0)
        return 0;

    // Ask the system for interfaces and their addresses
    char		theRequestBuffer[kIFConfigBufferSize];
    struct ifconf	theConfigRequest;
    int			theOffset = 0;
    
    theConfigRequest.ifc_len	= sizeof(theRequestBuffer);
    theConfigRequest.ifc_buf	= theRequestBuffer;
    
    int theResult = ioctl(theSocketFD, SIOCGIFCONF, &theConfigRequest);

    if(theResult < 0)
	return 0;

    // theOffset marches through the return buffer to help us find subsequent entries
    // (entries can have various sizes, but always >= sizeof(struct ifreq)... IP entries have minimum size.)
    // The while() condition avoids misbehaving in case there's only a partial entry at the end
    // of the buffer.
    while(theConfigRequest.ifc_len - theOffset >= int(sizeof(struct ifreq))) {
        // Point at the next result
        struct ifreq*	theReq	= (struct ifreq*) &(theRequestBuffer[theOffset]);
        
        // Make sure it's an entry for IP (not AppleTalk, ARP, etc.)
        if(theReq->ifr_addr.sa_family == AF_INET) {
            // Now we may interpret the address as an IP address.
            struct sockaddr_in*	theInetAddr = (struct sockaddr_in*) &theReq->ifr_addr;

            // Who cares about the actual address?  Turn this around into a request for the interface's
            // broadcast address.
            theResult = ioctl(theSocketFD, SIOCGIFBRDADDR, theReq);

            if(theResult >= 0) {
                // we retrieved an actual broadcast address for IP networking... assume it's good.

                // make sure there's room to store another broadcast address...
                if(sNumberOfBroadcastAddresses < kMaxNumBroadcastAddresses) {
                    // We can still use theInetAddr, since it's just a reference to actual storage
                    sBroadcastAddresses[sNumberOfBroadcastAddresses] = theInetAddr->sin_addr.s_addr;
                    sNumberOfBroadcastAddresses++;
                } // room for address in array
            } // broadcast-address lookup succeeded
        } // entry is IP
        
        // Increment theOffset to point at the next entry.
        // _SIZEOF_ADDR_IFREQ() is provided in Mac OS X.  It accounts for entries whose address families
        // use long addresses.  Use theReq->ifr_addr.sa_len (and add the overhead for the rest of *theReq)
        // if it's not provided for you.
#ifdef _SIZEOF_ADDR_IFREQ
        theOffset += _SIZEOF_ADDR_IFREQ(*theReq);
#else
		theOffset += sizeof(ifreq);
#endif
    } // while more entries
    
    return sNumberOfBroadcastAddresses;
}
Exemplo n.º 13
0
main() {

#ifdef SIOCRPHYSADDR
    struct ifdevea req = { 0 };
#endif
    struct ifconf list = { 0 };
    int s = { 0 };
    int i = { 0 };
    union {
        struct ifreq a;
        char b[4096];
    } buf;
    struct ifreq* p = { 0 };
#ifdef HAS_GETIFADDRS
    struct ifaddrs* if1;
    struct ifaddrs* if2;
#endif
    memset(&buf, 0, sizeof(buf));

    s = socket(AF_UNIX, SOCK_STREAM, PF_UNSPEC);
    if (s < 0) {
       perror("socket");
       exit(1);
    }
    
#ifdef HAS_GETIFADDRS
    getifaddrs(&if1);
    for (if2 = if1; if2; if2 = if2->ifa_next)
    {
        if (if2->ifa_addr->sa_family == AF_LINK)
        {
            struct sockaddr_dl* dl = (struct sockaddr_dl*)if2->ifa_addr;
            unsigned char* mac = (unsigned char*)LLADDR(dl);
            if (dl->sdl_alen == 6) /* 48 bits */
            {
                printf("%s %02X:%02X:%02X:%02X:%02X:%02X\n",
                    if2->ifa_name,
                    mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
            }
            else if (dl->sdl_alen == 8) /* 64 bits IP over firewire */
            {
                printf("%s %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\n",
                    if2->ifa_name,
                    mac[0], mac[1], mac[2], mac[3], mac[4], mac[5], mac[6], mac[7]);
            }
            breakpoint();
        }
    }
    freeifaddrs(if1);
#endif

    list.ifc_len = sizeof(buf);
    list.ifc_req = &buf.a;

    if (-1 == ioctl(s, SIOCGIFCONF, &list))
      {perror("SIOCGIFCONF"); exit(2);}

    printf("list.ifc_len %d\n", list.ifc_len);

    for (i = 0; i < list.ifc_len; i += _SIZEOF_ADDR_IFREQ(*p)) {
      p = (struct ifreq*)&buf.b[i];
      printf("buf[%d] = %s\n", i, p->ifr_name);
#ifdef SIOCRPHYSADDR
      strcpy(req.ifr_name, p->ifr_name);
      if (-1 == ioctl(s, SIOCRPHYSADDR, &req)) {
        perror("  SIOCRPHYSADDR");
      } else {
        printf("  Device address %02x%02x%02x%02x%02x%02x\n",
	     req.default_pa[0], req.default_pa[1],
	     req.default_pa[2], req.default_pa[3],
	     req.default_pa[4], req.default_pa[5]);}
    }
#endif
  }
Exemplo n.º 14
0
extern int/*bool*/ NcbiGetHostIfConfEx(SNcbiIfConf* c, int s, int flag)
{
    unsigned int a, b;
    struct ifconf ifc;
    struct ifreq ifr;
    char *buf, *p;
    size_t size;
    size_t mtu;
    int n, m;

    errno = 0;
    if (!c  ||  s < 0)
        return 0;

    for (size = 1024;  ;  size += 1024) {
        if (!(buf = (char*) calloc(1, size)))
            return 0;

        ifc.ifc_len = (SOCK_socklen_t) size;
        ifc.ifc_buf = buf;
        if ((n = ioctl(s, SIOCGIFCONF, &ifc)) >= 0
            &&  ifc.ifc_len + 2*sizeof(ifr) < size) {
            break;
        }

        free(buf);
        if (n < 0  &&  errno != EINVAL)
            return 0;

        if (size > 100000) {
            errno = E2BIG;
            return 0;
        }
    }

    mtu = 0;
    size = 0;
    errno = 0;
    n = m = 0;
    a = INADDR_NONE;       /* Host byte order */
    b = INADDR_ANY;        /* Host byte order */
    for (p = buf;  p < buf + ifc.ifc_len;  p += size) {
        unsigned int ip;

        memcpy(&ifr, p, sizeof(ifr));
#ifdef _SIZEOF_ADDR_IFREQ
        size = _SIZEOF_ADDR_IFREQ(ifr);
#else
        size = sizeof(ifr);
#endif /*_SIZEOF_ADDR_IFREQ*/

        if (ioctl(s, SIOCGIFADDR, &ifr) < 0)
            continue;

        n++;
        if (ifr.ifr_addr.sa_family != AF_INET) {
            m++;
            continue;
        }

        ip = ntohl(((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr);
        if (ip == INADDR_NONE  ||  ip == INADDR_LOOPBACK) {
            if (ip != INADDR_LOOPBACK)
                m++;
            else
                a = ip;
            continue;
        }

        if (ioctl(s, SIOCGIFFLAGS, &ifr) < 0)
            continue;

        if ((ifr.ifr_flags & IFF_LOOPBACK)  ||
#ifdef IFF_PRIVATE
            (ifr.ifr_flags & IFF_PRIVATE)   ||
#endif /*IFF_PRIVATE*/
            !(ifr.ifr_flags & IFF_UP)       ||
            !(ifr.ifr_flags & IFF_RUNNING)  ||
            (flag && !(ifr.ifr_flags & flag)))
            continue;

        if (ioctl(s, SIOCGIFNETMASK, &ifr) < 0)
            continue;

        b = ntohl(((struct sockaddr_in*) &ifr.ifr_addr)->sin_addr.s_addr);
        if (b != INADDR_ANY) {
            a = ip;
#ifdef SIOCGIFMTU
            if (ioctl(s, SIOCGIFMTU, &ifr) >= 0)
                mtu = (size_t)(ifr.ifr_mtu > 0 ? ifr.ifr_mtu : 0);
#endif /*SIOCGIFMTU*/
            break;
        }
    }

    free(buf);

    c->address   = htonl(a);
    c->netmask   = htonl(b);
    c->broadcast = ((a == INADDR_NONE  ||  b == INADDR_ANY) ? 0 :
                    (c->address & c->netmask) | ~c->netmask);
    c->nifs = n;
    c->sifs = m;
    c->mtu  = mtu;

    return 1;
}
Exemplo n.º 15
0
int hdhomerun_local_ip_info(struct hdhomerun_local_ip_info_t ip_info_list[], int max_count)
{
    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock == HDHOMERUN_SOCK_INVALID) {
        return -1;
    }

    struct ifconf ifc;
    size_t ifreq_buffer_size = 1024;

    while (1) {
        ifc.ifc_len = ifreq_buffer_size;
        ifc.ifc_buf = (char *)malloc(ifreq_buffer_size);
        if (!ifc.ifc_buf) {
            close(sock);
            return -1;
        }

        memset(ifc.ifc_buf, 0, ifreq_buffer_size);

        if (ioctl(sock, SIOCGIFCONF, &ifc) != 0) {
            free(ifc.ifc_buf);
            close(sock);
            return -1;
        }

        if (ifc.ifc_len < ifreq_buffer_size) {
            break;
        }

        free(ifc.ifc_buf);
        ifreq_buffer_size += 1024;
    }

    char *ptr = ifc.ifc_buf;
    char *end = ifc.ifc_buf + ifc.ifc_len;

    int count = 0;
    while (ptr < end) {
        struct ifreq *ifr = (struct ifreq *)ptr;
        ptr += _SIZEOF_ADDR_IFREQ(*ifr);

        /* Flags. */
        if (ioctl(sock, SIOCGIFFLAGS, ifr) != 0) {
            continue;
        }

        if ((ifr->ifr_flags & IFF_UP) == 0) {
            continue;
        }
        if ((ifr->ifr_flags & IFF_RUNNING) == 0) {
            continue;
        }

        /* Local IP address. */
        if (ioctl(sock, SIOCGIFADDR, ifr) != 0) {
            continue;
        }

        struct sockaddr_in *ip_addr_in = (struct sockaddr_in *)&(ifr->ifr_addr);
        uint32_t ip_addr = ntohl(ip_addr_in->sin_addr.s_addr);
        if (ip_addr == 0) {
            continue;
        }

        /* Subnet mask. */
        if (ioctl(sock, SIOCGIFNETMASK, ifr) != 0) {
            continue;
        }

        struct sockaddr_in *subnet_mask_in = (struct sockaddr_in *)&(ifr->ifr_addr);
        uint32_t subnet_mask = ntohl(subnet_mask_in->sin_addr.s_addr);

        /* Report. */
        if (count < max_count) {
            struct hdhomerun_local_ip_info_t *ip_info = &ip_info_list[count];
            ip_info->ip_addr = ip_addr;
            ip_info->subnet_mask = subnet_mask;
        }

        count++;
    }

    free(ifc.ifc_buf);
    close(sock);
    return count;
}
Exemplo n.º 16
0
int SDLNet_GetLocalAddresses(IPaddress *addresses, int maxcount)
{
	int count = 0;
#ifdef SIOCGIFCONF
/* Defined on Mac OS X */
#ifndef _SIZEOF_ADDR_IFREQ
#define _SIZEOF_ADDR_IFREQ sizeof
#endif
	SOCKET sock;
	struct ifconf conf;
	char data[4096];
	struct ifreq *ifr;
	struct sockaddr_in *sock_addr;

	sock = socket(AF_INET, SOCK_DGRAM, 0);
	if ( sock == INVALID_SOCKET ) {
		return 0;
	}

	conf.ifc_len = sizeof(data);
	conf.ifc_buf = (caddr_t) data;
	if ( ioctl(sock, SIOCGIFCONF, &conf) < 0 ) {
		closesocket(sock);
		return 0;
	}

	ifr = (struct ifreq*)data;
	while ((char*)ifr < data+conf.ifc_len) {
		if (ifr->ifr_addr.sa_family == AF_INET) {
			if (count < maxcount) {
				sock_addr = (struct sockaddr_in*)&ifr->ifr_addr;
				addresses[count].host = sock_addr->sin_addr.s_addr;
				addresses[count].port = sock_addr->sin_port;
			}
			++count;
		}
		ifr = (struct ifreq*)((char*)ifr + _SIZEOF_ADDR_IFREQ(*ifr));
	}
	closesocket(sock);
#elif defined(__WIN32__)
    PIP_ADAPTER_INFO pAdapterInfo;
    PIP_ADAPTER_INFO pAdapter;
	PIP_ADDR_STRING pAddress;
    unsigned long dwRetVal = 0;
    ULONG ulOutBufLen = sizeof (IP_ADAPTER_INFO);

    pAdapterInfo = (IP_ADAPTER_INFO *) SDL_malloc(sizeof (IP_ADAPTER_INFO));
    if (pAdapterInfo == NULL) {
		return 0;
    }

    if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == ERROR_BUFFER_OVERFLOW) {
        pAdapterInfo = (IP_ADAPTER_INFO *) SDL_realloc(pAdapterInfo, ulOutBufLen);
        if (pAdapterInfo == NULL) {
			return 0;
        }
		dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen);
    }

    if (dwRetVal == NO_ERROR) {
        for (pAdapter = pAdapterInfo; pAdapter; pAdapter = pAdapter->Next) {
			for (pAddress = &pAdapterInfo->IpAddressList; pAddress; pAddress = pAddress->Next) {
				if (count < maxcount) {
					addresses[count].host = inet_addr(pAddress->IpAddress.String);
					addresses[count].port = 0;
				}
				++count;
			}
        }
    }
	SDL_free(pAdapterInfo);
#endif
	return count;
}
Exemplo n.º 17
0
struct raw_iface *find_raw_ifaces4(void)
{
	static const int on = TRUE;	/* by-reference parameter; constant, we hope */
	int j;	/* index into buf */
	struct ifconf ifconf;
	struct ifreq *buf = NULL;	/* for list of interfaces -- arbitrary limit */
	struct ifreq *bp;	/* cursor into buf */
	struct raw_iface *rifaces = NULL;
	int master_sock = safe_socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);        /* Get a UDP socket */

	/*
	 * Current upper bound on number of interfaces.
	 * Tricky: because this is a static, we won't have to start from
	 * 64 in subsequent calls.
	 */
	static int num = 64;	/* number of interfaces */

	/* get list of interfaces with assigned IPv4 addresses from system */

	if (master_sock == -1)
		exit_log_errno((e, "socket() failed in find_raw_ifaces4()"));

	if (setsockopt(master_sock, SOL_SOCKET, SO_REUSEADDR,
		       (const void *)&on, sizeof(on)) < 0)
		exit_log_errno((e, "setsockopt() in find_raw_ifaces4()"));

	/* bind the socket */
	{
		ip_address any;

		happy(anyaddr(AF_INET, &any));
		setportof(htons(pluto_port), &any);
		if (bind(master_sock, sockaddrof(&any),
			 sockaddrlenof(&any)) < 0)
			exit_log_errno((e,
					"bind() failed in find_raw_ifaces4()"));
	}

	/* a million interfaces is probably the maximum, ever... */
	for (; num < (1024 * 1024); num *= 2) {
		/* Get num local interfaces.  See netdevice(7). */
		ifconf.ifc_len = num * sizeof(struct ifreq);
		buf = realloc(buf, ifconf.ifc_len);
		if (buf == NULL) {
			exit_log_errno((e,
					"realloc of %d in find_raw_ifaces4()",
					ifconf.ifc_len));
		}
		memset(buf, 0xDF, ifconf.ifc_len);	/* stomp */
		ifconf.ifc_buf = (void *) buf;

		if (ioctl(master_sock, SIOCGIFCONF, &ifconf) == -1)
			exit_log_errno((e,
					"ioctl(SIOCGIFCONF) in find_raw_ifaces4()"));


		/* if we got back less than we asked for, we have them all */
		if (ifconf.ifc_len < (int)(sizeof(struct ifreq) * num))
			break;
	}

	/* Add an entry to rifaces for each interesting interface.
	   On Apple, the size of struct ifreq depends on the contents of
	   the union. See if.h */
	for (bp = buf, j = 0;
	     bp < (unsigned char *)buf + (size_t)ifconf.ifc_len;
	     bp = (struct ifreq *)
		((unsigned char *)bp +_SIZEOF_ADDR_IFREQ(*bp)),
	     j++) {
		struct raw_iface ri;
		const struct sockaddr_in *rs =
			(struct sockaddr_in *) &bp->ifr_addr;
		struct ifreq auxinfo;

		/* ignore all but AF_INET interfaces */
		if (rs->sin_family != AF_INET)
			continue; /* not interesting */

		/* build a NUL-terminated copy of the rname field */
		memcpy(ri.name, bp->ifr_name, IFNAMSIZ);
		ri.name[IFNAMSIZ] = '\0';

		/* ignore if our interface names were specified, and this isn't one */
		if (pluto_ifn_roof != 0) {
			int i;

			for (i = 0; i != pluto_ifn_roof; i++)
				if (streq(ri.name, pluto_ifn[i]))
					break;
			if (i == pluto_ifn_roof)
				continue; /* not found -- skip */
		}

		/* Find out stuff about this interface.  See netdevice(7). */
		zero(&auxinfo); /* paranoia */
		memcpy(auxinfo.ifr_name, bp->ifr_name, IFNAMSIZ);
		if (ioctl(master_sock, SIOCGIFFLAGS, &auxinfo) == -1) {
			exit_log_errno((e,
					"ioctl(SIOCGIFFLAGS) for %s in find_raw_ifaces4()",
					ri.name));
		}
		if (!(auxinfo.ifr_flags & IFF_UP))
			continue; /* ignore an interface that isn't UP */

		/* ignore unconfigured interfaces */
		if (rs->sin_addr.s_addr == 0)
			continue;

		happy(initaddr((const void *)&rs->sin_addr,
			       sizeof(struct in_addr),
			       AF_INET, &ri.addr));

		DBG(DBG_CONTROL, {
			ipstr_buf b;
			DBG_log("found %s with address %s",
				ri.name, ipstr(&ri.addr, &b));
		});
		ri.next = rifaces;
		rifaces = clone_thing(ri, "struct raw_iface");
	}
Exemplo n.º 18
0
/*
 * Enumerate the system's network interface addresses and call the callback
 * for each one.  Returns 0 if successful, -1 if trouble.
 *
 * This version uses ioctl(SIOCGIFCONF).
 */
int
pg_foreach_ifaddr(PgIfAddrCallback callback, void *cb_data)
{
	struct ifconf ifc;
	struct ifreq *ifr,
			   *end,
				addr,
				mask;
	char	   *ptr,
			   *buffer = NULL;
	size_t		n_buffer = 1024;
	int			sock;

	sock = socket(AF_INET, SOCK_DGRAM, 0);
	if (sock == -1)
		return -1;

	while (n_buffer < 1024 * 100)
	{
		n_buffer += 1024;
		ptr = realloc(buffer, n_buffer);
		if (!ptr)
		{
			free(buffer);
			close(sock);
			errno = ENOMEM;
			return -1;
		}

		memset(&ifc, 0, sizeof(ifc));
		ifc.ifc_buf = buffer = ptr;
		ifc.ifc_len = n_buffer;

		if (ioctl(sock, SIOCGIFCONF, &ifc) < 0)
		{
			if (errno == EINVAL)
				continue;
			free(buffer);
			close(sock);
			return -1;
		}

		/*
		 * Some Unixes try to return as much data as possible, with no
		 * indication of whether enough space allocated. Don't believe we have
		 * it all unless there's lots of slop.
		 */
		if (ifc.ifc_len < n_buffer - 1024)
			break;
	}

	end = (struct ifreq *) (buffer + ifc.ifc_len);
	for (ifr = ifc.ifc_req; ifr < end;)
	{
		memcpy(&addr, ifr, sizeof(addr));
		memcpy(&mask, ifr, sizeof(mask));
		if (ioctl(sock, SIOCGIFADDR, &addr, sizeof(addr)) == 0 &&
			ioctl(sock, SIOCGIFNETMASK, &mask, sizeof(mask)) == 0)
			run_ifaddr_callback(callback, cb_data,
								&addr.ifr_addr, &mask.ifr_addr);
		ifr = (struct ifreq *) ((char *) ifr + _SIZEOF_ADDR_IFREQ(*ifr));
	}

	free(buffer);
	close(sock);
	return 0;
}
Exemplo n.º 19
0
static void reply_cb(gpointer data, gint source, PurpleInputCondition cond) {
	struct stun_conn *sc = data;
	guchar buffer[65536];
	struct ifreq buffer_ifr[1000];
	guchar *it, *it_end;
	gssize len;
	struct in_addr in;
	struct stun_attrib attrib;
	struct stun_header hdr;
	struct ifconf ifc;
	struct ifreq *ifr;
	struct sockaddr_in *sinptr;

	memset(&in, 0, sizeof(in));

	len = recv(source, buffer, sizeof(buffer) - 1, 0);
	if (len <= 0) {
		purple_debug_warning("stun", "unable to read stun response\n");
		return;
	}
	buffer[len] = '\0';

	if ((gsize)len < sizeof(struct stun_header)) {
		purple_debug_warning("stun", "got invalid response\n");
		return;
	}

	memcpy(&hdr, buffer, sizeof(hdr));
	if ((gsize)len != (ntohs(hdr.len) + sizeof(struct stun_header))) {
		purple_debug_warning("stun", "got incomplete response\n");
		return;
	}

	/* wrong transaction */
	if(hdr.transid[0] != sc->packet->transid[0]
			|| hdr.transid[1] != sc->packet->transid[1]
			|| hdr.transid[2] != sc->packet->transid[2]
			|| hdr.transid[3] != sc->packet->transid[3]) {
		purple_debug_warning("stun", "got wrong transid\n");
		return;
	}

	if(sc->test==1) {
		if (hdr.type != MSGTYPE_BINDINGRESPONSE) {
			purple_debug_warning("stun",
				"Expected Binding Response, got %d\n",
				hdr.type);
			return;
		}

		it = buffer + sizeof(struct stun_header);
		while((buffer + len) > (it + sizeof(struct stun_attrib))) {
			memcpy(&attrib, it, sizeof(attrib));
			it += sizeof(struct stun_attrib);

			if (!((buffer + len) > (it + ntohs(attrib.len))))
				break;

			if(attrib.type == htons(ATTRIB_MAPPEDADDRESS)
					&& ntohs(attrib.len) == 8) {
				char *ip;
				/* Skip the first unused byte,
				 * the family(1 byte), and the port(2 bytes);
				 * then read the 4 byte IPv4 address */
				memcpy(&in.s_addr, it + 4, 4);
				ip = inet_ntoa(in);
				if(ip)
					g_strlcpy(nattype.publicip, ip, sizeof(nattype.publicip));
			}

			it += ntohs(attrib.len);
		}
		purple_debug_info("stun", "got public ip %s\n", nattype.publicip);
		nattype.status = PURPLE_STUN_STATUS_DISCOVERED;
		nattype.type = PURPLE_STUN_NAT_TYPE_UNKNOWN_NAT;
		nattype.lookup_time = time(NULL);

		/* is it a NAT? */

		ifc.ifc_len = sizeof(buffer_ifr);
		ifc.ifc_req = buffer_ifr;
		ioctl(source, SIOCGIFCONF, &ifc);

		it = buffer;
		it_end = it + ifc.ifc_len;
		while (it < it_end) {
			ifr = (struct ifreq*)(gpointer)it;
			it += _SIZEOF_ADDR_IFREQ(*ifr);

			if(ifr->ifr_addr.sa_family == AF_INET) {
				/* we only care about ipv4 interfaces */
				sinptr = (struct sockaddr_in *)(gpointer)&ifr->ifr_addr;
				if(sinptr->sin_addr.s_addr == in.s_addr) {
					/* no NAT */
					purple_debug_info("stun", "no nat\n");
					nattype.type = PURPLE_STUN_NAT_TYPE_PUBLIC_IP;
				}
			}
		}

#if 1
		close_stun_conn(sc);
		do_callbacks();
#else
		purple_timeout_remove(sc->timeout);
		sc->timeout = 0;

		do_test2(sc);
	} else if(sc->test == 2) {
		close_stun_conn(sc);
		nattype.type = PURPLE_STUN_NAT_TYPE_FULL_CONE;
		do_callbacks();
#endif	/* 1 */
	}
}
Exemplo n.º 20
0
	std::vector<ip_interface> enum_net_interfaces(io_service& ios, error_code& ec)
	{
		std::vector<ip_interface> ret;
#if TORRENT_USE_IFADDRS
		int s = socket(AF_INET, SOCK_DGRAM, 0);
		if (s < 0)
		{
			ec = error_code(errno, asio::error::system_category);
			return ret;
		}

		ifaddrs *ifaddr;
		if (getifaddrs(&ifaddr) == -1)
		{
			ec = error_code(errno, asio::error::system_category);
			close(s);
			return ret;
		}

		for (ifaddrs* ifa = ifaddr; ifa; ifa = ifa->ifa_next)
		{
			if (ifa->ifa_addr == 0) continue;
			if ((ifa->ifa_flags & IFF_UP) == 0) continue;

			int family = ifa->ifa_addr->sa_family;
			if (family == AF_INET
#if TORRENT_USE_IPV6
				|| family == AF_INET6
#endif
				)
			{
				ip_interface iface;
				if (iface_from_ifaddrs(ifa, iface, ec))
				{
					ifreq req;
					memset(&req, 0, sizeof(req));
					// -1 to leave a null terminator
					strncpy(req.ifr_name, iface.name, IF_NAMESIZE - 1);
					if (ioctl(s, SIOCGIFMTU, &req) < 0)
					{
						continue;
					}
					iface.mtu = req.ifr_mtu;
					ret.push_back(iface);
				}
			}
		}
		close(s);
		freeifaddrs(ifaddr);
// MacOS X, BSD and solaris
#elif TORRENT_USE_IFCONF
		int s = socket(AF_INET, SOCK_DGRAM, 0);
		if (s < 0)
		{
			ec = error_code(errno, asio::error::system_category);
			return ret;
		}
		ifconf ifc;
		// make sure the buffer is aligned to hold ifreq structs
		ifreq buf[40];
		ifc.ifc_len = sizeof(buf);
		ifc.ifc_buf = (char*)buf;
		if (ioctl(s, SIOCGIFCONF, &ifc) < 0)
		{
			ec = error_code(errno, asio::error::system_category);
			close(s);
			return ret;
		}

		char *ifr = (char*)ifc.ifc_req;
		int remaining = ifc.ifc_len;

		while (remaining > 0)
		{
			ifreq const& item = *reinterpret_cast<ifreq*>(ifr);

#ifdef _SIZEOF_ADDR_IFREQ
			int current_size = _SIZEOF_ADDR_IFREQ(item);
#elif defined TORRENT_BSD
			int current_size = item.ifr_addr.sa_len + IFNAMSIZ;
#else
			int current_size = sizeof(ifreq);
#endif

			if (remaining < current_size) break;

			if (item.ifr_addr.sa_family == AF_INET
#if TORRENT_USE_IPV6
				|| item.ifr_addr.sa_family == AF_INET6
#endif
				)
			{
				ip_interface iface;
				iface.interface_address = sockaddr_to_address(&item.ifr_addr);
				strcpy(iface.name, item.ifr_name);

				ifreq req;
				memset(&req, 0, sizeof(req));
				// -1 to leave a null terminator
				strncpy(req.ifr_name, item.ifr_name, IF_NAMESIZE - 1);
				if (ioctl(s, SIOCGIFMTU, &req) < 0)
				{
					ec = error_code(errno, asio::error::system_category);
					close(s);
					return ret;
				}
#ifndef TORRENT_OS2
				iface.mtu = req.ifr_mtu;
#else
				iface.mtu = req.ifr_metric; // according to tcp/ip reference
#endif

				memset(&req, 0, sizeof(req));
				strncpy(req.ifr_name, item.ifr_name, IF_NAMESIZE - 1);
				if (ioctl(s, SIOCGIFNETMASK, &req) < 0)
				{
#if TORRENT_USE_IPV6
					if (iface.interface_address.is_v6())
					{
						// this is expected to fail (at least on MacOS X)
						iface.netmask = address_v6::any();
					}
					else
#endif
					{
						ec = error_code(errno, asio::error::system_category);
						close(s);
						return ret;
					}
				}
				else
				{
					iface.netmask = sockaddr_to_address(&req.ifr_addr, item.ifr_addr.sa_family);
				}
				ret.push_back(iface);
			}

			ifr += current_size;
			remaining -= current_size;
		}
		close(s);

#elif TORRENT_USE_GETADAPTERSADDRESSES

#if _WIN32_WINNT >= 0x0501
		// Load Iphlpapi library
		HMODULE iphlp = LoadLibraryA("Iphlpapi.dll");
		if (iphlp)
		{
			// Get GetAdaptersAddresses() pointer
			typedef ULONG (WINAPI *GetAdaptersAddresses_t)(ULONG,ULONG,PVOID,PIP_ADAPTER_ADDRESSES,PULONG);
			GetAdaptersAddresses_t GetAdaptersAddresses = (GetAdaptersAddresses_t)GetProcAddress(
				iphlp, "GetAdaptersAddresses");

			if (GetAdaptersAddresses)
			{
				PIP_ADAPTER_ADDRESSES adapter_addresses = 0;
				ULONG out_buf_size = 0;
				if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER
					| GAA_FLAG_SKIP_ANYCAST, NULL, adapter_addresses, &out_buf_size) != ERROR_BUFFER_OVERFLOW)
				{
					FreeLibrary(iphlp);
					ec = asio::error::operation_not_supported;
					return std::vector<ip_interface>();
				}

				adapter_addresses = (IP_ADAPTER_ADDRESSES*)malloc(out_buf_size);
				if (!adapter_addresses)
				{
					FreeLibrary(iphlp);
					ec = asio::error::no_memory;
					return std::vector<ip_interface>();
				}

				if (GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_SKIP_MULTICAST | GAA_FLAG_SKIP_DNS_SERVER
					| GAA_FLAG_SKIP_ANYCAST, NULL, adapter_addresses, &out_buf_size) == NO_ERROR)
				{
					for (PIP_ADAPTER_ADDRESSES adapter = adapter_addresses;
						adapter != 0; adapter = adapter->Next)
					{
						ip_interface r;
						strncpy(r.name, adapter->AdapterName, sizeof(r.name));
						r.name[sizeof(r.name)-1] = 0;
						r.mtu = adapter->Mtu;
						IP_ADAPTER_UNICAST_ADDRESS* unicast = adapter->FirstUnicastAddress;
						while (unicast)
						{
							r.interface_address = sockaddr_to_address(unicast->Address.lpSockaddr);

							ret.push_back(r);

							unicast = unicast->Next;
						}
					}
				}

				// Free memory
				free(adapter_addresses);
				FreeLibrary(iphlp);
				return ret;
			}
			FreeLibrary(iphlp);
		}
#endif

		SOCKET s = socket(AF_INET, SOCK_DGRAM, 0);
		if (s == SOCKET_ERROR)
		{
			ec = error_code(WSAGetLastError(), asio::error::system_category);
			return ret;
		}

		INTERFACE_INFO buffer[30];
		DWORD size;
	
		if (WSAIoctl(s, SIO_GET_INTERFACE_LIST, 0, 0, buffer,
			sizeof(buffer), &size, 0, 0) != 0)
		{
			ec = error_code(WSAGetLastError(), asio::error::system_category);
			closesocket(s);
			return ret;
		}
		closesocket(s);

		int n = size / sizeof(INTERFACE_INFO);

		ip_interface iface;
		for (int i = 0; i < n; ++i)
		{
			iface.interface_address = sockaddr_to_address(&buffer[i].iiAddress.Address);
			if (iface.interface_address == address_v4::any()) continue;
			iface.netmask = sockaddr_to_address(&buffer[i].iiNetmask.Address
				, iface.interface_address.is_v4() ? AF_INET : AF_INET6);
			iface.name[0] = 0;
			iface.mtu = 1500; // how to get the MTU?
			ret.push_back(iface);
		}

#else
#warning THIS OS IS NOT RECOGNIZED, enum_net_interfaces WILL PROBABLY NOT WORK
		// make a best guess of the interface we're using and its IP
		udp::resolver r(ios);
		udp::resolver::iterator i = r.resolve(udp::resolver::query(asio::ip::host_name(ec), "0"), ec);
		if (ec) return ret;
		ip_interface iface;
		for (;i != udp::resolver_iterator(); ++i)
		{
			iface.interface_address = i->endpoint().address();
			iface.mtu = 1500;
			if (iface.interface_address.is_v4())
				iface.netmask = address_v4::netmask(iface.interface_address.to_v4());
			ret.push_back(iface);
		}
#endif
		return ret;
	}
Exemplo n.º 21
0
/* Build a list of interfaces/IP-addresses/MAC adresses this 
	machine currently has configured.
	ifs points to a buffer large enough to hold size entries */
int
if_list_ips(struct interface *ifs,
	int size) {
  int count=0;
  struct ifconf d;
  struct ifreq *ifr, *end, *cur, *temp;
  struct in_addr ipaddr;
  char buffer[128];
  
  /* temporary storage for getting broadcast address */
  temp= (struct ifreq *)buffer;
  
  d.ifc_len= 4096;
  d.ifc_buf= malloc (d.ifc_len);
  if(ioctl (_if_sock, SIOCGIFCONF, &d) == -1) {
    perror("ioctl (SIOCGIFCONF)");
    free(d.ifc_buf);
    return 0;
  }

  ifr=(struct ifreq *)(d.ifc_req);
  end=(struct ifreq *)(((char *) ifr) + d.ifc_len);
  while((ifr<end) && (count<size)) {
    cur= ifr;
    ifr = (struct ifreq *)(((char *)ifr)+_SIZEOF_ADDR_IFREQ(*ifr));

	/* Handle LL adresses (MAC adress) */
    if(cur->ifr_addr.sa_family == AF_LINK) {
      struct sockaddr_dl *sdl = (struct sockaddr_dl *)&cur->ifr_addr;
      if(sdl->sdl_alen != ETH_ALEN) continue;
      memset(&ifs[count], sizeof(struct interface), 0);
      strncpy(ifs[count].ifname, sdl->sdl_data, sdl->sdl_nlen);
      ifs[count].ifname[sdl->sdl_nlen] = '\0';
      memcpy(ifs[count].mac, sdl->sdl_data+sdl->sdl_nlen, ETH_ALEN);
      continue;
    }

	/* Not AF_INET or AF_LINK, then ignore it */
    if(cur->ifr_addr.sa_family != AF_INET)
      continue;

	/* Handle AF_INET */
    memcpy(&ipaddr, &(((struct sockaddr_in *)&cur->ifr_addr)->sin_addr),
	   sizeof(struct in_addr));
    memcpy(temp, cur, sizeof(struct ifreq));
    if(ioctl (_if_sock, SIOCGIFFLAGS, (char *) cur) < 0)
      continue;
    if((cur->ifr_flags & IFF_UP) && (cur->ifr_flags & IFF_BROADCAST)) {
      memcpy(&ifs[count].ipaddr, &ipaddr, sizeof(struct in_addr));
      if(ioctl(_if_sock, SIOCGIFBRDADDR, (char *)temp) != -1)
	memcpy(&ifs[count].bcast,
	       &(((struct sockaddr_in *)&temp->ifr_addr)->sin_addr),
	       sizeof(struct in_addr));
      if(ioctl(_if_sock, SIOCGIFNETMASK, (char *)temp) != -1)
	memcpy(&ifs[count].netmask,
	       &(((struct sockaddr_in *)&temp->ifr_addr)->sin_addr),
	       sizeof(struct in_addr));
      strncpy(ifs[count].ifname, cur->ifr_name, IFNAMSIZ);
      count++;
      memcpy(&ifs[count], &ifs[count-1], sizeof(struct interface));
    }
  }
  free(d.ifc_buf);
  return count;
}