Comment envoyer des données sur un raw connecteur ethernet à l'aide de sendto sans l'aide de sockaddr_ll?
Je suis en train de travailler sur un projet dans lequel nous utilisons Enea OSE qui est un temps réel système d'exploitation embarqué. Je suppose que beaucoup d'entre vous ne sont pas familiers avec cet OS, mais je pense que vous pourriez répondre à ma question de toute façon. Je veux envoyer un raw de trame ethernet entre les 2 cartes en utilisant l'interface "eth1", qui sont directement connectés à oneanother par un câble ethernet (pas d'interrupteur ou de quoi que ce soit). Le "eth1" interface n'est pas attribué une adresse ip.
Je peux simplement déclarer un socket à l'aide de
int s = socket(AF_INET, RAW_SOCKET, ...)
J'ai peut alors se lier à la prise de l'appareil à l'aide de l'interface:
setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, "eth1", 4);
Ce que mon plan était de le faire, afin d'envoyer des données à partir d'une carte à l'autre, était de manuellement remplir un ethernet tableau tampon avec la source et la destination des adresses MAC. Puis envoyer les données à l'aide de sendto(....)
Cependant la sendto routine nécessite également un sockaddr struct avec de l'information:
sendto(int sockfd, const void *buf, size_t len, int flags,
const struct sockaddr *dest_addr, socklen_t addrlen);
Dans les exemples que j'ai trouvé sur internet utilise sockaddr_in lorsque l'adresse ip est connue et sockaddr_ll pour les images brutes. Cependant OSE ne pas fournir le sockaddr_ll struct. Toutefois, il fournit le sockaddr que je ne sais pas si je peux l'utiliser pour les matières premières trames ethernet?
struct sockaddr {
unsigned short sa_family; //address family, AF_xxx
char sa_data[14]; //14 bytes of protocol address
};
J'ai aussi essayé d'utiliser la valeur NULL, pour la structure sockaddr champ lors de l'appel de sendto(), l'envoyer échoue. Ce qui m'amène à mes questions(s). Puis-je utiliser le simple struct sockaddr de remplir le MAC de destination-adresse sans l'aide de toute la propriété intellectuelle? Comment regarder? (Je n'ai pas seeen code montrant ce). Pourquoi avons-nous même de fournir un sockaddr struct? Ne pas l'ethernet de la mémoire de données contiennent déjà cette information? Enfin, est-ce que je suis en train d'accomplir encore possible sans l'assignation d'adresses ip pour les périphériques réseau?
Je suis conscient de ce que je suis en train de faire semble étrange, mais il y a une raison pour ça 🙂 je serais vraiment heureux si vous me montrer comment faire cela sans avoir à utiliser le sockaddr_ll struct.
Vous devez vous connecter pour publier un commentaire.
Autant que je suis conscient de l'Enea OSE vient avec ces en-têtes
Ce dernier déclare
struct sockaddr_ll
qui devrait vous permettre d'envoyer des paquets ethernet à un socket de typeType peut être
SOCK_DGRAM
ouSOCK_RAW
(vous en aurez besoin pour créer l'en-tête ethernet vous-même).Je n'ai pas le droit d'en-tête pour les protocoles ethernet. Vous aurez besoin de chercher vos en-têtes pour
ETH_*
définit et trouver le bon en-tête ethernetstruct sockaddr
est juste un générique de l'espace réservé. Tout ce que vous mettez dans elle doit être interprétée par le support de la pile de protocole, de toute façon. Donc, si votre noyau implémente brut/paquet ethernet comminucation puis il y a un en-tête de la définition de l'adresse de la familleAF_*
, le protocole et la structure pour tenir le protocole de contrôle de l'information.Désolé pour la précédente vague réponse.
Voici ma réponse. Espérons que c'est utile.
Pour répondre à votre question: Oui, vous pouvez l'envoyer en utilisant simplement l'Adresse MAC.
Déclarer le socket comme ceci:
En cas d'erreur, sockfd, qui est le support le descripteur de fichier sera de retour -1.
La structure de la trame Ethernet peut être construit comme ceci:
Remarque comment mettre des tableaux de char de longueurs différentes à l'intérieur du cadre. Vous pouvez le régler en fonction de vos besoins. Pour obtenir l'adresse MAC de l'interface pour envoyer sur:
Ensuite pour obtenir l'index de l'appareil réseau:
Et puis, enfin, envoyer ce sur une socket:
Espère que ça aide.
J'ai utilisé ce lien et raffiné le code pour arriver à cela. Il a travaillé pour moi.
Je n'ai pas de bonne réponse, mais sous Linux une fois que vous liez l'adresse que l'exposition vous pouvez utiliser de l'écriture.
alors, pourquoi voulez-vous utiliser sendto() ?
tout d'abord pour envoyer les paquets sous Linux (je ne sais pas votre système d'exploitation temps réel, mais vous devriez regarder pour le manque définit dans les fichiers fournis par l'OS)
vous aurez besoin d'être root sur votre système ou de l'utilisation de la setcap de commande pour ajouter des premières capacités
par exemple:
dans vous programme:
Comme vous l'écrivez un raw paquet que vous aurez à mettre dans les adresses mac etc. vous-même.
Le FCS peuvent être laissés de côté(ce qui devrait être gérée par hw) de sorte que le minimum de la taille des paquets est de 60 octets, vous devez envoyer 60 octets je crois.
Si vous capturez sur les sortants de cartes vous ne verrez pas la FCS.
Je suppose que vous devez être en mesure d'utiliser la fonction sendto() au lieu de l'écrire, mais note que le
struct sockaddr_ll
ne contient pas toutes les informations sur la destination, alors pourquoi s'embêter?