【发布时间】:2018-03-28 09:15:03
【问题描述】:
我正在编写一个用于 DDoS 缓解的用户空间应用程序并实施某些缓解策略,我需要能够动态更改 TCP 选项以及数据包标头中的序列号和确认号等内容。
计算校验和的常用方法是重新创建一个新的 TCP 伪报头并遍历整个数据包以计算校验和,但还有另一种方法,即仅计算仅更改的单词之间的差异并执行一个-补减法。
我当前的代码似乎经常关闭 1 或 2。我怀疑这是一个问题,因为我没有正确处理进位/借位。我对如何解决这个问题一无所知:
unsigned short pseq1, pseq2, pseq3, pseq4
unsigned short sum1, sum2, sum3, prevcheck;
short pdiff1, pdiff2;
u_char *pkt_data;
prevcheck = (pkt_data[50] << 8) | pkt_data[51];
pseq1 = (pkt_data[38] << 8) | pkt_data[39];
pseq2 = (pkt_data[40] << 8) | pkt_data[41];
pkt_data[38] = ((seq_num - offsetResult) >> 24) & 0xFF;
pkt_data[39] = ((seq_num - offsetResult) >> 16) & 0xFF;
pkt_data[40] = ((seq_num - offsetResult) >> 8) & 0xFF;
pkt_data[41] = (seq_num - offsetResult) & 0xFF;
pseq3 = (pkt_data[38] << 8) | pkt_data[39];
pseq4 = (pkt_data[40] << 8) | pkt_data[41];
pdiff1 = pseq1 - pseq3;
pdiff2 = pseq2 - pseq4;
sum1 = ~pdiff1 + ~pdiff2;
sum2 = ~sum1;
sum3 = sum2 + prevcheck;
pkt_data[50] = (sum3 >> 8) & 0xFF;
pkt_data[51] = sum3 & 0xFF;
在这种情况下:68 05 ca 57 94 05 60 73 5c d0 57 bf 08 00 45 00 00 2c 00 00 40 00 3f 06 bc a5 b9 aa 2a 6a 42 f9 58 19 00 50 ed 48 fc e4 57 e5 6e c0 f6 c8 60 12 72 10 fe f3 00 00 02 04 05 b4 00 00
产生的校验和是fef3,而它应该是fef2。
任何建议都会很棒!
【问题讨论】:
-
请显示变量的声明以及它们的类型定义。
-
@Acorn:我已经继续添加变量声明及其类型定义。我们正在使用的所有内容都是未签名的,而且大部分时间都很短。
-
@rustyx:如果我没记错的话,我确实需要担心算术过程中带有“环绕”值的进位。我肯定会很清楚,因为它肯定不一致。
-
@rustyx:我将 pdiff 声明为带符号的 short 并删除了 -1 和 +1 if 语句,并且我的校验和值仍然经常不正确 1。在这种情况下:
68 05 ca 57 94 05 60 73 5c d0 57 bf 08 00 45 00 00 2c 00 00 40 00 3f 06 bc a5 b9 aa 2a 6a 42 f9 58 19 00 50 ed 48 fc e4 57 e5 6e c0 f6 c8 60 12 72 10 fe f3 00 00 02 04 05 b4 00 00生成的校验和是fef3应该是fef2。
标签: c