Exemple #1
0
static void
s_get_interface (zre_udp_t *self)
{
#if defined (__UNIX__)
#   if defined (HAVE_GETIFADDRS) && defined (HAVE_FREEIFADDRS)
    struct ifaddrs *interfaces;
    if (getifaddrs (&interfaces) == 0) {
        struct ifaddrs *interface = interfaces;
        while (interface) {
            //  Hopefully the last interface will be WiFi or Ethernet
            if (interface->ifa_addr->sa_family == AF_INET) {
                self->address = *(struct sockaddr_in *) interface->ifa_addr;
                self->broadcast = *(struct sockaddr_in *) interface->ifa_broadaddr;
                self->broadcast.sin_port = htons (self->port_nbr);
                if (s_wireless_nic (interface->ifa_name))
                    break;
            }
            interface = interface->ifa_next;
        }
    }
    freeifaddrs (interfaces);
#   else
    struct ifreq ifr;
    memset (&ifr, 0, sizeof (ifr));

#   if !defined (LIBZRE_HAVE_ANDROID)
    //  TODO: Using hardcoded wlan0 is ugly
    if (!s_wireless_nic ("wlan0"))
        s_handle_io_error ("wlan0_not_exist");
#   endif

    int sock = 0;
    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
        s_handle_io_error ("foo_socket_not_opened");

    //  Get interface address
    ifr.ifr_addr.sa_family = AF_INET;
    strncpy (ifr.ifr_name, "wlan0", sizeof (ifr.ifr_name));
    int rc = ioctl (sock, SIOCGIFADDR, (caddr_t) &ifr, sizeof (struct ifreq));
    if (rc == -1)
        s_handle_io_error ("siocgifaddr");

    //  Get interface broadcast address
    memcpy (&self->address, ((struct sockaddr_in *) &ifr.ifr_addr),
        sizeof (struct sockaddr_in));
    rc = ioctl (sock, SIOCGIFBRDADDR, (caddr_t) &ifr, sizeof (struct ifreq));
    if (rc == -1)
        s_handle_io_error ("siocgifbrdaddr");

    memcpy (&self->broadcast, ((struct sockaddr_in *) &ifr.ifr_broadaddr),
        sizeof (struct sockaddr_in));
    self->broadcast.sin_port = htons (self->port_nbr);
    close (sock);
#   endif

#   elif defined (__WINDOWS__)
    //  Currently does not filter for wireless NIC
    ULONG addr_size = 0;
    DWORD rc = GetAdaptersAddresses (AF_INET,
        GAA_FLAG_INCLUDE_PREFIX, NULL, NULL, &addr_size);
    assert (rc == ERROR_BUFFER_OVERFLOW);

    PIP_ADAPTER_ADDRESSES pip_addresses = malloc (addr_size);
    rc = GetAdaptersAddresses (AF_INET,
        GAA_FLAG_INCLUDE_PREFIX, NULL, pip_addresses, &addr_size);
    assert (rc == NO_ERROR);

    PIP_ADAPTER_ADDRESSES cur_address = pip_addresses;
    while (cur_address) {
        PIP_ADAPTER_UNICAST_ADDRESS pUnicast = cur_address->FirstUnicastAddress;
        PIP_ADAPTER_PREFIX pPrefix = cur_address->FirstPrefix;

        if (pUnicast && pPrefix) {
            //  self->broadcast.sin_addr is replaced with 255.255.255.255 in zre_udp_send()
            self->address = *(struct sockaddr_in *)(pUnicast->Address.lpSockaddr);
            self->broadcast = *(struct sockaddr_in *)(pPrefix->Address.lpSockaddr);
            self->broadcast.sin_addr.s_addr |= htonl ((1 << (32 - pPrefix->PrefixLength)) - 1);
        }
        self->broadcast.sin_port = htons (self->port_nbr);
        cur_address = cur_address->Next;
    }
    free (pip_addresses);
#   else
#       error "Interface detection TBD on this operating system"
#   endif
}
Exemple #2
0
zre_udp_t *
zre_udp_new (int port_nbr)
{
    zre_udp_t *self = (zre_udp_t *) zmalloc (sizeof (zre_udp_t));
    self->port_nbr = port_nbr;

    //  Create UDP socket
    self->handle = socket (AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (self->handle == -1)
        s_handle_io_error ("socket");

    //  Ask operating system to let us do broadcasts from socket
    int on = 1;
    if (setsockopt (self->handle, SOL_SOCKET,
                    SO_BROADCAST, (char *)&on, sizeof (on)) == -1)
        s_handle_io_error ("setsockopt (SO_BROADCAST)");

    //  Allow multiple processes to bind to socket; incoming
    //  messages will come to each process
    if (setsockopt (self->handle, SOL_SOCKET,
                    SO_REUSEADDR, (char *)&on, sizeof (on)) == -1)
        s_handle_io_error ("setsockopt (SO_REUSEADDR)");

#if defined (SO_REUSEPORT)
    if (setsockopt (self->handle, SOL_SOCKET,
                    SO_REUSEPORT, &on, sizeof (on)) == -1)
        s_handle_io_error ("setsockopt (SO_REUSEPORT)");
#endif
    //  PROBLEM: this design will not survive the network interface being
    //  killed and restarted while the program is running.
    struct sockaddr_in sockaddr = { 0 };
    sockaddr.sin_family = AF_INET;
    sockaddr.sin_port = htons (self->port_nbr);
    sockaddr.sin_addr.s_addr = htonl (INADDR_ANY);
    if (bind (self->handle, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) == -1)
        s_handle_io_error ("bind");

#   if defined (__UNIX__)

#   if defined (HAVE_GETIFADDRS) && defined (HAVE_FREEIFADDRS)
    struct ifaddrs *interfaces;
    if (getifaddrs (&interfaces) == 0) {
        struct ifaddrs *interface = interfaces;
        while (interface) {
            //  Hopefully the last interface will be WiFi
            if (interface->ifa_addr->sa_family == AF_INET) {
                self->address = *(struct sockaddr_in *) interface->ifa_addr;
                self->broadcast = *(struct sockaddr_in *) interface->ifa_broadaddr;
                self->broadcast.sin_port = htons (self->port_nbr);
                if (s_wireless_nic (interface->ifa_name))
                    break;
            }
            interface = interface->ifa_next;
        }
    }
    freeifaddrs (interfaces);
#   else 
    struct ifreq ifr;
    memset (&ifr, 0, sizeof (ifr));
    /*  TODO: Using hardcoded wlan0 is ugly */ 

#   if !defined ( LIBZRE_HAVE_ANDROID )
    if (!s_wireless_nic ("wlan0"))
        s_handle_io_error ("wlan0_not_exist");
#   endif

    int sock = 0;
    if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
        s_handle_io_error ("foo_socket_not_opened");
    
    ifr.ifr_addr.sa_family = AF_INET;
    strncpy (ifr.ifr_name, "wlan0", sizeof (ifr.ifr_name));
    int rc = ioctl (sock, SIOCGIFADDR, (caddr_t) &ifr, sizeof (struct ifreq));
    if (rc == -1)
        s_handle_io_error ("siocgifaddr");
    
    memcpy (&self->address, ((struct sockaddr_in*) &ifr.ifr_addr), sizeof (struct sockaddr_in));
    rc = ioctl (sock, SIOCGIFBRDADDR, (caddr_t) &ifr, sizeof (struct ifreq));
    if (rc == -1)
        s_handle_io_error ("siocgifbrdaddr");
    
    memcpy (&self->broadcast, ((struct sockaddr_in*) &ifr.ifr_broadaddr), sizeof (struct sockaddr_in));
    self->broadcast.sin_port = htons (self->port_nbr);
    close (sock);
#   endif
    if (self->host)
        free (self->host);
    
    self->host = zmalloc (INET_ADDRSTRLEN);
    inet_ntop (AF_INET, &self->address.sin_addr, self->host, sizeof (sockaddr));
#   elif defined (__WINDOWS__)
    s_win_get_interface(self);
    if (self->host)
        free (self->host);
    
    self->host = zmalloc (INET_ADDRSTRLEN);
    getnameinfo ((struct sockaddr *)&self->address, sizeof (self->address), self->host, INET_ADDRSTRLEN, NULL, 0, NI_NUMERICHOST);
#   else
#       error "Interface detection TBD on this operating system"
#   endif
    return self;
}