aboutsummaryrefslogtreecommitdiffstats
path: root/net/econet
diff options
context:
space:
mode:
Diffstat (limited to 'net/econet')
-rw-r--r--net/econet/Kconfig36
-rw-r--r--net/econet/Makefile7
-rw-r--r--net/econet/af_econet.c1170
3 files changed, 1213 insertions, 0 deletions
diff --git a/net/econet/Kconfig b/net/econet/Kconfig
new file mode 100644
index 00000000000..39a2d2975e0
--- /dev/null
+++ b/net/econet/Kconfig
@@ -0,0 +1,36 @@
1#
2# Acorn Econet/AUN protocols
3#
4
5config ECONET
6 tristate "Acorn Econet/AUN protocols (EXPERIMENTAL)"
7 depends on EXPERIMENTAL && INET
8 ---help---
9 Econet is a fairly old and slow networking protocol mainly used by
10 Acorn computers to access file and print servers. It uses native
11 Econet network cards. AUN is an implementation of the higher level
12 parts of Econet that runs over ordinary Ethernet connections, on
13 top of the UDP packet protocol, which in turn runs on top of the
14 Internet protocol IP.
15
16 If you say Y here, you can choose with the next two options whether
17 to send Econet/AUN traffic over a UDP Ethernet connection or over
18 a native Econet network card.
19
20 To compile this driver as a module, choose M here: the module
21 will be called econet.
22
23config ECONET_AUNUDP
24 bool "AUN over UDP"
25 depends on ECONET
26 help
27 Say Y here if you want to send Econet/AUN traffic over a UDP
28 connection (UDP is a packet based protocol that runs on top of the
29 Internet protocol IP) using an ordinary Ethernet network card.
30
31config ECONET_NATIVE
32 bool "Native Econet"
33 depends on ECONET
34 help
35 Say Y here if you have a native Econet network card installed in
36 your computer.
diff --git a/net/econet/Makefile b/net/econet/Makefile
new file mode 100644
index 00000000000..05fae8be2fe
--- /dev/null
+++ b/net/econet/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for Econet support code.
3#
4
5obj-$(CONFIG_ECONET) += econet.o
6
7econet-y := af_econet.o
diff --git a/net/econet/af_econet.c b/net/econet/af_econet.c
new file mode 100644
index 00000000000..1c1f26c5d67
--- /dev/null
+++ b/net/econet/af_econet.c
@@ -0,0 +1,1170 @@
1/*
2 * An implementation of the Acorn Econet and AUN protocols.
3 * Philip Blundell <philb@gnu.org>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 *
10 */
11
12#define pr_fmt(fmt) fmt
13
14#include <linux/module.h>
15
16#include <linux/types.h>
17#include <linux/kernel.h>
18#include <linux/string.h>
19#include <linux/mm.h>
20#include <linux/socket.h>
21#include <linux/sockios.h>
22#include <linux/in.h>
23#include <linux/errno.h>
24#include <linux/interrupt.h>
25#include <linux/if_ether.h>
26#include <linux/netdevice.h>
27#include <linux/inetdevice.h>
28#include <linux/route.h>
29#include <linux/inet.h>
30#include <linux/etherdevice.h>
31#include <linux/if_arp.h>
32#include <linux/wireless.h>
33#include <linux/skbuff.h>
34#include <linux/udp.h>
35#include <linux/slab.h>
36#include <linux/vmalloc.h>
37#include <net/sock.h>
38#include <net/inet_common.h>
39#include <linux/stat.h>
40#include <linux/init.h>
41#include <linux/if_ec.h>
42#include <net/udp.h>
43#include <net/ip.h>
44#include <linux/spinlock.h>
45#include <linux/rcupdate.h>
46#include <linux/bitops.h>
47#include <linux/mutex.h>
48
49#include <linux/uaccess.h>
50#include <asm/system.h>
51
52static const struct proto_ops econet_ops;
53static struct hlist_head econet_sklist;
54static DEFINE_SPINLOCK(econet_lock);
55static DEFINE_MUTEX(econet_mutex);
56
57/* Since there are only 256 possible network numbers (or fewer, depends
58 how you count) it makes sense to use a simple lookup table. */
59static struct net_device *net2dev_map[256];
60
61#define EC_PORT_IP 0xd2
62
63#ifdef CONFIG_ECONET_AUNUDP
64static DEFINE_SPINLOCK(aun_queue_lock);
65static struct socket *udpsock;
66#define AUN_PORT 0x8000
67
68struct aunhdr {
69 unsigned char code; /* AUN magic protocol byte */
70 unsigned char port;
71 unsigned char cb;
72 unsigned char pad;
73 unsigned long handle;
74};
75
76static unsigned long aun_seq;
77
78/* Queue of packets waiting to be transmitted. */
79static struct sk_buff_head aun_queue;
80static struct timer_list ab_cleanup_timer;
81
82#endif /* CONFIG_ECONET_AUNUDP */
83
84/* Per-packet information */
85struct ec_cb {
86 struct sockaddr_ec sec;
87 unsigned long cookie; /* Supplied by user. */
88#ifdef CONFIG_ECONET_AUNUDP
89 int done;
90 unsigned long seq; /* Sequencing */
91 unsigned long timeout; /* Timeout */
92 unsigned long start; /* jiffies */
93#endif
94#ifdef CONFIG_ECONET_NATIVE
95 void (*sent)(struct sk_buff *, int result);
96#endif
97};
98
99static void econet_remove_socket(struct hlist_head *list, struct sock *sk)
100{
101 spin_lock_bh(&econet_lock);
102 sk_del_node_init(sk);
103 spin_unlock_bh(&econet_lock);
104}
105
106static void econet_insert_socket(struct hlist_head *list, struct sock *sk)
107{
108 spin_lock_bh(&econet_lock);
109 sk_add_node(sk, list);
110 spin_unlock_bh(&econet_lock);
111}
112
113/*
114 * Pull a packet from our receive queue and hand it to the user.
115 * If necessary we block.
116 */
117
118static int econet_recvmsg(struct kiocb *iocb, struct socket *sock,
119 struct msghdr *msg, size_t len, int flags)
120{
121 struct sock *sk = sock->sk;
122 struct sk_buff *skb;
123 size_t copied;
124 int err;
125
126 msg->msg_namelen = sizeof(struct sockaddr_ec);
127
128 mutex_lock(&econet_mutex);
129
130 /*
131 * Call the generic datagram receiver. This handles all sorts
132 * of horrible races and re-entrancy so we can forget about it
133 * in the protocol layers.
134 *
135 * Now it will return ENETDOWN, if device have just gone down,
136 * but then it will block.
137 */
138
139 skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &err);
140
141 /*
142 * An error occurred so return it. Because skb_recv_datagram()
143 * handles the blocking we don't see and worry about blocking
144 * retries.
145 */
146
147 if (skb == NULL)
148 goto out;
149
150 /*
151 * You lose any data beyond the buffer you gave. If it worries a
152 * user program they can ask the device for its MTU anyway.
153 */
154
155 copied = skb->len;
156 if (copied > len) {
157 copied = len;
158 msg->msg_flags |= MSG_TRUNC;
159 }
160
161 /* We can't use skb_copy_datagram here */
162 err = memcpy_toiovec(msg->msg_iov, skb->data, copied);
163 if (err)
164 goto out_free;
165 sk->sk_stamp = skb->tstamp;
166
167 if (msg->msg_name)
168 memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
169
170 /*
171 * Free or return the buffer as appropriate. Again this
172 * hides all the races and re-entrancy issues from us.
173 */
174 err = copied;
175
176out_free:
177 skb_free_datagram(sk, skb);
178out:
179 mutex_unlock(&econet_mutex);