OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [econet/] [af_econet.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*
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
#include <linux/config.h>
13
#include <linux/module.h>
14
 
15
#include <linux/types.h>
16
#include <linux/kernel.h>
17
#include <linux/sched.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 <net/sock.h>
35
#include <net/inet_common.h>
36
#include <linux/stat.h>
37
#include <linux/init.h>
38
#include <linux/if_ec.h>
39
#include <net/udp.h>
40
#include <net/ip.h>
41
#include <linux/spinlock.h>
42
 
43
#include <asm/uaccess.h>
44
#include <asm/system.h>
45
#include <asm/bitops.h>
46
 
47
static struct proto_ops econet_ops;
48
static struct sock *econet_sklist;
49
 
50
/* Since there are only 256 possible network numbers (or fewer, depends
51
   how you count) it makes sense to use a simple lookup table. */
52
static struct net_device *net2dev_map[256];
53
 
54
#define EC_PORT_IP      0xd2
55
 
56
#ifdef CONFIG_ECONET_AUNUDP
57
static spinlock_t aun_queue_lock;
58
static struct socket *udpsock;
59
#define AUN_PORT        0x8000
60
 
61
 
62
struct aunhdr
63
{
64
        unsigned char code;             /* AUN magic protocol byte */
65
        unsigned char port;
66
        unsigned char cb;
67
        unsigned char pad;
68
        unsigned long handle;
69
};
70
 
71
static unsigned long aun_seq;
72
 
73
/* Queue of packets waiting to be transmitted. */
74
static struct sk_buff_head aun_queue;
75
static struct timer_list ab_cleanup_timer;
76
 
77
#endif          /* CONFIG_ECONET_AUNUDP */
78
 
79
/* Per-packet information */
80
struct ec_cb
81
{
82
        struct sockaddr_ec sec;
83
        unsigned long cookie;           /* Supplied by user. */
84
#ifdef CONFIG_ECONET_AUNUDP
85
        int done;
86
        unsigned long seq;              /* Sequencing */
87
        unsigned long timeout;          /* Timeout */
88
        unsigned long start;            /* jiffies */
89
#endif
90
#ifdef CONFIG_ECONET_NATIVE
91
        void (*sent)(struct sk_buff *, int result);
92
#endif
93
};
94
 
95
/*
96
 *      Pull a packet from our receive queue and hand it to the user.
97
 *      If necessary we block.
98
 */
99
 
100
static int econet_recvmsg(struct socket *sock, struct msghdr *msg, int len,
101
                          int flags, struct scm_cookie *scm)
102
{
103
        struct sock *sk = sock->sk;
104
        struct sk_buff *skb;
105
        int copied, err;
106
 
107
        msg->msg_namelen = sizeof(struct sockaddr_ec);
108
 
109
        /*
110
         *      Call the generic datagram receiver. This handles all sorts
111
         *      of horrible races and re-entrancy so we can forget about it
112
         *      in the protocol layers.
113
         *
114
         *      Now it will return ENETDOWN, if device have just gone down,
115
         *      but then it will block.
116
         */
117
 
118
        skb=skb_recv_datagram(sk,flags,flags&MSG_DONTWAIT,&err);
119
 
120
        /*
121
         *      An error occurred so return it. Because skb_recv_datagram()
122
         *      handles the blocking we don't see and worry about blocking
123
         *      retries.
124
         */
125
 
126
        if(skb==NULL)
127
                goto out;
128
 
129
        /*
130
         *      You lose any data beyond the buffer you gave. If it worries a
131
         *      user program they can ask the device for its MTU anyway.
132
         */
133
 
134
        copied = skb->len;
135
        if (copied > len)
136
        {
137
                copied=len;
138
                msg->msg_flags|=MSG_TRUNC;
139
        }
140
 
141
        /* We can't use skb_copy_datagram here */
142
        err = memcpy_toiovec(msg->msg_iov, skb->data, copied);
143
        if (err)
144
                goto out_free;
145
        sk->stamp=skb->stamp;
146
 
147
        if (msg->msg_name)
148
                memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
149
 
150
        /*
151
         *      Free or return the buffer as appropriate. Again this
152
         *      hides all the races and re-entrancy issues from us.
153
         */
154
        err = copied;
155
 
156
out_free:
157
        skb_free_datagram(sk, skb);
158
out:
159
        return err;
160
}
161
 
162
/*
163
 *      Bind an Econet socket.
164
 */
165
 
166
static int econet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
167
{
168
        struct sockaddr_ec *sec = (struct sockaddr_ec *)uaddr;
169
        struct sock *sk=sock->sk;
170
 
171
        /*
172
         *      Check legality
173
         */
174
 
175
        if (addr_len < sizeof(struct sockaddr_ec) ||
176
            sec->sec_family != AF_ECONET)
177
                return -EINVAL;
178
 
179
        sk->protinfo.af_econet->cb = sec->cb;
180
        sk->protinfo.af_econet->port = sec->port;
181
        sk->protinfo.af_econet->station = sec->addr.station;
182
        sk->protinfo.af_econet->net = sec->addr.net;
183
 
184
        return 0;
185
}
186
 
187
/*
188
 *      Queue a transmit result for the user to be told about.
189
 */
190
 
191
static void tx_result(struct sock *sk, unsigned long cookie, int result)
192
{
193
        struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
194
        struct ec_cb *eb;
195
        struct sockaddr_ec *sec;
196
 
197
        if (skb == NULL)
198
        {
199
                printk(KERN_DEBUG "ec: memory squeeze, transmit result dropped.\n");
200
                return;
201
        }
202
 
203
        eb = (struct ec_cb *)&skb->cb;
204
        sec = (struct sockaddr_ec *)&eb->sec;
205
        memset(sec, 0, sizeof(struct sockaddr_ec));
206
        sec->cookie = cookie;
207
        sec->type = ECTYPE_TRANSMIT_STATUS | result;
208
        sec->sec_family = AF_ECONET;
209
 
210
        if (sock_queue_rcv_skb(sk, skb) < 0)
211
                kfree_skb(skb);
212
}
213
 
214
#ifdef CONFIG_ECONET_NATIVE
215
/*
216
 *      Called by the Econet hardware driver when a packet transmit
217
 *      has completed.  Tell the user.
218
 */
219
 
220
static void ec_tx_done(struct sk_buff *skb, int result)
221
{
222
        struct ec_cb *eb = (struct ec_cb *)&skb->cb;
223
        tx_result(skb->sk, eb->cookie, result);
224
}
225
#endif
226
 
227
/*
228
 *      Send a packet.  We have to work out which device it's going out on
229
 *      and hence whether to use real Econet or the UDP emulation.
230
 */
231
 
232
static int econet_sendmsg(struct socket *sock, struct msghdr *msg, int len,
233
                          struct scm_cookie *scm)
234
{
235
        struct sock *sk = sock->sk;
236
        struct sockaddr_ec *saddr=(struct sockaddr_ec *)msg->msg_name;
237
        struct net_device *dev;
238
        struct ec_addr addr;
239
        int err;
240
        unsigned char port, cb;
241
        struct sk_buff *skb;
242
        struct ec_cb *eb;
243
#ifdef CONFIG_ECONET_NATIVE
244
        unsigned short proto = 0;
245
#endif
246
#ifdef CONFIG_ECONET_AUNUDP
247
        struct msghdr udpmsg;
248
        struct iovec iov[msg->msg_iovlen+1];
249
        struct aunhdr ah;
250
        struct sockaddr_in udpdest;
251
        __kernel_size_t size;
252
        int i;
253
        mm_segment_t oldfs;
254
#endif
255
 
256
        /*
257
         *      Check the flags.
258
         */
259
 
260
        if (msg->msg_flags&~MSG_DONTWAIT)
261
                return(-EINVAL);
262
 
263
        /*
264
         *      Get and verify the address.
265
         */
266
 
267
        if (saddr == NULL) {
268
                addr.station = sk->protinfo.af_econet->station;
269
                addr.net = sk->protinfo.af_econet->net;
270
                port = sk->protinfo.af_econet->port;
271
                cb = sk->protinfo.af_econet->cb;
272
        } else {
273
                if (msg->msg_namelen < sizeof(struct sockaddr_ec))
274
                        return -EINVAL;
275
                addr.station = saddr->addr.station;
276
                addr.net = saddr->addr.net;
277
                port = saddr->port;
278
                cb = saddr->cb;
279
        }
280
 
281
        /* Look for a device with the right network number. */
282
        dev = net2dev_map[addr.net];
283
 
284
        /* If not directly reachable, use some default */
285
        if (dev == NULL)
286
        {
287
                dev = net2dev_map[0];
288
                /* No interfaces at all? */
289
                if (dev == NULL)
290
                        return -ENETDOWN;
291
        }
292
 
293
        if (dev->type == ARPHRD_ECONET)
294
        {
295
                /* Real hardware Econet.  We're not worthy etc. */
296
#ifdef CONFIG_ECONET_NATIVE
297
                atomic_inc(&dev->refcnt);
298
 
299
                skb = sock_alloc_send_skb(sk, len+dev->hard_header_len+15,
300
                                          msg->msg_flags & MSG_DONTWAIT, &err);
301
                if (skb==NULL)
302
                        goto out_unlock;
303
 
304
                skb_reserve(skb, (dev->hard_header_len+15)&~15);
305
                skb->nh.raw = skb->data;
306
 
307
                eb = (struct ec_cb *)&skb->cb;
308
 
309
                /* BUG: saddr may be NULL */
310
                eb->cookie = saddr->cookie;
311
                eb->sec = *saddr;
312
                eb->sent = ec_tx_done;
313
 
314
                if (dev->hard_header) {
315
                        int res;
316
                        struct ec_framehdr *fh;
317
                        err = -EINVAL;
318
                        res = dev->hard_header(skb, dev, ntohs(proto),
319
                                               &addr, NULL, len);
320
                        /* Poke in our control byte and
321
                           port number.  Hack, hack.  */
322
                        fh = (struct ec_framehdr *)(skb->data);
323
                        fh->cb = cb;
324
                        fh->port = port;
325
                        if (sock->type != SOCK_DGRAM) {
326
                                skb->tail = skb->data;
327
                                skb->len = 0;
328
                        } else if (res < 0)
329
                                goto out_free;
330
                }
331
 
332
                /* Copy the data. Returns -EFAULT on error */
333
                err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);
334
                skb->protocol = proto;
335
                skb->dev = dev;
336
                skb->priority = sk->priority;
337
                if (err)
338
                        goto out_free;
339
 
340
                err = -ENETDOWN;
341
                if (!(dev->flags & IFF_UP))
342
                        goto out_free;
343
 
344
                /*
345
                 *      Now send it
346
                 */
347
 
348
                dev_queue_xmit(skb);
349
                dev_put(dev);
350
                return(len);
351
 
352
        out_free:
353
                kfree_skb(skb);
354
        out_unlock:
355
                if (dev)
356
                        dev_put(dev);
357
#else
358
                err = -EPROTOTYPE;
359
#endif
360
                return err;
361
        }
362
 
363
#ifdef CONFIG_ECONET_AUNUDP
364
        /* AUN virtual Econet. */
365
 
366
        if (udpsock == NULL)
367
                return -ENETDOWN;               /* No socket - can't send */
368
 
369
        /* Make up a UDP datagram and hand it off to some higher intellect. */
370
 
371
        memset(&udpdest, 0, sizeof(udpdest));
372
        udpdest.sin_family = AF_INET;
373
        udpdest.sin_port = htons(AUN_PORT);
374
 
375
        /* At the moment we use the stupid Acorn scheme of Econet address
376
           y.x maps to IP a.b.c.x.  This should be replaced with something
377
           more flexible and more aware of subnet masks.  */
378
        {
379
                struct in_device *idev = in_dev_get(dev);
380
                unsigned long network = 0;
381
                if (idev) {
382
                        read_lock(&idev->lock);
383
                        if (idev->ifa_list)
384
                                network = ntohl(idev->ifa_list->ifa_address) &
385
                                        0xffffff00;             /* !!! */
386
                        read_unlock(&idev->lock);
387
                        in_dev_put(idev);
388
                }
389
                udpdest.sin_addr.s_addr = htonl(network | addr.station);
390
        }
391
 
392
        ah.port = port;
393
        ah.cb = cb & 0x7f;
394
        ah.code = 2;            /* magic */
395
        ah.pad = 0;
396
 
397
        /* tack our header on the front of the iovec */
398
        size = sizeof(struct aunhdr);
399
        iov[0].iov_base = (void *)&ah;
400
        iov[0].iov_len = size;
401
        for (i = 0; i < msg->msg_iovlen; i++) {
402
                void *base = msg->msg_iov[i].iov_base;
403
                size_t len = msg->msg_iov[i].iov_len;
404
                /* Check it now since we switch to KERNEL_DS later. */
405
                if ((err = verify_area(VERIFY_READ, base, len)) < 0)
406
                        return err;
407
                iov[i+1].iov_base = base;
408
                iov[i+1].iov_len = len;
409
                size += len;
410
        }
411
 
412
        /* Get a skbuff (no data, just holds our cb information) */
413
        if ((skb = sock_alloc_send_skb(sk, 0,
414
                             msg->msg_flags & MSG_DONTWAIT, &err)) == NULL)
415
                return err;
416
 
417
        eb = (struct ec_cb *)&skb->cb;
418
 
419
        eb->cookie = saddr->cookie;
420
        eb->timeout = (5*HZ);
421
        eb->start = jiffies;
422
        ah.handle = aun_seq;
423
        eb->seq = (aun_seq++);
424
        eb->sec = *saddr;
425
 
426
        skb_queue_tail(&aun_queue, skb);
427
 
428
        udpmsg.msg_name = (void *)&udpdest;
429
        udpmsg.msg_namelen = sizeof(udpdest);
430
        udpmsg.msg_iov = &iov[0];
431
        udpmsg.msg_iovlen = msg->msg_iovlen + 1;
432
        udpmsg.msg_control = NULL;
433
        udpmsg.msg_controllen = 0;
434
        udpmsg.msg_flags=0;
435
 
436
        oldfs = get_fs(); set_fs(KERNEL_DS);    /* More privs :-) */
437
        err = sock_sendmsg(udpsock, &udpmsg, size);
438
        set_fs(oldfs);
439
#else
440
        err = -EPROTOTYPE;
441
#endif
442
        return err;
443
}
444
 
