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间隔没限制

 /*---------------------------------------------------------------------------*/
void
uip_ds6_send_ra_periodic(void)
{
if(racount > ) {
/* send previously scheduled RA */
uip_nd6_ra_output(NULL);
PRINTF("Sending periodic RA\n");
}
  /* rand_t = min + rand % (max - min) */
rand_time = UIP_ND6_MIN_RA_INTERVAL + random_rand() %
(uint16_t) (UIP_ND6_MAX_RA_INTERVAL - UIP_ND6_MIN_RA_INTERVAL);
PRINTF("Random time 1 = %u\n", rand_time);
  /* intial ra interval = 16s, initial 3 ra, should not exceed initial_ra_interval */
if(racount < UIP_ND6_MAX_INITIAL_RAS) {
if(rand_time > UIP_ND6_MAX_INITIAL_RA_INTERVAL) {
rand_time = UIP_ND6_MAX_INITIAL_RA_INTERVAL;
PRINTF("Random time 2 = %u\n", rand_time);
}
racount++;
}
PRINTF("Random time 3 = %u\n", rand_time);
stimer_set(&uip_ds6_timer_ra, rand_time);
}

如果收到了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 = ;
PRINTF("Solicited RA, random time %u\n", 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在这个文件中定义

 /*---------------------------------------------------------------------------*/
static void
rs_input(void)
{ PRINTF("Received RS from ");
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
PRINTF(" to ");
PRINT6ADDR(&UIP_IP_BUF->destipaddr);
PRINTF("\n");
UIP_STAT(++uip_stat.nd6.recv); #if UIP_CONF_IPV6_CHECKS
/*
* Check hop limit / icmp code
* target address must not be multicast
* if the NA is solicited, dest must not be multicast
*/
if((UIP_IP_BUF->ttl != UIP_ND6_HOP_LIMIT) || (UIP_ICMP_BUF->icode != )) {
PRINTF("RS received is bad\n");
goto discard;
}
#endif /*UIP_CONF_IPV6_CHECKS */ /* Only valid option is Source Link-Layer Address option any thing
else is discarded */
nd6_opt_offset = UIP_ND6_RS_LEN;
nd6_opt_llao = NULL; while(uip_l3_icmp_hdr_len + nd6_opt_offset < uip_len) {
#if UIP_CONF_IPV6_CHECKS
if(UIP_ND6_OPT_HDR_BUF->len == ) {
PRINTF("RS received is bad\n");
goto discard;
}
#endif /*UIP_CONF_IPV6_CHECKS */
switch (UIP_ND6_OPT_HDR_BUF->type) {
case UIP_ND6_OPT_SLLAO:
nd6_opt_llao = (uint8_t *)UIP_ND6_OPT_HDR_BUF;
break;
default:
PRINTF("ND option not supported in RS\n");
break;
}
nd6_opt_offset += (UIP_ND6_OPT_HDR_BUF->len << );
}
/* Options processing: only SLLAO */
if(nd6_opt_llao != NULL) {
#if UIP_CONF_IPV6_CHECKS
if(uip_is_addr_unspecified(&UIP_IP_BUF->srcipaddr)) {
PRINTF("RS received is bad\n");
goto discard;
} else {
#endif /*UIP_CONF_IPV6_CHECKS */
uip_lladdr_t lladdr_aligned;
extract_lladdr_from_llao_aligned(&lladdr_aligned);
if((nbr = uip_ds6_nbr_lookup(&UIP_IP_BUF->srcipaddr)) == NULL) {
/* we need to add the neighbor */
uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned,
, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL);
} else {
/* If LL address changed, set neighbor state to stale */
const uip_lladdr_t *lladdr = uip_ds6_nbr_get_ll(nbr);
if(lladdr == NULL) {
goto discard;
}
if(memcmp(&nd6_opt_llao[UIP_ND6_OPT_DATA_OFFSET],
lladdr, UIP_LLADDR_LEN) != ) {
uip_ds6_nbr_t nbr_data;
nbr_data = *nbr;
uip_ds6_nbr_rm(nbr);
nbr = uip_ds6_nbr_add(&UIP_IP_BUF->srcipaddr, &lladdr_aligned,
, NBR_STALE, NBR_TABLE_REASON_IPV6_ND, NULL);
nbr->reachable = nbr_data.reachable;
nbr->sendns = nbr_data.sendns;
nbr->nscount = nbr_data.nscount;
}
nbr->isrouter = ;
}
#if UIP_CONF_IPV6_CHECKS
}
#endif /*UIP_CONF_IPV6_CHECKS */
} /* Schedule a sollicited RA */
uip_ds6_send_ra_sollicited(); discard:
uip_clear_buf();
return;
}
 /*---------------------------------------------------------------------------*/
