⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 strip.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Copyright 1996 The Board of Trustees of The Leland Stanford * Junior University. All Rights Reserved. * * Permission to use, copy, modify, and distribute this * software and its documentation for any purpose and without * fee is hereby granted, provided that the above copyright * notice appear in all copies.  Stanford University * makes no representations about the suitability of this * software for any purpose.  It is provided "as is" without * express or implied warranty. * * strip.c	This module implements Starmode Radio IP (STRIP) *		for kernel-based devices like TTY.  It interfaces between a *		raw TTY, and the kernel's INET protocol layers (via DDI). * * Version:	@(#)strip.c	1.3	July 1997 * * Author:	Stuart Cheshire <cheshire@cs.stanford.edu> * * Fixes:	v0.9 12th Feb 1996 (SC) *		New byte stuffing (2+6 run-length encoding) *		New watchdog timer task *		New Protocol key (SIP0) *		 *		v0.9.1 3rd March 1996 (SC) *		Changed to dynamic device allocation -- no more compile *		time (or boot time) limit on the number of STRIP devices. *		 *		v0.9.2 13th March 1996 (SC) *		Uses arp cache lookups (but doesn't send arp packets yet) *		 *		v0.9.3 17th April 1996 (SC) *		Fixed bug where STR_ERROR flag was getting set unneccessarily *		(causing otherwise good packets to be unneccessarily dropped) *		 *		v0.9.4 27th April 1996 (SC) *		First attempt at using "&COMMAND" Starmode AT commands *		 *		v0.9.5 29th May 1996 (SC) *		First attempt at sending (unicast) ARP packets *		 *		v0.9.6 5th June 1996 (Elliot) *		Put "message level" tags in every "printk" statement *		 *		v0.9.7 13th June 1996 (laik) *		Added support for the /proc fs * *              v0.9.8 July 1996 (Mema) *              Added packet logging * *              v1.0 November 1996 (SC) *              Fixed (severe) memory leaks in the /proc fs code *              Fixed race conditions in the logging code * *              v1.1 January 1997 (SC) *              Deleted packet logging (use tcpdump instead) *              Added support for Metricom Firmware v204 features *              (like message checksums) * *              v1.2 January 1997 (SC) *              Put portables list back in * *              v1.3 July 1997 (SC) *              Made STRIP driver set the radio's baud rate automatically. *              It is no longer necessarily to manually set the radio's *              rate permanently to 115200 -- the driver handles setting *              the rate automatically. */#ifdef MODULEstatic const char StripVersion[] = "1.3A-STUART.CHESHIRE-MODULAR";#elsestatic const char StripVersion[] = "1.3A-STUART.CHESHIRE";#endif#define TICKLE_TIMERS 0#define EXT_COUNTERS 1/************************************************************************//* Header files								*/#include <linux/config.h>#include <linux/kernel.h>#include <linux/module.h>#include <linux/init.h>#include <linux/bitops.h>#include <asm/system.h>#include <asm/uaccess.h># include <linux/ctype.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/interrupt.h>#include <linux/in.h>#include <linux/tty.h>#include <linux/errno.h>#include <linux/netdevice.h>#include <linux/inetdevice.h>#include <linux/etherdevice.h>#include <linux/skbuff.h>#include <linux/if_arp.h>#include <linux/if_strip.h>#include <linux/proc_fs.h>#include <linux/seq_file.h>#include <linux/serial.h>#include <linux/serialP.h>#include <linux/rcupdate.h>#include <net/arp.h>#include <linux/ip.h>#include <linux/tcp.h>#include <linux/time.h>/************************************************************************//* Useful structures and definitions					*//* * A MetricomKey identifies the protocol being carried inside a Metricom * Starmode packet. */typedef union {	__u8 c[4];	__u32 l;} MetricomKey;/* * An IP address can be viewed as four bytes in memory (which is what it is) or as * a single 32-bit long (which is convenient for assignment, equality testing etc.) */typedef union {	__u8 b[4];	__u32 l;} IPaddr;/* * A MetricomAddressString is used to hold a printable representation of * a Metricom address. */typedef struct {	__u8 c[24];} MetricomAddressString;/* Encapsulation can expand packet of size x to 65/64x + 1 * Sent packet looks like "<CR>*<address>*<key><encaps payload><CR>" *                           1 1   1-18  1  4         ?         1 * eg.                     <CR>*0000-1234*SIP0<encaps payload><CR> * We allow 31 bytes for the stars, the key, the address and the <CR>s */#define STRIP_ENCAP_SIZE(X) (32 + (X)*65L/64L)/* * A STRIP_Header is never really sent over the radio, but making a dummy * header for internal use within the kernel that looks like an Ethernet * header makes certain other software happier. For example, tcpdump * already understands Ethernet headers. */typedef struct {	MetricomAddress dst_addr;	/* Destination address, e.g. "0000-1234"   */	MetricomAddress src_addr;	/* Source address, e.g. "0000-5678"        */	unsigned short protocol;	/* The protocol type, using Ethernet codes */} STRIP_Header;typedef struct {	char c[60];} MetricomNode;#define NODE_TABLE_SIZE 32typedef struct {	struct timeval timestamp;	int num_nodes;	MetricomNode node[NODE_TABLE_SIZE];} MetricomNodeTable;enum { FALSE = 0, TRUE = 1 };/* * Holds the radio's firmware version. */typedef struct {	char c[50];} FirmwareVersion;/* * Holds the radio's serial number. */typedef struct {	char c[18];} SerialNumber;/* * Holds the radio's battery voltage. */typedef struct {	char c[11];} BatteryVoltage;typedef struct {	char c[8];} char8;enum {	NoStructure = 0,	/* Really old firmware */	StructuredMessages = 1,	/* Parsable AT response msgs */	ChecksummedMessages = 2	/* Parsable AT response msgs with checksums */};struct strip {	int magic;	/*	 * These are pointers to the malloc()ed frame buffers.	 */	unsigned char *rx_buff;	/* buffer for received IP packet */	unsigned char *sx_buff;	/* buffer for received serial data */	int sx_count;		/* received serial data counter */	int sx_size;		/* Serial buffer size           */	unsigned char *tx_buff;	/* transmitter buffer           */	unsigned char *tx_head;	/* pointer to next byte to XMIT */	int tx_left;		/* bytes left in XMIT queue     */	int tx_size;		/* Serial buffer size           */	/*	 * STRIP interface statistics.	 */	unsigned long rx_packets;	/* inbound frames counter       */	unsigned long tx_packets;	/* outbound frames counter      */	unsigned long rx_errors;	/* Parity, etc. errors          */	unsigned long tx_errors;	/* Planned stuff                */	unsigned long rx_dropped;	/* No memory for skb            */	unsigned long tx_dropped;	/* When MTU change              */	unsigned long rx_over_errors;	/* Frame bigger then STRIP buf. */	unsigned long pps_timer;	/* Timer to determine pps       */	unsigned long rx_pps_count;	/* Counter to determine pps     */	unsigned long tx_pps_count;	/* Counter to determine pps     */	unsigned long sx_pps_count;	/* Counter to determine pps     */	unsigned long rx_average_pps;	/* rx packets per second * 8    */	unsigned long tx_average_pps;	/* tx packets per second * 8    */	unsigned long sx_average_pps;	/* sent packets per second * 8  */#ifdef EXT_COUNTERS	unsigned long rx_bytes;		/* total received bytes */	unsigned long tx_bytes;		/* total received bytes */	unsigned long rx_rbytes;	/* bytes thru radio i/f */	unsigned long tx_rbytes;	/* bytes thru radio i/f */	unsigned long rx_sbytes;	/* tot bytes thru serial i/f */	unsigned long tx_sbytes;	/* tot bytes thru serial i/f */	unsigned long rx_ebytes;	/* tot stat/err bytes */	unsigned long tx_ebytes;	/* tot stat/err bytes */#endif	/*	 * Internal variables.	 */	struct list_head  list;		/* Linked list of devices */	int discard;			/* Set if serial error          */	int working;			/* Is radio working correctly?  */	int firmware_level;		/* Message structuring level    */	int next_command;		/* Next periodic command        */	unsigned int user_baud;		/* The user-selected baud rate  */	int mtu;			/* Our mtu (to spot changes!)   */	long watchdog_doprobe;		/* Next time to test the radio  */	long watchdog_doreset;		/* Time to do next reset        */	long gratuitous_arp;		/* Time to send next ARP refresh */	long arp_interval;		/* Next ARP interval            */	struct timer_list idle_timer;	/* For periodic wakeup calls    */	MetricomAddress true_dev_addr;	/* True address of radio        */	int manual_dev_addr;		/* Hack: See note below         */	FirmwareVersion firmware_version;	/* The radio's firmware version */	SerialNumber serial_number;	/* The radio's serial number    */	BatteryVoltage battery_voltage;	/* The radio's battery voltage  */	/*	 * Other useful structures.	 */	struct tty_struct *tty;		/* ptr to TTY structure         */	struct net_device *dev;		/* Our device structure         */	/*	 * Neighbour radio records	 */	MetricomNodeTable portables;	MetricomNodeTable poletops;};/* * Note: manual_dev_addr hack *  * It is not possible to change the hardware address of a Metricom radio, * or to send packets with a user-specified hardware source address, thus * trying to manually set a hardware source address is a questionable * thing to do.  However, if the user *does* manually set the hardware * source address of a STRIP interface, then the kernel will believe it, * and use it in certain places. For example, the hardware address listed * by ifconfig will be the manual address, not the true one. * (Both addresses are listed in /proc/net/strip.) * Also, ARP packets will be sent out giving the user-specified address as * the source address, not the real address. This is dangerous, because * it means you won't receive any replies -- the ARP replies will go to * the specified address, which will be some other radio. The case where * this is useful is when that other radio is also connected to the same * machine. This allows you to connect a pair of radios to one machine, * and to use one exclusively for inbound traffic, and the other * exclusively for outbound traffic. Pretty neat, huh? *  * Here's the full procedure to set this up: *  * 1. "slattach" two interfaces, e.g. st0 for outgoing packets, *    and st1 for incoming packets *  * 2. "ifconfig" st0 (outbound radio) to have the hardware address *    which is the real hardware address of st1 (inbound radio). *    Now when it sends out packets, it will masquerade as st1, and *    replies will be sent to that radio, which is exactly what we want. *  * 3. Set the route table entry ("route add default ..." or *    "route add -net ...", as appropriate) to send packets via the st0 *    interface (outbound radio). Do not add any route which sends packets *    out via the st1 interface -- that radio is for inbound traffic only. *  * 4. "ifconfig" st1 (inbound radio) to have hardware address zero. *    This tells the STRIP driver to "shut down" that interface and not *    send any packets through it. In particular, it stops sending the *    periodic gratuitous ARP packets that a STRIP interface normally sends. *    Also, when packets arrive on that interface, it will search the *    interface list to see if there is another interface who's manual *    hardware address matches its own real address (i.e. st0 in this *    example) and if so it will transfer ownership of the skbuff to *    that interface, so that it looks to the kernel as if the packet *    arrived on that interface. This is necessary because when the *    kernel sends an ARP packet on st0, it expects to get a reply on *    st0, and if it sees the reply come from st1 then it will ignore *    it (to be accurate, it puts the entry in the ARP table, but *    labelled in such a way that st0 can't use it). *  * Thanks to Petros Maniatis for coming up with the idea of splitting * inbound and outbound traffic between two interfaces, which turned * out to be really easy to implement, even if it is a bit of a hack. *  * Having set a manual address on an interface, you can restore it * to automatic operation (where the address is automatically kept * consistent with the real address of the radio) by setting a manual * address of all ones, e.g. "ifconfig st0 hw strip FFFFFFFFFFFF" * This 'turns off' manual override mode for the device address. *  * Note: The IEEE 802 headers reported in tcpdump will show the *real* * radio addresses the packets were sent and received from, so that you * can see what is really going on with packets, and which interfaces * they are really going through. *//************************************************************************//* Constants								*//* * CommandString1 works on all radios * Other CommandStrings are only used with firmware that provides structured responses. *  * ats319=1 Enables Info message for node additions and deletions * ats319=2 Enables Info message for a new best node * ats319=4 Enables checksums * ats319=8 Enables ACK messages */static const int MaxCommandStringLength = 32;static const int CompatibilityCommand = 1;static const char CommandString0[] = "*&COMMAND*ATS319=7";	/* Turn on checksums & info messages */static const char CommandString1[] = "*&COMMAND*ATS305?";	/* Query radio name */static const char CommandString2[] = "*&COMMAND*ATS325?";	/* Query battery voltage */static const char CommandString3[] = "*&COMMAND*ATS300?";	/* Query version information */static const char CommandString4[] = "*&COMMAND*ATS311?";	/* Query poletop list */static const char CommandString5[] = "*&COMMAND*AT~LA";		/* Query portables list */typedef struct {	const char *string;	long length;} StringDescriptor;static const StringDescriptor CommandString[] = {	{CommandString0, sizeof(CommandString0) - 1},	{CommandString1, sizeof(CommandString1) - 1},	{CommandString2, sizeof(CommandString2) - 1},	{CommandString3, sizeof(CommandString3) - 1},	{CommandString4, sizeof(CommandString4) - 1},	{CommandString5, sizeof(CommandString5) - 1}};#define GOT_ALL_RADIO_INFO(S)      \    ((S)->firmware_version.c[0] && \     (S)->battery_voltage.c[0]  && \     memcmp(&(S)->true_dev_addr, zero_address.c, sizeof(zero_address)))static const char hextable[16] = "0123456789ABCDEF";static const MetricomAddress zero_address;static const MetricomAddress broadcast_address =    { {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF} };static const MetricomKey SIP0Key = { "SIP0" };static const MetricomKey ARP0Key = { "ARP0" };static const MetricomKey ATR_Key = { "ATR " };static const MetricomKey ACK_Key = { "ACK_" };static const MetricomKey INF_Key = { "INF_" };static const MetricomKey ERR_Key = { "ERR_" };static const long MaxARPInterval = 60 * HZ;	/* One minute */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -