patch-1.3.81 linux/net/802/p8022tr.c
Next file: linux/net/appletalk/ddp.c
Previous file: linux/net/802/Makefile
Back to the patch index
Back to the overall index
- Lines: 138
- Date:
Sat Mar 30 13:20:33 1996
- Orig file:
v1.3.80/linux/net/802/p8022tr.c
- Orig date:
Thu Jan 1 02:00:00 1970
diff -u --recursive --new-file v1.3.80/linux/net/802/p8022tr.c linux/net/802/p8022tr.c
@@ -0,0 +1,137 @@
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <net/datalink.h>
+#include <linux/mm.h>
+#include <linux/in.h>
+#include <net/p8022tr.h>
+
+#define SNAP_HEADER_LEN 8
+
+static struct datalink_proto *p8022tr_list = NULL;
+
+/*
+ * We don't handle the loopback SAP stuff, the extended
+ * 802.2 command set, multicast SAP identifiers and non UI
+ * frames. We have the absolute minimum needed for IPX,
+ * IP and Appletalk phase 2.
+ */
+
+static struct datalink_proto *
+find_8022tr_client(unsigned char type)
+{
+ struct datalink_proto *proto;
+
+ for (proto = p8022tr_list;
+ ((proto != NULL) && (*(proto->type) != type));
+ proto = proto->next)
+ ;
+
+ return proto;
+}
+
+int
+p8022tr_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
+{
+ struct datalink_proto *proto;
+
+ proto = find_8022tr_client(*(skb->h.raw));
+ if (proto != NULL) {
+ skb->h.raw += 3;
+ skb_pull(skb,3);
+ return proto->rcvfunc(skb, dev, pt);
+ }
+
+ skb->sk = NULL;
+ kfree_skb(skb, FREE_READ);
+ return 0;
+}
+
+static void
+p8022tr_datalink_header(struct datalink_proto *dl,
+ struct sk_buff *skb, unsigned char *dest_node)
+{
+ struct device *dev = skb->dev;
+ unsigned char *rawp;
+ unsigned char *olddata;
+ unsigned char *newdata;
+
+ rawp = skb_push(skb,3);
+ *rawp++ = dl->type[0];
+ *rawp++ = dl->type[0];
+ *rawp = 0x03; /* UI */
+ dev->hard_header(skb, dev, ETH_P_802_3, dest_node, NULL, skb->len);
+ olddata = skb->data;
+ newdata = skb_pull(skb, SNAP_HEADER_LEN);
+ memmove(newdata, olddata, dev->hard_header_len - SNAP_HEADER_LEN);
+}
+
+static struct packet_type p8022tr_packet_type =
+{
+ 0,
+ NULL, /* All devices */
+ p8022tr_rcv,
+ NULL,
+ NULL,
+};
+
+
+static struct symbol_table p8022tr_proto_syms = {
+#include <linux/symtab_begin.h>
+ X(register_8022tr_client),
+ X(unregister_8022tr_client),
+#include <linux/symtab_end.h>
+};
+
+void p8022tr_proto_init(struct net_proto *pro)
+{
+ p8022tr_packet_type.type=htons(ETH_P_TR_802_2);
+ dev_add_pack(&p8022tr_packet_type);
+ register_symtab(&p8022tr_proto_syms);
+}
+
+struct datalink_proto *
+register_8022tr_client(unsigned char type, int (*rcvfunc)(struct sk_buff *, struct device *, struct packet_type *))
+{
+ struct datalink_proto *proto;
+
+ if (find_8022tr_client(type) != NULL)
+ return NULL;
+
+ proto = (struct datalink_proto *) kmalloc(sizeof(*proto), GFP_ATOMIC);
+ if (proto != NULL) {
+ proto->type[0] = type;
+ proto->type_len = 1;
+ proto->rcvfunc = rcvfunc;
+ proto->header_length = 3;
+ proto->datalink_header = p8022tr_datalink_header;
+ proto->string_name = "802.2TR";
+ proto->next = p8022tr_list;
+ p8022tr_list = proto;
+ }
+
+ return proto;
+}
+
+void unregister_8022tr_client(unsigned char type)
+{
+ struct datalink_proto *tmp, **clients = &p8022tr_list;
+ unsigned long flags;
+
+ save_flags(flags);
+ cli();
+
+ while ((tmp = *clients) != NULL)
+ {
+ if (tmp->type[0] == type) {
+ *clients = tmp->next;
+ kfree_s(tmp, sizeof(struct datalink_proto));
+ break;
+ } else {
+ clients = &tmp->next;
+ }
+ }
+
+ restore_flags(flags);
+}
+
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov
with Sam's (original) version of this