gpt4 book ai didi

c - IPv4 header 校验和计算,我错过了什么

转载 作者:可可西里 更新时间:2023-11-01 02:34:41 26 4
gpt4 key购买 nike

一段时间以来一直在尝试修复此代码,但没有成功,尝试了计算 IPv4 header 校验和的不同实现,但是它们的输出与我的程序输出有很大不同:

我从 linux 中窃取的函数 kernel这样做:

static inline uint16_t ip_fast_csum(const void *iph, unsigned int ihl){

unsigned int sum;

asm(" movl (%1), %0\n"
" subl $4, %2\n"
" jbe 2f\n"
" addl 4(%1), %0\n"
" adcl 8(%1), %0\n"
" adcl 12(%1), %0\n"
"1: adcl 16(%1), %0\n"
" lea 4(%1), %1\n"
" decl %2\n"
" jne 1b\n"
" adcl $0, %0\n"
" movl %0, %2\n"
" shrl $16, %0\n"
" addw %w2, %w0\n"
" adcl $0, %0\n"
" notl %0\n"
"2:"
/* Since the input registers which are loaded with iph and ihl
are modified, we must also specify them as outputs, or gcc
will assume they contain their original values. */
: "=r" (sum), "=r" (iph), "=r" (ihl)
: "1" (iph), "2" (ihl)
: "memory");
return ( uint16_t)sum; }

样本头(字节):45009d4326400406af6cd052ed12ac10a51

调用上述函数的程序部分将校验和分配给 header 并打印 header 和校验和:

  newpacket.ipheader->check = ip_fast_csum ((unsigned short *) newpacket.ipheader, IP4_HDRLEN);
debug(5,"newpacket checksum set to %0x\r\n",newpacket.ipheader->check);
uint8_t *ipbuf=(uint8_t *)newpacket.ipheader;
for(i=0;i<IP4_HDRLEN;i++){
debug(5,"%0x",ipbuf[i]);
}debug(5,"\n");

debug() 只是一个 printf() 包装器,下面是示例输出:

newpacket checksum set to 6caf
45009d4326400406af6cd052ed12ac10a51

wireshark 告诉我的屏幕截图:

wiresharkcap

你能帮帮我,告诉我哪里做错了吗?

这是我通常使用的功能:

inline unsigned short csum (unsigned short *buf, int nwords) {
unsigned long sum;

for (sum = 0; nwords > 0; nwords--)
sum += *buf++;
sum = (sum >> 16) + (sum & 0xffff);
sum += (sum >> 16);
return (unsigned short) (~sum);
}

提前致谢。

最佳答案

只是为了从评论中扩展更多@SergeyA 和我自己。如果您查看您引用的文件 above ,您会在该功能的评论中注意到

ip_fast_csum - Compute the IPv4 header checksum efficiently.

你不想计算你想要的 TCP 校验和的 IPv4 header 校验和。这些是 OSI 模型中的独立层 here .要计算 TCP 校验和,您需要执行 these细人形容。

如您之前所想,仅使用内核代码,可在此处找到一个函数,该函数应计算 TCP 校验和。下面我将复制它的描述和标题。

static inline __sum16 tcp_v4_check(int len, __be32 saddr,
__be32 daddr, __wsum base)
  • Calculate(/check) TCP checksum

但是,如果您想以困难的方式进行。查看您引用的同一个文件,您可以使用该函数计算 TCP 数据包的伪 header 。

csum_tcpudp_nofold(__be32 saddr, __be32 daddr, __u32 len,
__u8 proto, __wsum sum)

Returns the pseudo header checksum the input data. Result is 32bit unfolded.

这只是伪 header ,但从那里您需要计算总校验和,我相信(不是 100% 确定)如果您将前面描述的伪 header 填充到它上面,您可以只使用您之前显示的函数来计算。

顺便说一句,我没有检查过这段代码,但乍一看它似乎相当准确所以 here是一种C/汇编的方式来计算TCP校验和。

关于c - IPv4 header 校验和计算,我错过了什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37351659/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com