1 /*
2  *  linux/fs/ncpfs/sock.c
3  *
4  *  Copyright (C) 1992, 1993  Rick Sladkey
5  *
6  *  Modified 1995, 1996 by Volker Lendecke to be usable for ncp
7  *  Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache
8  *
9  */
10 
11 #include <linux/config.h>
12 
13 #include <linux/sched.h>
14 #include <linux/errno.h>
15 #include <linux/socket.h>
16 #include <linux/fcntl.h>
17 #include <linux/stat.h>
18 #include <asm/uaccess.h>
19 #include <linux/in.h>
20 #include <linux/net.h>
21 #include <linux/mm.h>
22 #include <linux/netdevice.h>
23 #include <linux/signal.h>
24 #include <net/scm.h>
25 #include <net/sock.h>
26 #include <linux/ipx.h>
27 #include <linux/poll.h>
28 #include <linux/file.h>
29 
30 #include <linux/ncp_fs.h>
31 
32 #ifdef CONFIG_NCPFS_PACKET_SIGNING
33 #include "ncpsign_kernel.h"
34 #endif
35 
_recv(struct socket * sock,unsigned char * ubuf,int size,unsigned flags)36 static int _recv(struct socket *sock, unsigned char *ubuf, int size,
37 		 unsigned flags)
38 {
39 	struct iovec iov;
40 	struct msghdr msg;
41 	struct scm_cookie scm;
42 
43 	memset(&scm, 0, sizeof(scm));
44 
45 	iov.iov_base = ubuf;
46 	iov.iov_len = size;
47 
48 	msg.msg_name = NULL;
49 	msg.msg_namelen = 0;
50 	msg.msg_control = NULL;
51 	msg.msg_iov = &iov;
52 	msg.msg_iovlen = 1;
53 	return sock->ops->recvmsg(sock, &msg, size, flags, &scm);
54 }
55 
_send(struct socket * sock,const void * buff,int len)56 static int _send(struct socket *sock, const void *buff, int len)
57 {
58 	struct iovec iov;
59 	struct msghdr msg;
60 	struct scm_cookie scm;
61 	int err;
62 
63 	iov.iov_base = (void *) buff;
64 	iov.iov_len = len;
65 
66 	msg.msg_name = NULL;
67 	msg.msg_namelen = 0;
68 	msg.msg_control = NULL;
69 	msg.msg_iov = &iov;
70 	msg.msg_iovlen = 1;
71 	msg.msg_flags = 0;
72 
73 	err = scm_send(sock, &msg, &scm);
74 	if (err < 0) {
75 		return err;
76 	}
77 	err = sock->ops->sendmsg(sock, &msg, len, &scm);
78 	scm_destroy(&scm);
79 	return err;
80 }
81 
do_ncp_rpc_call(struct ncp_server * server,int size,struct ncp_reply_header * reply_buf,int max_reply_size)82 static int do_ncp_rpc_call(struct ncp_server *server, int size,
83 		struct ncp_reply_header* reply_buf, int max_reply_size)
84 {
85 	struct file *file;
86 	struct socket *sock;
87 	int result;
88 	char *start = server->packet;
89 	poll_table wait_table;
90 	int init_timeout, max_timeout;
91 	int timeout;
92 	int retrans;
93 	int major_timeout_seen;
94 	int acknowledge_seen;
95 	int n;
96 
97 	/* We have to check the result, so store the complete header */
98 	struct ncp_request_header request =
99 	*((struct ncp_request_header *) (server->packet));
100 
101 	struct ncp_reply_header reply;
102 
103 	file = server->ncp_filp;
104 	sock = &file->f_dentry->d_inode->u.socket_i;
105 
106 	init_timeout = server->m.time_out;
107 	max_timeout = NCP_MAX_RPC_TIMEOUT;
108 	retrans = server->m.retry_count;
109 	major_timeout_seen = 0;
110 	acknowledge_seen = 0;
111 
112 	for (n = 0, timeout = init_timeout;; n++, timeout <<= 1) {
113 		/*
114 		DDPRINTK("ncpfs: %08lX:%02X%02X%02X%02X%02X%02X:%04X\n",
115 			 htonl(server->m.serv_addr.sipx_network),
116 			 server->m.serv_addr.sipx_node[0],
117 			 server->m.serv_addr.sipx_node[1],
118 			 server->m.serv_addr.sipx_node[2],
119 			 server->m.serv_addr.sipx_node[3],
120 			 server->m.serv_addr.sipx_node[4],
121 			 server->m.serv_addr.sipx_node[5],
122 			 ntohs(server->m.serv_addr.sipx_port));
123 		*/
124 		DDPRINTK("ncpfs: req.typ: %04X, con: %d, "
125 			 "seq: %d",
126 			 request.type,
127 			 (request.conn_high << 8) + request.conn_low,
128 			 request.sequence);
129 		DDPRINTK(" func: %d\n",
130 			 request.function);
131 
132 		result = _send(sock, (void *) start, size);
133 		if (result < 0) {
134 			printk(KERN_ERR "ncp_rpc_call: send error = %d\n", result);
135 			break;
136 		}
137 	      re_select:
138 		poll_initwait(&wait_table);
139 		/* mb() is not necessary because ->poll() will serialize
140 		   instructions adding the wait_table waitqueues in the
141 		   waitqueue-head before going to calculate the mask-retval. */
142 		__set_current_state(TASK_INTERRUPTIBLE);
143 		if (!(sock->ops->poll(file, sock, &wait_table) & POLLIN)) {
144 			int timed_out;
145 			if (timeout > max_timeout) {
146 				/* JEJB/JSP 2/7/94
147 				 * This is useful to see if the system is
148 				 * hanging */
149 				if (acknowledge_seen == 0) {
150 					printk(KERN_WARNING "NCP max timeout\n");
151 				}
152 				timeout = max_timeout;
153 			}
154 			timed_out = !schedule_timeout(timeout);
155 			poll_freewait(&wait_table);
156 			current->state = TASK_RUNNING;
157 			if (signal_pending(current)) {
158 				result = -ERESTARTSYS;
159 				break;
160 			}
161 			if(wait_table.error) {
162 				result = wait_table.error;
163 				break;
164 			}
165 			if (timed_out) {
166 				if (n < retrans)
167 					continue;
168 				if (server->m.flags & NCP_MOUNT_SOFT) {
169 					printk(KERN_WARNING "NCP server not responding\n");
170 					result = -EIO;
171 					break;
172 				}
173 				n = 0;
174 				timeout = init_timeout;
175 				if (init_timeout < max_timeout)
176 					init_timeout <<= 1;
177 				if (!major_timeout_seen) {
178 					printk(KERN_WARNING "NCP server not responding\n");
179 				}
180 				major_timeout_seen = 1;
181 				continue;
182 			}
183 		} else {
184 			poll_freewait(&wait_table);
185 		}
186 		current->state = TASK_RUNNING;
187 
188 		/* Get the header from the next packet using a peek, so keep it
189 		 * on the recv queue.  If it is wrong, it will be some reply
190 		 * we don't now need, so discard it */
191 		result = _recv(sock, (void *) &reply, sizeof(reply),
192 			       MSG_PEEK | MSG_DONTWAIT);
193 		if (result < 0) {
194 			if (result == -EAGAIN) {
195 				DDPRINTK("ncp_rpc_call: bad select ready\n");
196 				goto re_select;
197 			}
198 			if (result == -ECONNREFUSED) {
199 				DPRINTK("ncp_rpc_call: server playing coy\n");
200 				goto re_select;
201 			}
202 			if (result != -ERESTARTSYS) {
203 				printk(KERN_ERR "ncp_rpc_call: recv error = %d\n",
204 				       -result);
205 			}
206 			break;
207 		}
208 		if ((result == sizeof(reply))
209 		    && (reply.type == NCP_POSITIVE_ACK)) {
210 			/* Throw away the packet */
211 			DPRINTK("ncp_rpc_call: got positive acknowledge\n");
212 			_recv(sock, (void *) &reply, sizeof(reply),
213 			      MSG_DONTWAIT);
214 			n = 0;
215 			timeout = max_timeout;
216 			acknowledge_seen = 1;
217 			goto re_select;
218 		}
219 		DDPRINTK("ncpfs: rep.typ: %04X, con: %d, tsk: %d,"
220 			 "seq: %d\n",
221 			 reply.type,
222 			 (reply.conn_high << 8) + reply.conn_low,
223 			 reply.task,
224 			 reply.sequence);
225 
226 		if ((result >= sizeof(reply))
227 		    && (reply.type == NCP_REPLY)
228 		    && ((request.type == NCP_ALLOC_SLOT_REQUEST)
229 			|| ((reply.sequence == request.sequence)
230 			    && (reply.conn_low == request.conn_low)
231 /* seem to get wrong task from NW311 && (reply.task      == request.task) */
232 			    && (reply.conn_high == request.conn_high)))) {
233 			if (major_timeout_seen)
234 				printk(KERN_NOTICE "NCP server OK\n");
235 			break;
236 		}
237 		/* JEJB/JSP 2/7/94
238 		 * we have xid mismatch, so discard the packet and start
239 		 * again.  What a hack! but I can't call recvfrom with
240 		 * a null buffer yet. */
241 		_recv(sock, (void *) &reply, sizeof(reply), MSG_DONTWAIT);
242 
243 		DPRINTK("ncp_rpc_call: reply mismatch\n");
244 		goto re_select;
245 	}
246 	/*
247 	 * we have the correct reply, so read into the correct place and
248 	 * return it
249 	 */
250 	result = _recv(sock, (void *)reply_buf, max_reply_size, MSG_DONTWAIT);
251 	if (result < 0) {
252 		printk(KERN_WARNING "NCP: notice message: result=%d\n", result);
253 	} else if (result < sizeof(struct ncp_reply_header)) {
254 		printk(KERN_ERR "NCP: just caught a too small read memory size..., "
255 		       "email to NET channel\n");
256 		printk(KERN_ERR "NCP: result=%d\n", result);
257 		result = -EIO;
258 	}
259 
260 	return result;
261 }
262 
do_tcp_rcv(struct ncp_server * server,void * buffer,size_t len)263 static int do_tcp_rcv(struct ncp_server *server, void *buffer, size_t len) {
264 	poll_table wait_table;
265 	struct file *file;
266 	struct socket *sock;
267 	int init_timeout;
268 	size_t dataread;
269 	int result = 0;
270 
271 	file = server->ncp_filp;
272 	sock = &file->f_dentry->d_inode->u.socket_i;
273 
274 	dataread = 0;
275 
276 	init_timeout = server->m.time_out * 20;
277 
278 	/* hard-mounted volumes have no timeout, except connection close... */
279 	if (!(server->m.flags & NCP_MOUNT_SOFT))
280 		init_timeout = 0x7FFF0000;
281 
282 	while (len) {
283 		poll_initwait(&wait_table);
284 		/* mb() is not necessary because ->poll() will serialize
285 		   instructions adding the wait_table waitqueues in the
286 		   waitqueue-head before going to calculate the mask-retval. */
287 		__set_current_state(TASK_INTERRUPTIBLE);
288 		if (!(sock->ops->poll(file, sock, &wait_table) & POLLIN)) {
289 			init_timeout = schedule_timeout(init_timeout);
290 			poll_freewait(&wait_table);
291 			current->state = TASK_RUNNING;
292 			if (signal_pending(current)) {
293 				return -ERESTARTSYS;
294 			}
295 			if (!init_timeout) {
296 				return -EIO;
297 			}
298 			if(wait_table.error) {
299 				return wait_table.error;
300 			}
301 		} else {
302 			poll_freewait(&wait_table);
303 		}
304 		current->state = TASK_RUNNING;
305 
306 		result = _recv(sock, buffer, len, MSG_DONTWAIT);
307 		if (result < 0) {
308 			if (result == -EAGAIN) {
309 				DDPRINTK("ncpfs: tcp: bad select ready\n");
310 				continue;
311 			}
312 			return result;
313 		}
314 		if (result == 0) {
315 			printk(KERN_ERR "ncpfs: tcp: EOF on socket\n");
316 			return -EIO;
317 		}
318 		if (result > len) {
319 			printk(KERN_ERR "ncpfs: tcp: bug in recvmsg\n");
320 			return -EIO;
321 		}
322 		dataread += result;
323 		buffer += result;
324 		len -= result;
325 	}
326 	return 0;
327 }
328 
329 #define NCP_TCP_XMIT_MAGIC	(0x446D6454)
330 #define NCP_TCP_XMIT_VERSION	(1)
331 #define NCP_TCP_RCVD_MAGIC	(0x744E6350)
332 
do_ncp_tcp_rpc_call(struct ncp_server * server,int size,struct ncp_reply_header * reply_buf,int max_reply_size)333 static int do_ncp_tcp_rpc_call(struct ncp_server *server, int size,
334 		struct ncp_reply_header* reply_buf, int max_reply_size)
335 {
336 	struct file *file;
337 	struct socket *sock;
338 	int result;
339 	struct iovec iov[2];
340 	struct msghdr msg;
341 	struct scm_cookie scm;
342 	__u32 ncptcp_rcvd_hdr[2];
343 	__u32 ncptcp_xmit_hdr[4];
344 	int   datalen;
345 
346 	/* We have to check the result, so store the complete header */
347 	struct ncp_request_header request =
348 	*((struct ncp_request_header *) (server->packet));
349 
350 	file = server->ncp_filp;
351 	sock = &file->f_dentry->d_inode->u.socket_i;
352 
353 	ncptcp_xmit_hdr[0] = htonl(NCP_TCP_XMIT_MAGIC);
354 	ncptcp_xmit_hdr[1] = htonl(size + 16);
355 	ncptcp_xmit_hdr[2] = htonl(NCP_TCP_XMIT_VERSION);
356 	ncptcp_xmit_hdr[3] = htonl(max_reply_size + 8);
357 
358 	DDPRINTK("ncpfs: req.typ: %04X, con: %d, "
359 		 "seq: %d",
360 		 request.type,
361 		 (request.conn_high << 8) + request.conn_low,
362 		 request.sequence);
363 	DDPRINTK(" func: %d\n",
364 		 request.function);
365 
366 	iov[1].iov_base = (void *) server->packet;
367 	iov[1].iov_len = size;
368 	iov[0].iov_base = ncptcp_xmit_hdr;
369 	iov[0].iov_len = 16;
370 	msg.msg_name = NULL;
371 	msg.msg_namelen = 0;
372 	msg.msg_control = NULL;
373 	msg.msg_iov = iov;
374 	msg.msg_iovlen = 2;
375 	msg.msg_flags = MSG_NOSIGNAL;
376 
377 	result = scm_send(sock, &msg, &scm);
378 	if (result < 0) {
379 		return result;
380 	}
381 	result = sock->ops->sendmsg(sock, &msg, size + 16, &scm);
382 	scm_destroy(&scm);
383 	if (result < 0) {
384 		printk(KERN_ERR "ncpfs: tcp: Send failed: %d\n", result);
385 		return result;
386 	}
387 rstrcv:
388 	result = do_tcp_rcv(server, ncptcp_rcvd_hdr, 8);
389 	if (result)
390 		return result;
391 	if (ncptcp_rcvd_hdr[0] != htonl(NCP_TCP_RCVD_MAGIC)) {
392 		printk(KERN_ERR "ncpfs: tcp: Unexpected reply type %08X\n", ntohl(ncptcp_rcvd_hdr[0]));
393 		return -EIO;
394 	}
395 	datalen = ntohl(ncptcp_rcvd_hdr[1]);
396 	if (datalen < 8 + sizeof(*reply_buf) || datalen > max_reply_size + 8) {
397 		printk(KERN_ERR "ncpfs: tcp: Unexpected reply len %d\n", datalen);
398 		return -EIO;
399 	}
400 	datalen -= 8;
401 	result = do_tcp_rcv(server, reply_buf, datalen);
402 	if (result)
403 		return result;
404 	if (reply_buf->type != NCP_REPLY) {
405 		DDPRINTK("ncpfs: tcp: Unexpected NCP type %02X\n", reply_buf->type);
406 		goto rstrcv;
407 	}
408 	if (request.type == NCP_ALLOC_SLOT_REQUEST)
409 		return datalen;
410 	if (reply_buf->sequence != request.sequence) {
411 		printk(KERN_ERR "ncpfs: tcp: Bad sequence number\n");
412 		return -EIO;
413 	}
414 	if ((reply_buf->conn_low != request.conn_low) ||
415 	    (reply_buf->conn_high != request.conn_high)) {
416 		printk(KERN_ERR "ncpfs: tcp: Connection number mismatch\n");
417 		return -EIO;
418 	}
419 	return datalen;
420 }
421 
422 /*
423  * We need the server to be locked here, so check!
424  */
425 
ncp_do_request(struct ncp_server * server,int size,void * reply,int max_reply_size)426 static int ncp_do_request(struct ncp_server *server, int size,
427 		void* reply, int max_reply_size)
428 {
429 	struct file *file;
430 	struct socket *sock;
431 	int result;
432 
433 	if (server->lock == 0) {
434 		printk(KERN_ERR "ncpfs: Server not locked!\n");
435 		return -EIO;
436 	}
437 	if (!ncp_conn_valid(server)) {
438 		return -EIO;
439 	}
440 #ifdef CONFIG_NCPFS_PACKET_SIGNING
441 	if (server->sign_active)
442 	{
443 		sign_packet(server, &size);
444 	}
445 #endif /* CONFIG_NCPFS_PACKET_SIGNING */
446 	file = server->ncp_filp;
447 	sock = &file->f_dentry->d_inode->u.socket_i;
448 	/* N.B. this isn't needed ... check socket type? */
449 	if (!sock) {
450 		printk(KERN_ERR "ncp_rpc_call: socki_lookup failed\n");
451 		result = -EBADF;
452 	} else {
453 		mm_segment_t fs;
454 		sigset_t old_set;
455 		unsigned long mask, flags;
456 
457 		spin_lock_irqsave(&current->sigmask_lock, flags);
458 		old_set = current->blocked;
459 		if (current->flags & PF_EXITING)
460 			mask = 0;
461 		else
462 			mask = sigmask(SIGKILL);
463 		if (server->m.flags & NCP_MOUNT_INTR) {
464 			/* FIXME: This doesn't seem right at all.  So, like,
465 			   we can't handle SIGINT and get whatever to stop?
466 			   What if we've blocked it ourselves?  What about
467 			   alarms?  Why, in fact, are we mucking with the
468 			   sigmask at all? -- r~ */
469 			if (current->sig->action[SIGINT - 1].sa.sa_handler == SIG_DFL)
470 				mask |= sigmask(SIGINT);
471 			if (current->sig->action[SIGQUIT - 1].sa.sa_handler == SIG_DFL)
472 				mask |= sigmask(SIGQUIT);
473 		}
474 		siginitsetinv(&current->blocked, mask);
475 		recalc_sigpending(current);
476 		spin_unlock_irqrestore(&current->sigmask_lock, flags);
477 
478 		fs = get_fs();
479 		set_fs(get_ds());
480 
481 		if (sock->type == SOCK_STREAM)
482 			result = do_ncp_tcp_rpc_call(server, size, reply, max_reply_size);
483 		else
484 			result = do_ncp_rpc_call(server, size, reply, max_reply_size);
485 
486 		set_fs(fs);
487 
488 		spin_lock_irqsave(&current->sigmask_lock, flags);
489 		current->blocked = old_set;
490 		recalc_sigpending(current);
491 		spin_unlock_irqrestore(&current->sigmask_lock, flags);
492 	}
493 
494 	DDPRINTK("do_ncp_rpc_call returned %d\n", result);
495 
496 	if (result < 0) {
497 		/* There was a problem with I/O, so the connections is
498 		 * no longer usable. */
499 		ncp_invalidate_conn(server);
500 	}
501 	return result;
502 }
503 
504 /* ncp_do_request assures that at least a complete reply header is
505  * received. It assumes that server->current_size contains the ncp
506  * request size
507  */
ncp_request2(struct ncp_server * server,int function,void * rpl,int size)508 int ncp_request2(struct ncp_server *server, int function,
509 		void* rpl, int size)
510 {
511 	struct ncp_request_header *h;
512 	struct ncp_reply_header* reply = rpl;
513 	int request_size = server->current_size
514 			 - sizeof(struct ncp_request_header);
515 	int result;
516 
517 	h = (struct ncp_request_header *) (server->packet);
518 	if (server->has_subfunction != 0) {
519 		*(__u16 *) & (h->data[0]) = htons(request_size - 2);
520 	}
521 	h->type = NCP_REQUEST;
522 
523 	server->sequence += 1;
524 	h->sequence = server->sequence;
525 	h->conn_low = (server->connection) & 0xff;
526 	h->conn_high = ((server->connection) & 0xff00) >> 8;
527 	/*
528 	 * The server shouldn't know or care what task is making a
529 	 * request, so we always use the same task number.
530 	 */
531 	h->task = 2; /* (current->pid) & 0xff; */
532 	h->function = function;
533 
534 	result = ncp_do_request(server, request_size + sizeof(*h), reply, size);
535 	if (result < 0) {
536 		DPRINTK("ncp_request_error: %d\n", result);
537 		goto out;
538 	}
539 	server->completion = reply->completion_code;
540 	server->conn_status = reply->connection_state;
541 	server->reply_size = result;
542 	server->ncp_reply_size = result - sizeof(struct ncp_reply_header);
543 
544 	result = reply->completion_code;
545 
546 	if (result != 0)
547 		PPRINTK("ncp_request: completion code=%x\n", result);
548 out:
549 	return result;
550 }
551 
ncp_connect(struct ncp_server * server)552 int ncp_connect(struct ncp_server *server)
553 {
554 	struct ncp_request_header *h;
555 	int result;
556 
557 	h = (struct ncp_request_header *) (server->packet);
558 	h->type = NCP_ALLOC_SLOT_REQUEST;
559 
560 	server->sequence = 0;
561 	h->sequence	= server->sequence;
562 	h->conn_low	= 0xff;
563 	h->conn_high	= 0xff;
564 	h->task		= 2; /* see above */
565 	h->function	= 0;
566 
567 	result = ncp_do_request(server, sizeof(*h), server->packet, server->packet_size);
568 	if (result < 0)
569 		goto out;
570 	server->sequence = 0;
571 	server->connection = h->conn_low + (h->conn_high * 256);
572 	result = 0;
573 out:
574 	return result;
575 }
576 
ncp_disconnect(struct ncp_server * server)577 int ncp_disconnect(struct ncp_server *server)
578 {
579 	struct ncp_request_header *h;
580 
581 	h = (struct ncp_request_header *) (server->packet);
582 	h->type = NCP_DEALLOC_SLOT_REQUEST;
583 
584 	server->sequence += 1;
585 	h->sequence	= server->sequence;
586 	h->conn_low	= (server->connection) & 0xff;
587 	h->conn_high	= ((server->connection) & 0xff00) >> 8;
588 	h->task		= 2; /* see above */
589 	h->function	= 0;
590 
591 	return ncp_do_request(server, sizeof(*h), server->packet, server->packet_size);
592 }
593 
ncp_lock_server(struct ncp_server * server)594 void ncp_lock_server(struct ncp_server *server)
595 {
596 	down(&server->sem);
597 	if (server->lock)
598 		printk(KERN_WARNING "ncp_lock_server: was locked!\n");
599 	server->lock = 1;
600 }
601 
ncp_unlock_server(struct ncp_server * server)602 void ncp_unlock_server(struct ncp_server *server)
603 {
604 	if (!server->lock) {
605 		printk(KERN_WARNING "ncp_unlock_server: was not locked!\n");
606 		return;
607 	}
608 	server->lock = 0;
609 	up(&server->sem);
610 }
611