vincular el socket a la interfaz de red

2 minutos de lectura

avatar de usuario
usuario2003595

¿Cómo puedo vincular un socket a una interfaz de red en particular? Traté de usar setsockopt en el lado del servidor, pero los clientes aún pueden acceder al servicio a través de las interfaces eth0 y lo.

Puedo lograr esto configurando la dirección IP particular usando serv_addr.sin_addr.s_addr.

Pero sospecho que podemos unirnos a una interfaz usando solo setsockopt (sin mencionar la dirección IP).

avatar de usuario
david berra

Puede enlazar a una interfaz específica configurando SO_BINDTODEVICE opción de enchufe.

struct ifreq ifr;

memset(&ifr, 0, sizeof(ifr));
snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "eth0");
if (setsockopt(s, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) < 0) {
    ... error handling ...
}

Advertencia: Tienes que ser root y tener el CAP_NET_RAW capacidad para utilizar esta opción.

El segundo método es que puede resolver la dirección IP vinculada a una interfaz con getifaddrs().

Siga el último enlace para ver un ejemplo completo.

  • Tengo una nueva pregunta, entonces, ¿importa que eth0 y eth1 tengan la misma dirección IP usando su método?

    – Salpicadura

    24/10/2015 a las 14:40

avatar de usuario
José

La única forma en que puedes hacerlo es como mencionas:

configurando la dirección IP particular usando serv_addr.sin_addr.s_addr

No puede hacerlo sin conocer la dirección a la que enlazar.

Puedes usar ioctls para determinar la dirección IP actual si lo necesita, aunque puede haber una forma más inteligente de hacerlo en estos días: últimamente no he hecho mucho en las distribuciones modernas de Linux.

  • Gracias joe. ¿Puedo saber el uso de setsockopt con SO_BINDTODEVICE?

    – usuario2003595

    23 de enero de 2013 a las 11:59

Tal vez alguien lo encuentre útil, así que comparto la solución que funcionó para mí (Linux, C++):

uint32_t interfaceIndex = if_nametoindex(interfaceName);

Donde “interfaceName” es el nombre de la interfaz a la que queremos vincularnos, por ejemplo, “eth0” (ver: https://linux.die.net/man/3/if_nametoindex). Ahora podemos especificar esta interfaz en la estructura de dirección del socket a través de “sin6_scope_id” (en caso de que usemos IPv6):

struct sockaddr_in6 socketAddress;
socketAddress.sin6_scope_id = interfaceIndex;

Ahora podemos vincular el socket a la interfaz a través de “bind” como de costumbre.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad