关于socket在Linux下系统调用的分析

pointfish 2019-12-04

1.在include/linux/syscalls.h中定义了sys_socket函数的函数原型

asmlinkage long sys_socket(int, int, int);

系统调用函数必须满足:

asmlinkage long sys_##function-name(##args){ ,return ret}

关于socket在Linux下系统调用的分析

2.在arch/arm/include/asm,unistd.h中,将sys_socket系统调用和系统调用好关联起来

#define __NR_socket 97    

__SYSCALL(__NR_socket, sys_socket)//系统调用号为97

关于socket在Linux下系统调用的分析

在unistd.h中,同时给出注释表明,给函数的实现在socket.c中

3.进入socket.c(net/中),发现有这样一个函数实现(或者定义)

SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol){ ….}

关于socket在Linux下系统调用的分析

肯定这就是asmlinkage long sys_socket(int,int,int)的实现了。为了表明这一切,需要进一步查看宏SYSCALL_DEFINE3的定义

SYSCALL_DEINFE3的定义也在syscalls.h中

#define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)

#define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__) 

#define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)

#define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__)

#define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__)

#define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__)

关于socket在Linux下系统调用的分析

那么:SYSCALL_DEFINE3(socket,int,family,int,type,int,protocal)===SYSCALL_DEFINEX(3,socket,__VA_ARGS__)

由此,我们得到

SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol){ ….}

SYSCALL_DEFINEX(3,_socket,__VA_ARGS__)

_SYSCALL_DEFINE(3,_socket,__VA_ARGS__)

asmlinkage long sys_socket(int family,int type,int protocol)

而他的原型正是:asmlinkage long sys_socketintintint

4.

分析了系统是如何定义和实现sys_socket的系统调用。接下来,仔细分析sys_socket是如何实现创socket的。在前面,我们知道inet_family_ops中的create函数为inet_create,也就是说,如果要创建inet型的socket,将由函数inet_create来创建。

先来看看inet_family_ops

static const struct net_proto_family inet_family_ops = {

       .family = PF_INET,

       .create = inet_create,

       .owner  = THIS_MODULE,

};

下面看看sys_socket中的函数调用关系:

sys_socket

       |

       +--------- sock_create

       |                    |

       |                    +------- __sock_create

       |                                         |

       |                                         +------- security_socket_create

       |                                         +-------- sock_alloc()

       |                                         +--------- rcu_dereference(net_families[family])

       |                                         +--------- pf->create(net, sock, protocol, kern)

       |                                         +--------- module_put(pf->owner)

       |                                         +--------- security_socket_post_create

       +---------- sock_map_fd

sys_socket 调用sock_create函数,最终调用rcu_dereference函数来得到相应的net_family_ops,在这里是inet_family_ops,然后调用inet_family_ops结构中的create函数,这里是inet_create函数,来创建socket。sock_map_fd是得到一个文件号。

当使用socket(int,int,int)创建一个socket时,socket会调用sys_socket来完成socket的创建。

相关推荐