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

📄 strip.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * Maximum Starmode packet length is 1183 bytes. Allowing 4 bytes for * protocol key, 4 bytes for checksum, one byte for CR, and 65/64 expansion * for STRIP encoding, that translates to a maximum payload MTU of 1155. * Note: A standard NFS 1K data packet is a total of 0x480 (1152) bytes * long, including IP header, UDP header, and NFS header. Setting the STRIP * MTU to 1152 allows us to send default sized NFS packets without fragmentation. */static const unsigned short MAX_SEND_MTU = 1152;static const unsigned short MAX_RECV_MTU = 1500;	/* Hoping for Ethernet sized packets in the future! */static const unsigned short DEFAULT_STRIP_MTU = 1152;static const int STRIP_MAGIC = 0x5303;static const long LongTime = 0x7FFFFFFF;/************************************************************************//* Global variables							*/static LIST_HEAD(strip_list);static DEFINE_SPINLOCK(strip_lock);/************************************************************************//* Macros								*//* Returns TRUE if text T begins with prefix P */#define has_prefix(T,L,P) (((L) >= sizeof(P)-1) && !strncmp((T), (P), sizeof(P)-1))/* Returns TRUE if text T of length L is equal to string S */#define text_equal(T,L,S) (((L) == sizeof(S)-1) && !strncmp((T), (S), sizeof(S)-1))#define READHEX(X) ((X)>='0' && (X)<='9' ? (X)-'0' :      \                    (X)>='a' && (X)<='f' ? (X)-'a'+10 :   \                    (X)>='A' && (X)<='F' ? (X)-'A'+10 : 0 )#define READHEX16(X) ((__u16)(READHEX(X)))#define READDEC(X) ((X)>='0' && (X)<='9' ? (X)-'0' : 0)#define ARRAY_END(X) (&((X)[ARRAY_SIZE(X)]))#define JIFFIE_TO_SEC(X) ((X) / HZ)/************************************************************************//* Utility routines							*/static int arp_query(unsigned char *haddr, u32 paddr,		     struct net_device *dev){	struct neighbour *neighbor_entry;	neighbor_entry = neigh_lookup(&arp_tbl, &paddr, dev);	if (neighbor_entry != NULL) {		neighbor_entry->used = jiffies;		if (neighbor_entry->nud_state & NUD_VALID) {			memcpy(haddr, neighbor_entry->ha, dev->addr_len);			return 1;		}	}	return 0;}static void DumpData(char *msg, struct strip *strip_info, __u8 * ptr,		     __u8 * end){	static const int MAX_DumpData = 80;	__u8 pkt_text[MAX_DumpData], *p = pkt_text;	*p++ = '\"';	while (ptr < end && p < &pkt_text[MAX_DumpData - 4]) {		if (*ptr == '\\') {			*p++ = '\\';			*p++ = '\\';		} else {			if (*ptr >= 32 && *ptr <= 126) {				*p++ = *ptr;			} else {				sprintf(p, "\\%02X", *ptr);				p += 3;			}		}		ptr++;	}	if (ptr == end)		*p++ = '\"';	*p++ = 0;	printk(KERN_INFO "%s: %-13s%s\n", strip_info->dev->name, msg, pkt_text);}/************************************************************************//* Byte stuffing/unstuffing routines					*//* Stuffing scheme: * 00    Unused (reserved character) * 01-3F Run of 2-64 different characters * 40-7F Run of 1-64 different characters plus a single zero at the end * 80-BF Run of 1-64 of the same character * C0-FF Run of 1-64 zeroes (ASCII 0) */typedef enum {	Stuff_Diff = 0x00,	Stuff_DiffZero = 0x40,	Stuff_Same = 0x80,	Stuff_Zero = 0xC0,	Stuff_NoCode = 0xFF,	/* Special code, meaning no code selected */	Stuff_CodeMask = 0xC0,	Stuff_CountMask = 0x3F,	Stuff_MaxCount = 0x3F,	Stuff_Magic = 0x0D	/* The value we are eliminating */} StuffingCode;/* StuffData encodes the data starting at "src" for "length" bytes. * It writes it to the buffer pointed to by "dst" (which must be at least * as long as 1 + 65/64 of the input length). The output may be up to 1.6% * larger than the input for pathological input, but will usually be smaller. * StuffData returns the new value of the dst pointer as its result. * "code_ptr_ptr" points to a "__u8 *" which is used to hold encoding state * between calls, allowing an encoded packet to be incrementally built up * from small parts. On the first call, the "__u8 *" pointed to should be * initialized to NULL; between subsequent calls the calling routine should * leave the value alone and simply pass it back unchanged so that the * encoder can recover its current state. */#define StuffData_FinishBlock(X) \(*code_ptr = (X) ^ Stuff_Magic, code = Stuff_NoCode)static __u8 *StuffData(__u8 * src, __u32 length, __u8 * dst,		       __u8 ** code_ptr_ptr){	__u8 *end = src + length;	__u8 *code_ptr = *code_ptr_ptr;	__u8 code = Stuff_NoCode, count = 0;	if (!length)		return (dst);	if (code_ptr) {		/*		 * Recover state from last call, if applicable		 */		code = (*code_ptr ^ Stuff_Magic) & Stuff_CodeMask;		count = (*code_ptr ^ Stuff_Magic) & Stuff_CountMask;	}	while (src < end) {		switch (code) {			/* Stuff_NoCode: If no current code, select one */		case Stuff_NoCode:			/* Record where we're going to put this code */			code_ptr = dst++;			count = 0;	/* Reset the count (zero means one instance) */			/* Tentatively start a new block */			if (*src == 0) {				code = Stuff_Zero;				src++;			} else {				code = Stuff_Same;				*dst++ = *src++ ^ Stuff_Magic;			}			/* Note: We optimistically assume run of same -- */			/* which will be fixed later in Stuff_Same */			/* if it turns out not to be true. */			break;			/* Stuff_Zero: We already have at least one zero encoded */		case Stuff_Zero:			/* If another zero, count it, else finish this code block */			if (*src == 0) {				count++;				src++;			} else {				StuffData_FinishBlock(Stuff_Zero + count);			}			break;			/* Stuff_Same: We already have at least one byte encoded */		case Stuff_Same:			/* If another one the same, count it */			if ((*src ^ Stuff_Magic) == code_ptr[1]) {				count++;				src++;				break;			}			/* else, this byte does not match this block. */			/* If we already have two or more bytes encoded, finish this code block */			if (count) {				StuffData_FinishBlock(Stuff_Same + count);				break;			}			/* else, we only have one so far, so switch to Stuff_Diff code */			code = Stuff_Diff;			/* and fall through to Stuff_Diff case below			 * Note cunning cleverness here: case Stuff_Diff compares 			 * the current character with the previous two to see if it			 * has a run of three the same. Won't this be an error if			 * there aren't two previous characters stored to compare with?			 * No. Because we know the current character is *not* the same			 * as the previous one, the first test below will necessarily			 * fail and the send half of the "if" won't be executed.			 */			/* Stuff_Diff: We have at least two *different* bytes encoded */		case Stuff_Diff:			/* If this is a zero, must encode a Stuff_DiffZero, and begin a new block */			if (*src == 0) {				StuffData_FinishBlock(Stuff_DiffZero +						      count);			}			/* else, if we have three in a row, it is worth starting a Stuff_Same block */			else if ((*src ^ Stuff_Magic) == dst[-1]				 && dst[-1] == dst[-2]) {				/* Back off the last two characters we encoded */				code += count - 2;				/* Note: "Stuff_Diff + 0" is an illegal code */				if (code == Stuff_Diff + 0) {					code = Stuff_Same + 0;				}				StuffData_FinishBlock(code);				code_ptr = dst - 2;				/* dst[-1] already holds the correct value */				count = 2;	/* 2 means three bytes encoded */				code = Stuff_Same;			}			/* else, another different byte, so add it to the block */			else {				*dst++ = *src ^ Stuff_Magic;				count++;			}			src++;	/* Consume the byte */			break;		}		if (count == Stuff_MaxCount) {			StuffData_FinishBlock(code + count);		}	}	if (code == Stuff_NoCode) {		*code_ptr_ptr = NULL;	} else {		*code_ptr_ptr = code_ptr;		StuffData_FinishBlock(code + count);	}	return (dst);}/* * UnStuffData decodes the data at "src", up to (but not including) "end". * It writes the decoded data into the buffer pointed to by "dst", up to a * maximum of "dst_length", and returns the new value of "src" so that a * follow-on call can read more data, continuing from where the first left off. *  * There are three types of results: * 1. The source data runs out before extracting "dst_length" bytes: *    UnStuffData returns NULL to indicate failure. * 2. The source data produces exactly "dst_length" bytes: *    UnStuffData returns new_src = end to indicate that all bytes were consumed. * 3. "dst_length" bytes are extracted, with more remaining. *    UnStuffData returns new_src < end to indicate that there are more bytes *    to be read. *  * Note: The decoding may be destructive, in that it may alter the source * data in the process of decoding it (this is necessary to allow a follow-on * call to resume correctly). */static __u8 *UnStuffData(__u8 * src, __u8 * end, __u8 * dst,			 __u32 dst_length){	__u8 *dst_end = dst + dst_length;	/* Sanity check */	if (!src || !end || !dst || !dst_length)		return (NULL);	while (src < end && dst < dst_end) {		int count = (*src ^ Stuff_Magic) & Stuff_CountMask;		switch ((*src ^ Stuff_Magic) & Stuff_CodeMask) {		case Stuff_Diff:			if (src + 1 + count >= end)				return (NULL);			do {				*dst++ = *++src ^ Stuff_Magic;			}			while (--count >= 0 && dst < dst_end);			if (count < 0)				src += 1;			else {				if (count == 0)					*src = Stuff_Same ^ Stuff_Magic;				else					*src =					    (Stuff_Diff +					     count) ^ Stuff_Magic;			}			break;		case Stuff_DiffZero:			if (src + 1 + count >= end)				return (NULL);			do {				*dst++ = *++src ^ Stuff_Magic;			}			while (--count >= 0 && dst < dst_end);			if (count < 0)				*src = Stuff_Zero ^ Stuff_Magic;			else				*src =				    (Stuff_DiffZero + count) ^ Stuff_Magic;			break;		case Stuff_Same:			if (src + 1 >= end)				return (NULL);			do {				*dst++ = src[1] ^ Stuff_Magic;			}			while (--count >= 0 && dst < dst_end);			if (count < 0)				src += 2;			else				*src = (Stuff_Same + count) ^ Stuff_Magic;			break;		case Stuff_Zero:			do {				*dst++ = 0;			}			while (--count >= 0 && dst < dst_end);			if (count < 0)				src += 1;			else				*src = (Stuff_Zero + count) ^ Stuff_Magic;			break;		}	}	if (dst < dst_end)		return (NULL);	else		return (src);}/************************************************************************//* General routines for STRIP						*//* * get_baud returns the current baud rate, as one of the constants defined in * termbits.h * If the user has issued a baud rate override using the 'setserial' command * and the logical current rate is set to 38.4, then the true baud rate * currently in effect (57.6 or 115.2) is returned. */static unsigned int get_baud(struct tty_struct *tty){	if (!tty || !tty->termios)		return (0);	if ((tty->termios->c_cflag & CBAUD) == B38400 && tty->driver_data) {		struct async_struct *info =		    (struct async_struct *) tty->driver_data;		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)			return (B57600);		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)			return (B115200);	}	return (tty->termios->c_cflag & CBAUD);}/* * set_baud sets the baud rate to the rate defined by baudcode * Note: The rate B38400 should be avoided, because the user may have * issued a 'setserial' speed override to map that to a different speed. * We could achieve a true rate of 38400 if we needed to by cancelling * any user speed override that is in place, but that might annoy the * user, so it is simplest to just avoid using 38400. */static void set_baud(struct tty_struct *tty, unsigned int baudcode){	struct termios old_termios = *(tty->termios);	tty->termios->c_cflag &= ~CBAUD;	/* Clear the old baud setting */	tty->termios->c_cflag |= baudcode;	/* Set the new baud setting */	tty->driver->set_termios(tty, &old_termios);}/* * Convert a string to a Metricom Address. */#define IS_RADIO_ADDRESS(p) (                                                 \  isdigit((p)[0]) && isdigit((p)[1]) && isdigit((p)[2]) && isdigit((p)[3]) && \  (p)[4] == '-' &&                                                            \  isdigit((p)[5]) && isdigit((p)[6]) && isdigit((p)[7]) && isdigit((p)[8])    )static int string_to_radio_address(MetricomAddress * addr, __u8 * p){	if (!IS_RADIO_ADDRESS(p))		return (1);	addr->c[0] = 0;	addr->c[1] = 0;	addr->c[2] = READHEX(p[0]) << 4 | READHEX(p[1]);	addr->c[3] = READHEX(p[2]) << 4 | READHEX(p[3]);	addr->c[4] = READHEX(p[5]) << 4 | READHEX(p[6]);	addr->c[5] = READHEX(p[7]) << 4 | READHEX(p[8]);	return (0);}/* * Convert a Metricom Address to a string. */static __u8 *radio_address_to_string(const MetricomAddress * addr,				     MetricomAddressString * p){	sprintf(p->c, "%02X%02X-%02X%02X", addr->c[2], addr->c[3],		addr->c[4], addr->c[5]);	return (p->c);}/*

⌨️ 快捷键说明

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