gpt4 book ai didi

c - Libnet TCP 校验和错误

转载 作者:太空宇宙 更新时间:2023-11-03 23:55:54 29 4
gpt4 key购买 nike

我正在尝试使用 libnet 库构建一个 TCP 数据包。我在 libnet_build_tcp 函数中使用 '0' 自动计算校验和值。但是,校验和似乎在计算时忽略了 pseudo-header,由于校验和错误导致无用的数据包。有谁知道如何解决这个问题?

最佳答案

据我在代码中看到的,只要你没有使用过libnet_toggle_checksum(l, ptag, 1);你的0sum libnet_build_tcp() 的参数应该通过调用 libnet_pblock_setflags(p, LIBNET_PBLOCK_DO_CHECKSUM) 使其自动为您计算校验和.

我真的不能告诉你如何解决它,但既然你是构建数据包的人,也许你可以选择创建自己的校验和?

TCP 伪报头是一个 12 字节的字段,包含源 IP 地址和目标 IP 地址(均为 4 字节)、一个 2 字节且始终设置为零的保留字段,以及一个 4 字节的 TCP 段长度,该段长度等于TCP header 的大小 + 有效负载长度。

你可以创建这样的东西:

首先创建你的变量:

int bytesRead;
int pseudoHeaderLength;
int payloadLength;
int tcpHdrLength;
int tcpSegmentLength;
int ipHdrLength;
int headerLengths;
int ethIPHdrLengths;

struct ethhdr *ethHdr;
struct iphdr *ipHdr;
struct tcphdr *tcpHdr;

u_int8_t *pkt_data;
u_int8_t pseudoHeader[12];
u_int8_t packetBuffer[1600];
u_int16_t newChecksum;

然后创建实际函数,其中 b->len 是数据包的总大小(只需添加所有 header + 有效负载并获得总大小),您只需将 header 和数据 memcpy 到 pkt_data:

ethHdr = (struct ethhdr*)pkt_data;
ipHdr = (struct iphdr*)(pkt_data + ETH_HLEN);

ipHdrLength = ipHdr->ihl * 4;

ethIPHdrLengths = ETH_HLEN + ipHdrLength;

tcpHdr = (struct tcphdr*)(pkt_data + ethIPHdrLengths);

tcpHdrLength = tcpHdr->doff * 4;

headerLengths = ethIPHdrLengths + tcpHdrLength;

payloadLength = b->len - headerLengths;

tcpSegmentLength = tcpHdrLength + payloadLength;

pseudoHeaderLength = tcpSegmentLength + 12;

pseudoHeader[0] = pkt_data[30];
pseudoHeader[1] = pkt_data[31];
pseudoHeader[2] = pkt_data[32];
pseudoHeader[3] = pkt_data[33];
pseudoHeader[4] = pkt_data[26];
pseudoHeader[5] = pkt_data[27];
pseudoHeader[6] = pkt_data[28];
pseudoHeader[7] = pkt_data[29];
pseudoHeader[8] = 0x00;
pseudoHeader[9] = 0x06;
pseudoHeader[10] = (tcpSegmentLength >> 8) & 0xFF;
pseudoHeader[11] = tcpSegmentLength & 0xFF;

bytesRead = 0;

for(i = 0; i < 12; i++) {
packetBuffer[bytesRead] = pseudoHeader[i];
bytesRead++;
}

for(i = ethIPHdrLengths; i < headerLengths; i++) {
packetBuffer[bytesRead] = pkt_data[i];
bytesRead++;
}

for(i = b->len - payloadLength; i < b->len; i++) {
packetBuffer[bytesRead] = pkt_data[i];
bytesRead++;
}

newChecksum = checksum((uint16_t *)packetBuffer, pseudoHeaderLength);

只需使用 https://www.rfc-editor.org/rfc/rfc1071 提供的校验和功能即可计算缓冲区的校验和:

uint16_t checksum(uint16_t *addr, int len)
{

int count = len;
register uint32_t sum = 0;
uint16_t answer = 0;

while (count > 1) {
sum += *(addr++);
count -= 2;
}

if (count > 0) {
sum += *(uint8_t *) addr;
}

while (sum >> 16) {
sum = (sum & 0xffff) + (sum >> 16);
}

answer = ~sum;

return (answer);
}

我在现实环境中使用它来计算 500 万 PPS 的校验和。

关于c - Libnet TCP 校验和错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7871285/

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