Understanding of Linux Socket can (3)-socket can send data flow __linux

Source: Internet
Author: User
Tags sendmsg
For this article, we will from the user layer using the socket can for data transmission, data from user space to the underlying driver of the entire communication process, the user layer using the socket can can refer to the article "on the socket can understanding (2)-socket principle and use."
When we send the can data to the user layer through the socket, the following actions are required:
(1) Create a socket socket, using Af_can protocol;
(2) Returning the created socket to the descriptor SOCKFD and binding to the local address;
(3) through the SendTo system call function to send;


SendTo's function declaration is as follows:
int sendto (int sockfd, const void *msg, intlen,unsigned intflags, const struct SOCKADDR *to, int tolen);
The main parameters are described as follows:
SOCKFD: Socket descriptor generated by the socket function;
Msg: The pointer points to a buffer that needs to send data;
Len: Is the length of the data sent;
To: The target host's IP address and port number information;

SendTo system calls send a frame of data to the specified address, move the address to kernel space before the can protocol call, and check the User space data field for readability.
In the net/socket.c source file, the system of the SendTo function calls the following code:

Syscall_define6 (sendto, int, fd, void __user *, buff, size_t, Len, unsigned, flags, structsockaddr __user *, addr, int, ad Dr_len)
{
Structsocket *sock;
Structsockaddr_storage address;
Interr;
STRUCTMSGHDR msg;
Structiovec Iov;
intfput_needed;
if (Len > Int_max)
Len= Int_max;
sock= sockfd_lookup_light (FD, &err, &fput_needed);
if (!sock)
Gotoout;
iov.iov_base= Buff;
Iov.iov_len= Len;
Msg.msg_name= NULL;
msg.msg_iov= &iov;
Msg.msg_iovlen= 1;
Msg.msg_control= NULL;
msg.msg_controllen= 0;
msg.msg_namelen= 0;
* * To move the address of the user space into the kernel space.
if (addr) {
Err= Move_addr_to_kernel (addr, Addr_len, (struct sockaddr *) &address);
if (Err < 0)
Gotoout_put;
Msg.msg_name= (struct sockaddr *) &address;
Msg.msg_namelen= Addr_len;
}
if (Sock->file->f_flags & O_nonblock)
Flags|= msg_dontwait;
Msg.msg_flags= flags;
Err= sock_sendmsg (sock, &msg, Len);
}

In the SendTo system call (Sys_sendto), the sock_sendmsg () function is called, which is as follows:
int sock_sendmsg (struct socket *sock, struct MSGHDR *msg, size_t size)
{
STRUCTKIOCB IOCB;
STRUCTSOCK_IOCB SIOCB;
intret;
INIT_SYNC_KIOCB (&iocb,null);
Iocb.private= &siocb;
Ret= __sock_sendmsg (&AMP;IOCB, sock, msg, size);
if (-eiocbqueued = ret)
ret= WAIT_ON_SYNC_KIOCB (&AMP;IOCB);
Returnret;
}

Next, call the __sock_sendmsg () function.
static inline int __sock_sendmsg (struct KIOCB *iocb,struct socket *sock, struct MSGHDR *msg, size_t size)
{
Interr = security_socket_sendmsg (sock, MSG, size);
Returnerr: __sock_sendmsg_nosec (IOCB, sock, msg, size);
}

Another step down is the __SOCK_SENDMSG_NOSEC function. A sendmsg function pointer is returned in the __sock_sendmsg_nosec () function.
static inline int __sock_sendmsg_nosec (struct KIOCB*IOCB, struct socket *sock, struct MSGHDR *msg, size_t size)
{
STRUCTSOCK_IOCB *si = KIOCB_TO_SIOCB (IOCB);
Sock_update_classid (SOCK-&GT;SK);
Si->sock= sock;
Si->scm= NULL;
si->msg= msg;
Si->size= size;
Returnsock->ops->sendmsg (IOCB, sock,msg, size);
}

In the/NET/CAN/RAW.C source file, assign the RAW_SENDMSG function address to the SENDMSG function pointer, in the function __sock_sendmsg_nosec (), Return sock->ops->sendmsg ( Iocb,sock, MSG, size), the returned function pointer will point to the raw_sendmsg () function.
static const struct Proto_ops Raw_ops = {
. Family = Pf_can,
. Release = Raw_release,
. bind = Raw_bind,
. connect = Sock_no_connect,
. Socketpair = Sock_no_socketpair,
. Accept = Sock_no_accept,
. getname = Raw_getname,
. Poll = Datagram_poll,
. IOCTL = CAN_IOCTL,/* use Can_ioctl () from AF_CAN.C * *
. Listen = Sock_no_listen,
. Shutdown = Sock_no_shutdown,
. setsockopt = raw_setsockopt,
. getsockopt = raw_getsockopt,
. sendmsg = Raw_sendmsg,
. recvmsg = Raw_recvmsg,
. mmap = Sock_no_mmap,
. Sendpage = Sock_no_sendpage,
};

static int raw_sendmsg (struct KIOCB *iocb, struct socket *sock, struct MSGHDR *msg, size_tsize)
{
Structsock *sk = sock->sk;
         structraw_sock *ro = Raw_sk (SK);

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.