码迷,mamicode.com
首页 > 其他好文 > 详细

lwip之一:minimal

时间:2016-05-11 19:36:25      阅读:326      评论:0      收藏:0      [点我收藏+]

标签:

会比较杂乱吧,随心所欲的写。

先从lwip开始。Minimal是无os的。
一、Minimal

lwip-contrib/ports/unix/proj/minimalecho srv

采用tap0接口,在README中有说明。

技术分享 

技术分享 

 

运行echop, ip.srv == 102 / ip.cli == 108

技术分享 

在程序中修改*.18---->*.108了。

技术分享 

low_level_init()

{

  snprintf(buf, sizeof(buf), "/sbin/ifconfig " IFCONFIG_ARGS,

           ip4_addr1(&(netif->gw)),

           ip4_addr2(&(netif->gw)),

           ip4_addr3(&(netif->gw)),

           ip4_addr4(&(netif->gw))+107); /*zlz add +107*/

}

分析,主要关注netif(本例为tap)的适配。

技术分享 

int main(int argc, char **argv)

{

  /* startup defaults (may be overridden by one or more opts) */

  IP4_ADDR(&gw, 192,168,0,1);

  IP4_ADDR(&ipaddr, 192,168,0,102);

  IP4_ADDR(&netmask, 255,255,255,0);

  netif_add(&netif, &ipaddr, &netmask, &gw, NULL, mintapif_init, ethernet_input);

}

struct netif

{

netif_input_fn input; //netif fetch a pack

netif_output_fn output; //ip put a pack pack 2 netif,call linkoutput

netif_linkoutput_fn linkoutput; //called by output

}

//netif_add执行了netif_init_fn()--->mintapif_init()

netif_add(&netif, &ipaddr, &netmask, &gw, NULL, mintapif_init, ethernet_input);

{

netif->input = input;


     if (init(netif) != ERR_OK) 
{

return NULL;

}

}

//tap0 init

mintapif_init(struct netif *netif)

{

  netif->hwaddr_len = 6;

  netif->name[0] = IFNAME0;

  netif->name[1] = IFNAME1;

  netif->output = etharp_output;

  netif->linkoutput = low_level_output;

  netif->mtu = 1500;

  mintapif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]);

  

  low_level_init(netif);

 

  return ERR_OK;

}

low_level_init(struct netif *netif) //可以看作是具体网卡的initinit后就可以供其他cb使用了。

{

  mintapif = (struct mintapif *)netif->state;

  mintapif->fd = open(DEVTAP, O_RDWR);

}

low_level_output(struct netif *netif, struct pbuf *p) //wr--->send

{

  mintapif = (struct mintapif *)netif->state;

  /* signal that packet should be sent(); */

  written = write(mintapif->fd, buf, p->tot_len);

}

low_level_input(struct netif *netif) //rd--->recv

{

  mintapif = (struct mintapif *)netif->state;

  /* Obtain the size of the packet and put it into the "len" variable. */

  len = read(mintapif->fd, buf, sizeof(buf));

}

low_level_input/low_level_output就是具体的netifrecv/send

现在来总结下,哪些是需要根据具体netif来重写的(红色),哪些是lwip的框架。

netif_add(&netif, &ipaddr, &netmask, &gw, NULL, mintapif_init, ethernet_input);

Ø 需要重写

mintapif_init()

low_level_output netif_linkoutput_fn  linkoutput

low_level_input  见下面mintapif_input

Ø lwip框架

ethernet_input()

ethernet_input(struct pbuf *p, struct netif *netif) 是在netif init后才调用的,需要netif具体化。

etharp_output ,不要被“arp”误导。output最终calllinkoutput,这2output可以看做是一个。

etharp_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr)

{

  return etharp_send_ip(netif, q, (struct eth_addr*)(netif->hwaddr), dest);

}

etharp_send_ip(struct netif *netif, struct pbuf *p, struct eth_addr *src, const struct eth_addr *dst)

{

  /* send the packet */

  return netif->linkoutput(netif, p);

}

 

Ø Input flow

int

main(int argc, char **argv)

{

技术分享 

}

 

技术分享 

 

技术分享技术分享技术分享 

Ø Output flow

echo_send

{

  wr_err = tcp_write(tpcb, ptr->payload, ptr->len, 1);

}

1.4.x版本中,tcp_write只是准备好segmenttcpip_tcp_timer周期性(TCP_TMR_INTERVAL)调用tcp_tmr(){-->tcp_output},最终调用netif->output(本例为low_level_output)

若无必要,不用tcp_write后就紧接着tcp_output,有可能打乱tcp的节奏。建议交给lwip自行处理(tcp_write就好了,参考echo.c)

 

下图是从LwIP协议深度剖析与实战演练(朱升林著,应该和老衲五木是同一个人)中截取的。

技术分享 

 

自己技术分享的图

技术分享 

技术分享 

 





lwip之一:minimal

标签:

原文地址:http://www.cnblogs.com/freezlz/p/5483067.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!