J'essaie d'utiliser C pour envoyer des paquets Ethernet bruts via sendmsg. Ce code ouvre avec succès un socket de paquet brut, tente de remplir une structure iovec avec un seul tableau d'octets (char message []), puis remplit une structure msghdr avec l'adresse de destination, la longueur de l'adresse et un pointeur vers le struct iovec le message. sendmsg() renvoie EINVAL pour chaque appel mais je n'ai aucune idée des arguments qui sont invalides. (Je l'ai supprimé certains perror() appelle à rendre ce code plus simple à lire, la sortie est « Invalid argument ».)Utilisation de sendmsg/sendmmsg avec des trames Ethernet brutes
Je n'ai pas été en mesure de trouver des exemples de la façon dont sendmsg() travaillerait avec raw sockets, mais un code similaire à l'aide de sendto() fonctionne comme prévu. Dans ce code, je forme explicitement la trame Ethernet, y compris les en-têtes et les informations de protocole, mais à ma connaissance cela n'est pas nécessaire avec un appel sendmsg()? J'ai également essayé de faire pointer le point de message.iov_base vers un tampon contenant cette trame Ethernet explicitement formée comprenant l'en-tête de 14 octets, mais sendmsg() rechigne aussi à cela.
Est-ce que sendmsg() et sendmmsg() peuvent fonctionner avec des trames Ethernet brutes? Y a-t-il quelque chose qui me manque dans l'iovec qui le rend invalide?
30 int main(void) {
32 unsigned char dest[ETH_ALEN] = {0x11, 0x11, 0x11, 0x11, 0x11, 0x11}; // destination MAC address
33
34 // Socket variables
35 int s;
36 unsigned short protocol = htons(ETH_P_802_EX1);
38
39 // Message variables
40 char message[] = {"Test message. Test message. Test message!\n"};
41 size_t msg_len = strlen(message) + 1; // Message length includes null terminator
42 int e; // Error code
43 struct msghdr msg;
44 struct iovec msgvec;
45
46 // Setup source-side socket
47 s = socket(AF_PACKET, SOCK_RAW, protocol);
48 if (s < 0) { printf("%d: %s\n", errno, strerror(errno)); return EXIT_FAILURE; }
49
50 msgvec.iov_base = message;
51 msgvec.iov_len = msg_len;
52 memset(&msg, 0, sizeof(msg));
53 msg.msg_name = dest;
54 msg.msg_namelen = ETH_ALEN;
55 msg.msg_control = NULL;
56 msg.msg_controllen = 0;
57 msg.msg_flags = 0;
65 msg.msg_iov = &msgvec;
66 msg.msg_iovlen = 1;
67
68 for (int i=0; i<10; i++) {
69 e = sendmsg(s, &msg, 0);
73 }
79 close(s);
80 return EXIT_SUCCESS;
81 }