协议栈(套接口层)

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
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值