📄 psnap.c
字号:
/* * SNAP data link layer. Derived from 802.2 * * Alan Cox <Alan.Cox@linux.org>, * from the 802.2 layer by Greg Page. * Merged in additions from Greg Page's psnap.c. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. */#include <linux/module.h>#include <linux/netdevice.h>#include <linux/skbuff.h>#include <net/datalink.h>#include <net/llc.h>#include <net/psnap.h>#include <linux/mm.h>#include <linux/in.h>#include <linux/init.h>static LIST_HEAD(snap_list);static DEFINE_SPINLOCK(snap_lock);static struct llc_sap *snap_sap;/* * Find a snap client by matching the 5 bytes. */static struct datalink_proto *find_snap_client(unsigned char *desc){ struct list_head *entry; struct datalink_proto *proto = NULL, *p; list_for_each_rcu(entry, &snap_list) { p = list_entry(entry, struct datalink_proto, node); if (!memcmp(p->type, desc, 5)) { proto = p; break; } } return proto;}/* * A SNAP packet has arrived */static int snap_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev){ int rc = 1; struct datalink_proto *proto; static struct packet_type snap_packet_type = { .type = __constant_htons(ETH_P_SNAP), }; if (unlikely(!pskb_may_pull(skb, 5))) goto drop; rcu_read_lock(); proto = find_snap_client(skb_transport_header(skb)); if (proto) { /* Pass the frame on. */ skb->transport_header += 5; skb_pull_rcsum(skb, 5); rc = proto->rcvfunc(skb, dev, &snap_packet_type, orig_dev); } rcu_read_unlock(); if (unlikely(!proto)) goto drop;out: return rc;drop: kfree_skb(skb); goto out;}/* * Put a SNAP header on a frame and pass to 802.2 */static int snap_request(struct datalink_proto *dl, struct sk_buff *skb, u8 *dest){ memcpy(skb_push(skb, 5), dl->type, 5); llc_build_and_send_ui_pkt(snap_sap, skb, dest, snap_sap->laddr.lsap); return 0;}/* * Set up the SNAP layer */EXPORT_SYMBOL(register_snap_client);EXPORT_SYMBOL(unregister_snap_client);static char snap_err_msg[] __initdata = KERN_CRIT "SNAP - unable to register with 802.2\n";static int __init snap_init(void){ snap_sap = llc_sap_open(0xAA, snap_rcv); if (!snap_sap) printk(snap_err_msg); return 0;}module_init(snap_init);static void __exit snap_exit(void){ llc_sap_put(snap_sap);}module_exit(snap_exit);/* * Register SNAP clients. We don't yet use this for IP. */struct datalink_proto *register_snap_client(unsigned char *desc, int (*rcvfunc)(struct sk_buff *, struct net_device *, struct packet_type *, struct net_device *)){ struct datalink_proto *proto = NULL; spin_lock_bh(&snap_lock); if (find_snap_client(desc)) goto out; proto = kmalloc(sizeof(*proto), GFP_ATOMIC); if (proto) { memcpy(proto->type, desc,5); proto->rcvfunc = rcvfunc; proto->header_length = 5 + 3; /* snap + 802.2 */ proto->request = snap_request; list_add_rcu(&proto->node, &snap_list); }out: spin_unlock_bh(&snap_lock); synchronize_net(); return proto;}/* * Unregister SNAP clients. Protocols no longer want to play with us ... */void unregister_snap_client(struct datalink_proto *proto){ spin_lock_bh(&snap_lock); list_del_rcu(&proto->node); spin_unlock_bh(&snap_lock); synchronize_net(); kfree(proto);}MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -