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}
v6.13.7
  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	if (skb->mac_len < ETH_HLEN)
 80		goto out;
 81
 82	/* The test request command is type U (llc_len = 3) */
 83	data_size = ntohs(eth_hdr(skb)->h_proto) - 3;
 84	nskb = llc_alloc_frame(NULL, skb->dev, LLC_PDU_TYPE_U, data_size);
 85
 86	if (!nskb)
 87		goto out;
 88	llc_pdu_decode_sa(skb, mac_da);
 89	llc_pdu_decode_ssap(skb, &dsap);
 90	llc_pdu_header_init(nskb, LLC_PDU_TYPE_U, 0, dsap, LLC_PDU_RSP);
 91	llc_pdu_init_as_test_rsp(nskb, skb);
 92	rc = llc_mac_hdr_init(nskb, skb->dev->dev_addr, mac_da);
 93	if (unlikely(rc))
 94		goto free;
 95	dev_queue_xmit(nskb);
 96out:
 97	return rc;
 98free:
 99	kfree_skb(nskb);
100	goto out;
101}
102
103/**
104 *	llc_station_rcv - send received pdu to the station state machine
105 *	@skb: received frame.
106 *
107 *	Sends data unit to station state machine.
108 */
109static void llc_station_rcv(struct sk_buff *skb)
110{
111	if (llc_stat_ev_rx_null_dsap_xid_c(skb))
112		llc_station_ac_send_xid_r(skb);
113	else if (llc_stat_ev_rx_null_dsap_test_c(skb))
114		llc_station_ac_send_test_r(skb);
115	kfree_skb(skb);
116}
117
118void __init llc_station_init(void)
119{
120	llc_set_station_handler(llc_station_rcv);
121}
122
123void llc_station_exit(void)
124{
125	llc_set_station_handler(NULL);
126}