void
uip_nd6_ra_output(uip_ipaddr_t * dest)
{ UIP_IP_BUF->vtc = 0x60;
UIP_IP_BUF->tcflow = ;
UIP_IP_BUF->flow = ;
UIP_IP_BUF->proto = UIP_PROTO_ICMP6;
UIP_IP_BUF->ttl = UIP_ND6_HOP_LIMIT; if(dest == NULL) {
uip_create_linklocal_allnodes_mcast(&UIP_IP_BUF->destipaddr);
} else {
/* For sollicited RA */
uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, dest);
}
uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); UIP_ICMP_BUF->type = ICMP6_RA;
UIP_ICMP_BUF->icode = ; UIP_ND6_RA_BUF->cur_ttl = uip_ds6_if.cur_hop_limit; UIP_ND6_RA_BUF->flags_reserved =
(UIP_ND6_M_FLAG << ) | (UIP_ND6_O_FLAG << ); UIP_ND6_RA_BUF->router_lifetime = uip_htons(UIP_ND6_ROUTER_LIFETIME);
//UIP_ND6_RA_BUF->reachable_time = uip_htonl(uip_ds6_if.reachable_time);
//UIP_ND6_RA_BUF->retrans_timer = uip_htonl(uip_ds6_if.retrans_timer);
UIP_ND6_RA_BUF->reachable_time = ;
UIP_ND6_RA_BUF->retrans_timer = ; uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_RA_LEN;
nd6_opt_offset = UIP_ND6_RA_LEN; /* Prefix list */
for(prefix = uip_ds6_prefix_list;
prefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; prefix++) {
if((prefix->isused) && (prefix->advertise)) {
UIP_ND6_OPT_PREFIX_BUF->type = UIP_ND6_OPT_PREFIX_INFO;
UIP_ND6_OPT_PREFIX_BUF->len = UIP_ND6_OPT_PREFIX_INFO_LEN / ;
UIP_ND6_OPT_PREFIX_BUF->preflen = prefix->length;
UIP_ND6_OPT_PREFIX_BUF->flagsreserved1 = prefix->l_a_reserved;
UIP_ND6_OPT_PREFIX_BUF->validlt = uip_htonl(prefix->vlifetime);
UIP_ND6_OPT_PREFIX_BUF->preferredlt = uip_htonl(prefix->plifetime);
UIP_ND6_OPT_PREFIX_BUF->reserved2 = ;
uip_ipaddr_copy(&(UIP_ND6_OPT_PREFIX_BUF->prefix), &(prefix->ipaddr));
nd6_opt_offset += UIP_ND6_OPT_PREFIX_INFO_LEN;
uip_len += UIP_ND6_OPT_PREFIX_INFO_LEN;
}
} /* Source link-layer option */
create_llao((uint8_t *)UIP_ND6_OPT_HDR_BUF, UIP_ND6_OPT_SLLAO); uip_len += UIP_ND6_OPT_LLAO_LEN;
nd6_opt_offset += UIP_ND6_OPT_LLAO_LEN; /* MTU */
UIP_ND6_OPT_MTU_BUF->type = UIP_ND6_OPT_MTU;
UIP_ND6_OPT_MTU_BUF->len = UIP_ND6_OPT_MTU_LEN >> ;
UIP_ND6_OPT_MTU_BUF->reserved = ;
//UIP_ND6_OPT_MTU_BUF->mtu = uip_htonl(uip_ds6_if.link_mtu);
UIP_ND6_OPT_MTU_BUF->mtu = uip_htonl(); uip_len += UIP_ND6_OPT_MTU_LEN;
nd6_opt_offset += UIP_ND6_OPT_MTU_LEN; #if UIP_ND6_RA_RDNSS
if(uip_nameserver_count() > ) {
uint8_t i = ;
uip_ipaddr_t *ip = &UIP_ND6_OPT_RDNSS_BUF->ip;
uip_ipaddr_t *dns = NULL;
UIP_ND6_OPT_RDNSS_BUF->type = UIP_ND6_OPT_RDNSS;
UIP_ND6_OPT_RDNSS_BUF->reserved = ;
UIP_ND6_OPT_RDNSS_BUF->lifetime = uip_nameserver_next_expiration();
if(UIP_ND6_OPT_RDNSS_BUF->lifetime != UIP_NAMESERVER_INFINITE_LIFETIME) {
UIP_ND6_OPT_RDNSS_BUF->lifetime -= clock_seconds();
}
while((dns = uip_nameserver_get(i)) != NULL) {
uip_ipaddr_copy(ip++, dns);
i++;
}
UIP_ND6_OPT_RDNSS_BUF->len = UIP_ND6_OPT_RDNSS_LEN + (i << );
PRINTF("%d nameservers reported\n", i);
uip_len += UIP_ND6_OPT_RDNSS_BUF->len << ;
nd6_opt_offset += UIP_ND6_OPT_RDNSS_BUF->len << ;
}
#endif /* UIP_ND6_RA_RDNSS */ UIP_IP_BUF->len[] = ((uip_len - UIP_IPH_LEN) >> );
UIP_IP_BUF->len[] = ((uip_len - UIP_IPH_LEN) & 0xff); /*ICMP checksum */
UIP_ICMP_BUF->icmpchksum = ;
UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); UIP_STAT(++uip_stat.nd6.sent);
PRINTF("Sending RA to ");
PRINT6ADDR(&UIP_IP_BUF->destipaddr);
PRINTF(" from ");
PRINT6ADDR(&UIP_IP_BUF->srcipaddr);
PRINTF("\n");
return;
}

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

