Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

econet.c

Go to the documentation of this file.
00001 /*
00002  *      An implementation of the Acorn Econet and AUN protocols.
00003  *      Philip Blundell <philb@gnu.org>
00004  *
00005  *      Fixes:
00006  *
00007  *      This program is free software; you can redistribute it and/or
00008  *      modify it under the terms of the GNU General Public License
00009  *      as published by the Free Software Foundation; either version
00010  *      2 of the License, or (at your option) any later version.
00011  *
00012  */
00013 
00014 #include <linux/config.h>
00015 #include <linux/module.h>
00016 
00017 #include <asm/uaccess.h>
00018 #include <asm/system.h>
00019 #include <asm/bitops.h>
00020 #include <linux/types.h>
00021 #include <linux/kernel.h>
00022 #include <linux/sched.h>
00023 #include <linux/string.h>
00024 #include <linux/mm.h>
00025 #include <linux/socket.h>
00026 #include <linux/sockios.h>
00027 #include <linux/in.h>
00028 #include <linux/errno.h>
00029 #include <linux/interrupt.h>
00030 #include <linux/if_ether.h>
00031 #include <linux/netdevice.h>
00032 #include <linux/inetdevice.h>
00033 #include <linux/route.h>
00034 #include <linux/inet.h>
00035 #include <linux/etherdevice.h>
00036 #include <linux/if_arp.h>
00037 #include <linux/wireless.h>
00038 #include <linux/skbuff.h>
00039 #include <net/sock.h>
00040 #include <net/inet_common.h>
00041 #include <linux/stat.h>
00042 #include <linux/init.h>
00043 #include <linux/if_ec.h>
00044 #include <net/udp.h>
00045 #include <net/ip.h>
00046 #include <asm/spinlock.h>
00047 
00048 static struct proto_ops econet_ops;
00049 static struct sock *econet_sklist;
00050 
00051 static spinlock_t aun_queue_lock;
00052 
00053 #ifdef CONFIG_ECONET_AUNUDP
00054 static struct socket *udpsock;
00055 #define AUN_PORT        0x8000
00056 
00057 struct aunhdr
00058 {
00059         unsigned char code;             /* AUN magic protocol byte */
00060         unsigned char port;
00061         unsigned char cb;
00062         unsigned char pad;
00063         unsigned long handle;
00064 };
00065 
00066 static unsigned long aun_seq = 0;
00067 
00068 /* Queue of packets waiting to be transmitted. */
00069 static struct sk_buff_head aun_queue;
00070 static struct timer_list ab_cleanup_timer;
00071 
00072 #endif          /* CONFIG_ECONET_AUNUDP */
00073 
00074 /* Per-packet information */
00075 struct ec_cb
00076 {
00077         struct sockaddr_ec sec;
00078         unsigned long cookie;           /* Supplied by user. */
00079 #ifdef CONFIG_ECONET_AUNUDP
00080         int done;
00081         unsigned long seq;              /* Sequencing */
00082         unsigned long timeout;          /* Timeout */
00083         unsigned long start;            /* jiffies */
00084 #endif
00085 #ifdef CONFIG_ECONET_NATIVE
00086         void (*sent)(struct sk_buff *, int result);
00087 #endif
00088 };
00089 
00090 struct ec_device
00091 {
00092         struct device *dev;             /* Real device structure */
00093         unsigned char station, net;     /* Econet protocol address */
00094         struct ec_device *prev, *next;  /* Linked list */
00095 };
00096 
00097 static struct ec_device *edevlist = NULL;
00098 
00099 static spinlock_t edevlist_lock;
00100 
00101 /*
00102  *      Faster version of edev_get - call with IRQs off
00103  */
00104 
00105 static __inline__ struct ec_device *__edev_get(struct device *dev)
00106 {
00107         struct ec_device *edev;
00108         for (edev = edevlist; edev; edev = edev->next)
00109         {
00110                 if (edev->dev == dev)
00111                         break;
00112         }
00113         return edev;
00114 }
00115 
00116 /*
00117  *      Find an Econet device given its `dev' pointer.  This is IRQ safe.
00118  */
00119 
00120 static struct ec_device *edev_get(struct device *dev)
00121 {
00122         struct ec_device *edev;
00123         unsigned long flags;
00124         spin_lock_irqsave(&edevlist_lock, flags);
00125         edev = __edev_get(dev);
00126         spin_unlock_irqrestore(&edevlist_lock, flags);
00127         return edev;
00128 }
00129 
00130 /*
00131  *      Pull a packet from our receive queue and hand it to the user.
00132  *      If necessary we block.
00133  */
00134 
00135 static int econet_recvmsg(struct socket *sock, struct msghdr *msg, int len,
00136                           int flags, struct scm_cookie *scm)
00137 {
00138         struct sock *sk = sock->sk;
00139         struct sk_buff *skb;
00140         int copied, err;
00141 
00142         msg->msg_namelen = sizeof(struct sockaddr_ec);
00143 
00144         /*
00145          *      Call the generic datagram receiver. This handles all sorts
00146          *      of horrible races and re-entrancy so we can forget about it
00147          *      in the protocol layers.
00148          *
00149          *      Now it will return ENETDOWN, if device have just gone down,
00150          *      but then it will block.
00151          */
00152 
00153         skb=skb_recv_datagram(sk,flags,flags&MSG_DONTWAIT,&err);
00154 
00155         /*
00156          *      An error occurred so return it. Because skb_recv_datagram() 
00157          *      handles the blocking we don't see and worry about blocking
00158          *      retries.
00159          */
00160 
00161         if(skb==NULL)
00162                 goto out;
00163 
00164         /*
00165          *      You lose any data beyond the buffer you gave. If it worries a
00166          *      user program they can ask the device for its MTU anyway.
00167          */
00168 
00169         copied = skb->len;
00170         if (copied > len)
00171         {
00172                 copied=len;
00173                 msg->msg_flags|=MSG_TRUNC;
00174         }
00175 
00176         /* We can't use skb_copy_datagram here */
00177         err = memcpy_toiovec(msg->msg_iov, skb->data, copied);
00178         if (err)
00179                 goto out_free;
00180         sk->stamp=skb->stamp;
00181 
00182         if (msg->msg_name)
00183                 memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
00184 
00185         /*
00186          *      Free or return the buffer as appropriate. Again this
00187          *      hides all the races and re-entrancy issues from us.
00188          */
00189         err = copied;
00190 
00191 out_free:
00192         skb_free_datagram(sk, skb);
00193 out:
00194         return err;
00195 }
00196 
00197 /*
00198  *      Bind an Econet socket.
00199  */
00200 
00201 static int econet_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
00202 {
00203         struct sockaddr_ec *sec = (struct sockaddr_ec *)uaddr;
00204         struct sock *sk=sock->sk;
00205         
00206         /*
00207          *      Check legality
00208          */
00209          
00210         if (addr_len < sizeof(struct sockaddr_ec))
00211                 return -EINVAL;
00212         if (sec->sec_family != AF_ECONET)
00213                 return -EINVAL;
00214         
00215         sk->protinfo.af_econet->cb = sec->cb;
00216         sk->protinfo.af_econet->port = sec->port;
00217         sk->protinfo.af_econet->station = sec->addr.station;
00218         sk->protinfo.af_econet->net = sec->addr.net;
00219 
00220         return 0;
00221 }
00222 
00223 /*
00224  *      Queue a transmit result for the user to be told about.
00225  */
00226 
00227 static void tx_result(struct sock *sk, unsigned long cookie, int result)
00228 {
00229         struct sk_buff *skb = alloc_skb(0, GFP_ATOMIC);
00230         struct ec_cb *eb;
00231         struct sockaddr_ec *sec;
00232 
00233         if (skb == NULL)
00234         {
00235                 printk(KERN_DEBUG "ec: memory squeeze, transmit result dropped.\n");
00236                 return;
00237         }
00238 
00239         eb = (struct ec_cb *)&skb->cb;
00240         sec = (struct sockaddr_ec *)&eb->sec;
00241         memset(sec, 0, sizeof(struct sockaddr_ec));
00242         sec->cookie = cookie;
00243         sec->type = ECTYPE_TRANSMIT_STATUS | result;
00244         sec->sec_family = AF_ECONET;
00245 
00246         if (sock_queue_rcv_skb(sk, skb) < 0)
00247                 kfree_skb(skb);
00248 }
00249 
00250 #ifdef CONFIG_ECONET_NATIVE
00251 /*
00252  *      Called by the Econet hardware driver when a packet transmit
00253  *      has completed.  Tell the user.
00254  */
00255 
00256 static void ec_tx_done(struct sk_buff *skb, int result)
00257 {
00258         struct ec_cb *eb = (struct ec_cb *)&skb->cb;
00259         tx_result(skb->sk, eb->cookie, result);
00260 }
00261 #endif
00262 
00263 /*
00264  *      Send a packet.  We have to work out which device it's going out on
00265  *      and hence whether to use real Econet or the UDP emulation.
00266  */
00267 
00268 static int econet_sendmsg(struct socket *sock, struct msghdr *msg, int len,
00269                           struct scm_cookie *scm)
00270 {
00271         struct sock *sk = sock->sk;
00272         struct sockaddr_ec *saddr=(struct sockaddr_ec *)msg->msg_name;
00273         struct device *dev;
00274         struct ec_addr addr;
00275         struct ec_device *edev;
00276         int err;
00277         unsigned char port, cb;
00278         struct sk_buff *skb;
00279         struct ec_cb *eb;
00280 #ifdef CONFIG_ECONET_NATIVE
00281         unsigned short proto = 0;
00282 #endif
00283 #ifdef CONFIG_ECONET_AUNUDP
00284         struct msghdr udpmsg;
00285         struct iovec iov[msg->msg_iovlen+1];
00286         struct aunhdr ah;
00287         struct sockaddr_in udpdest;
00288         __kernel_size_t size;
00289         int i;
00290         mm_segment_t oldfs;
00291 #endif
00292                 
00293         /*
00294          *      Check the flags. 
00295          */
00296 
00297         if (msg->msg_flags&~MSG_DONTWAIT) 
00298                 return(-EINVAL);
00299 
00300         /*
00301          *      Get and verify the address. 
00302          */
00303          
00304         if (saddr == NULL) {
00305                 addr.station = sk->protinfo.af_econet->station;
00306                 addr.net = sk->protinfo.af_econet->net;
00307                 port = sk->protinfo.af_econet->port;
00308                 cb = sk->protinfo.af_econet->cb;
00309         } else {
00310                 if (msg->msg_namelen < sizeof(struct sockaddr_ec)) 
00311                         return -EINVAL;
00312                 addr.station = saddr->addr.station;
00313                 addr.net = saddr->addr.net;
00314                 port = saddr->port;
00315                 cb = saddr->cb;
00316         }
00317 
00318         /* Look for a device with the right network number. */
00319         for (edev = edevlist; edev && (edev->net != addr.net); 
00320              edev = edev->next);
00321 
00322         /* Bridge?  What's that? */
00323         if (edev == NULL) 
00324                 return -ENETUNREACH;
00325 
00326         dev = edev->dev;
00327 
00328         if (dev->type == ARPHRD_ECONET)
00329         {
00330                 /* Real hardware Econet.  We're not worthy etc. */
00331 #ifdef CONFIG_ECONET_NATIVE
00332                 dev_lock_list();
00333                 
00334                 skb = sock_alloc_send_skb(sk, len+dev->hard_header_len+15, 0, 
00335                                           msg->msg_flags & MSG_DONTWAIT, &err);
00336                 if (skb==NULL)
00337                         goto out_unlock;
00338                 
00339                 skb_reserve(skb, (dev->hard_header_len+15)&~15);
00340                 skb->nh.raw = skb->data;
00341                 
00342                 eb = (struct ec_cb *)&skb->cb;
00343                 
00344                 eb->cookie = saddr->cookie;
00345                 eb->sec = *saddr;
00346                 eb->sent = ec_tx_done;
00347 
00348                 if (dev->hard_header) {
00349                         int res;
00350                         err = -EINVAL;
00351                         res = dev->hard_header(skb, dev, ntohs(proto), &addr, NULL, len);
00352                         if (sock->type != SOCK_DGRAM) {
00353                                 skb->tail = skb->data;
00354                                 skb->len = 0;
00355                         } else if (res < 0)
00356                                 goto out_free;
00357                 }
00358                 
00359                 /* Copy the data. Returns -EFAULT on error */
00360                 err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);
00361                 skb->protocol = proto;
00362                 skb->dev = dev;
00363                 skb->priority = sk->priority;
00364                 if (err)
00365                         goto out_free;
00366                 
00367                 err = -ENETDOWN;
00368                 if (!(dev->flags & IFF_UP))
00369                         goto out_free;
00370                 
00371                 /*
00372                  *      Now send it
00373                  */
00374                 
00375                 dev_unlock_list();
00376                 dev_queue_xmit(skb);
00377                 return(len);
00378 
00379         out_free:
00380                 kfree_skb(skb);
00381         out_unlock:
00382                 dev_unlock_list();
00383 #else
00384                 err = -EPROTOTYPE;
00385 #endif
00386                 return err;
00387         }
00388 
00389 #ifdef CONFIG_ECONET_AUNUDP
00390         /* AUN virtual Econet. */
00391 
00392         if (udpsock == NULL)
00393                 return -ENETDOWN;               /* No socket - can't send */
00394         
00395         /* Make up a UDP datagram and hand it off to some higher intellect. */
00396 
00397         memset(&udpdest, 0, sizeof(udpdest));
00398         udpdest.sin_family = AF_INET;
00399         udpdest.sin_port = htons(AUN_PORT);
00400 
00401         /* At the moment we use the stupid Acorn scheme of Econet address
00402            y.x maps to IP a.b.c.x.  This should be replaced with something
00403            more flexible and more aware of subnet masks.  */
00404         {
00405                 struct in_device *idev = (struct in_device *)dev->ip_ptr;
00406                 unsigned long network = ntohl(idev->ifa_list->ifa_address) & 
00407                         0xffffff00;             /* !!! */
00408                 udpdest.sin_addr.s_addr = htonl(network | addr.station);
00409         }
00410 
00411         ah.port = port;
00412         ah.cb = cb & 0x7f;
00413         ah.code = 2;            /* magic */
00414         ah.pad = 0;
00415 
00416         /* tack our header on the front of the iovec */
00417         size = sizeof(struct aunhdr);
00418         iov[0].iov_base = (void *)&ah;
00419         iov[0].iov_len = size;
00420         for (i = 0; i < msg->msg_iovlen; i++) {
00421                 void *base = msg->msg_iov[i].iov_base;
00422                 size_t len = msg->msg_iov[i].iov_len;
00423                 /* Check it now since we switch to KERNEL_DS later. */
00424                 if ((err = verify_area(VERIFY_READ, base, len)) < 0)
00425                         return err;
00426                 iov[i+1].iov_base = base;
00427                 iov[i+1].iov_len = len;
00428                 size += len;
00429         }
00430 
00431         /* Get a skbuff (no data, just holds our cb information) */
00432         if ((skb = sock_alloc_send_skb(sk, 0, 0, 
00433                              msg->msg_flags & MSG_DONTWAIT, &err)) == NULL)
00434                 return err;
00435 
00436         eb = (struct ec_cb *)&skb->cb;
00437 
00438         eb->cookie = saddr->cookie;
00439         eb->timeout = (5*HZ);
00440         eb->start = jiffies;
00441         ah.handle = aun_seq;
00442         eb->seq = (aun_seq++);
00443         eb->sec = *saddr;
00444 
00445         skb_queue_tail(&aun_queue, skb);
00446 
00447         udpmsg.msg_name = (void *)&udpdest;
00448         udpmsg.msg_namelen = sizeof(udpdest);
00449         udpmsg.msg_iov = &iov[0];
00450         udpmsg.msg_iovlen = msg->msg_iovlen + 1;
00451         udpmsg.msg_control = NULL;
00452         udpmsg.msg_controllen = 0;
00453         udpmsg.msg_flags=0;
00454 
00455         oldfs = get_fs(); set_fs(KERNEL_DS);    /* More privs :-) */
00456         err = sock_sendmsg(udpsock, &udpmsg, size);
00457         set_fs(oldfs);
00458 #else
00459         err = -EPROTOTYPE;
00460 #endif
00461         return err;
00462 }
00463 
00464 /*
00465  *      Look up the address of a socket.
00466  */
00467 
00468 static int econet_getname(struct socket *sock, struct sockaddr *uaddr,
00469                           int *uaddr_len, int peer)
00470 {
00471         struct sock *sk = sock->sk;
00472         struct sockaddr_ec *sec = (struct sockaddr_ec *)uaddr;
00473 
00474         if (peer)
00475                 return -EOPNOTSUPP;
00476 
00477         sec->sec_family = AF_ECONET;
00478         sec->port = sk->protinfo.af_econet->port;
00479         sec->addr.station = sk->protinfo.af_econet->station;
00480         sec->addr.net = sk->protinfo.af_econet->net;
00481 
00482         *uaddr_len = sizeof(*sec);
00483         return 0;
00484 }
00485 
00486 static void econet_destroy_timer(unsigned long data)
00487 {
00488         struct sock *sk=(struct sock *)data;
00489 
00490         if (!atomic_read(&sk->wmem_alloc) && !atomic_read(&sk->rmem_alloc)) {
00491                 sk_free(sk);
00492                 MOD_DEC_USE_COUNT;
00493                 return;
00494         }
00495 
00496         sk->timer.expires=jiffies+10*HZ;
00497         add_timer(&sk->timer);
00498         printk(KERN_DEBUG "econet socket destroy delayed\n");
00499 }
00500 
00501 /*
00502  *      Close an econet socket.
00503  */
00504 
00505 static int econet_release(struct socket *sock, struct socket *peersock)
00506 {
00507         struct sk_buff  *skb;
00508         struct sock *sk = sock->sk;
00509 
00510         if (!sk)
00511                 return 0;
00512 
00513         sklist_remove_socket(&econet_sklist, sk);
00514 
00515         /*
00516          *      Now the socket is dead. No more input will appear.
00517          */
00518 
00519         sk->state_change(sk);   /* It is useless. Just for sanity. */
00520 
00521         sock->sk = NULL;
00522         sk->socket = NULL;
00523         sk->dead = 1;
00524 
00525         /* Purge queues */
00526 
00527         while ((skb=skb_dequeue(&sk->receive_queue))!=NULL)
00528                 kfree_skb(skb);
00529 
00530         if (atomic_read(&sk->rmem_alloc) || atomic_read(&sk->wmem_alloc)) {
00531                 sk->timer.data=(unsigned long)sk;
00532                 sk->timer.expires=jiffies+HZ;
00533                 sk->timer.function=econet_destroy_timer;
00534                 add_timer(&sk->timer);
00535                 return 0;
00536         }
00537 
00538         sk_free(sk);
00539         MOD_DEC_USE_COUNT;
00540         return 0;
00541 }
00542 
00543 /*
00544  *      Create an Econet socket
00545  */
00546 
00547 static int econet_create(struct socket *sock, int protocol)
00548 {
00549         struct sock *sk;
00550         int err;
00551 
00552         /* Econet only provides datagram services. */
00553         if (sock->type != SOCK_DGRAM)
00554                 return -ESOCKTNOSUPPORT;
00555 
00556         sock->state = SS_UNCONNECTED;
00557         MOD_INC_USE_COUNT;
00558 
00559         err = -ENOBUFS;
00560         sk = sk_alloc(PF_ECONET, GFP_KERNEL, 1);
00561         if (sk == NULL)
00562                 goto out;
00563 
00564         sk->reuse = 1;
00565         sock->ops = &econet_ops;
00566         sock_init_data(sock,sk);
00567 
00568         sk->protinfo.af_econet = kmalloc(sizeof(struct econet_opt), GFP_KERNEL);
00569         if (sk->protinfo.af_econet == NULL)
00570                 goto out_free;
00571         memset(sk->protinfo.af_econet, 0, sizeof(struct econet_opt));
00572         sk->zapped=0;
00573         sk->family = PF_ECONET;
00574         sk->num = protocol;
00575 
00576         sklist_insert_socket(&econet_sklist, sk);
00577         return(0);
00578 
00579 out_free:
00580         sk_free(sk);
00581 out:
00582         MOD_DEC_USE_COUNT;
00583         return err;
00584 }
00585 
00586 /*
00587  *      Handle Econet specific ioctls
00588  */
00589 
00590 static int ec_dev_ioctl(struct socket *sock, unsigned int cmd, void *arg)
00591 {
00592         struct ifreq ifr;
00593         struct ec_device *edev;
00594         struct device *dev;
00595         unsigned long flags;
00596         struct sockaddr_ec *sec;
00597 
00598         /*
00599          *      Fetch the caller's info block into kernel space
00600          */
00601 
00602         if (copy_from_user(&ifr, arg, sizeof(struct ifreq)))
00603                 return -EFAULT;
00604 
00605         if ((dev = dev_get(ifr.ifr_name)) == NULL) 
00606                 return -ENODEV;
00607 
00608         sec = (struct sockaddr_ec *)&ifr.ifr_addr;
00609 
00610         switch (cmd)
00611         {
00612         case SIOCSIFADDR:
00613                 spin_lock_irqsave(&edevlist_lock, flags);
00614                 edev = __edev_get(dev);
00615                 if (edev == NULL)
00616                 {
00617                         /* Magic up a new one. */
00618                         edev = kmalloc(GFP_KERNEL, sizeof(struct ec_device));
00619                         if (edev == NULL) {
00620                                 printk("af_ec: memory squeeze.\n");
00621                                 spin_unlock_irqrestore(&edevlist_lock, flags);
00622                                 return -ENOMEM;
00623                         }
00624                         memset(edev, 0, sizeof(struct ec_device));
00625                         edev->dev = dev;
00626                         edev->next = edevlist;
00627                         edevlist = edev;
00628                 }
00629                 edev->station = sec->addr.station;
00630                 edev->net = sec->addr.net;
00631                 spin_unlock_irqrestore(&edevlist_lock, flags);
00632                 return 0;
00633 
00634         case SIOCGIFADDR:
00635                 spin_lock_irqsave(&edevlist_lock, flags);
00636                 edev = __edev_get(dev);
00637                 if (edev == NULL)
00638                 {
00639                         spin_unlock_irqrestore(&edevlist_lock, flags);
00640                         return -ENODEV;
00641                 }
00642                 memset(sec, 0, sizeof(struct sockaddr_ec));
00643                 sec->addr.station = edev->station;
00644                 sec->addr.net = edev->net;
00645                 sec->sec_family = AF_ECONET;
00646                 spin_unlock_irqrestore(&edevlist_lock, flags);
00647                 if (copy_to_user(arg, &ifr, sizeof(struct ifreq)))
00648                         return -EFAULT;
00649                 return 0;
00650         }
00651 
00652         return -EINVAL;
00653 }
00654 
00655 /*
00656  *      Handle generic ioctls
00657  */
00658 
00659 static int econet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
00660 {
00661         struct sock *sk = sock->sk;
00662         int err;
00663         int pid;
00664 
00665         switch(cmd) 
00666         {
00667                 case FIOSETOWN:
00668                 case SIOCSPGRP:
00669                         err = get_user(pid, (int *) arg);
00670                         if (err)
00671                                 return err; 
00672                         if (current->pid != pid && current->pgrp != -pid && !suser())
00673                                 return -EPERM;
00674                         sk->proc = pid;
00675                         return(0);
00676                 case FIOGETOWN:
00677                 case SIOCGPGRP:
00678                         return put_user(sk->proc, (int *)arg);
00679                 case SIOCGSTAMP:
00680                         if(sk->stamp.tv_sec==0)
00681                                 return -ENOENT;
00682                         err = -EFAULT;
00683                         if (!copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)))
00684                                 err = 0;
00685                         return err;
00686                 case SIOCGIFFLAGS:
00687                 case SIOCSIFFLAGS:
00688                 case SIOCGIFCONF:
00689                 case SIOCGIFMETRIC:
00690                 case SIOCSIFMETRIC:
00691                 case SIOCGIFMEM:
00692                 case SIOCSIFMEM:
00693                 case SIOCGIFMTU:
00694                 case SIOCSIFMTU:
00695                 case SIOCSIFLINK:
00696                 case SIOCGIFHWADDR:
00697                 case SIOCSIFHWADDR:
00698                 case SIOCSIFMAP:
00699                 case SIOCGIFMAP:
00700                 case SIOCSIFSLAVE:
00701                 case SIOCGIFSLAVE:
00702                 case SIOCGIFINDEX:
00703                 case SIOCGIFNAME:
00704                 case SIOCGIFCOUNT:
00705                 case SIOCSIFHWBROADCAST:
00706                         return(dev_ioctl(cmd,(void *) arg));
00707 
00708                 case SIOCSIFADDR:
00709                 case SIOCGIFADDR:
00710                         return ec_dev_ioctl(sock, cmd, (void *)arg);
00711                         break;
00712 
00713                 default:
00714                         return(dev_ioctl(cmd,(void *) arg));
00715         }
00716         /*NOTREACHED*/
00717         return 0;
00718 }
00719 
00720 static struct net_proto_family econet_family_ops = {
00721         PF_ECONET,
00722         econet_create
00723 };
00724 
00725 static struct proto_ops econet_ops = {
00726         PF_ECONET,
00727 
00728         sock_no_dup,
00729         econet_release,
00730         econet_bind,
00731         sock_no_connect,
00732         sock_no_socketpair,
00733         sock_no_accept,
00734         econet_getname, 
00735         datagram_poll,
00736         econet_ioctl,
00737         sock_no_listen,
00738         sock_no_shutdown,
00739         sock_no_setsockopt,
00740         sock_no_getsockopt,
00741         sock_no_fcntl,
00742         econet_sendmsg,
00743         econet_recvmsg
00744 };
00745 
00746 /*
00747  *      Find the listening socket, if any, for the given data.
00748  */
00749 
00750 static struct sock *ec_listening_socket(unsigned char port, unsigned char
00751                                         station, unsigned char net)
00752 {
00753         struct sock *sk = econet_sklist;
00754 
00755         while (sk)
00756         {
00757                 struct econet_opt *opt = sk->protinfo.af_econet;
00758                 if ((opt->port == port || opt->port == 0) && 
00759                     (opt->station == station || opt->station == 0) &&
00760                     (opt->net == net || opt->net == 0))
00761                         return sk;
00762                 sk = sk->sklist_next;
00763         }
00764 
00765         return NULL;
00766 }
00767 
00768 #ifdef CONFIG_ECONET_AUNUDP
00769 
00770 /*
00771  *      Send an AUN protocol response. 
00772  */
00773 
00774 static void aun_send_response(__u32 addr, unsigned long seq, int code, int cb)
00775 {
00776         struct sockaddr_in sin;
00777         struct iovec iov;
00778         struct aunhdr ah;
00779         struct msghdr udpmsg;
00780         int err;
00781         mm_segment_t oldfs;
00782         
00783         memset(&sin, 0, sizeof(sin));
00784         sin.sin_family = AF_INET;
00785         sin.sin_port = htons(AUN_PORT);
00786         sin.sin_addr.s_addr = addr;
00787 
00788         ah.code = code;
00789         ah.pad = 0;
00790         ah.port = 0;
00791         ah.cb = cb;
00792         ah.handle = seq;
00793 
00794         iov.iov_base = (void *)&ah;
00795         iov.iov_len = sizeof(ah);
00796 
00797         udpmsg.msg_name = (void *)&sin;
00798         udpmsg.msg_namelen = sizeof(sin);
00799         udpmsg.msg_iov = &iov;
00800         udpmsg.msg_iovlen = 1;
00801         udpmsg.msg_control = NULL;
00802         udpmsg.msg_controllen = 0;
00803         udpmsg.msg_flags=0;
00804 
00805         oldfs = get_fs(); set_fs(KERNEL_DS);
00806         err = sock_sendmsg(udpsock, &udpmsg, sizeof(ah));
00807         set_fs(oldfs);
00808 }
00809 
00810 /*
00811  *      Handle incoming AUN packets.  Work out if anybody wants them,
00812  *      and send positive or negative acknowledgements as appropriate.
00813  */
00814 
00815 static void aun_incoming(struct sk_buff *skb, struct aunhdr *ah, size_t len)
00816 {
00817         struct ec_device *edev = edev_get(skb->dev);
00818         struct iphdr *ip = skb->nh.iph;
00819         unsigned char stn = ntohl(ip->saddr) & 0xff;
00820         struct sock *sk;
00821         struct sk_buff *newskb;
00822         struct ec_cb *eb;
00823         struct sockaddr_ec *sec;
00824 
00825         if (edev == NULL)
00826                 return;         /* Device not configured for AUN */
00827         
00828         if ((sk = ec_listening_socket(ah->port, stn, edev->net)) == NULL)
00829                 goto bad;               /* Nobody wants it */
00830 
00831         newskb = alloc_skb((len - sizeof(struct aunhdr) + 15) & ~15, 
00832                            GFP_ATOMIC);
00833         if (newskb == NULL)
00834         {
00835                 printk(KERN_DEBUG "AUN: memory squeeze, dropping packet.\n");
00836                 /* Send nack and hope sender tries again */
00837                 goto bad;
00838         }
00839 
00840         eb = (struct ec_cb *)&newskb->cb;
00841         sec = (struct sockaddr_ec *)&eb->sec;
00842         memset(sec, 0, sizeof(struct sockaddr_ec));
00843         sec->sec_family = AF_ECONET;
00844         sec->type = ECTYPE_PACKET_RECEIVED;
00845         sec->port = ah->port;
00846         sec->cb = ah->cb;
00847         sec->addr.net = edev->net;
00848         sec->addr.station = stn;
00849 
00850         memcpy(skb_put(newskb, len - sizeof(struct aunhdr)), (void *)(ah+1), 
00851                len - sizeof(struct aunhdr));
00852 
00853         if (sock_queue_rcv_skb(sk, newskb) < 0)
00854         {
00855                 /* Socket is bankrupt. */
00856                 kfree_skb(newskb);
00857                 goto bad;
00858         }
00859 
00860         aun_send_response(ip->saddr, ah->handle, 3, 0);
00861         return;
00862 
00863 bad:
00864         aun_send_response(ip->saddr, ah->handle, 4, 0);
00865 }
00866 
00867 /*
00868  *      Handle incoming AUN transmit acknowledgements.  If the sequence
00869  *      number matches something in our backlog then kill it and tell
00870  *      the user.  If the remote took too long to reply then we may have
00871  *      dropped the packet already.
00872  */
00873 
00874 static void aun_tx_ack(unsigned long seq, int result)
00875 {
00876         struct sk_buff *skb;
00877         unsigned long flags;
00878         struct ec_cb *eb;
00879 
00880         spin_lock_irqsave(&aun_queue_lock, flags);
00881         skb = skb_peek(&aun_queue);
00882         while (skb && skb != (struct sk_buff *)&aun_queue)
00883         {
00884                 struct sk_buff *newskb = skb->next;
00885                 eb = (struct ec_cb *)&skb->cb;
00886                 if (eb->seq == seq)
00887                         goto foundit;
00888 
00889                 skb = newskb;
00890         }
00891         spin_unlock_irqrestore(&aun_queue_lock, flags);
00892         printk(KERN_DEBUG "AUN: unknown sequence %ld\n", seq);
00893         return;
00894 
00895 foundit:
00896         tx_result(skb->sk, eb->cookie, result);
00897         skb_unlink(skb);
00898         spin_unlock_irqrestore(&aun_queue_lock, flags);
00899 }
00900 
00901 /*
00902  *      Deal with received AUN frames - sort out what type of thing it is
00903  *      and hand it to the right function.
00904  */
00905 
00906 static void aun_data_available(struct sock *sk, int slen)
00907 {
00908         int err;
00909         struct sk_buff *skb;
00910         unsigned char *data;
00911         struct aunhdr *ah;
00912         struct iphdr *ip;
00913         size_t len;
00914 
00915         while ((skb = skb_recv_datagram(sk, 0, 1, &err)) == NULL) {
00916                 if (err == -EAGAIN) {
00917                         printk(KERN_ERR "AUN: no data available?!");
00918                         return;
00919                 }
00920                 printk(KERN_DEBUG "AUN: recvfrom() error %d\n", -err);
00921         }
00922 
00923         data = skb->h.raw + sizeof(struct udphdr);
00924         ah = (struct aunhdr *)data;
00925         len = skb->len - sizeof(struct udphdr);
00926         ip = skb->nh.iph;
00927 
00928         switch (ah->code)
00929         {
00930         case 2:
00931                 aun_incoming(skb, ah, len);
00932                 break;
00933         case 3:
00934                 aun_tx_ack(ah->handle, ECTYPE_TRANSMIT_OK);
00935                 break;
00936         case 4:
00937                 aun_tx_ack(ah->handle, ECTYPE_TRANSMIT_NOT_LISTENING);
00938                 break;
00939 #if 0
00940                 /* This isn't quite right yet. */
00941         case 5:
00942                 aun_send_response(ip->saddr, ah->handle, 6, ah->cb);
00943                 break;
00944 #endif
00945         default:
00946                 printk(KERN_DEBUG "unknown AUN packet (type %d)\n", data[0]);
00947         }
00948 
00949         skb_free_datagram(sk, skb);
00950 }
00951 
00952 /*
00953  *      Called by the timer to manage the AUN transmit queue.  If a packet
00954  *      was sent to a dead or nonexistent host then we will never get an
00955  *      acknowledgement back.  After a few seconds we need to spot this and
00956  *      drop the packet.
00957  */
00958 
00959 
00960 static void ab_cleanup(unsigned long h)
00961 {
00962         struct sk_buff *skb;
00963         unsigned long flags;
00964 
00965         spin_lock_irqsave(&aun_queue_lock, flags);
00966         skb = skb_peek(&aun_queue);
00967         while (skb && skb != (struct sk_buff *)&aun_queue)
00968         {
00969                 struct sk_buff *newskb = skb->next;
00970                 struct ec_cb *eb = (struct ec_cb *)&skb->cb;
00971                 if ((jiffies - eb->start) > eb->timeout)
00972                 {
00973                         tx_result(skb->sk, eb->cookie, 
00974                                   ECTYPE_TRANSMIT_NOT_PRESENT);
00975                         skb_unlink(skb);
00976                 }
00977                 skb = newskb;
00978         }
00979         spin_unlock_irqrestore(&aun_queue_lock, flags);
00980 
00981         mod_timer(&ab_cleanup_timer, jiffies + (HZ*2));
00982 }
00983 
00984 __initfunc(static int aun_udp_initialise(void))
00985 {
00986         int error;
00987         struct sockaddr_in sin;
00988 
00989         skb_queue_head_init(&aun_queue);
00990         spin_lock_init(&aun_queue_lock);
00991         init_timer(&ab_cleanup_timer);
00992         ab_cleanup_timer.expires = jiffies + (HZ*2);
00993         ab_cleanup_timer.function = ab_cleanup;
00994         add_timer(&ab_cleanup_timer);
00995 
00996         memset(&sin, 0, sizeof(sin));
00997         sin.sin_port = htons(AUN_PORT);
00998 
00999         /* We can count ourselves lucky Acorn machines are too dim to
01000            speak IPv6. :-) */
01001         if ((error = sock_create(PF_INET, SOCK_DGRAM, 0, &udpsock)) < 0)
01002         {
01003                 printk("AUN: socket error %d\n", -error);
01004                 return error;
01005         }
01006         
01007         udpsock->sk->reuse = 1;
01008         udpsock->sk->allocation = GFP_ATOMIC;   /* we're going to call it
01009                                                    from interrupts */
01010         
01011         error = udpsock->ops->bind(udpsock, (struct sockaddr *)&sin,
01012                                 sizeof(sin));
01013         if (error < 0)
01014         {
01015                 printk("AUN: bind error %d\n", -error);
01016                 goto release;
01017         }
01018 
01019         udpsock->sk->data_ready = aun_data_available;
01020 
01021         return 0;
01022 
01023 release:
01024         sock_release(udpsock);
01025         udpsock = NULL;
01026         return error;
01027 }
01028 #endif
01029 
01030 static int econet_notifier(struct notifier_block *this, unsigned long msg, void *data)
01031 {
01032         struct device *dev = (struct device *)data;
01033         struct ec_device *edev;
01034         unsigned long flags;
01035 
01036         switch (msg) {
01037         case NETDEV_UNREGISTER:
01038                 /* A device has gone down - kill any data we hold for it. */
01039                 spin_lock_irqsave(&edevlist_lock, flags);
01040                 for (edev = edevlist; edev; edev = edev->next)
01041                 {
01042                         if (edev->dev == dev)
01043                         {
01044                                 if (edev->prev)
01045                                         edev->prev->next = edev->next;
01046                                 else
01047                                         edevlist = edev->next;
01048                                 if (edev->next)
01049                                         edev->next->prev = edev->prev;
01050                                 kfree(edev);
01051                                 break;
01052                         }
01053                 }
01054                 spin_unlock_irqrestore(&edevlist_lock, flags);
01055                 break;
01056         }
01057 
01058         return NOTIFY_DONE;
01059 }
01060 
01061 struct notifier_block econet_netdev_notifier={
01062         econet_notifier,
01063         NULL,
01064         0
01065 };
01066 
01067 #ifdef MODULE
01068 void cleanup_module(void)
01069 {
01070 #ifdef CONFIG_ECONET_AUNUDP
01071         del_timer(&ab_cleanup_timer);
01072         if (udpsock)
01073                 sock_release(udpsock);
01074 #endif
01075         unregister_netdevice_notifier(&econet_netdev_notifier);
01076         sock_unregister(econet_family_ops.family);
01077         return;
01078 }
01079 
01080 int init_module(void)
01081 #else
01082 __initfunc(void econet_proto_init(struct net_proto *pro))
01083 #endif
01084 {
01085         spin_lock_init(&edevlist_lock);
01086         spin_lock_init(&aun_queue_lock);
01087         /* Stop warnings from happening on UP systems. */
01088         (void)edevlist_lock;
01089         (void)aun_queue_lock;
01090         sock_register(&econet_family_ops);
01091 #ifdef CONFIG_ECONET_AUNUDP
01092         aun_udp_initialise();
01093 #endif
01094         register_netdevice_notifier(&econet_netdev_notifier);
01095 #ifdef MODULE
01096         return 0;
01097 #endif
01098 }