views:

41

answers:

2

Hello, I am trying to implement my own transport layer protocol in Linux for an experiment. I am going to use socket interface and add my protocol using sock_register. For the proto_ops i can see that the parameters for the sendmsg and recvmsg are (struct kiocb *iocb, struct socket *sock, struct msghdr *msg, size_t len, int flags). But there are three types of user api's send, sendto, sendmsg. Of these three only sendmsg contains a parameter for msghdr. I find that the other two api's are incompatible with the parameters supplied by the kernel to my kernel-space sendmsg function. So what happens when we use send and sendto user-space api's? Hope i am clear..

Thanks, Bala

A: 

Assuming you are comfortable with the system call mechanism - start from net/socket.c and follow the call chains - it's more or less clear.

Nikolai N Fetissov
A: 

send() is implemented in terms of sendto(): send(s, buf, len, flags); is equivalent to sendto(s, buf, len, flags, NULL, 0);

sendto() is in turn implemented in terms of sendmsg(). send(s, buf, len, flags, addr, addr_len); is implemented with (in terms of the userspace interface):

struct iovec iov =  { 
    .iov_base = buf, 
    .iov_len = len
};
struct msghdr msg = { 
    .msg_name = addr, 
    .msg_namelen = addr_len, 
    .msg_iov = &iov, 
    .msg_iovlen = 1,
    .msg_control = NULL,
    .msg_controllen = 0
};

return sendmsg(s, &msg, flags);

The kernelspace interface is slightly different - eg. you get the kiocb parameter - but the basic idea is the same. A send() or sendto() is converted into a sendmsg() with a msghdr that points at a single iovec that references the buffer.

caf