linux-old/net/802/psnap.c
<<
>>
Prefs
   1/*
   2 *      SNAP data link layer. Derived from 802.2
   3 *
   4 *              Alan Cox <Alan.Cox@linux.org>, from the 802.2 layer by Greg Page.
   5 *              Merged in additions from Greg Page's psnap.c.
   6 *
   7 *              This program is free software; you can redistribute it and/or
   8 *              modify it under the terms of the GNU General Public License
   9 *              as published by the Free Software Foundation; either version
  10 *              2 of the License, or (at your option) any later version.
  11 */
  12
  13#include <linux/module.h>
  14#include <linux/netdevice.h>
  15#include <linux/skbuff.h>
  16#include <net/datalink.h>
  17#include <net/p8022.h>
  18#include <net/psnap.h>
  19#include <linux/mm.h>
  20#include <linux/in.h>
  21#include <linux/init.h>
  22
  23static struct datalink_proto *snap_list = NULL;
  24static struct datalink_proto *snap_dl = NULL;           /* 802.2 DL for SNAP */
  25
  26/*
  27 *      Find a snap client by matching the 5 bytes.
  28 */
  29
  30static struct datalink_proto *find_snap_client(unsigned char *desc)
  31{
  32        struct datalink_proto   *proto;
  33
  34        for (proto = snap_list; proto != NULL && memcmp(proto->type, desc, 5) ; proto = proto->next);
  35        return proto;
  36}
  37
  38/*
  39 *      A SNAP packet has arrived
  40 */
  41
  42int snap_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
  43{
  44        static struct packet_type psnap_packet_type =
  45        {
  46                0,
  47                NULL,           /* All Devices */
  48                snap_rcv,
  49                NULL,
  50                NULL,
  51        };
  52
  53        struct datalink_proto   *proto;
  54
  55        proto = find_snap_client(skb->h.raw);
  56        if (proto != NULL)
  57        {
  58                /*
  59                 *      Pass the frame on.
  60                 */
  61
  62                skb->h.raw += 5;
  63                skb->nh.raw += 5;
  64                skb_pull(skb,5);
  65                if (psnap_packet_type.type == 0)
  66                        psnap_packet_type.type=htons(ETH_P_SNAP);
  67
  68                return proto->rcvfunc(skb, dev, &psnap_packet_type);
  69        }
  70        skb->sk = NULL;
  71        kfree_skb(skb);
  72        return 0;
  73}
  74
  75/*
  76 *      Put a SNAP header on a frame and pass to 802.2
  77 */
  78
  79static void snap_datalink_header(struct datalink_proto *dl, struct sk_buff *skb, unsigned char *dest_node)
  80{
  81        memcpy(skb_push(skb,5),dl->type,5);
  82        snap_dl->datalink_header(snap_dl, skb, dest_node);
  83}
  84
  85/*
  86 *      Set up the SNAP layer
  87 */
  88
  89EXPORT_SYMBOL(register_snap_client);
  90EXPORT_SYMBOL(unregister_snap_client);
  91
  92static int __init snap_init(void)
  93{
  94        snap_dl=register_8022_client(0xAA, snap_rcv);
  95        if(snap_dl==NULL)
  96                printk("SNAP - unable to register with 802.2\n");
  97        return 0;
  98}
  99
 100static void __exit snap_exit(void)
 101{
 102        unregister_8022_client(0xAA);
 103}
 104
 105module_init(snap_init);
 106module_exit(snap_exit);
 107
 108
 109/*
 110 *      Register SNAP clients. We don't yet use this for IP.
 111 */
 112
 113struct datalink_proto *register_snap_client(unsigned char *desc, int (*rcvfunc)(struct sk_buff *, struct net_device *, struct packet_type *))
 114{
 115        struct datalink_proto   *proto;
 116
 117        if (find_snap_client(desc) != NULL)
 118                return NULL;
 119
 120        proto = (struct datalink_proto *) kmalloc(sizeof(*proto), GFP_ATOMIC);
 121        if (proto != NULL)
 122        {
 123                memcpy(proto->type, desc,5);
 124                proto->type_len = 5;
 125                proto->rcvfunc = rcvfunc;
 126                proto->header_length = 5+snap_dl->header_length;
 127                proto->datalink_header = snap_datalink_header;
 128                proto->string_name = "SNAP";
 129                proto->next = snap_list;
 130                snap_list = proto;
 131        }
 132
 133        return proto;
 134}
 135
 136/*
 137 *      Unregister SNAP clients. Protocols no longer want to play with us ...
 138 */
 139
 140void unregister_snap_client(unsigned char *desc)
 141{
 142        struct datalink_proto **clients = &snap_list;
 143        struct datalink_proto *tmp;
 144        unsigned long flags;
 145
 146        save_flags(flags);
 147        cli();
 148
 149        while ((tmp = *clients) != NULL)
 150        {
 151                if (memcmp(tmp->type,desc,5) == 0)
 152                {
 153                        *clients = tmp->next;
 154                        kfree(tmp);
 155                        break;
 156                }
 157                else
 158                        clients = &tmp->next;
 159        }
 160
 161        restore_flags(flags);
 162}
 163
 164MODULE_LICENSE("GPL");
 165
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.