* added 0.99 linux version
[mascara-docs.git] / i386 / linux / linux-2.3.21 / net / decnet / dn_raw.c
blobca7ec06317b12c1e0556d3bd40066397c3fb076b
1 /*
2 * DECnet An implementation of the DECnet protocol suite for the LINUX
3 * operating system. DECnet is implemented using the BSD Socket
4 * interface as the means of communication with the user level.
6 * DECnet Raw Sockets Interface
8 * Author: Steve Whitehouse <SteveW@ACM.org>
11 * Changes:
12 * Steve Whitehouse - connect() function.
13 * Steve Whitehouse - SMP changes, removed MOP stubs. MOP will
14 * be userland only.
17 #include <linux/config.h>
18 #include <linux/net.h>
19 #include <linux/skbuff.h>
20 #include <linux/netdevice.h>
21 #include <linux/socket.h>
22 #include <linux/sockios.h>
23 #include <net/sock.h>
24 #include <net/dst.h>
25 #include <net/dn.h>
26 #include <net/dn_raw.h>
27 #include <net/dn_route.h>
29 static rwlock_t dn_raw_hash_lock = RW_LOCK_UNLOCKED;
30 static struct sock *dn_raw_nsp_sklist = NULL;
31 static struct sock *dn_raw_routing_sklist = NULL;
33 static void dn_raw_hash(struct sock *sk)
35 struct sock **skp;
37 switch(sk->protocol) {
38 case DNPROTO_NSP:
39 skp = &dn_raw_nsp_sklist;
40 break;
41 case DNPROTO_ROU:
42 skp = &dn_raw_routing_sklist;
43 break;
44 default:
45 printk(KERN_DEBUG "dn_raw_hash: Unknown protocol\n");
46 return;
49 write_lock_bh(&dn_raw_hash_lock);
50 sk->next = *skp;
51 sk->pprev = skp;
52 *skp = sk;
53 write_unlock_bh(&dn_raw_hash_lock);
56 static void dn_raw_unhash(struct sock *sk)
58 struct sock **skp = sk->pprev;
60 if (skp == NULL)
61 return;
63 write_lock_bh(&dn_raw_hash_lock);
64 while(*skp != sk)
65 skp = &((*skp)->next);
66 *skp = sk->next;
67 write_unlock_bh(&dn_raw_hash_lock);
69 sk->next = NULL;
70 sk->pprev = NULL;
73 static void dn_raw_autobind(struct sock *sk)
75 dn_raw_hash(sk);
76 sk->zapped = 0;
79 static int dn_raw_release(struct socket *sock)
81 struct sock *sk = sock->sk;
83 if (sk == NULL)
84 return 0;
86 if (!sk->dead) sk->state_change(sk);
88 sk->dead = 1;
89 sk->socket = NULL;
90 sock->sk = NULL;
92 dn_raw_unhash(sk);
93 sock_put(sk);
95 return 0;
99 * Bind does odd things with raw sockets. Its basically used to filter
100 * the incoming packets, but this differs with the different layers
101 * at which you extract packets.
103 * For Routing layer sockets, the object name is a host ordered unsigned
104 * short which is a mask for the 16 different types of possible routing
105 * packet. I'd like to also select by destination address of the packets
106 * but alas, this is rather too difficult to do at the moment.
108 static int dn_raw_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
110 struct sock *sk = sock->sk;
111 struct sockaddr_dn *addr = (struct sockaddr_dn *)uaddr;
113 if (addr_len != sizeof(struct sockaddr_dn))
114 return -EINVAL;
116 if (sk->zapped == 0)
117 return -EINVAL;
119 switch(sk->protocol) {
120 case DNPROTO_ROU:
121 if (dn_ntohs(addr->sdn_objnamel) && (dn_ntohs(addr->sdn_objnamel) != 2))
122 return -EINVAL;
123 /* Fall through here */
124 case DNPROTO_NSP:
125 if (dn_ntohs(addr->sdn_add.a_len) && (dn_ntohs(addr->sdn_add.a_len) != 2))
126 return -EINVAL;
127 break;
128 default:
129 return -EPROTONOSUPPORT;
132 if (dn_ntohs(addr->sdn_objnamel) > (DN_MAXOBJL-1))
133 return -EINVAL;
135 if (dn_ntohs(addr->sdn_add.a_len) > DN_MAXADDL)
136 return -EINVAL;
138 memcpy(&sk->protinfo.dn.addr, addr, sizeof(struct sockaddr_dn));
140 dn_raw_autobind(sk);
142 return 0;
146 * This is to allow send() and write() to work. You set the destination address
147 * with this function.
149 static int dn_raw_connect(struct socket *sock, struct sockaddr *uaddr, int addr_len, int flags)
151 struct sock *sk = sock->sk;
152 struct dn_scp *scp = &sk->protinfo.dn;
153 struct sockaddr_dn *saddr = (struct sockaddr_dn *)uaddr;
154 int err;
156 lock_sock(sk);
158 err = -EINVAL;
159 if (addr_len != sizeof(struct sockaddr_dn))
160 goto out;
162 if (saddr->sdn_family != AF_DECnet)
163 goto out;
165 if (dn_ntohs(saddr->sdn_objnamel) > (DN_MAXOBJL-1))
166 goto out;
168 if (dn_ntohs(saddr->sdn_add.a_len) > DN_MAXADDL)
169 goto out;
171 if (sk->zapped)
172 dn_raw_autobind(sk);
174 if ((err = dn_route_output(&sk->dst_cache, dn_saddr2dn(saddr), dn_saddr2dn(&scp->addr), 0)) < 0)
175 goto out;
177 memcpy(&scp->peer, saddr, sizeof(struct sockaddr_dn));
178 out:
179 release_sock(sk);
181 return err;
185 * TBD.
187 static int dn_raw_sendmsg(struct socket *sock, struct msghdr *hdr, int size,
188 struct scm_cookie *scm)
190 struct sock *sk = sock->sk;
192 if (sk->zapped)
193 dn_raw_autobind(sk);
195 if (sk->protocol != DNPROTO_NSP)
196 return -EOPNOTSUPP;
198 return 0;
202 * This works fine, execpt that it doesn't report the originating address
203 * or anything at the moment.
205 static int dn_raw_recvmsg(struct socket *sock, struct msghdr *msg, int size,
206 int flags, struct scm_cookie *scm)
208 struct sock *sk = sock->sk;
209 struct sk_buff *skb;
210 int err = 0;
211 int copied = 0;
213 lock_sock(sk);
215 if (sk->zapped)
216 dn_raw_autobind(sk);
218 if ((skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, flags & MSG_DONTWAIT, &err)) == NULL)
219 goto out;
221 copied = skb->len;
223 if (copied > size) {
224 copied = size;
225 msg->msg_flags |= MSG_TRUNC;
228 if ((err = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied)) != 0) {
229 if (flags & MSG_PEEK)
230 atomic_dec(&skb->users);
231 else
232 skb_queue_head(&sk->receive_queue, skb);
234 goto out;
237 skb_free_datagram(sk, skb);
239 out:
240 release_sock(sk);
242 return copied ? copied : err;
245 struct proto_ops dn_raw_proto_ops = {
246 AF_DECnet,
248 dn_raw_release,
249 dn_raw_bind,
250 dn_raw_connect,
251 sock_no_socketpair,
252 sock_no_accept,
253 sock_no_getname,
254 datagram_poll,
255 sock_no_ioctl,
256 sock_no_listen,
257 sock_no_shutdown,
258 sock_no_setsockopt,
259 sock_no_getsockopt,
260 sock_no_fcntl,
261 dn_raw_sendmsg,
262 dn_raw_recvmsg,
263 sock_no_mmap
266 #ifdef CONFIG_PROC_FS
267 int dn_raw_get_info(char *buffer, char **start, off_t offset, int length, int dummy)
269 int len = 0;
270 off_t pos = 0;
271 off_t begin = 0;
272 struct sock *sk;
274 read_lock_bh(&dn_raw_hash_lock);
275 for(sk = dn_raw_nsp_sklist; sk; sk = sk->next) {
276 len += sprintf(buffer+len, "NSP\n");
278 pos = begin + len;
280 if (pos < offset) {
281 len = 0;
282 begin = pos;
285 if (pos > offset + length)
286 goto all_done;
290 for(sk = dn_raw_routing_sklist; sk; sk = sk->next) {
291 len += sprintf(buffer+len, "ROU\n");
293 pos = begin + len;
295 if (pos < offset) {
296 len = 0;
297 begin = pos;
300 if (pos > offset + length)
301 goto all_done;
304 all_done:
305 read_unlock_bh(&dn_raw_hash_lock);
307 *start = buffer + (offset - begin);
308 len -= (offset - begin);
310 if (len > length) len = length;
312 return(len);
314 #endif /* CONFIG_PROC_FS */
316 void dn_raw_rx_nsp(struct sk_buff *skb)
318 struct sock *sk;
319 struct sk_buff *skb2;
321 read_lock(&dn_raw_hash_lock);
322 for(sk = dn_raw_nsp_sklist; sk != NULL; sk = sk->next) {
323 if (skb->len > sock_rspace(sk))
324 continue;
325 if (sk->dead)
326 continue;
327 if ((skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) {
328 skb_set_owner_r(skb2, sk);
329 skb_queue_tail(&sk->receive_queue, skb2);
330 sk->data_ready(sk, skb->len);
333 read_unlock(&dn_raw_hash_lock);
336 void dn_raw_rx_routing(struct sk_buff *skb)
338 struct sock *sk;
339 struct sk_buff *skb2;
340 struct dn_skb_cb *cb = (struct dn_skb_cb *)skb->cb;
341 unsigned short rt_flagmask;
342 unsigned short objnamel;
343 struct dn_scp *scp;
345 read_lock(&dn_raw_hash_lock);
346 for(sk = dn_raw_routing_sklist; sk != NULL; sk = sk->next) {
347 if (skb->len > sock_rspace(sk))
348 continue;
349 if (sk->dead)
350 continue;
351 scp = &sk->protinfo.dn;
353 rt_flagmask = dn_ntohs(*(unsigned short *)scp->addr.sdn_objname);
354 objnamel = dn_ntohs(scp->addr.sdn_objnamel);
356 if ((objnamel == 2) && (!((1 << (cb->rt_flags & 0x0f)) & rt_flagmask)))
357 continue;
359 if ((skb2 = skb_clone(skb, GFP_ATOMIC)) != NULL) {
360 skb_set_owner_r(skb2, sk);
361 skb_queue_tail(&sk->receive_queue, skb2);
362 sk->data_ready(sk, skb->len);
365 read_unlock(&dn_raw_hash_lock);