I am working with RAW sockets on Linux/Debian and I have a problem when I use write() instead of sendto():
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);
If I use write instead of sendto, I get the following perror:
No such device or address" (errno=6, which is defined as EXNIO).
Using sendto, I have no problem and packet is shown in tcpdump -nettti eth0 '(ether dst host 00:11:22:33:44:55)'.
In accordance with man sendto, sendto is equivalent to a write without specifying any flags. Since the flags field that I use for sendto is '0', I guess that both system calls are equivalent.
What might I be doing wrong? Is it correct that both calls are equivalent?
You have to bind() (see manual) the address to your socket, then use write() correctly (That means, with only 3 parameters).
/* 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);
The sendto() call may be used only when the socket is in a connected state (so that the intended recipient is known). Following is the prototype of write function and it has 3 parameters not 5 like send() function.
write(int fd, const void *buf, size_t count);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With