2010-07-29 5 views
7

J'écris du code pour envoyer des trames Ethernet brutes entre deux boîtes Linux. Pour tester cela, je veux juste obtenir un simple client-envoyer et serveur-recevoir.linux raw socket ethernet se lier à un protocole spécifique

J'ai le client faisant correctement des paquets (je peux les voir en utilisant un renifleur de paquet).

Du côté du serveur, j'initialiser la prise comme ceci:

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

MY_ETH_PROTOCOL est une constante que j'utilise 2 octets comme ethertype donc je n'entends pas le trafic réseau étranger.

quand je lie cette prise à mon interface je dois le transmettre à nouveau un protocole dans le struct socket_addr: socket_address.sll_protocol = htons(MY_ETH_PROTOCOL);
Si je compiler et exécuter le code comme celui-ci alors il échoue. Mon serveur ne voit pas le paquet. Cependant si je change le code comme ceci:
socket_address.sll_protocol = htons(ETH_P_ALL);
Le serveur peut alors voir le paquet envoyé du client (aussi bien que beaucoup d'autres paquets) ainsi je dois faire une certaine vérification du paquet pour voir qu'il correspond à MY_ETH_PROTOCOL.

Mais je ne veux pas que mon serveur entende du trafic qui n'est pas envoyé sur le protocole spécifié, donc ce n'est pas une solution. Comment puis-je faire cela?

+0

Pouvez-vous coller le code dans lequel vous avez configuré 'socket_address'? – bstpierre

Répondre

5

J'ai résolu le problème.

Selon http://linuxreviews.org/dictionary/Ethernet/ référence au champ 2 octets suivant les adresses MAC:

« valeurs de ce domaine entre 64 et 1522 a indiqué l'utilisation du nouveau format 802.3 Ethernet avec un champ de longueur, tandis que les valeurs de 1536 décimal (0600 hexadécimal) et supérieur indiquaient l'utilisation du format de trame original DIX ou Ethernet II avec un identificateur de sous-protocole EtherType. "

donc je dois vous assurer que mon ethertype est> = 0x0600.

Selon http://standards.ieee.org/regauth/ethertype/eth.txt, l'utilisation de 0x88b5 et 0x88b6 est "disponible pour un usage public pour le développement de prototypes et de protocoles spécifiques au fournisseur". Donc c'est ce que je vais utiliser comme un ethertype. Je ne devrais pas avoir besoin de plus de filtrage car le noyau devrait s'assurer de ne prendre que les trames ethernet avec la bonne adresse MAC de destination et d'utiliser ce protocole.

+0

J'ai fais comme tu l'as dit.Mais mon client ne peut pas recevoir le paquet de protocole spécifié. Pouvez-vous coller votre code? Je vous remercie! email: [email protected] –

0

J'ai déjà travaillé sur ce problème en utilisant un filtre de paquets.

main Waving (pseudo-code non testé)

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)); 

vérification d'erreur et obtenir le filtre de paquet droit est laissé comme un exercice pour le lecteur ...

En fonction de votre application, un alternative qui peut être plus facile à travailler est libpcap.

Questions connexes