This source file includes following definitions.
- ipxcfg_set_auto_create
- ipxcfg_set_auto_select
- ipxcfg_get_config_data
- ipx_remove_socket
- ipx_destroy_socket
- ipxitf_clear_primary_net
- ipxitf_find_using_phys
- ipxitf_find_using_net
- ipxitf_insert_socket
- ipxitf_find_socket
- ipxitf_find_internal_socket
- ipxitf_down
- ipxitf_device_event
- ipxitf_def_skb_handler
- ipxitf_demux_socket
- ipxitf_demux_socket
- ipxitf_adjust_skbuff
- ipxitf_send
- ipxitf_add_local_route
- ipxitf_rcv
- ipxitf_insert
- ipxitf_create_internal
- ipx_map_frame_type
- ipxitf_create
- ipxitf_delete
- ipxitf_auto_create
- ipxitf_ioctl
- ipxrtr_lookup
- ipxrtr_add_route
- ipxrtr_del_routes
- ipxrtr_create
- ipxrtr_delete
- ipxrtr_route_packet
- ipxrtr_route_skb
- ipxrtr_ioctl
- ipx_frame_name
- ipx_device_name
- ipx_interface_get_info
- ipx_get_info
- ipx_rt_get_info
- ipx_fcntl
- ipx_setsockopt
- ipx_getsockopt
- ipx_listen
- def_callback1
- def_callback2
- ipx_create
- ipx_release
- ipx_dup
- ipx_first_free_socketnum
- ipx_bind
- ipx_connect
- ipx_socketpair
- ipx_accept
- ipx_getname
- dump_data
- dump_addr
- dump_hdr
- dump_pkt
- ipx_rcv
- ipx_sendmsg
- ipx_recvmsg
- ipx_shutdown
- ipx_select
- ipx_ioctl
- ipx_proto_init
- ipx_proto_finito
- init_module
- cleanup_module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 #include <linux/module.h>
53
54 #include <linux/config.h>
55 #include <linux/errno.h>
56 #include <linux/types.h>
57 #include <linux/socket.h>
58 #include <linux/in.h>
59 #include <linux/kernel.h>
60 #include <linux/sched.h>
61 #include <linux/timer.h>
62 #include <linux/string.h>
63 #include <linux/sockios.h>
64 #include <linux/net.h>
65 #include <linux/netdevice.h>
66 #include <net/ipx.h>
67 #include <linux/inet.h>
68 #include <linux/route.h>
69 #include <net/sock.h>
70 #include <asm/segment.h>
71 #include <asm/system.h>
72 #include <linux/fcntl.h>
73 #include <linux/mm.h>
74 #include <linux/termios.h>
75 #include <linux/interrupt.h>
76 #include <net/p8022.h>
77 #include <net/psnap.h>
78 #include <linux/proc_fs.h>
79 #include <linux/stat.h>
80 #include <linux/firewall.h>
81
82 #ifdef MODULE
83 static void ipx_proto_finito(void);
84 #endif
85
86
87 static unsigned char ipxcfg_max_hops = 16;
88 static char ipxcfg_auto_select_primary = 0;
89 static char ipxcfg_auto_create_interfaces = 0;
90
91
92 static struct datalink_proto *p8022_datalink = NULL;
93 static struct datalink_proto *pEII_datalink = NULL;
94 static struct datalink_proto *p8023_datalink = NULL;
95 static struct datalink_proto *pSNAP_datalink = NULL;
96
97 static ipx_route *ipx_routes = NULL;
98 static ipx_interface *ipx_interfaces = NULL;
99 static ipx_interface *ipx_primary_net = NULL;
100 static ipx_interface *ipx_internal_net = NULL;
101
102 static int
103 ipxcfg_set_auto_create(char val)
104 {
105 ipxcfg_auto_create_interfaces = val;
106 return 0;
107 }
108
109 static int
110 ipxcfg_set_auto_select(char val)
111 {
112 ipxcfg_auto_select_primary = val;
113 if (val && (ipx_primary_net == NULL))
114 ipx_primary_net = ipx_interfaces;
115 return 0;
116 }
117
118 static int
119 ipxcfg_get_config_data(ipx_config_data *arg)
120 {
121 ipx_config_data vals;
122
123 vals.ipxcfg_auto_create_interfaces = ipxcfg_auto_create_interfaces;
124 vals.ipxcfg_auto_select_primary = ipxcfg_auto_select_primary;
125 memcpy_tofs(arg, &vals, sizeof(vals));
126 return 0;
127 }
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142 static void
143 ipx_remove_socket(ipx_socket *sk)
144 {
145 ipx_socket *s;
146 ipx_interface *intrfc;
147 unsigned long flags;
148
149 save_flags(flags);
150 cli();
151
152
153 intrfc = sk->protinfo.af_ipx.intrfc;
154 if (intrfc == NULL) {
155 restore_flags(flags);
156 return;
157 }
158
159 s=intrfc->if_sklist;
160 if(s==sk) {
161 intrfc->if_sklist=s->next;
162 restore_flags(flags);
163 return;
164 }
165
166 while(s && s->next) {
167 if(s->next==sk) {
168 s->next=sk->next;
169 restore_flags(flags);
170 return;
171 }
172 s=s->next;
173 }
174 restore_flags(flags);
175 }
176
177
178
179
180
181
182
183
184 static void
185 ipx_destroy_socket(ipx_socket *sk)
186 {
187 struct sk_buff *skb;
188
189 ipx_remove_socket(sk);
190 while((skb=skb_dequeue(&sk->receive_queue))!=NULL) {
191 kfree_skb(skb,FREE_READ);
192 }
193
194 kfree_s(sk,sizeof(*sk));
195 MOD_DEC_USE_COUNT;
196 }
197
198
199
200
201
202 static ipx_route * ipxrtr_lookup(unsigned long);
203
204 static void
205 ipxitf_clear_primary_net(void)
206 {
207 if (ipxcfg_auto_select_primary && (ipx_interfaces != NULL))
208 ipx_primary_net = ipx_interfaces;
209 else
210 ipx_primary_net = NULL;
211 }
212
213 static ipx_interface *
214 ipxitf_find_using_phys(struct device *dev, unsigned short datalink)
215 {
216 ipx_interface *i;
217
218 for (i=ipx_interfaces;
219 i && ((i->if_dev!=dev) || (i->if_dlink_type!=datalink));
220 i=i->if_next)
221 ;
222 return i;
223 }
224
225 static ipx_interface *
226 ipxitf_find_using_net(unsigned long net)
227 {
228 ipx_interface *i;
229
230 if (net == 0L)
231 return ipx_primary_net;
232
233 for (i=ipx_interfaces; i && (i->if_netnum!=net); i=i->if_next)
234 ;
235
236 return i;
237 }
238
239
240 static void
241 ipxitf_insert_socket(ipx_interface *intrfc, ipx_socket *sk)
242 {
243 ipx_socket *s;
244
245 sk->protinfo.af_ipx.intrfc = intrfc;
246 sk->next = NULL;
247 if (intrfc->if_sklist == NULL) {
248 intrfc->if_sklist = sk;
249 } else {
250 for (s = intrfc->if_sklist; s->next != NULL; s = s->next)
251 ;
252 s->next = sk;
253 }
254 }
255
256 static ipx_socket *
257 ipxitf_find_socket(ipx_interface *intrfc, unsigned short port)
258 {
259 ipx_socket *s;
260
261 for (s=intrfc->if_sklist;
262 (s != NULL) && (s->protinfo.af_ipx.port != port);
263 s=s->next)
264 ;
265
266 return s;
267 }
268
269 #ifdef CONFIG_IPX_INTERN
270
271 static ipx_socket *
272 ipxitf_find_internal_socket(ipx_interface *intrfc,
273 unsigned char *node, unsigned short port)
274 {
275 ipx_socket *s = intrfc->if_sklist;
276
277 while (s != NULL)
278 {
279 if ( (s->protinfo.af_ipx.port == port)
280 && (memcmp(node, s->protinfo.af_ipx.node, IPX_NODE_LEN) == 0))
281 {
282 break;
283 }
284 s = s->next;
285 }
286 return s;
287 }
288 #endif
289
290 static void ipxrtr_del_routes(ipx_interface *);
291
292 static void
293 ipxitf_down(ipx_interface *intrfc)
294 {
295 ipx_interface *i;
296 ipx_socket *s, *t;
297
298
299 ipxrtr_del_routes(intrfc);
300
301
302 for (s = intrfc->if_sklist; s != NULL; ) {
303 s->err = ENOLINK;
304 s->error_report(s);
305 s->protinfo.af_ipx.intrfc = NULL;
306 s->protinfo.af_ipx.port = 0;
307 s->zapped=1;
308 t = s;
309 s = s->next;
310 t->next = NULL;
311 }
312 intrfc->if_sklist = NULL;
313
314
315 if (intrfc == ipx_interfaces) {
316 ipx_interfaces = intrfc->if_next;
317 } else {
318 for (i = ipx_interfaces;
319 (i != NULL) && (i->if_next != intrfc);
320 i = i->if_next)
321 ;
322 if ((i != NULL) && (i->if_next == intrfc))
323 i->if_next = intrfc->if_next;
324 }
325
326
327 if (intrfc == ipx_primary_net)
328 ipxitf_clear_primary_net();
329 if (intrfc == ipx_internal_net)
330 ipx_internal_net = NULL;
331
332 kfree_s(intrfc, sizeof(*intrfc));
333
334
335
336 return;
337 }
338
339 static int
340 ipxitf_device_event(struct notifier_block *notifier, unsigned long event, void *ptr)
341 {
342 struct device *dev = ptr;
343 ipx_interface *i, *tmp;
344
345 if(event!=NETDEV_DOWN)
346 return NOTIFY_DONE;
347
348 for (i = ipx_interfaces; i != NULL; ) {
349
350 tmp = i->if_next;
351 if (i->if_dev == dev)
352 ipxitf_down(i);
353 i = tmp;
354
355 }
356
357 return NOTIFY_DONE;
358 }
359
360 static int ipxitf_def_skb_handler(struct sock *sock, struct sk_buff *skb)
361 {
362 int retval;
363
364 if((retval = sock_queue_rcv_skb(sock, skb))<0)
365 {
366
367
368
369
370 kfree_skb(skb,FREE_WRITE);
371 }
372 return retval;
373 }
374
375
376
377
378
379 #ifdef CONFIG_IPX_INTERN
380 static int
381 ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int copy)
382 {
383 ipx_packet *ipx = (ipx_packet *)(skb->h.raw);
384 ipx_socket *s;
385
386 int is_broadcast = (memcmp(ipx->ipx_dest.node, ipx_broadcast_node,
387 IPX_NODE_LEN) == 0);
388
389 s = intrfc->if_sklist;
390
391 while (s != NULL)
392 {
393 if ( (s->protinfo.af_ipx.port == ipx->ipx_dest.sock)
394 && ( is_broadcast
395 || (memcmp(ipx->ipx_dest.node, s->protinfo.af_ipx.node,
396 IPX_NODE_LEN) == 0)))
397 {
398
399 struct sk_buff *skb1;
400
401 if (copy != 0)
402 {
403 skb1 = skb_clone(skb, GFP_ATOMIC);
404 if (skb1 != NULL)
405 {
406 skb1->arp = skb1->free = 1;
407 }
408 else
409 {
410 return -ENOMEM;
411 }
412 }
413 else
414 {
415 skb1 = skb;
416 copy = 1;
417 }
418 ipxitf_def_skb_handler(s, skb1);
419
420 if (intrfc != ipx_internal_net)
421 {
422
423
424
425 break;
426 }
427 }
428 s = s->next;
429 }
430
431 if (copy == 0)
432 {
433
434
435
436
437 kfree_skb(skb, FREE_WRITE);
438 }
439 return 0;
440 }
441
442 #else
443
444 static int
445 ipxitf_demux_socket(ipx_interface *intrfc, struct sk_buff *skb, int copy)
446 {
447 ipx_packet *ipx = (ipx_packet *)(skb->h.raw);
448 ipx_socket *sock1 = NULL, *sock2 = NULL;
449 struct sk_buff *skb1 = NULL, *skb2 = NULL;
450
451 sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock);
452
453
454
455
456
457
458
459
460
461 if (ipx_primary_net && (intrfc != ipx_primary_net))
462 {
463 switch (ntohs(ipx->ipx_dest.sock))
464 {
465 case 0x452:
466 case 0x453:
467 case 0x456:
468
469
470
471
472
473
474 sock2 = ipxitf_find_socket(ipx_primary_net,
475 ipx->ipx_dest.sock);
476 break;
477 default:
478 break;
479 }
480 }
481
482
483
484
485
486
487 if (sock1 == NULL && sock2 == NULL)
488 {
489 if (!copy)
490 kfree_skb(skb,FREE_WRITE);
491 return 0;
492 }
493
494
495
496
497
498
499
500
501
502 if (copy)
503 {
504 skb1 = skb_clone(skb, GFP_ATOMIC);
505 if (skb1 != NULL)
506 skb1->arp = skb1->free = 1;
507 }
508 else
509 {
510 skb1 = skb;
511 }
512
513 if (skb1 == NULL)
514 return -ENOMEM;
515
516
517
518
519
520 if (sock1 && sock2)
521 {
522 skb2 = skb_clone(skb1, GFP_ATOMIC);
523 if (skb2 != NULL)
524 skb2->arp = skb2->free = 1;
525 }
526 else
527 skb2 = skb1;
528
529 if (sock1)
530 (void) ipxitf_def_skb_handler(sock1, skb1);
531
532 if (skb2 == NULL)
533 return -ENOMEM;
534
535 if (sock2)
536 (void) ipxitf_def_skb_handler(sock2, skb2);
537
538 return 0;
539 }
540 #endif
541
542 static struct sk_buff *
543 ipxitf_adjust_skbuff(ipx_interface *intrfc, struct sk_buff *skb)
544 {
545 struct sk_buff *skb2;
546 int in_offset = skb->h.raw - skb->head;
547 int out_offset = intrfc->if_ipx_offset;
548 int len;
549
550
551 if (in_offset >= out_offset) {
552 skb->arp = skb->free = 1;
553 return skb;
554 }
555
556
557 len = skb->len + out_offset;
558 skb2 = alloc_skb(len, GFP_ATOMIC);
559 if (skb2 != NULL) {
560 skb_reserve(skb2,out_offset);
561 skb2->h.raw=skb_put(skb2,skb->len);
562 skb2->free=1;
563 skb2->arp=1;
564 memcpy(skb2->h.raw, skb->h.raw, skb->len);
565 }
566 kfree_skb(skb, FREE_WRITE);
567 return skb2;
568 }
569
570 static int ipxitf_send(ipx_interface *intrfc, struct sk_buff *skb, char *node)
571 {
572 ipx_packet *ipx = (ipx_packet *)(skb->h.raw);
573 struct device *dev = intrfc->if_dev;
574 struct datalink_proto *dl = intrfc->if_dlink;
575 char dest_node[IPX_NODE_LEN];
576 int send_to_wire = 1;
577 int addr_len;
578
579
580
581
582
583
584 if ((dl == NULL) || (dev == NULL) || (dev->flags & IFF_LOOPBACK))
585 send_to_wire = 0;
586
587
588
589
590
591
592
593
594 if (ipx->ipx_dest.net == intrfc->if_netnum)
595 {
596
597
598
599 if (memcmp(intrfc->if_node, node, IPX_NODE_LEN) == 0)
600 {
601
602
603
604 if(skb->sk)
605 {
606 atomic_sub(skb->truesize, &skb->sk->wmem_alloc);
607 skb->sk=NULL;
608 }
609
610
611
612 return ipxitf_demux_socket(intrfc, skb, 0);
613 }
614
615
616
617 if (memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0)
618 {
619 if (!send_to_wire && skb->sk)
620 {
621 atomic_sub(skb->truesize, &skb->sk->wmem_alloc);
622 skb->sk=NULL;
623 }
624 ipxitf_demux_socket(intrfc, skb, send_to_wire);
625 if (!send_to_wire)
626 return 0;
627 }
628 }
629
630
631
632
633
634
635
636 if (ipx->ipx_source.net != intrfc->if_netnum)
637 {
638 if (++(ipx->ipx_tctrl) > ipxcfg_max_hops)
639 send_to_wire = 0;
640 }
641
642 if (!send_to_wire)
643 {
644
645
646
647
648
649
650
651
652 kfree_skb(skb,FREE_WRITE);
653 return 0;
654 }
655
656
657
658
659
660 addr_len = dev->addr_len;
661 if (memcmp(ipx_broadcast_node, node, IPX_NODE_LEN) == 0)
662 memcpy(dest_node, dev->broadcast, addr_len);
663 else
664 memcpy(dest_node, &(node[IPX_NODE_LEN-addr_len]), addr_len);
665
666
667
668
669
670 skb = ipxitf_adjust_skbuff(intrfc, skb);
671 if (skb == NULL)
672 return 0;
673
674
675 skb->dev = dev;
676 skb->protocol = htons(ETH_P_IPX);
677 dl->datalink_header(dl, skb, dest_node);
678 #if 0
679
680
681
682
683 dump_pkt("IPX snd:", (ipx_packet *)skb->h.raw);
684 dump_data("ETH hdr:", skb->data, skb->h.raw - skb->data);
685 #endif
686
687
688
689
690
691 dev_queue_xmit(skb, dev, SOPRI_NORMAL);
692 return 0;
693 }
694
695 static int ipxrtr_add_route(unsigned long, ipx_interface *, unsigned char *);
696
697 static int ipxitf_add_local_route(ipx_interface *intrfc)
698 {
699 return ipxrtr_add_route(intrfc->if_netnum, intrfc, NULL);
700 }
701
702 static const char * ipx_frame_name(unsigned short);
703 static const char * ipx_device_name(ipx_interface *);
704 static int ipxrtr_route_skb(struct sk_buff *);
705
706 static int ipxitf_rcv(ipx_interface *intrfc, struct sk_buff *skb)
707 {
708 ipx_packet *ipx = (ipx_packet *) (skb->h.raw);
709 ipx_interface *i;
710
711 #ifdef CONFIG_FIREWALL
712
713
714
715
716 if (call_in_firewall(PF_IPX, skb, ipx)!=FW_ACCEPT)
717 {
718 kfree_skb(skb, FREE_READ);
719 return 0;
720 }
721
722 #endif
723
724
725 if ((intrfc->if_netnum == 0L) &&
726 (ipx->ipx_source.net == ipx->ipx_dest.net) &&
727 (ipx->ipx_source.net != 0L))
728 {
729
730
731
732
733 if ((i=ipxitf_find_using_net(ipx->ipx_source.net))==NULL)
734 {
735 intrfc->if_netnum = ipx->ipx_source.net;
736 (void) ipxitf_add_local_route(intrfc);
737 }
738 else
739 {
740 printk("IPX: Network number collision %lx\n\t%s %s and %s %s\n",
741 htonl(ipx->ipx_source.net),
742 ipx_device_name(i),
743 ipx_frame_name(i->if_dlink_type),
744 ipx_device_name(intrfc),
745 ipx_frame_name(intrfc->if_dlink_type));
746 }
747 }
748
749 if (ipx->ipx_dest.net == 0L)
750 ipx->ipx_dest.net = intrfc->if_netnum;
751 if (ipx->ipx_source.net == 0L)
752 ipx->ipx_source.net = intrfc->if_netnum;
753
754 if (intrfc->if_netnum != ipx->ipx_dest.net)
755 {
756 #ifdef CONFIG_FIREWALL
757
758
759
760 if (call_fw_firewall(PF_IPX, skb, ipx)!=FW_ACCEPT)
761 {
762 kfree_skb(skb, FREE_READ);
763 return 0;
764 }
765 #endif
766
767 if ((skb->pkt_type != PACKET_BROADCAST) &&
768 (skb->pkt_type != PACKET_MULTICAST))
769 return ipxrtr_route_skb(skb);
770
771 kfree_skb(skb,FREE_READ);
772 return 0;
773 }
774
775
776 if ((memcmp(ipx_broadcast_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0)
777 || (memcmp(intrfc->if_node, ipx->ipx_dest.node, IPX_NODE_LEN) == 0))
778 {
779 return ipxitf_demux_socket(intrfc, skb, 0);
780 }
781
782
783 kfree_skb(skb,FREE_READ);
784 return 0;
785 }
786
787 static void
788 ipxitf_insert(ipx_interface *intrfc)
789 {
790 ipx_interface *i;
791
792 intrfc->if_next = NULL;
793 if (ipx_interfaces == NULL) {
794 ipx_interfaces = intrfc;
795 } else {
796 for (i = ipx_interfaces; i->if_next != NULL; i = i->if_next)
797 ;
798 i->if_next = intrfc;
799 }
800
801 if (ipxcfg_auto_select_primary && (ipx_primary_net == NULL))
802 ipx_primary_net = intrfc;
803 return;
804 }
805
806 static int
807 ipxitf_create_internal(ipx_interface_definition *idef)
808 {
809 ipx_interface *intrfc;
810
811
812 if (ipx_primary_net != NULL) return -EEXIST;
813
814
815 if (idef->ipx_network == 0L) return -EADDRNOTAVAIL;
816 if (ipxitf_find_using_net(idef->ipx_network) != NULL)
817 return -EADDRINUSE;
818
819 intrfc=(ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC);
820 if (intrfc==NULL)
821 return -EAGAIN;
822 intrfc->if_dev=NULL;
823 intrfc->if_netnum=idef->ipx_network;
824 intrfc->if_dlink_type = 0;
825 intrfc->if_dlink = NULL;
826 intrfc->if_sklist = NULL;
827 intrfc->if_internal = 1;
828 intrfc->if_ipx_offset = 0;
829 intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET;
830 memcpy((char *)&(intrfc->if_node), idef->ipx_node, IPX_NODE_LEN);
831 ipx_internal_net = intrfc;
832 ipx_primary_net = intrfc;
833 ipxitf_insert(intrfc);
834 return ipxitf_add_local_route(intrfc);
835 }
836
837 static int
838 ipx_map_frame_type(unsigned char type)
839 {
840 switch (type) {
841 case IPX_FRAME_ETHERII: return htons(ETH_P_IPX);
842 case IPX_FRAME_8022: return htons(ETH_P_802_2);
843 case IPX_FRAME_SNAP: return htons(ETH_P_SNAP);
844 case IPX_FRAME_8023: return htons(ETH_P_802_3);
845 }
846 return 0;
847 }
848
849 static int
850 ipxitf_create(ipx_interface_definition *idef)
851 {
852 struct device *dev;
853 unsigned short dlink_type = 0;
854 struct datalink_proto *datalink = NULL;
855 ipx_interface *intrfc;
856
857 if (idef->ipx_special == IPX_INTERNAL)
858 return ipxitf_create_internal(idef);
859
860 if ((idef->ipx_special == IPX_PRIMARY) && (ipx_primary_net != NULL))
861 return -EEXIST;
862
863 if ((idef->ipx_network != 0L) &&
864 (ipxitf_find_using_net(idef->ipx_network) != NULL))
865 return -EADDRINUSE;
866
867 switch (idef->ipx_dlink_type) {
868 case IPX_FRAME_ETHERII:
869 dlink_type = htons(ETH_P_IPX);
870 datalink = pEII_datalink;
871 break;
872 case IPX_FRAME_8022:
873 dlink_type = htons(ETH_P_802_2);
874 datalink = p8022_datalink;
875 break;
876 case IPX_FRAME_SNAP:
877 dlink_type = htons(ETH_P_SNAP);
878 datalink = pSNAP_datalink;
879 break;
880 case IPX_FRAME_8023:
881 dlink_type = htons(ETH_P_802_3);
882 datalink = p8023_datalink;
883 break;
884 case IPX_FRAME_NONE:
885 default:
886 break;
887 }
888
889 if (datalink == NULL)
890 return -EPROTONOSUPPORT;
891
892 dev=dev_get(idef->ipx_device);
893 if (dev==NULL)
894 return -ENODEV;
895
896 if (!(dev->flags & IFF_UP))
897 return -ENETDOWN;
898
899
900 if(dev->addr_len>IPX_NODE_LEN)
901 return -EINVAL;
902
903 if ((intrfc = ipxitf_find_using_phys(dev, dlink_type)) == NULL) {
904
905
906 intrfc=(ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC);
907 if (intrfc==NULL)
908 return -EAGAIN;
909 intrfc->if_dev=dev;
910 intrfc->if_netnum=idef->ipx_network;
911 intrfc->if_dlink_type = dlink_type;
912 intrfc->if_dlink = datalink;
913 intrfc->if_sklist = NULL;
914 intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET;
915
916 if ((idef->ipx_special == IPX_PRIMARY))
917 ipx_primary_net = intrfc;
918 intrfc->if_internal = 0;
919 intrfc->if_ipx_offset = dev->hard_header_len + datalink->header_length;
920 memset(intrfc->if_node, 0, IPX_NODE_LEN);
921 memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]), dev->dev_addr, dev->addr_len);
922
923 ipxitf_insert(intrfc);
924 }
925
926
927 if (intrfc->if_netnum == 0L)
928 return 0;
929
930 return ipxitf_add_local_route(intrfc);
931 }
932
933 static int
934 ipxitf_delete(ipx_interface_definition *idef)
935 {
936 struct device *dev = NULL;
937 unsigned short dlink_type = 0;
938 ipx_interface *intrfc;
939
940 if (idef->ipx_special == IPX_INTERNAL) {
941 if (ipx_internal_net != NULL) {
942 ipxitf_down(ipx_internal_net);
943 return 0;
944 }
945 return -ENOENT;
946 }
947
948 dlink_type = ipx_map_frame_type(idef->ipx_dlink_type);
949 if (dlink_type == 0)
950 return -EPROTONOSUPPORT;
951
952 dev=dev_get(idef->ipx_device);
953 if(dev==NULL) return -ENODEV;
954
955 intrfc = ipxitf_find_using_phys(dev, dlink_type);
956 if (intrfc != NULL) {
957 ipxitf_down(intrfc);
958 return 0;
959 }
960 return -EINVAL;
961 }
962
963 static ipx_interface *
964 ipxitf_auto_create(struct device *dev, unsigned short dlink_type)
965 {
966 struct datalink_proto *datalink = NULL;
967 ipx_interface *intrfc;
968
969 switch (htons(dlink_type)) {
970 case ETH_P_IPX: datalink = pEII_datalink; break;
971 case ETH_P_802_2: datalink = p8022_datalink; break;
972 case ETH_P_SNAP: datalink = pSNAP_datalink; break;
973 case ETH_P_802_3: datalink = p8023_datalink; break;
974 default: return NULL;
975 }
976
977 if (dev == NULL)
978 return NULL;
979
980
981 if(dev->addr_len>IPX_NODE_LEN) return NULL;
982
983 intrfc=(ipx_interface *)kmalloc(sizeof(ipx_interface),GFP_ATOMIC);
984 if (intrfc!=NULL) {
985 intrfc->if_dev=dev;
986 intrfc->if_netnum=0L;
987 intrfc->if_dlink_type = dlink_type;
988 intrfc->if_dlink = datalink;
989 intrfc->if_sklist = NULL;
990 intrfc->if_internal = 0;
991 intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET;
992 intrfc->if_ipx_offset = dev->hard_header_len +
993 datalink->header_length;
994 memset(intrfc->if_node, 0, IPX_NODE_LEN);
995 memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]),
996 dev->dev_addr, dev->addr_len);
997 ipxitf_insert(intrfc);
998 }
999
1000 return intrfc;
1001 }
1002
1003 static int
1004 ipxitf_ioctl(unsigned int cmd, void *arg)
1005 {
1006 int err;
1007 switch(cmd)
1008 {
1009 case SIOCSIFADDR:
1010 {
1011 struct ifreq ifr;
1012 struct sockaddr_ipx *sipx;
1013 ipx_interface_definition f;
1014 err=verify_area(VERIFY_READ,arg,sizeof(ifr));
1015 if(err)
1016 return err;
1017 memcpy_fromfs(&ifr,arg,sizeof(ifr));
1018 sipx=(struct sockaddr_ipx *)&ifr.ifr_addr;
1019 if(sipx->sipx_family!=AF_IPX)
1020 return -EINVAL;
1021 f.ipx_network=sipx->sipx_network;
1022 memcpy(f.ipx_device, ifr.ifr_name, sizeof(f.ipx_device));
1023 memcpy(f.ipx_node, sipx->sipx_node, IPX_NODE_LEN);
1024 f.ipx_dlink_type=sipx->sipx_type;
1025 f.ipx_special=sipx->sipx_special;
1026 if(sipx->sipx_action==IPX_DLTITF)
1027 return ipxitf_delete(&f);
1028 else
1029 return ipxitf_create(&f);
1030 }
1031 case SIOCGIFADDR:
1032 {
1033 struct ifreq ifr;
1034 struct sockaddr_ipx *sipx;
1035 ipx_interface *ipxif;
1036 struct device *dev;
1037 err=verify_area(VERIFY_WRITE,arg,sizeof(ifr));
1038 if(err)
1039 return err;
1040 memcpy_fromfs(&ifr,arg,sizeof(ifr));
1041 sipx=(struct sockaddr_ipx *)&ifr.ifr_addr;
1042 dev=dev_get(ifr.ifr_name);
1043 if(!dev)
1044 return -ENODEV;
1045 ipxif=ipxitf_find_using_phys(dev, ipx_map_frame_type(sipx->sipx_type));
1046 if(ipxif==NULL)
1047 return -EADDRNOTAVAIL;
1048 sipx->sipx_family=AF_IPX;
1049 sipx->sipx_network=ipxif->if_netnum;
1050 memcpy(sipx->sipx_node, ipxif->if_node, sizeof(sipx->sipx_node));
1051 memcpy_tofs(arg,&ifr,sizeof(ifr));
1052 return 0;
1053 }
1054 case SIOCAIPXITFCRT:
1055 err=verify_area(VERIFY_READ,arg,sizeof(char));
1056 if(err)
1057 return err;
1058 return ipxcfg_set_auto_create(get_fs_byte(arg));
1059 case SIOCAIPXPRISLT:
1060 err=verify_area(VERIFY_READ,arg,sizeof(char));
1061 if(err)
1062 return err;
1063 return ipxcfg_set_auto_select(get_fs_byte(arg));
1064 default:
1065 return -EINVAL;
1066 }
1067 }
1068
1069
1070
1071
1072
1073
1074
1075 static ipx_route *
1076 ipxrtr_lookup(unsigned long net)
1077 {
1078 ipx_route *r;
1079
1080 for (r=ipx_routes; (r!=NULL) && (r->ir_net!=net); r=r->ir_next)
1081 ;
1082
1083 return r;
1084 }
1085
1086 static int
1087 ipxrtr_add_route(unsigned long network, ipx_interface *intrfc, unsigned char *node)
1088 {
1089 ipx_route *rt;
1090
1091
1092 rt = ipxrtr_lookup(network);
1093 if (rt==NULL) {
1094 rt=(ipx_route *)kmalloc(sizeof(ipx_route),GFP_ATOMIC);
1095 if(rt==NULL)
1096 return -EAGAIN;
1097 rt->ir_next=ipx_routes;
1098 ipx_routes=rt;
1099 }
1100 else if (intrfc == ipx_internal_net)
1101 return(-EEXIST);
1102
1103 rt->ir_net = network;
1104 rt->ir_intrfc = intrfc;
1105 if (node == NULL) {
1106 memset(rt->ir_router_node, '\0', IPX_NODE_LEN);
1107 rt->ir_routed = 0;
1108 } else {
1109 memcpy(rt->ir_router_node, node, IPX_NODE_LEN);
1110 rt->ir_routed=1;
1111 }
1112 return 0;
1113 }
1114
1115 static void
1116 ipxrtr_del_routes(ipx_interface *intrfc)
1117 {
1118 ipx_route **r, *tmp;
1119
1120 for (r = &ipx_routes; (tmp = *r) != NULL; ) {
1121 if (tmp->ir_intrfc == intrfc) {
1122 *r = tmp->ir_next;
1123 kfree_s(tmp, sizeof(ipx_route));
1124 } else {
1125 r = &(tmp->ir_next);
1126 }
1127 }
1128 }
1129
1130 static int
1131 ipxrtr_create(ipx_route_definition *rd)
1132 {
1133 ipx_interface *intrfc;
1134
1135
1136 intrfc = ipxitf_find_using_net(rd->ipx_router_network);
1137 if (intrfc == NULL)
1138 return -ENETUNREACH;
1139
1140 return ipxrtr_add_route(rd->ipx_network, intrfc, rd->ipx_router_node);
1141 }
1142
1143
1144 static int
1145 ipxrtr_delete(long net)
1146 {
1147 ipx_route **r;
1148 ipx_route *tmp;
1149
1150 for (r = &ipx_routes; (tmp = *r) != NULL; ) {
1151 if (tmp->ir_net == net) {
1152 if (!(tmp->ir_routed)) {
1153
1154 return -EPERM;
1155 }
1156 *r = tmp->ir_next;
1157 kfree_s(tmp, sizeof(ipx_route));
1158 return 0;
1159 }
1160 r = &(tmp->ir_next);
1161 }
1162
1163 return -ENOENT;
1164 }
1165
1166
1167
1168
1169
1170 static int ipxrtr_route_packet(ipx_socket *sk, struct sockaddr_ipx *usipx, struct iovec *iov, int len)
1171 {
1172 struct sk_buff *skb;
1173 ipx_interface *intrfc;
1174 ipx_packet *ipx;
1175 int size;
1176 int ipx_offset;
1177 ipx_route *rt = NULL;
1178 int err;
1179
1180
1181 if ((usipx->sipx_network == 0L) && (ipx_primary_net != NULL))
1182 {
1183 usipx->sipx_network = ipx_primary_net->if_netnum;
1184 intrfc = ipx_primary_net;
1185 }
1186 else
1187 {
1188 rt = ipxrtr_lookup(usipx->sipx_network);
1189 if (rt==NULL) {
1190 return -ENETUNREACH;
1191 }
1192 intrfc = rt->ir_intrfc;
1193 }
1194
1195 ipx_offset = intrfc->if_ipx_offset;
1196 size=sizeof(ipx_packet)+len;
1197 size += ipx_offset;
1198
1199 skb=sock_alloc_send_skb(sk, size, 0, 0, &err);
1200 if(skb==NULL)
1201 return err;
1202
1203 skb_reserve(skb,ipx_offset);
1204 skb->free=1;
1205 skb->arp=1;
1206 skb->sk=sk;
1207
1208
1209 ipx=(ipx_packet *)skb_put(skb,sizeof(ipx_packet));
1210 ipx->ipx_checksum=0xFFFF;
1211 ipx->ipx_pktsize=htons(len+sizeof(ipx_packet));
1212 ipx->ipx_tctrl=0;
1213 ipx->ipx_type=usipx->sipx_type;
1214 skb->h.raw = (unsigned char *)ipx;
1215
1216 ipx->ipx_source.net = sk->protinfo.af_ipx.intrfc->if_netnum;
1217 #ifdef CONFIG_IPX_INTERN
1218 memcpy(ipx->ipx_source.node, sk->protinfo.af_ipx.node, IPX_NODE_LEN);
1219 #else
1220 if ((err = ntohs(sk->protinfo.af_ipx.port)) == 0x453 || err == 0x452)
1221 {
1222
1223 ipx->ipx_source.net = intrfc->if_netnum;
1224 memcpy(ipx->ipx_source.node, intrfc->if_node, IPX_NODE_LEN);
1225 }
1226 else
1227 {
1228 ipx->ipx_source.net = sk->protinfo.af_ipx.intrfc->if_netnum;
1229 memcpy(ipx->ipx_source.node, sk->protinfo.af_ipx.intrfc->if_node, IPX_NODE_LEN);
1230 }
1231 #endif
1232 ipx->ipx_source.sock = sk->protinfo.af_ipx.port;
1233 ipx->ipx_dest.net=usipx->sipx_network;
1234 memcpy(ipx->ipx_dest.node,usipx->sipx_node,IPX_NODE_LEN);
1235 ipx->ipx_dest.sock=usipx->sipx_port;
1236
1237 memcpy_fromiovec(skb_put(skb,len),iov,len);
1238
1239 #ifdef CONFIG_FIREWALL
1240 if(call_out_firewall(PF_IPX, skb, ipx)!=FW_ACCEPT)
1241 {
1242 kfree_skb(skb, FREE_WRITE);
1243 return -EPERM;
1244 }
1245 #endif
1246
1247 return ipxitf_send(intrfc, skb, (rt && rt->ir_routed) ?
1248 rt->ir_router_node : ipx->ipx_dest.node);
1249 }
1250
1251 static int
1252 ipxrtr_route_skb(struct sk_buff *skb)
1253 {
1254 ipx_packet *ipx = (ipx_packet *) (skb->h.raw);
1255 ipx_route *r;
1256 ipx_interface *i;
1257
1258 r = ipxrtr_lookup(ipx->ipx_dest.net);
1259 if (r == NULL) {
1260
1261 kfree_skb(skb,FREE_READ);
1262 return 0;
1263 }
1264 i = r->ir_intrfc;
1265 (void)ipxitf_send(i, skb, (r->ir_routed) ?
1266 r->ir_router_node : ipx->ipx_dest.node);
1267 return 0;
1268 }
1269
1270
1271
1272
1273
1274 static int ipxrtr_ioctl(unsigned int cmd, void *arg)
1275 {
1276 int err;
1277 struct rtentry rt;
1278 struct sockaddr_ipx *sg,*st;
1279
1280 err=verify_area(VERIFY_READ,arg,sizeof(rt));
1281 if(err)
1282 return err;
1283
1284 memcpy_fromfs(&rt,arg,sizeof(rt));
1285
1286 sg=(struct sockaddr_ipx *)&rt.rt_gateway;
1287 st=(struct sockaddr_ipx *)&rt.rt_dst;
1288
1289 if(!(rt.rt_flags&RTF_GATEWAY))
1290 return -EINVAL;
1291 if(sg->sipx_family!=AF_IPX)
1292 return -EINVAL;
1293 if(st->sipx_family!=AF_IPX)
1294 return -EINVAL;
1295
1296 switch(cmd)
1297 {
1298 case SIOCDELRT:
1299 return ipxrtr_delete(st->sipx_network);
1300 case SIOCADDRT:
1301 {
1302 struct ipx_route_definition f;
1303 f.ipx_network=st->sipx_network;
1304 f.ipx_router_network=sg->sipx_network;
1305 memcpy(f.ipx_router_node, sg->sipx_node, IPX_NODE_LEN);
1306 return ipxrtr_create(&f);
1307 }
1308 default:
1309 return -EINVAL;
1310 }
1311 }
1312
1313 static const char *
1314 ipx_frame_name(unsigned short frame)
1315 {
1316 switch (ntohs(frame)) {
1317 case ETH_P_IPX: return "EtherII";
1318 case ETH_P_802_2: return "802.2";
1319 case ETH_P_SNAP: return "SNAP";
1320 case ETH_P_802_3: return "802.3";
1321 default: return "None";
1322 }
1323 }
1324
1325 static const char *
1326 ipx_device_name(ipx_interface *intrfc)
1327 {
1328 return (intrfc->if_internal ? "Internal" :
1329 (intrfc->if_dev ? intrfc->if_dev->name : "Unknown"));
1330 }
1331
1332
1333 static int ipx_interface_get_info(char *buffer, char **start, off_t offset,
1334 int length, int dummy)
1335 {
1336 ipx_interface *i;
1337 int len=0;
1338 off_t pos=0;
1339 off_t begin=0;
1340
1341
1342
1343 len += sprintf (buffer,"%-11s%-15s%-9s%-11s%s\n", "Network",
1344 "Node_Address", "Primary", "Device", "Frame_Type");
1345 for (i = ipx_interfaces; i != NULL; i = i->if_next) {
1346 len += sprintf(buffer+len, "%08lX ", ntohl(i->if_netnum));
1347 len += sprintf (buffer+len,"%02X%02X%02X%02X%02X%02X ",
1348 i->if_node[0], i->if_node[1], i->if_node[2],
1349 i->if_node[3], i->if_node[4], i->if_node[5]);
1350 len += sprintf(buffer+len, "%-9s", (i == ipx_primary_net) ?
1351 "Yes" : "No");
1352 len += sprintf (buffer+len, "%-11s", ipx_device_name(i));
1353 len += sprintf (buffer+len, "%s\n",
1354 ipx_frame_name(i->if_dlink_type));
1355
1356
1357 pos=begin+len;
1358
1359 if(pos<offset) {
1360 len=0;
1361 begin=pos;
1362 }
1363 if(pos>offset+length)
1364 break;
1365 }
1366
1367
1368 *start=buffer+(offset-begin);
1369 len-=(offset-begin);
1370 if(len>length)
1371 len=length;
1372
1373 return len;
1374 }
1375
1376 static int ipx_get_info(char *buffer, char **start, off_t offset,
1377 int length, int dummy)
1378 {
1379 ipx_socket *s;
1380 ipx_interface *i;
1381 int len=0;
1382 off_t pos=0;
1383 off_t begin=0;
1384
1385
1386
1387 #ifdef CONFIG_IPX_INTERN
1388 len += sprintf (buffer,"%-28s%-28s%-10s%-10s%-7s%s\n", "Local_Address",
1389 #else
1390 len += sprintf (buffer,"%-15s%-28s%-10s%-10s%-7s%s\n", "Local_Address",
1391 #endif
1392 "Remote_Address", "Tx_Queue", "Rx_Queue",
1393 "State", "Uid");
1394 for (i = ipx_interfaces; i != NULL; i = i->if_next) {
1395 for (s = i->if_sklist; s != NULL; s = s->next) {
1396 #ifdef CONFIG_IPX_INTERN
1397 len += sprintf(buffer+len,
1398 "%08lX:%02X%02X%02X%02X%02X%02X:%04X ",
1399 htonl(s->protinfo.af_ipx.intrfc->if_netnum),
1400 s->protinfo.af_ipx.node[0],
1401 s->protinfo.af_ipx.node[1],
1402 s->protinfo.af_ipx.node[2],
1403 s->protinfo.af_ipx.node[3],
1404 s->protinfo.af_ipx.node[4],
1405 s->protinfo.af_ipx.node[5],
1406 htons(s->protinfo.af_ipx.port));
1407 #else
1408 len += sprintf(buffer+len,"%08lX:%04X ",
1409 htonl(i->if_netnum),
1410 htons(s->protinfo.af_ipx.port));
1411 #endif
1412 if (s->state!=TCP_ESTABLISHED) {
1413 len += sprintf(buffer+len, "%-28s", "Not_Connected");
1414 } else {
1415 len += sprintf (buffer+len,
1416 "%08lX:%02X%02X%02X%02X%02X%02X:%04X ",
1417 htonl(s->protinfo.af_ipx.dest_addr.net),
1418 s->protinfo.af_ipx.dest_addr.node[0],
1419 s->protinfo.af_ipx.dest_addr.node[1],
1420 s->protinfo.af_ipx.dest_addr.node[2],
1421 s->protinfo.af_ipx.dest_addr.node[3],
1422 s->protinfo.af_ipx.dest_addr.node[4],
1423 s->protinfo.af_ipx.dest_addr.node[5],
1424 htons(s->protinfo.af_ipx.dest_addr.sock));
1425 }
1426 len += sprintf (buffer+len,"%08lX %08lX ",
1427 s->wmem_alloc, s->rmem_alloc);
1428 len += sprintf (buffer+len,"%02X %03d\n",
1429 s->state, SOCK_INODE(s->socket)->i_uid);
1430
1431
1432 pos=begin+len;
1433
1434 if(pos<offset)
1435 {
1436 len=0;
1437 begin=pos;
1438 }
1439 if(pos>offset+length)
1440 break;
1441 }
1442 }
1443
1444
1445 *start=buffer+(offset-begin);
1446 len-=(offset-begin);
1447 if(len>length)
1448 len=length;
1449
1450 return len;
1451 }
1452
1453 static int ipx_rt_get_info(char *buffer, char **start, off_t offset,
1454 int length, int dummy)
1455 {
1456 ipx_route *rt;
1457 int len=0;
1458 off_t pos=0;
1459 off_t begin=0;
1460
1461 len += sprintf (buffer,"%-11s%-13s%s\n",
1462 "Network", "Router_Net", "Router_Node");
1463 for (rt = ipx_routes; rt != NULL; rt = rt->ir_next)
1464 {
1465 len += sprintf (buffer+len,"%08lX ", ntohl(rt->ir_net));
1466 if (rt->ir_routed) {
1467 len += sprintf (buffer+len,"%08lX %02X%02X%02X%02X%02X%02X\n",
1468 ntohl(rt->ir_intrfc->if_netnum),
1469 rt->ir_router_node[0], rt->ir_router_node[1],
1470 rt->ir_router_node[2], rt->ir_router_node[3],
1471 rt->ir_router_node[4], rt->ir_router_node[5]);
1472 } else {
1473 len += sprintf (buffer+len, "%-13s%s\n",
1474 "Directly", "Connected");
1475 }
1476 pos=begin+len;
1477 if(pos<offset)
1478 {
1479 len=0;
1480 begin=pos;
1481 }
1482 if(pos>offset+length)
1483 break;
1484 }
1485 *start=buffer+(offset-begin);
1486 len-=(offset-begin);
1487 if(len>length)
1488 len=length;
1489 return len;
1490 }
1491
1492
1493
1494
1495
1496
1497
1498 static int ipx_fcntl(struct socket *sock, unsigned int cmd, unsigned long arg)
1499 {
1500 switch(cmd)
1501 {
1502 default:
1503 return(-EINVAL);
1504 }
1505 }
1506
1507 static int ipx_setsockopt(struct socket *sock, int level, int optname, char *optval, int optlen)
1508 {
1509 ipx_socket *sk;
1510 int err,opt;
1511
1512 sk=(ipx_socket *)sock->data;
1513
1514 if(optval==NULL)
1515 return(-EINVAL);
1516
1517 err=verify_area(VERIFY_READ,optval,sizeof(int));
1518 if(err)
1519 return err;
1520 opt=get_fs_long((unsigned long *)optval);
1521
1522 switch(level)
1523 {
1524 case SOL_IPX:
1525 switch(optname)
1526 {
1527 case IPX_TYPE:
1528 sk->protinfo.af_ipx.type=opt;
1529 return 0;
1530 default:
1531 return -EOPNOTSUPP;
1532 }
1533 break;
1534
1535 case SOL_SOCKET:
1536 return sock_setsockopt(sk,level,optname,optval,optlen);
1537
1538 default:
1539 return -EOPNOTSUPP;
1540 }
1541 }
1542
1543 static int ipx_getsockopt(struct socket *sock, int level, int optname,
1544 char *optval, int *optlen)
1545 {
1546 ipx_socket *sk;
1547 int val=0;
1548 int err;
1549
1550 sk=(ipx_socket *)sock->data;
1551
1552 switch(level)
1553 {
1554
1555 case SOL_IPX:
1556 switch(optname)
1557 {
1558 case IPX_TYPE:
1559 val=sk->protinfo.af_ipx.type;
1560 break;
1561 default:
1562 return -ENOPROTOOPT;
1563 }
1564 break;
1565
1566 case SOL_SOCKET:
1567 return sock_getsockopt(sk,level,optname,optval,optlen);
1568
1569 default:
1570 return -EOPNOTSUPP;
1571 }
1572 err=verify_area(VERIFY_WRITE,optlen,sizeof(int));
1573 if(err)
1574 return err;
1575 put_fs_long(sizeof(int),(unsigned long *)optlen);
1576 err=verify_area(VERIFY_WRITE,optval,sizeof(int));
1577 if (err) return err;
1578 put_fs_long(val,(unsigned long *)optval);
1579 return(0);
1580 }
1581
1582 static int ipx_listen(struct socket *sock, int backlog)
1583 {
1584 return -EOPNOTSUPP;
1585 }
1586
1587 static void def_callback1(struct sock *sk)
1588 {
1589 if(!sk->dead)
1590 wake_up_interruptible(sk->sleep);
1591 }
1592
1593 static void def_callback2(struct sock *sk, int len)
1594 {
1595 if(!sk->dead)
1596 {
1597 wake_up_interruptible(sk->sleep);
1598 sock_wake_async(sk->socket, 1);
1599 }
1600 }
1601
1602 static int
1603 ipx_create(struct socket *sock, int protocol)
1604 {
1605 ipx_socket *sk;
1606 sk=(ipx_socket *)kmalloc(sizeof(*sk),GFP_KERNEL);
1607 if(sk==NULL)
1608 return(-ENOMEM);
1609 switch(sock->type)
1610 {
1611 case SOCK_DGRAM:
1612 break;
1613 default:
1614 kfree_s((void *)sk,sizeof(*sk));
1615 return(-ESOCKTNOSUPPORT);
1616 }
1617 sk->dead=0;
1618 sk->next=NULL;
1619 sk->broadcast=0;
1620 sk->rcvbuf=SK_RMEM_MAX;
1621 sk->sndbuf=SK_WMEM_MAX;
1622 sk->wmem_alloc=0;
1623 sk->rmem_alloc=0;
1624 sk->users=0;
1625 sk->shutdown=0;
1626 sk->prot=NULL;
1627 sk->err=0;
1628 skb_queue_head_init(&sk->receive_queue);
1629 skb_queue_head_init(&sk->write_queue);
1630 sk->send_head=NULL;
1631 skb_queue_head_init(&sk->back_log);
1632 sk->state=TCP_CLOSE;
1633 sk->socket=sock;
1634 sk->type=sock->type;
1635 sk->protinfo.af_ipx.type=0;
1636 sk->debug=0;
1637 sk->protinfo.af_ipx.intrfc = NULL;
1638 memset(&sk->protinfo.af_ipx.dest_addr,'\0',
1639 sizeof(sk->protinfo.af_ipx.dest_addr));
1640 sk->protinfo.af_ipx.port = 0;
1641 sk->protinfo.af_ipx.ncp_server = 0;
1642 sk->mtu=IPX_MTU;
1643
1644 if(sock!=NULL)
1645 {
1646 sock->data=(void *)sk;
1647 sk->sleep=sock->wait;
1648 }
1649
1650 sk->state_change=def_callback1;
1651 sk->data_ready=def_callback2;
1652 sk->write_space=def_callback1;
1653 sk->error_report=def_callback1;
1654
1655 sk->zapped=1;
1656 MOD_INC_USE_COUNT;
1657 return 0;
1658 }
1659
1660 static int ipx_release(struct socket *sock, struct socket *peer)
1661 {
1662 ipx_socket *sk=(ipx_socket *)sock->data;
1663 if(sk==NULL)
1664 return(0);
1665 if(!sk->dead)
1666 sk->state_change(sk);
1667 sk->dead=1;
1668 sock->data=NULL;
1669 ipx_destroy_socket(sk);
1670 return(0);
1671 }
1672
1673 static int ipx_dup(struct socket *newsock,struct socket *oldsock)
1674 {
1675 return(ipx_create(newsock,SOCK_DGRAM));
1676 }
1677
1678 static unsigned short
1679 ipx_first_free_socketnum(ipx_interface *intrfc)
1680 {
1681 unsigned short socketNum = intrfc->if_sknum;
1682
1683 if (socketNum < IPX_MIN_EPHEMERAL_SOCKET)
1684 socketNum = IPX_MIN_EPHEMERAL_SOCKET;
1685
1686 while (ipxitf_find_socket(intrfc, ntohs(socketNum)) != NULL)
1687 if (socketNum > IPX_MAX_EPHEMERAL_SOCKET)
1688 socketNum = IPX_MIN_EPHEMERAL_SOCKET;
1689 else
1690 socketNum++;
1691
1692 intrfc->if_sknum = socketNum;
1693 return ntohs(socketNum);
1694 }
1695
1696 static int ipx_bind(struct socket *sock, struct sockaddr *uaddr,int addr_len)
1697 {
1698 ipx_socket *sk;
1699 ipx_interface *intrfc;
1700 struct sockaddr_ipx *addr=(struct sockaddr_ipx *)uaddr;
1701
1702 sk=(ipx_socket *)sock->data;
1703
1704 if(sk->zapped==0)
1705 return -EIO;
1706
1707 if(addr_len!=sizeof(struct sockaddr_ipx))
1708 return -EINVAL;
1709
1710 intrfc = ipxitf_find_using_net(addr->sipx_network);
1711 if (intrfc == NULL)
1712 return -EADDRNOTAVAIL;
1713
1714 if (addr->sipx_port == 0) {
1715 addr->sipx_port = ipx_first_free_socketnum(intrfc);
1716 if (addr->sipx_port == 0)
1717 return -EINVAL;
1718 }
1719
1720 if(ntohs(addr->sipx_port)<IPX_MIN_EPHEMERAL_SOCKET && !suser())
1721 return -EPERM;
1722
1723 sk->protinfo.af_ipx.port=addr->sipx_port;
1724
1725 #ifdef CONFIG_IPX_INTERN
1726 if (intrfc == ipx_internal_net)
1727 {
1728
1729
1730
1731
1732
1733 if (memcmp(addr->sipx_node, ipx_broadcast_node,
1734 IPX_NODE_LEN) == 0)
1735 {
1736 return -EINVAL;
1737 }
1738 if (memcmp(addr->sipx_node, ipx_this_node, IPX_NODE_LEN) == 0)
1739 {
1740 memcpy(sk->protinfo.af_ipx.node, intrfc->if_node,
1741 IPX_NODE_LEN);
1742 }
1743 else
1744 {
1745 memcpy(sk->protinfo.af_ipx.node, addr->sipx_node, IPX_NODE_LEN);
1746 }
1747 if (ipxitf_find_internal_socket(intrfc,
1748 sk->protinfo.af_ipx.node,
1749 sk->protinfo.af_ipx.port) != NULL)
1750 {
1751 if(sk->debug)
1752 printk("IPX: bind failed because port %X in"
1753 " use.\n", (int)addr->sipx_port);
1754 return -EADDRINUSE;
1755 }
1756 }
1757 else
1758 {
1759
1760
1761
1762
1763
1764 memcpy(sk->protinfo.af_ipx.node, intrfc->if_node,
1765 IPX_NODE_LEN);
1766
1767 if(ipxitf_find_socket(intrfc, addr->sipx_port)!=NULL) {
1768 if(sk->debug)
1769 printk("IPX: bind failed because port %X in"
1770 " use.\n", (int)addr->sipx_port);
1771 return -EADDRINUSE;
1772 }
1773 }
1774
1775 #else
1776
1777
1778
1779
1780 if(ipxitf_find_socket(intrfc, addr->sipx_port)!=NULL) {
1781 if(sk->debug)
1782 printk("IPX: bind failed because port %X in use.\n",
1783 (int)addr->sipx_port);
1784 return -EADDRINUSE;
1785 }
1786
1787 #endif
1788
1789 ipxitf_insert_socket(intrfc, sk);
1790 sk->zapped=0;
1791 if(sk->debug)
1792 printk("IPX: socket is bound.\n");
1793 return 0;
1794 }
1795
1796 static int ipx_connect(struct socket *sock, struct sockaddr *uaddr,
1797 int addr_len, int flags)
1798 {
1799 ipx_socket *sk=(ipx_socket *)sock->data;
1800 struct sockaddr_ipx *addr;
1801
1802 sk->state = TCP_CLOSE;
1803 sock->state = SS_UNCONNECTED;
1804
1805 if(addr_len!=sizeof(*addr))
1806 return(-EINVAL);
1807 addr=(struct sockaddr_ipx *)uaddr;
1808
1809 if(sk->protinfo.af_ipx.port==0)
1810
1811 {
1812 struct sockaddr_ipx uaddr;
1813 int ret;
1814
1815 uaddr.sipx_port = 0;
1816 uaddr.sipx_network = 0L;
1817 #ifdef CONFIG_IPX_INTERN
1818 memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc->if_node,
1819 IPX_NODE_LEN);
1820 #endif
1821 ret = ipx_bind (sock, (struct sockaddr *)&uaddr,
1822 sizeof(struct sockaddr_ipx));
1823 if (ret != 0) return (ret);
1824 }
1825
1826 if(ipxrtr_lookup(addr->sipx_network)==NULL)
1827 return -ENETUNREACH;
1828 sk->protinfo.af_ipx.dest_addr.net=addr->sipx_network;
1829 sk->protinfo.af_ipx.dest_addr.sock=addr->sipx_port;
1830 memcpy(sk->protinfo.af_ipx.dest_addr.node,
1831 addr->sipx_node,IPX_NODE_LEN);
1832 sk->protinfo.af_ipx.type=addr->sipx_type;
1833 sock->state = SS_CONNECTED;
1834 sk->state=TCP_ESTABLISHED;
1835 return 0;
1836 }
1837
1838 static int ipx_socketpair(struct socket *sock1, struct socket *sock2)
1839 {
1840 return(-EOPNOTSUPP);
1841 }
1842
1843 static int ipx_accept(struct socket *sock, struct socket *newsock, int flags)
1844 {
1845 if(newsock->data) {
1846 kfree_s(newsock->data,sizeof(ipx_socket));
1847 MOD_DEC_USE_COUNT;
1848 }
1849 return -EOPNOTSUPP;
1850 }
1851
1852 static int ipx_getname(struct socket *sock, struct sockaddr *uaddr,
1853 int *uaddr_len, int peer)
1854 {
1855 ipx_address *addr;
1856 struct sockaddr_ipx sipx;
1857 ipx_socket *sk;
1858
1859 sk=(ipx_socket *)sock->data;
1860
1861 *uaddr_len = sizeof(struct sockaddr_ipx);
1862
1863 if(peer) {
1864 if(sk->state!=TCP_ESTABLISHED)
1865 return -ENOTCONN;
1866 addr=&sk->protinfo.af_ipx.dest_addr;
1867 sipx.sipx_network = addr->net;
1868 memcpy(sipx.sipx_node,addr->node,IPX_NODE_LEN);
1869 sipx.sipx_port = addr->sock;
1870 } else {
1871 if (sk->protinfo.af_ipx.intrfc != NULL) {
1872 sipx.sipx_network = sk->protinfo.af_ipx.intrfc->if_netnum;
1873 #ifdef CONFIG_IPX_INTERN
1874 memcpy(sipx.sipx_node, sk->protinfo.af_ipx.node, IPX_NODE_LEN);
1875 #else
1876 memcpy(sipx.sipx_node,
1877 sk->protinfo.af_ipx.intrfc->if_node, IPX_NODE_LEN);
1878 #endif
1879
1880 } else {
1881 sipx.sipx_network = 0L;
1882 memset(sipx.sipx_node, '\0', IPX_NODE_LEN);
1883 }
1884 sipx.sipx_port = sk->protinfo.af_ipx.port;
1885 }
1886
1887 sipx.sipx_family = AF_IPX;
1888 sipx.sipx_type = sk->protinfo.af_ipx.type;
1889 memcpy(uaddr,&sipx,sizeof(sipx));
1890 return 0;
1891 }
1892
1893 #if 0
1894
1895
1896
1897 void dump_data(char *str,unsigned char *d, int len) {
1898 static char h2c[] = "0123456789ABCDEF";
1899 int l,i;
1900 char *p, b[64];
1901 for (l=0;len > 0 && l<16;l++) {
1902 p = b;
1903 for (i=0; i < 8 ; i++, --len) {
1904 if (len > 0) {
1905 *(p++) = h2c[(d[i] >> 4) & 0x0f];
1906 *(p++) = h2c[d[i] & 0x0f];
1907 }
1908 else {
1909 *(p++) = ' ';
1910 *(p++) = ' ';
1911 }
1912 *(p++) = ' ';
1913 }
1914 *(p++) = '-';
1915 *(p++) = ' ';
1916 len += 8;
1917 for (i=0; i < 8 ; i++, --len)
1918 if (len > 0)
1919 *(p++) = ' '<= d[i] && d[i]<'\177' ? d[i] : '.';
1920 else
1921 *(p++) = ' ';
1922 *p = '\000';
1923 d += i;
1924 printk("%s-%04X: %s\n",str,l*8,b);
1925 }
1926 }
1927
1928 void dump_addr(char *str,ipx_address *p) {
1929 printk("%s: %08X:%02X%02X%02X%02X%02X%02X:%04X\n",
1930 str,ntohl(p->net),p->node[0],p->node[1],p->node[2],
1931 p->node[3],p->node[4],p->node[5],ntohs(p->sock));
1932 }
1933
1934 void dump_hdr(char *str,ipx_packet *p) {
1935 printk("%s: CHKSUM=%04X SIZE=%d (%04X) HOPS=%d (%02X) TYPE=%02X\n",
1936 str,p->ipx_checksum,ntohs(p->ipx_pktsize),ntohs(p->ipx_pktsize),
1937 p->ipx_tctrl,p->ipx_tctrl,p->ipx_type);
1938 dump_addr(" IPX-DST",&p->ipx_dest);
1939 dump_addr(" IPX-SRC",&p->ipx_source);
1940 }
1941
1942 void dump_pkt(char *str,ipx_packet *p) {
1943 int len = ntohs(p->ipx_pktsize);
1944 dump_hdr(str,p);
1945 if (len > 30)
1946 dump_data(str,(unsigned char *)p + 30, len - 30);
1947 }
1948 #endif
1949
1950 int ipx_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
1951 {
1952
1953 ipx_interface *intrfc;
1954 ipx_packet *ipx;
1955
1956
1957 ipx=(ipx_packet *)skb->h.raw;
1958
1959 if(ipx->ipx_checksum!=IPX_NO_CHECKSUM) {
1960
1961
1962
1963 kfree_skb(skb,FREE_READ);
1964 return 0;
1965 }
1966
1967
1968 if(htons(ipx->ipx_pktsize)<sizeof(ipx_packet)) {
1969 kfree_skb(skb,FREE_READ);
1970 return 0;
1971 }
1972
1973
1974 intrfc = ipxitf_find_using_phys(dev, pt->type);
1975 if (intrfc == NULL) {
1976 if (ipxcfg_auto_create_interfaces) {
1977 intrfc = ipxitf_auto_create(dev, pt->type);
1978 }
1979
1980 if (intrfc == NULL) {
1981
1982 kfree_skb(skb,FREE_READ);
1983 return 0;
1984 }
1985 }
1986
1987 return ipxitf_rcv(intrfc, skb);
1988 }
1989
1990 static int ipx_sendmsg(struct socket *sock, struct msghdr *msg, int len, int noblock,
1991 int flags)
1992 {
1993 ipx_socket *sk=(ipx_socket *)sock->data;
1994 struct sockaddr_ipx *usipx=(struct sockaddr_ipx *)msg->msg_name;
1995 struct sockaddr_ipx local_sipx;
1996 int retval;
1997
1998 if (sk->zapped) return -EIO;
1999 if(flags) return -EINVAL;
2000
2001 if(usipx)
2002 {
2003 if(sk->protinfo.af_ipx.port == 0)
2004 {
2005 struct sockaddr_ipx uaddr;
2006 int ret;
2007
2008 uaddr.sipx_port = 0;
2009 uaddr.sipx_network = 0L;
2010 #ifdef CONFIG_IPX_INTERN
2011 memcpy(uaddr.sipx_node, sk->protinfo.af_ipx.intrfc
2012 ->if_node, IPX_NODE_LEN);
2013 #endif
2014 ret = ipx_bind (sock, (struct sockaddr *)&uaddr,
2015 sizeof(struct sockaddr_ipx));
2016 if (ret != 0) return ret;
2017 }
2018
2019 if(msg->msg_namelen <sizeof(*usipx))
2020 return -EINVAL;
2021 if(usipx->sipx_family != AF_IPX)
2022 return -EINVAL;
2023 }
2024 else
2025 {
2026 if(sk->state!=TCP_ESTABLISHED)
2027 return -ENOTCONN;
2028 usipx=&local_sipx;
2029 usipx->sipx_family=AF_IPX;
2030 usipx->sipx_type=sk->protinfo.af_ipx.type;
2031 usipx->sipx_port=sk->protinfo.af_ipx.dest_addr.sock;
2032 usipx->sipx_network=sk->protinfo.af_ipx.dest_addr.net;
2033 memcpy(usipx->sipx_node,sk->protinfo.af_ipx.dest_addr.node,IPX_NODE_LEN);
2034 }
2035
2036 retval = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len);
2037 if (retval < 0) return retval;
2038
2039 return len;
2040 }
2041
2042
2043 static int ipx_recvmsg(struct socket *sock, struct msghdr *msg, int size, int noblock,
2044 int flags, int *addr_len)
2045 {
2046 ipx_socket *sk=(ipx_socket *)sock->data;
2047 struct sockaddr_ipx *sipx=(struct sockaddr_ipx *)msg->msg_name;
2048 struct ipx_packet *ipx = NULL;
2049 int copied = 0;
2050 int truesize;
2051 struct sk_buff *skb;
2052 int er;
2053
2054 if(sk->err)
2055 return sock_error(sk);
2056
2057 if (sk->zapped)
2058 return -EIO;
2059
2060
2061 skb=skb_recv_datagram(sk,flags,noblock,&er);
2062 if(skb==NULL)
2063 return er;
2064
2065 if(addr_len)
2066 *addr_len=sizeof(*sipx);
2067
2068 ipx = (ipx_packet *)(skb->h.raw);
2069 truesize=ntohs(ipx->ipx_pktsize) - sizeof(ipx_packet);
2070 copied = (truesize > size) ? size : truesize;
2071 skb_copy_datagram_iovec(skb,sizeof(struct ipx_packet),msg->msg_iov,copied);
2072
2073 if(sipx)
2074 {
2075 sipx->sipx_family=AF_IPX;
2076 sipx->sipx_port=ipx->ipx_source.sock;
2077 memcpy(sipx->sipx_node,ipx->ipx_source.node,IPX_NODE_LEN);
2078 sipx->sipx_network=ipx->ipx_source.net;
2079 sipx->sipx_type = ipx->ipx_type;
2080 }
2081 skb_free_datagram(sk, skb);
2082 return(truesize);
2083 }
2084
2085 static int ipx_shutdown(struct socket *sk,int how)
2086 {
2087 return -EOPNOTSUPP;
2088 }
2089
2090 static int ipx_select(struct socket *sock , int sel_type, select_table *wait)
2091 {
2092 ipx_socket *sk=(ipx_socket *)sock->data;
2093
2094 return datagram_select(sk,sel_type,wait);
2095 }
2096
2097 static int ipx_ioctl(struct socket *sock,unsigned int cmd, unsigned long arg)
2098 {
2099 int err;
2100 long amount=0;
2101 ipx_socket *sk=(ipx_socket *)sock->data;
2102
2103 switch(cmd)
2104 {
2105 case TIOCOUTQ:
2106 err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(unsigned long));
2107 if(err)
2108 return err;
2109 amount=sk->sndbuf-sk->wmem_alloc;
2110 if(amount<0)
2111 amount=0;
2112 put_fs_long(amount,(unsigned long *)arg);
2113 return 0;
2114 case TIOCINQ:
2115 {
2116 struct sk_buff *skb;
2117
2118 if((skb=skb_peek(&sk->receive_queue))!=NULL)
2119 amount=skb->len-sizeof(struct ipx_packet);
2120 err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(unsigned long));
2121 if(err)
2122 return err;
2123 put_fs_long(amount,(unsigned long *)arg);
2124 return 0;
2125 }
2126 case SIOCADDRT:
2127 case SIOCDELRT:
2128 if(!suser())
2129 return -EPERM;
2130 return(ipxrtr_ioctl(cmd,(void *)arg));
2131 case SIOCSIFADDR:
2132 case SIOCGIFADDR:
2133 case SIOCAIPXITFCRT:
2134 case SIOCAIPXPRISLT:
2135 if(!suser())
2136 return -EPERM;
2137 return(ipxitf_ioctl(cmd,(void *)arg));
2138 case SIOCIPXCFGDATA:
2139 {
2140 err=verify_area(VERIFY_WRITE,(void *)arg,
2141 sizeof(ipx_config_data));
2142 if(err) return err;
2143 return(ipxcfg_get_config_data((void *)arg));
2144 }
2145 case SIOCGSTAMP:
2146 if (sk)
2147 {
2148 if(sk->stamp.tv_sec==0)
2149 return -ENOENT;
2150 err=verify_area(VERIFY_WRITE,(void *)arg,sizeof(struct timeval));
2151 if(err)
2152 return err;
2153 memcpy_tofs((void *)arg,&sk->stamp,sizeof(struct timeval));
2154 return 0;
2155 }
2156 return -EINVAL;
2157 case SIOCGIFDSTADDR:
2158 case SIOCSIFDSTADDR:
2159 case SIOCGIFBRDADDR:
2160 case SIOCSIFBRDADDR:
2161 case SIOCGIFNETMASK:
2162 case SIOCSIFNETMASK:
2163 return -EINVAL;
2164 default:
2165 return(dev_ioctl(cmd,(void *) arg));
2166 }
2167
2168 return(0);
2169 }
2170
2171 static struct proto_ops ipx_proto_ops = {
2172 AF_IPX,
2173
2174 ipx_create,
2175 ipx_dup,
2176 ipx_release,
2177 ipx_bind,
2178 ipx_connect,
2179 ipx_socketpair,
2180 ipx_accept,
2181 ipx_getname,
2182 ipx_select,
2183 ipx_ioctl,
2184 ipx_listen,
2185 ipx_shutdown,
2186 ipx_setsockopt,
2187 ipx_getsockopt,
2188 ipx_fcntl,
2189 ipx_sendmsg,
2190 ipx_recvmsg
2191 };
2192
2193
2194
2195 static struct packet_type ipx_8023_packet_type =
2196
2197 {
2198 0,
2199 NULL,
2200 ipx_rcv,
2201 NULL,
2202 NULL,
2203 };
2204
2205 static struct packet_type ipx_dix_packet_type =
2206 {
2207 0,
2208 NULL,
2209 ipx_rcv,
2210 NULL,
2211 NULL,
2212 };
2213
2214 static struct notifier_block ipx_dev_notifier={
2215 ipxitf_device_event,
2216 NULL,
2217 0
2218 };
2219
2220
2221 extern struct datalink_proto *make_EII_client(void);
2222 extern struct datalink_proto *make_8023_client(void);
2223 extern void destroy_EII_client(struct datalink_proto *);
2224 extern void destroy_8023_client(struct datalink_proto *);
2225
2226 struct proc_dir_entry ipx_procinfo = {
2227 PROC_NET_IPX, 3, "ipx", S_IFREG | S_IRUGO,
2228 1, 0, 0, 0, &proc_net_inode_operations, ipx_get_info
2229 };
2230
2231 struct proc_dir_entry ipx_if_procinfo = {
2232 PROC_NET_IPX_INTERFACE, 13, "ipx_interface", S_IFREG | S_IRUGO,
2233 1, 0, 0, 0, &proc_net_inode_operations, ipx_interface_get_info
2234 };
2235
2236 struct proc_dir_entry ipx_rt_procinfo = {
2237 PROC_NET_IPX_ROUTE, 9, "ipx_route", S_IFREG | S_IRUGO,
2238 1, 0, 0, 0, &proc_net_inode_operations, ipx_rt_get_info
2239 };
2240
2241 static unsigned char ipx_8022_type = 0xE0;
2242 static unsigned char ipx_snap_id[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 };
2243
2244 void
2245 ipx_proto_init(struct net_proto *pro)
2246 {
2247 (void) sock_register(ipx_proto_ops.family, &ipx_proto_ops);
2248
2249 pEII_datalink = make_EII_client();
2250 ipx_dix_packet_type.type=htons(ETH_P_IPX);
2251 dev_add_pack(&ipx_dix_packet_type);
2252
2253 p8023_datalink = make_8023_client();
2254 ipx_8023_packet_type.type=htons(ETH_P_802_3);
2255 dev_add_pack(&ipx_8023_packet_type);
2256
2257 if ((p8022_datalink = register_8022_client(ipx_8022_type, ipx_rcv)) == NULL)
2258 printk("IPX: Unable to register with 802.2\n");
2259
2260 if ((pSNAP_datalink = register_snap_client(ipx_snap_id, ipx_rcv)) == NULL)
2261 printk("IPX: Unable to register with SNAP\n");
2262
2263 register_netdevice_notifier(&ipx_dev_notifier);
2264
2265 proc_net_register(&ipx_procinfo);
2266 proc_net_register(&ipx_if_procinfo);
2267 proc_net_register(&ipx_rt_procinfo);
2268
2269 printk("Swansea University Computer Society IPX 0.34 for NET3.034\n");
2270 printk("IPX Portions Copyright (c) 1995 Caldera, Inc.\n");
2271 }
2272
2273 #ifdef MODULE
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287 static void
2288 ipx_proto_finito(void)
2289 { ipx_interface *ifc;
2290
2291 while (ipx_interfaces) {
2292 ifc = ipx_interfaces;
2293 ipx_interfaces = ifc->if_next;
2294 ifc->if_next = NULL;
2295 ipxitf_down(ifc);
2296 }
2297
2298 proc_net_unregister(PROC_NET_IPX_ROUTE);
2299 proc_net_unregister(PROC_NET_IPX_INTERFACE);
2300 proc_net_unregister(PROC_NET_IPX);
2301
2302 unregister_netdevice_notifier(&ipx_dev_notifier);
2303
2304 unregister_snap_client(ipx_snap_id);
2305 pSNAP_datalink = NULL;
2306
2307 unregister_8022_client(ipx_8022_type);
2308 p8022_datalink = NULL;
2309
2310 dev_remove_pack(&ipx_8023_packet_type);
2311 destroy_8023_client(p8023_datalink);
2312 p8023_datalink = NULL;
2313
2314 dev_remove_pack(&ipx_dix_packet_type);
2315 destroy_EII_client(pEII_datalink);
2316 pEII_datalink = NULL;
2317
2318 (void) sock_unregister(ipx_proto_ops.family);
2319
2320 return;
2321 }
2322
2323 int init_module(void)
2324 {
2325 ipx_proto_init(NULL);
2326 register_symtab(0);
2327 return 0;
2328 }
2329
2330 void cleanup_module(void)
2331 {
2332 ipx_proto_finito();
2333 return;
2334 }
2335 #endif