File: /usr/src/linux/net/ipx/af_spx.c

1     /*
2      *	This module implements the (SPP-derived) Sequenced Packet eXchange
3      *	(SPX) protocol for Linux 2.1.X as specified in
4      *		NetWare SPX Services Specification, Semantics and API
5      *		 Revision:       1.00
6      *		 Revision Date:  February 9, 1993
7      *
8      *	Developers:
9      *      Jay Schulist    <jschlst@samba.org>
10      *	Jim Freeman	<jfree@caldera.com>
11      *
12      *	Changes:
13      *	Alan Cox	:	Fixed an skb_unshare check for NULL
14      *				that crashed it under load. Renamed and
15      *				made static the ipx ops. Removed the hack
16      *				ipx methods interface. Dropped AF_SPX - its
17      *				the wrong abstraction.
18      *	Eduardo Trapani	:	Added a check for the return value of
19      *				ipx_if_offset that crashed sock_alloc_send_skb.
20      *				Added spx_datagram_poll() so that select()
21      *				works now on SPX sockets.  Added updating
22      *				of the alloc count to follow rmt_seq.
23      *
24      *	This program is free software; you can redistribute it and/or
25      *      modify it under the terms of the GNU General Public License
26      *      as published by the Free Software Foundation; either version
27      *      2 of the License, or (at your option) any later version.
28      *
29      *	None of the authors or maintainers or their employers admit
30      *	liability nor provide warranty for any of this software.
31      *	This material is provided "as is" and at no charge.
32      */
33     
34     #include <linux/module.h>
35     #include <net/ipx.h>
36     #include <net/spx.h>
37     #include <net/sock.h>
38     #include <asm/byteorder.h>
39     #include <asm/uaccess.h>
40     #include <linux/uio.h>
41     #include <linux/unistd.h>
42     #include <linux/poll.h>
43     
44     static struct proto_ops *ipx_operations;
45     static struct proto_ops spx_ops;
46     static __u16  connids;
47     
48     /* Functions needed for SPX connection start up */
49     static int spx_transmit(struct sock *sk,struct sk_buff *skb,int type,int len);
50     static void spx_retransmit(unsigned long data);
51     static void spx_watchdog(unsigned long data);
52     void spx_rcv(struct sock *sk, int bytes);
53     
54     extern void ipx_remove_socket(struct sock *sk);
55     
56     /* Datagram poll:	the same code as datagram_poll() in net/core
57     			but the right spx buffers are looked at and
58     			there is no question on the type of the socket
59     			*/
60     static unsigned int spx_datagram_poll(struct file * file, struct socket *sock, poll_table *wait)
61     {
62     	struct sock *sk = sock->sk;
63     	struct spx_opt *pdata = &sk->tp_pinfo.af_spx;
64     	unsigned int mask;
65     
66     	poll_wait(file, sk->sleep, wait);
67     	mask = 0;
68     
69     	/* exceptional events? */
70     	if (sk->err || !skb_queue_empty(&sk->error_queue))
71     		mask |= POLLERR;
72     	if (sk->shutdown & RCV_SHUTDOWN)
73     		mask |= POLLHUP;
74     
75     	/* readable? */
76     	if (!skb_queue_empty(&pdata->rcv_queue))
77     		mask |= POLLIN | POLLRDNORM;
78     
79     	/* Need to check for termination and startup */
80     	if (sk->state==TCP_CLOSE)
81     		mask |= POLLHUP;
82     	/* connection hasn't started yet? */
83     	if (sk->state == TCP_SYN_SENT)
84     		return mask;
85     
86     	/* writable? */
87     	if (sock_writeable(sk))
88     		mask |= POLLOUT | POLLWRNORM | POLLWRBAND;
89     	else
90     		set_bit(SOCK_ASYNC_NOSPACE,&sk->socket->flags);
91     
92     	return mask;
93     }
94     
95     /* Create the SPX specific data */
96     static int spx_sock_init(struct sock *sk)
97     {
98             struct spx_opt *pdata = &sk->tp_pinfo.af_spx;
99     
100             pdata->state            = SPX_CLOSED;
101             pdata->sequence         = 0;
102     	pdata->acknowledge	= 0;
103             pdata->source_connid    = htons(connids);
104     	pdata->rmt_seq		= 0;
105             connids++;
106     
107             pdata->owner            = (void *)sk;
108             pdata->sndbuf           = sk->sndbuf;
109     
110             pdata->watchdog.function = spx_watchdog;
111             pdata->watchdog.data    = (unsigned long)sk;
112             pdata->wd_interval      = VERIFY_TIMEOUT;
113     	pdata->retransmit.function = spx_retransmit;
114     	pdata->retransmit.data	= (unsigned long)sk;
115     	pdata->retransmits	= 0;
116             pdata->retries          = 0;
117             pdata->max_retries      = RETRY_COUNT;
118     
119     	skb_queue_head_init(&pdata->rcv_queue);
120     	skb_queue_head_init(&pdata->transmit_queue);
121     	skb_queue_head_init(&pdata->retransmit_queue);
122     
123             return (0);
124     }
125     
126     static int spx_create(struct socket *sock, int protocol)
127     {
128     	struct sock *sk;
129     
130     	/*
131     	 *	Called on connection receive so cannot be GFP_KERNEL
132     	 */
133     	 
134     	sk = sk_alloc(PF_IPX, GFP_ATOMIC, 1);
135     	if(sk == NULL)
136                     return (-ENOMEM);
137     
138     	switch(sock->type)
139             {
140                     case SOCK_SEQPACKET:
141     			sock->ops = &spx_ops;
142     			break;
143     		default:
144     			sk_free(sk);
145                             return (-ESOCKTNOSUPPORT);
146             }
147     
148     	sock_init_data(sock, sk);
149     	spx_sock_init(sk);
150     	sk->data_ready  = spx_rcv;
151     	sk->destruct 	= NULL;
152             sk->no_check 	= 1;
153     
154             MOD_INC_USE_COUNT;
155     
156     	return (0);
157     }
158     
159     
160     void spx_close_socket(struct sock *sk)
161     {
162     	struct spx_opt *pdata = &sk->tp_pinfo.af_spx;
163     
164     	pdata->state	= SPX_CLOSED;
165     	sk->state 	= TCP_CLOSE;
166     	del_timer(&pdata->retransmit);
167     	del_timer(&pdata->watchdog);
168     }
169     
170     void spx_destroy_socket(struct sock *sk)
171     {
172     	struct spx_opt *pdata = &sk->tp_pinfo.af_spx;
173     	struct sk_buff *skb;
174     
175             ipx_remove_socket(sk);
176             while((skb = skb_dequeue(&sk->receive_queue)) != NULL)
177                     kfree_skb(skb);
178     	while((skb = skb_dequeue(&pdata->transmit_queue)) != NULL)
179                     kfree_skb(skb);
180     	while((skb = skb_dequeue(&pdata->retransmit_queue)) != NULL)
181     		kfree_skb(skb);
182     	while((skb = skb_dequeue(&pdata->rcv_queue)) != NULL)
183                     kfree_skb(skb);
184     
185             sk_free(sk);
186     	MOD_DEC_USE_COUNT;
187     }
188     
189     /* Release an SPX socket */
190     static int spx_release(struct socket *sock)
191     {
192      	struct sock *sk = sock->sk;
193     	struct spx_opt *pdata = &sk->tp_pinfo.af_spx;
194     
195     	if(sk == NULL)
196     		return (0);
197     	if(!sk->dead)
198                     sk->state_change(sk);
199             sk->dead = 1;
200     
201     	if(pdata->state != SPX_CLOSED)
202     	{
203     		spx_transmit(sk, NULL, DISCON, 0);
204     		spx_close_socket(sk);
205     	}
206     
207     	sock->sk	= NULL;
208     	sk->socket 	= NULL;
209     	spx_destroy_socket(sk);
210     
211             return (0);
212     }
213     
214     /* Move a socket into listening state. */
215     static int spx_listen(struct socket *sock, int backlog)
216     {
217             struct sock *sk = sock->sk;
218     
219             if(sock->state != SS_UNCONNECTED)
220                     return (-EINVAL);
221     	if(sock->type != SOCK_SEQPACKET)
222     		return (-EOPNOTSUPP);
223             if(sk->zapped != 0)
224                     return (-EAGAIN);
225     
226             sk->max_ack_backlog = backlog;
227             if(sk->state != TCP_LISTEN)
228             {
229                     sk->ack_backlog = 0;
230                     sk->state = TCP_LISTEN;
231             }
232             sk->socket->flags |= __SO_ACCEPTCON;
233     
234             return (0);
235     }
236     
237     /* Accept a pending SPX connection */
238     static int spx_accept(struct socket *sock, struct socket *newsock, int flags)
239     {
240             struct sock *sk;
241             struct sock *newsk;
242             struct sk_buff *skb;
243     	int err;
244     
245     	if(sock->sk == NULL)
246     		return (-EINVAL);
247     	sk = sock->sk;
248     
249             if((sock->state != SS_UNCONNECTED) || !(sock->flags & __SO_ACCEPTCON))
250                     return (-EINVAL);
251             if(sock->type != SOCK_SEQPACKET)
252     		return (-EOPNOTSUPP);
253     	if(sk->state != TCP_LISTEN)
254                     return (-EINVAL);
255     
256     	cli();
257     	do {
258     		skb = skb_dequeue(&sk->receive_queue);
259     		if(skb == NULL)
260     		{
261                     	if(flags & O_NONBLOCK)
262     			{
263                                     sti();
264                                     return (-EWOULDBLOCK);
265                             }
266                     	interruptible_sleep_on(sk->sleep);
267                     	if(signal_pending(current))
268                     	{
269                             	sti();
270                             	return (-ERESTARTSYS);
271                     	}
272     		}
273     	} while (skb == NULL);
274     
275     	newsk 		= skb->sk;
276             newsk->pair 	= NULL;
277     	sti();
278     
279     	err = spx_transmit(newsk, skb, CONACK, 0);   /* Connection ACK */
280     	if(err)
281     		return (err);
282     
283     	/* Now attach up the new socket */
284     	sock->sk 	= NULL;
285             sk->ack_backlog--;
286             newsock->sk 	= newsk;
287     	newsk->state 	= TCP_ESTABLISHED;
288     	newsk->protinfo.af_ipx.dest_addr = newsk->tp_pinfo.af_spx.dest_addr;
289     
290     	return (0);
291     }
292     
293     /* Build a connection to an SPX socket */
294     static int spx_connect(struct socket *sock, struct sockaddr *uaddr,
295                     int addr_len, int flags)
296     {
297     	struct sock *sk = sock->sk;
298             struct spx_opt *pdata = &sk->tp_pinfo.af_spx;
299             struct sockaddr_ipx src;
300     	struct sk_buff *skb;
301     	int size, err;
302     
303     	size = sizeof(src);
304     	err  = ipx_operations->getname(sock, (struct sockaddr *)&src, &size, 0);
305     	if(err)
306     		return (err);
307     
308             pdata->source_addr.net	= src.sipx_network;
309             memcpy(pdata->source_addr.node, src.sipx_node, IPX_NODE_LEN);
310             pdata->source_addr.sock = (unsigned short)src.sipx_port;
311     
312     	err = ipx_operations->connect(sock, uaddr, addr_len, flags);
313             if(err)
314                     return (err);
315     
316             pdata->dest_addr = sk->protinfo.af_ipx.dest_addr;
317     	pdata->state	 = SPX_CONNECTING;
318     	sock->state	 = SS_CONNECTING;
319             sk->state	 = TCP_SYN_SENT;
320     
321             /* Send Connection request */
322     	err = spx_transmit(sk, NULL, CONREQ, 0);
323             if(err)
324                     return (err);
325     
326     	cli();
327             do {
328                     skb = skb_dequeue(&sk->receive_queue);
329                     if(skb == NULL)
330                     {
331                             if(flags & O_NONBLOCK)
332                             {
333                                     sti();
334                                     return (-EWOULDBLOCK);
335                             }
336                             interruptible_sleep_on(sk->sleep);
337                             if(signal_pending(current))
338                             {
339                                     sti();
340                                     return (-ERESTARTSYS);
341                             }
342                     }
343             } while (skb == NULL);
344     
345             if(pdata->state == SPX_CLOSED)
346             {
347     		sti();
348                     del_timer(&pdata->watchdog);
349                     return (-ETIMEDOUT);
350             }
351     
352     	sock->state	= SS_CONNECTED;
353     	sk->state 	= TCP_ESTABLISHED;
354     	kfree_skb(skb);
355     	sti();
356     
357             return (0);
358     }
359     
360     /*
361      * Calculate the timeout for a packet. Thankfully SPX has a large
362      * fudge factor (3/4 secs) and does not pay much attention to RTT.
363      * As we simply have a default retry time of 1*HZ and a max retry
364      * time of 5*HZ. Between those values we increase the timeout based
365      * on the number of retransmit tries.
366      *
367      * FixMe: This is quite fake, but will work for now. (JS)
368      */
369     static inline unsigned long spx_calc_rtt(int tries)
370     {
371             if(tries < 1)
372                     return (RETRY_TIME);
373             if(tries > 5)
374                     return (MAX_RETRY_DELAY);
375             return (tries * HZ);
376     }
377     
378     static int spx_route_skb(struct spx_opt *pdata, struct sk_buff *skb, int type)
379     {
380     	struct sk_buff *skb2;
381     	int err = 0;
382     
383     	skb = skb_unshare(skb, GFP_ATOMIC);
384     	if(skb == NULL)
385     		return (-ENOBUFS);
386     
387     	switch(type)
388     	{
389     		case (CONREQ):
390     		case (DATA):
391     			if(!skb_queue_empty(&pdata->retransmit_queue))
392     			{
393     				skb_queue_tail(&pdata->transmit_queue, skb);
394     				return 0;
395     			}
396     
397     		case (TQUEUE):
398     			pdata->retransmit.expires = jiffies + spx_calc_rtt(0);
399     			add_timer(&pdata->retransmit);
400     
401     			skb2 = skb_clone(skb, GFP_NOIO);
402     	                if(skb2 == NULL)
403             	                return -ENOBUFS;
404             	        skb_queue_tail(&pdata->retransmit_queue, skb2);
405     
406     		case (ACK):
407     		case (CONACK):
408     		case (WDREQ):
409     		case (WDACK):
410     		case (DISCON):
411     		case (DISACK):
412     		case (RETRAN):
413     		default:
414     			/* Send data */
415             		err = ipxrtr_route_skb(skb);
416             		if(err)
417                     		kfree_skb(skb);
418     	}
419     
420     	return (err);
421     }
422     
423     /* SPX packet transmit engine */
424     static int spx_transmit(struct sock *sk, struct sk_buff *skb, int type, int len)
425     {
426             struct spx_opt *pdata = &sk->tp_pinfo.af_spx;
427             struct ipxspxhdr *ipxh;
428     	unsigned long flags;
429     	int err;
430     
431     	if(skb == NULL)
432     	{
433     		int offset  = ipx_if_offset(pdata->dest_addr.net);
434             	int size    = offset + sizeof(struct ipxspxhdr);
435     
436             	if (offset < 0) /* ENETUNREACH */
437             		return(-ENETUNREACH);
438     
439     		save_flags(flags);
440     		cli();
441             	skb = sock_alloc_send_skb(sk, size, 0, &err);
442             	if(skb == NULL) {
443     			restore_flags(flags);
444                     	return (-ENOMEM);
445     		}
446             	skb_reserve(skb, offset);
447             	skb->h.raw = skb->nh.raw = skb_put(skb,sizeof(struct ipxspxhdr));
448     		restore_flags(flags);
449     	}
450     
451     	/* IPX header */
452     	ipxh = (struct ipxspxhdr *)skb->nh.raw;
453     	ipxh->ipx.ipx_checksum  = 0xFFFF;
454     	ipxh->ipx.ipx_pktsize   = htons(SPX_SYS_PKT_LEN);
455             ipxh->ipx.ipx_tctrl     = 0;
456     	ipxh->ipx.ipx_type 	= IPX_TYPE_SPX;
457             ipxh->ipx.ipx_dest      = pdata->dest_addr;
458             ipxh->ipx.ipx_source    = pdata->source_addr;
459     
460     	/* SPX header */
461             ipxh->spx.dtype         = 0;
462     	ipxh->spx.sequence      = htons(pdata->sequence);
463     	ipxh->spx.ackseq        = htons(pdata->rmt_seq);
464     	ipxh->spx.sconn         = pdata->source_connid;
465             ipxh->spx.dconn         = pdata->dest_connid;
466             ipxh->spx.allocseq      = htons(pdata->alloc);
467     
468     	/* Reset/Set WD timer */
469             mod_timer(&pdata->watchdog, jiffies+VERIFY_TIMEOUT);
470     
471     	switch(type)
472     	{
473     		case (DATA):	/* Data */
474     			ipxh->ipx.ipx_pktsize 	= htons(SPX_SYS_PKT_LEN + len);
475     			ipxh->spx.cctl 		= (CCTL_ACK | CCTL_EOM);
476                     	pdata->sequence++;
477     			break;
478     
479     		case (ACK):	/* ACK */
480     			pdata->rmt_seq++;
481     		case (WDACK):	/* WD ACK */
482     		case (CONACK):	/* Connection ACK */
483     			ipxh->spx.cctl 		= CCTL_SYS;
484     			ipxh->spx.ackseq 	= htons(pdata->rmt_seq);
485     			break;
486     
487     		case (CONREQ):	/* Connection Request */
488     			del_timer(&pdata->watchdog);
489     		case (WDREQ):	/* WD Request */
490     			pdata->source_connid    = htons(connids++);
491                     	pdata->dest_connid      = 0xFFFF;
492                     	pdata->alloc 		= 3 + pdata->rmt_seq;
493     			ipxh->spx.cctl          = (CCTL_ACK | CCTL_SYS);
494     			ipxh->spx.sconn         = pdata->source_connid;
495     		        ipxh->spx.dconn         = pdata->dest_connid;
496     		        ipxh->spx.allocseq      = htons(pdata->alloc);
497     			break;
498     
499     		case (DISCON):	/* Informed Disconnect */
500     			ipxh->spx.cctl 		= CCTL_ACK;
501     			ipxh->spx.dtype 	= SPX_DTYPE_ECONN;
502     			break;
503     
504     		case (DISACK):	/* Informed Disconnect ACK */
505     			ipxh->spx.cctl  	= 0;
506     			ipxh->spx.dtype 	= SPX_DTYPE_ECACK;
507     			ipxh->spx.sequence 	= 0;
508     			ipxh->spx.ackseq 	= htons(pdata->rmt_seq++);
509     			break;
510     
511     		default:
512     			return (-EOPNOTSUPP);
513     	}
514     
515     	/* Send data */
516             return (spx_route_skb(pdata, skb, type));
517     }
518     
519     /* Check the state of the connection and send a WD request if needed. */
520     static void spx_watchdog(unsigned long data)
521     {
522     	struct sock *sk = (struct sock*)data;
523             struct spx_opt *pdata = &sk->tp_pinfo.af_spx;
524     
525             del_timer(&pdata->watchdog);
526     	if(pdata->state == SPX_CLOSED)
527                     return;
528     	if(pdata->retries > pdata->max_retries)
529             {
530     		spx_close_socket(sk);	/* Unilateral Abort */
531                     return;
532             }
533     
534             /* Send WD request */
535     	spx_transmit(sk, NULL, WDREQ, 0);
536     	pdata->retries++;
537     
538             return;
539     }
540     
541     static void spx_retransmit(unsigned long data)
542     {
543     	struct sock *sk = (struct sock*)data;
544             struct spx_opt *pdata = &sk->tp_pinfo.af_spx;
545     	struct sk_buff *skb;
546     	unsigned long flags;
547     	int err;
548     
549     	del_timer(&pdata->retransmit);
550     	if(pdata->state == SPX_CLOSED)
551     		return;
552     	if(pdata->retransmits > RETRY_COUNT)
553     	{
554     		spx_close_socket(sk);   /* Unilateral Abort */
555                     return;
556             }
557     
558     	/* Need to leave skb on the queue, aye the fear */
559     	save_flags(flags);
560     	cli();
561     	skb = skb_peek(&pdata->retransmit_queue);
562     	if(skb_cloned(skb))
563                     skb = skb_copy(skb, GFP_ATOMIC);
564             else
565                     skb = skb_clone(skb, GFP_ATOMIC);
566     	restore_flags(flags);
567     
568     	pdata->retransmit.expires = jiffies + spx_calc_rtt(pdata->retransmits);
569     	add_timer(&pdata->retransmit);
570     
571     	err = spx_route_skb(pdata, skb, RETRAN);
572     	pdata->retransmits++;
573     
574     	return;
575     }
576     
577     /* Check packet for retransmission, ConReqAck aware */
578     static int spx_retransmit_chk(struct spx_opt *pdata, int ackseq, int type)
579     {
580     	struct ipxspxhdr *ipxh;
581     	struct sk_buff *skb;
582     
583     	skb = skb_dequeue(&pdata->retransmit_queue);
584     	if(!skb)
585     		return (-ENOENT);
586     
587     	/* Check Data/ACK seq */
588     	switch(type)
589     	{
590     		case ACK:	/* Check Sequence, Should == 1 */
591     			ipxh = (struct ipxspxhdr *)skb->nh.raw;
592     			if(!(ntohs(ipxh->spx.sequence) - htons(ackseq)))
593     				break;
594     
595     		case CONACK:
596     			del_timer(&pdata->retransmit);
597     			pdata->retransmits = 0;
598     			kfree_skb(skb);
599     			if(skb_queue_empty(&pdata->retransmit_queue))
600     			{
601     				skb = skb_dequeue(&pdata->transmit_queue);
602     				if(skb != NULL)
603     					spx_route_skb(pdata, skb, TQUEUE);
604     			}
605     			return (0);
606     	}
607     
608     	skb_queue_head(&pdata->retransmit_queue, skb);
609     	return (-1);
610     }
611     
612     /* SPX packet receive engine */
613     void spx_rcv(struct sock *sk, int bytes)
614     {
615     	struct sk_buff *skb;
616     	struct ipxspxhdr *ipxh;
617     	struct spx_opt *pdata = &sk->tp_pinfo.af_spx;
618     
619     	skb = skb_dequeue(&sk->receive_queue);
620     	if(skb == NULL)
621     		return;
622     	ipxh = (struct ipxspxhdr *)skb->nh.raw;
623     
624     	/* Can't receive on a closed connection */
625             if((pdata->state == SPX_CLOSED) && (ipxh->spx.sequence != 0))
626     		goto toss_skb;
627     	if(ntohs(ipxh->ipx.ipx_pktsize) < SPX_SYS_PKT_LEN)
628     		goto toss_skb;
629             if(ipxh->ipx.ipx_type != IPX_TYPE_SPX)
630     		goto toss_skb;
631             if(ntohs(ipxh->spx.ackseq) > pdata->sequence)
632     		goto toss_skb;
633     
634     	/* Reset WD timer on any received packet */
635     	del_timer(&pdata->watchdog);
636     	pdata->retries = 0;
637     	pdata->watchdog.expires = jiffies + ABORT_TIMEOUT;
638             add_timer(&pdata->watchdog);
639     
640     	switch(ipxh->spx.cctl)
641     	{
642     		case (CCTL_SYS | CCTL_ACK):
643     			if((ipxh->spx.sequence == 0)	/* ConReq */
644     				&& (ipxh->spx.ackseq == 0)
645     				&& (ipxh->spx.dconn == 0xFFFF))
646     			{
647     				pdata->state		= SPX_CONNECTED;
648     				pdata->dest_addr        = ipxh->ipx.ipx_source;
649     				pdata->source_addr      = ipxh->ipx.ipx_dest;
650     				pdata->dest_connid      = ipxh->spx.sconn;
651     				pdata->alloc = 3 + ntohs(ipxh->spx.sequence);
652     
653     				skb_queue_tail(&sk->receive_queue, skb);
654     				wake_up_interruptible(sk->sleep);
655     			}
656     			else	/* WD Request */
657     				spx_transmit(sk, skb, WDACK, 0);
658     			goto finish;
659     
660     		case CCTL_SYS:	/* ACK */
661     			if((ipxh->spx.dtype == 0)       /* ConReq ACK */
662                                     && (ipxh->spx.sconn != 0xFFFF)
663                                     && (ipxh->spx.dconn != 0xFFFF)
664                                     && (ipxh->spx.sequence == 0)
665                                     && (ipxh->spx.ackseq == 0)
666                                     && (pdata->state != SPX_CONNECTED))
667                             {
668                                     pdata->state = SPX_CONNECTED;
669     				pdata->dest_connid = ipxh->spx.sconn;
670     
671     				if(spx_retransmit_chk(pdata, 0, CONACK) < 0)
672     					goto toss_skb;
673     
674                                     skb_queue_tail(&sk->receive_queue, skb);
675                                     wake_up_interruptible(sk->sleep);
676                                     goto finish;
677                             }
678     
679     			spx_retransmit_chk(pdata, ipxh->spx.ackseq, ACK);
680     			goto toss_skb;
681     
682     		case (CCTL_ACK):
683     			/* Informed Disconnect */
684     			if(ipxh->spx.dtype == SPX_DTYPE_ECONN)
685     			{
686     				
687     				spx_transmit(sk, skb, DISACK, 0);
688     				spx_close_socket(sk);
689     				goto finish;
690     			}
691     			/* Fall through */
692     
693     		default:
694     			if(ntohs(ipxh->spx.sequence) == pdata->rmt_seq)
695     			{
696     				pdata->rmt_seq = ntohs(ipxh->spx.sequence);
697     				pdata->rmt_ack = ntohs(ipxh->spx.ackseq);
698     				pdata->alloc   = pdata->rmt_seq + 3;
699     				if(pdata->rmt_ack > 0 || pdata->rmt_ack == 0)
700     					spx_retransmit_chk(pdata,pdata->rmt_ack, ACK);
701     
702     				skb_queue_tail(&pdata->rcv_queue, skb);
703     				wake_up_interruptible(sk->sleep);
704     				if(ipxh->spx.cctl&CCTL_ACK)
705     					spx_transmit(sk, NULL, ACK, 0);
706     				goto finish;
707     			}
708     
709     			if(ipxh->spx.dtype == SPX_DTYPE_ECACK)
710     			{
711     				if(pdata->state != SPX_CLOSED)
712     					spx_close_socket(sk);
713     				goto toss_skb;
714     			}
715     	}
716     
717     toss_skb:	/* Catch All */
718     	kfree_skb(skb);
719     finish:
720             return;
721     }
722     
723     /* Get message/packet data from user-land */
724     static int spx_sendmsg(struct socket *sock, struct msghdr *msg, int len,
725     			struct scm_cookie *scm)
726     {
727     	struct sock *sk = sock->sk;
728     	int flags = msg->msg_flags;
729     	struct sk_buff *skb;
730     	int err, offset, size;
731     
732     	if(len > 534)
733                     return (-EMSGSIZE);
734             if(sk->zapped)
735                     return (-ENOTCONN); /* Socket not bound */
736     	if(flags&~MSG_DONTWAIT)
737                     return (-EINVAL);
738     
739     	offset	= ipx_if_offset(sk->tp_pinfo.af_spx.dest_addr.net);
740             size 	= offset + sizeof(struct ipxspxhdr) + len;
741     
742     	cli();
743             skb  	= sock_alloc_send_skb(sk, size, flags&MSG_DONTWAIT, &err);
744     	sti();
745             if(skb == NULL)
746                     return (err);
747     
748     	skb->sk = sk;
749             skb_reserve(skb, offset);
750     	skb->h.raw = skb->nh.raw = skb_put(skb, sizeof(struct ipxspxhdr));
751     
752     	err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
753     	if(err)
754             {
755                     kfree_skb(skb);
756                     return (-EFAULT);
757             }
758     
759     	err = spx_transmit(sk, skb, DATA, len);
760     	if(err)
761     		return (-EAGAIN);
762     
763             return (len);
764     }
765     
766     /* Send message/packet data to user-land */
767     static int spx_recvmsg(struct socket *sock, struct msghdr *msg, int size,
768     			int flags, struct scm_cookie *scm)
769     {
770     	struct sk_buff *skb;
771     	struct ipxspxhdr *ispxh;
772     	struct sock *sk = sock->sk;
773     	struct spx_opt *pdata = &sk->tp_pinfo.af_spx;
774     	struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)msg->msg_name;
775     	int copied, err;
776     
777             if(sk->zapped)
778                     return (-ENOTCONN); /* Socket not bound */
779     
780     	lock_sock(sk);
781     restart:
782             while(skb_queue_empty(&pdata->rcv_queue))      /* No data */
783             {
784                     /* Socket errors? */
785                     err = sock_error(sk);
786                     if(err)
787     			return (err);
788     
789                     /* Socket shut down? */
790                     if(sk->shutdown & RCV_SHUTDOWN)
791     			return (-ESHUTDOWN);
792     
793                     /* handle signals */
794                     if(signal_pending(current))
795     			return (-ERESTARTSYS);
796     
797                     /* User doesn't want to wait */
798                     if(flags&MSG_DONTWAIT)
799     			return (-EAGAIN);
800     
801     		release_sock(sk);
802             	save_flags(flags);
803             	cli();
804             	if(skb_peek(&pdata->rcv_queue) == NULL)
805                     	interruptible_sleep_on(sk->sleep);
806             	restore_flags(flags);
807             	lock_sock(sk);
808             }
809     
810             skb = skb_dequeue(&pdata->rcv_queue);
811             if(skb == NULL) 
812     		goto restart;
813     
814     	ispxh 	= (struct ipxspxhdr *)skb->nh.raw;
815     	copied 	= ntohs(ispxh->ipx.ipx_pktsize) - SPX_SYS_PKT_LEN;
816             if(copied > size)
817     	{
818                     copied = size;
819                     msg->msg_flags |= MSG_TRUNC;
820             }
821     
822     	err = memcpy_toiovec(msg->msg_iov, skb->nh.raw+SPX_SYS_PKT_LEN, copied);
823             if(err)
824                     return (-EFAULT);
825     
826     	msg->msg_namelen = sizeof(*sipx);
827     	if(sipx)
828     	{
829     		sipx->sipx_family	= AF_IPX;
830                     sipx->sipx_port		= ispxh->ipx.ipx_source.sock;
831                     memcpy(sipx->sipx_node,ispxh->ipx.ipx_source.node,IPX_NODE_LEN);
832                     sipx->sipx_network	= ispxh->ipx.ipx_source.net;
833                     sipx->sipx_type 	= ispxh->ipx.ipx_type;
834             }
835     	kfree_skb(skb);
836             release_sock(sk);
837     
838     	return (copied);
839     }
840     
841     /*
842      * Functions which just wrap their IPX cousins
843      */
844     
845     static int spx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
846     {
847             int err;
848             err = ipx_operations->bind(sock, uaddr, addr_len);
849             return (err);
850     }
851     
852     static int spx_getname (struct socket *sock, struct sockaddr *uaddr,
853                              int *usockaddr_len, int peer)
854     {
855     	int err;
856     	err = ipx_operations->getname(sock, uaddr, usockaddr_len, peer);
857     	return (err);
858     }
859     
860     static int spx_ioctl (struct socket *sock, unsigned int cmd,
861                              unsigned long arg)
862     {
863     	int err;
864     	err = ipx_operations->ioctl(sock, cmd, arg);
865     	return (err);
866     }
867     
868     static int spx_setsockopt(struct socket *sock, int level, int optname,
869                              char *optval, int optlen)
870     {
871     	int err;
872     	err = ipx_operations->setsockopt(sock, level, optname, optval, optlen);
873     	return (err);
874     }
875     
876     static int spx_getsockopt(struct socket *sock, int level, int optname,
877                              char *optval, int *optlen)
878     {
879     	int err;
880     	err = ipx_operations->getsockopt(sock, level, optname, optval, optlen);
881     	return (err);
882     }
883     
884     static struct proto_ops SOCKOPS_WRAPPED(spx_ops) = {
885     	family:		PF_IPX,
886     
887     	release:	spx_release,
888     	bind:		spx_bind,
889     	connect:	spx_connect,
890     	socketpair:	sock_no_socketpair,
891     	accept:		spx_accept,
892     	getname:	spx_getname,
893     	poll:		spx_datagram_poll,
894     	ioctl:		spx_ioctl,
895     	listen:		spx_listen,
896     	shutdown:	sock_no_shutdown,
897     	setsockopt:	spx_setsockopt,
898     	getsockopt:	spx_getsockopt,
899     	sendmsg:	spx_sendmsg,
900     	recvmsg:	spx_recvmsg,
901     	mmap:		sock_no_mmap,
902     	sendpage:	sock_no_sendpage,
903     };
904     
905     #include <linux/smp_lock.h>
906     SOCKOPS_WRAP(spx, PF_IPX);
907     
908     static struct net_proto_family spx_family_ops = {
909     	family:		PF_IPX,
910     	create:		spx_create,
911     };
912     
913     static char banner[] __initdata = KERN_INFO "NET4: Sequenced Packet eXchange (SPX) 0.02 for Linux NET4.0\n";
914     
915     static int __init spx_proto_init(void)
916     {
917     	int error;
918     
919     	connids = (__u16)jiffies;	/* initalize random */
920     
921     	error = ipx_register_spx(&ipx_operations, &spx_family_ops);
922             if (error)
923                     printk(KERN_ERR "SPX: unable to register with IPX.\n");
924     
925     	/* route socket(PF_IPX, SOCK_SEQPACKET) calls through spx_create() */
926     
927     	printk(banner);
928     	return 0;
929     }
930     module_init(spx_proto_init);
931     
932     static void __exit spx_proto_finito(void)
933     {
934     	ipx_unregister_spx();
935     	return;
936     }
937     module_exit(spx_proto_finito);
938