sendmsg経由で未処理のイーサネットパケットを送信するためにCを使用しようとしています。このコードは、生のパケットソケットを正常にオープンし、構造体のiovecに1バイトの配列(char message [])を入力しようとし、次に構造体msghdrに宛先アドレス、アドレスの長さ、および構造体iovecメッセージ。 sendmsg()はすべての呼び出しに対してEINVALを返しますが、無効な引数は何もわかりません。 (このコードを読みやすくするためにいくつかのperror()呼び出しを削除しました。出力は "無効な引数"です)生のイーサネットフレームでsendmsg/sendmmsgを使用する
sendmsg()がrawとどのように機能するかの例は見つかりませんでしたsendto()を使って同様のコードを期待どおりに動作させます。そのコードでは、私はヘッダーとプロトコル情報を含むイーサネットフレームを明示的に形成しますが、sendmsg()呼び出しでは必要ではないことを理解していますか?私はまた、message.iov_baseが14バイトのヘッダを含む明示的に形成されたイーサネットフレームを含むバッファを指し示すように試みましたが、sendmsg()もそれを嫌にします。
生のイーサネットフレームでsendmsg()とsendmmsg()を動作させることはできますか?それを無効にしているiovecについて、私が見逃していることはありますか?
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 }