patch-2.1.15 linux/net/802/llc_macinit.c
Next file: linux/net/802/llc_sendpdu.c
Previous file: linux/net/802/llc.c
Back to the patch index
Back to the overall index
- Lines: 226
- Date:
Thu Dec 12 16:54:22 1996
- Orig file:
v2.1.14/linux/net/802/llc_macinit.c
- Orig date:
Thu Jan 1 02:00:00 1970
diff -u --recursive --new-file v2.1.14/linux/net/802/llc_macinit.c linux/net/802/llc_macinit.c
@@ -0,0 +1,225 @@
+/*
+ * NET An implementation of the IEEE 802.2 LLC protocol for the
+ * LINUX operating system. LLC is implemented as a set of
+ * state machines and callbacks for higher networking layers.
+ *
+ * Code for initialization, termination, registration and
+ * MAC layer glue.
+ *
+ * Written by Tim Alpaerts, Tim_Alpaerts@toyota-motor-europe.com
+ *
+ * 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.
+ *
+ * Changes
+ * Alan Cox : Chainsawed to Linux format
+ * Added llc_ to names
+ * Started restructuring handlers
+ */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/kernel.h>
+#include <linux/malloc.h>
+#include <linux/unistd.h>
+#include <linux/netdevice.h>
+#include <net/p8022.h>
+
+#include <asm/byteorder.h>
+
+#include <net/llc_frame.h>
+#include <net/llc.h>
+
+/*
+ * All incoming frames pass thru mac_data_indicate().
+ * Here an llc structure is associated with an skb depending on the source
+ * MAC address in the pdu.
+ * The received sk_buffs with pdus other than I_CMD and I_RSP
+ * are freed by mac_data_indicate() after processing,
+ * the I pdu buffers are freed by the cl2llc client when it no longer needs
+ * the skb.
+*/
+
+int llc_mac_data_indicate(llcptr lp, struct sk_buff *skb, struct device *dev, struct packet_type *pt)
+{
+ int ll; /* logical length == 802.3 length field */
+ unsigned char p_flag;
+ unsigned char type;
+ frameptr fr;
+ int free=1;
+
+ /*
+ * Truncate buffer to true 802.3 length
+ * [FIXME: move to 802.2 demux]
+ */
+
+ ll = *(skb->data -2) * 256 + *(skb->data -1);
+ skb_trim( skb, ll );
+
+ fr = (frameptr) skb->data;
+ type = llc_decode_frametype( fr );
+
+
+ if (type <= FRMR_RSP)
+ {
+ /*
+ * PDU is of the type 2 set
+ */
+ if ((lp->llc_mode == MODE_ABM)||(type == SABME_CMD))
+ llc_process_otype2_frame(lp, skb, type);
+
+ }
+ else
+ {
+ /*
+ * PDU belongs to type 1 set
+ */
+ p_flag = fr->u_hdr.u_pflag;
+ switch(type)
+ {
+ case TEST_CMD:
+ llc_sendpdu(lp, TEST_RSP, 0,ll -3,
+ fr->u_hdr.u_info);
+ break;
+ case TEST_RSP:
+ if (lp->ops->test_indication_ep != NULL)
+ {
+ lp->ops->test_indication_ep(lp,
+ ll -3, fr->u_hdr.u_info);
+ }
+ break;
+ case XID_CMD:
+ /*
+ * Basic format XID is handled by LLC itself
+ * Doc 5.4.1.1.2 p 48/49
+ */
+
+ if ((ll == 6)&&(fr->u_hdr.u_info[0] == 0x81))
+ {
+ lp->k = fr->u_hdr.u_info[2];
+ llc_sendpdu(lp, XID_RSP,
+ fr->u_hdr.u_pflag, ll -3,
+ fr->u_hdr.u_info);
+ }
+ break;
+
+ case XID_RSP:
+ if( ll == 6 && fr->u_hdr.u_info[0] == 0x81 )
+ {
+ lp->k = fr->u_hdr.u_info[2];
+ }
+ if (lp->ops->xid_indication_ep != NULL)
+ {
+ lp->ops->xid_indication_ep(lp,
+ ll-3, fr->u_hdr.u_info);
+ }
+ break;
+
+ case UI_CMD:
+ if(lp->ops->unit_data_indication_ep != NULL)
+ {
+ free=lp->ops->unit_data_indication_ep(lp,
+ ll-3, fr->u_hdr.u_info);
+ }
+ break;
+
+ default:
+ /*
+ * All other type 1 pdus ignored for now
+ */
+ }
+ }
+
+ if (free&&(!(IS_IFRAME(fr))))
+ {
+ /*
+ * No auto free for I pdus
+ */
+ skb->sk = NULL;
+ kfree_skb(skb, FREE_READ);
+ }
+ return 0;
+}
+
+
+/*
+ * Create an LLC client. As it is the job of the caller to clean up
+ * LLC's on device down, the device list must be locked before this call.
+ */
+
+int register_cl2llc_client(llcptr lp, const char *device, llc_ops *ops, u8 *rmac, u8 ssap, u8 dsap)
+{
+ char eye_init[] = "LLC\0";
+
+ memset(lp, 0, sizeof(*lp));
+ lp->dev = dev_get(device);
+ if(lp->dev == NULL)
+ return -ENODEV;
+ memcpy(lp->eye, eye_init, sizeof(lp->eye));
+ lp->rw = 1;
+ lp->k = 127;
+ lp->n1 = 1490;
+ lp->n2 = 10;
+ lp->timer_interval[P_TIMER] = HZ; /* 1 sec */
+ lp->timer_interval[REJ_TIMER] = HZ/8;
+ lp->timer_interval[ACK_TIMER] = HZ/8;
+ lp->timer_interval[BUSY_TIMER] = HZ*2;
+ lp->local_sap = ssap;
+ lp->ops = ops;
+ lp->remote_mac_len = lp->dev->addr_len;
+ memcpy(lp->remote_mac, rmac, lp->remote_mac_len);
+ lp->state = 0;
+ lp->llc_mode = MODE_ADM;
+ lp->remote_sap = dsap;
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+
+void unregister_cl2llc_client(llcptr lp)
+{
+ llc_cancel_timers(lp);
+ MOD_DEC_USE_COUNT;
+ kfree(lp);
+}
+
+
+static struct symbol_table cl2llc_proto_syms =
+{
+#include <linux/symtab_begin.h>
+ X(register_cl2llc_client),
+ X(unregister_cl2llc_client),
+ X(llc_data_request),
+ X(llc_unit_data_request),
+ X(llc_test_request),
+ X(llc_xid_request),
+#include <linux/symtab_end.h>
+};
+
+
+#define ALL_TYPES_8022 0
+
+void llc_init(struct net_proto *proto)
+{
+ register_symtab( &cl2llc_proto_syms );
+ printk(KERN_NOTICE "IEEE 802.2 LLC for Linux 2.1 (c) 1996 Tim Alpaerts\n");
+ return;
+}
+
+#ifdef MODULE
+
+
+int init_module(void)
+{
+ llc_init(NULL);
+ return 0;
+}
+
+void cleanup_module(void)
+{
+
+}
+
+#endif
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov