SYSCALL_DEFINEx()
#define SYSCALL_DEFINE0(name) asmlinkage long sys_##name(void)
// __VA_ARGS__是一个可变参数宏,替换...
#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__)
#define SYSCALL_DEFINEx(x, sname, ...) \
__SYSCALL_DEFINEx(x, sname, __VA_ARGS__)
#define __SYSCALL_DEFINEx(x, name, ...) \
asmlinkage long sys##name(__SC_DECL##x(__VA_ARGS__)); \
static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__)); \
asmlinkage long SyS##name(__SC_LONG##x(__VA_ARGS__)) \
{ \
__SC_TEST##x(__VA_ARGS__); \
return (long) SYSC##name(__SC_CAST##x(__VA_ARGS__)); \
} \
SYSCALL_ALIAS(sys##name, SyS##name); \
static inline long SYSC##name(__SC_DECL##x(__VA_ARGS__))
#define SYSCALL_ALIAS(alias, name) \
asm ("\t.globl " #alias "\n\t.set " #alias ", " #name)
以SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)为例,它主要定义了SyS_socket()和SYSC_socket()、设置sys_socket是SyS_socket的别名,因此sys_socket()/SyS_socket() -> SYSC_socket(),相当于定义了sys_socket()
SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol)
SYSCALL_DEFINEx(3, _socket, int, family, int, type, int, protocol)
__SYSCALL_DEFINEx(3, _socket, int, family, int, type, int, protocol)
asmlinkage long sys_socket(int family, int type, int protocol); // 申明sys_socket()
static inline long SYSC_socket(int family, int type, int protocol); // 申明SYSC_socket()
asmlinkage long SyS_socket(long family, long type, long protocol) // 定义SyS_socket()
{
BUILD_BUG_ON(sizeof(int) > sizeof(long));
BUILD_BUG_ON(sizeof(int) > sizeof(long));
BUILD_BUG_ON(sizeof(int) > sizeof(long));
return (long) SYSC_socket((int) family, (int) type, (int) protocol); // 调用SYSC_socket()
}
SYSCALL_ALIAS(sys_socket, SyS_socket); // 设置sys_socket是SyS_socket的别名
static inline long SYSC_socket(int family, int type, int protocol) // 定义SYSC_socket()
套接口层到传输层的调用过程
sys_socket() -> SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) ->
sock_create() -> __sock_create() -> inet_create() ->
// TCP / RAW
tcp_v4_init_sock() / raw_init()
sys_bind() -> SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen) ->
inet_bind() ->
// TCP / UDP / RAW
inet_csk_get_port() / udp_v4_get_port() / raw_bind()
sys_listen() -> SYSCALL_DEFINE2(listen, int, fd, int, backlog) ->
// TCP / UDP&RAW
inet_listen() -> inet_csk_listen_start() / sock_no_listen()
sys_connect() -> SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr, int, addrlen) ->
// TCP / UDP&RAW
inet_stream_connect() -> tcp_v4_connect() / inet_dgram_connect() -> ip4_datagram_connect()
sys_accept() -> SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr, int __user *, upeer_addrlen) ->
sys_accept4() -> SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr, int __user *, upeer_addrlen, int, flags) ->
// TCP / UDP&RAW
inet_accept() -> inet_csk_accept() / sock_no_accept()
sys_sendmsg() -> SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags) ->
sock_sendmsg() -> __sock_sendmsg() ->
// TCP / UDP / RAW
tcp_sendmsg() / inet_sendmsg() -> udp_sendmsg() / inet_sendmsg() -> raw_sendmsg()
socket
struct socket {
socket_state state;
kmemcheck_bitfield_begin(type);
short type; // TCP为SOCK_STREAM(1)、UDP为SOCK_DGRAM(2)、RAW为SOCK_RAW(3)
kmemcheck_bitfield_end(type);
unsigned long flags;
/*
* Please keep fasync_list & wait fields in the same cache line
*/
struct fasync_struct *fasync_list;
wait_queue_head_t wait;
struct file *file;
struct sock *sk; // 指向sock
const struct proto_ops *ops; // TCP为inet_stream_ops、UDP为inet_dgram_ops、RAW为inet_sockraw_ops
};
socket()
sys_socket() {
sock_create() {
__sock_create() {
sock_alloc() // 创建socket
inet_create() {
sk_alloc() // 创建sock
tcp_v4_init_sock()
}
}
}
sock_map_fd()
}
bind()
sys_bind() {
inet_bind() {
snum = ntohs(addr->sin_port); // 监听端口
inet->rcv_saddr = inet->saddr = addr->sin_addr.s_addr; // 设置sip为INADDR_ANY(0.0.0.0)
inet_csk_get_port() {
inet_bind_bucket_create() // 创建inet_bind_bucket,插入bhash
inet_bind_hash() {
inet_sk(sk)->num = snum; // 设置inet->num为监听端口
sk_add_bind_node() // 将sk插入inet_bind_bucket的owners
}
}
inet->sport = htons(inet->num); // 设置sport
inet->daddr = 0; // 设置dip
inet->dport = 0; // 设置dport
}
}