📄 sock.c
字号:
/* * linux/fs/ncpfs/sock.c * * Copyright (C) 1992, 1993 Rick Sladkey * * Modified 1995, 1996 by Volker Lendecke to be usable for ncp * */#include <linux/sched.h>#include <linux/ncp_fs.h>#include <linux/errno.h>#include <linux/socket.h>#include <linux/fcntl.h>#include <linux/stat.h>#include <asm/segment.h>#include <linux/in.h>#include <linux/net.h>#include <linux/mm.h>#include <linux/netdevice.h>#include <linux/ipx.h>#include <linux/ncp.h>#include <linux/ncp_fs.h>#include <linux/ncp_fs_sb.h>#include <net/sock.h>#define _S(nr) (1<<((nr)-1))static int _recvfrom(struct socket *sock, unsigned char *ubuf, int size, int noblock, unsigned flags, struct sockaddr_ipx *sa, int *addr_len){ struct iovec iov; struct msghdr msg; iov.iov_base = ubuf; iov.iov_len = size; msg.msg_name = (void *)sa; msg.msg_namelen = 0; if (addr_len) msg.msg_namelen = *addr_len; msg.msg_control = NULL; msg.msg_iov = &iov; msg.msg_iovlen = 1; return sock->ops->recvmsg(sock, &msg, size, noblock, flags, addr_len);}static int _sendto(struct socket *sock, const void *buff, int len, int nonblock, unsigned flags, struct sockaddr_ipx *sa, int addr_len){ struct iovec iov; struct msghdr msg; iov.iov_base = (void *)buff; iov.iov_len = len; msg.msg_name = (void *)sa; msg.msg_namelen = addr_len; msg.msg_control = NULL; msg.msg_iov = &iov; msg.msg_iovlen = 1; return sock->ops->sendmsg(sock, &msg, len, nonblock, flags);}static voidncp_wdog_data_ready(struct sock *sk, int len){ struct socket *sock = sk->socket; if (!sk->dead) { unsigned char packet_buf[2]; struct sockaddr_ipx sender; int addr_len = sizeof(struct sockaddr_ipx); int result; unsigned short fs; fs = get_fs(); set_fs(get_ds()); result = _recvfrom(sock, (void *)packet_buf, 2, 1, 0, &sender, &addr_len); if ( (result != 2) || (packet_buf[1] != '?') /* How to check connection number here? */ ) { printk("ncpfs: got strange packet on watchdog " "socket\n"); } else { int result; DDPRINTK("ncpfs: got watchdog from:\n"); DDPRINTK("ncpfs: %08lX:%02X%02X%02X%02X%02X%02X:%04X," " conn:%02X,type:%c\n", htonl(sender.sipx_network), sender.sipx_node[0], sender.sipx_node[1], sender.sipx_node[2], sender.sipx_node[3], sender.sipx_node[4], sender.sipx_node[5], ntohs(sender.sipx_port), packet_buf[0], packet_buf[1]); packet_buf[1] = 'Y'; result = _sendto(sock, (void *)packet_buf, 2, 1, 0, &sender, sizeof(sender)); DDPRINTK("send result: %d\n", result); } set_fs(fs); }}intncp_catch_watchdog(struct ncp_server *server){ struct file *file; struct inode *inode; struct socket *sock; struct sock *sk; if ( (server == NULL) || ((file = server->wdog_filp) == NULL) || ((inode = file->f_inode) == NULL) || (!S_ISSOCK(inode->i_mode))) { printk("ncp_catch_watchdog: did not get valid server!\n"); server->data_ready = NULL; return -EINVAL; } sock = &(inode->u.socket_i); if (sock->type != SOCK_DGRAM) { printk("ncp_catch_watchdog: did not get SOCK_DGRAM\n"); server->data_ready = NULL; return -EINVAL; } sk = (struct sock *)(sock->data); if (sk == NULL) { printk("ncp_catch_watchdog: sk == NULL"); server->data_ready = NULL; return -EINVAL; } DDPRINTK("ncp_catch_watchdog: sk->d_r = %x, server->d_r = %x\n", (unsigned int)(sk->data_ready), (unsigned int)(server->data_ready)); if (sk->data_ready == ncp_wdog_data_ready) { printk("ncp_catch_watchdog: already done\n"); return -EINVAL; } server->data_ready = sk->data_ready; sk->data_ready = ncp_wdog_data_ready; sk->allocation = GFP_ATOMIC; return 0;} intncp_dont_catch_watchdog(struct ncp_server *server){ struct file *file; struct inode *inode; struct socket *sock; struct sock *sk; if ( (server == NULL) || ((file = server->wdog_filp) == NULL) || ((inode = file->f_inode) == NULL) || (!S_ISSOCK(inode->i_mode))) { printk("ncp_dont_catch_watchdog: " "did not get valid server!\n"); return -EINVAL; } sock = &(inode->u.socket_i); if (sock->type != SOCK_DGRAM) { printk("ncp_dont_catch_watchdog: did not get SOCK_DGRAM\n"); return -EINVAL; } sk = (struct sock *)(sock->data); if (sk == NULL) { printk("ncp_dont_catch_watchdog: sk == NULL"); return -EINVAL; } if (server->data_ready == NULL) { printk("ncp_dont_catch_watchdog: " "server->data_ready == NULL\n"); return -EINVAL; } if (sk->data_ready != ncp_wdog_data_ready) { printk("ncp_dont_catch_watchdog: " "sk->data_callback != ncp_data_callback\n"); return -EINVAL; } DDPRINTK("ncp_dont_catch_watchdog: sk->d_r = %x, server->d_r = %x\n", (unsigned int)(sk->data_ready), (unsigned int)(server->data_ready)); sk->data_ready = server->data_ready; sk->allocation = GFP_KERNEL; server->data_ready = NULL; return 0;}static voidncp_msg_data_ready(struct sock *sk, int len){ struct socket *sock = sk->socket; if (!sk->dead) { unsigned char packet_buf[2]; struct sockaddr_ipx sender; int addr_len = sizeof(struct sockaddr_ipx); int result; unsigned short fs; fs = get_fs(); set_fs(get_ds()); result = _recvfrom(sock, (void *)packet_buf, 2, 1, 0, &sender, &addr_len); DPRINTK("ncpfs: got message of size %d from:\n", result); DPRINTK("ncpfs: %08lX:%02X%02X%02X%02X%02X%02X:%04X," " conn:%02X,type:%c\n", htonl(sender.sipx_network), sender.sipx_node[0], sender.sipx_node[1], sender.sipx_node[2], sender.sipx_node[3], sender.sipx_node[4], sender.sipx_node[5], ntohs(sender.sipx_port), packet_buf[0], packet_buf[1]); ncp_trigger_message(sk->protinfo.af_ipx.ncp_server); set_fs(fs); }}intncp_catch_message(struct ncp_server *server){ struct file *file; struct inode *inode; struct socket *sock; struct sock *sk; if ( (server == NULL) || ((file = server->msg_filp) == NULL) || ((inode = file->f_inode) == NULL) || (!S_ISSOCK(inode->i_mode))) { printk("ncp_catch_message: did not get valid server!\n"); return -EINVAL; } sock = &(inode->u.socket_i); if (sock->type != SOCK_DGRAM) { printk("ncp_catch_message: did not get SOCK_DGRAM\n"); return -EINVAL; } sk = (struct sock *)(sock->data); if (sk == NULL) { printk("ncp_catch_message: sk == NULL"); return -EINVAL; } DDPRINTK("ncp_catch_message: sk->d_r = %x\n", (unsigned int)(sk->data_ready)); if (sk->data_ready == ncp_msg_data_ready) { printk("ncp_catch_message: already done\n"); return -EINVAL; } sk->data_ready = ncp_msg_data_ready; sk->protinfo.af_ipx.ncp_server = server; return 0;} #define NCP_SLACK_SPACE 1024#define _S(nr) (1<<((nr)-1))static intdo_ncp_rpc_call(struct ncp_server *server, int size){ struct file *file; struct inode *inode; struct socket *sock; unsigned short fs; int result; char *start = server->packet; select_table wait_table; struct select_table_entry entry; int (*select) (struct inode *, struct file *, int, select_table *); int init_timeout, max_timeout; int timeout; int retrans; int major_timeout_seen; int acknowledge_seen; char *server_name; int n; int addrlen; unsigned long old_mask; /* We have to check the result, so store the complete header */ struct ncp_request_header request = *((struct ncp_request_header *)(server->packet)); struct ncp_reply_header reply; file = server->ncp_filp; inode = file->f_inode; select = file->f_op->select; sock = &inode->u.socket_i; if (!sock) { printk("ncp_rpc_call: socki_lookup failed\n"); return -EBADF;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -