Msghdr structure - (sys / socket.h)

I am trying to understand the following members of the msghdr sys / socket.h lib structure .

  • struct iovec *msg_iov scatter/gather array
  • void *msg_control ancillary data, see below

It states the following:

Auxiliary data consists of a sequence of pairs, each of which consists of a cmsghdr structure, followed by a data array. The data array contains an auxiliary data message, and the cmsghdr structure contains descriptive information that allows the application to correctly analyze the data.


I assume the structure msghdrcontains protocol header information? if so ... *msg_iov- is this a "vector" of input / output parameters in the request / response? and *msg_controlcontains response messages?

+4
source share
1 answer

msg_iovis an array of I / O buffers with a length msg_iovlen. Each member of this array contains a pointer to a data buffer and a buffer size. This is where the data to read / write life. This allows you to read / write to an array of buffers that are not necessarily located in adjacent memory areas.

msg_controlpoints to a size buffer msg_controllenthat contains additional information about the package. To read this field, you first need to declare struct cmsghdr *(call him cmhdr). You fill it in, calling CMSG_FIRSTHDR()for the first time, passing it the address of the structure msghdrand CMSG_NXTHDR()each subsequent time, passing it the address of the structure msghdrand the current value cmhdr.

msg_control , IP- ( ) TOS/DSCP IP ( ), , setsockopt, . IP_PKTINFO IP_TOS.

. cmsg (3) manpage.

IP- msg_control, msg_name, struct sockaddr msg_namelen.

, :

struct msghdr mhdr;
struct iovec iov[1];
struct cmsghdr *cmhdr;
char control[1000];
struct sockaddr_in sin;
char databuf[1500];
unsigned char tos;

mhdr.msg_name = &sin
mhdr.msg_namelen = sizeof(sin);
mhdr.msg_iov = iov;
mhdr.msg_iovlen = 1;
mhdr.msg_control = &control;
mhdr.msg_controllen = sizeof(control);
iov[0].iov_base = databuf;
iov[0].iov_len = sizeof(databuf);
memset(databuf, 0, sizeof(databuf));
if ((*len = recvmsg(sock, &mhdr, 0)) == -1) {
    perror("error on recvmsg");
    exit(1);
} else {
    cmhdr = CMSG_FIRSTHDR(&mhdr);
    while (cmhdr) {
        if (cmhdr->cmsg_level == IPPROTO_IP && cmhdr->cmsg_type == IP_TOS) {
            // read the TOS byte in the IP header
            tos = ((unsigned char *)CMSG_DATA(cmhdr))[0];
        }
        cmhdr = CMSG_NXTHDR(&mhdr, cmhdr);
    }
    printf("data read: %s, tos byte = %02X\n", databuf, tos); 
}
+4

Source: https://habr.com/ru/post/1607533/


All Articles