当前位置: 首页 >> 程序设计 >> 巧用pcap 在linux下开发嵌入式网络协议栈
 

巧用pcap 在linux下开发嵌入式网络协议栈

作者:      来源:http://blog.csdn.net/lm_tom     发表时间:2006-12-31     浏览次数:      字号:    

巧用pcap 在linux下开发嵌入式网络协议栈
           lm_tom@163.com

       转载时请注明出处:http://blog.csdn.net/lm_tom


1,引言
   相对pc软件的开发,嵌入式软件的开发可供使用的调试资源非常有限.
嵌入式系统差异很大,有的嵌入式处理器是32bit,有的可能是8bit,16bit;
有的可以运行操作系统,比如(linux,ucos...),有的由于资源所限以及应用
实际,没有必要或者说无法运行操作系统;大多嵌入式系统只有有限的调试设备,
比如仿真器,串口输出等,有的甚至只有仿真器。
  网络协议(比如tcpip)以及基于其的一些应用有一定复杂性,一般需要一定
的调试手段才能保证正常的开发。但网络协议还有一个特点就是,和硬件无关
(当然,字节序问题可以通过宏的方式解决)。那么自然而然,我们可以想到在
调试资源丰富的pc环境下将协议栈调试通过,然后再移植到嵌入式系统上去。无疑
可以大大降低开发难度,缩短开发周期(你可以在没有拿到任何硬件单板时候就
可以动工了,呵呵)。
   笔者在pc-linux下调试通过了uip[2]/lwip[3]等tcpip协议栈,实现了dhcp/dns/http
等应用,同时很方便的将在pc-linux下调试通过的uip在z80(8-bit)上跑通(大概
只用了半天时间)。

2,思路
  tcpip协议栈主要依靠数据(来自网络接口)和定时器来驱动。定时器在pc-linux
下很容易模拟,但如何模拟网络数据呢?需要从文件读取和写入吗?这是一个办法,
但就是太不方便。 这时候想到了tcpdump软件,该软件可以抓到连接到hub上所有机
器的以太网packet,那么自然想到了可以通过该软件模拟一个虚拟网口,通过该网口
可以向网络上任何机器发送packet,同时可以接收属于自己的packet)。这个网口有
自己的mac地址。
  tcpdump基于pcap库[1]实现,hub也很容易满足(50RMB就可以买到一个4-port的,
呵呵).

3,使用pcap模拟以太网虚拟网口
3.1 虚拟网口初始化

1) 主要是初始化pcap,参考如下代码:

     dev = "eth0";
  /* Find the properties for the device */
    if (pcap_lookupnet(dev, &net, &mask, errbuf) == -1) {
        fprintf(stderr, "Couldn't get netmask for device %s: %s\n", dev, errbuf);
        net = 0;
        mask = 0;
    }
    /* Open the session in promiscuous mode */
    handle = pcap_open_live(dev, 65500, 1, 1, errbuf);
    if (handle == NULL) {
        fprintf(stderr, "Couldn't open device %s: %s\n", dev, errbuf);
        return(2);
    }
    /* Compile and apply the filter */
    if (pcap_compile(handle, &fp, filter_exp, 0, net) == -1) {
        fprintf(stderr, "Couldn't parse filter %s: %s\n", filter_exp, pcap_geterr(handle));
        return(2);
    }
    if (pcap_setfilter(handle, &fp) == -1) {
        fprintf(stderr, "Couldn't install filter %s: %s\n", filter_exp, pcap_geterr(handle));
        return(2);
    }

2)如何设置filter_exp  
   sprintf(filter_exp,"ether dst %2x:%2x:%2x:%2x:%2x:%2x or ether dst ff:ff:ff:ff:ff:ff",
          mac[0],mac[1],mac[2],mac[3],mac[4],mac[5]);

   mac[6]代表虚拟网口的mac地址,由于pc通过hub接入以太网络,可以抓包mac[]对应的包。

3.2 如何读取ethernet frame
    res = pcap_next_ex(handle, &header, &packet);
    if (res != 1)
    {
        readSize = 0;
        goto exit;
    }
    readSize = (int)header->len >= 1514 ? 1514 : (int)header->len;

    packet地址保存了收到包的内容,readSize保存了收到包的长度。


3.3 如何发送ethernet frame

  ret = pcap_sendpacket(handle, buf, buf_len);

  即可将buf,buf_len对应的数据包发送出去。


  即可将buf,buf_len对应的数据包发送出去。  即可将buf,buf_len对应的数据包发送出去。  即可将buf,buf_len对应的数据包发送出去。


3.4 一些说明
  以上部分模拟了一个虚拟网口的驱动,完成了调试协议栈所需的数据驱动条件。
利用上面的驱动,笔者成功调试通过了基于uip/lwip的arp/icmp/dhcp/dns/tcp/udp
协议等。支持动态设置ip/network mask/gateway等,可以接收和发送广播包等。
理论上通过设置合适的filter expresion,也可以支持组波协议的调试。可以直接和
外部网络通信,是一个网络世界标准的citizen.
 

  另外,从目前来看,不足之处主要是:无法动态设置单板mac地址,但这应该不会
影响到调试。

4,结束语
  本文给出了一种在pc-linux下调试用于嵌入式设备的网络协议栈的方法,该方法容易实现,
可以大大降低了开发调试难度和缩短了开发时间。非常值得大家一试。
 
5,参考文献
[1],http://www.tcpdump.org/
[2],http://www.sics.se/~adam/uip/
[3],http://www.sics.se/~adam/lwip/

责任编辑 webmaster

 
 
 
 
 
评论更多>>
 
 
 
发表
 
姓名: QQ:
性别: MSN:
E-mail: 主页:
评分: 1 2 3 4 5
评论内容:
验证码:
  
  • 请遵守《互联网电子公告服务管理规定》及中华人民共和国其他各项有关法律法规。
  • 严禁发表危害国家安全、损害国家利益、破坏民族团结、破坏国家宗教政策、破坏社会稳定、侮辱、诽谤、教唆、淫秽等内容的评论 。
  • 用户需对自己在使用本站服务过程中的行为承担法律责任(直接或间接导致的)。
  • 本站管理员有权保留或删除评论内容。
  • 评论内容只代表网友个人观点,与本网站立场无关。
  •