445
/*
446
 *      Look up the address of a socket.
447
 */
448
 
449
static int econet_getname(struct socket *sock, struct sockaddr *uaddr,
450
                          int *uaddr_len, int peer)
451
{
452
        struct sock *sk = sock->sk;
453
        struct sockaddr_ec *sec = (struct sockaddr_ec *)uaddr;
454
 
455
        if (peer)
456
                return -EOPNOTSUPP;
457
 
458
        sec->sec_family = AF_ECONET;
459
        sec->port = sk->protinfo.af_econet->port;
460
        sec->addr.station = sk->protinfo.af_econet->station;
461
        sec->addr.net = sk->protinfo.af_econet->net;
462
 
463
        *uaddr_len = sizeof(*sec);
464
        return 0;
465
}
466
 
467
static void econet_destroy_timer(unsigned long data)
468
{
469
        struct sock *sk=(struct sock *)data;
470
 
471
        if (!atomic_read(&sk->wmem_alloc) && !atomic_read(&sk->rmem_alloc)) {
472
                sk_free(sk);
473
                MOD_DEC_USE_COUNT;
474
                return;
475
        }
476
 
477
        sk->timer.expires=jiffies+10*HZ;
478
        add_timer(&sk->timer);
479
        printk(KERN_DEBUG "econet socket destroy delayed\n");
480
}
481
 
