0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/module.h>
0011 #include <linux/netdevice.h>
0012 #include <linux/skbuff.h>
0013 #include <linux/slab.h>
0014 #include <net/datalink.h>
0015 #include <net/llc.h>
0016 #include <net/psnap.h>
0017 #include <linux/mm.h>
0018 #include <linux/in.h>
0019 #include <linux/init.h>
0020 #include <linux/rculist.h>
0021
0022 static LIST_HEAD(snap_list);
0023 static DEFINE_SPINLOCK(snap_lock);
0024 static struct llc_sap *snap_sap;
0025
0026
0027
0028
0029 static struct datalink_proto *find_snap_client(const unsigned char *desc)
0030 {
0031 struct datalink_proto *proto = NULL, *p;
0032
0033 list_for_each_entry_rcu(p, &snap_list, node, lockdep_is_held(&snap_lock)) {
0034 if (!memcmp(p->type, desc, 5)) {
0035 proto = p;
0036 break;
0037 }
0038 }
0039 return proto;
0040 }
0041
0042
0043
0044
0045 static int snap_rcv(struct sk_buff *skb, struct net_device *dev,
0046 struct packet_type *pt, struct net_device *orig_dev)
0047 {
0048 int rc = 1;
0049 struct datalink_proto *proto;
0050 static struct packet_type snap_packet_type = {
0051 .type = cpu_to_be16(ETH_P_SNAP),
0052 };
0053
0054 if (unlikely(!pskb_may_pull(skb, 5)))
0055 goto drop;
0056
0057 rcu_read_lock();
0058 proto = find_snap_client(skb_transport_header(skb));
0059 if (proto) {
0060
0061 skb->transport_header += 5;
0062 skb_pull_rcsum(skb, 5);
0063 rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev);
0064 }
0065 rcu_read_unlock();
0066
0067 if (unlikely(!proto))
0068 goto drop;
0069
0070 out:
0071 return rc;
0072
0073 drop:
0074 kfree_skb(skb);
0075 goto out;
0076 }
0077
0078
0079
0080
0081 static int snap_request(struct datalink_proto *dl,
0082 struct sk_buff *skb, const u8 *dest)
0083 {
0084 memcpy(skb_push(skb, 5), dl->type, 5);
0085 llc_build_and_send_ui_pkt(snap_sap, skb, dest, snap_sap->laddr.lsap);
0086 return 0;
0087 }
0088
0089
0090
0091
0092 EXPORT_SYMBOL(register_snap_client);
0093 EXPORT_SYMBOL(unregister_snap_client);
0094
0095 static const char snap_err_msg[] __initconst =
0096 KERN_CRIT "SNAP - unable to register with 802.2\n";
0097
0098 static int __init snap_init(void)
0099 {
0100 snap_sap = llc_sap_open(0xAA, snap_rcv);
0101 if (!snap_sap) {
0102 printk(snap_err_msg);
0103 return -EBUSY;
0104 }
0105
0106 return 0;
0107 }
0108
0109 module_init(snap_init);
0110
0111 static void __exit snap_exit(void)
0112 {
0113 llc_sap_put(snap_sap);
0114 }
0115
0116 module_exit(snap_exit);
0117
0118
0119
0120
0121
0122 struct datalink_proto *register_snap_client(const unsigned char *desc,
0123 int (*rcvfunc)(struct sk_buff *,
0124 struct net_device *,
0125 struct packet_type *,
0126 struct net_device *))
0127 {
0128 struct datalink_proto *proto = NULL;
0129
0130 spin_lock_bh(&snap_lock);
0131
0132 if (find_snap_client(desc))
0133 goto out;
0134
0135 proto = kmalloc(sizeof(*proto), GFP_ATOMIC);
0136 if (proto) {
0137 memcpy(proto->type, desc, 5);
0138 proto->rcvfunc = rcvfunc;
0139 proto->header_length = 5 + 3;
0140 proto->request = snap_request;
0141 list_add_rcu(&proto->node, &snap_list);
0142 }
0143 out:
0144 spin_unlock_bh(&snap_lock);
0145
0146 return proto;
0147 }
0148
0149
0150
0151
0152 void unregister_snap_client(struct datalink_proto *proto)
0153 {
0154 spin_lock_bh(&snap_lock);
0155 list_del_rcu(&proto->node);
0156 spin_unlock_bh(&snap_lock);
0157
0158 synchronize_net();
0159
0160 kfree(proto);
0161 }
0162
0163 MODULE_LICENSE("GPL");