12 #include <linux/time.h>
13 #include <linux/errno.h>
14 #include <linux/socket.h>
15 #include <linux/fcntl.h>
16 #include <linux/stat.h>
17 #include <linux/string.h>
18 #include <asm/uaccess.h>
20 #include <linux/net.h>
22 #include <linux/netdevice.h>
23 #include <linux/signal.h>
24 #include <linux/slab.h>
28 #include <linux/poll.h>
43 int len,
unsigned flags)
45 struct msghdr msg = { .msg_flags = flags };
49 static int _send(
struct socket *
sock,
const void *buff,
int len)
54 return do_send(sock, &vec, 1, len, 0);
136 if (req->
status != RQ_ABANDONED)
143 static void __abort_ncp_connection(
struct ncp_server *server)
147 ncp_invalidate_conn(server);
149 while (!list_empty(&server->
tx.requests)) {
152 list_del_init(&req->
req);
153 ncp_finish_request(server, req, -
EIO);
155 req = server->
rcv.creq;
158 ncp_finish_request(server, req, -
EIO);
160 server->
rcv.state = 0;
162 req = server->
tx.creq;
165 ncp_finish_request(server, req, -
EIO);
182 list_del_init(&req->
req);
183 ncp_finish_request(server, req, err);
196 __ncp_abort_request(server, req, err);
200 static inline void __ncptcp_abort(
struct ncp_server *server)
202 __abort_ncp_connection(server);
210 return do_send(sock, vec, req->
tx_iovlen,
214 static void __ncptcp_try_send(
struct ncp_server *server)
221 rq = server->
tx.creq;
235 __ncp_abort_request(server, rq, result);
239 server->
rcv.creq =
rq;
245 while (iov->
iov_len <= result) {
257 req->
status = RQ_INPROGRESS;
270 h = req->
tx_iov[1].iov_base;
271 ncp_init_header(server, req, h);
277 req->
tx_ciov[1].iov_len = signlen;
284 ncpdgram_send(server->
ncp_sock, req);
288 #define NCP_TCP_XMIT_MAGIC (0x446D6454)
289 #define NCP_TCP_XMIT_VERSION (1)
290 #define NCP_TCP_RCVD_MAGIC (0x744E6350)
298 h = req->
tx_iov[1].iov_base;
299 ncp_init_header(server, req, h);
309 req->
tx_iov[0].iov_len = signlen;
313 server->
tx.creq =
req;
314 __ncptcp_try_send(server);
325 ncptcp_start_request(server, req);
327 ncpdgram_start_request(server, req);
333 if (!ncp_conn_valid(server)) {
339 if (server->
tx.creq || server->
rcv.creq) {
345 __ncp_start_request(server, req);
350 static void __ncp_next_request(
struct ncp_server *server)
355 if (list_empty(&server->
tx.requests)) {
359 list_del_init(&req->
req);
360 __ncp_start_request(server, req);
363 static void info_server(
struct ncp_server *server,
unsigned int id,
const void *
data,
size_t len)
397 if (result >=
sizeof(reply)) {
401 unsigned char buf[10];
403 if (server->
connection != get_conn_number(&reply)) {
408 DPRINTK(
"recv failed with %d\n", result);
412 DPRINTK(
"too short (%u) watchdog packet\n", result);
416 DPRINTK(
"bad signature (%02X) in watchdog packet\n", buf[9]);
420 _send(sock, buf,
sizeof(buf));
432 req = server->
rcv.creq;
434 server->
connection == get_conn_number(&reply)))) {
441 #ifdef CONFIG_NCPFS_PACKET_SIGNING
443 if (result < 8 + 8) {
449 hdrl = sock->
sk->sk_family ==
AF_INET ? 8 : 6;
450 if (sign_verify_reply(server, server->
rxbuf + hdrl, result - hdrl,
cpu_to_le32(result), server->
rxbuf + result)) {
459 ncp_finish_request(server, req, result);
460 __ncp_next_request(server);
472 static void __ncpdgram_timeout_proc(
struct ncp_server *server)
478 req = server->
rcv.creq;
484 __ncp_abort_request(server, req, -
ETIMEDOUT);
489 ncpdgram_send(server->
ncp_sock, req);
505 __ncpdgram_timeout_proc(server);
516 static unsigned char dummy[1024];
518 if (len >
sizeof(dummy)) {
527 printk(
KERN_ERR "ncpfs: tcp: bug in recvmsg (%u > %Zu)\n", result, len);
533 static int __ncptcp_rcv_proc(
struct ncp_server *server)
542 while (server->
rcv.len) {
543 result = do_tcp_rcv(server, server->
rcv.ptr, server->
rcv.len);
548 req = server->
rcv.creq;
550 __ncp_abort_request(server, req, -
EIO);
552 __ncptcp_abort(server);
561 if (server->
rcv.ptr) {
566 switch (server->
rcv.state) {
570 __ncptcp_abort(server);
573 datalen =
ntohl(server->
rcv.buf.len) & 0x0FFFFFFF;
575 printk(
KERN_ERR "ncpfs: tcp: Unexpected reply len %d\n", datalen);
576 __ncptcp_abort(server);
579 #ifdef CONFIG_NCPFS_PACKET_SIGNING
582 printk(
KERN_ERR "ncpfs: tcp: Unexpected reply len %d\n", datalen);
583 __ncptcp_abort(server);
586 server->
rcv.buf.len = datalen - 8;
587 server->
rcv.ptr = (
unsigned char*)&server->
rcv.buf.p1;
589 server->
rcv.state = 4;
594 #ifdef CONFIG_NCPFS_PACKET_SIGNING
602 server->
rcv.state = 5;
604 server->
rcv.len = datalen - 10;
607 DPRINTK(
"ncpfs: tcp: Unexpected NCP type %02X\n", type);
609 server->
rcv.state = 2;
612 server->
rcv.len = datalen - 10;
615 req = server->
rcv.creq;
620 if (datalen > req->
datalen + 8) {
621 printk(
KERN_ERR "ncpfs: tcp: Unexpected reply len %d (expected at most %Zd)\n", datalen, req->
datalen + 8);
622 server->
rcv.state = 3;
627 server->
rcv.ptr = server->
rxbuf + 2;
628 server->
rcv.len = datalen - 10;
629 server->
rcv.state = 1;
631 #ifdef CONFIG_NCPFS_PACKET_SIGNING
633 datalen = server->
rcv.buf.len;
634 type =
ntohs(server->
rcv.buf.type2);
638 req = server->
rcv.creq;
642 __ncp_abort_request(server, req, -
EIO);
647 __ncp_abort_request(server, req, -
EIO);
651 #ifdef CONFIG_NCPFS_PACKET_SIGNING
655 __ncp_abort_request(server, req, -
EIO);
660 ncp_finish_request(server, req, req->
datalen);
662 __ncp_next_request(server);
665 server->
rcv.ptr = (
unsigned char*)&server->
rcv.buf;
666 server->
rcv.len = 10;
667 server->
rcv.state = 0;
670 ncp_finish_request(server, server->
rcv.creq, -
EIO);
685 __ncptcp_rcv_proc(server);
695 __ncptcp_try_send(server);
700 unsigned char*
reply_buf,
int max_reply_size)
705 req = ncp_alloc_req();
717 result = ncp_add_request(server, req);
722 ncp_abort_request(server, req, -
EINTR);
739 static int ncp_do_request(
struct ncp_server *server,
int size,
740 void* reply,
int max_reply_size)
744 if (server->
lock == 0) {
748 if (!ncp_conn_valid(server)) {
772 siginitsetinv(&
current->blocked, mask);
774 spin_unlock_irqrestore(&
current->sighand->siglock, flags);
776 result = do_ncp_rpc_call(server, size, reply, max_reply_size);
781 spin_unlock_irqrestore(&
current->sighand->siglock, flags);
784 DDPRINTK(
"do_ncp_rpc_call returned %d\n", result);
812 result = ncp_do_request(server, server->
current_size, reply, size);
814 DPRINTK(
"ncp_request_error: %d\n", result);
825 PPRINTK(
"ncp_request: completion code=%x\n", result);
843 result = ncp_do_request(server,
sizeof(*h), server->
packet, server->
packet_size);