バイトストリーム(イーサネットヘッダーと、おそらくイーサネットパケット内にカプセル化された上位層プロトコルも含む)を取得し、特定のインターフェイスのネットワークに送信する関数を作成しようとしています。
これが私のコードの要約です:
// 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
}
エラーが発生します
sendto: Invalid argument
このエラーを修正するにはどうすればよいですか?
私の最初の推測では、これは引数が原因であると考えられsa
ます。他のすべての引数はかなり標準的であり、うまくいかないことはあまりないからです。この例sockaddr_ll
のように、これをtypeの引数に置き換えることもできますが、これはヘッダー情報を から抽出することを意味し、既にそこにあり、準備ができているため、これは少し無意味に思えます。もっと良い方法があるはずですか?カプセル化、カプセル化解除、再カプセル化、送信には不要な手順が多すぎるようです。既存のコードの基礎となるインターフェイスを作成しているため、データリンク層のヘッダーが含まれないように入力を調整する方法はありません。buf