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 */
spx_datagram_poll(struct file * file,struct socket * sock,poll_table * wait)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 */
spx_sock_init(struct sock * sk)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
spx_create(struct socket * sock,int protocol)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
spx_close_socket(struct sock * sk)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
spx_destroy_socket(struct sock * sk)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 */
spx_release(struct socket * sock)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. */
spx_listen(struct socket * sock,int backlog)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 */
spx_accept(struct socket * sock,struct socket * newsock,int flags)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 */
spx_connect(struct socket * sock,struct sockaddr * uaddr,int addr_len,int flags)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 */
spx_calc_rtt(int tries)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
spx_route_skb(struct spx_opt * pdata,struct sk_buff * skb,int type)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 */
spx_transmit(struct sock * sk,struct sk_buff * skb,int type,int len)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. */
spx_watchdog(unsigned long data)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
spx_retransmit(unsigned long data)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 */
spx_retransmit_chk(struct spx_opt * pdata,int ackseq,int type)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 */
spx_rcv(struct sock * sk,int bytes)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 */
spx_sendmsg(struct socket * sock,struct msghdr * msg,int len,struct scm_cookie * scm)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 */
spx_recvmsg(struct socket * sock,struct msghdr * msg,int size,int flags,struct scm_cookie * scm)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
spx_bind(struct socket * sock,struct sockaddr * uaddr,int addr_len)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
spx_getname(struct socket * sock,struct sockaddr * uaddr,int * usockaddr_len,int peer)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
spx_ioctl(struct socket * sock,unsigned int cmd,unsigned long arg)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
spx_setsockopt(struct socket * sock,int level,int optname,char * optval,int optlen)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
spx_getsockopt(struct socket * sock,int level,int optname,char * optval,int * optlen)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
spx_proto_init(void)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
spx_proto_finito(void)932 static void __exit spx_proto_finito(void)
933 {
934 ipx_unregister_spx();
935 return;
936 }
937 module_exit(spx_proto_finito);
938