Windows下uIP协议栈调试详解(使用winpcap)

来源:互联网 发布:望月峰太郎 末日知乎 编辑:程序博客网 时间:2024/05/21 01:46
      摘要:在进行以太网协议栈开发时,需要有方便的调试方法,如果在嵌入式平台上调试,非常麻烦,因而大家一般都在PC平台上进行调试,本文介绍了如何在Windows平台下调试uIP。

   关键字:uIP Cygwin WinPcap

下载源码

1.建立调试环境  

2.uIP设备驱动中使用WinPcap模拟底层设备

    接着,按照uIP文档中的要求,编写基于WinPcap的驱动程序。

       2.1 uIP网络设备驱动编写
 

       uIP网络设备驱动需要三个接口:

       初始化网络设备:
       void network_devide_init(void);
       读取数据:
       unsigned int network_device_read(void);
       发送数据:
       void network_device_send(void);     

       在Windows下调试uIP协议栈,我们需要提供uIP的网络设备驱动。

这里,我使用WinPcap来模拟以太网设备。

 

       2.2 使用WinPcap模拟网络设备

       将WinPcap的截取模式设置为混杂模式,我们就能够截获网卡上所流过的所有数据。

       WinPcap开发包提供了简单的接口让我们初始化、

       2.3 编写基于WinPcap模拟网络设备的uIP网络设备驱动

 

        pcap_t *adhandle;


        void
        network_device_init(void)
        {
            printf("/nNetWork Device Init...../n");
            printf("%s/n======================================================/n",pcap_lib_version());
            
            pcap_if_t *alldevs;
            pcap_if_t *d;
            int inum;
            int i=0;
            char errbuf[PCAP_ERRBUF_SIZE];
            
            
            /* Retrieve the device list on the local machine */
            if (pcap_findalldevs_ex("rpcap://", NULL, &alldevs, errbuf) == -1)
            {
                fprintf(stderr,"Error in pcap_findalldevs: %s/n", errbuf);
                exit(1);
            }
            
            /* Print the list */
            for(d=alldevs; d; d=d->next)
            {
                printf("%d. %s", ++i, d->name);
                if (d->description)
                    printf(" (%s)/n", d->description);
                else
                    printf(" (No description available)/n");
            }
            
            if(i==0)
            {
                printf("/nNo interfaces found! Make sure WinPcap is installed./n");
                return;
            }
            
            printf("Enter the interface number (1-%d):",i);
            scanf("%d", &inum);
            
            if(inum < 1 || inum > i)
            {
                printf("/nInterface number out of range./n");
                /* Free the device list */
                pcap_freealldevs(alldevs);
                return;
            }
            
            /* Jump to the selected adapter */
            for(d=alldevs, i=0; i< inum-1 ;d=d->next, i++);
            
            /* Open the device */
            if ( (adhandle= pcap_open(d->name,          // name of the device
                                      65536,            // portion of the packet to capture.
                                                        // 65536 guarantees that the whole packet will be captured on all the link layers
                                      1,//PCAP_OPENFLAG_PROMISCUOUS=1,    // promiscuous mode
                                      1000,             // read timeout
                                      NULL,             // authentication on the remote machine
                                      errbuf            // error buffer
                                      ) ) == NULL)
            {
                fprintf(stderr,"/nUnable to open the adapter. %s is not supported by WinPcap/n", d->name);
                /* Free the device list */
                pcap_freealldevs(alldevs);
                return;
            }
            
            printf("/nlistening on %s.../n", d->description);
            printf("/nStart Uip Loop.../n");
            
            /* At this point, we don't need any more the device list. Free it */
            pcap_freealldevs(alldevs);
        
        }


        unsigned int
        network_device_read(void)
        {
            /* Retrieve the packets */
            
            int res;
            
            char timestr[16];
            struct pcap_pkthdr *header;
            const u_char *pkt_data;
            struct tm *ltime;
            time_t local_tv_sec;
            
            res = pcap_next_ex( adhandle, &header, &pkt_data);

            if(res == -1){
                printf("Error reading the packets: %s/n", pcap_geterr(adhandle));
                return -1;
            }
            //写入uip_buf, (UIP_BUFSIZE)
            
            
            int i;
            for(i=0;i<UIP_BUFSIZE;i++)
            {
                uip_buf[i]=0;
            }//uip_buf清空   
            
            for(i=0;i<header->len;i++)
            {
                uip_buf[i]=pkt_data[i];
                if(i>UIP_BUFSIZE)
                    break;
            }      
            
          return header->len;//返回读入数据的长度uip_len
        }


        void
        network_device_send(void)
        {
            /* Send down the packet */
            if (pcap_sendpacket(adhandle, uip_buf, uip_len /* size */) != 0)
            {
                fprintf(stderr,"/nError sending the packet: %s/n", pcap_geterr(adhandle));
                return;
            }
            printf("/nDev Sending data => len:%d/n", uip_len);
            return;
        }
     

   

3.基于uIP协议栈的简单测试程序

       最后我们使用uIP协议写了一个简单的服务,响应80端口的请求,返回一个固定的网页

      这是uIP在Windows平台上运行时的截图:



        收到请求后的截图:

 

 


 

       客户端显示的网页:

 



 


 

下载源码

  转载请注明出处, by Eagle 谢谢

 

原创粉丝点击