lwip nd没有实现ra,contik有参考的更多相关文章

  1. ETH—Lwip以太网通信

    第39章     ETH—Lwip以太网通信 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/ ...

  2. 第39章 ETH—Lwip以太网通信

    第39章     ETH—Lwip以太网通信 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/ ...

  3. 第39章 ETH—Lwip以太网通信—零死角玩转STM32-F429系列

    第39章     ETH—Lwip以太网通信 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com/ ...

  4. 【lwip】06-网络接口层分析

    目录 前言 6.1 概念引入 6.2 网络接口层数据概念流图 6.3 网卡收包程序流图 6.4 网卡数据结构 6.4.1 struct netif源码 6.4.2 字段分析 6.4.2.1 网卡链表 ...

  5. LWIP总结

    介绍 Lwip,light weight IP:是由Adam Dunkels 开发的一个小型开源的TCP/IP协议栈:目前已经为全球共同开发的开源协议:支持TCPIP协议族的核心协议:包括:ARP/I ...

  6. LwIP移植和使用

    LwIP移植和使用 本手册基于lwip-1.4.x编写,本人没有移植过1.4.0之前的版本,更早的版本或许有差别.如果看官发现问题欢迎联系<QQ: 937431539  email: 93743 ...

  7. No compiler is provided in this environment. Perhaps you are running on a JRE ra

    No compiler is provided in this environment. Perhaps you are running on a JRE ra,有需要的朋友可以参考下. 控制台输出的 ...

  8. rt—移植笔记2(Lwip)

    首先参考f107已经有的目录结构添加Lwip这一组,添加各种.c文件及.文件. 还有drive下边的很重要的eth.c 到此,工程编译通过.(刚开始,小编是一个一个 的比对...一个一个错误排查... ...

  9. 理解 OpenStack 高可用(HA) (4): Pacemaker 和 OpenStack Resource Agent (RA)

    本系列会分析OpenStack 的高可用性(HA)概念和解决方案: (1)OpenStack 高可用方案概述 (2)Neutron L3 Agent HA - VRRP (虚拟路由冗余协议) (3)N ...

随机推荐

  1. 使用zipwithindex 算子给dataframe增加自增列 row_number函数实现自增,udf函数实现自增

    DataFrame df = ...StructType schema = df.schema().add(DataTypes.createStructField("id", Da ...

  2. Nginx配置文件模板

    主配置文件nginx.conf user nginx; #设置nginx服务的系统使用用户 worker_processes 1; #工作进程数(和cpu核心数保持一致) error_log /var ...

  3. 【javaScript】加减乘除的精确计算

    在js中使用"+"."-"等符号进行运算会出现很大的误差,所以需要自己创建函数进行精确运算. //说明:javascript的加法结果会有误差,在两个浮点数相加 ...

  4. 关于Xen

    尝试了各种方法搭建xen,尝试过从xenserver入手,但似乎最近时间端不允许访问,感谢我的老师,叫我从kvm入手,暂时记下xen中种种的坑,以后有缘再战.欢迎交流

  5. cesium纽约3dtiles数据下载

    cesium示例有纽约的3dtiles数据,下载官方有下载链接,但是下载后为乱码. 因此研究了下,写了个爬虫解码下载,使用办法,安装Python直接运行即可,代码如下: #coding=utf-8 f ...

  6. LESS 用法入门

    本文旨在加深对 LESS 的理解和记忆,供自己开发时参考.相信对没有接触过 LESS 的程序员还是有用的,大佬绕路. 一. 安装和使用 LESS 1.1 安装 使用命令行安装 LESS npm ins ...

  7. ubuntu系统下安装pip3及第三方库的安装

    ubuntu系统下会自带python2.x和python3.x坏境,不需要我们去安装.并且ubuntu系统下还会自动帮助我们安装python2.x坏境下的pip安装工具, 但是没有python3.x坏 ...

  8. 找python爬虫小项目?github给你准备好了!

    前言 即使我们都是程序员,但我们也并非都会修电脑,都会做酷炫的ppt,都会优化系统卡顿.其实程序员也是分行业.分专业的,就像医生也分内外科.呼吸科.神经科神的. 作为非专业的python选手,或者非专 ...

  9. 闲谈一下,ES3、ES4、ES5、ES6 分别是什么

    上图按照时间顺序说明了JavaScript.JScript和ECMAScript的发展. 显示在网景工作的Brendan Eich临危受命,用十天时间设计出LiveScript的第一个版本.临时发布前 ...

  10. 详解python的装饰器decorator

    装饰器本质上是一个python函数,它可以让其它函数在不需要任何代码改动的情况下增加额外的功能. 装饰器的返回值也是一个函数对象.它经常用于有切面需求的场景,比如:插入日志,性能测试,事务处理,缓存, ...