cleanup
[linux-2.4.21-pre4.git] / 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);