español linux networking network-programming udp dhcp

linux - español - Transmitiendo paquete UDP a 255.255.255.255



rfc 2131 (3)

primer póster, ojalá sea fácil:

Necesito enviar un paquete de transmisión a una pieza de hardware que, cuando se enciende, está en una subred diferente a la de mi máquina, para decirle que restablezca su dirección IP a una que está en mi red. Pero, parece que no puedo transmitir desde mi propia subred a menos que esté usando DHCP, que finalmente no podré hacer. No hay enrutador en la red, solo un simple cambio entre mi máquina y la caja con la que estoy tratando de hablar, más algunas otras máquinas Linux en la red.

Así que, básicamente, este código de ejemplo FUNCIONA en Fedora 19 en un entorno de prueba (en una red más grande donde tengo habilitado DHCP), hasta que intento establecer estáticamente mi dirección IP:

int main(int argc, char *argv[]) { int sock; if( (sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) { perror("socket : "); return -1; } int broadcast = 1; if( setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) != 0 ) { perror("setsockopt : "); close(sock); return -1; } char *ip = "255.255.255.255"; char * msg = "Hello World!"; struct sockaddr_in si; si.sin_family = AF_INET; si.sin_port = htons( 4444 ); inet_aton( ip, &si.sin_addr.s_addr ); /* send data */ size_t nBytes = sendto(sock, msg, strlen(msg), 0, (struct sockaddr*) &si, sizeof(si)); printf("Sent msg: %s, %d bytes with socket %d to %s/n", msg, nBytes, sock, ip); return 0; }

Si estoy usando DHCP, el resultado es:

Sent msg: Hello World!, 12 bytes with socket 3 to 255.255.255.255

Y puedo ver que el paquete se va en Wireshark.

Luego, si configuro mi IP estáticamente para decir, 192.168.100.1, obtengo:

Sent msg: Hello World!, -1 bytes with socket 3 to 255.255.255.255

Y no veo el paquete en Wireshark. Y puedo confirmar que la cantidad de paquetes TX que se muestran en ifconfig no aumenta. Intenté desactivar el firewall:

sudo iptables -F

pero eso no hizo nada. ¿Alguien ve algo que me estoy perdiendo? Puedo transmitir a 192.168.100.255, pero eso no llegará a la casilla con la que necesito hablar, que por ejemplo podría estar en 192.168.200.10, 255.255.255.0 de manera predeterminada. Podría hacerlo funcionar cambiando los parámetros de red de todo lo demás en la red, pero esa no es realmente una opción.

EDITAR: Con respecto a algunos de los comentarios y respuestas, tenga en cuenta que no estoy usando un enrutador y puedo replicar el comportamiento con nada más que un cable entre mi computadora y la otra caja. Entonces, realmente la pregunta es, ¿por qué Linux no está enviando los paquetes? No lo sé, obviamente, pero sospecho que el propio Linux deja caer paquetes de difusión de subred cruzada a menos que pueda delegar esa decisión a otra autoridad en la red. En cualquier caso, dado que mi red es tan pequeña, tendré que evitarla.


Compruebe su puerta de enlace predeterminada. Si la IP de la puerta de enlace está en otra subred, se obtendría el error "No se puede acceder a la red". después de algún tiempo de transmisión a la dirección 255.255.255.255, por cierto enviando directamente a la difusión de la subred (192.168.1.255 si su IP es 192.168.1.1 por ejemplo) funcionará correctamente incluso si la puerta de enlace IP está en otra subred.


La difusión por definición está limitada a una subred. Sería horrible ver cómo la transmisión escapa de la subred y desborda Internet. Si está buscando una forma de cruzar subredes, debería echarle un vistazo a Multicast . También revisa esto . ¡Buena suerte!


Me encontré con este problema. Todo funcionó bien hasta que eliminé la puerta de enlace y luego recibí un error de red inalcanzable al intentar enviar desde el socket.

Como utilizo los mensajes de difusión para configurar los ajustes de red de mi casilla, no es una alternativa para mí configurar la dirección de la puerta de enlace para que funcione. Sin embargo, dado que mi cuadro solo tiene una única interfaz de red, encontré la siguiente solución:

// Bind to the proper interface to be able to send without default gateway char netif[] = "eth0"; setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, netif, sizeof(netif));

Con esto puedo enviar a la dirección de transmisión 255.255.255.255 en el socket independientemente de cualquier puerta de enlace predeterminada. Esta solución debería funcionar con múltiples interfaces de red siempre que sepa qué interfaz desea usar.