482
/*
483
 *      Close an econet socket.
484
 */
485
 
486
static int econet_release(struct socket *sock)
487
{
488
        struct sock *sk = sock->sk;
489
 
490
        if (!sk)
491
                return 0;
492
 
493
        sklist_remove_socket(&econet_sklist, sk);
494
 
495
        /*
496
         *      Now the socket is dead. No more input will appear.
497
         */
498
 
499
        sk->state_change(sk);   /* It is useless. Just for sanity. */
500
 
501
        sock->sk = NULL;
502
        sk->socket = NULL;
503
        sk->dead = 1;
504
 
505
        /* Purge queues */
506
 
507
        skb_queue_purge(&sk->receive_queue);
508
 
509
        if (atomic_read(&sk->rmem_alloc) || atomic_read(&sk->wmem_alloc)) {
510
                sk->timer.data=(unsigned long)sk;
511
                sk->timer.expires=jiffies+HZ;
512
                sk->timer.function=econet_destroy_timer;
513
                add_timer(&sk->timer);
514
                return 0;
515
        }
516
 
517
        sk_free(sk);
518
        MOD_DEC_USE_COUNT;
519
        return 0;
520
}
521
 
522
/*
523
 *      Create an Econet socket
524
 */
525
 
526
static int econet_create(struct socket *sock, int protocol)
527
{
528
        struct sock *sk;
529
        int err;
530
 
531
        /* Econet only provides datagram services. */
532
        if (sock->type != SOCK_DGRAM)
533
                return -ESOCKTNOSUPPORT;
534
 
535
        sock->state = SS_UNCONNECTED;
536
        MOD_INC_USE_COUNT;
537
 
538
        err = -ENOBUFS;
539
        sk = sk_alloc(PF_ECONET, GFP_KERNEL, 1);
540
        if (sk == NULL)
541
                goto out;
542
 
543
        sk->reuse = 1;
544
        sock->ops = &econet_ops;
545
        sock_init_data(sock,sk);
546
 
547
        sk->protinfo.af_econet = kmalloc(sizeof(struct econet_opt), GFP_KERNEL);
548
        if (sk->protinfo.af_econet == NULL)
549
                goto out_free;
550
        memset(sk->protinfo.af_econet, 0, sizeof(struct econet_opt));
551
        sk->zapped=0;
552
        sk->family = PF_ECONET;
553
        sk->num = protocol;
554
 
555
        sklist_insert_socket(&econet_sklist, sk);
556
        return(0);
557
 
558
out_free:
559
        sk_free(sk);
560
out:
561
        MOD_DEC_USE_COUNT;
562
        return err;
563
}
564
 
