hdlc_x25.c (0612ec48762bf8712db1925b2e67246d2237ebab) hdlc_x25.c (eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfb)
1/*
2 * Generic HDLC support routines for Linux
3 * X.25 support
4 *
1/*
2 * Generic HDLC support routines for Linux
3 * X.25 support
4 *
5 * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl>
5 * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License
9 * as published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/kernel.h>

--- 6 unchanged lines hidden (view full) ---

20#include <linux/pkt_sched.h>
21#include <linux/inetdevice.h>
22#include <linux/lapb.h>
23#include <linux/rtnetlink.h>
24#include <linux/hdlc.h>
25
26#include <net/x25device.h>
27
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License
9 * as published by the Free Software Foundation.
10 */
11
12#include <linux/module.h>
13#include <linux/kernel.h>

--- 6 unchanged lines hidden (view full) ---

20#include <linux/pkt_sched.h>
21#include <linux/inetdevice.h>
22#include <linux/lapb.h>
23#include <linux/rtnetlink.h>
24#include <linux/hdlc.h>
25
26#include <net/x25device.h>
27
28static int x25_ioctl(struct net_device *dev, struct ifreq *ifr);
29
28/* These functions are callbacks called by LAPB layer */
29
30static void x25_connect_disconnect(struct net_device *dev, int reason, int code)
31{
32 struct sk_buff *skb;
33 unsigned char *ptr;
34
35 if ((skb = dev_alloc_skb(1)) == NULL) {

--- 121 unchanged lines hidden (view full) ---

157{
158 lapb_unregister(dev);
159}
160
161
162
163static int x25_rx(struct sk_buff *skb)
164{
30/* These functions are callbacks called by LAPB layer */
31
32static void x25_connect_disconnect(struct net_device *dev, int reason, int code)
33{
34 struct sk_buff *skb;
35 unsigned char *ptr;
36
37 if ((skb = dev_alloc_skb(1)) == NULL) {

--- 121 unchanged lines hidden (view full) ---

159{
160 lapb_unregister(dev);
161}
162
163
164
165static int x25_rx(struct sk_buff *skb)
166{
165 hdlc_device *hdlc = dev_to_hdlc(skb->dev);
167 struct hdlc_device_desc *desc = dev_to_desc(skb->dev);
166
167 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
168
169 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
168 hdlc->stats.rx_dropped++;
170 desc->stats.rx_dropped++;
169 return NET_RX_DROP;
170 }
171
172 if (lapb_data_received(skb->dev, skb) == LAPB_OK)
173 return NET_RX_SUCCESS;
174
171 return NET_RX_DROP;
172 }
173
174 if (lapb_data_received(skb->dev, skb) == LAPB_OK)
175 return NET_RX_SUCCESS;
176
175 hdlc->stats.rx_errors++;
177 desc->stats.rx_errors++;
176 dev_kfree_skb_any(skb);
177 return NET_RX_DROP;
178}
179
180
178 dev_kfree_skb_any(skb);
179 return NET_RX_DROP;
180}
181
182
183static struct hdlc_proto proto = {
184 .open = x25_open,
185 .close = x25_close,
186 .ioctl = x25_ioctl,
187 .module = THIS_MODULE,
188};
181
189
182int hdlc_x25_ioctl(struct net_device *dev, struct ifreq *ifr)
190
191static int x25_ioctl(struct net_device *dev, struct ifreq *ifr)
183{
184 hdlc_device *hdlc = dev_to_hdlc(dev);
185 int result;
186
187 switch (ifr->ifr_settings.type) {
188 case IF_GET_PROTO:
192{
193 hdlc_device *hdlc = dev_to_hdlc(dev);
194 int result;
195
196 switch (ifr->ifr_settings.type) {
197 case IF_GET_PROTO:
198 if (dev_to_hdlc(dev)->proto != &proto)
199 return -EINVAL;
189 ifr->ifr_settings.type = IF_PROTO_X25;
190 return 0; /* return protocol only, no settable parameters */
191
192 case IF_PROTO_X25:
193 if(!capable(CAP_NET_ADMIN))
194 return -EPERM;
195
196 if(dev->flags & IFF_UP)
197 return -EBUSY;
198
199 result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT);
200 if (result)
201 return result;
202
200 ifr->ifr_settings.type = IF_PROTO_X25;
201 return 0; /* return protocol only, no settable parameters */
202
203 case IF_PROTO_X25:
204 if(!capable(CAP_NET_ADMIN))
205 return -EPERM;
206
207 if(dev->flags & IFF_UP)
208 return -EBUSY;
209
210 result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT);
211 if (result)
212 return result;
213
203 hdlc_proto_detach(hdlc);
204 memset(&hdlc->proto, 0, sizeof(hdlc->proto));
205
206 hdlc->proto.open = x25_open;
207 hdlc->proto.close = x25_close;
208 hdlc->proto.netif_rx = x25_rx;
209 hdlc->proto.type_trans = NULL;
210 hdlc->proto.id = IF_PROTO_X25;
214 if ((result = attach_hdlc_protocol(dev, &proto,
215 x25_rx, 0)) != 0)
216 return result;
211 dev->hard_start_xmit = x25_xmit;
212 dev->hard_header = NULL;
213 dev->type = ARPHRD_X25;
214 dev->addr_len = 0;
215 netif_dormant_off(dev);
216 return 0;
217 }
218
219 return -EINVAL;
220}
217 dev->hard_start_xmit = x25_xmit;
218 dev->hard_header = NULL;
219 dev->type = ARPHRD_X25;
220 dev->addr_len = 0;
221 netif_dormant_off(dev);
222 return 0;
223 }
224
225 return -EINVAL;
226}
227
228
229static int __init mod_init(void)
230{
231 register_hdlc_protocol(&proto);
232 return 0;
233}
234
235
236
237static void __exit mod_exit(void)
238{
239 unregister_hdlc_protocol(&proto);
240}
241
242
243module_init(mod_init);
244module_exit(mod_exit);
245
246MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
247MODULE_DESCRIPTION("X.25 protocol support for generic HDLC");
248MODULE_LICENSE("GPL v2");