⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socket32.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 2 页
字号:
	/* Copy back fixed up data, and adjust pointers. */	bufsz = (wp - workbuf);	copy_to_user((void *)orig_cmsg_uptr, workbuf, bufsz);	kmsg->msg_control = (struct cmsghdr *)		(((char *)orig_cmsg_uptr) + bufsz);	kmsg->msg_controllen = space_avail - bufsz;	kfree(workbuf);	return;fail:	/* If we leave the 64-bit format CMSG chunks in there,	 * the application could get confused and crash.  So to	 * ensure greater recovery, we report no CMSGs.	 */	kmsg->msg_controllen += bufsz;	kmsg->msg_control = (void *) orig_cmsg_uptr;}asmlinkage long sys32_sendmsg(int fd, struct msghdr32 *user_msg, unsigned user_flags){	struct socket *sock;	char address[MAX_SOCK_ADDR];	struct iovec iov[UIO_FASTIOV];	unsigned char ctl[sizeof(struct cmsghdr) + 20];	unsigned char *ctl_buf = ctl;	struct msghdr kern_msg;	int err, total_len;	if(msghdr_from_user32_to_kern(&kern_msg, user_msg))		return -EFAULT;	if(kern_msg.msg_iovlen > UIO_MAXIOV)		return -EINVAL;	err = verify_iovec32(&kern_msg, iov, address, VERIFY_READ);	if (err < 0)		goto out;	total_len = err;	if(kern_msg.msg_controllen) {		err = cmsghdr_from_user32_to_kern(&kern_msg, ctl, sizeof(ctl));		if(err)			goto out_freeiov;		ctl_buf = kern_msg.msg_control;	}	kern_msg.msg_flags = user_flags;	sock = sockfd_lookup(fd, &err);	if (sock != NULL) {		if (sock->file->f_flags & O_NONBLOCK)			kern_msg.msg_flags |= MSG_DONTWAIT;		err = sock_sendmsg(sock, &kern_msg, total_len);		sockfd_put(sock);	}	/* N.B. Use kfree here, as kern_msg.msg_controllen might change? */	if(ctl_buf != ctl)		kfree(ctl_buf);out_freeiov:	if(kern_msg.msg_iov != iov)		kfree(kern_msg.msg_iov);out:	return err;}asmlinkage long sys32_recvmsg(int fd, struct msghdr32 *user_msg, unsigned int user_flags){	struct iovec iovstack[UIO_FASTIOV];	struct msghdr kern_msg;	char addr[MAX_SOCK_ADDR];	struct socket *sock;	struct iovec *iov = iovstack;	struct sockaddr *uaddr;	int *uaddr_len;	unsigned long cmsg_ptr;	int err, total_len, len = 0;	if(msghdr_from_user32_to_kern(&kern_msg, user_msg))		return -EFAULT;	if(kern_msg.msg_iovlen > UIO_MAXIOV)		return -EINVAL;	uaddr = kern_msg.msg_name;	uaddr_len = &user_msg->msg_namelen;	err = verify_iovec32(&kern_msg, iov, addr, VERIFY_WRITE);	if (err < 0)		goto out;	total_len = err;	cmsg_ptr = (unsigned long) kern_msg.msg_control;	kern_msg.msg_flags = 0;	sock = sockfd_lookup(fd, &err);	if (sock != NULL) {		struct scm_cookie scm;		if (sock->file->f_flags & O_NONBLOCK)			user_flags |= MSG_DONTWAIT;		memset(&scm, 0, sizeof(scm));		err = sock->ops->recvmsg(sock, &kern_msg, total_len,					 user_flags, &scm);		if(err >= 0) {			len = err;			if(!kern_msg.msg_control) {				if(sock->passcred || scm.fp)					kern_msg.msg_flags |= MSG_CTRUNC;				if(scm.fp)					__scm_destroy(&scm);			} else {				/* If recvmsg processing itself placed some				 * control messages into user space, it's is				 * using 64-bit CMSG processing, so we need				 * to fix it up before we tack on more stuff.				 */				if((unsigned long) kern_msg.msg_control != cmsg_ptr)					cmsg32_recvmsg_fixup(&kern_msg, cmsg_ptr);				/* Wheee... */				if(sock->passcred)					put_cmsg32(&kern_msg,						   SOL_SOCKET, SCM_CREDENTIALS,						   sizeof(scm.creds), &scm.creds);				if(scm.fp != NULL)					scm_detach_fds32(&kern_msg, &scm);			}		}		sockfd_put(sock);	}	if(uaddr != NULL && err >= 0)		err = move_addr_to_user(addr, kern_msg.msg_namelen, uaddr, uaddr_len);	if(cmsg_ptr != 0 && err >= 0) {		unsigned long ucmsg_ptr = ((unsigned long)kern_msg.msg_control);		__kernel_size_t32 uclen = (__kernel_size_t32) (ucmsg_ptr - cmsg_ptr);		err |= __put_user(uclen, &user_msg->msg_controllen);	}	if(err >= 0)		err = __put_user(kern_msg.msg_flags, &user_msg->msg_flags);	if(kern_msg.msg_iov != iov)		kfree(kern_msg.msg_iov);out:	if(err < 0)		return err;	return len;}extern asmlinkage int sys_setsockopt(int fd, int level, int optname,				     char *optval, int optlen);static int do_set_attach_filter(int fd, int level, int optname,				char *optval, int optlen){	struct sock_fprog32 {		__u16 len;		__u32 filter;	} *fprog32 = (struct sock_fprog32 *)optval;	struct sock_fprog kfprog;	struct sock_filter *kfilter;	unsigned int fsize;	mm_segment_t old_fs;	__u32 uptr;	int ret;	if (get_user(kfprog.len, &fprog32->len) ||	    __get_user(uptr, &fprog32->filter))		return -EFAULT;	kfprog.filter = (struct sock_filter *)A(uptr);	fsize = kfprog.len * sizeof(struct sock_filter);	kfilter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);	if (kfilter == NULL)		return -ENOMEM;	if (copy_from_user(kfilter, kfprog.filter, fsize)) {		kfree(kfilter);		return -EFAULT;	}	kfprog.filter = kfilter;	old_fs = get_fs();	set_fs(KERNEL_DS);	ret = sys_setsockopt(fd, level, optname,			     (char *)&kfprog, sizeof(kfprog));	set_fs(old_fs);	kfree(kfilter);	return ret;}static int do_set_icmpv6_filter(int fd, int level, int optname,				char *optval, int optlen){	struct icmp6_filter kfilter;	mm_segment_t old_fs;	int ret, i;	if (copy_from_user(&kfilter, optval, sizeof(kfilter)))		return -EFAULT;	for (i = 0; i < 8; i += 2) {		u32 tmp = kfilter.data[i];		kfilter.data[i] = kfilter.data[i + 1];		kfilter.data[i + 1] = tmp;	}	old_fs = get_fs();	set_fs(KERNEL_DS);	ret = sys_setsockopt(fd, level, optname,			     (char *) &kfilter, sizeof(kfilter));	set_fs(old_fs);	return ret;}asmlinkage long sys32_setsockopt(int fd, int level, int optname,				char *optval, int optlen){	if (optname == SO_ATTACH_FILTER)		return do_set_attach_filter(fd, level, optname,					    optval, optlen);	if (level == SOL_ICMPV6 && optname == ICMPV6_FILTER)		return do_set_icmpv6_filter(fd, level, optname,					    optval, optlen);	return sys_setsockopt(fd, level, optname, optval, optlen);}/* Argument list sizes for sys_socketcall */#define AL(x) ((x) * sizeof(u32))static unsigned char nas[18]={AL(0),AL(3),AL(3),AL(3),AL(2),AL(3),                                AL(3),AL(3),AL(4),AL(4),AL(4),AL(6),                                AL(6),AL(2),AL(5),AL(5),AL(3),AL(3)};#undef ALextern asmlinkage long sys_bind(int fd, struct sockaddr *umyaddr, int addrlen);extern asmlinkage long sys_connect(int fd, struct sockaddr *uservaddr,				  int addrlen);extern asmlinkage long sys_accept(int fd, struct sockaddr *upeer_sockaddr,				 int *upeer_addrlen); extern asmlinkage long sys_getsockname(int fd, struct sockaddr *usockaddr,				      int *usockaddr_len);extern asmlinkage long sys_getpeername(int fd, struct sockaddr *usockaddr,				      int *usockaddr_len);extern asmlinkage long sys_send(int fd, void *buff, size_t len, unsigned flags);extern asmlinkage long sys_sendto(int fd, u32 buff, __kernel_size_t32 len,				   unsigned flags, u32 addr, int addr_len);extern asmlinkage long sys_recv(int fd, void *ubuf, size_t size, unsigned flags);extern asmlinkage long sys_recvfrom(int fd, u32 ubuf, __kernel_size_t32 size,				     unsigned flags, u32 addr, u32 addr_len);extern asmlinkage long sys_getsockopt(int fd, int level, int optname,				       u32 optval, u32 optlen);extern asmlinkage long sys_socket(int family, int type, int protocol);extern asmlinkage long sys_socketpair(int family, int type, int protocol,				     int usockvec[2]);extern asmlinkage long sys_shutdown(int fd, int how);extern asmlinkage long sys_listen(int fd, int backlog);asmlinkage long sys32_socketcall(int call, u32 *args){	int ret;	u32 a[6];	u32 a0,a1;				 	if (call<SYS_SOCKET||call>SYS_RECVMSG)		return -EINVAL;	if (copy_from_user(a, args, nas[call]))		return -EFAULT;	a0=a[0];	a1=a[1];		switch(call) 	{		case SYS_SOCKET:			ret = sys_socket(a0, a1, a[2]);			break;		case SYS_BIND:			ret = sys_bind(a0, (struct sockaddr *)A(a1), a[2]);			break;		case SYS_CONNECT:			ret = sys_connect(a0, (struct sockaddr *)A(a1), a[2]);			break;		case SYS_LISTEN:			ret = sys_listen(a0, a1);			break;		case SYS_ACCEPT:			ret = sys_accept(a0, (struct sockaddr *)A(a1),					  (int *)A(a[2]));			break;		case SYS_GETSOCKNAME:			ret = sys_getsockname(a0, (struct sockaddr *)A(a1),					       (int *)A(a[2]));			break;		case SYS_GETPEERNAME:			ret = sys_getpeername(a0, (struct sockaddr *)A(a1),					       (int *)A(a[2]));			break;		case SYS_SOCKETPAIR:			ret = sys_socketpair(a0, a1, a[2], (int *)A(a[3]));			break;		case SYS_SEND:			ret = sys_send(a0, (void *)A(a1), a[2], a[3]);			break;		case SYS_SENDTO:			ret = sys_sendto(a0, a1, a[2], a[3], a[4], a[5]);			break;		case SYS_RECV:			ret = sys_recv(a0, (void *)A(a1), a[2], a[3]);			break;		case SYS_RECVFROM:			ret = sys_recvfrom(a0, a1, a[2], a[3], a[4], a[5]);			break;		case SYS_SHUTDOWN:			ret = sys_shutdown(a0,a1);			break;		case SYS_SETSOCKOPT:			ret = sys32_setsockopt(a0, a1, a[2], (char *)A(a[3]),					      a[4]);			break;		case SYS_GETSOCKOPT:			ret = sys_getsockopt(a0, a1, a[2], a[3], a[4]);			break;		case SYS_SENDMSG:			ret = sys32_sendmsg(a0, (struct msghdr32 *)A(a1),					     a[2]);			break;		case SYS_RECVMSG:			ret = sys32_recvmsg(a0, (struct msghdr32 *)A(a1),					     a[2]);			break;		default:			ret = -EINVAL;			break;	}	return ret;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -