2010-07-29 19 views
7

Estoy escribiendo código para enviar tramas Ethernet sin procesar entre dos cajas de Linux. Para probar esto, solo quiero obtener un simple cliente-enviar y servidor-recibir.zócalo de Ethernet sin conexión de Linux se une al protocolo específico

Tengo el cliente haciendo paquetes correctamente (puedo verlos usando un sniffer de paquetes).

En el lado del servidor que inicializar el zócalo de este modo:

fd = socket(PF_PACKET, SOCK_RAW, htons(MY_ETH_PROTOCOL)); 

donde MY_ETH_PROTOCOL 2 es una constante byte utilizo como un ethertype por lo que no se oye el tráfico de red ajena.

cuando me ato esta toma a mi interfaz que debe pasar es un protocolo de nuevo en la estructura socket_addr: socket_address.sll_protocol = htons(MY_ETH_PROTOCOL);
Si puedo compilar y ejecutar el código como esto, entonces se produce un error. Mi servidor no ve el paquete. Sin embargo, si cambio el código de la siguiente manera:
socket_address.sll_protocol = htons(ETH_P_ALL);
El servidor puede ver el paquete enviado desde el cliente (así como muchos otros paquetes), así que tengo que verificar el paquete para ver si coincide con MY_ETH_PROTOCOL.

Pero no quiero que mi servidor escuche el tráfico que no se envía en el protocolo especificado, así que no es una solución. ¿Cómo hago esto?

+0

¿Se puede pegar el código donde se configuró su 'socket_address'? – bstpierre

Respuesta

5

He resuelto el problema.

Según http://linuxreviews.org/dictionary/Ethernet/ se refiere al campo de 2 bytes siguiendo las direcciones MAC:

valores

" de ese campo entre 64 y 1522 indicaron el uso del nuevo formato de 802.3 Ethernet con un campo de longitud, mientras los valores de 1536 decimal (0600 hexadecimal) y mayor indicaron el uso del formato de trama DIX o Ethernet II original con un identificador de sub-protocolo EtherType ".

por lo que tienen que asegurarse de que mi ethertype es> = 0x0600.

Según http://standards.ieee.org/regauth/ethertype/eth.txt, el uso de 0x88b5 y 0x88b6 está "disponible para uso público para prototipos y desarrollo de protocolos específicos del proveedor". Entonces esto es lo que voy a usar como un ethertype. No debería necesitar ningún otro filtro, ya que el kernel debería asegurarse de recoger únicamente tramas de Ethernet con la dirección MAC de destino correcta y usar ese protocolo.

+0

Tengo que hacer lo que dijiste.Pero mi cliente no puede recibir el paquete de protocolo especificado. ¿Puedes pegar tu código? ¡gracias! correo electrónico: [email protected] –

0

He solucionado este problema en el pasado mediante el uso de un filtro de paquetes.

mano que saluda (pseudocódigo no probado)

struct bpf_insn my_filter[] = { 
    ... 
} 

s = socket(PF_PACKET, SOCK_DGRAM, htons(protocol)); 
struct sock_fprog pf; 
pf.filter = my_filter; 
pf.len = my_filter_len; 
setsockopt(s, SOL_SOCKET, SO_ATTACH_FILTER, &pf, sizeof(pf)); 

sll.sll_family = PF_PACKET; 
sll.sll_protocol = htons(protocol); 
sll.sll_ifindex = if_nametoindex("eth0"); 

bind(s, &sll, sizeof(sll)); 

comprobación de errores y conseguir el filtro de paquetes derecha se deja como ejercicio para el lector ...

Dependiendo de la aplicación, una Una alternativa que puede ser más fácil de obtener es libpcap.

Cuestiones relacionadas