root/net/802/p8022.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. find_8022_client
  2. p8022_rcv
  3. p8022_datalink_header
  4. p8022_proto_init
  5. register_8022_client
  6. unregister_8022_client

   1 #include <linux/module.h>
   2 #include <linux/netdevice.h>
   3 #include <linux/skbuff.h>
   4 #include <net/datalink.h>
   5 #include <linux/mm.h>
   6 #include <linux/in.h>
   7 #include <net/p8022.h>
   8 
   9 static struct datalink_proto *p8022_list = NULL;
  10 
  11 /*
  12  *      We don't handle the loopback SAP stuff, the extended
  13  *      802.2 command set, multicast SAP identifiers and non UI
  14  *      frames. We have the absolute minimum needed for IPX,
  15  *      IP and Appletalk phase 2.
  16  */
  17  
  18 static struct datalink_proto *
  19 find_8022_client(unsigned char type)
     /* [previous][next][first][last][top][bottom][index][help] */
  20 {
  21         struct datalink_proto   *proto;
  22 
  23         for (proto = p8022_list;
  24                 ((proto != NULL) && (*(proto->type) != type));
  25                 proto = proto->next)
  26                 ;
  27 
  28         return proto;
  29 }
  30 
  31 int
  32 p8022_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
     /* [previous][next][first][last][top][bottom][index][help] */
  33 {
  34         struct datalink_proto   *proto;
  35 
  36         proto = find_8022_client(*(skb->h.raw));
  37         if (proto != NULL) {
  38                 skb->h.raw += 3;
  39                 skb_pull(skb,3);
  40                 return proto->rcvfunc(skb, dev, pt);
  41         }
  42 
  43         skb->sk = NULL;
  44         kfree_skb(skb, FREE_READ);
  45         return 0;
  46 }
  47 
  48 static void
  49 p8022_datalink_header(struct datalink_proto *dl, 
     /* [previous][next][first][last][top][bottom][index][help] */
  50                 struct sk_buff *skb, unsigned char *dest_node)
  51 {
  52         struct device   *dev = skb->dev;
  53         unsigned char   *rawp;
  54 
  55         rawp = skb_push(skb,3);
  56         *rawp++ = dl->type[0];
  57         *rawp++ = dl->type[0];
  58         *rawp = 0x03;   /* UI */
  59         dev->hard_header(skb, dev, ETH_P_802_3, dest_node, NULL, skb->len);
  60 }
  61 
  62 static struct packet_type p8022_packet_type = 
  63 {
  64         0,      /* MUTTER ntohs(ETH_P_8022),*/
  65         NULL,           /* All devices */
  66         p8022_rcv,
  67         NULL,
  68         NULL,
  69 };
  70 
  71 static struct symbol_table p8022_proto_syms = {
  72 #include <linux/symtab_begin.h>
  73         X(register_8022_client),
  74         X(unregister_8022_client),
  75 #include <linux/symtab_end.h>
  76 };
  77  
  78 
  79 void p8022_proto_init(struct net_proto *pro)
     /* [previous][next][first][last][top][bottom][index][help] */
  80 {
  81         p8022_packet_type.type=htons(ETH_P_802_2);
  82         dev_add_pack(&p8022_packet_type);
  83         register_symtab(&p8022_proto_syms);
  84 }
  85         
  86 struct datalink_proto *
  87 register_8022_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *))
     /* [previous][next][first][last][top][bottom][index][help] */
  88 {
  89         struct datalink_proto   *proto;
  90 
  91         if (find_8022_client(type) != NULL)
  92                 return NULL;
  93 
  94         proto = (struct datalink_proto *) kmalloc(sizeof(*proto), GFP_ATOMIC);
  95         if (proto != NULL) {
  96                 proto->type[0] = type;
  97                 proto->type_len = 1;
  98                 proto->rcvfunc = rcvfunc;
  99                 proto->header_length = 3;
 100                 proto->datalink_header = p8022_datalink_header;
 101                 proto->string_name = "802.2";
 102                 proto->next = p8022_list;
 103                 p8022_list = proto;
 104         }
 105 
 106         return proto;
 107 }
 108 
 109 void unregister_8022_client(unsigned char type)
     /* [previous][next][first][last][top][bottom][index][help] */
 110 {
 111         struct datalink_proto *tmp, **clients = &p8022_list;
 112         unsigned long flags;
 113 
 114         save_flags(flags);
 115         cli();
 116 
 117         while ((tmp = *clients) != NULL)
 118         {
 119                 if (tmp->type[0] == type) {
 120                         *clients = tmp->next;
 121                         kfree_s(tmp, sizeof(struct datalink_proto));
 122                         break;
 123                 } else {
 124                         clients = &tmp->next;
 125                 }
 126         }
 127 
 128         restore_flags(flags);
 129 }

/* [previous][next][first][last][top][bottom][index][help] */