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的部分。

  • 相关阅读:
    UVA12125 March of the Penguins (最大流+拆点)
    UVA 1317 Concert Hall Scheduling(最小费用最大流)
    UVA10249 The Grand Dinner(最大流)
    UVA1349 Optimal Bus Route Design(KM最佳完美匹配)
    UVA1212 Duopoly(最大流最小割)
    UVA1395 Slim Span(kruskal)
    UVA1045 The Great Wall Game(二分图最佳匹配)
    UVA12168 Cat vs. Dog( 二分图最大独立集)
    hdu3488Tour(KM最佳完美匹配)
    UVA1345 Jamie's Contact Groups(最大流+二分)
  • 原文地址:https://www.cnblogs.com/yanhc/p/8542849.html
Copyright © 2011-2022 走看看