2010-08-05 5 views
0

J'ai le code suivant pour ouvrir une socket raw et l'envoyer. Dans la fonction d'envoi que j'ai une instruction trace me montrant que la longueur de mon paquet est 21. Cependant, quand je considère les paquets sur la réception en utilisant un renifleur de paquets, je vois:802.3 longueur de l'en-tête toujours 256 lors de l'utilisation des sockets raw dans Linux

  1. La longueur réelle du paquet est 60.
  2. la longueur (comme indiqué dans l'en-tête 802.3) est 256.

Aucun de ces chiffres est 21, et je suis en communication avec un dispositif intégré qui n'aime pas la différence. J'ai parcouru Google mais je n'arrive pas à comprendre comment envoyer sendto() la bonne longueur.

bool EthernetSocket::_open(const char *ifname) { 
    _sd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_802_2)); 
    _ifname = ifname; 
    _ifidx = Ethernet::GetInterface(ifname); 
    if(_sd < 0) { 
    perror("Failed to open socket"); 
    _bOpened = false; 
    } 
    else { 
    _bOpened = true; 
    } 
    return _bOpened; 
} 


bool EthernetSocket::_send(const Buffer& txbuff, Address& addr) { 
    if(txbuff.Length() == 0) 
    return false; 

    if(_ifidx != -1) 
    addr.SetInterface(_ifidx); 

printf("SEND: Length: %d\n", txbuff.Length()); 
    if(sendto(_sd, txbuff.Data(), txbuff.Length(), 0, (struct sockaddr *) addr.Component(), (socklen_t) addr.Size()) == -1) { 
    perror("Failed broadcast"); 
    return false; 
    } 
    return true; 
} 

Edit: J'ai découvert que ce champ est réglé sur le champ sll_protocol dans ma structure sockaddr_ll. Mais pourquoi? Le réglage à htons (ETH_P_802_2), comme il se doit, n'aide pas.

Répondre

0

J'ai une réponse partielle.

La définition de sll_protocol sur htons (ETH_P_802_3) résout le problème. Je ne suis pas sûr de savoir pourquoi, puisque ETH_P_802_2 et ETH_P_802_3 sont censés se comporter à peu près de la même façon - et toute la source de noyau pertinente que je pourrais trouver me soutient là-dessus.

Je reçois des paquets via recvfrom() avec le protocole ETH_P_802_2, et l'adresse retournée a donc son champ sll_protocol réglé sur ETH_P_802_2. Cela signifie que pour répondre, je dois manuellement définir le champ à ETH_P_802_3 après avoir reçu des données. C'est un horrible kludge.

Que se passe-t-il ??