• IP结构与操作之inet_select_addr


    当通过输出设备向目的地址发送报文时,如果没有源地址,则需要调用inet_select_addr来选择ip地址作为源地址;

      1 /* 
      2     选择ip地址 
      3 
      4     通过设备找到ip控制块,从ip控制块中遍历地址列表中的主地址,
      5     优先选择满足范围,满足于目的地址网络部分相同的地址,
      6     找不到则默认第一个满足范围的地址
      7 
      8     找不到ip控制块,则走no_in_dev流程
      9   */
     10 __be32 inet_select_addr(const struct net_device *dev, __be32 dst, int scope)
     11 {
     12     __be32 addr = 0;
     13     struct in_device *in_dev;
     14     struct net *net = dev_net(dev);
     15     int master_idx;
     16 
     17     rcu_read_lock();
     18 
     19     /* 获取ip配置块 */
     20     in_dev = __in_dev_get_rcu(dev);
     21     if (!in_dev)
     22         goto no_in_dev;
     23 
     24     /* 遍历链表中的主地址 */
     25     for_primary_ifa(in_dev) {
     26     
     27         /* 当前地址范围> 传入地址范围
     28             则实际地址范围小,不满足要求
     29         */
     30         if (ifa->ifa_scope > scope)
     31             continue;
     32 
     33         /* 如果未提供目的地址|| 目的地址与当前地址网络部分相同 */
     34         if (!dst || inet_ifa_match(dst, ifa)) {
     35             /* 设置当前地址为查找地址 */
     36             addr = ifa->ifa_local;
     37             break;
     38         }
     39 
     40         /*     如果第一次遍历到这里地址未找到,
     41             则先将其默认为第一个满足范围主地址 
     42         */
     43         if (!addr)
     44             addr = ifa->ifa_local;
     45     } endfor_ifa(in_dev);
     46 
     47     /* 找到地址 */
     48     if (addr)
     49         goto out_unlock;
     50 
     51 /* 没有ip控制块 */
     52 no_in_dev:
     53 
     54     /* TODO l3mdev相关不熟 */
     55 
     56     /* 获取主设备id */
     57     master_idx = l3mdev_master_ifindex_rcu(dev);
     58 
     59     /* For VRFs, the VRF device takes the place of the loopback device,
     60      * with addresses on it being preferred.  Note in such cases the
     61      * loopback device will be among the devices that fail the master_idx
     62      * equality check in the loop below.
     63      */
     64     /* 主设备id不为空,通过该设备id能够获取到设备,
     65         通过该设备能够获取到地址控制块
     66     */
     67     if (master_idx &&
     68         (dev = dev_get_by_index_rcu(net, master_idx)) &&
     69         (in_dev = __in_dev_get_rcu(dev))) {
     70         /* 选择ip地址 */
     71         addr = in_dev_select_addr(in_dev, scope);
     72         if (addr)
     73             goto out_unlock;
     74     }
     75 
     76     /* Not loopback addresses on loopback should be preferred
     77        in this case. It is important that lo is the first interface
     78        in dev_base list.
     79      */
     80     /* 遍历所有设备 */
     81     for_each_netdev_rcu(net, dev) {
     82 
     83         /* 与主设备不等 */
     84         if (l3mdev_master_ifindex_rcu(dev) != master_idx)
     85             continue;
     86 
     87         /* 获取地址配置块 */
     88         in_dev = __in_dev_get_rcu(dev);
     89         if (!in_dev)
     90             continue;
     91 
     92         /* 获取ip地址 */
     93         addr = in_dev_select_addr(in_dev, scope);
     94         if (addr)
     95             goto out_unlock;
     96     }
     97 out_unlock:
     98     rcu_read_unlock();
     99     return addr;
    100 }
     1 /* 通过ip控制块和范围选择合适地址 */
     2 static __be32 in_dev_select_addr(const struct in_device *in_dev,
     3                  int scope)
     4 {
     5     /* 遍历该ip控制块中主地址 */
     6     for_primary_ifa(in_dev) {
     7         /* 找地址范围不是link && 范围小于输入范围的地址 */
     8         if (ifa->ifa_scope != RT_SCOPE_LINK &&
     9             ifa->ifa_scope <= scope)
    10             return ifa->ifa_local;
    11     } endfor_ifa(in_dev);
    12 
    13     return 0;
    14 }
  • 相关阅读:
    使用metasploit进行栈溢出攻击-2
    使用metasploit进行栈溢出攻击-1
    如何利用 Visual Studio 自带工具提高开发效率
    Visaul Studio 常用快捷键动画演示
    WinForm AutoComplete 输入提示、自动补全
    RTL2832U+R820T电视棒windows下安装sdr# 以及搭建ADS-B使用VirtualRadar看飞机的教程
    传说中的WCF(12):服务器回调有啥用
    传说中的WCF(11):会话(Session)
    传说中的WCF(10):消息拦截与篡改
    传说中的WCF(9):流与文件传输
  • 原文地址:https://www.cnblogs.com/wanpengcoder/p/7536913.html
Copyright © 2020-2023  润新知