Question

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 migh I be doing wrong? Is it correct that both calls are equivalent?

Was it helpful?

Solution

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);

OTHER TIPS

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);

This message results from I/O to a special file's subdevice that either does not exist or that exists beyond the limit of the device. So check, Do you have permission or access to write where you want to perform write operation. Also change write parameters as it can have only three parameters.

from man page

int write(fd, buf, nbyte)

I hope this solve the issue.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top