- 声明 看了一个博主写的文章 但是因为自己电脑环境的问题最终没有运行 本文仅对思路进行一个讲解 大家就看一下这个思路就好 不好意思大家
- 测试环境 window10系统 哈工大的泰山服务器
检验和部分
原理
首先让检验和部分为0(二进制) 然后将左边的部分依次相加 然后将地址分成如图所示的几个部分 然后求和 最后将结果取反码。
代码实现
USHORT checksum(USHORT *buffer, int size)//这是检验和函数,复制网上的,没什么好注释的
{
unsigned long cksum=0;
while(size >1)
{
cksum+=*buffer++;
size -=sizeof(USHORT);
}
if(size )
{
cksum += *(UCHAR*)buffer;
}
cksum = (cksum >> 16) + (cksum & 0xffff);
cksum += (cksum >>16);
return (USHORT)(~cksum);
}
解析
函数的输入参数包括一个指向数据缓冲区的指针 buffer
和数据缓冲区的大小 size
(以字节为单位)。假定 buffer
指向一个由 USHORT(2字节) 元素组成的序列。
函数的工作步骤如下:
-
函数初始化一个无符号长整型变量
cksum
,用于存储校验和的值。 -
然后进入一个循环,从缓冲区处理 USHORT 元素。循环会在
size
大于1时执行(也就是说,至少有2个字节需要处理)。在循环内部,它将每个 USHORT 元素的值累加到cksum
中,并将指针buffer
移动到下一个 USHORT 元素。 -
如果总字节数是奇数,并且还有一个剩余的字节(size = 1),则会单独处理该字节。它将剩余字节视为一个 UCHAR(1字节)并将其值加到
cksum
中。 -
上述两个步骤确保了正确处理缓冲区中的所有字节,无论总字节数是奇数还是偶数。
-
在处理完缓冲区所有元素后,需要处理可能在累加过程中产生的进位位。它将
cksum
分成两部分:超过第16位的进位位和低16位。 -
然后将进位位加到低16位,并将结果存回
cksum
。这一步很重要,以确保校验和值是一个16位的数。 -
接下来,它再次将进位位加到低16位。
-
最后,它对结果取反(即翻转所有位),并以 USHORT 格式返回校验和值。
接下来 我们对各层数据部分进行赋值
物理帧格式
物理帧位于数据链路层,他建立的是端到端之间的连接 本文为了简化 将以太网数据帧包装成只有源和目的mac地址(源是本机的地址 通过getmac指令和排除法确定 目的mac地址是网关) 物理帧在传输的过程中源和目的mac是一直在变化的 中间需要拆包处理再发送 看下方第二个图)