2

Linux/Debian で RAW ソケットを使用していますが、sendto() の代わりに write() を使用すると問題が発生します。

struct sockaddr_ll socket_address;
/* Index of the network device */
socket_address.sll_ifindex = if_idx.ifr_ifindex;
/* Address length*/
socket_address.sll_halen = ETH_ALEN;
/* Destination MAC */
socket_address.sll_addr[0] = 0x00;
socket_address.sll_addr[1] = 0x11;
socket_address.sll_addr[2] = 0x22;
socket_address.sll_addr[3] = 0x33;
socket_address.sll_addr[4] = 0x44;
socket_address.sll_addr[5] = 0x55;

/* Send packet */
int b_written = 0;

if ( ( b_written = write(sockfd, sendbuf, tx_len,
                                   (struct sockaddr*)&socket_address,
                                    sizeof(struct sockaddr_ll))) < 0 )
/*
if ( ( b_written = sendto(sockfd, sendbuf, tx_len, 0,
                                   (struct sockaddr*)&socket_address,
                    sizeof(struct sockaddr_ll))) < 0 )
*/
{
    perror("Could not write socket...");
    fprintf(stderr, "ERRNO = %d\n", errno);
    exit(-1);
}
printf("Packet sent!, Bytes written = %d\n", b_written);

sendto の代わりに「write」を使用すると、「No such device or address」という perror が表示されます (errno=6、EXNIO として定義されています)。

「sendto」を使用しても問題はなく、パケットは「tcpdump -nettti eth0 '(ether dst host 00:11:22:33:44:55)」に表示されます。

man(sendto) によると、sendto はフラグを指定しない書き込みと同等です。「sendto」に使用する flags フィールドが「0」であるため、両方のシステム コールが同等であると推測します。

私は何が間違っているのでしょうか?両方の呼び出しが同等であることは正しいですか?

4

3 に答える 3

3

sendto() 呼び出しは、ソケットが接続状態にある場合にのみ使用できます (そのため、意図した受信者が認識されます)。以下は write 関数のプロトタイプで、send()関数のように 5 つではなく 3 つのパラメーターを持ちます。

write(int fd, const void *buf, size_t count);

于 2013-07-03T11:19:13.250 に答える
3

ソケットへのアドレスを(マニュアルを参照)し、正しく使用する必要があります(bind()つまりwrite() 3つのパラメーターのみを使用します)。

/* Send packet */
int b_written = 0;

if (bind(sockfd, (struct sockaddr*)&socket_address, sizeof(struct sockaddr_ll)) == -1)
{
    perror("bind");
    exit(-1);
}
if ( ( b_written = write(sockfd, sendbuf, tx_len)) < 0 )
{
    perror("Could not write socket...");
    fprintf(stderr, "ERRNO = %d\n", errno);
    exit(-1);
}
printf("Packet sent!, Bytes written = %d\n", b_written);
于 2013-07-03T11:27:33.407 に答える
0

このメッセージは、存在しないか、デバイスの制限を超えて存在する特殊ファイルのサブデバイスへの I/O の結果です。したがって、書き込み操作を実行する場所に書き込み権限またはアクセス権がありますか。3 つのパラメーターしか持てないため、書き込みパラメーターも変更します。

マニュアルページから

int write(fd, buf, nbyte)

これで問題が解決することを願っています。

于 2013-07-03T11:06:24.163 に答える