【发布时间】:2012-10-24 01:45:39
【问题描述】:
来自这个网站:http://www.enderunix.org/docs/en/rawipspoof/
我拉了以下函数
unsigned short in_cksum(unsigned short *addr, int len)
{
int nleft = len;
int sum = 0;
unsigned short *w = addr;
unsigned short answer = 0;
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
if (nleft == 1) {
*(unsigned char *) (&answer) = *(unsigned char *) w;
sum += answer;
}
sum = (sum >> 16) + (sum & 0xFFFF);
sum += (sum >> 16);
answer = ~sum;
return (answer);
}
unsigned short in_cksum_tcp(int src, int dst, unsigned short *addr, int len)
{
struct psd_tcp buf;
u_short ans;
memset(&buf, 0, sizeof(buf));
buf.src.s_addr = src;
buf.dst.s_addr = dst;
buf.pad = 0;
buf.proto = IPPROTO_TCP;
buf.tcp_len = htons(len);
memcpy(&(buf.tcp), addr, len);
ans = in_cksum((unsigned short *)&buf, 12 + len);
return (ans);
}
但是,当我对看到的传入 TCP 数据包运行此程序时,我没有得到与当前相同的校验和结果(我保存传入的 TCP 校验和并将数据包上的校验和设置为零,然后再尝试运行校验和函数)
现在,当我对 IP 标头运行“in_cksum”时,我得到了正确的答案。
这是来自该站点的 TCP 伪标头:
struct psd_tcp {
struct in_addr src;
struct in_addr dst;
unsigned char pad;
unsigned char proto;
unsigned short tcp_len;
struct tcphdr tcp;
};
是不是缺少了一些东西来完成这项工作?
【问题讨论】:
-
对我来说,不清楚什么时候算对,什么时候算错?
-
当我使用 in_cksum() 作为 IP 标头的校验和时,我得到了正确的结果。当我将 in_cksum_tcp() 用于 TCP 校验和时,我得到了错误的总和。唯一的修改是我在调用任一方法之前将 IP 和 TCP 校验和字段设置为零。
-
你确定你的编译器没有在
struct psd_tcp中添加填充,它真的有12个字节长(没有struct tcphdr)? @德里克 -
我可以仔细检查。 sizeof() 总是会给你准确的答案吗?我知道 sizeof 告诉我 12 个字节,但也许我需要在声明中指定打包。
-
这个神奇的数字 12 是什么意思?更好地使用 sizeof() 那里。
标签: c tcp network-programming ip freebsd