📄 hdlc_generic.c
字号:
/* * Generic HDLC support routines for Linux * * Copyright (C) 1999 - 2001 Krzysztof Halasa <khc@pm.waw.pl> * * 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. * * Current status: * - this is work in progress * - not heavily tested on SMP * - currently supported: * * raw IP-in-HDLC * * Cisco HDLC * * Frame Relay with ANSI or CCITT LMI (both user and network side) * * PPP * * X.25 * * Use sethdlc utility to set line parameters, protocol and PVCs */#include <linux/config.h>#include <linux/module.h>#include <linux/kernel.h>#include <linux/slab.h>#include <linux/poll.h>#include <linux/errno.h>#include <linux/if_arp.h>#include <linux/init.h>#include <linux/skbuff.h>#include <linux/pkt_sched.h>#include <linux/inetdevice.h>#include <linux/lapb.h>#include <linux/rtnetlink.h>#include <linux/hdlc.h>static const char* version = "HDLC support module revision 1.11";static int hdlc_change_mtu(struct net_device *dev, int new_mtu){ if ((new_mtu < 68) || (new_mtu > HDLC_MAX_MTU)) return -EINVAL; dev->mtu = new_mtu; return 0;}static struct net_device_stats *hdlc_get_stats(struct net_device *dev){ return &dev_to_hdlc(dev)->stats;}static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *p){ dev_to_hdlc(dev)->netif_rx(skb); return 0;}#ifndef CONFIG_HDLC_RAW#define hdlc_raw_ioctl(hdlc, ifr) -ENOSYS#endif#ifndef CONFIG_HDLC_PPP#define hdlc_ppp_ioctl(hdlc, ifr) -ENOSYS#endif#ifndef CONFIG_HDLC_CISCO#define hdlc_cisco_ioctl(hdlc, ifr) -ENOSYS#endif#ifndef CONFIG_HDLC_FR#define hdlc_fr_ioctl(hdlc, ifr) -ENOSYS#endif#ifndef CONFIG_HDLC_X25#define hdlc_x25_ioctl(hdlc, ifr) -ENOSYS#endifint hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd){ hdlc_device *hdlc = dev_to_hdlc(dev); unsigned int proto; if (cmd != SIOCWANDEV) return -EINVAL; switch(ifr->ifr_settings.type) { case IF_PROTO_HDLC: case IF_PROTO_PPP: case IF_PROTO_CISCO: case IF_PROTO_FR: case IF_PROTO_X25: proto = ifr->ifr_settings.type; break; default: proto = hdlc->proto; } switch(proto) { case IF_PROTO_HDLC: return hdlc_raw_ioctl(hdlc, ifr); case IF_PROTO_PPP: return hdlc_ppp_ioctl(hdlc, ifr); case IF_PROTO_CISCO: return hdlc_cisco_ioctl(hdlc, ifr); case IF_PROTO_FR: return hdlc_fr_ioctl(hdlc, ifr); case IF_PROTO_X25: return hdlc_x25_ioctl(hdlc, ifr); default: return -EINVAL; }}int register_hdlc_device(hdlc_device *hdlc){ int result; struct net_device *dev = hdlc_to_dev(hdlc); dev->get_stats = hdlc_get_stats; dev->change_mtu = hdlc_change_mtu; dev->mtu = HDLC_MAX_MTU; dev->type = ARPHRD_RAWHDLC; dev->hard_header_len = 16; dev->flags = IFF_POINTOPOINT | IFF_NOARP; hdlc->proto = -1; hdlc->proto_detach = NULL; result = dev_alloc_name(dev, "hdlc%d"); if (result<0) return result; result = register_netdev(dev); if (result != 0) return -EIO; MOD_INC_USE_COUNT; return 0;}void unregister_hdlc_device(hdlc_device *hdlc){ hdlc_proto_detach(hdlc); unregister_netdev(hdlc_to_dev(hdlc)); MOD_DEC_USE_COUNT;}MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");MODULE_DESCRIPTION("HDLC support module");MODULE_LICENSE("GPL");EXPORT_SYMBOL(hdlc_ioctl);EXPORT_SYMBOL(register_hdlc_device);EXPORT_SYMBOL(unregister_hdlc_device);struct packet_type hdlc_packet_type={ __constant_htons(ETH_P_HDLC), NULL, hdlc_rcv, NULL, NULL};static int __init hdlc_module_init(void){ printk(KERN_INFO "%s\n", version); dev_add_pack(&hdlc_packet_type); return 0;}static void __exit hdlc_module_exit(void){ dev_remove_pack(&hdlc_packet_type);}module_init(hdlc_module_init);module_exit(hdlc_module_exit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -