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[] = { ...@@ -307,6 +307,7 @@ static const struct ncp_option ncp_opts[] = {
{ "flags", OPT_INT, 'f' }, { "flags", OPT_INT, 'f' },
{ "wdogpid", OPT_INT, 'w' }, { "wdogpid", OPT_INT, 'w' },
{ "ncpfd", OPT_INT, 'n' }, { "ncpfd", OPT_INT, 'n' },
{ "infofd", OPT_INT, 'i' }, /* v5 */
{ "version", OPT_INT, 'v' }, { "version", OPT_INT, 'v' },
{ NULL, 0, 0 } }; { NULL, 0, 0 } };
...@@ -327,6 +328,7 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) ...@@ -327,6 +328,7 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
data->gid = 0; data->gid = 0;
data->file_mode = 0600; data->file_mode = 0600;
data->dir_mode = 0700; data->dir_mode = 0700;
data->info_fd = -1;
data->mounted_vol[0] = 0; data->mounted_vol[0] = 0;
while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 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) ...@@ -363,11 +365,14 @@ static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options)
case 'n': case 'n':
data->ncp_fd = optint; data->ncp_fd = optint;
break; break;
case 'i':
data->info_fd = optint;
break;
case 'v': case 'v':
if (optint < NCP_MOUNT_VERSION_V4) { if (optint < NCP_MOUNT_VERSION_V4) {
return -ECHRNG; return -ECHRNG;
} }
if (optint > NCP_MOUNT_VERSION_V4) { if (optint > NCP_MOUNT_VERSION_V5) {
return -ECHRNG; return -ECHRNG;
} }
version = optint; version = optint;
...@@ -418,6 +423,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) ...@@ -418,6 +423,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
data.gid = md->gid; data.gid = md->gid;
data.file_mode = md->file_mode; data.file_mode = md->file_mode;
data.dir_mode = md->dir_mode; data.dir_mode = md->dir_mode;
data.info_fd = -1;
memcpy(data.mounted_vol, md->mounted_vol, memcpy(data.mounted_vol, md->mounted_vol,
NCP_VOLNAME_LEN+1); NCP_VOLNAME_LEN+1);
} }
...@@ -437,6 +443,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) ...@@ -437,6 +443,7 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
data.gid = md->gid; data.gid = md->gid;
data.file_mode = md->file_mode; data.file_mode = md->file_mode;
data.dir_mode = md->dir_mode; data.dir_mode = md->dir_mode;
data.info_fd = -1;
data.mounted_vol[0] = 0; data.mounted_vol[0] = 0;
} }
break; break;
...@@ -478,6 +485,26 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) ...@@ -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_filp = ncp_filp;
server->ncp_sock = sock; 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; */ /* server->lock = 0; */
init_MUTEX(&server->sem); init_MUTEX(&server->sem);
server->packet = NULL; server->packet = NULL;
...@@ -630,6 +657,9 @@ static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent) ...@@ -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_io);
unload_nls(server->nls_vol); unload_nls(server->nls_vol);
#endif #endif
out_fput2:
if (server->info_filp)
fput(server->info_filp);
out_fput: out_fput:
/* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>: /* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
* *
...@@ -667,6 +697,8 @@ static void ncp_put_super(struct super_block *sb) ...@@ -667,6 +697,8 @@ static void ncp_put_super(struct super_block *sb)
} }
#endif /* CONFIG_NCPFS_NLS */ #endif /* CONFIG_NCPFS_NLS */
if (server->info_filp)
fput(server->info_filp);
fput(server->ncp_filp); fput(server->ncp_filp);
kill_proc(server->m.wdog_pid, SIGTERM, 1); kill_proc(server->m.wdog_pid, SIGTERM, 1);
......
...@@ -336,6 +336,31 @@ static void __ncp_next_request(struct ncp_server *server) { ...@@ -336,6 +336,31 @@ static void __ncp_next_request(struct ncp_server *server) {
__ncp_start_request(server, req); __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) { static void __ncpdgram_rcv_proc(void *s) {
struct ncp_server *server = s; struct ncp_server *server = s;
struct socket* sock; struct socket* sock;
...@@ -376,6 +401,14 @@ static void __ncpdgram_rcv_proc(void *s) { ...@@ -376,6 +401,14 @@ static void __ncpdgram_rcv_proc(void *s) {
_send(sock, buf, sizeof(buf)); _send(sock, buf, sizeof(buf));
continue; 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); down(&server->rcv.creq_sem);
req = server->rcv.creq; req = server->rcv.creq;
if (req && (req->tx_type == NCP_ALLOC_SLOT_REQUEST || (server->sequence == reply.sequence && 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) { ...@@ -556,6 +589,15 @@ static int __ncptcp_rcv_proc(struct ncp_server *server) {
type = ntohs(server->rcv.buf.type); type = ntohs(server->rcv.buf.type);
cont:; cont:;
if (type != NCP_REPLY) { 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); DPRINTK("ncpfs: tcp: Unexpected NCP type %02X\n", type);
skipdata2:; skipdata2:;
server->rcv.state = 2; server->rcv.state = 2;
...@@ -613,6 +655,7 @@ skipdata:; ...@@ -613,6 +655,7 @@ skipdata:;
nextreq:; nextreq:;
__ncp_next_request(server); __ncp_next_request(server);
case 2: case 2:
next:;
server->rcv.ptr = (unsigned char*)&server->rcv.buf; server->rcv.ptr = (unsigned char*)&server->rcv.buf;
server->rcv.len = 10; server->rcv.len = 10;
server->rcv.state = 0; server->rcv.state = 0;
...@@ -620,6 +663,9 @@ skipdata:; ...@@ -620,6 +663,9 @@ skipdata:;
case 3: case 3:
ncp_finish_request(server->rcv.creq, -EIO); ncp_finish_request(server->rcv.creq, -EIO);
goto nextreq; 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 { ...@@ -27,6 +27,8 @@ struct ncp_server {
struct file *ncp_filp; /* File pointer to ncp socket */ struct file *ncp_filp; /* File pointer to ncp socket */
struct socket *ncp_sock;/* ncp socket */ struct socket *ncp_sock;/* ncp socket */
struct file *info_filp;
struct socket *info_sock;
u8 sequence; u8 sequence;
u8 task; u8 task;
...@@ -115,6 +117,10 @@ struct ncp_server { ...@@ -115,6 +117,10 @@ struct ncp_server {
struct tq_struct timeout_tq; /* DGRAM only: associated queue, we run timers from process context */ 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_last; /* DGRAM only: current timeout length */
int timeout_retries; /* DGRAM only: retries left */ int timeout_retries; /* DGRAM only: retries left */
struct {
size_t len;
__u8 data[128];
} unexpected_packet;
}; };
extern void ncp_tcp_rcv_proc(void *server); extern void ncp_tcp_rcv_proc(void *server);
......
...@@ -66,6 +66,8 @@ struct ncp_mount_data_v4 { ...@@ -66,6 +66,8 @@ struct ncp_mount_data_v4 {
unsigned long dir_mode; unsigned long dir_mode;
}; };
#define NCP_MOUNT_VERSION_V5 (5) /* Text only */
#ifdef __KERNEL__ #ifdef __KERNEL__
struct ncp_mount_data_kernel { struct ncp_mount_data_kernel {
...@@ -83,6 +85,7 @@ struct ncp_mount_data_kernel { ...@@ -83,6 +85,7 @@ struct ncp_mount_data_kernel {
__kernel_gid32_t gid; __kernel_gid32_t gid;
__kernel_mode_t file_mode; __kernel_mode_t file_mode;
__kernel_mode_t dir_mode; __kernel_mode_t dir_mode;
int info_fd;
}; };
#endif /* __KERNEL__ */ #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