数据包校验和
IP校验:IP校验范围为IP字段共ip_hdr.ip_hl*4个字节;
code:
/*
参数:
buffer:IP段开始地址;
length:IP段长度;
返回值:
成功:返回checksum:两个字节
*/
uint16_t checksum(uint16_t *buffer, int length)
{
uint32_t cksum = 0;
while(length> 1)
{
cksum += *buffer ++;
length-= sizeof(uint16_t);
}
if (length)
{
cksum += *(uint8_t*)buffer;
}
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >> 16);
return (uint16_t)(~cksum);
}
数据包FCS校验:
#include <stdio.h>
#include <stdlib.h>
#include <arpa/inet.h>
#define alt_8 char
#define alt_u8 unsigned char
#define alt_32 int
#define alt_u32 unsigned int
#define alt_64 long long
#define alt_u64 unsigned long long
alt_u64 Reflect(alt_u64 ref,alt_u8 ch)
{
int i;
alt_u64 value = 0;
for( i = 1; i < ( ch + 1 ); i++ )
{
if( ref & 1 )
value |= 1 << ( ch - i );
ref >>= 1;
}
return value;
}
#define poly 0x04C11DB7
#define upoly 0xEDB88320
alt_u32 crc32_bit(alt_u8 *ptr, alt_u32 len, alt_u32 gx)
{
alt_u8 i;
alt_u32 crc = 0xffffffff;
while( len-- )
{
for( i = 1; i != 0; i <<= 1 )
{
if( ( crc & 0x80000000 ) != 0 )
{
crc <<= 1;
crc ^= gx;
}
else
crc <<= 1;
if( ( *ptr & i ) != 0 )
crc ^= gx;
}
ptr++;
}
return ( Reflect(crc,32) ^ 0xffffffff );
}
alt_u32 Table1[256];
alt_u32 Table2[256];
void gen_direct_table(alt_u32 *table)
{
alt_u32 gx = 0x04c11db7;
unsigned long i32, j32;
unsigned long nData32;
unsigned long nAccum32;
for ( i32 = 0; i32 < 256; i32++ )
{
nData32 = ( unsigned long )( i32 << 24 );
nAccum32 = 0;
for ( j32 = 0; j32 < 8; j32++ )
{
if ( ( nData32 ^ nAccum32 ) & 0x80000000 )
nAccum32 = ( nAccum32 << 1 ) ^ gx;
else
nAccum32 <<= 1;
nData32 <<= 1;
}
table[i32] = nAccum32;
}
}
void gen_normal_table(alt_u32 *table)
{
alt_u32 gx = 0x04c11db7;
alt_u32 temp,crc;
for(int i = 0; i <= 0xFF; i++)
{
temp=Reflect(i, 8);
table[i]= temp<< 24;
for (int j = 0; j < 8; j++)
{
unsigned long int t1,t2;
unsigned long int flag=table[i]&0x80000000;
t1=(table[i] << 1);
if(flag==0)
t2=0;
else
t2=gx;
table[i] =t1^t2 ;
}
crc=table[i];
table[i] = Reflect(table[i], 32);
}
}
alt_u32 DIRECT_TABLE_CRC(alt_u8 *ptr,int len, alt_u32 * table)
{
alt_u32 crc = 0xffffffff;
alt_u8 *p= ptr;
int i;
for ( i = 0; i < len; i++ )
crc = ( crc << 8 ) ^ table[( crc >> 24 ) ^ (alt_u8)Reflect((*(p+i)), 8)];
return ~(alt_u32)Reflect(crc, 32) ;
}
alt_u32 Reverse_Table_CRC(alt_u8 *data, alt_32 len, alt_u32 * table)
{
alt_u32 crc = 0xffffffff;
alt_u8 *p = data;
int i;
for(i=0; i <len; i++)
crc = table[( crc ^( *(p+i)) ) & 0xff] ^ (crc >> 8);
return ~crc ;
}
alt_u8 tx_data[] = {
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x1f, //8
0x29, 0x00, 0xb5, 0xfa, 0x08, 0x06, 0x00, 0x01, //15
0x08, 0x00, 0x06, 0x04, 0x00, 0x01, 0x00, 0x1f, //24
0x29, 0x00, 0xb5, 0xfa, 0xac, 0x15, 0x0e, 0xd9, //32
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xac, 0x15, //40
0x0e, 0x8e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //48
0x00, 0x00 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //56
0x00, 0x00, 0x00, 0x00, 0x8b, 0x6b, 0xf5, 0x13 //64
};
alt_u8 packet[] = {
0xFF, 0xFF, 0xFF ,0xFF, 0xFF, 0xFF, 0x68, 0x17, 0x29, 0x1F, 0x01, 0x71, 0x08, 0x00, 0x45, 0x00,
0x00, 0x4E, 0x3C, 0x82, 0x00, 0x00, 0x40, 0x11, 0xB9, 0xC8, 0xC0, 0xA8, 0x01, 0x05, 0xC0, 0xA8,
0x01, 0xFF, 0x00, 0x89, 0x00, 0x89, 0x00, 0x3A, 0x1E, 0x0C, 0xDA, 0x8A, 0x01, 0x10, 0x00, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x46, 0x48, 0x45, 0x50, 0x46, 0x43, 0x45, 0x4C, 0x45,
0x48, 0x46, 0x43, 0x45, 0x50, 0x46, 0x46, 0x46, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43, 0x41, 0x43,
0x41, 0x43, 0x41, 0x43, 0x41, 0x42, 0x4D, 0x00, 0x00, 0x20, 0x00, 0x01
};
int main()
{
// alt_u8 *data = tx_data;
// alt_u8 dataLen = sizeof(tx_data) -4;
alt_u8 *data = packet;
alt_u8 dataLen = sizeof(packet) ;
int sum = 256;
int i = 0;
gen_direct_table(Table1);
printf("Table1 :\n");
for( i = 0; i < sum; i++)
{
if(i<16)
printf("%08x ",Table1[i]);
}
printf("\n\n");
gen_normal_table(Table2);
printf("Table2 :\n");
for( i = 0; i < sum; i++)
{
if(i<16)
printf("%08x ",Table2[i]);
}
printf("\n\n");
printf("dataLen = %d\n",dataLen);
printf("Slow CRC by bit : %08x\n",ntohl(crc32_bit( data, dataLen, 0x04c11db7 )));
printf("Reverse Table ref + xor : %08x\n",Reverse_Table_CRC(data,dataLen,Table2));
system("pause");
return 0;
}