Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
macOS NKE ipf#U过滤器&x2013;IP校验和为0_Macos_Networking_Tcp_Kernel_Ip - Fatal编程技术网

macOS NKE ipf#U过滤器&x2013;IP校验和为0

macOS NKE ipf#U过滤器&x2013;IP校验和为0,macos,networking,tcp,kernel,ip,Macos,Networking,Tcp,Kernel,Ip,我正在通过IP筛选器拦截、修改和重新注入传出的IPv4 TCP数据包。 问题是,在我更改数据包并设置IP和TCP校验和后,当我使用Wireshark分析结果数据包时,IP校验和等于0(我正在计算的校验和似乎是正确的,因为它等于Wireshark建议的校验和) 以下是我遵循的程序,我希望有人能够发现错误或提出更好的处理方法: static int handle_数据包(mbuf_t*数据、int ip_len、int dir、ipf_pktopts_选项) { 错误结果=0; 无符号字符包[150

我正在通过IP筛选器拦截、修改和重新注入传出的IPv4 TCP数据包。 问题是,在我更改数据包并设置IP和TCP校验和后,当我使用Wireshark分析结果数据包时,IP校验和等于0(我正在计算的校验和似乎是正确的,因为它等于Wireshark建议的校验和)

以下是我遵循的程序,我希望有人能够发现错误或提出更好的处理方法:

static int handle_数据包(mbuf_t*数据、int ip_len、int dir、ipf_pktopts_选项)
{
错误结果=0;
无符号字符包[1500];
结构tcphdr*tcp;
结构ip*ip;
mbuf_t old_packet=*数据,新_packet;
uint32_t mbufs=0,数据包字节=0;
//零数据包
bzero(数据包,sizeof(数据包));
//“完成”数据包,以便安全地修改它
mbuf_出站_最终确定(*数据,AF_INET,0);
//获取mbuf链的长度
做
    {
mbufs++;
数据包字节数+=mbuf长度(旧数据包);
旧_数据包=mbuf_下一个(旧_数据包);
}while(旧_包!=NULL);
//将数据复制到本地缓冲区
如果(0!=(结果=mbuf_copydata(*数据,0,数据包字节,数据包))){
printf(“mbuf_copydata返回%d”,结果);
返回0;
    }
//指向起始IP头的指针
ip=(结构ip*)数据包;
tcp=(结构tcphdr*)((u_int32_t*)ip+ip->ip\u hl);
{ / /只考虑SYN包
如果(!(tcp->THU标志和THU SYN))
返回KERN_成功;
如果(0!=(结果=mbuf_dup(*数据、mbuf_DONTWAIT和新数据包)))
    {
printf(“错误-mbuf_dup:无法复制mbuf,%d”,结果);
返回0;
    }
/**
…我正在修改数据包并重新计算ip和tcp的校验和
(之前将其设置为0,以避免之前的值
在计算中会考虑到这些因素)…
*/
    /*
*将缓冲区复制回mbuf
     */
如果(0!=(结果=mbuf_copyback(新_数据包,0,ntohs(ip->ip_len),数据包,mbuf_DONTWAIT)))
    {
mbuf_freem(新的_包);
开关(结果){
案例EINVAL:
printf(“错误-处理数据包:mbuf\u copyback返回EINVAL”);
返回0;
中断;
案例ENOBUFS:
printf(“错误-处理数据包:mbuf\u copyback返回ENOBUFS”);
返回0;
中断;
默认值:
中断;
        }
    }
//重新计算因数据更改而无效的任何校验和
//mbuf_outbound_finalize(新_数据包,AF_INET,0);//->PANIC(m->m_标志和m_PKTHDR)
  // 这有必要吗?
mbuf_set_csum_performed(新数据包,mbuf_csum_DID_IP | mbuf_csum_IP|GOOD | mbuf_csum_DID_DATA | mbuf_csum_伪HDR,校验和_IP(IP));
结果=ipf_注入_输出(新_数据包、ip_过滤器_参考、选项);
返回结果==0?EJUSTRETURN:result;
}
静态错误ip过滤器输出(void*cookie、mbuf\u t*数据、ipf\u pktopts\u选项)
{
结构ip*ip;
char src[32],dst[32];
int ip_len;
//指向起始IP头的指针
ip=(结构ip*)mbuf_数据(*数据);
ip_len=ntohs(ip->ip_len);
bzero(src,sizeof(src));
bzero(dst,sizeof(dst));
//将网络地址结构转换为字符串
inet_ntop(AF_inet,&ip->ip_src,src,sizeof(src));
inet_ntop(AF_inet,&ip->ip_dst,dst,sizeof(dst));
//避免拥塞并仅过滤来自/到tcpcrypt网站的数据包
如果(ip->ip\U p==IPPROTO\U TCP
&&mbuf_标志(*数据)==mbuf_-PKTHDR){
返回句柄数据包(数据、ip长度、方向输出/*1*/、选项);
    }
//继续正常处理数据包
返回KERN_成功;
}
我怀疑得到零是在整个报头上重新计算校验和的预期结果,也就是说,它会导致计算出的和自身抵消

无论如何,我真的不明白为什么会发生这种事

有人知道答案或者能帮忙吗

事先非常感谢


罗密欧如果你不运行你的程序,你会看到非零校验和吗

否则,您的NIC可能会进行校验和卸载,这使得驱动程序实际上不会向数据包中插入任何校验和(因为网络接口会处理它)


请参阅WireShark文档的第页。

如果不运行程序,是否会看到非零校验和

否则,您的NIC可能会进行校验和卸载,这使得驱动程序实际上不会向数据包中插入任何校验和(因为网络接口会处理它)

请参阅WireShark文档的第页。

首先

do
{
    mbufs++;
    packet_bytes += mbuf_len(old_packet);
    old_packet = mbuf_next(old_packet);
} while (old_packet != NULL);
这是一种获取mbuf链长度的可怕方法。正确的方法是

size_t totalLength = (
    mbuf_flags(mbuf) & MBUF_PKTHDR ?
    mbuf_pkthdr_len(mbuf) : mbuf_len(mbuf)
);
因为它是一个mbuf链,但是该链的第一个mbuf应该有一个paket头,并且这个paket头包含整个mbuf链的大小(没有这样的头的链根据定义是断开的),或者它只是一个mbuf,但是只要问这个mbuf的大小就足够了。在整个内核代码中,mbuf链的大小都会被检索到,如我上面的代码所示

然后请理解
mbuf\u outbound\u finalize()
的作用。根据该方法的文件:

此函数将“完成”数据包,允许代码检查最终数据包

有许多操作是在硬件中执行的,例如计算校验和。此功能将在软件中执行计划在硬件中执行的各种选择

所以,校验和计算是否转移到硬件上并不重要