Linux Audio

Check our new training course

Loading...
v6.2
  1/*
  2 * llc_station.c - station component of LLC
  3 *
  4 * Copyright (c) 1997 by Procom Technology, Inc.
  5 * 		 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  6 *
  7 * This program can be redistributed or modified under the terms of the
  8 * GNU General Public License as published by the Free Software Foundation.
  9 * This program is distributed without any warranty or implied warranty
 10 * of merchantability or fitness for a particular purpose.
 11 *
 12 * See the GNU General Public License for more details.
 13 */
 14#include <linux/init.h>
 15#include <linux/module.h>
 16#include <linux/slab.h>
 17#include <net/llc.h>
 18#include <net/llc_sap.h>
 19#include <net/llc_conn.h>
 20#include <net/llc_c_ac.h>
 21#include <net/llc_s_ac.h>
 22#include <net/llc_c_ev.h>
 23#include <net/llc_c_st.h>
 24#include <net/llc_s_ev.h>
 25#include <net/llc_s_st.h>
 26#include <net/llc_pdu.h>
 27
 28static int llc_stat_ev_rx_null_dsap_xid_c(struct sk_buff *skb)
 29{
 30	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 31
 32	return LLC_PDU_IS_CMD(pdu) &&			/* command PDU */
 33	       LLC_PDU_TYPE_IS_U(pdu) &&		/* U type PDU */
 34	       LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_XID &&
 35	       !pdu->dsap;				/* NULL DSAP value */
 36}
 37
 38static int llc_stat_ev_rx_null_dsap_test_c(struct sk_buff *skb)
 39{
 40	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 41
 42	return LLC_PDU_IS_CMD(pdu) &&			/* command PDU */
 43	       LLC_PDU_TYPE_IS_U(pdu) &&		/* U type PDU */
 44	       LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_TEST &&
 45	       !pdu->dsap;				/* NULL DSAP */
 46}
 47
 48static int llc_station_ac_send_xid_r(struct sk_buff *skb)
 49{
 50	u8 mac_da[ETH_ALEN], dsap;
 51	int rc = 1;
 52	struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U,
 53					       sizeof(struct llc_xid_info));
 54
 55	if (!nskb)
 56		goto out;
 
 57	llc_pdu_decode_sa(skb, mac_da);
 58	llc_pdu_decode_ssap(skb, &dsap);
 59	llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
 60	llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 127);
 61	rc = llc_mac_hdr_init(nskb, skb->dev->dev_addr, mac_da);
 62	if (unlikely(rc))
 63		goto free;
 64	dev_queue_xmit(nskb);
 65out:
 66	return rc;
 67free:
 68	kfree_skb(nskb);
 69	goto out;
 70}
 71
 72static int llc_station_ac_send_test_r(struct sk_buff *skb)
 73{
 74	u8 mac_da[ETH_ALEN], dsap;
 75	int rc = 1;
 76	u32 data_size;
 77	struct sk_buff *nskb;
 78
 79	/* The test request command is type U (llc_len = 3) */
 80	data_size = ntohs(eth_hdr(skb)->h_proto) - 3;
 81	nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, data_size);
 82
 83	if (!nskb)
 84		goto out;
 
 85	llc_pdu_decode_sa(skb, mac_da);
 86	llc_pdu_decode_ssap(skb, &dsap);
 87	llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
 88	llc_pdu_init_as_test_rsp(nskb, skb);
 89	rc = llc_mac_hdr_init(nskb, skb->dev->dev_addr, mac_da);
 90	if (unlikely(rc))
 91		goto free;
 92	dev_queue_xmit(nskb);
 93out:
 94	return rc;
 95free:
 96	kfree_skb(nskb);
 97	goto out;
 98}
 99