565
/*
566
 *      Handle Econet specific ioctls
567
 */
568
 
569
static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void *arg)
570
{
571
        struct ifreq ifr;
572
        struct ec_device *edev;
573
        struct net_device *dev;
574
        struct sockaddr_ec *sec;
575
 
576
        /*
577
         *      Fetch the caller's info block into kernel space
578
         */
579
 
580
        if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
581
                return -EFAULT;
582
 
583
        if ((dev = dev_get_by_name(ifr.ifr_name)) == NULL)
584
                return -ENODEV;
585
 
586
        sec = (struct sockaddr_ec *)&ifr.ifr_addr;
587
 
588
        switch (cmd)
589
        {
590
        case SIOCSIFADDR:
591
                edev = dev->ec_ptr;
592
                if (edev == NULL)
593
                {
594
                        /* Magic up a new one. */
595
                        edev = kmalloc(sizeof(struct ec_device), GFP_KERNEL);
596
                        if (edev == NULL) {
597
                                printk("af_ec: memory squeeze.\n");
598
                                dev_put(dev);
599
                                return -ENOMEM;
600
                        }
601
                        memset(edev, 0, sizeof(struct ec_device));
602
                        dev->ec_ptr = edev;
603
                }
604
                else
605
                        net2dev_map[edev->net] = NULL;
606
                edev->station = sec->addr.station;
607
                edev->net = sec->addr.net;
608
                net2dev_map[sec->addr.net] = dev;
609
                if (!net2dev_map[0])
610
                        net2dev_map[0] = dev;
611
                dev_put(dev);
612
                return 0;
613
 
614
        case SIOCGIFADDR:
615
                edev = dev->ec_ptr;
616
                if (edev == NULL)
617
                {
618
                        dev_put(dev);
619
                        return -ENODEV;
620
                }
621
                memset(sec, 0, sizeof(struct sockaddr_ec));
622
                sec->addr.station = edev->station;
623
                sec->addr.net = edev->net;
624
                sec->sec_family = AF_ECONET;
625
                dev_put(dev);
626
                if (copy_to_user(arg, &ifr, sizeof(struct ifreq)))
627
                        return -EFAULT;
628
                return 0;
629
        }
630
 
631
        dev_put(dev);
632
        return -EINVAL;
633
}
634
 
