結合如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 */
-
- }
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);
這些配置完成之後,進入協議的主循環,接受,和發送等等的過程了。
要應用到實際的使用中,還需要結合硬件,比如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();
-
}
-
}
- }