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

📄 strip.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
 *    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 *//* * 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 struct strip *struct_strip_list;/************************************************************************//* 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 MIN(X, Y) ((X) < (Y) ? (X) : (Y))#define MAX(X, Y) ((X) > (Y) ? (X) : (Y))#define ELEMENTS_OF(X) (sizeof(X) / sizeof((X)[0]))#define ARRAY_END(X) (&((X)[ELEMENTS_OF(X)]))#define JIFFIE_TO_SEC(X) ((X) / HZ)/************************************************************************//* Utility routines							*/typedef unsigned long InterruptStatus;static inline InterruptStatus DisableInterrupts(void){    InterruptStatus x;    save_flags(x);    cli();    return(x);}static inline void RestoreInterrupts(InterruptStatus x){    restore_flags(x);}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);}#if 0static void HexDump(char *msg, struct strip *strip_info, __u8 *start, __u8 *end){    __u8 *ptr = start;    printk(KERN_INFO "%s: %s: %d bytes\n", strip_info->dev.name, msg, end-ptr);    while (ptr < end)    {        long offset = ptr - start;        __u8 text[80], *p = text;        while (ptr < end && p < &text[16*3])        {            *p++ = hextable[*ptr >> 4];            *p++ = hextable[*ptr++ & 0xF];            *p++ = ' ';        }        p[-1] = 0;        printk(KERN_INFO "%s: %4lX %s\n", strip_info->dev.name, offset, text);    }}#endif/************************************************************************//* 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                {

⌨️ 快捷键说明

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