635
/*
636
 *      Handle generic ioctls
637
 */
638
 
639
static int econet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
640
{
641
        struct sock *sk = sock->sk;
642
        int pid;
643
 
644
        switch(cmd)
645
        {
646
                case FIOSETOWN:
647
                case SIOCSPGRP:
648
                        if (get_user(pid, (int *) arg))
649
                                return -EFAULT;
650
                        if (current->pid != pid && current->pgrp != -pid && !capable(CAP_NET_ADMIN))
651
                                return -EPERM;
652
                        sk->proc = pid;
653
                        return(0);
654
                case FIOGETOWN:
655
                case SIOCGPGRP:
656
                        return put_user(sk->proc, (int *)arg);
657
                case SIOCGSTAMP:
658
                        if(sk->stamp.tv_sec==0)
659
                                return -ENOENT;
660
                        return copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)) ? -EFAULT : 0;
661
                case SIOCGIFFLAGS:
662
                case SIOCSIFFLAGS:
663
                case SIOCGIFCONF:
664
                case SIOCGIFMETRIC:
665
                case SIOCSIFMETRIC:
666
                case SIOCGIFMEM:
667
                case SIOCSIFMEM:
668
                case SIOCGIFMTU:
669
                case SIOCSIFMTU:
670
                case SIOCSIFLINK:
671
                case SIOCGIFHWADDR:
672
                case SIOCSIFHWADDR:
673
                case SIOCSIFMAP:
674
                case SIOCGIFMAP:
675
                case SIOCSIFSLAVE:
676
                case SIOCGIFSLAVE:
677
                case SIOCGIFINDEX:
678
                case SIOCGIFNAME:
679
                case SIOCGIFCOUNT:
680
                case SIOCSIFHWBROADCAST:
681
                        return(dev_ioctl(cmd,(void *) arg));
682
 
683
                case SIOCSIFADDR:
684
                case SIOCGIFADDR:
685
                        return ec_dev_ioctl(sock, cmd, (void *)arg);
686
                        break;
687
 
688
                default:
689
                        return(dev_ioctl(cmd,(void *) arg));
690
        }
691
        /*NOTREACHED*/
692
        return 0;
693
}
694
 
695
static struct net_proto_family econet_family_ops = {
696
        family:         PF_ECONET,
697
        create:         econet_create,
698
};
699
 
700
static struct proto_ops SOCKOPS_WRAPPED(econet_ops) = {
701
        family:         PF_ECONET,
702
 
703
        release:        econet_release,
704
        bind:           econet_bind,
705
        connect:        sock_no_connect,
706
        socketpair:     sock_no_socketpair,
707
        accept:         sock_no_accept,
708
        getname:        econet_getname,
709
        poll:           datagram_poll,
710
        ioctl:          econet_ioctl,
711
        listen:         sock_no_listen,
712
        shutdown:       sock_no_shutdown,
713
        setsockopt:     sock_no_setsockopt,
714
        getsockopt:     sock_no_getsockopt,
715
        sendmsg:        econet_sendmsg,
716
        recvmsg:        econet_recvmsg,
717
        mmap:           sock_no_mmap,
718
        sendpage:       sock_no_sendpage,
719
};
720
 
721
#include <linux/smp_lock.h>
722
SOCKOPS_WRAP(econet, PF_ECONET);
723
 
724
/*
725
 *      Find the listening socket, if any, for the given data.
726
 */
727
 
728
static struct sock *ec_listening_socket(unsigned char port, unsigned char
729
                                 station, unsigned char net)
