关键字:uIP Cygwin WinPcap
1.建立调试环境
首先下载Cygwin开发包、 WinPcap工具包、uIP源码包。安装Cygwin和WinPcap,使用默认安装配置即可。然后将从我们网站下载的uIP源码包解压至硬盘,其中已经包括了最新的uIP源码和WinPcap开发SDK库。
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 谢谢