zoukankan      html  css  js  c++  java
  • lwip nd没有实现ra,contik有参考

    lwip中关于nd的实现,没有路由器的功能,不能发送ra

    在contiki中发现有nd发送ra的实现,

    contiki/core/net/ipv6/uip-ds6.c

    在rs的接收处理中,发送sollicited,在定时器中定期发送periodic。

    发送solicted的时候,其实,是让定时器直接到时间实现的。

    在uip_ds6_init中初始化ra发送定时器,初始设为2s后发送?等待链路本地地址有效

    初始设置为2s,之后定时处理函数会处理定时器首次超时,处理完之后,会将定时器设置为RA间隔时间。

    void
    uip_ds6_init(void)
    {
    #if UIP_ND6_SEND_RA
      stimer_set(&uip_ds6_timer_ra, 2);     /* wait to have a link local IP address */
    #endif /* UIP_ND6_SEND_RA */

    在uip_ds6_periodic中定期处理是否超时,uip_ds6_periodic类似lwip中的nd_tmr。如果超时了,就发送uip_ds6_send_ra_periodic

    void
    uip_ds6_periodic(void)
    {
    #if UIP_CONF_ROUTER && UIP_ND6_SEND_RA
      /* Periodic RA sending */
      if(stimer_expired(&uip_ds6_timer_ra) && (uip_len == 0)) {
        uip_ds6_send_ra_periodic();
      }
    #endif /* UIP_CONF_ROUTER && UIP_ND6_SEND_RA */

     uip_ds6_send_ra_periodic函数中设置了两次随机时间,没看明白为什么?

    第一次时间:间隔=最小间隔+随机数*(最大间隔-最小间隔)

    第二次时间:初始的3次ra间隔不能超过初始最大间隔16s,后续的ra间隔没限制

     1 /*---------------------------------------------------------------------------*/
     2 void
     3 uip_ds6_send_ra_periodic(void)
     4 {
     5   if(racount > 0) {
     6     /* send previously scheduled RA */
     7     uip_nd6_ra_output(NULL);
     8     PRINTF("Sending periodic RA
    ");
     9   }
    10   /* rand_t = min + rand % (max - min) */
    11   rand_time = UIP_ND6_MIN_RA_INTERVAL + random_rand() %
    12     (uint16_t) (UIP_ND6_MAX_RA_INTERVAL - UIP_ND6_MIN_RA_INTERVAL);
    13   PRINTF("Random time 1 = %u
    ", rand_time);
    14   /* intial ra interval = 16s, initial 3 ra, should not exceed initial_ra_interval */
    15   if(racount < UIP_ND6_MAX_INITIAL_RAS) {
    16     if(rand_time > UIP_ND6_MAX_INITIAL_RA_INTERVAL) {
    17       rand_time = UIP_ND6_MAX_INITIAL_RA_INTERVAL;
    18       PRINTF("Random time 2 = %u
    ", rand_time);
    19     }
    20     racount++;
    21   }
    22   PRINTF("Random time 3 = %u
    ", rand_time);
    23   stimer_set(&uip_ds6_timer_ra, rand_time);
    24 }
    25  

    如果收到了rs(rs_input在uip-nd6.c文件中),则会发送sollicited的ra,在uip_ds6_send_ra_sollicited中,其实是直接将定时器设置到时间。

    /*---------------------------------------------------------------------------*/
    #if UIP_CONF_ROUTER
    #if UIP_ND6_SEND_RA
    void
    uip_ds6_send_ra_sollicited(void)
    {
      /* We have a pb here: RA timer max possible value is 1800s,
       * hence we have to use stimers. However, when receiving a RS, we
       * should delay the reply by a random value between 0 and 500ms timers.
       * stimers are in seconds, hence we cannot do this. Therefore we just send
       * the RA (setting the timer to 0 below). We keep the code logic for
       * the days contiki will support appropriate timers */
      rand_time = 0;
      PRINTF("Solicited RA, random time %u
    ", rand_time);
    
      if(stimer_remaining(&uip_ds6_timer_ra) > rand_time) {
        if(stimer_elapsed(&uip_ds6_timer_ra) < UIP_ND6_MIN_DELAY_BETWEEN_RAS) {
          /* Ensure that the RAs are rate limited */
    /*      stimer_set(&uip_ds6_timer_ra, rand_time +
                     UIP_ND6_MIN_DELAY_BETWEEN_RAS -
                     stimer_elapsed(&uip_ds6_timer_ra));
      */ } else {
          stimer_set(&uip_ds6_timer_ra, rand_time);
        }
      }
    }
    
    

    uip-nd6.c实际的接收rs和发送ra在这个文件中定义

     1 /*---------------------------------------------------------------------------*/
     2 static void
     3 rs_input(void)
     4 {
     5 
     6   PRINTF("Received RS from ");
     7   PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
     8   PRINTF(" to ");
     9   PRINT6ADDR(&UIP_IP_BUF->destipaddr);
    10   PRINTF("
    ");
    11   UIP_STAT(++uip_stat.nd6.recv);
    12 
    13 
    14 #if UIP_CONF_IPV6_CHECKS
    15   /*
    16    * Check hop limit / icmp code
    17    * target address must not be multicast
    18    * if the NA is solicited, dest must not be multicast
    19    */
    20   if((UIP_IP_BUF->ttl != UIP_ND6_HOP_LIMIT) || (UIP_ICMP_BUF->icode != 0)) {
    21     PRINTF("RS received is bad
    ");
    22     goto discard;
    23   }
    24 #endif /*UIP_CONF_IPV6_CHECKS */
    25 
    26   /* Only valid option is Source Link-Layer Address option any thing
    27      else is discarded */
    28   nd6_opt_offset = UIP_ND6_RS_LEN;
    29   nd6_opt_llao = NULL;
    30 
    31   while(uip_l3_icmp_hdr_len + nd6_opt_offset < uip_len) {
    32 #if UIP_CONF_IPV6_CHECKS
    33     if(UIP_ND6_OPT_HDR_BUF->len == 0) {
    34       PRINTF("RS received is bad
    ");
    35       goto discard;
    36     }
    37 #endif /*UIP_CONF_IPV6_CHECKS */
    38     switch (UIP_ND6_OPT_HDR_BUF->type) {
    39     case UIP_ND6_OPT_SLLAO:
    40       nd6_opt_llao = (uint8_t *)UIP_ND6_OPT_HDR_BUF;
    41       break;
    42     default:
    43       PRINTF("ND option not supported in RS
    ");
    44       break;
    45     }
    46     nd6_opt_offset += (UIP_ND6_OPT_HDR_BUF->len << 3);
    47   }
    48   /* Options processing: only SLLAO */
    49   if(nd6_opt_llao != NULL) {
    50 #if UIP_CONF_IPV6_CHECKS
    51     if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) {
    52       PRINTF("RS received is bad
    ");
    53       goto discard;
    54     } else {
    55 #endif /*UIP_CONF_IPV6_CHECKS */
    56       uip_lladdr_t lladdr_aligned;
    57       extract_lladdr_from_llao_aligned(&lladdr_aligned);
    58       if((nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr)) == NULL) {
    59         /* we need to add the neighbor */
    60         uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned,
    61                         0, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL);
    62       } else {
    63         /* If LL address changed, set neighbor state to stale */
    64         const uip_lladdr_t *lladdr = uip_ds6_nbr_get_ll(nbr);
    65         if(lladdr == NULL) {
    66           goto discard;
    67         }
    68         if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
    69             lladdr, UIP_LLADDR_LEN) != 0) {
    70           uip_ds6_nbr_t nbr_data;
    71           nbr_data = *nbr;
    72           uip_ds6_nbr_rm(nbr);
    73           nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned,
    74                                 0, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL);
    75           nbr->reachable = nbr_data.reachable;
    76           nbr->sendns = nbr_data.sendns;
    77           nbr->nscount = nbr_data.nscount;
    78         }
    79         nbr->isrouter = 0;
    80       }
    81 #if UIP_CONF_IPV6_CHECKS
    82     }
    83 #endif /*UIP_CONF_IPV6_CHECKS */
    84   }
    85 
    86   /* Schedule a sollicited RA */
    87   uip_ds6_send_ra_sollicited();
    88 
    89 discard:
    90   uip_clear_buf();
    91   return;
    92 }
      1 /*---------------------------------------------------------------------------*/
      2 void
      3 uip_nd6_ra_output(uip_ipaddr_t * dest)
      4 {
      5 
      6   UIP_IP_BUF->vtc = 0x60;
      7   UIP_IP_BUF->tcflow = 0;
      8   UIP_IP_BUF->flow = 0;
      9   UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
     10   UIP_IP_BUF->ttl = UIP_ND6_HOP_LIMIT;
     11 
     12   if(dest == NULL) {
     13     uip_create_linklocal_allnodes_mcast(&UIP_IP_BUF->destipaddr);
     14   } else {
     15     /* For sollicited RA */
     16     uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, dest);
     17   }
     18   uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr);
     19 
     20   UIP_ICMP_BUF->type = ICMP6_RA;
     21   UIP_ICMP_BUF->icode = 0;
     22 
     23   UIP_ND6_RA_BUF->cur_ttl = uip_ds6_if.cur_hop_limit;
     24 
     25   UIP_ND6_RA_BUF->flags_reserved =
     26     (UIP_ND6_M_FLAG << 7) | (UIP_ND6_O_FLAG << 6);
     27 
     28   UIP_ND6_RA_BUF->router_lifetime = uip_htons(UIP_ND6_ROUTER_LIFETIME);
     29   //UIP_ND6_RA_BUF->reachable_time = uip_htonl(uip_ds6_if.reachable_time);
     30   //UIP_ND6_RA_BUF->retrans_timer = uip_htonl(uip_ds6_if.retrans_timer);
     31   UIP_ND6_RA_BUF->reachable_time = 0;
     32   UIP_ND6_RA_BUF->retrans_timer = 0;
     33 
     34   uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_RA_LEN;
     35   nd6_opt_offset = UIP_ND6_RA_LEN;
     36 
     37 
     38   /* Prefix list */
     39   for(prefix = uip_ds6_prefix_list;
     40       prefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; prefix++) {
     41     if((prefix->isused) && (prefix->advertise)) {
     42       UIP_ND6_OPT_PREFIX_BUF->type = UIP_ND6_OPT_PREFIX_INFO;
     43       UIP_ND6_OPT_PREFIX_BUF->len = UIP_ND6_OPT_PREFIX_INFO_LEN / 8;
     44       UIP_ND6_OPT_PREFIX_BUF->preflen = prefix->length;
     45       UIP_ND6_OPT_PREFIX_BUF->flagsreserved1 = prefix->l_a_reserved;
     46       UIP_ND6_OPT_PREFIX_BUF->validlt = uip_htonl(prefix->vlifetime);
     47       UIP_ND6_OPT_PREFIX_BUF->preferredlt = uip_htonl(prefix->plifetime);
     48       UIP_ND6_OPT_PREFIX_BUF->reserved2 = 0;
     49       uip_ipaddr_copy(&(UIP_ND6_OPT_PREFIX_BUF->prefix), &(prefix->ipaddr));
     50       nd6_opt_offset += UIP_ND6_OPT_PREFIX_INFO_LEN;
     51       uip_len += UIP_ND6_OPT_PREFIX_INFO_LEN;
     52     }
     53   }
     54 
     55   /* Source link-layer option */
     56   create_llao((uint8_t *)UIP_ND6_OPT_HDR_BUF, UIP_ND6_OPT_SLLAO);
     57 
     58   uip_len += UIP_ND6_OPT_LLAO_LEN;
     59   nd6_opt_offset += UIP_ND6_OPT_LLAO_LEN;
     60 
     61   /* MTU */
     62   UIP_ND6_OPT_MTU_BUF->type = UIP_ND6_OPT_MTU;
     63   UIP_ND6_OPT_MTU_BUF->len = UIP_ND6_OPT_MTU_LEN >> 3;
     64   UIP_ND6_OPT_MTU_BUF->reserved = 0;
     65   //UIP_ND6_OPT_MTU_BUF->mtu = uip_htonl(uip_ds6_if.link_mtu);
     66   UIP_ND6_OPT_MTU_BUF->mtu = uip_htonl(1500);
     67 
     68   uip_len += UIP_ND6_OPT_MTU_LEN;
     69   nd6_opt_offset += UIP_ND6_OPT_MTU_LEN;
     70 
     71 #if UIP_ND6_RA_RDNSS
     72   if(uip_nameserver_count() > 0) {
     73     uint8_t i = 0;
     74     uip_ipaddr_t *ip = &UIP_ND6_OPT_RDNSS_BUF->ip;
     75     uip_ipaddr_t *dns = NULL;
     76     UIP_ND6_OPT_RDNSS_BUF->type = UIP_ND6_OPT_RDNSS;
     77     UIP_ND6_OPT_RDNSS_BUF->reserved = 0;
     78     UIP_ND6_OPT_RDNSS_BUF->lifetime = uip_nameserver_next_expiration();
     79     if(UIP_ND6_OPT_RDNSS_BUF->lifetime != UIP_NAMESERVER_INFINITE_LIFETIME) {
     80       UIP_ND6_OPT_RDNSS_BUF->lifetime -= clock_seconds();
     81     }
     82     while((dns = uip_nameserver_get(i)) != NULL) {
     83       uip_ipaddr_copy(ip++, dns);
     84       i++;
     85     }
     86     UIP_ND6_OPT_RDNSS_BUF->len = UIP_ND6_OPT_RDNSS_LEN + (i << 1);
     87     PRINTF("%d nameservers reported
    ", i);
     88     uip_len += UIP_ND6_OPT_RDNSS_BUF->len << 3;
     89     nd6_opt_offset += UIP_ND6_OPT_RDNSS_BUF->len << 3;
     90   }
     91 #endif /* UIP_ND6_RA_RDNSS */
     92 
     93   UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8);
     94   UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff);
     95 
     96   /*ICMP checksum */
     97   UIP_ICMP_BUF->icmpchksum = 0;
     98   UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum();
     99 
    100   UIP_STAT(++uip_stat.nd6.sent);
    101   PRINTF("Sending RA to ");
    102   PRINT6ADDR(&UIP_IP_BUF->destipaddr);
    103   PRINTF(" from ");
    104   PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
    105   PRINTF("
    ");
    106   return;
    107 }

    在linux和freebsd中每怎么找到发送ra的部分。

  • 相关阅读:
    Hello world
    Kubernetes容器云平台建设实践
    工作方法决定自己的发展
    Excel中对身份证号的处理
    详解慢查询日志的相关设置及mysqldumpslow工具
    安全测试工具简介
    Redis使用
    linux centos 查看防火墙firewalld、iptables状态
    悄悄地存在这里,因为里面的一句话
    GAE Python 2009322
  • 原文地址:https://www.cnblogs.com/yanhc/p/8542849.html
Copyright © 2011-2022 走看看