730
{
731
        struct sock *sk = econet_sklist;
732
 
733
        while (sk)
734
        {
735
                struct econet_opt *opt = sk->protinfo.af_econet;
736
                if ((opt->port == port || opt->port == 0) &&
737
                    (opt->station == station || opt->station == 0) &&
738
                    (opt->net == net || opt->net == 0))
739
                        return sk;
740
 
741
                sk = sk->next;
742
        }
743
 
744
        return NULL;
745
}
746
 
747
/*
748
 *      Queue a received packet for a socket.
749
 */
750
 
751
static int ec_queue_packet(struct sock *sk, struct sk_buff *skb,
752
                           unsigned char stn, unsigned char net,
753
                           unsigned char cb, unsigned char port)
754
{
755
        struct ec_cb *eb = (struct ec_cb *)&skb->cb;
756
        struct sockaddr_ec *sec = (struct sockaddr_ec *)&eb->sec;
757
 
758
        memset(sec, 0, sizeof(struct sockaddr_ec));
759
        sec->sec_family = AF_ECONET;
760
        sec->type = ECTYPE_PACKET_RECEIVED;
761
        sec->port = port;
762
        sec->cb = cb;
763
        sec->addr.net = net;
764
        sec->addr.station = stn;
765
 
766
        return sock_queue_rcv_skb(sk, skb);
767
}
768
 
769
#ifdef CONFIG_ECONET_AUNUDP
770
 
771
/*
772
 *      Send an AUN protocol response.
773
 */
774
 
775
static void aun_send_response(__u32 addr, unsigned long seq, int code, int cb)
776
{
777
        struct sockaddr_in sin;
778
        struct iovec iov;
779
        struct aunhdr ah;
780
        struct msghdr udpmsg;
781
        int err;
782
        mm_segment_t oldfs;
783
 
784
        memset(&sin, 0, sizeof(sin));
785
        sin.sin_family = AF_INET;
786
        sin.sin_port = htons(AUN_PORT);
787
        sin.sin_addr.s_addr = addr;
788
 
789
        ah.code = code;
790
        ah.pad = 0;
791
        ah.port = 0;
792
        ah.cb = cb;
793
        ah.handle = seq;
794
 
795
        iov.iov_base = (void *)&ah;
796
        iov.iov_len = sizeof(ah);
797
 
798
        udpmsg.msg_name = (void *)&sin;
799
        udpmsg.msg_namelen = sizeof(sin);
800
        udpmsg.msg_iov = &iov;
801
        udpmsg.msg_iovlen = 1;
802
        udpmsg.msg_control = NULL;
803
        udpmsg.msg_controllen = 0;
804
        udpmsg.msg_flags=0;
805
 
806
        oldfs = get_fs(); set_fs(KERNEL_DS);
807
        err = sock_sendmsg(udpsock, &udpmsg, sizeof(ah));
808
        set_fs(oldfs);
809
}
810
 
811
 
812
/*
813
 *      Handle incoming AUN packets.  Work out if anybody wants them,
814
 *      and send positive or negative acknowledgements as appropriate.
815
 */
816
 
817
static void aun_incoming(struct sk_buff *skb, struct aunhdr *ah, size_t len)
818
{
819
        struct iphdr *ip = skb->nh.iph;
820
        unsigned char stn = ntohl(ip->saddr) & 0xff;
821
        struct sock *sk;
822
        struct sk_buff *newskb;
823
        struct ec_device *edev = skb->dev->ec_ptr;
824
 
825
        if (! edev)
826
                goto bad;
827
 
828
        if ((sk = ec_listening_socket(ah->port, stn, edev->net)) == NULL)
829
                goto bad;               /* Nobody wants it */
830
 
831
        newskb = alloc_skb((len - sizeof(struct aunhdr) + 15) & ~15,
832
                           GFP_ATOMIC);
833
        if (newskb == NULL)
834
        {
835
                printk(KERN_DEBUG "AUN: memory squeeze, dropping packet.\n");
836
                /* Send nack and hope sender tries again */
837
                goto bad;
838
        }
839
 
840
        memcpy(skb_put(newskb, len - sizeof(struct aunhdr)), (void *)(ah+1),
841
               len - sizeof(struct aunhdr));
842
 
843
        if (ec_queue_packet(sk, newskb, stn, edev->net, ah->cb, ah->port))
844
        {
845
                /* Socket is bankrupt. */
846
                kfree_skb(newskb);
847
                goto bad;
848
        }
849
 
850
        aun_send_response(ip->saddr, ah->handle, 3, 0);
851
        return;
852
 
853
bad:
854
        aun_send_response(ip->saddr, ah->handle, 4, 0);
855
}
856
 
857
/*
858
 *      Handle incoming AUN transmit acknowledgements.  If the sequence
859
 *      number matches something in our backlog then kill it and tell
860
 *      the user.  If the remote took too long to reply then we may have
861
 *      dropped the packet already.
862
 */
