2013-07-31 2 views
0

J'essaye d'écrire une fonction qui prend un flux d'octets (y compris l'en-tête ethernet et éventuellement les protocoles de couche supérieure encapsulés dans le paquet ethernet) et l'envoie sur le réseau sur une interface particulière.Injection de paquet brut sur le réseau en C (Linux)

Voici un résumé de mon code:

// create socket 
int s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); 
if (s < 0) { 
    // error handling 
} 

// set up to just receive/send packets on one interface (stored in the variable iface_name e.g. eth0) 
struct ifreq ifr; 
bzero(&ifr, sizeof(struct ifreq)); 
strncpy(ifr.ifr_ifrn.ifrn_name, iface_name, IFNAMSIZ); 
if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) { 
    // error handling 
} 

// set up socaddr for write 
struct sockaddr sa; 
sa.sa_family = PF_PACKET; 
sa.sa_data = htons(ETH_P_ALL); 

// write to wire 
// buf has type char* and len has type int 
// buf contains ethernet header, followed by payload (e.g. ARP packet or IP packet) 
if (sendto(s, buf, len, 0, &sa, sizeof(struct sockaddr)) < 0) { 
    perror("sendto"); 
    // more error handling 
} 

Je reçois l'erreur

sendto: Invalid argument 

Comment puis-je corriger cette erreur?

Ma première estimation est que cela est en quelque sorte causé par l'argument , puisque tous les autres sont assez standard et il n'y a pas grand chose à se tromper. Je pourrais remplacer cela par un argument de type sockaddr_ll comme dans this example, mais cela signifierait extraire l'information d'en-tête de buf et cela semble un peu inutile car il est déjà là, prêt à partir. Il doit y avoir un meilleur moyen? Encapsuler, désencapsuler, ré-encapsuler, envoyer semble avoir trop de pas inutiles. J'écris une interface sous-jacente pour un code pré-existant, donc je ne peux pas adapter l'entrée pour ne pas avoir déjà les en-têtes de couche de liaison de données inclus.

+0

Jetez un coup d'oeil ici . http://austinmarton.wordpress.com/2011/09/14/sending-raw-ethernet-packets-from-a-specific-interface-in-c-on-linux/ –

+0

Je pense que c'est proche, mais qu'est-ce que je remplissez l'adresse MAC de destination dans sll_addr? Si possible, je veux éviter d'avoir à extraire ceci de mes données d'entrée (puisque le paquet est déjà construit, donc je ne vois pas pourquoi je dois le déchirer). Je suppose que je comprends si ce n'est pas possible cependant? – Froskoy

+0

Ahem. http://stackoverflow.com/questions/1519585/how-to-get-mac-address-for-an-interface-in-linux-using-ac-program –

Répondre

0

ses vos bibliothèques:

http://linux.die.net/man/7/raw voir la définition d'en-tête et regarder comment il fait sa prise il ne l'utilise htons, mais plutôt: IPPROTO_RAW situé dans

#include <netinet/in.h>