1.把校验和字段置为0;
2.对IP头部中的每16bit进行二进制求和;
3.如果和的高16bit不为0,则将和的高16bit和低16bit反复相加,直到和的高16bit为0,从而获得一个16bit的值;
4.将该16bit的值取反,存入校验和字段。
UDP/TCP报头中的校验和的计算比较复杂的,要用到 UDP/TCP伪首部:先要填充伪首部各个字段,然后再将UDP/TCP报头以后(包括报头)的数据附加到伪首部的后面,再对位首部使用上述校验和计算,所得到的值才是UDP/TCP报头部分的校验和。 位首部可以用如下的结构体表示:typedef struct{
ULONG sourceip; //源IP地址
ULONG destip; //目的IP地址
BYTE mbz; //置空(0)
BYTE ptcl; //协议类型
USHORT plen; //TCP/UDP数据包的长度(即从TCP/UDP报头算起到数据包结束的长度 单位:字节)
}Psd_Header; 注:1.对于UDP协议,如果不想计算的话,可以把校验和的两个字节置0,根据RFC的规定,这样上层UDP协议就不会计算校验和了2.sniffer查看校验和时,最好在中间节点。你在本机抓的时候,你的协议驱动在NDIS架构中层次太高,与标准协议栈是平级的,此时校验和处未被计算填充,还是垃圾填充数据。你在网络其它节点抓的时候,报文已经经过网卡的处理,校验和被正确设置了。
USHORT checksum(USHORT *buffer,int size)
{
unsigned long cksum=0;
while(size>1)
{
cksum+=*buffer++;
size-=sizeof(USHORT);
}
if(size)
{
cksum+=*(UCHAR *)buffer;
}
//将32位数转换成16
while (cksum>>16)
cksum=(cksum>>16)+(cksum & 0xffff);
return (USHORT) (~cksum);
}
#include "stm32f4xx.h"
#include "usart.h"
#include "delay.h"
#include
#define LWIP_MAKE_U16(a, b) ((a << 8) | b) //((b << 8) | a)
#define LWIP_hton_U16(a) ((((a)>>8)&0x00ff) |(((a)<<8)&0xff00))
#define LWIP_hton_U32(a) \
((u32)((a>>0) & 0xff) << 24) | \
((u32)((a>>8) & 0xff) << 16) | \
((u32)((a>>16) & 0xff) << 8) | \
(u32)((a>>24) & 0xff)
#define IP4_ADDR( a,b,c,d) \
((u32)((a) & 0xff) << 24) | \
((u32)((b) & 0xff) << 16) | \
((u32)((c) & 0xff) << 8) | \
(u32)((d) & 0xff)
#define FOLD_U32T(u) (((u) >> 16) + ((u) & 0x0000ffffUL))
#define SWAP_BYTES_IN_WORD(w) (((w) & 0xff) << 8) | (((w) & 0xff00) >> 8)
u16 lwip_standard_chksum(void *dataptr, int len)
{
u8 *pb = (u8 *)dataptr;
u16 *ps, t = 0;
u32 sum = 0;
int odd = ((u32)pb & 1);
/* Get aligned to u16_t */
if (odd && len > 0) {
((u8 *)&t)[1] = *pb++;
len--;
}
/* Add the bulk of the data */
ps = (u16 *)(void *)pb;
while (len > 1) {
sum += *ps++;
len -= 2;
}
/* Consume left-over byte, if any */
if (len > 0) {
((u8 *)&t)[0] = *(u8 *)ps;
}
/* Add end bytes */
sum += t;
/* Fold 32-bit sum to 16 bits
calling this twice is propably faster than if statements... */
sum = FOLD_U32T(sum);
sum = FOLD_U32T(sum);
/* Swap if alignment was odd */
if (odd) {
sum = SWAP_BYTES_IN_WORD(sum);
}
return (u16)sum;
}
typedef struct udp_pcb {
//IP
u8 headIP;
u8 priority;
u16 lenIP;
u16 identifyflag;
u16 flags ;
u8 ttl;
u8 proto;
u16 checkIP;
u32 srcIP;
u32 destIP;
//UDP
u16 srcPORT;
u16 destPORT;
u16 lenUDP;
u16 checkUDP;
}udp_pcb_def;
udp_pcb_def udata;
void UDP_data(u8* retbuf,u16* retlen,u16 srcPort,u16 destPort,u8* srcIpbuf,u8* destIpbuf,u8 *dbuf,u16 dlen)
{
u32 chk_sum_IP = 0;
u32 chk_sum_UDP = 0;
u32 chk_sum = 0;
u16 chk_sumxxx = 0;//测试
u16 srcPORT = srcPort;
u16 destPORT = destPort;
u16 lenUDP = 8+dlen;
u8 proto = 0x11;//udp
u32 srcIP = IP4_ADDR(srcIpbuf[0],srcIpbuf[1],srcIpbuf[2],srcIpbuf[3]);//高低位对调
u32 destIP = IP4_ADDR(destIpbuf[0],destIpbuf[1],destIpbuf[2],destIpbuf[3]);//高低位对调
u8 * databuf = dbuf;
u16 datalen = dlen;
u8 headIP = 0x45;//ipv4 20B
u8 priority = 0x00;//优先级
u16 lenIP = 20+8+dlen;
static u16 identifyflag = 0x0001;//++
u16 flags = 0x0000;
u8 ttl = 0x40;//生命
//~~~~~~~~~~~~~~~~~~~IP头
chk_sum=0;
chk_sumxxx = LWIP_MAKE_U16(headIP, priority);//0x4500
chk_sum +=chk_sumxxx;
chk_sumxxx = lenIP;
chk_sum += chk_sumxxx;
chk_sumxxx = identifyflag;
chk_sum += chk_sumxxx;
chk_sumxxx = flags;
chk_sum += chk_sumxxx;
chk_sumxxx = LWIP_MAKE_U16(ttl, proto);//0x4011
chk_sum += chk_sumxxx;
chk_sumxxx = (srcIP & 0xFFFF);
chk_sum += chk_sumxxx;
chk_sumxxx = (srcIP >> 16);
chk_sum += chk_sumxxx;
chk_sumxxx = (destIP & 0xFFFF);
chk_sum += chk_sumxxx;
chk_sumxxx = (destIP >> 16);
chk_sum += chk_sumxxx;
chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);
chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);
chk_sum = ~chk_sum;
chk_sum_IP=chk_sum;
//~~~~~~~~~~~~~~~~~~~UDP头+data
chk_sum=0;
chk_sumxxx = (srcPORT);
chk_sum += chk_sumxxx;
chk_sumxxx = (destPORT);
chk_sum += chk_sumxxx;
chk_sumxxx = (lenUDP);
chk_sum += chk_sumxxx;
chk_sumxxx = lwip_standard_chksum(databuf, datalen);//求和完的结果会 高低位对调
chk_sumxxx = SWAP_BYTES_IN_WORD(chk_sumxxx);
chk_sum += chk_sumxxx;
//~~~~~~~~~~~~~~~~~~~伪UDP头
chk_sumxxx = (srcIP & 0xFFFF);
chk_sum += chk_sumxxx;
chk_sumxxx = (srcIP >> 16);
chk_sum += chk_sumxxx;
chk_sumxxx = (destIP & 0xFFFF);
chk_sum += chk_sumxxx;
chk_sumxxx = (destIP >> 16);
chk_sum += chk_sumxxx;
chk_sumxxx = (lenUDP);
chk_sum += chk_sumxxx;
chk_sumxxx = (proto);
chk_sum += chk_sumxxx;
chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);
chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);
chk_sum = ~chk_sum;
chk_sum_UDP=chk_sum;
//~~~~~~~~~~~~~~~~~~~整理数据
//IP
udata.headIP = headIP;
udata.priority = priority;
udata.lenIP = LWIP_hton_U16(lenIP);
udata.identifyflag = LWIP_hton_U16(identifyflag);
udata.flags = LWIP_hton_U16(flags);
udata.ttl = ttl;
udata.proto = proto;
udata.checkIP = LWIP_hton_U16(chk_sum_IP);
udata.srcIP = LWIP_hton_U32(srcIP);
udata.destIP = LWIP_hton_U32(destIP);
//UDP
udata.srcPORT = LWIP_hton_U16(srcPORT);
udata.destPORT = LWIP_hton_U16(destPORT);
udata.lenUDP = LWIP_hton_U16(lenUDP);
udata.checkUDP = LWIP_hton_U16(chk_sum_UDP);
memcpy(&(retbuf[0]),(u8*)(&udata),sizeof(udp_pcb_def));
//retbuf = (u8*)(&udata);
//*retlen = sizeof(udp_pcb_def);
return;
}
int main(void)
{
//IP_data();
u8 ipsrcbuf[4];
ipsrcbuf[0]=10;
ipsrcbuf[1]=50;
ipsrcbuf[2]=133;
ipsrcbuf[3]=37;
u8 ipdesbuf[4];
ipdesbuf[0]=114;
ipdesbuf[1]=55;
ipdesbuf[2]=168;
ipdesbuf[3]=54;
u8 sdatabuf[] = "from minh";
u8 retbuf[(sizeof(udp_pcb_def)+sizeof(sdatabuf))];
u16 retlen=0;
UDP_data(retbuf,&retlen,1501,1501,ipsrcbuf,ipdesbuf,sdatabuf,sizeof(sdatabuf)-1);
memcpy(&(retbuf[sizeof(udp_pcb_def)]),sdatabuf,sizeof(sdatabuf)-1);
}
^DPPPI: 1,"10.50.143.226","0.0.0.0","219.150.32.132","123.150.150.150"
int i,n=0;
String[] words;
Scanner sc=new Scanner(System.in);
System.out.println ("请输入一串数字,以逗号隔开:");
String str=sc.next();
for(i=0;i> 16);
chk_sum += chk_sumxxx;
chk_sumxxx = LWIP_CHANGE_U16(destIP & 0xFFFF);
chk_sum += chk_sumxxx;
chk_sumxxx = LWIP_CHANGE_U16(destIP >> 16);
chk_sum += chk_sumxxx;
//chk_sumxxx = (chk_sum >> 16);
//chk_sum += chk_sumxxx;
//chk_sumxxx = (chk_sum & 0xFFFF);
//chk_sum += chk_sumxxx;
chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);
chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF);
chk_sum = ~chk_sum;
}
*/