863
 
864
static void aun_tx_ack(unsigned long seq, int result)
865
{
866
        struct sk_buff *skb;
867
        unsigned long flags;
868
        struct ec_cb *eb;
869
 
870
        spin_lock_irqsave(&aun_queue_lock, flags);
871
        skb = skb_peek(&aun_queue);
872
        while (skb && skb != (struct sk_buff *)&aun_queue)
873
        {
874
                struct sk_buff *newskb = skb->next;
875
                eb = (struct ec_cb *)&skb->cb;
876
                if (eb->seq == seq)
877
                        goto foundit;
878
 
879
                skb = newskb;
880
        }
881
        spin_unlock_irqrestore(&aun_queue_lock, flags);
882
        printk(KERN_DEBUG "AUN: unknown sequence %ld\n", seq);
883
        return;
884
 
885
foundit:
886
        tx_result(skb->sk, eb->cookie, result);
887
        skb_unlink(skb);
888
        spin_unlock_irqrestore(&aun_queue_lock, flags);
889
        kfree_skb(skb);
890
}
891
 
892
/*
893
 *      Deal with received AUN frames - sort out what type of thing it is
894
 *      and hand it to the right function.
895
 */
896
 
897
static void aun_data_available(struct sock *sk, int slen)
898
{
899
        int err;
900
        struct sk_buff *skb;
901
        unsigned char *data;
902
        struct aunhdr *ah;
903
        struct iphdr *ip;
904
        size_t len;
905
 
906
        while ((skb = skb_recv_datagram(sk, 0, 1, &err)) == NULL) {
907
                if (err == -EAGAIN) {
908
                        printk(KERN_ERR "AUN: no data available?!");
909
                        return;
910
                }
911
                printk(KERN_DEBUG "AUN: recvfrom() error %d\n", -err);
912
        }
913
 
914
        data = skb->h.raw + sizeof(struct udphdr);
915
        ah = (struct aunhdr *)data;
916
        len = skb->len - sizeof(struct udphdr);
917
        ip = skb->nh.iph;
918
 
919
        switch (ah->code)
920
        {
921
        case 2:
922
                aun_incoming(skb, ah, len);
923
                break;
924
        case 3:
925
                aun_tx_ack(ah->handle, ECTYPE_TRANSMIT_OK);
926
                break;
927
        case 4:
928
                aun_tx_ack(ah->handle, ECTYPE_TRANSMIT_NOT_LISTENING);
929
                break;
930
#if 0
931
                /* This isn't quite right yet. */
932
        case 5:
933
                aun_send_response(ip->saddr, ah->handle, 6, ah->cb);
934
                break;
935
#endif
936
        default:
937
                printk(KERN_DEBUG "unknown AUN packet (type %d)\n", data[0]);
938
        }
939
 
940
        skb_free_datagram(sk, skb);
941
}
942
 
943
/*
944
 *      Called by the timer to manage the AUN transmit queue.  If a packet
945
 *      was sent to a dead or nonexistent host then we will never get an
946
 *      acknowledgement back.  After a few seconds we need to spot this and
947
 *      drop the packet.
948
 */
949
 
950
static void ab_cleanup(unsigned long h)
951
{
952
        struct sk_buff *skb;
953
        unsigned long flags;
954
 
955
        spin_lock_irqsave(&aun_queue_lock, flags);
956
        skb = skb_peek(&aun_queue);
957
        while (skb && skb != (struct sk_buff *)&aun_queue)
958
        {
959
                struct sk_buff *newskb = skb->next;
960
                struct ec_cb *eb = (struct ec_cb *)&skb->cb;
961
                if ((jiffies - eb->start) > eb->timeout)
962
                {
963
                        tx_result(skb->sk, eb->cookie,
964
                                  ECTYPE_TRANSMIT_NOT_PRESENT);
965
                        skb_unlink(skb);
966
                        kfree_skb(skb);
967
                }
968
                skb = newskb;
969
        }
970
        spin_unlock_irqrestore(&aun_queue_lock, flags);
971
 
972
        mod_timer(&ab_cleanup_timer, jiffies + (HZ*2));
973
}
974
 
