通过raw socket修改通信数据后,可通过函数
set_udp_checksum1
重新校验计算iph->check值
在http://www.cnblogs.com/dpf-10/p/7899237.html查看实际应用
static u_int16_t checksum(u_int32_t init, u_int8_t *addr, size_t count){
/* Compute Internet Checksum for "count" bytes * beginning at location "addr". */
u_int32_t sum = init; while( count > ) {
/* This is the inner loop */
sum += ntohs(* (u_int16_t*) addr);
addr += ;
count -= ;
} /* Add left-over byte, if any */
if( count > )
sum += ntohs(* (u_int8_t*) addr); /* Fold 32-bit sum to 16 bits */
while (sum>>)
sum = (sum & 0xffff) + (sum >> );
return (u_int16_t)~sum;
}
static u_int16_t udp_checksum2(struct iphdr* iphdrp, struct udphdr* udphdrp){
size_t udplen = ntohs(iphdrp->tot_len) - (iphdrp->ihl<<);
u_int32_t cksum = ; cksum += ntohs((iphdrp->saddr >> ) & 0x0000ffff);
cksum += ntohs(iphdrp->saddr & 0x0000ffff);
cksum += ntohs((iphdrp->daddr >> ) & 0x0000ffff);
cksum += ntohs(iphdrp->daddr & 0x0000ffff);
cksum += iphdrp->protocol & 0x00ff;
cksum += udplen;
return checksum(cksum, (u_int8_t*)udphdrp, udplen);
} static u_int16_t udp_checksum1(struct iphdr* iphdrp){
struct udphdr *udphdrp = (struct udphdr*)((u_int8_t*)iphdrp + (iphdrp->ihl<<));
return udp_checksum2(iphdrp, udphdrp);
}
static void set_udp_checksum2(struct iphdr* iphdrp, struct udphdr* udphdrp){
udphdrp->check = ;
udphdrp->check = htons(udp_checksum2(iphdrp, udphdrp));
}
static void set_udp_checksum1(struct iphdr* iphdrp){
struct udphdr *udphdrp = (struct udphdr*)((u_int8_t*)iphdrp + (iphdrp->ihl<<));
set_udp_checksum2(iphdrp, udphdrp);
}