转载地址: http://blog.chinaunix.net/uid-23247944-id-2973884.html
UIP协议多用于嵌入式产品。
结合如CP2200芯片的网卡芯片,组成嵌入式网卡,硬件提供能力,UIP提供的是策略。
由上往下逐步封装用户的数据,如:
应用层----------传输层--------网络层------数据链路层-----物理层
应用数据---TCP封装头部---IP封装头部-----mac封装+尾部-----发送
任何的事物需要经过一定的初始阶段,在UIP协议里面通过uip_init()来初始化。
在uip_init()函数里面主要工作是:
1. 将uip_state结构体全部清零。
2. 初始化用于TCP链接的uip_conn结构体,将连接状态置为close。
3. 设置用于TCP链接的端口lastport = 4096;应该是最大的端口号,待查证。
4. 如果定义了UDP,同样进行初始化。
- void uip_init(void) {
- // clean statistics
- char* ptr= (char*) &uip_stat;
- for (int i = 0; i<sizeof (uip_stat); i++) {
- ptr[i] = 0;
- }
- for (c = 0; c < UIP_LISTENPORTS; ++c) {
- uip_listenports[c] = 0;
- }
- for (c = 0; c < UIP_CONNS; ++c) {
- uip_conns[c].tcpstateflags = UIP_CLOSED;
- }
- lastport = 4096;
- #if UIP_UDP
- for (c = 0; c < UIP_UDP_CONNS; ++c) {
- uip_udp_conns[c].lport = 0;
- }
- #endif /* UIP_UDP */
- /* IPv4 initialization. */
- #if UIP_FIXEDADDR == 0
- /* uip_hostaddr[0] = uip_hostaddr[1] = 0;*/
- #endif /* UIP_FIXEDADDR */
- }
同样,我在ourdev.cn上下载了,一份总结,一点一点上传,感谢ourdev.cn。
uip_arp_init(); arp协议的初始化,其中进行的是构造arp协议的缓存。
在配置UIP协议的时候要主要配置超时。
// 摘自uip协议包main.c
- struct timer periodic_timer, arp_timer;
- timer_set(&periodic_timer, CLOCK_SECOND / 2);
- timer_set(&arp_timer, CLOCK_SECOND * 10);
还要进行的配置是,比如配置主机地址,ip地址,还有掩码,以太网mac地址等信息,或者配置dhcp。
这些配置完成之后,进入协议的主循环,接受,和发送等等的过程了。
要应用到实际的使用中,还需要结合硬件,比如CP2200芯片,使用过程中,需要有接收,和发送函
数,这个需要自己实现,循环的流程如下:
- while(1)
- {
- uip_len = tapdev_read(); // 接收的函数
- if(uip_len > 0)
- {
- if(BUF->type == htons(UIP_ETHTYPE_IP))
- {
- uip_arp_ipin();
- uip_input(); // 这个是实际的从上往下封装包的函数
- /* If the above function invocation resulted in data that
- should be sent out on the network, the global variable
- uip_len is set to a value > 0. */
- if(uip_len > 0)
- {
- uip_arp_out();
- tapdev_send(); // 发送的实际函数
- }
- }
- else if(BUF->type == htons(UIP_ETHTYPE_ARP))
- {
- uip_arp_arpin();
- /* If the above function invocation resulted in data that
- should be sent out on the network, the global variable
- uip_len is set to a value > 0. */
- if(uip_len > 0)
- {
- tapdev_send();
- }
- }
- }
- else if(timer_expired(&periodic_timer))
- {
- timer_reset(&periodic_timer);
- for(i = 0; i < UIP_CONNS; i++)
- {
- uip_periodic(i);
- /* If the above function invocation resulted in data that
- should be sent out on the network, the global variable
- uip_len is set to a value > 0. */
- if(uip_len > 0)
- {
- uip_arp_out();
- tapdev_send();
- }
- }
- #if UIP_UDP
- for(i = 0; i < UIP_UDP_CONNS; i++)
- {
- uip_udp_periodic(i);
- /* If the above function invocation resulted in data that
- should be sent out on the network, the global variable
- uip_len is set to a value > 0. */
- if(uip_len > 0)
- {
- uip_arp_out();
- tapdev_send();
- }
- }
- #endif /* UIP_UDP */
- /* Call the ARP timer function every 10 seconds. */
- if(timer_expired(&arp_timer))
- {
- timer_reset(&arp_timer);
- uip_arp_timer();
- }
- }
- }
在主循环里面,还有好多需要分析的,特别是uip_input(),各种跳转... UIP.zip (从ourdev.cn下载的一点资料,感谢ourdev.cn)