通过raw socket修改通信数据后,可通过函数
set_tcp_checksum1(iph);
重新校验计算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 > 1 ) { /* This is the inner loop */ sum += ntohs(* (u_int16_t*) addr); addr += 2; count -= 2; } /* Add left-over byte, if any */ if( count > 0 ) sum += ntohs(* (u_int8_t*) addr); /* Fold 32-bit sum to 16 bits */ while (sum>>16) sum = (sum & 0xffff) + (sum >> 16); return (u_int16_t)~sum; } static u_int16_t tcp_checksum2(struct iphdr* iphdrp, struct tcphdr* tcphdrp){ size_t tcplen = ntohs(iphdrp->tot_len) - (iphdrp->ihl<<2); u_int32_t cksum = 0; cksum += ntohs((iphdrp->saddr >> 16) & 0x0000ffff); cksum += ntohs(iphdrp->saddr & 0x0000ffff); cksum += ntohs((iphdrp->daddr >> 16) & 0x0000ffff); cksum += ntohs(iphdrp->daddr & 0x0000ffff); cksum += iphdrp->protocol & 0x00ff; cksum += tcplen; return checksum(cksum, (u_int8_t*)tcphdrp, tcplen); } static u_int16_t tcp_checksum1(struct iphdr* iphdrp){ struct tcphdr *tcphdrp = (struct tcphdr*)((u_int8_t*)iphdrp + (iphdrp->ihl<<2)); return tcp_checksum2(iphdrp, tcphdrp); } static void set_tcp_checksum2(struct iphdr* iphdrp, struct tcphdr* tcphdrp){ tcphdrp->check = 0; tcphdrp->check = htons(tcp_checksum2(iphdrp, tcphdrp)); } static void set_tcp_checksum1(struct iphdr* iphdrp){ struct tcphdr *tcphdrp = (struct tcphdr*)((u_int8_t*)iphdrp + (iphdrp->ihl<<2)); set_tcp_checksum2(iphdrp, tcphdrp); }