Chinaunix

标题: ip option选项时间戳 ip_options_echo函数 [打印本页]

作者: jonas_mao    时间: 2014-01-13 14:47
标题: ip option选项时间戳 ip_options_echo函数
本帖最后由 jonas_mao 于 2014-01-13 14:50 编辑
  1. if (sopt->ts) {
  2.                 optlen = sptr[sopt->ts+1];
  3.                 soffset = sptr[sopt->ts+2];
  4.                 dopt->ts = dopt->optlen + sizeof(struct iphdr);
  5.                 memcpy(dptr, sptr+sopt->ts, optlen);
  6.                 if (soffset <= optlen) {
  7.                         if (sopt->ts_needaddr) {
  8.                                 if (soffset + 3 > optlen)
  9.                                         return -EINVAL;
  10.                                 dopt->ts_needaddr = 1;
  11.                                 soffset += 4;
  12.                         }
  13.                         if (sopt->ts_needtime) {
  14.                                 if (soffset + 3 > optlen)
  15.                                         return -EINVAL;
  16.                                 if ((dptr[3]&0xF) != IPOPT_TS_PRESPEC) {
  17.                                         dopt->ts_needtime = 1;
  18.                                         soffset += 4;
  19.                                 } else {
  20.                                         dopt->ts_needtime = 0;

  21.                                             if (soffset + 8 <= optlen) {
  22.                                                 __be32 addr;

  23.                                                 memcpy(&addr, sptr+soffset-1, 4);
  24.                                                 if (inet_addr_type(dev_net(skb_dst(skb)->dev), addr) != RTN_LOCAL){
  25.                                                         dopt->ts_needtime = 1;
  26.                                                         soffset += 8;
  27.                                                 }
  28.                                         }
  29.                                 }
  30.                         }
  31.                         dptr[2] = soffset;
  32.                 }
  33.                 dptr += optlen;
  34.                 dopt->optlen += optlen;
  35.         }
复制代码
请问上面if (inet_addr_type(dev_net(skb_dst(skb)->dev), addr) != RTN_LOCAL)
一行中 if 判断的地址类型为什么是LOCAL的,这里的local是不是指本地存在的地址,ip 选项的时间戳的IPOPT_TS_PRESPEC这种不是说记录的ip地址如果是本地设备节点的地址的话才记录时间的,这里为毛是 != RTN_LOCAL ? 不可能是个坑吧>
作者: 瀚海书香    时间: 2014-01-15 13:49
回复 1# jonas_mao
请问上面if (inet_addr_type(dev_net(skb_dst(skb)->dev), addr) != RTN_LOCAL)
一行中 if 判断的地址类型为什么是LOCAL的,这里的local是不是指本地存在的地址,ip 选项的时间戳的IPOPT_TS_PRESPEC这种不是说记录的ip地址如果是本地设备节点的地址的话才记录时间的,这里为毛是 != RTN_LOCAL ? 不可能是个坑吧>


1. 这的确是个坑
2. 这是个很老的坑,2011年3月份已经填上了
详细信息:

git log 8628bd8a
  1. commit 8628bd8af7c4c14f40f5183f80f5744c4e682439
  2. Author: Jan Luebbe <jluebbe@debian.org>
  3. Date:   Thu Mar 24 07:44:22 2011 +0000

  4.     ipv4: Fix IP timestamp option (IPOPT_TS_PRESPEC) handling in ip_options_echo()
  5.    
  6.     The current handling of echoed IP timestamp options with prespecified
  7.     addresses is rather broken since the 2.2.x kernels. As far as i understand
  8.     it, it should behave like when originating packets.
  9.    
  10.     Currently it will only timestamp the next free slot if:
  11.      - there is space for *two* timestamps
  12.      - some random data from the echoed packet taken as an IP is *not* a local IP
  13.    
  14.     This first is caused by an off-by-one error. 'soffset' points to the next
  15.     free slot and so we only need to have 'soffset + 7 <= optlen'.
  16.    
  17.     The second bug is using sptr as the start of the option, when it really is
  18.     set to 'skb_network_header(skb)'. I just use dptr instead which points to
  19.     the timestamp option.
  20.    
  21.     Finally it would only timestamp for non-local IPs, which we shouldn't do.
  22.     So instead we exclude all unicast destinations, similar to what we do in
  23.     ip_options_compile().
  24.    
  25.     Signed-off-by: Jan Luebbe <jluebbe@debian.org>
  26.     Signed-off-by: David S. Miller <davem@davemloft.net>

  27. diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
  28. index 1906fa3..28a736f 100644
  29. --- a/net/ipv4/ip_options.c
  30. +++ b/net/ipv4/ip_options.c
  31. @@ -140,11 +140,11 @@ int ip_options_echo(struct ip_options * dopt, struct sk_buff * skb)
  32.                                 } else {
  33.                                         dopt->ts_needtime = 0;

  34. -                                       if (soffset + 8 <= optlen) {
  35. +                                       if (soffset + 7 <= optlen) {
  36.                                                 __be32 addr;

  37. -                                               memcpy(&addr, sptr+soffset-1, 4);
  38. -                                               if (inet_addr_type(dev_net(skb_dst(skb)->dev), addr) != RTN_LOCAL) {
  39. +                                               memcpy(&addr, dptr+soffset-1, 4);
  40. +                                               if (inet_addr_type(dev_net(skb_dst(skb)->dev), addr) != RTN_UNICAST) {
  41.                                                         dopt->ts_needtime = 1;
复制代码

作者: jonas_mao    时间: 2014-01-20 10:17
回复 2# 瀚海书香

谢谢版主,已经按照最新的版本修改了。ip_options 可能用的比较少,所以以前没怎么注意


   




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2