IP协议--TTL详解
什么是TTL
linux 内核修改TTL
IP包头中TTL值每过一次中间设备就会被减1,当TTL值为0的时候在网络中会被丢弃。
在Linux 内核中是如何操作的?
对TTL值做减法的函数
文件:ip.h
static inline
int ip_decrease_ttl(struct iphdr *iph)
{
/* 重新计算IP包头的校验和 */
u32 check = (__force u32)iph->check;
check += (__force u32)htons(0x0100);
iph->check = (__force __sum16)(check + (check>=0xFFFF));
/* TTL值在转发前被减1 */
return --iph->ttl;
}
因为调用这个函数后,TTL的值减一,所以需要重新计算校验和。为什么是这种方式计算校验和呢?参考《IP协议首部校验和》中的解释。
重新为TTL赋值
如果重新给TTL赋值,那么需要重新计算首部校验和,但是不能用上面的办法了,需要调用ip_fast_csum函数来重新计算校验和。
注意,调用ip_fast_csum函数前,需要把check置0.
static inline
int ip_decrease_ttl(struct iphdr *iph)
{
iph->ttl = 64;
iph->check = 0;
iph->check = ip_fast_csum( ( char * ) iph, iph->ihl );
/* TTL值在转发前被减1 */
return iph->ttl;
}
参考文档
在执行ip_fast_csum前忘记把ip头的check设置为0,导致接收数据包的程序无法收到数据包
IP首部校验和计算
Linux从用户层到内核层系列 - TCP/IP协议栈部分系列4: IP层IP封包中TTL值何时修改
Linux内核入门: ip协议头定义
大端存储和小端存储,网络字节序