void ziflist_test (bool verbose) { printf (" * ziflist: "); if (verbose) printf ("\n"); // @selftest ziflist_t *iflist = ziflist_new (); assert (iflist); size_t items = ziflist_size (iflist); if (verbose) { // printf ("ziflist: interfaces=%zu\n", ziflist_size (iflist)); const char *name = ziflist_first (iflist); while (name) { printf (" - name=%s address=%s netmask=%s broadcast=%s\n", name, ziflist_address (iflist), ziflist_netmask (iflist), ziflist_broadcast (iflist)); name = ziflist_next (iflist); } } ziflist_reload (iflist); assert (items == ziflist_size (iflist)); ziflist_destroy (&iflist); // @end printf ("OK\n"); }
static void s_self_prepare_udp (self_t *self) { // Create our UDP socket if (self->udpsock) zsys_udp_close (self->udpsock); self->hostname [0] = 0; self->udpsock = zsys_udp_new (false); if (self->udpsock == INVALID_SOCKET) return; // Get the network interface fro ZSYS_INTERFACE or else use first // broadcast interface defined on system. ZSYS_INTERFACE=* means // use INADDR_ANY + INADDR_BROADCAST. const char *iface = zsys_interface (); in_addr_t bind_to = 0; in_addr_t send_to = 0; if (streq (iface, "*")) { // Wildcard means bind to INADDR_ANY and send to INADDR_BROADCAST bind_to = INADDR_ANY; send_to = INADDR_BROADCAST; } else { // Look for matching interface, or first ziflist item ziflist_t *iflist = ziflist_new (); assert (iflist); const char *name = ziflist_first (iflist); while (name) { if (streq (iface, name) || streq (iface, "")) { // Using inet_addr instead of inet_aton or inet_atop // because these are not supported in Win XP send_to = inet_addr (ziflist_broadcast (iflist)); bind_to = inet_addr (ziflist_address (iflist)); if (self->verbose) zsys_info ("zbeacon: interface=%s address=%s broadcast=%s", name, ziflist_address (iflist), ziflist_broadcast (iflist)); break; // iface is known, so allow it } name = ziflist_next (iflist); } ziflist_destroy (&iflist); } if (bind_to) { self->broadcast.sin_family = AF_INET; self->broadcast.sin_port = htons (self->port_nbr); self->broadcast.sin_addr.s_addr = send_to; inaddr_t address = self->broadcast; address.sin_addr.s_addr = bind_to; // Bind to the port on all interfaces #if (defined (__WINDOWS__)) inaddr_t sockaddr = address; #elif (defined (__APPLE__)) inaddr_t sockaddr = self->broadcast; sockaddr.sin_addr.s_addr = htons (INADDR_ANY); #else inaddr_t sockaddr = self->broadcast; #endif // Bind must succeed; we treat failure here as a hard violation (assert) if (bind (self->udpsock, (struct sockaddr *) &sockaddr, sizeof (inaddr_t))) zsys_socket_error ("bind"); // Get our hostname so we can send it back to the API if (getnameinfo ((struct sockaddr *) &address, sizeof (inaddr_t), self->hostname, NI_MAXHOST, NULL, 0, NI_NUMERICHOST) == 0) { if (self->verbose) zsys_info ("zbeacon: configured, hostname=%s", self->hostname); } } }