Commit d29d5c4a authored by Petr Vandrovec's avatar Petr Vandrovec

ncpfs: Pass unknown packets from server to userspace daemon. Now we can

deliver server messages to logged-in users even with UDP or TCP transport.
parent 9f29a6d2
......@@ -307,6 +307,7 @@ static const struct ncp_option ncp_opts[] = {
{ "flags", OPT_INT, 'f' },
{ "wdogpid", OPT_INT, 'w' },
{ "ncpfd", OPT_INT, 'n' },
{ "infofd", OPT_INT, 'i' }, /* v5 */
{ "version", OPT_INT, 'v' },
{ NULL, 0, 0 } };
......@@ -327,6 +328,7 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
data->gid = 0;
data->file_mode = 0600;
data->dir_mode = 0700;
data->info_fd = -1;
data->mounted_vol[0] = 0;
while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) {
......@@ -363,11 +365,14 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
case 'n':
data->ncp_fd = optint;
break;
case 'i':
data->info_fd = optint;
break;
case 'v':
if (optint < NCP_MOUNT_VERSION_V4) {
return -ECHRNG;
}
if (optint > NCP_MOUNT_VERSION_V4) {
if (optint > NCP_MOUNT_VERSION_V5) {
return -ECHRNG;
}
version = optint;
......@@ -418,6 +423,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
data.gid = md->gid;
data.file_mode = md->file_mode;
data.dir_mode = md->dir_mode;
data.info_fd = -1;
memcpy(data.mounted_vol, md->mounted_vol,
NCP_VOLNAME_LEN+1);
}
......@@ -437,6 +443,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
data.gid = md->gid;
data.file_mode = md->file_mode;
data.dir_mode = md->dir_mode;
data.info_fd = -1;
data.mounted_vol[0] = 0;
}
break;
......@@ -478,6 +485,26 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
server->ncp_filp = ncp_filp;
server->ncp_sock = sock;
if (data.info_fd != -1) {
struct socket *info_sock;
error = -EBADF;
server->info_filp = fget(data.info_fd);
if (!server->info_filp)
goto out_fput;
error = -ENOTSOCK;
sock_inode = server->info_filp->f_dentry->d_inode;
if (!S_ISSOCK(sock_inode->i_mode))
goto out_fput2;
info_sock = SOCKET_I(sock_inode);
if (!info_sock)
goto out_fput2;
error = -EBADFD;
if (info_sock->type != SOCK_STREAM)
goto out_fput2;
server->info_sock = info_sock;
}
/* server->lock = 0; */
init_MUTEX(&server->sem);
server->packet = NULL;
......@@ -630,6 +657,9 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
unload_nls(server->nls_io);
unload_nls(server->nls_vol);
#endif
out_fput2:
if (server->info_filp)
fput(server->info_filp);
out_fput:
/* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
*
......@@ -667,6 +697,8 @@ static void ncp_put_super(struct super_block *sb)
}
#endif /* CONFIG_NCPFS_NLS */
if (server->info_filp)
fput(server->info_filp);
fput(server->ncp_filp);
kill_proc(server->m.wdog_pid, SIGTERM, 1);
......
......@@ -336,6 +336,31 @@ static void __ncp_next_request(struct ncp_server *server) {
__ncp_start_request(server, req);
}
static void info_server(struct ncp_server *server, unsigned int id, const void * data, size_t len) {
if (server->info_sock) {
struct iovec iov[2];
struct msghdr msg;
__u32 hdr[2];
hdr[0] = cpu_to_be32(len + 8);
hdr[1] = cpu_to_be32(id);
iov[0].iov_base = hdr;
iov[0].iov_len = 8;
iov[1].iov_base = (void *) data;
iov[1].iov_len = len;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_control = NULL;
msg.msg_iov = iov;
msg.msg_iovlen = 2;
msg.msg_flags = MSG_NOSIGNAL;
sock_sendmsg(server->info_sock, &msg, len + 8);
}
}
static void __ncpdgram_rcv_proc(void *s) {
struct ncp_server *server = s;
struct socket* sock;
......@@ -376,6 +401,14 @@ static void __ncpdgram_rcv_proc(void *s) {
_send(sock, buf, sizeof(buf));
continue;
}
if (reply.type != NCP_POSITIVE_ACK && reply.type != NCP_REPLY) {
result = _recv(sock, server->unexpected_packet.data, sizeof(server->unexpected_packet.data), MSG_DONTWAIT);
if (result < 0) {
continue;
}
info_server(server, 0, server->unexpected_packet.data, result);
continue;
}
down(&server->rcv.creq_sem);
req = server->rcv.creq;
if (req && (req->tx_type == NCP_ALLOC_SLOT_REQUEST || (server->sequence == reply.sequence &&
......@@ -556,6 +589,15 @@ static int __ncptcp_rcv_proc(struct ncp_server *server) {
type = ntohs(server->rcv.buf.type);
cont:;
if (type != NCP_REPLY) {
if (datalen - 8 <= sizeof(server->unexpected_packet.data)) {
*(__u16*)(server->unexpected_packet.data) = htons(type);
server->unexpected_packet.len = datalen - 8;
server->rcv.state = 5;
server->rcv.ptr = server->unexpected_packet.data + 2;
server->rcv.len = datalen - 10;
break;
}
DPRINTK("ncpfs: tcp: Unexpected NCP type %02X\n", type);
skipdata2:;
server->rcv.state = 2;
......@@ -613,6 +655,7 @@ skipdata:;
nextreq:;
__ncp_next_request(server);
case 2:
next:;
server->rcv.ptr = (unsigned char*)&server->rcv.buf;
server->rcv.len = 10;
server->rcv.state = 0;
......@@ -620,6 +663,9 @@ skipdata:;
case 3:
ncp_finish_request(server->rcv.creq, -EIO);
goto nextreq;
case 5:
info_server(server, 0, server->unexpected_packet.data, server->unexpected_packet.len);
goto next;
}
}
}
......
......@@ -27,6 +27,8 @@ struct ncp_server {
struct file *ncp_filp; /* File pointer to ncp socket */
struct socket *ncp_sock;/* ncp socket */
struct file *info_filp;
struct socket *info_sock;
u8 sequence;
u8 task;
......@@ -115,6 +117,10 @@ struct ncp_server {
struct tq_struct timeout_tq; /* DGRAM only: associated queue, we run timers from process context */
int timeout_last; /* DGRAM only: current timeout length */
int timeout_retries; /* DGRAM only: retries left */
struct {
size_t len;
__u8 data[128];
} unexpected_packet;
};
extern void ncp_tcp_rcv_proc(void *server);
......
......@@ -66,6 +66,8 @@ struct ncp_mount_data_v4 {
unsigned long dir_mode;
};
#define NCP_MOUNT_VERSION_V5 (5) /* Text only */
#ifdef __KERNEL__
struct ncp_mount_data_kernel {
......@@ -83,6 +85,7 @@ struct ncp_mount_data_kernel {
__kernel_gid32_t gid;
__kernel_mode_t file_mode;
__kernel_mode_t dir_mode;
int info_fd;
};
#endif /* __KERNEL__ */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment