aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipx
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipx')
-rw-r--r--net/ipx/ChangeLog101
-rw-r--r--net/ipx/Kconfig31
-rw-r--r--net/ipx/Makefile8
-rw-r--r--net/ipx/af_ipx.c2024
-rw-r--r--net/ipx/ipx_proc.c408
-rw-r--r--net/ipx/ipx_route.c293
-rw-r--r--net/ipx/sysctl_net_ipx.c62
7 files changed, 2927 insertions, 0 deletions
diff --git a/net/ipx/ChangeLog b/net/ipx/ChangeLog
new file mode 100644
index 000000000000..3b29763751a3
--- /dev/null
+++ b/net/ipx/ChangeLog
@@ -0,0 +1,101 @@
1 Revision 0.21: Uses the new generic socket option code.
2
3 Revision 0.22: Gcc clean ups and drop out device registration. Use the
4 new multi-protocol edition of hard_header
5
6 Revision 0.23: IPX /proc by Mark Evans. Adding a route will
7 will overwrite any existing route to the same network.
8
9 Revision 0.24: Supports new /proc with no 4K limit
10
11 Revision 0.25: Add ephemeral sockets, passive local network
12 identification, support for local net 0 and
13 multiple datalinks <Greg Page>
14
15 Revision 0.26: Device drop kills IPX routes via it. (needed for module)
16
17 Revision 0.27: Autobind <Mark Evans>
18
19 Revision 0.28: Small fix for multiple local networks <Thomas Winder>
20
21 Revision 0.29: Assorted major errors removed <Mark Evans>
22 Small correction to promisc mode error fix <Alan Cox>
23 Asynchronous I/O support. Changed to use notifiers
24 and the newer packet_type stuff. Assorted major
25 fixes <Alejandro Liu>
26
27 Revision 0.30: Moved to net/ipx/... <Alan Cox>
28 Don't set address length on recvfrom that errors.
29 Incorrect verify_area.
30
31 Revision 0.31: New sk_buffs. This still needs a lot of
32 testing. <Alan Cox>
33
34 Revision 0.32: Using sock_alloc_send_skb, firewall hooks. <Alan Cox>
35 Supports sendmsg/recvmsg
36
37 Revision 0.33: Internal network support, routing changes, uses a
38 protocol private area for ipx data.
39
40 Revision 0.34: Module support. <Jim Freeman>
41
42 Revision 0.35: Checksum support. <Neil Turton>, hooked in by <Alan Cox>
43 Handles WIN95 discovery packets <Volker Lendecke>
44
45 Revision 0.36: Internal bump up for 2.1
46
47 Revision 0.37: Began adding POSIXisms.
48
49 Revision 0.38: Asynchronous socket stuff made current.
50
51 Revision 0.39: SPX interfaces
52
53 Revision 0.40: Tiny SIOCGSTAMP fix (chris@cybernet.co.nz)
54
55 Revision 0.41: 802.2TR removed (p.norton@computer.org)
56 Fixed connecting to primary net,
57 Automatic binding on send & receive,
58 Martijn van Oosterhout <kleptogimp@geocities.com>
59
60 Revision 042: Multithreading - use spinlocks and refcounting to
61 protect some structures: ipx_interface sock list, list
62 of ipx interfaces, etc.
63 Bugfixes - do refcounting on net_devices, check function
64 results, etc. Thanks to davem and freitag for
65 suggestions and guidance.
66 Arnaldo Carvalho de Melo <acme@conectiva.com.br>,
67 November, 2000
68
69 Revision 043: Shared SKBs, don't mangle packets, some cleanups
70 Arnaldo Carvalho de Melo <acme@conectiva.com.br>,
71 December, 2000
72
73 Revision 044: Call ipxitf_hold on NETDEV_UP - acme
74
75 Revision 045: fix PPROP routing bug - acme
76
77 Revision 046: Further fixes to PPROP, ipxitf_create_internal was
78 doing an unneeded MOD_INC_USE_COUNT, implement
79 sysctl for ipx_pprop_broacasting, fix the ipx sysctl
80 handling, making it dynamic, some cleanups, thanks to
81 Petr Vandrovec for review and good suggestions. (acme)
82
83 Revision 047: Cleanups, CodingStyle changes, move the ncp connection
84 hack out of line - acme
85
86 Revision 048: Use sk->protinfo to store the pointer to IPX private
87 area, remove af_ipx from sk->protinfo and move ipx_opt
88 to include/net/ipx.h, use IPX_SK like DecNET, etc - acme
89
90 Revision 049: SPX support dropped, see comment in ipx_create - acme
91
92 Revision 050: Use seq_file for proc stuff, moving it to ipx_proc.c - acme
93
94Other fixes:
95
96 Protect the module by a MOD_INC_USE_COUNT/MOD_DEC_USE_COUNT pair. Also, now
97 usage count is managed this way:
98 -Count one if the auto_interface mode is on
99 -Count one per configured interface
100
101 Jacques Gelinas (jacques@solucorp.qc.ca)
diff --git a/net/ipx/Kconfig b/net/ipx/Kconfig
new file mode 100644
index 000000000000..a16237c0e783
--- /dev/null
+++ b/net/ipx/Kconfig
@@ -0,0 +1,31 @@
1#
2# IPX configuration
3#
4config IPX_INTERN
5 bool "IPX: Full internal IPX network"
6 depends on IPX
7 ---help---
8 Every IPX network has an address that identifies it. Sometimes it is
9 useful to give an IPX "network" address to your Linux box as well
10 (for example if your box is acting as a file server for different
11 IPX networks: it will then be accessible from everywhere using the
12 same address). The way this is done is to create a virtual internal
13 "network" inside your box and to assign an IPX address to this
14 network. Say Y here if you want to do this; read the IPX-HOWTO at
15 <http://www.tldp.org/docs.html#howto> for details.
16
17 The full internal IPX network enables you to allocate sockets on
18 different virtual nodes of the internal network. This is done by
19 evaluating the field sipx_node of the socket address given to the
20 bind call. So applications should always initialize the node field
21 to 0 when binding a socket on the primary network. In this case the
22 socket is assigned the default node that has been given to the
23 kernel when the internal network was created. By enabling the full
24 internal IPX network the cross-forwarding of packets targeted at
25 'special' sockets to sockets listening on the primary network is
26 disabled. This might break existing applications, especially RIP/SAP
27 daemons. A RIP/SAP daemon that works well with the full internal net
28 can be found on <ftp://ftp.gwdg.de/pub/linux/misc/ncpfs/>.
29
30 If you don't know what you are doing, say N.
31
diff --git a/net/ipx/Makefile b/net/ipx/Makefile
new file mode 100644
index 000000000000..4b95e3ea0f8b
--- /dev/null
+++ b/net/ipx/Makefile
@@ -0,0 +1,8 @@
1#
2# Makefile for the Linux IPX layer.
3#
4
5obj-$(CONFIG_IPX) += ipx.o
6
7ipx-y := af_ipx.o ipx_route.o ipx_proc.o
8ipx-$(CONFIG_SYSCTL) += sysctl_net_ipx.o
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
new file mode 100644
index 000000000000..5a27e5df5886
--- /dev/null
+++ b/net/ipx/af_ipx.c
@@ -0,0 +1,2024 @@
1/*
2 * Implements an IPX socket layer.
3 *
4 * This code is derived from work by
5 * Ross Biro : Writing the original IP stack
6 * Fred Van Kempen : Tidying up the TCP/IP
7 *
8 * Many thanks go to Keith Baker, Institute For Industrial Information
9 * Technology Ltd, Swansea University for allowing me to work on this
10 * in my own time even though it was in some ways related to commercial
11 * work I am currently employed to do there.
12 *
13 * All the material in this file is subject to the Gnu license version 2.
14 * Neither Alan Cox nor the Swansea University Computer Society admit
15 * liability nor provide warranty for any of this software. This material
16 * is provided as is and at no charge.
17 *
18 * Portions Copyright (c) 2000-2003 Conectiva, Inc. <acme@conectiva.com.br>
19 * Neither Arnaldo Carvalho de Melo nor Conectiva, Inc. admit liability nor
20 * provide warranty for any of this software. This material is provided
21 * "AS-IS" and at no charge.
22 *
23 * Portions Copyright (c) 1995 Caldera, Inc. <greg@caldera.com>
24 * Neither Greg Page nor Caldera, Inc. admit liability nor provide
25 * warranty for any of this software. This material is provided
26 * "AS-IS" and at no charge.
27 *
28 * See net/ipx/ChangeLog.
29 */
30
31#include <linux/config.h>
32#include <linux/errno.h>
33#include <linux/if_arp.h>
34#include <linux/if_ether.h>
35#include <linux/init.h>
36#include <linux/ipx.h>
37#include <linux/kernel.h>
38#include <linux/list.h>
39#include <linux/module.h>
40#include <linux/net.h>
41#include <linux/netdevice.h>
42#include <linux/uio.h>
43#include <linux/skbuff.h>
44#include <linux/socket.h>
45#include <linux/sockios.h>
46#include <linux/string.h>
47#include <linux/tcp.h>
48#include <linux/types.h>
49#include <linux/termios.h>
50
51#include <net/ipx.h>
52#include <net/p8022.h>
53#include <net/psnap.h>
54#include <net/sock.h>
55
56#include <asm/uaccess.h>
57
58#ifdef CONFIG_SYSCTL
59extern void ipx_register_sysctl(void);
60extern void ipx_unregister_sysctl(void);
61#else
62#define ipx_register_sysctl()
63#define ipx_unregister_sysctl()
64#endif
65
66/* Configuration Variables */
67static unsigned char ipxcfg_max_hops = 16;
68static char ipxcfg_auto_select_primary;
69static char ipxcfg_auto_create_interfaces;
70int sysctl_ipx_pprop_broadcasting = 1;
71
72/* Global Variables */
73static struct datalink_proto *p8022_datalink;
74static struct datalink_proto *pEII_datalink;
75static struct datalink_proto *p8023_datalink;
76static struct datalink_proto *pSNAP_datalink;
77
78static struct proto_ops ipx_dgram_ops;
79
80LIST_HEAD(ipx_interfaces);
81DEFINE_SPINLOCK(ipx_interfaces_lock);
82
83struct ipx_interface *ipx_primary_net;
84struct ipx_interface *ipx_internal_net;
85
86extern int ipxrtr_add_route(__u32 network, struct ipx_interface *intrfc,
87 unsigned char *node);
88extern void ipxrtr_del_routes(struct ipx_interface *intrfc);
89extern int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx,
90 struct iovec *iov, int len, int noblock);
91extern int ipxrtr_route_skb(struct sk_buff *skb);
92extern struct ipx_route *ipxrtr_lookup(__u32 net);
93extern int ipxrtr_ioctl(unsigned int cmd, void __user *arg);
94
95#undef IPX_REFCNT_DEBUG
96#ifdef IPX_REFCNT_DEBUG
97atomic_t ipx_sock_nr;
98#endif
99
100struct ipx_interface *ipx_interfaces_head(void)
101{
102 struct ipx_interface *rc = NULL;
103
104 if (!list_empty(&ipx_interfaces))
105 rc = list_entry(ipx_interfaces.next,
106 struct ipx_interface, node);
107 return rc;
108}
109
110static void ipxcfg_set_auto_select(char val)
111{
112 ipxcfg_auto_select_primary = val;
113 if (val && !ipx_primary_net)
114 ipx_primary_net = ipx_interfaces_head();
115}
116
117static int ipxcfg_get_config_data(struct ipx_config_data __user *arg)
118{
119 struct ipx_config_data vals;
120
121 vals.ipxcfg_auto_create_interfaces = ipxcfg_auto_create_interfaces;
122 vals.ipxcfg_auto_select_primary = ipxcfg_auto_select_primary;
123
124 return copy_to_user(arg, &vals, sizeof(vals)) ? -EFAULT : 0;
125}
126
127/*
128 * Note: Sockets may not be removed _during_ an interrupt or inet_bh
129 * handler using this technique. They can be added although we do not
130 * use this facility.
131 */
132
133static void ipx_remove_socket(struct sock *sk)
134{
135 /* Determine interface with which socket is associated */
136 struct ipx_interface *intrfc = ipx_sk(sk)->intrfc;
137
138 if (!intrfc)
139 goto out;
140
141 ipxitf_hold(intrfc);
142 spin_lock_bh(&intrfc->if_sklist_lock);
143 sk_del_node_init(sk);
144 spin_unlock_bh(&intrfc->if_sklist_lock);
145 ipxitf_put(intrfc);
146out:
147 return;
148}
149
150static void ipx_destroy_socket(struct sock *sk)
151{
152 ipx_remove_socket(sk);
153 skb_queue_purge(&sk->sk_receive_queue);
154#ifdef IPX_REFCNT_DEBUG
155 atomic_dec(&ipx_sock_nr);
156 printk(KERN_DEBUG "IPX socket %p released, %d are still alive\n", sk,
157 atomic_read(&ipx_sock_nr));
158 if (atomic_read(&sk->sk_refcnt) != 1)
159 printk(KERN_DEBUG "Destruction sock ipx %p delayed, cnt=%d\n",
160 sk, atomic_read(&sk->sk_refcnt));
161#endif
162 sock_put(sk);
163}
164
165/*
166 * The following code is used to support IPX Interfaces (IPXITF). An
167 * IPX interface is defined by a physical device and a frame type.
168 */
169
170/* ipxitf_clear_primary_net has to be called with ipx_interfaces_lock held */
171
172static void ipxitf_clear_primary_net(void)
173{
174 ipx_primary_net = NULL;
175 if (ipxcfg_auto_select_primary)
176 ipx_primary_net = ipx_interfaces_head();
177}
178
179static struct ipx_interface *__ipxitf_find_using_phys(struct net_device *dev,
180 unsigned short datalink)
181{
182 struct ipx_interface *i;
183
184 list_for_each_entry(i, &ipx_interfaces, node)
185 if (i->if_dev == dev && i->if_dlink_type == datalink)
186 goto out;
187 i = NULL;
188out:
189 return i;
190}
191
192static struct ipx_interface *ipxitf_find_using_phys(struct net_device *dev,
193 unsigned short datalink)
194{
195 struct ipx_interface *i;
196
197 spin_lock_bh(&ipx_interfaces_lock);
198 i = __ipxitf_find_using_phys(dev, datalink);
199 if (i)
200 ipxitf_hold(i);
201 spin_unlock_bh(&ipx_interfaces_lock);
202 return i;
203}
204
205struct ipx_interface *ipxitf_find_using_net(__u32 net)
206{
207 struct ipx_interface *i;
208
209 spin_lock_bh(&ipx_interfaces_lock);
210 if (net) {
211 list_for_each_entry(i, &ipx_interfaces, node)
212 if (i->if_netnum == net)
213 goto hold;
214 i = NULL;
215 goto unlock;
216 }
217
218 i = ipx_primary_net;
219 if (i)
220hold:
221 ipxitf_hold(i);
222unlock:
223 spin_unlock_bh(&ipx_interfaces_lock);
224 return i;
225}
226
227/* Sockets are bound to a particular IPX interface. */
228static void ipxitf_insert_socket(struct ipx_interface *intrfc, struct sock *sk)
229{
230 ipxitf_hold(intrfc);
231 spin_lock_bh(&intrfc->if_sklist_lock);
232 ipx_sk(sk)->intrfc = intrfc;
233 sk_add_node(sk, &intrfc->if_sklist);
234 spin_unlock_bh(&intrfc->if_sklist_lock);
235 ipxitf_put(intrfc);
236}
237
238/* caller must hold intrfc->if_sklist_lock */
239static struct sock *__ipxitf_find_socket(struct ipx_interface *intrfc,
240 unsigned short port)
241{
242 struct sock *s;
243 struct hlist_node *node;
244
245 sk_for_each(s, node, &intrfc->if_sklist)
246 if (ipx_sk(s)->port == port)
247 goto found;
248 s = NULL;
249found:
250 return s;
251}
252
253/* caller must hold a reference to intrfc */
254static struct sock *ipxitf_find_socket(struct ipx_interface *intrfc,
255 unsigned short port)
256{
257 struct sock *s;
258
259 spin_lock_bh(&intrfc->if_sklist_lock);
260 s = __ipxitf_find_socket(intrfc, port);
261 if (s)
262 sock_hold(s);
263 spin_unlock_bh(&intrfc->if_sklist_lock);
264
265 return s;
266}
267
268#ifdef CONFIG_IPX_INTERN
269static struct sock *ipxitf_find_internal_socket(struct ipx_interface *intrfc,
270 unsigned char *ipx_node,
271 unsigned short port)
272{
273 struct sock *s;
274 struct hlist_node *node;
275
276 ipxitf_hold(intrfc);
277 spin_lock_bh(&intrfc->if_sklist_lock);
278
279 sk_for_each(s, node, &intrfc->if_sklist) {
280 struct ipx_sock *ipxs = ipx_sk(s);
281
282 if (ipxs->port == port &&
283 !memcmp(ipx_node, ipxs->node, IPX_NODE_LEN))
284 goto found;
285 }
286 s = NULL;
287found:
288 spin_unlock_bh(&intrfc->if_sklist_lock);
289 ipxitf_put(intrfc);
290 return s;
291}
292#endif
293
294static void __ipxitf_down(struct ipx_interface *intrfc)
295{
296 struct sock *s;
297 struct hlist_node *node, *t;
298
299 /* Delete all routes associated with this interface */
300 ipxrtr_del_routes(intrfc);
301
302 spin_lock_bh(&intrfc->if_sklist_lock);
303 /* error sockets */
304 sk_for_each_safe(s, node, t, &intrfc->if_sklist) {
305 struct ipx_sock *ipxs = ipx_sk(s);
306
307 s->sk_err = ENOLINK;
308 s->sk_error_report(s);
309 ipxs->intrfc = NULL;
310 ipxs->port = 0;
311 sock_set_flag(s, SOCK_ZAPPED); /* Indicates it is no longer bound */
312 sk_del_node_init(s);
313 }
314 INIT_HLIST_HEAD(&intrfc->if_sklist);
315 spin_unlock_bh(&intrfc->if_sklist_lock);
316
317 /* remove this interface from list */
318 list_del(&intrfc->node);
319
320 /* remove this interface from *special* networks */
321 if (intrfc == ipx_primary_net)
322 ipxitf_clear_primary_net();
323 if (intrfc == ipx_internal_net)
324 ipx_internal_net = NULL;
325
326 if (intrfc->if_dev)
327 dev_put(intrfc->if_dev);
328 kfree(intrfc);
329}
330
331void ipxitf_down(struct ipx_interface *intrfc)
332{
333 spin_lock_bh(&ipx_interfaces_lock);
334 __ipxitf_down(intrfc);
335 spin_unlock_bh(&ipx_interfaces_lock);
336}
337
338static __inline__ void __ipxitf_put(struct ipx_interface *intrfc)
339{
340 if (atomic_dec_and_test(&intrfc->refcnt))
341 __ipxitf_down(intrfc);
342}
343
344static int ipxitf_device_event(struct notifier_block *notifier,
345 unsigned long event, void *ptr)
346{
347 struct net_device *dev = ptr;
348 struct ipx_interface *i, *tmp;
349
350 if (event != NETDEV_DOWN && event != NETDEV_UP)
351 goto out;
352
353 spin_lock_bh(&ipx_interfaces_lock);
354 list_for_each_entry_safe(i, tmp, &ipx_interfaces, node)
355 if (i->if_dev == dev) {
356 if (event == NETDEV_UP)
357 ipxitf_hold(i);
358 else
359 __ipxitf_put(i);
360 }
361 spin_unlock_bh(&ipx_interfaces_lock);
362out:
363 return NOTIFY_DONE;
364}
365
366
367static __exit void ipxitf_cleanup(void)
368{
369 struct ipx_interface *i, *tmp;
370
371 spin_lock_bh(&ipx_interfaces_lock);
372 list_for_each_entry_safe(i, tmp, &ipx_interfaces, node)
373 __ipxitf_put(i);
374 spin_unlock_bh(&ipx_interfaces_lock);
375}
376
377static void ipxitf_def_skb_handler(struct sock *sock, struct sk_buff *skb)
378{
379 if (sock_queue_rcv_skb(sock, skb) < 0)
380 kfree_skb(skb);
381}
382
383/*
384 * On input skb->sk is NULL. Nobody is charged for the memory.
385 */
386
387/* caller must hold a reference to intrfc */
388
389#ifdef CONFIG_IPX_INTERN
390static int ipxitf_demux_socket(struct ipx_interface *intrfc,
391 struct sk_buff *skb, int copy)
392{
393 struct ipxhdr *ipx = ipx_hdr(skb);
394 int is_broadcast = !memcmp(ipx->ipx_dest.node, ipx_broadcast_node,
395 IPX_NODE_LEN);
396 struct sock *s;
397 struct hlist_node *node;
398 int rc;
399
400 spin_lock_bh(&intrfc->if_sklist_lock);
401
402 sk_for_each(s, node, &intrfc->if_sklist) {
403 struct ipx_sock *ipxs = ipx_sk(s);
404
405 if (ipxs->port == ipx->ipx_dest.sock &&
406 (is_broadcast || !memcmp(ipx->ipx_dest.node,
407 ipxs->node, IPX_NODE_LEN))) {
408 /* We found a socket to which to send */
409 struct sk_buff *skb1;
410
411 if (copy) {
412 skb1 = skb_clone(skb, GFP_ATOMIC);
413 rc = -ENOMEM;
414 if (!skb1)
415 goto out;
416 } else {
417 skb1 = skb;
418 copy = 1; /* skb may only be used once */
419 }
420 ipxitf_def_skb_handler(s, skb1);
421
422 /* On an external interface, one socket can listen */
423 if (intrfc != ipx_internal_net)
424 break;
425 }
426 }
427
428 /* skb was solely for us, and we did not make a copy, so free it. */
429 if (!copy)
430 kfree_skb(skb);
431
432 rc = 0;
433out:
434 spin_unlock_bh(&intrfc->if_sklist_lock);
435 return rc;
436}
437#else
438static struct sock *ncp_connection_hack(struct ipx_interface *intrfc,
439 struct ipxhdr *ipx)
440{
441 /* The packet's target is a NCP connection handler. We want to hand it
442 * to the correct socket directly within the kernel, so that the
443 * mars_nwe packet distribution process does not have to do it. Here we
444 * only care about NCP and BURST packets.
445 *
446 * You might call this a hack, but believe me, you do not want a
447 * complete NCP layer in the kernel, and this is VERY fast as well. */
448 struct sock *sk = NULL;
449 int connection = 0;
450 u8 *ncphdr = (u8 *)(ipx + 1);
451
452 if (*ncphdr == 0x22 && *(ncphdr + 1) == 0x22) /* NCP request */
453 connection = (((int) *(ncphdr + 5)) << 8) | (int) *(ncphdr + 3);
454 else if (*ncphdr == 0x77 && *(ncphdr + 1) == 0x77) /* BURST packet */
455 connection = (((int) *(ncphdr + 9)) << 8) | (int) *(ncphdr + 8);
456
457 if (connection) {
458 struct hlist_node *node;
459 /* Now we have to look for a special NCP connection handling
460 * socket. Only these sockets have ipx_ncp_conn != 0, set by
461 * SIOCIPXNCPCONN. */
462 spin_lock_bh(&intrfc->if_sklist_lock);
463 sk_for_each(sk, node, &intrfc->if_sklist)
464 if (ipx_sk(sk)->ipx_ncp_conn == connection) {
465 sock_hold(sk);
466 goto found;
467 }
468 sk = NULL;
469 found:
470 spin_unlock_bh(&intrfc->if_sklist_lock);
471 }
472 return sk;
473}
474
475static int ipxitf_demux_socket(struct ipx_interface *intrfc,
476 struct sk_buff *skb, int copy)
477{
478 struct ipxhdr *ipx = ipx_hdr(skb);
479 struct sock *sock1 = NULL, *sock2 = NULL;
480 struct sk_buff *skb1 = NULL, *skb2 = NULL;
481 int rc;
482
483 if (intrfc == ipx_primary_net && ntohs(ipx->ipx_dest.sock) == 0x451)
484 sock1 = ncp_connection_hack(intrfc, ipx);
485 if (!sock1)
486 /* No special socket found, forward the packet the normal way */
487 sock1 = ipxitf_find_socket(intrfc, ipx->ipx_dest.sock);
488
489 /*
490 * We need to check if there is a primary net and if
491 * this is addressed to one of the *SPECIAL* sockets because
492 * these need to be propagated to the primary net.
493 * The *SPECIAL* socket list contains: 0x452(SAP), 0x453(RIP) and
494 * 0x456(Diagnostic).
495 */
496
497 if (ipx_primary_net && intrfc != ipx_primary_net) {
498 const int dsock = ntohs(ipx->ipx_dest.sock);
499
500 if (dsock == 0x452 || dsock == 0x453 || dsock == 0x456)
501 /* The appropriate thing to do here is to dup the
502 * packet and route to the primary net interface via
503 * ipxitf_send; however, we'll cheat and just demux it
504 * here. */
505 sock2 = ipxitf_find_socket(ipx_primary_net,
506 ipx->ipx_dest.sock);
507 }
508
509 /*
510 * If there is nothing to do return. The kfree will cancel any charging.
511 */
512 rc = 0;
513 if (!sock1 && !sock2) {
514 if (!copy)
515 kfree_skb(skb);
516 goto out;
517 }
518
519 /*
520 * This next segment of code is a little awkward, but it sets it up
521 * so that the appropriate number of copies of the SKB are made and
522 * that skb1 and skb2 point to it (them) so that it (they) can be
523 * demuxed to sock1 and/or sock2. If we are unable to make enough
524 * copies, we do as much as is possible.
525 */
526
527 if (copy)
528 skb1 = skb_clone(skb, GFP_ATOMIC);
529 else
530 skb1 = skb;
531
532 rc = -ENOMEM;
533 if (!skb1)
534 goto out_put;
535
536 /* Do we need 2 SKBs? */
537 if (sock1 && sock2)
538 skb2 = skb_clone(skb1, GFP_ATOMIC);
539 else
540 skb2 = skb1;
541
542 if (sock1)
543 ipxitf_def_skb_handler(sock1, skb1);
544
545 if (!skb2)
546 goto out_put;
547
548 if (sock2)
549 ipxitf_def_skb_handler(sock2, skb2);
550
551 rc = 0;
552out_put:
553 if (sock1)
554 sock_put(sock1);
555 if (sock2)
556 sock_put(sock2);
557out:
558 return rc;
559}
560#endif /* CONFIG_IPX_INTERN */
561
562static struct sk_buff *ipxitf_adjust_skbuff(struct ipx_interface *intrfc,
563 struct sk_buff *skb)
564{
565 struct sk_buff *skb2;
566 int in_offset = (unsigned char *)ipx_hdr(skb) - skb->head;
567 int out_offset = intrfc->if_ipx_offset;
568 int len;
569
570 /* Hopefully, most cases */
571 if (in_offset >= out_offset)
572 return skb;
573
574 /* Need new SKB */
575 len = skb->len + out_offset;
576 skb2 = alloc_skb(len, GFP_ATOMIC);
577 if (skb2) {
578 skb_reserve(skb2, out_offset);
579 skb2->nh.raw = skb2->h.raw = skb_put(skb2, skb->len);
580 memcpy(ipx_hdr(skb2), ipx_hdr(skb), skb->len);
581 memcpy(skb2->cb, skb->cb, sizeof(skb->cb));
582 }
583 kfree_skb(skb);
584 return skb2;
585}
586
587/* caller must hold a reference to intrfc and the skb has to be unshared */
588int ipxitf_send(struct ipx_interface *intrfc, struct sk_buff *skb, char *node)
589{
590 struct ipxhdr *ipx = ipx_hdr(skb);
591 struct net_device *dev = intrfc->if_dev;
592 struct datalink_proto *dl = intrfc->if_dlink;
593 char dest_node[IPX_NODE_LEN];
594 int send_to_wire = 1;
595 int addr_len;
596
597 ipx->ipx_tctrl = IPX_SKB_CB(skb)->ipx_tctrl;
598 ipx->ipx_dest.net = IPX_SKB_CB(skb)->ipx_dest_net;
599 ipx->ipx_source.net = IPX_SKB_CB(skb)->ipx_source_net;
600
601 /* see if we need to include the netnum in the route list */
602 if (IPX_SKB_CB(skb)->last_hop.index >= 0) {
603 u32 *last_hop = (u32 *)(((u8 *) skb->data) +
604 sizeof(struct ipxhdr) +
605 IPX_SKB_CB(skb)->last_hop.index *
606 sizeof(u32));
607 *last_hop = IPX_SKB_CB(skb)->last_hop.netnum;
608 IPX_SKB_CB(skb)->last_hop.index = -1;
609 }
610
611 /*
612 * We need to know how many skbuffs it will take to send out this
613 * packet to avoid unnecessary copies.
614 */
615
616 if (!dl || !dev || dev->flags & IFF_LOOPBACK)
617 send_to_wire = 0; /* No non looped */
618
619 /*
620 * See if this should be demuxed to sockets on this interface
621 *
622 * We want to ensure the original was eaten or that we only use
623 * up clones.
624 */
625
626 if (ipx->ipx_dest.net == intrfc->if_netnum) {
627 /*
628 * To our own node, loop and free the original.
629 * The internal net will receive on all node address.
630 */
631 if (intrfc == ipx_internal_net ||
632 !memcmp(intrfc->if_node, node, IPX_NODE_LEN)) {
633 /* Don't charge sender */
634 skb_orphan(skb);
635
636 /* Will charge receiver */
637 return ipxitf_demux_socket(intrfc, skb, 0);
638 }
639
640 /* Broadcast, loop and possibly keep to send on. */
641 if (!memcmp(ipx_broadcast_node, node, IPX_NODE_LEN)) {
642 if (!send_to_wire)
643 skb_orphan(skb);
644 ipxitf_demux_socket(intrfc, skb, send_to_wire);
645 if (!send_to_wire)
646 goto out;
647 }
648 }
649
650 /*
651 * If the originating net is not equal to our net; this is routed
652 * We are still charging the sender. Which is right - the driver
653 * free will handle this fairly.
654 */
655 if (ipx->ipx_source.net != intrfc->if_netnum) {
656 /*
657 * Unshare the buffer before modifying the count in
658 * case it's a flood or tcpdump
659 */
660 skb = skb_unshare(skb, GFP_ATOMIC);
661 if (!skb)
662 goto out;
663 if (++ipx->ipx_tctrl > ipxcfg_max_hops)
664 send_to_wire = 0;
665 }
666
667 if (!send_to_wire) {
668 kfree_skb(skb);
669 goto out;
670 }
671
672 /* Determine the appropriate hardware address */
673 addr_len = dev->addr_len;
674 if (!memcmp(ipx_broadcast_node, node, IPX_NODE_LEN))
675 memcpy(dest_node, dev->broadcast, addr_len);
676 else
677 memcpy(dest_node, &(node[IPX_NODE_LEN-addr_len]), addr_len);
678
679 /* Make any compensation for differing physical/data link size */
680 skb = ipxitf_adjust_skbuff(intrfc, skb);
681 if (!skb)
682 goto out;
683
684 /* set up data link and physical headers */
685 skb->dev = dev;
686 skb->protocol = htons(ETH_P_IPX);
687
688 /* Send it out */
689 dl->request(dl, skb, dest_node);
690out:
691 return 0;
692}
693
694static int ipxitf_add_local_route(struct ipx_interface *intrfc)
695{
696 return ipxrtr_add_route(intrfc->if_netnum, intrfc, NULL);
697}
698
699static void ipxitf_discover_netnum(struct ipx_interface *intrfc,
700 struct sk_buff *skb);
701static int ipxitf_pprop(struct ipx_interface *intrfc, struct sk_buff *skb);
702
703static int ipxitf_rcv(struct ipx_interface *intrfc, struct sk_buff *skb)
704{
705 struct ipxhdr *ipx = ipx_hdr(skb);
706 int rc = 0;
707
708 ipxitf_hold(intrfc);
709
710 /* See if we should update our network number */
711 if (!intrfc->if_netnum) /* net number of intrfc not known yet */
712 ipxitf_discover_netnum(intrfc, skb);
713
714 IPX_SKB_CB(skb)->last_hop.index = -1;
715 if (ipx->ipx_type == IPX_TYPE_PPROP) {
716 rc = ipxitf_pprop(intrfc, skb);
717 if (rc)
718 goto out_free_skb;
719 }
720
721 /* local processing follows */
722 if (!IPX_SKB_CB(skb)->ipx_dest_net)
723 IPX_SKB_CB(skb)->ipx_dest_net = intrfc->if_netnum;
724 if (!IPX_SKB_CB(skb)->ipx_source_net)
725 IPX_SKB_CB(skb)->ipx_source_net = intrfc->if_netnum;
726
727 /* it doesn't make sense to route a pprop packet, there's no meaning
728 * in the ipx_dest_net for such packets */
729 if (ipx->ipx_type != IPX_TYPE_PPROP &&
730 intrfc->if_netnum != IPX_SKB_CB(skb)->ipx_dest_net) {
731 /* We only route point-to-point packets. */
732 if (skb->pkt_type == PACKET_HOST) {
733 skb = skb_unshare(skb, GFP_ATOMIC);
734 if (skb)
735 rc = ipxrtr_route_skb(skb);
736 goto out_intrfc;
737 }
738
739 goto out_free_skb;
740 }
741
742 /* see if we should keep it */
743 if (!memcmp(ipx_broadcast_node, ipx->ipx_dest.node, IPX_NODE_LEN) ||
744 !memcmp(intrfc->if_node, ipx->ipx_dest.node, IPX_NODE_LEN)) {
745 rc = ipxitf_demux_socket(intrfc, skb, 0);
746 goto out_intrfc;
747 }
748
749 /* we couldn't pawn it off so unload it */
750out_free_skb:
751 kfree_skb(skb);
752out_intrfc:
753 ipxitf_put(intrfc);
754 return rc;
755}
756
757static void ipxitf_discover_netnum(struct ipx_interface *intrfc,
758 struct sk_buff *skb)
759{
760 const struct ipx_cb *cb = IPX_SKB_CB(skb);
761
762 /* see if this is an intra packet: source_net == dest_net */
763 if (cb->ipx_source_net == cb->ipx_dest_net && cb->ipx_source_net) {
764 struct ipx_interface *i =
765 ipxitf_find_using_net(cb->ipx_source_net);
766 /* NB: NetWare servers lie about their hop count so we
767 * dropped the test based on it. This is the best way
768 * to determine this is a 0 hop count packet. */
769 if (!i) {
770 intrfc->if_netnum = cb->ipx_source_net;
771 ipxitf_add_local_route(intrfc);
772 } else {
773 printk(KERN_WARNING "IPX: Network number collision "
774 "%lx\n %s %s and %s %s\n",
775 (unsigned long) htonl(cb->ipx_source_net),
776 ipx_device_name(i),
777 ipx_frame_name(i->if_dlink_type),
778 ipx_device_name(intrfc),
779 ipx_frame_name(intrfc->if_dlink_type));
780 ipxitf_put(i);
781 }
782 }
783}
784
785/**
786 * ipxitf_pprop - Process packet propagation IPX packet type 0x14, used for
787 * NetBIOS broadcasts
788 * @intrfc: IPX interface receiving this packet
789 * @skb: Received packet
790 *
791 * Checks if packet is valid: if its more than %IPX_MAX_PPROP_HOPS hops or if it
792 * is smaller than a IPX header + the room for %IPX_MAX_PPROP_HOPS hops we drop
793 * it, not even processing it locally, if it has exact %IPX_MAX_PPROP_HOPS we
794 * don't broadcast it, but process it locally. See chapter 5 of Novell's "IPX
795 * RIP and SAP Router Specification", Part Number 107-000029-001.
796 *
797 * If it is valid, check if we have pprop broadcasting enabled by the user,
798 * if not, just return zero for local processing.
799 *
800 * If it is enabled check the packet and don't broadcast it if we have already
801 * seen this packet.
802 *
803 * Broadcast: send it to the interfaces that aren't on the packet visited nets
804 * array, just after the IPX header.
805 *
806 * Returns -EINVAL for invalid packets, so that the calling function drops
807 * the packet without local processing. 0 if packet is to be locally processed.
808 */
809static int ipxitf_pprop(struct ipx_interface *intrfc, struct sk_buff *skb)
810{
811 struct ipxhdr *ipx = ipx_hdr(skb);
812 int i, rc = -EINVAL;
813 struct ipx_interface *ifcs;
814 char *c;
815 u32 *l;
816
817 /* Illegal packet - too many hops or too short */
818 /* We decide to throw it away: no broadcasting, no local processing.
819 * NetBIOS unaware implementations route them as normal packets -
820 * tctrl <= 15, any data payload... */
821 if (IPX_SKB_CB(skb)->ipx_tctrl > IPX_MAX_PPROP_HOPS ||
822 ntohs(ipx->ipx_pktsize) < sizeof(struct ipxhdr) +
823 IPX_MAX_PPROP_HOPS * sizeof(u32))
824 goto out;
825 /* are we broadcasting this damn thing? */
826 rc = 0;
827 if (!sysctl_ipx_pprop_broadcasting)
828 goto out;
829 /* We do broadcast packet on the IPX_MAX_PPROP_HOPS hop, but we
830 * process it locally. All previous hops broadcasted it, and process it
831 * locally. */
832 if (IPX_SKB_CB(skb)->ipx_tctrl == IPX_MAX_PPROP_HOPS)
833 goto out;
834
835 c = ((u8 *) ipx) + sizeof(struct ipxhdr);
836 l = (u32 *) c;
837
838 /* Don't broadcast packet if already seen this net */
839 for (i = 0; i < IPX_SKB_CB(skb)->ipx_tctrl; i++)
840 if (*l++ == intrfc->if_netnum)
841 goto out;
842
843 /* < IPX_MAX_PPROP_HOPS hops && input interface not in list. Save the
844 * position where we will insert recvd netnum into list, later on,
845 * in ipxitf_send */
846 IPX_SKB_CB(skb)->last_hop.index = i;
847 IPX_SKB_CB(skb)->last_hop.netnum = intrfc->if_netnum;
848 /* xmit on all other interfaces... */
849 spin_lock_bh(&ipx_interfaces_lock);
850 list_for_each_entry(ifcs, &ipx_interfaces, node) {
851 /* Except unconfigured interfaces */
852 if (!ifcs->if_netnum)
853 continue;
854
855 /* That aren't in the list */
856 if (ifcs == intrfc)
857 continue;
858 l = (__u32 *) c;
859 /* don't consider the last entry in the packet list,
860 * it is our netnum, and it is not there yet */
861 for (i = 0; i < IPX_SKB_CB(skb)->ipx_tctrl; i++)
862 if (ifcs->if_netnum == *l++)
863 break;
864 if (i == IPX_SKB_CB(skb)->ipx_tctrl) {
865 struct sk_buff *s = skb_copy(skb, GFP_ATOMIC);
866
867 if (s) {
868 IPX_SKB_CB(s)->ipx_dest_net = ifcs->if_netnum;
869 ipxrtr_route_skb(s);
870 }
871 }
872 }
873 spin_unlock_bh(&ipx_interfaces_lock);
874out:
875 return rc;
876}
877
878static void ipxitf_insert(struct ipx_interface *intrfc)
879{
880 spin_lock_bh(&ipx_interfaces_lock);
881 list_add_tail(&intrfc->node, &ipx_interfaces);
882 spin_unlock_bh(&ipx_interfaces_lock);
883
884 if (ipxcfg_auto_select_primary && !ipx_primary_net)
885 ipx_primary_net = intrfc;
886}
887
888static struct ipx_interface *ipxitf_alloc(struct net_device *dev, __u32 netnum,
889 unsigned short dlink_type,
890 struct datalink_proto *dlink,
891 unsigned char internal,
892 int ipx_offset)
893{
894 struct ipx_interface *intrfc = kmalloc(sizeof(*intrfc), GFP_ATOMIC);
895
896 if (intrfc) {
897 intrfc->if_dev = dev;
898 intrfc->if_netnum = netnum;
899 intrfc->if_dlink_type = dlink_type;
900 intrfc->if_dlink = dlink;
901 intrfc->if_internal = internal;
902 intrfc->if_ipx_offset = ipx_offset;
903 intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET;
904 INIT_HLIST_HEAD(&intrfc->if_sklist);
905 atomic_set(&intrfc->refcnt, 1);
906 spin_lock_init(&intrfc->if_sklist_lock);
907 }
908
909 return intrfc;
910}
911
912static int ipxitf_create_internal(struct ipx_interface_definition *idef)
913{
914 struct ipx_interface *intrfc;
915 int rc = -EEXIST;
916
917 /* Only one primary network allowed */
918 if (ipx_primary_net)
919 goto out;
920
921 /* Must have a valid network number */
922 rc = -EADDRNOTAVAIL;
923 if (!idef->ipx_network)
924 goto out;
925 intrfc = ipxitf_find_using_net(idef->ipx_network);
926 rc = -EADDRINUSE;
927 if (intrfc) {
928 ipxitf_put(intrfc);
929 goto out;
930 }
931 intrfc = ipxitf_alloc(NULL, idef->ipx_network, 0, NULL, 1, 0);
932 rc = -EAGAIN;
933 if (!intrfc)
934 goto out;
935 memcpy((char *)&(intrfc->if_node), idef->ipx_node, IPX_NODE_LEN);
936 ipx_internal_net = ipx_primary_net = intrfc;
937 ipxitf_hold(intrfc);
938 ipxitf_insert(intrfc);
939
940 rc = ipxitf_add_local_route(intrfc);
941 ipxitf_put(intrfc);
942out:
943 return rc;
944}
945
946static int ipx_map_frame_type(unsigned char type)
947{
948 int rc = 0;
949
950 switch (type) {
951 case IPX_FRAME_ETHERII: rc = htons(ETH_P_IPX); break;
952 case IPX_FRAME_8022: rc = htons(ETH_P_802_2); break;
953 case IPX_FRAME_SNAP: rc = htons(ETH_P_SNAP); break;
954 case IPX_FRAME_8023: rc = htons(ETH_P_802_3); break;
955 }
956
957 return rc;
958}
959
960static int ipxitf_create(struct ipx_interface_definition *idef)
961{
962 struct net_device *dev;
963 unsigned short dlink_type = 0;
964 struct datalink_proto *datalink = NULL;
965 struct ipx_interface *intrfc;
966 int rc;
967
968 if (idef->ipx_special == IPX_INTERNAL) {
969 rc = ipxitf_create_internal(idef);
970 goto out;
971 }
972
973 rc = -EEXIST;
974 if (idef->ipx_special == IPX_PRIMARY && ipx_primary_net)
975 goto out;
976
977 intrfc = ipxitf_find_using_net(idef->ipx_network);
978 rc = -EADDRINUSE;
979 if (idef->ipx_network && intrfc) {
980 ipxitf_put(intrfc);
981 goto out;
982 }
983
984 if (intrfc)
985 ipxitf_put(intrfc);
986
987 dev = dev_get_by_name(idef->ipx_device);
988 rc = -ENODEV;
989 if (!dev)
990 goto out;
991
992 switch (idef->ipx_dlink_type) {
993 case IPX_FRAME_TR_8022:
994 printk(KERN_WARNING "IPX frame type 802.2TR is "
995 "obsolete Use 802.2 instead.\n");
996 /* fall through */
997 case IPX_FRAME_8022:
998 dlink_type = htons(ETH_P_802_2);
999 datalink = p8022_datalink;
1000 break;
1001 case IPX_FRAME_ETHERII:
1002 if (dev->type != ARPHRD_IEEE802) {
1003 dlink_type = htons(ETH_P_IPX);
1004 datalink = pEII_datalink;
1005 break;
1006 } else
1007 printk(KERN_WARNING "IPX frame type EtherII over "
1008 "token-ring is obsolete. Use SNAP "
1009 "instead.\n");
1010 /* fall through */
1011 case IPX_FRAME_SNAP:
1012 dlink_type = htons(ETH_P_SNAP);
1013 datalink = pSNAP_datalink;
1014 break;
1015 case IPX_FRAME_8023:
1016 dlink_type = htons(ETH_P_802_3);
1017 datalink = p8023_datalink;
1018 break;
1019 case IPX_FRAME_NONE:
1020 default:
1021 rc = -EPROTONOSUPPORT;
1022 goto out_dev;
1023 }
1024
1025 rc = -ENETDOWN;
1026 if (!(dev->flags & IFF_UP))
1027 goto out_dev;
1028
1029 /* Check addresses are suitable */
1030 rc = -EINVAL;
1031 if (dev->addr_len > IPX_NODE_LEN)
1032 goto out_dev;
1033
1034 intrfc = ipxitf_find_using_phys(dev, dlink_type);
1035 if (!intrfc) {
1036 /* Ok now create */
1037 intrfc = ipxitf_alloc(dev, idef->ipx_network, dlink_type,
1038 datalink, 0, dev->hard_header_len +
1039 datalink->header_length);
1040 rc = -EAGAIN;
1041 if (!intrfc)
1042 goto out_dev;
1043 /* Setup primary if necessary */
1044 if (idef->ipx_special == IPX_PRIMARY)
1045 ipx_primary_net = intrfc;
1046 if (!memcmp(idef->ipx_node, "\000\000\000\000\000\000",
1047 IPX_NODE_LEN)) {
1048 memset(intrfc->if_node, 0, IPX_NODE_LEN);
1049 memcpy(intrfc->if_node + IPX_NODE_LEN - dev->addr_len,
1050 dev->dev_addr, dev->addr_len);
1051 } else
1052 memcpy(intrfc->if_node, idef->ipx_node, IPX_NODE_LEN);
1053 ipxitf_hold(intrfc);
1054 ipxitf_insert(intrfc);
1055 }
1056
1057
1058 /* If the network number is known, add a route */
1059 rc = 0;
1060 if (!intrfc->if_netnum)
1061 goto out_intrfc;
1062
1063 rc = ipxitf_add_local_route(intrfc);
1064out_intrfc:
1065 ipxitf_put(intrfc);
1066 goto out;
1067out_dev:
1068 dev_put(dev);
1069out:
1070 return rc;
1071}
1072
1073static int ipxitf_delete(struct ipx_interface_definition *idef)
1074{
1075 struct net_device *dev = NULL;
1076 unsigned short dlink_type = 0;
1077 struct ipx_interface *intrfc;
1078 int rc = 0;
1079
1080 spin_lock_bh(&ipx_interfaces_lock);
1081 if (idef->ipx_special == IPX_INTERNAL) {
1082 if (ipx_internal_net) {
1083 __ipxitf_put(ipx_internal_net);
1084 goto out;
1085 }
1086 rc = -ENOENT;
1087 goto out;
1088 }
1089
1090 dlink_type = ipx_map_frame_type(idef->ipx_dlink_type);
1091 rc = -EPROTONOSUPPORT;
1092 if (!dlink_type)
1093 goto out;
1094
1095 dev = __dev_get_by_name(idef->ipx_device);
1096 rc = -ENODEV;
1097 if (!dev)
1098 goto out;
1099
1100 intrfc = __ipxitf_find_using_phys(dev, dlink_type);
1101 rc = -EINVAL;
1102 if (!intrfc)
1103 goto out;
1104 __ipxitf_put(intrfc);
1105
1106 rc = 0;
1107out:
1108 spin_unlock_bh(&ipx_interfaces_lock);
1109 return rc;
1110}
1111
1112static struct ipx_interface *ipxitf_auto_create(struct net_device *dev,
1113 unsigned short dlink_type)
1114{
1115 struct ipx_interface *intrfc = NULL;
1116 struct datalink_proto *datalink;
1117
1118 if (!dev)
1119 goto out;
1120
1121 /* Check addresses are suitable */
1122 if (dev->addr_len > IPX_NODE_LEN)
1123 goto out;
1124
1125 switch (htons(dlink_type)) {
1126 case ETH_P_IPX: datalink = pEII_datalink; break;
1127 case ETH_P_802_2: datalink = p8022_datalink; break;
1128 case ETH_P_SNAP: datalink = pSNAP_datalink; break;
1129 case ETH_P_802_3: datalink = p8023_datalink; break;
1130 default: goto out;
1131 }
1132
1133 intrfc = ipxitf_alloc(dev, 0, dlink_type, datalink, 0,
1134 dev->hard_header_len + datalink->header_length);
1135
1136 if (intrfc) {
1137 memset(intrfc->if_node, 0, IPX_NODE_LEN);
1138 memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]),
1139 dev->dev_addr, dev->addr_len);
1140 spin_lock_init(&intrfc->if_sklist_lock);
1141 atomic_set(&intrfc->refcnt, 1);
1142 ipxitf_insert(intrfc);
1143 dev_hold(dev);
1144 }
1145
1146out:
1147 return intrfc;
1148}
1149
1150static int ipxitf_ioctl(unsigned int cmd, void __user *arg)
1151{
1152 int rc = -EINVAL;
1153 struct ifreq ifr;
1154 int val;
1155
1156 switch (cmd) {
1157 case SIOCSIFADDR: {
1158 struct sockaddr_ipx *sipx;
1159 struct ipx_interface_definition f;
1160
1161 rc = -EFAULT;
1162 if (copy_from_user(&ifr, arg, sizeof(ifr)))
1163 break;
1164 sipx = (struct sockaddr_ipx *)&ifr.ifr_addr;
1165 rc = -EINVAL;
1166 if (sipx->sipx_family != AF_IPX)
1167 break;
1168 f.ipx_network = sipx->sipx_network;
1169 memcpy(f.ipx_device, ifr.ifr_name,
1170 sizeof(f.ipx_device));
1171 memcpy(f.ipx_node, sipx->sipx_node, IPX_NODE_LEN);
1172 f.ipx_dlink_type = sipx->sipx_type;
1173 f.ipx_special = sipx->sipx_special;
1174
1175 if (sipx->sipx_action == IPX_DLTITF)
1176 rc = ipxitf_delete(&f);
1177 else
1178 rc = ipxitf_create(&f);
1179 break;
1180 }
1181 case SIOCGIFADDR: {
1182 struct sockaddr_ipx *sipx;
1183 struct ipx_interface *ipxif;
1184 struct net_device *dev;
1185
1186 rc = -EFAULT;
1187 if (copy_from_user(&ifr, arg, sizeof(ifr)))
1188 break;
1189 sipx = (struct sockaddr_ipx *)&ifr.ifr_addr;
1190 dev = __dev_get_by_name(ifr.ifr_name);
1191 rc = -ENODEV;
1192 if (!dev)
1193 break;
1194 ipxif = ipxitf_find_using_phys(dev,
1195 ipx_map_frame_type(sipx->sipx_type));
1196 rc = -EADDRNOTAVAIL;
1197 if (!ipxif)
1198 break;
1199
1200 sipx->sipx_family = AF_IPX;
1201 sipx->sipx_network = ipxif->if_netnum;
1202 memcpy(sipx->sipx_node, ipxif->if_node,
1203 sizeof(sipx->sipx_node));
1204 rc = -EFAULT;
1205 if (copy_to_user(arg, &ifr, sizeof(ifr)))
1206 break;
1207 ipxitf_put(ipxif);
1208 rc = 0;
1209 break;
1210 }
1211 case SIOCAIPXITFCRT:
1212 rc = -EFAULT;
1213 if (get_user(val, (unsigned char __user *) arg))
1214 break;
1215 rc = 0;
1216 ipxcfg_auto_create_interfaces = val;
1217 break;
1218 case SIOCAIPXPRISLT:
1219 rc = -EFAULT;
1220 if (get_user(val, (unsigned char __user *) arg))
1221 break;
1222 rc = 0;
1223 ipxcfg_set_auto_select(val);
1224 break;
1225 }
1226
1227 return rc;
1228}
1229
1230/*
1231 * Checksum routine for IPX
1232 */
1233
1234/* Note: We assume ipx_tctrl==0 and htons(length)==ipx_pktsize */
1235/* This functions should *not* mess with packet contents */
1236
1237__u16 ipx_cksum(struct ipxhdr *packet, int length)
1238{
1239 /*
1240 * NOTE: sum is a net byte order quantity, which optimizes the
1241 * loop. This only works on big and little endian machines. (I
1242 * don't know of a machine that isn't.)
1243 */
1244 /* start at ipx_dest - We skip the checksum field and start with
1245 * ipx_type before the loop, not considering ipx_tctrl in the calc */
1246 __u16 *p = (__u16 *)&packet->ipx_dest;
1247 __u32 i = (length >> 1) - 1; /* Number of complete words */
1248 __u32 sum = packet->ipx_type << sizeof(packet->ipx_tctrl);
1249
1250 /* Loop through all complete words except the checksum field,
1251 * ipx_type (accounted above) and ipx_tctrl (not used in the cksum) */
1252 while (--i)
1253 sum += *p++;
1254
1255 /* Add on the last part word if it exists */
1256 if (packet->ipx_pktsize & htons(1))
1257 sum += ntohs(0xff00) & *p;
1258
1259 /* Do final fixup */
1260 sum = (sum & 0xffff) + (sum >> 16);
1261
1262 /* It's a pity there's no concept of carry in C */
1263 if (sum >= 0x10000)
1264 sum++;
1265
1266 return ~sum;
1267}
1268
1269const char *ipx_frame_name(unsigned short frame)
1270{
1271 char* rc = "None";
1272
1273 switch (ntohs(frame)) {
1274 case ETH_P_IPX: rc = "EtherII"; break;
1275 case ETH_P_802_2: rc = "802.2"; break;
1276 case ETH_P_SNAP: rc = "SNAP"; break;
1277 case ETH_P_802_3: rc = "802.3"; break;
1278 case ETH_P_TR_802_2: rc = "802.2TR"; break;
1279 }
1280
1281 return rc;
1282}
1283
1284const char *ipx_device_name(struct ipx_interface *intrfc)
1285{
1286 return intrfc->if_internal ? "Internal" :
1287 intrfc->if_dev ? intrfc->if_dev->name : "Unknown";
1288}
1289
1290/* Handling for system calls applied via the various interfaces to an IPX
1291 * socket object. */
1292
1293static int ipx_setsockopt(struct socket *sock, int level, int optname,
1294 char __user *optval, int optlen)
1295{
1296 struct sock *sk = sock->sk;
1297 int opt;
1298 int rc = -EINVAL;
1299
1300 if (optlen != sizeof(int))
1301 goto out;
1302
1303 rc = -EFAULT;
1304 if (get_user(opt, (unsigned int __user *)optval))
1305 goto out;
1306
1307 rc = -ENOPROTOOPT;
1308 if (!(level == SOL_IPX && optname == IPX_TYPE))
1309 goto out;
1310
1311 ipx_sk(sk)->type = opt;
1312 rc = 0;
1313out:
1314 return rc;
1315}
1316
1317static int ipx_getsockopt(struct socket *sock, int level, int optname,
1318 char __user *optval, int __user *optlen)
1319{
1320 struct sock *sk = sock->sk;
1321 int val = 0;
1322 int len;
1323 int rc = -ENOPROTOOPT;
1324
1325 if (!(level == SOL_IPX && optname == IPX_TYPE))
1326 goto out;
1327
1328 val = ipx_sk(sk)->type;
1329
1330 rc = -EFAULT;
1331 if (get_user(len, optlen))
1332 goto out;
1333
1334 len = min_t(unsigned int, len, sizeof(int));
1335 rc = -EINVAL;
1336 if(len < 0)
1337 goto out;
1338
1339 rc = -EFAULT;
1340 if (put_user(len, optlen) || copy_to_user(optval, &val, len))
1341 goto out;
1342
1343 rc = 0;
1344out:
1345 return rc;
1346}
1347
1348static struct proto ipx_proto = {
1349 .name = "IPX",
1350 .owner = THIS_MODULE,
1351 .obj_size = sizeof(struct ipx_sock),
1352};
1353
1354static int ipx_create(struct socket *sock, int protocol)
1355{
1356 int rc = -ESOCKTNOSUPPORT;
1357 struct sock *sk;
1358
1359 /*
1360 * SPX support is not anymore in the kernel sources. If you want to
1361 * ressurrect it, completing it and making it understand shared skbs,
1362 * be fully multithreaded, etc, grab the sources in an early 2.5 kernel
1363 * tree.
1364 */
1365 if (sock->type != SOCK_DGRAM)
1366 goto out;
1367
1368 rc = -ENOMEM;
1369 sk = sk_alloc(PF_IPX, GFP_KERNEL, &ipx_proto, 1);
1370 if (!sk)
1371 goto out;
1372#ifdef IPX_REFCNT_DEBUG
1373 atomic_inc(&ipx_sock_nr);
1374 printk(KERN_DEBUG "IPX socket %p created, now we have %d alive\n", sk,
1375 atomic_read(&ipx_sock_nr));
1376#endif
1377 sock_init_data(sock, sk);
1378 sk->sk_no_check = 1; /* Checksum off by default */
1379 sock->ops = &ipx_dgram_ops;
1380 rc = 0;
1381out:
1382 return rc;
1383}
1384
1385static int ipx_release(struct socket *sock)
1386{
1387 struct sock *sk = sock->sk;
1388
1389 if (!sk)
1390 goto out;
1391
1392 if (!sock_flag(sk, SOCK_DEAD))
1393 sk->sk_state_change(sk);
1394
1395 sock_set_flag(sk, SOCK_DEAD);
1396 sock->sk = NULL;
1397 ipx_destroy_socket(sk);
1398out:
1399 return 0;
1400}
1401
1402/* caller must hold a reference to intrfc */
1403
1404static unsigned short ipx_first_free_socketnum(struct ipx_interface *intrfc)
1405{
1406 unsigned short socketNum = intrfc->if_sknum;
1407
1408 spin_lock_bh(&intrfc->if_sklist_lock);
1409
1410 if (socketNum < IPX_MIN_EPHEMERAL_SOCKET)
1411 socketNum = IPX_MIN_EPHEMERAL_SOCKET;
1412
1413 while (__ipxitf_find_socket(intrfc, ntohs(socketNum)))
1414 if (socketNum > IPX_MAX_EPHEMERAL_SOCKET)
1415 socketNum = IPX_MIN_EPHEMERAL_SOCKET;
1416 else
1417 socketNum++;
1418
1419 spin_unlock_bh(&intrfc->if_sklist_lock);
1420 intrfc->if_sknum = socketNum;
1421
1422 return ntohs(socketNum);
1423}
1424
1425static int ipx_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
1426{
1427 struct sock *sk = sock->sk;
1428 struct ipx_sock *ipxs = ipx_sk(sk);
1429 struct ipx_interface *intrfc;
1430 struct sockaddr_ipx *addr = (struct sockaddr_ipx *)uaddr;
1431 int rc = -EINVAL;
1432
1433 if (!sock_flag(sk, SOCK_ZAPPED) || addr_len != sizeof(struct sockaddr_ipx))
1434 goto out;
1435
1436 intrfc = ipxitf_find_using_net(addr->sipx_network);
1437 rc = -EADDRNOTAVAIL;
1438 if (!intrfc)
1439 goto out;
1440
1441 if (!addr->sipx_port) {
1442 addr->sipx_port = ipx_first_free_socketnum(intrfc);
1443 rc = -EINVAL;
1444 if (!addr->sipx_port)
1445 goto out_put;
1446 }
1447
1448 /* protect IPX system stuff like routing/sap */
1449 rc = -EACCES;
1450 if (ntohs(addr->sipx_port) < IPX_MIN_EPHEMERAL_SOCKET &&
1451 !capable(CAP_NET_ADMIN))
1452 goto out_put;
1453
1454 ipxs->port = addr->sipx_port;
1455
1456#ifdef CONFIG_IPX_INTERN
1457 if (intrfc == ipx_internal_net) {
1458 /* The source address is to be set explicitly if the
1459 * socket is to be bound on the internal network. If a
1460 * node number 0 was specified, the default is used.
1461 */
1462
1463 rc = -EINVAL;
1464 if (!memcmp(addr->sipx_node, ipx_broadcast_node, IPX_NODE_LEN))
1465 goto out_put;
1466 if (!memcmp(addr->sipx_node, ipx_this_node, IPX_NODE_LEN))
1467 memcpy(ipxs->node, intrfc->if_node, IPX_NODE_LEN);
1468 else
1469 memcpy(ipxs->node, addr->sipx_node, IPX_NODE_LEN);
1470
1471 rc = -EADDRINUSE;
1472 if (ipxitf_find_internal_socket(intrfc, ipxs->node,
1473 ipxs->port)) {
1474 SOCK_DEBUG(sk,
1475 "IPX: bind failed because port %X in use.\n",
1476 ntohs((int)addr->sipx_port));
1477 goto out_put;
1478 }
1479 } else {
1480 /* Source addresses are easy. It must be our
1481 * network:node pair for an interface routed to IPX
1482 * with the ipx routing ioctl()
1483 */
1484
1485 memcpy(ipxs->node, intrfc->if_node, IPX_NODE_LEN);
1486
1487 rc = -EADDRINUSE;
1488 if (ipxitf_find_socket(intrfc, addr->sipx_port)) {
1489 SOCK_DEBUG(sk,
1490 "IPX: bind failed because port %X in use.\n",
1491 ntohs((int)addr->sipx_port));
1492 goto out_put;
1493 }
1494 }
1495
1496#else /* !def CONFIG_IPX_INTERN */
1497
1498 /* Source addresses are easy. It must be our network:node pair for
1499 an interface routed to IPX with the ipx routing ioctl() */
1500
1501 rc = -EADDRINUSE;
1502 if (ipxitf_find_socket(intrfc, addr->sipx_port)) {
1503 SOCK_DEBUG(sk, "IPX: bind failed because port %X in use.\n",
1504 ntohs((int)addr->sipx_port));
1505 goto out_put;
1506 }
1507
1508#endif /* CONFIG_IPX_INTERN */
1509
1510 ipxitf_insert_socket(intrfc, sk);
1511 sock_reset_flag(sk, SOCK_ZAPPED);
1512
1513 rc = 0;
1514out_put:
1515 ipxitf_put(intrfc);
1516out:
1517 return rc;
1518}
1519
1520static int ipx_connect(struct socket *sock, struct sockaddr *uaddr,
1521 int addr_len, int flags)
1522{
1523 struct sock *sk = sock->sk;
1524 struct ipx_sock *ipxs = ipx_sk(sk);
1525 struct sockaddr_ipx *addr;
1526 int rc = -EINVAL;
1527 struct ipx_route *rt;
1528
1529 sk->sk_state = TCP_CLOSE;
1530 sock->state = SS_UNCONNECTED;
1531
1532 if (addr_len != sizeof(*addr))
1533 goto out;
1534 addr = (struct sockaddr_ipx *)uaddr;
1535
1536 /* put the autobinding in */
1537 if (!ipxs->port) {
1538 struct sockaddr_ipx uaddr;
1539
1540 uaddr.sipx_port = 0;
1541 uaddr.sipx_network = 0;
1542
1543#ifdef CONFIG_IPX_INTERN
1544 rc = -ENETDOWN;
1545 if (!ipxs->intrfc)
1546 goto out; /* Someone zonked the iface */
1547 memcpy(uaddr.sipx_node, ipxs->intrfc->if_node,
1548 IPX_NODE_LEN);
1549#endif /* CONFIG_IPX_INTERN */
1550
1551 rc = ipx_bind(sock, (struct sockaddr *)&uaddr,
1552 sizeof(struct sockaddr_ipx));
1553 if (rc)
1554 goto out;
1555 }
1556
1557 /* We can either connect to primary network or somewhere
1558 * we can route to */
1559 rt = ipxrtr_lookup(addr->sipx_network);
1560 rc = -ENETUNREACH;
1561 if (!rt && !(!addr->sipx_network && ipx_primary_net))
1562 goto out;
1563
1564 ipxs->dest_addr.net = addr->sipx_network;
1565 ipxs->dest_addr.sock = addr->sipx_port;
1566 memcpy(ipxs->dest_addr.node, addr->sipx_node, IPX_NODE_LEN);
1567 ipxs->type = addr->sipx_type;
1568
1569 if (sock->type == SOCK_DGRAM) {
1570 sock->state = SS_CONNECTED;
1571 sk->sk_state = TCP_ESTABLISHED;
1572 }
1573
1574 if (rt)
1575 ipxrtr_put(rt);
1576 rc = 0;
1577out:
1578 return rc;
1579}
1580
1581
1582static int ipx_getname(struct socket *sock, struct sockaddr *uaddr,
1583 int *uaddr_len, int peer)
1584{
1585 struct ipx_address *addr;
1586 struct sockaddr_ipx sipx;
1587 struct sock *sk = sock->sk;
1588 struct ipx_sock *ipxs = ipx_sk(sk);
1589 int rc;
1590
1591 *uaddr_len = sizeof(struct sockaddr_ipx);
1592
1593 if (peer) {
1594 rc = -ENOTCONN;
1595 if (sk->sk_state != TCP_ESTABLISHED)
1596 goto out;
1597
1598 addr = &ipxs->dest_addr;
1599 sipx.sipx_network = addr->net;
1600 sipx.sipx_port = addr->sock;
1601 memcpy(sipx.sipx_node, addr->node, IPX_NODE_LEN);
1602 } else {
1603 if (ipxs->intrfc) {
1604 sipx.sipx_network = ipxs->intrfc->if_netnum;
1605#ifdef CONFIG_IPX_INTERN
1606 memcpy(sipx.sipx_node, ipxs->node, IPX_NODE_LEN);
1607#else
1608 memcpy(sipx.sipx_node, ipxs->intrfc->if_node,
1609 IPX_NODE_LEN);
1610#endif /* CONFIG_IPX_INTERN */
1611
1612 } else {
1613 sipx.sipx_network = 0;
1614 memset(sipx.sipx_node, '\0', IPX_NODE_LEN);
1615 }
1616
1617 sipx.sipx_port = ipxs->port;
1618 }
1619
1620 sipx.sipx_family = AF_IPX;
1621 sipx.sipx_type = ipxs->type;
1622 sipx.sipx_zero = 0;
1623 memcpy(uaddr, &sipx, sizeof(sipx));
1624
1625 rc = 0;
1626out:
1627 return rc;
1628}
1629
1630static int ipx_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
1631{
1632 /* NULL here for pt means the packet was looped back */
1633 struct ipx_interface *intrfc;
1634 struct ipxhdr *ipx;
1635 u16 ipx_pktsize;
1636 int rc = 0;
1637
1638 /* Not ours */
1639 if (skb->pkt_type == PACKET_OTHERHOST)
1640 goto drop;
1641
1642 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
1643 goto out;
1644
1645 ipx = ipx_hdr(skb);
1646 ipx_pktsize = ntohs(ipx->ipx_pktsize);
1647
1648 /* Too small or invalid header? */
1649 if (ipx_pktsize < sizeof(struct ipxhdr) || ipx_pktsize > skb->len)
1650 goto drop;
1651
1652 if (ipx->ipx_checksum != IPX_NO_CHECKSUM &&
1653 ipx->ipx_checksum != ipx_cksum(ipx, ipx_pktsize))
1654 goto drop;
1655
1656 IPX_SKB_CB(skb)->ipx_tctrl = ipx->ipx_tctrl;
1657 IPX_SKB_CB(skb)->ipx_dest_net = ipx->ipx_dest.net;
1658 IPX_SKB_CB(skb)->ipx_source_net = ipx->ipx_source.net;
1659
1660 /* Determine what local ipx endpoint this is */
1661 intrfc = ipxitf_find_using_phys(dev, pt->type);
1662 if (!intrfc) {
1663 if (ipxcfg_auto_create_interfaces &&
1664 ntohl(IPX_SKB_CB(skb)->ipx_dest_net)) {
1665 intrfc = ipxitf_auto_create(dev, pt->type);
1666 if (intrfc)
1667 ipxitf_hold(intrfc);
1668 }
1669
1670 if (!intrfc) /* Not one of ours */
1671 /* or invalid packet for auto creation */
1672 goto drop;
1673 }
1674
1675 rc = ipxitf_rcv(intrfc, skb);
1676 ipxitf_put(intrfc);
1677 goto out;
1678drop:
1679 kfree_skb(skb);
1680out:
1681 return rc;
1682}
1683
1684static int ipx_sendmsg(struct kiocb *iocb, struct socket *sock,
1685 struct msghdr *msg, size_t len)
1686{
1687 struct sock *sk = sock->sk;
1688 struct ipx_sock *ipxs = ipx_sk(sk);
1689 struct sockaddr_ipx *usipx = (struct sockaddr_ipx *)msg->msg_name;
1690 struct sockaddr_ipx local_sipx;
1691 int rc = -EINVAL;
1692 int flags = msg->msg_flags;
1693
1694 /* Socket gets bound below anyway */
1695/* if (sk->sk_zapped)
1696 return -EIO; */ /* Socket not bound */
1697 if (flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
1698 goto out;
1699
1700 /* Max possible packet size limited by 16 bit pktsize in header */
1701 if (len >= 65535 - sizeof(struct ipxhdr))
1702 goto out;
1703
1704 if (usipx) {
1705 if (!ipxs->port) {
1706 struct sockaddr_ipx uaddr;
1707
1708 uaddr.sipx_port = 0;
1709 uaddr.sipx_network = 0;
1710#ifdef CONFIG_IPX_INTERN
1711 rc = -ENETDOWN;
1712 if (!ipxs->intrfc)
1713 goto out; /* Someone zonked the iface */
1714 memcpy(uaddr.sipx_node, ipxs->intrfc->if_node,
1715 IPX_NODE_LEN);
1716#endif
1717 rc = ipx_bind(sock, (struct sockaddr *)&uaddr,
1718 sizeof(struct sockaddr_ipx));
1719 if (rc)
1720 goto out;
1721 }
1722
1723 rc = -EINVAL;
1724 if (msg->msg_namelen < sizeof(*usipx) ||
1725 usipx->sipx_family != AF_IPX)
1726 goto out;
1727 } else {
1728 rc = -ENOTCONN;
1729 if (sk->sk_state != TCP_ESTABLISHED)
1730 goto out;
1731
1732 usipx = &local_sipx;
1733 usipx->sipx_family = AF_IPX;
1734 usipx->sipx_type = ipxs->type;
1735 usipx->sipx_port = ipxs->dest_addr.sock;
1736 usipx->sipx_network = ipxs->dest_addr.net;
1737 memcpy(usipx->sipx_node, ipxs->dest_addr.node, IPX_NODE_LEN);
1738 }
1739
1740 rc = ipxrtr_route_packet(sk, usipx, msg->msg_iov, len,
1741 flags & MSG_DONTWAIT);
1742 if (rc >= 0)
1743 rc = len;
1744out:
1745 return rc;
1746}
1747
1748
1749static int ipx_recvmsg(struct kiocb *iocb, struct socket *sock,
1750 struct msghdr *msg, size_t size, int flags)
1751{
1752 struct sock *sk = sock->sk;
1753 struct ipx_sock *ipxs = ipx_sk(sk);
1754 struct sockaddr_ipx *sipx = (struct sockaddr_ipx *)msg->msg_name;
1755 struct ipxhdr *ipx = NULL;
1756 struct sk_buff *skb;
1757 int copied, rc;
1758
1759 /* put the autobinding in */
1760 if (!ipxs->port) {
1761 struct sockaddr_ipx uaddr;
1762
1763 uaddr.sipx_port = 0;
1764 uaddr.sipx_network = 0;
1765
1766#ifdef CONFIG_IPX_INTERN
1767 rc = -ENETDOWN;
1768 if (!ipxs->intrfc)
1769 goto out; /* Someone zonked the iface */
1770 memcpy(uaddr.sipx_node, ipxs->intrfc->if_node, IPX_NODE_LEN);
1771#endif /* CONFIG_IPX_INTERN */
1772
1773 rc = ipx_bind(sock, (struct sockaddr *)&uaddr,
1774 sizeof(struct sockaddr_ipx));
1775 if (rc)
1776 goto out;
1777 }
1778
1779 rc = -ENOTCONN;
1780 if (sock_flag(sk, SOCK_ZAPPED))
1781 goto out;
1782
1783 skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
1784 flags & MSG_DONTWAIT, &rc);
1785 if (!skb)
1786 goto out;
1787
1788 ipx = ipx_hdr(skb);
1789 copied = ntohs(ipx->ipx_pktsize) - sizeof(struct ipxhdr);
1790 if (copied > size) {
1791 copied = size;
1792 msg->msg_flags |= MSG_TRUNC;
1793 }
1794
1795 rc = skb_copy_datagram_iovec(skb, sizeof(struct ipxhdr), msg->msg_iov,
1796 copied);
1797 if (rc)
1798 goto out_free;
1799 if (skb->stamp.tv_sec)
1800 sk->sk_stamp = skb->stamp;
1801
1802 msg->msg_namelen = sizeof(*sipx);
1803
1804 if (sipx) {
1805 sipx->sipx_family = AF_IPX;
1806 sipx->sipx_port = ipx->ipx_source.sock;
1807 memcpy(sipx->sipx_node, ipx->ipx_source.node, IPX_NODE_LEN);
1808 sipx->sipx_network = IPX_SKB_CB(skb)->ipx_source_net;
1809 sipx->sipx_type = ipx->ipx_type;
1810 sipx->sipx_zero = 0;
1811 }
1812 rc = copied;
1813
1814out_free:
1815 skb_free_datagram(sk, skb);
1816out:
1817 return rc;
1818}
1819
1820
1821static int ipx_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1822{
1823 int rc = 0;
1824 long amount = 0;
1825 struct sock *sk = sock->sk;
1826 void __user *argp = (void __user *)arg;
1827
1828 switch (cmd) {
1829 case TIOCOUTQ:
1830 amount = sk->sk_sndbuf - atomic_read(&sk->sk_wmem_alloc);
1831 if (amount < 0)
1832 amount = 0;
1833 rc = put_user(amount, (int __user *)argp);
1834 break;
1835 case TIOCINQ: {
1836 struct sk_buff *skb = skb_peek(&sk->sk_receive_queue);
1837 /* These two are safe on a single CPU system as only
1838 * user tasks fiddle here */
1839 if (skb)
1840 amount = skb->len - sizeof(struct ipxhdr);
1841 rc = put_user(amount, (int __user *)argp);
1842 break;
1843 }
1844 case SIOCADDRT:
1845 case SIOCDELRT:
1846 rc = -EPERM;
1847 if (capable(CAP_NET_ADMIN))
1848 rc = ipxrtr_ioctl(cmd, argp);
1849 break;
1850 case SIOCSIFADDR:
1851 case SIOCAIPXITFCRT:
1852 case SIOCAIPXPRISLT:
1853 rc = -EPERM;
1854 if (!capable(CAP_NET_ADMIN))
1855 break;
1856 case SIOCGIFADDR:
1857 rc = ipxitf_ioctl(cmd, argp);
1858 break;
1859 case SIOCIPXCFGDATA:
1860 rc = ipxcfg_get_config_data(argp);
1861 break;
1862 case SIOCIPXNCPCONN:
1863 /*
1864 * This socket wants to take care of the NCP connection
1865 * handed to us in arg.
1866 */
1867 rc = -EPERM;
1868 if (!capable(CAP_NET_ADMIN))
1869 break;
1870 rc = get_user(ipx_sk(sk)->ipx_ncp_conn,
1871 (const unsigned short __user *)argp);
1872 break;
1873 case SIOCGSTAMP:
1874 rc = -EINVAL;
1875 if (sk)
1876 rc = sock_get_timestamp(sk, argp);
1877 break;
1878 case SIOCGIFDSTADDR:
1879 case SIOCSIFDSTADDR:
1880 case SIOCGIFBRDADDR:
1881 case SIOCSIFBRDADDR:
1882 case SIOCGIFNETMASK:
1883 case SIOCSIFNETMASK:
1884 rc = -EINVAL;
1885 break;
1886 default:
1887 rc = dev_ioctl(cmd, argp);
1888 break;
1889 }
1890
1891 return rc;
1892}
1893
1894/*
1895 * Socket family declarations
1896 */
1897
1898static struct net_proto_family ipx_family_ops = {
1899 .family = PF_IPX,
1900 .create = ipx_create,
1901 .owner = THIS_MODULE,
1902};
1903
1904static struct proto_ops SOCKOPS_WRAPPED(ipx_dgram_ops) = {
1905 .family = PF_IPX,
1906 .owner = THIS_MODULE,
1907 .release = ipx_release,
1908 .bind = ipx_bind,
1909 .connect = ipx_connect,
1910 .socketpair = sock_no_socketpair,
1911 .accept = sock_no_accept,
1912 .getname = ipx_getname,
1913 .poll = datagram_poll,
1914 .ioctl = ipx_ioctl,
1915 .listen = sock_no_listen,
1916 .shutdown = sock_no_shutdown, /* FIXME: support shutdown */
1917 .setsockopt = ipx_setsockopt,
1918 .getsockopt = ipx_getsockopt,
1919 .sendmsg = ipx_sendmsg,
1920 .recvmsg = ipx_recvmsg,
1921 .mmap = sock_no_mmap,
1922 .sendpage = sock_no_sendpage,
1923};
1924
1925#include <linux/smp_lock.h>
1926SOCKOPS_WRAP(ipx_dgram, PF_IPX);
1927
1928static struct packet_type ipx_8023_packet_type = {
1929 .type = __constant_htons(ETH_P_802_3),
1930 .func = ipx_rcv,
1931};
1932
1933static struct packet_type ipx_dix_packet_type = {
1934 .type = __constant_htons(ETH_P_IPX),
1935 .func = ipx_rcv,
1936};
1937
1938static struct notifier_block ipx_dev_notifier = {
1939 .notifier_call = ipxitf_device_event,
1940};
1941
1942extern struct datalink_proto *make_EII_client(void);
1943extern struct datalink_proto *make_8023_client(void);
1944extern void destroy_EII_client(struct datalink_proto *);
1945extern void destroy_8023_client(struct datalink_proto *);
1946
1947static unsigned char ipx_8022_type = 0xE0;
1948static unsigned char ipx_snap_id[5] = { 0x0, 0x0, 0x0, 0x81, 0x37 };
1949static char ipx_EII_err_msg[] __initdata =
1950 KERN_CRIT "IPX: Unable to register with Ethernet II\n";
1951static char ipx_8023_err_msg[] __initdata =
1952 KERN_CRIT "IPX: Unable to register with 802.3\n";
1953static char ipx_llc_err_msg[] __initdata =
1954 KERN_CRIT "IPX: Unable to register with 802.2\n";
1955static char ipx_snap_err_msg[] __initdata =
1956 KERN_CRIT "IPX: Unable to register with SNAP\n";
1957
1958static int __init ipx_init(void)
1959{
1960 int rc = proto_register(&ipx_proto, 1);
1961
1962 if (rc != 0)
1963 goto out;
1964
1965 sock_register(&ipx_family_ops);
1966
1967 pEII_datalink = make_EII_client();
1968 if (pEII_datalink)
1969 dev_add_pack(&ipx_dix_packet_type);
1970 else
1971 printk(ipx_EII_err_msg);
1972
1973 p8023_datalink = make_8023_client();
1974 if (p8023_datalink)
1975 dev_add_pack(&ipx_8023_packet_type);
1976 else
1977 printk(ipx_8023_err_msg);
1978
1979 p8022_datalink = register_8022_client(ipx_8022_type, ipx_rcv);
1980 if (!p8022_datalink)
1981 printk(ipx_llc_err_msg);
1982
1983 pSNAP_datalink = register_snap_client(ipx_snap_id, ipx_rcv);
1984 if (!pSNAP_datalink)
1985 printk(ipx_snap_err_msg);
1986
1987 register_netdevice_notifier(&ipx_dev_notifier);
1988 ipx_register_sysctl();
1989 ipx_proc_init();
1990out:
1991 return rc;
1992}
1993
1994static void __exit ipx_proto_finito(void)
1995{
1996 ipx_proc_exit();
1997 ipx_unregister_sysctl();
1998
1999 unregister_netdevice_notifier(&ipx_dev_notifier);
2000
2001 ipxitf_cleanup();
2002
2003 unregister_snap_client(pSNAP_datalink);
2004 pSNAP_datalink = NULL;
2005
2006 unregister_8022_client(p8022_datalink);
2007 p8022_datalink = NULL;
2008
2009 dev_remove_pack(&ipx_8023_packet_type);
2010 destroy_8023_client(p8023_datalink);
2011 p8023_datalink = NULL;
2012
2013 dev_remove_pack(&ipx_dix_packet_type);
2014 destroy_EII_client(pEII_datalink);
2015 pEII_datalink = NULL;
2016
2017 proto_unregister(&ipx_proto);
2018 sock_unregister(ipx_family_ops.family);
2019}
2020
2021module_init(ipx_init);
2022module_exit(ipx_proto_finito);
2023MODULE_LICENSE("GPL");
2024MODULE_ALIAS_NETPROTO(PF_IPX);
diff --git a/net/ipx/ipx_proc.c b/net/ipx/ipx_proc.c
new file mode 100644
index 000000000000..b6761913445a
--- /dev/null
+++ b/net/ipx/ipx_proc.c
@@ -0,0 +1,408 @@
1/*
2 * IPX proc routines
3 *
4 * Copyright(C) Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2002
5 */
6
7#include <linux/config.h>
8#include <linux/init.h>
9#ifdef CONFIG_PROC_FS
10#include <linux/proc_fs.h>
11#include <linux/spinlock.h>
12#include <linux/seq_file.h>
13#include <linux/tcp.h>
14#include <net/ipx.h>
15
16static __inline__ struct ipx_interface *ipx_get_interface_idx(loff_t pos)
17{
18 struct ipx_interface *i;
19
20 list_for_each_entry(i, &ipx_interfaces, node)
21 if (!pos--)
22 goto out;
23 i = NULL;
24out:
25 return i;
26}
27
28static struct ipx_interface *ipx_interfaces_next(struct ipx_interface *i)
29{
30 struct ipx_interface *rc = NULL;
31
32 if (i->node.next != &ipx_interfaces)
33 rc = list_entry(i->node.next, struct ipx_interface, node);
34 return rc;
35}
36
37static void *ipx_seq_interface_start(struct seq_file *seq, loff_t *pos)
38{
39 loff_t l = *pos;
40
41 spin_lock_bh(&ipx_interfaces_lock);
42 return l ? ipx_get_interface_idx(--l) : SEQ_START_TOKEN;
43}
44
45static void *ipx_seq_interface_next(struct seq_file *seq, void *v, loff_t *pos)
46{
47 struct ipx_interface *i;
48
49 ++*pos;
50 if (v == SEQ_START_TOKEN)
51 i = ipx_interfaces_head();
52 else
53 i = ipx_interfaces_next(v);
54 return i;
55}
56
57static void ipx_seq_interface_stop(struct seq_file *seq, void *v)
58{
59 spin_unlock_bh(&ipx_interfaces_lock);
60}
61
62static int ipx_seq_interface_show(struct seq_file *seq, void *v)
63{
64 struct ipx_interface *i;
65
66 if (v == SEQ_START_TOKEN) {
67 seq_puts(seq, "Network Node_Address Primary Device "
68 "Frame_Type");
69#ifdef IPX_REFCNT_DEBUG
70 seq_puts(seq, " refcnt");
71#endif
72 seq_puts(seq, "\n");
73 goto out;
74 }
75
76 i = v;
77 seq_printf(seq, "%08lX ", (unsigned long int)ntohl(i->if_netnum));
78 seq_printf(seq, "%02X%02X%02X%02X%02X%02X ",
79 i->if_node[0], i->if_node[1], i->if_node[2],
80 i->if_node[3], i->if_node[4], i->if_node[5]);
81 seq_printf(seq, "%-9s", i == ipx_primary_net ? "Yes" : "No");
82 seq_printf(seq, "%-11s", ipx_device_name(i));
83 seq_printf(seq, "%-9s", ipx_frame_name(i->if_dlink_type));
84#ifdef IPX_REFCNT_DEBUG
85 seq_printf(seq, "%6d", atomic_read(&i->refcnt));
86#endif
87 seq_puts(seq, "\n");
88out:
89 return 0;
90}
91
92static struct ipx_route *ipx_routes_head(void)
93{
94 struct ipx_route *rc = NULL;
95
96 if (!list_empty(&ipx_routes))
97 rc = list_entry(ipx_routes.next, struct ipx_route, node);
98 return rc;
99}
100
101static struct ipx_route *ipx_routes_next(struct ipx_route *r)
102{
103 struct ipx_route *rc = NULL;
104
105 if (r->node.next != &ipx_routes)
106 rc = list_entry(r->node.next, struct ipx_route, node);
107 return rc;
108}
109
110static __inline__ struct ipx_route *ipx_get_route_idx(loff_t pos)
111{
112 struct ipx_route *r;
113
114 list_for_each_entry(r, &ipx_routes, node)
115 if (!pos--)
116 goto out;
117 r = NULL;
118out:
119 return r;
120}
121
122static void *ipx_seq_route_start(struct seq_file *seq, loff_t *pos)
123{
124 loff_t l = *pos;
125 read_lock_bh(&ipx_routes_lock);
126 return l ? ipx_get_route_idx(--l) : SEQ_START_TOKEN;
127}
128
129static void *ipx_seq_route_next(struct seq_file *seq, void *v, loff_t *pos)
130{
131 struct ipx_route *r;
132
133 ++*pos;
134 if (v == SEQ_START_TOKEN)
135 r = ipx_routes_head();
136 else
137 r = ipx_routes_next(v);
138 return r;
139}
140
141static void ipx_seq_route_stop(struct seq_file *seq, void *v)
142{
143 read_unlock_bh(&ipx_routes_lock);
144}
145
146static int ipx_seq_route_show(struct seq_file *seq, void *v)
147{
148 struct ipx_route *rt;
149
150 if (v == SEQ_START_TOKEN) {
151 seq_puts(seq, "Network Router_Net Router_Node\n");
152 goto out;
153 }
154 rt = v;
155 seq_printf(seq, "%08lX ", (unsigned long int)ntohl(rt->ir_net));
156 if (rt->ir_routed)
157 seq_printf(seq, "%08lX %02X%02X%02X%02X%02X%02X\n",
158 (long unsigned int)ntohl(rt->ir_intrfc->if_netnum),
159 rt->ir_router_node[0], rt->ir_router_node[1],
160 rt->ir_router_node[2], rt->ir_router_node[3],
161 rt->ir_router_node[4], rt->ir_router_node[5]);
162 else
163 seq_puts(seq, "Directly Connected\n");
164out:
165 return 0;
166}
167
168static __inline__ struct sock *ipx_get_socket_idx(loff_t pos)
169{
170 struct sock *s = NULL;
171 struct hlist_node *node;
172 struct ipx_interface *i;
173
174 list_for_each_entry(i, &ipx_interfaces, node) {
175 spin_lock_bh(&i->if_sklist_lock);
176 sk_for_each(s, node, &i->if_sklist) {
177 if (!pos)
178 break;
179 --pos;
180 }
181 spin_unlock_bh(&i->if_sklist_lock);
182 if (!pos) {
183 if (node)
184 goto found;
185 break;
186 }
187 }
188 s = NULL;
189found:
190 return s;
191}
192
193static void *ipx_seq_socket_start(struct seq_file *seq, loff_t *pos)
194{
195 loff_t l = *pos;
196
197 spin_lock_bh(&ipx_interfaces_lock);
198 return l ? ipx_get_socket_idx(--l) : SEQ_START_TOKEN;
199}
200
201static void *ipx_seq_socket_next(struct seq_file *seq, void *v, loff_t *pos)
202{
203 struct sock* sk, *next;
204 struct ipx_interface *i;
205 struct ipx_sock *ipxs;
206
207 ++*pos;
208 if (v == SEQ_START_TOKEN) {
209 sk = NULL;
210 i = ipx_interfaces_head();
211 if (!i)
212 goto out;
213 sk = sk_head(&i->if_sklist);
214 if (sk)
215 spin_lock_bh(&i->if_sklist_lock);
216 goto out;
217 }
218 sk = v;
219 next = sk_next(sk);
220 if (next) {
221 sk = next;
222 goto out;
223 }
224 ipxs = ipx_sk(sk);
225 i = ipxs->intrfc;
226 spin_unlock_bh(&i->if_sklist_lock);
227 sk = NULL;
228 for (;;) {
229 i = ipx_interfaces_next(i);
230 if (!i)
231 break;
232 spin_lock_bh(&i->if_sklist_lock);
233 if (!hlist_empty(&i->if_sklist)) {
234 sk = sk_head(&i->if_sklist);
235 break;
236 }
237 spin_unlock_bh(&i->if_sklist_lock);
238 }
239out:
240 return sk;
241}
242
243static int ipx_seq_socket_show(struct seq_file *seq, void *v)
244{
245 struct sock *s;
246 struct ipx_sock *ipxs;
247
248 if (v == SEQ_START_TOKEN) {
249#ifdef CONFIG_IPX_INTERN
250 seq_puts(seq, "Local_Address "
251 "Remote_Address Tx_Queue "
252 "Rx_Queue State Uid\n");
253#else
254 seq_puts(seq, "Local_Address Remote_Address "
255 "Tx_Queue Rx_Queue State Uid\n");
256#endif
257 goto out;
258 }
259
260 s = v;
261 ipxs = ipx_sk(s);
262#ifdef CONFIG_IPX_INTERN
263 seq_printf(seq, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ",
264 (unsigned long)htonl(ipxs->intrfc->if_netnum),
265 ipxs->node[0], ipxs->node[1], ipxs->node[2], ipxs->node[3],
266 ipxs->node[4], ipxs->node[5], htons(ipxs->port));
267#else
268 seq_printf(seq, "%08lX:%04X ", (unsigned long) htonl(ipxs->intrfc->if_netnum),
269 htons(ipxs->port));
270#endif /* CONFIG_IPX_INTERN */
271 if (s->sk_state != TCP_ESTABLISHED)
272 seq_printf(seq, "%-28s", "Not_Connected");
273 else {
274 seq_printf(seq, "%08lX:%02X%02X%02X%02X%02X%02X:%04X ",
275 (unsigned long)htonl(ipxs->dest_addr.net),
276 ipxs->dest_addr.node[0], ipxs->dest_addr.node[1],
277 ipxs->dest_addr.node[2], ipxs->dest_addr.node[3],
278 ipxs->dest_addr.node[4], ipxs->dest_addr.node[5],
279 htons(ipxs->dest_addr.sock));
280 }
281
282 seq_printf(seq, "%08X %08X %02X %03d\n",
283 atomic_read(&s->sk_wmem_alloc),
284 atomic_read(&s->sk_rmem_alloc),
285 s->sk_state, SOCK_INODE(s->sk_socket)->i_uid);
286out:
287 return 0;
288}
289
290static struct seq_operations ipx_seq_interface_ops = {
291 .start = ipx_seq_interface_start,
292 .next = ipx_seq_interface_next,
293 .stop = ipx_seq_interface_stop,
294 .show = ipx_seq_interface_show,
295};
296
297static struct seq_operations ipx_seq_route_ops = {
298 .start = ipx_seq_route_start,
299 .next = ipx_seq_route_next,
300 .stop = ipx_seq_route_stop,
301 .show = ipx_seq_route_show,
302};
303
304static struct seq_operations ipx_seq_socket_ops = {
305 .start = ipx_seq_socket_start,
306 .next = ipx_seq_socket_next,
307 .stop = ipx_seq_interface_stop,
308 .show = ipx_seq_socket_show,
309};
310
311static int ipx_seq_route_open(struct inode *inode, struct file *file)
312{
313 return seq_open(file, &ipx_seq_route_ops);
314}
315
316static int ipx_seq_interface_open(struct inode *inode, struct file *file)
317{
318 return seq_open(file, &ipx_seq_interface_ops);
319}
320
321static int ipx_seq_socket_open(struct inode *inode, struct file *file)
322{
323 return seq_open(file, &ipx_seq_socket_ops);
324}
325
326static struct file_operations ipx_seq_interface_fops = {
327 .owner = THIS_MODULE,
328 .open = ipx_seq_interface_open,
329 .read = seq_read,
330 .llseek = seq_lseek,
331 .release = seq_release,
332};
333
334static struct file_operations ipx_seq_route_fops = {
335 .owner = THIS_MODULE,
336 .open = ipx_seq_route_open,
337 .read = seq_read,
338 .llseek = seq_lseek,
339 .release = seq_release,
340};
341
342static struct file_operations ipx_seq_socket_fops = {
343 .owner = THIS_MODULE,
344 .open = ipx_seq_socket_open,
345 .read = seq_read,
346 .llseek = seq_lseek,
347 .release = seq_release,
348};
349
350static struct proc_dir_entry *ipx_proc_dir;
351
352int __init ipx_proc_init(void)
353{
354 struct proc_dir_entry *p;
355 int rc = -ENOMEM;
356
357 ipx_proc_dir = proc_mkdir("ipx", proc_net);
358
359 if (!ipx_proc_dir)
360 goto out;
361 p = create_proc_entry("interface", S_IRUGO, ipx_proc_dir);
362 if (!p)
363 goto out_interface;
364
365 p->proc_fops = &ipx_seq_interface_fops;
366 p = create_proc_entry("route", S_IRUGO, ipx_proc_dir);
367 if (!p)
368 goto out_route;
369
370 p->proc_fops = &ipx_seq_route_fops;
371 p = create_proc_entry("socket", S_IRUGO, ipx_proc_dir);
372 if (!p)
373 goto out_socket;
374
375 p->proc_fops = &ipx_seq_socket_fops;
376
377 rc = 0;
378out:
379 return rc;
380out_socket:
381 remove_proc_entry("route", ipx_proc_dir);
382out_route:
383 remove_proc_entry("interface", ipx_proc_dir);
384out_interface:
385 remove_proc_entry("ipx", proc_net);
386 goto out;
387}
388
389void __exit ipx_proc_exit(void)
390{
391 remove_proc_entry("interface", ipx_proc_dir);
392 remove_proc_entry("route", ipx_proc_dir);
393 remove_proc_entry("socket", ipx_proc_dir);
394 remove_proc_entry("ipx", proc_net);
395}
396
397#else /* CONFIG_PROC_FS */
398
399int __init ipx_proc_init(void)
400{
401 return 0;
402}
403
404void __exit ipx_proc_exit(void)
405{
406}
407
408#endif /* CONFIG_PROC_FS */
diff --git a/net/ipx/ipx_route.c b/net/ipx/ipx_route.c
new file mode 100644
index 000000000000..67774448efd9
--- /dev/null
+++ b/net/ipx/ipx_route.c
@@ -0,0 +1,293 @@
1/*
2 * Implements the IPX routing routines.
3 * Code moved from af_ipx.c.
4 *
5 * Arnaldo Carvalho de Melo <acme@conectiva.com.br>, 2003
6 *
7 * See net/ipx/ChangeLog.
8 */
9
10#include <linux/config.h>
11#include <linux/list.h>
12#include <linux/route.h>
13#include <linux/spinlock.h>
14
15#include <net/ipx.h>
16#include <net/sock.h>
17
18LIST_HEAD(ipx_routes);
19DEFINE_RWLOCK(ipx_routes_lock);
20
21extern struct ipx_interface *ipx_internal_net;
22
23extern __u16 ipx_cksum(struct ipxhdr *packet, int length);
24extern struct ipx_interface *ipxitf_find_using_net(__u32 net);
25extern int ipxitf_demux_socket(struct ipx_interface *intrfc,
26 struct sk_buff *skb, int copy);
27extern int ipxitf_demux_socket(struct ipx_interface *intrfc,
28 struct sk_buff *skb, int copy);
29extern int ipxitf_send(struct ipx_interface *intrfc, struct sk_buff *skb,
30 char *node);
31extern struct ipx_interface *ipxitf_find_using_net(__u32 net);
32
33struct ipx_route *ipxrtr_lookup(__u32 net)
34{
35 struct ipx_route *r;
36
37 read_lock_bh(&ipx_routes_lock);
38 list_for_each_entry(r, &ipx_routes, node)
39 if (r->ir_net == net) {
40 ipxrtr_hold(r);
41 goto unlock;
42 }
43 r = NULL;
44unlock:
45 read_unlock_bh(&ipx_routes_lock);
46 return r;
47}
48
49/*
50 * Caller must hold a reference to intrfc
51 */
52int ipxrtr_add_route(__u32 network, struct ipx_interface *intrfc,
53 unsigned char *node)
54{
55 struct ipx_route *rt;
56 int rc;
57
58 /* Get a route structure; either existing or create */
59 rt = ipxrtr_lookup(network);
60 if (!rt) {
61 rt = kmalloc(sizeof(*rt), GFP_ATOMIC);
62 rc = -EAGAIN;
63 if (!rt)
64 goto out;
65
66 atomic_set(&rt->refcnt, 1);
67 ipxrtr_hold(rt);
68 write_lock_bh(&ipx_routes_lock);
69 list_add(&rt->node, &ipx_routes);
70 write_unlock_bh(&ipx_routes_lock);
71 } else {
72 rc = -EEXIST;
73 if (intrfc == ipx_internal_net)
74 goto out_put;
75 }
76
77 rt->ir_net = network;
78 rt->ir_intrfc = intrfc;
79 if (!node) {
80 memset(rt->ir_router_node, '\0', IPX_NODE_LEN);
81 rt->ir_routed = 0;
82 } else {
83 memcpy(rt->ir_router_node, node, IPX_NODE_LEN);
84 rt->ir_routed = 1;
85 }
86
87 rc = 0;
88out_put:
89 ipxrtr_put(rt);
90out:
91 return rc;
92}
93
94void ipxrtr_del_routes(struct ipx_interface *intrfc)
95{
96 struct ipx_route *r, *tmp;
97
98 write_lock_bh(&ipx_routes_lock);
99 list_for_each_entry_safe(r, tmp, &ipx_routes, node)
100 if (r->ir_intrfc == intrfc) {
101 list_del(&r->node);
102 ipxrtr_put(r);
103 }
104 write_unlock_bh(&ipx_routes_lock);
105}
106
107static int ipxrtr_create(struct ipx_route_definition *rd)
108{
109 struct ipx_interface *intrfc;
110 int rc = -ENETUNREACH;
111
112 /* Find the appropriate interface */
113 intrfc = ipxitf_find_using_net(rd->ipx_router_network);
114 if (!intrfc)
115 goto out;
116 rc = ipxrtr_add_route(rd->ipx_network, intrfc, rd->ipx_router_node);
117 ipxitf_put(intrfc);
118out:
119 return rc;
120}
121
122static int ipxrtr_delete(long net)
123{
124 struct ipx_route *r, *tmp;
125 int rc;
126
127 write_lock_bh(&ipx_routes_lock);
128 list_for_each_entry_safe(r, tmp, &ipx_routes, node)
129 if (r->ir_net == net) {
130 /* Directly connected; can't lose route */
131 rc = -EPERM;
132 if (!r->ir_routed)
133 goto out;
134 list_del(&r->node);
135 ipxrtr_put(r);
136 rc = 0;
137 goto out;
138 }
139 rc = -ENOENT;
140out:
141 write_unlock_bh(&ipx_routes_lock);
142 return rc;
143}
144
145/*
146 * The skb has to be unshared, we'll end up calling ipxitf_send, that'll
147 * modify the packet
148 */
149int ipxrtr_route_skb(struct sk_buff *skb)
150{
151 struct ipxhdr *ipx = ipx_hdr(skb);
152 struct ipx_route *r = ipxrtr_lookup(IPX_SKB_CB(skb)->ipx_dest_net);
153
154 if (!r) { /* no known route */
155 kfree_skb(skb);
156 return 0;
157 }
158
159 ipxitf_hold(r->ir_intrfc);
160 ipxitf_send(r->ir_intrfc, skb, r->ir_routed ?
161 r->ir_router_node : ipx->ipx_dest.node);
162 ipxitf_put(r->ir_intrfc);
163 ipxrtr_put(r);
164
165 return 0;
166}
167
168/*
169 * Route an outgoing frame from a socket.
170 */
171int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx,
172 struct iovec *iov, size_t len, int noblock)
173{
174 struct sk_buff *skb;
175 struct ipx_sock *ipxs = ipx_sk(sk);
176 struct ipx_interface *intrfc;
177 struct ipxhdr *ipx;
178 size_t size;
179 int ipx_offset;
180 struct ipx_route *rt = NULL;
181 int rc;
182
183 /* Find the appropriate interface on which to send packet */
184 if (!usipx->sipx_network && ipx_primary_net) {
185 usipx->sipx_network = ipx_primary_net->if_netnum;
186 intrfc = ipx_primary_net;
187 } else {
188 rt = ipxrtr_lookup(usipx->sipx_network);
189 rc = -ENETUNREACH;
190 if (!rt)
191 goto out;
192 intrfc = rt->ir_intrfc;
193 }
194
195 ipxitf_hold(intrfc);
196 ipx_offset = intrfc->if_ipx_offset;
197 size = sizeof(struct ipxhdr) + len + ipx_offset;
198
199 skb = sock_alloc_send_skb(sk, size, noblock, &rc);
200 if (!skb)
201 goto out_put;
202
203 skb_reserve(skb, ipx_offset);
204 skb->sk = sk;
205
206 /* Fill in IPX header */
207 skb->h.raw = skb->nh.raw = skb_put(skb, sizeof(struct ipxhdr));
208 ipx = ipx_hdr(skb);
209 ipx->ipx_pktsize = htons(len + sizeof(struct ipxhdr));
210 IPX_SKB_CB(skb)->ipx_tctrl = 0;
211 ipx->ipx_type = usipx->sipx_type;
212
213 IPX_SKB_CB(skb)->last_hop.index = -1;
214#ifdef CONFIG_IPX_INTERN
215 IPX_SKB_CB(skb)->ipx_source_net = ipxs->intrfc->if_netnum;
216 memcpy(ipx->ipx_source.node, ipxs->node, IPX_NODE_LEN);
217#else
218 rc = ntohs(ipxs->port);
219 if (rc == 0x453 || rc == 0x452) {
220 /* RIP/SAP special handling for mars_nwe */
221 IPX_SKB_CB(skb)->ipx_source_net = intrfc->if_netnum;
222 memcpy(ipx->ipx_source.node, intrfc->if_node, IPX_NODE_LEN);
223 } else {
224 IPX_SKB_CB(skb)->ipx_source_net = ipxs->intrfc->if_netnum;
225 memcpy(ipx->ipx_source.node, ipxs->intrfc->if_node,
226 IPX_NODE_LEN);
227 }
228#endif /* CONFIG_IPX_INTERN */
229 ipx->ipx_source.sock = ipxs->port;
230 IPX_SKB_CB(skb)->ipx_dest_net = usipx->sipx_network;
231 memcpy(ipx->ipx_dest.node, usipx->sipx_node, IPX_NODE_LEN);
232 ipx->ipx_dest.sock = usipx->sipx_port;
233
234 rc = memcpy_fromiovec(skb_put(skb, len), iov, len);
235 if (rc) {
236 kfree_skb(skb);
237 goto out_put;
238 }
239
240 /* Apply checksum. Not allowed on 802.3 links. */
241 if (sk->sk_no_check || intrfc->if_dlink_type == IPX_FRAME_8023)
242 ipx->ipx_checksum = 0xFFFF;
243 else
244 ipx->ipx_checksum = ipx_cksum(ipx, len + sizeof(struct ipxhdr));
245
246 rc = ipxitf_send(intrfc, skb, (rt && rt->ir_routed) ?
247 rt->ir_router_node : ipx->ipx_dest.node);
248out_put:
249 ipxitf_put(intrfc);
250 if (rt)
251 ipxrtr_put(rt);
252out:
253 return rc;
254}
255
256/*
257 * We use a normal struct rtentry for route handling
258 */
259int ipxrtr_ioctl(unsigned int cmd, void __user *arg)
260{
261 struct rtentry rt; /* Use these to behave like 'other' stacks */
262 struct sockaddr_ipx *sg, *st;
263 int rc = -EFAULT;
264
265 if (copy_from_user(&rt, arg, sizeof(rt)))
266 goto out;
267
268 sg = (struct sockaddr_ipx *)&rt.rt_gateway;
269 st = (struct sockaddr_ipx *)&rt.rt_dst;
270
271 rc = -EINVAL;
272 if (!(rt.rt_flags & RTF_GATEWAY) || /* Direct routes are fixed */
273 sg->sipx_family != AF_IPX ||
274 st->sipx_family != AF_IPX)
275 goto out;
276
277 switch (cmd) {
278 case SIOCDELRT:
279 rc = ipxrtr_delete(st->sipx_network);
280 break;
281 case SIOCADDRT: {
282 struct ipx_route_definition f;
283 f.ipx_network = st->sipx_network;
284 f.ipx_router_network = sg->sipx_network;
285 memcpy(f.ipx_router_node, sg->sipx_node, IPX_NODE_LEN);
286 rc = ipxrtr_create(&f);
287 break;
288 }
289 }
290
291out:
292 return rc;
293}
diff --git a/net/ipx/sysctl_net_ipx.c b/net/ipx/sysctl_net_ipx.c
new file mode 100644
index 000000000000..510eda96d10a
--- /dev/null
+++ b/net/ipx/sysctl_net_ipx.c
@@ -0,0 +1,62 @@
1/* -*- linux-c -*-
2 * sysctl_net_ipx.c: sysctl interface to net IPX subsystem.
3 *
4 * Begun April 1, 1996, Mike Shaver.
5 * Added /proc/sys/net/ipx directory entry (empty =) ). [MS]
6 * Added /proc/sys/net/ipx/ipx_pprop_broadcasting - acme March 4, 2001
7 */
8
9#include <linux/config.h>
10#include <linux/mm.h>
11#include <linux/sysctl.h>
12
13#ifndef CONFIG_SYSCTL
14#error This file should not be compiled without CONFIG_SYSCTL defined
15#endif
16
17/* From af_ipx.c */
18extern int sysctl_ipx_pprop_broadcasting;
19
20static struct ctl_table ipx_table[] = {
21 {
22 .ctl_name = NET_IPX_PPROP_BROADCASTING,
23 .procname = "ipx_pprop_broadcasting",
24 .data = &sysctl_ipx_pprop_broadcasting,
25 .maxlen = sizeof(int),
26 .mode = 0644,
27 .proc_handler = &proc_dointvec,
28 },
29 { 0 },
30};
31
32static struct ctl_table ipx_dir_table[] = {
33 {
34 .ctl_name = NET_IPX,
35 .procname = "ipx",
36 .mode = 0555,
37 .child = ipx_table,
38 },
39 { 0 },
40};
41
42static struct ctl_table ipx_root_table[] = {
43 {
44 .ctl_name = CTL_NET,
45 .procname = "net",
46 .mode = 0555,
47 .child = ipx_dir_table,
48 },
49 { 0 },
50};
51
52static struct ctl_table_header *ipx_table_header;
53
54void ipx_register_sysctl(void)
55{
56 ipx_table_header = register_sysctl_table(ipx_root_table, 1);
57}
58
59void ipx_unregister_sysctl(void)
60{
61 unregister_sysctl_table(ipx_table_header);
62}