975
static int __init aun_udp_initialise(void)
976
{
977
        int error;
978
        struct sockaddr_in sin;
979
 
980
        skb_queue_head_init(&aun_queue);
981
        spin_lock_init(&aun_queue_lock);
982
        init_timer(&ab_cleanup_timer);
983
        ab_cleanup_timer.expires = jiffies + (HZ*2);
984
        ab_cleanup_timer.function = ab_cleanup;
985
        add_timer(&ab_cleanup_timer);
986
 
987
        memset(&sin, 0, sizeof(sin));
988
        sin.sin_port = htons(AUN_PORT);
989
 
990
        /* We can count ourselves lucky Acorn machines are too dim to
991
           speak IPv6. :-) */
992
        if ((error = sock_create(PF_INET, SOCK_DGRAM, 0, &udpsock)) < 0)
993
        {
994
                printk("AUN: socket error %d\n", -error);
995
                return error;
996
        }
997
 
998
        udpsock->sk->reuse = 1;
999
        udpsock->sk->allocation = GFP_ATOMIC;   /* we're going to call it
1000
                                                   from interrupts */
1001
 
1002
        error = udpsock->ops->bind(udpsock, (struct sockaddr *)&sin,
1003
                                sizeof(sin));
1004
        if (error < 0)
1005
        {
1006
                printk("AUN: bind error %d\n", -error);
1007
                goto release;
1008
        }
1009
 
1010
        udpsock->sk->data_ready = aun_data_available;
1011
 
1012
        return 0;
1013
 
1014
release:
1015
        sock_release(udpsock);
1016
        udpsock = NULL;
1017
        return error;
1018
}
1019
#endif
1020
 
1021
#ifdef CONFIG_ECONET_NATIVE
1022
 
1023
/*
1024
 *      Receive an Econet frame from a device.
1025
 */
1026
 
1027
static int econet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
1028
{
1029
        struct ec_framehdr *hdr = (struct ec_framehdr *)skb->data;
1030
        struct sock *sk;
1031
        struct ec_device *edev = dev->ec_ptr;
1032
 
1033
        if (! edev)
1034
        {
1035
                kfree_skb(skb);
1036
                return NET_RX_DROP;
1037
        }
1038
 
1039
        if (skb->len < sizeof(struct ec_framehdr))
1040
        {
1041
                /* Frame is too small to be any use */
1042
                kfree_skb(skb);
1043
                return NET_RX_DROP;
1044
        }
1045
 
1046
        /* First check for encapsulated IP */
1047
        if (hdr->port == EC_PORT_IP)
1048
        {
1049
                skb->protocol = htons(ETH_P_IP);
1050
                skb_pull(skb, sizeof(struct ec_framehdr));
1051
                netif_rx(skb);
1052
                return 0;
1053
        }
1054
 
1055
        sk = ec_listening_socket(hdr->port, hdr->src_stn, hdr->src_net);
1056
        if (!sk)
1057
        {
1058
                kfree_skb(skb);
1059
                return NET_RX_DROP;
1060
        }
1061
 
1062
        if (ec_queue_packet(sk, skb, edev->net, hdr->src_stn, hdr->cb,
1063
                            hdr->port)) {
1064
                kfree_skb(skb);
1065
                return NET_RX_DROP;
1066
        }
1067
        return 0;
1068
}
1069
 
1070
static struct packet_type econet_packet_type = {
1071
        type:           __constant_htons(ETH_P_ECONET),
1072
        func:           econet_rcv,
1073
};
1074
 
1075
static void econet_hw_initialise(void)
1076
{
1077
        dev_add_pack(&econet_packet_type);
1078
}
1079
 
1080
#endif
1081
 
1082
static int econet_notifier(struct notifier_block *this, unsigned long msg, void *data)
1083
{
1084
        struct net_device *dev = (struct net_device *)data;
1085
        struct ec_device *edev;
1086
 
1087
        switch (msg) {
1088
        case NETDEV_UNREGISTER:
1089
                /* A device has gone down - kill any data we hold for it. */
1090
                edev = dev->ec_ptr;
1091
                if (edev)
1092
                {
1093
                        if (net2dev_map[0] == dev)
1094
                                net2dev_map[0] = 0;
1095
                        net2dev_map[edev->net] = NULL;
1096
                        kfree(edev);
1097
                        dev->ec_ptr = NULL;
1098
                }
1099
                break;
1100
        }
1101
 
1102
        return NOTIFY_DONE;
1103
}
1104
 
1105
static struct notifier_block econet_netdev_notifier = {
1106
        notifier_call:  econet_notifier,
1107
};
1108
 
1109
static void __exit econet_proto_exit(void)
1110
{
1111
#ifdef CONFIG_ECONET_AUNUDP
1112
        del_timer(&ab_cleanup_timer);
1113
        if (udpsock)
1114
                sock_release(udpsock);
1115
#endif
1116
        unregister_netdevice_notifier(&econet_netdev_notifier);
1117
        sock_unregister(econet_family_ops.family);
1118
}
1119
 
1120
static int __init econet_proto_init(void)
1121
{
1122
        sock_register(&econet_family_ops);
1123
#ifdef CONFIG_ECONET_AUNUDP
1124
        spin_lock_init(&aun_queue_lock);
1125
        aun_udp_initialise();
1126
#endif
1127
#ifdef CONFIG_ECONET_NATIVE
1128
        econet_hw_initialise();
1129
#endif
1130
        register_netdevice_notifier(&econet_netdev_notifier);
1131
        return 0;
1132
}
1133
 
1134
module_init(econet_proto_init);
1135
module_exit(econet_proto_exit);
1136
 
1137
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.