// 绑定套接字到地址 // 步骤: // 1.根据用户空间的文件描述符查找socket描述符 // 2.复制地址信息到内核空间 // 3.由具体的协议族完成绑定 1.1 SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen) { struct socket *sock; struct sockaddr_storage address; int err, fput_needed; //通过用户空间文件描述符查找socket描述符 sock = sockfd_lookup_light(fd, &err, &fput_needed); if (sock) { //复制用户空间的地址信息到内核 err = move_addr_to_kernel(umyaddr, addrlen, &address); //由具体的协议层完成绑定 sock->ops->bind(sock, (struct sockaddr *)&address, addrlen); fput_light(sock->file, fput_needed); } return err; } // 根据用户空间文件描述符查找socket描述符 // 步骤: // 1.交由文件系统通过用户空间的文件描述符查找struct file结构 // 2.file->private_data指向socket结构 2.1 static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed) { struct file *file; struct socket *sock; *err = -EBADF; //由文件系统查找文件描述符 file = fget_light(fd, fput_needed); if (file) { //file->private_data指向socket结构 sock = sock_from_file(file, err); if (sock) return sock; fput_light(file, *fput_needed); } return NULL; }