100/**
101 *	llc_station_rcv - send received pdu to the station state machine
102 *	@skb: received frame.
103 *
104 *	Sends data unit to station state machine.
105 */
106static void llc_station_rcv(struct sk_buff *skb)
107{
108	if (llc_stat_ev_rx_null_dsap_xid_c(skb))
109		llc_station_ac_send_xid_r(skb);
110	else if (llc_stat_ev_rx_null_dsap_test_c(skb))
111		llc_station_ac_send_test_r(skb);
112	kfree_skb(skb);
113}
114
115void __init llc_station_init(void)
116{
117	llc_set_station_handler(llc_station_rcv);
118}
119
120void llc_station_exit(void)
121{
122	llc_set_station_handler(NULL);
123}
v5.9
  1/*
  2 * llc_station.c - station component of LLC
  3 *
  4 * Copyright (c) 1997 by Procom Technology, Inc.
  5 * 		 2001-2003 by Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  6 *
  7 * This program can be redistributed or modified under the terms of the
  8 * GNU General Public License as published by the Free Software Foundation.
  9 * This program is distributed without any warranty or implied warranty
 10 * of merchantability or fitness for a particular purpose.
 11 *
 12 * See the GNU General Public License for more details.
 13 */
 14#include <linux/init.h>
 15#include <linux/module.h>
 16#include <linux/slab.h>
 17#include <net/llc.h>
 18#include <net/llc_sap.h>
 19#include <net/llc_conn.h>
 20#include <net/llc_c_ac.h>
 21#include <net/llc_s_ac.h>
 22#include <net/llc_c_ev.h>
 23#include <net/llc_c_st.h>
 24#include <net/llc_s_ev.h>
 25#include <net/llc_s_st.h>
 26#include <net/llc_pdu.h>
 27
 28static int llc_stat_ev_rx_null_dsap_xid_c(struct sk_buff *skb)
 29{
 30	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 31
 32	return LLC_PDU_IS_CMD(pdu) &&			/* command PDU */
 33	       LLC_PDU_TYPE_IS_U(pdu) &&		/* U type PDU */
 34	       LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_XID &&
 35	       !pdu->dsap;				/* NULL DSAP value */
 36}
 37
 38static int llc_stat_ev_rx_null_dsap_test_c(struct sk_buff *skb)
 39{
 40	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 41
 42	return LLC_PDU_IS_CMD(pdu) &&			/* command PDU */
 43	       LLC_PDU_TYPE_IS_U(pdu) &&		/* U type PDU */
 44	       LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_TEST &&
 45	       !pdu->dsap;				/* NULL DSAP */
 46}
 47
 48static int llc_station_ac_send_xid_r(struct sk_buff *skb)
 49{
 50	u8 mac_da[ETH_ALEN], dsap;
 51	int rc = 1;
 52	struct sk_buff *nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U,
 53					       sizeof(struct llc_xid_info));
 54
 55	if (!nskb)
 56		goto out;
 57	rc = 0;
 58	llc_pdu_decode_sa(skb, mac_da);
 59	llc_pdu_decode_ssap(skb, &dsap);
 60	llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
 61	llc_pdu_init_as_xid_rsp(nskb, LLC_XID_NULL_CLASS_2, 127);
 62	rc = llc_mac_hdr_init(nskb, skb->dev->dev_addr, mac_da);
 63	if (unlikely(rc))
 64		goto free;
 65	dev_queue_xmit(nskb);
 66out:
 67	return rc;
 68free:
 69	kfree_skb(nskb);
 70	goto out;
 71}
 72
 73static int llc_station_ac_send_test_r(struct sk_buff *skb)
 74{
 75	u8 mac_da[ETH_ALEN], dsap;
 76	int rc = 1;
 77	u32 data_size;
 78	struct sk_buff *nskb;
 79
 80	/* The test request command is type U (llc_len = 3) */
 81	data_size = ntohs(eth_hdr(skb)->h_proto) - 3;
 82	nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, data_size);
 83
 84	if (!nskb)
 85		goto out;
 86	rc = 0;
 87	llc_pdu_decode_sa(skb, mac_da);
 88	llc_pdu_decode_ssap(skb, &dsap);
 89	llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
 90	llc_pdu_init_as_test_rsp(nskb, skb);
 91	rc = llc_mac_hdr_init(nskb, skb->dev->dev_addr, mac_da);
 92	if (unlikely(rc))
 93		goto free;
 94	dev_queue_xmit(nskb);
 95out:
 96	return rc;
 97free:
 98	kfree_skb(nskb);
 99	goto out;
100}
101
102/**
103 *	llc_station_rcv - send received pdu to the station state machine
104 *	@skb: received frame.
105 *
106 *	Sends data unit to station state machine.
107 */
108static void llc_station_rcv(struct sk_buff *skb)
109{
110	if (llc_stat_ev_rx_null_dsap_xid_c(skb))
111		llc_station_ac_send_xid_r(skb);
112	else if (llc_stat_ev_rx_null_dsap_test_c(skb))
113		llc_station_ac_send_test_r(skb);
114	kfree_skb(skb);
115}
116
117void __init llc_station_init(void)
118{
119	llc_set_station_handler(llc_station_rcv);
120}
121
122void llc_station_exit(void)
123{
124	llc_set_station_handler(NULL);
125}