﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-时光隧道-文章分类-Winpcap</title><link>http://www.cppblog.com/thinke365/category/11866.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 22 Sep 2009 11:52:22 GMT</lastBuildDate><pubDate>Tue, 22 Sep 2009 11:52:22 GMT</pubDate><ttl>60</ttl><item><title>winpcap关键接口</title><link>http://www.cppblog.com/thinke365/articles/96904.html</link><dc:creator>thinke365</dc:creator><author>thinke365</author><pubDate>Mon, 21 Sep 2009 18:26:00 GMT</pubDate><guid>http://www.cppblog.com/thinke365/articles/96904.html</guid><wfw:comment>http://www.cppblog.com/thinke365/comments/96904.html</wfw:comment><comments>http://www.cppblog.com/thinke365/articles/96904.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/thinke365/comments/commentRss/96904.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/thinke365/services/trackbacks/96904.html</trackback:ping><description><![CDATA[pcap_loop(adhandle, 0, packet_handler, NULL);<br>res = pcap_next_ex( adhandle, &amp;header, &amp;pkt_data)) &gt;= 0<br>
<img src ="http://www.cppblog.com/thinke365/aggbug/96904.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/thinke365/" target="_blank">thinke365</a> 2009-09-22 02:26 <a href="http://www.cppblog.com/thinke365/articles/96904.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>1_basic_dump例子</title><link>http://www.cppblog.com/thinke365/articles/96903.html</link><dc:creator>thinke365</dc:creator><author>thinke365</author><pubDate>Mon, 21 Sep 2009 17:59:00 GMT</pubDate><guid>http://www.cppblog.com/thinke365/articles/96903.html</guid><wfw:comment>http://www.cppblog.com/thinke365/comments/96903.html</wfw:comment><comments>http://www.cppblog.com/thinke365/articles/96903.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/thinke365/comments/commentRss/96903.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/thinke365/services/trackbacks/96903.html</trackback:ping><description><![CDATA[截获数据包并打印时间和数据包长度。<br>/* Callback function invoked by libpcap for every incoming packet */<br>// 定义回调函数，一定要符合接口，这个是麻烦的地方啊。。。<br>void packet_handler(u_char *param, const struct pcap_pkthdr *header, const u_char *pkt_data)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;struct tm *ltime;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;char timestr[16];<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;time_t local_tv_sec;<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;/* convert the timestamp to readable format */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;local_tv_sec = header-&gt;ts.tv_sec;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ltime=localtime(&amp;local_tv_sec);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// strftime是win32的API?或者Linux、Windows下都有这个函数？<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 把ltime里的时间，格式化后，输到字符数组中？<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;strftime( timestr, sizeof timestr, "%H:%M:%S", ltime);<br>&nbsp;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 前面是标准时间，后面是毫秒<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;printf("%s,%.6d len:%d\n", timestr, header-&gt;ts.tv_usec, header-&gt;len);<br>}<br><br><span style="COLOR: #0000ff">以下是windows定义的时间结构</span>：<br>struct tm {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int tm_sec;&nbsp;&nbsp;&nbsp;&nbsp; /* seconds after the minute - [0,59] */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int tm_min;&nbsp;&nbsp;&nbsp;&nbsp; /* minutes after the hour - [0,59] */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int tm_hour;&nbsp;&nbsp;&nbsp; /* hours since midnight - [0,23] */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int tm_mday;&nbsp;&nbsp;&nbsp; /* day of the month - [1,31] */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int tm_mon;&nbsp;&nbsp;&nbsp;&nbsp; /* months since January - [0,11] */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int tm_year;&nbsp;&nbsp;&nbsp; /* years since 1900 */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int tm_wday;&nbsp;&nbsp;&nbsp; /* days since Sunday - [0,6] */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int tm_yday;&nbsp;&nbsp;&nbsp; /* days since January 1 - [0,365] */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int tm_isdst;&nbsp;&nbsp; /* daylight savings time flag */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; };<br>
<img src ="http://www.cppblog.com/thinke365/aggbug/96903.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/thinke365/" target="_blank">thinke365</a> 2009-09-22 01:59 <a href="http://www.cppblog.com/thinke365/articles/96903.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>winpcap基本数据结构</title><link>http://www.cppblog.com/thinke365/articles/96878.html</link><dc:creator>thinke365</dc:creator><author>thinke365</author><pubDate>Mon, 21 Sep 2009 13:03:00 GMT</pubDate><guid>http://www.cppblog.com/thinke365/articles/96878.html</guid><wfw:comment>http://www.cppblog.com/thinke365/comments/96878.html</wfw:comment><comments>http://www.cppblog.com/thinke365/articles/96878.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/thinke365/comments/commentRss/96878.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/thinke365/services/trackbacks/96878.html</trackback:ping><description><![CDATA[<p>// 网络接口列表<br>struct pcap_if {<br>&nbsp;struct pcap_if *next;&nbsp; // 从这里可以看出是接口<span style="FONT-SIZE: 10pt; COLOR: #000080">链表。这是标准C的写法</span>。如果使用C++，可以只定义item，之后放到STL的list中就可以了。这种写法的效率应该更高些。但是使用标准C的库就够了，不需要C++库的支持，也不需要STL的支持，<span style="FONT-SIZE: 10pt; COLOR: #000080">可以适应大部分的系统和硬件</span>。使用了最少的语言特性，Simple and reliable，<span style="FONT-SIZE: 10pt; COLOR: #ff0000">除非对开发效率和移植能力有要求</span>，有时候C比C++更好些。<br>&nbsp;char *name;&nbsp;&nbsp;// 仅仅使用一个指针，而不是一个结构，这种做法不错的。 不是像C++放一个string，Java放一个String，虽然麻烦些，<span style="FONT-SIZE: 10pt; COLOR: #0000ff">但是小巧、紧凑<br></span>&nbsp;char *description;&nbsp;<br>&nbsp;struct pcap_addr *addresses;<br>&nbsp;bpf_u_int32 flags;&nbsp;/* PCAP_IF_ interface flags */<br>};<br><br>// 接口地址<br>struct pcap_addr {<br>&nbsp;<span style="COLOR: #0000ff">struct pcap_addr *next;</span>&nbsp;&nbsp; // 在winpcap中好像没有用到列表功能。但是这么设计，当需要用到地址列表功能时就比较方便。<br>&nbsp;struct sockaddr *addr;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;<span style="COLOR: #0000ff">sockaddr结构可以存放各种类型的地址</span>。从下面可以看出。 地址、网络掩码、广播地址和<span style="COLOR: #800080">P2P地址</span><br>&nbsp;struct sockaddr *netmask;<br>&nbsp;struct sockaddr *broadaddr;&nbsp;<br>&nbsp;struct sockaddr *dstaddr;&nbsp;<br>};<br><br>// 内核使用该结构来保存大部分的地址。以下定义是在windows系统头文件winsock2.h中找到的，<span style="COLOR: #0000ff">在Linux中应该也定义了同样名称的结构吧</span>。<br>struct sockaddr {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u_short sa_family;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// 地址类型<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; char&nbsp;&nbsp;&nbsp; sa_data[14];&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // <span style="COLOR: #ff0000">14字节的地址，这里为什么没有用 char*了? <br></span>};<br><br>typedef struct pcap pcap_t;<br>// <span style="COLOR: red">原来这是一个挺复杂的结构</span><br>struct pcap {<br>#ifdef WIN32<br>&nbsp;&nbsp;&nbsp;&nbsp; ADAPTER *adapter;<br>&nbsp;&nbsp;&nbsp;&nbsp; LPPACKET Packet;<br>&nbsp;&nbsp;&nbsp;&nbsp;int timeout;<br>&nbsp;&nbsp;&nbsp;&nbsp;int nonblock;<br>#else<br>&nbsp;&nbsp;&nbsp;&nbsp;int fd;<br>&nbsp;&nbsp;&nbsp;&nbsp;int selectable_fd;<br>&nbsp;&nbsp;&nbsp;&nbsp;int send_fd;<br>#endif /* WIN32 */<br>&nbsp;&nbsp;&nbsp;&nbsp;int snapshot;<br>&nbsp;&nbsp;&nbsp;&nbsp;int linktype;<br>&nbsp;&nbsp;&nbsp;&nbsp;int tzoff;&nbsp;&nbsp;/* timezone offset */<br>&nbsp;&nbsp;&nbsp;&nbsp;int offset;&nbsp;&nbsp;/* offset for proper alignment */</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;int break_loop;&nbsp;&nbsp;/* flag set to force break from packet-reading loop */</p>
<p>#ifdef PCAP_FDDIPAD<br>&nbsp;&nbsp;&nbsp;int fddipad;<br>#endif</p>
<p>#ifdef MSDOS<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int inter_packet_wait;&nbsp;&nbsp; /* offline: wait between packets */<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void (*wait_proc)(void); /*&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call proc while waiting */<br>#endif</p>
<p>&nbsp;struct pcap_sf sf;<br>&nbsp;struct pcap_md md;</p>
<p>// 读缓存<br>&nbsp;&nbsp;&nbsp; &nbsp;int bufsize;<br>&nbsp;&nbsp;&nbsp;&nbsp; u_char *buffer;<br>&nbsp;&nbsp;&nbsp;&nbsp; u_char *bp;<br>&nbsp;&nbsp;&nbsp;&nbsp; int cc;</p>
<p>&nbsp;/*<br>&nbsp; * Place holder for pcap_next().<br>&nbsp; */<br>&nbsp;&nbsp;&nbsp;&nbsp; u_char *pkt;</p>
<p><span style="COLOR: #800080"><strong>&nbsp;//&nbsp;只接受来自这个方向的包。如何做到， INOUT是怎么回事？一个端口的通信都是单向的? Socket端口通信? 和串口有什么关系，或者相似之处?/串口也可以理解为一个端口，也可以分配一个端口号啊。。。</strong></span><br>&nbsp;pcap_direction_t direction;</p>
<p>// <span style="COLOR: red">定义了一堆的函数指针，都可以模拟OO机制了，呵呵</span>。<br>// 不过是一种极简化的操作，在Linux内核代码中可以看到很多这样的代码<br>&nbsp;int&nbsp;(*read_op)(pcap_t *, int cnt, pcap_handler, u_char *);<br>&nbsp;int&nbsp;(*inject_op)(pcap_t *, const void *, size_t);<br>&nbsp;int&nbsp;(*setfilter_op)(pcap_t *, struct bpf_program *);<br>&nbsp;int&nbsp;(*setdirection_op)(pcap_t *, pcap_direction_t);<br>&nbsp;int&nbsp;(*set_datalink_op)(pcap_t *, int);<br>&nbsp;int&nbsp;(*getnonblock_op)(pcap_t *, char *);<br>&nbsp;int&nbsp;(*setnonblock_op)(pcap_t *, int, char *);<br>&nbsp;int&nbsp;(*stats_op)(pcap_t *, struct pcap_stat *);<br>&nbsp;void&nbsp;(*close_op)(pcap_t *);</p>
<p>&nbsp;/*<br>&nbsp; * Placeholder for filter code if bpf not in kernel.<br>&nbsp; */<br>&nbsp;struct bpf_program fcode;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; char errbuf[PCAP_ERRBUF_SIZE + 1];<br>&nbsp;&nbsp;&nbsp;&nbsp; int dlt_count;<br>&nbsp;&nbsp;&nbsp; &nbsp;u_int *dlt_list;</p>
<p>&nbsp;struct pcap_pkthdr pcap_header;&nbsp;/* This is needed for the pcap_next_ex() to work */</p>
<p>&nbsp;&nbsp;&nbsp; #ifdef HAVE_REMOTE<br>&nbsp;&nbsp; #ifndef WIN32&nbsp;// Win32 already defines 'timeout'<br>&nbsp;&nbsp;&nbsp;&nbsp; int timeout;&nbsp;&nbsp;&nbsp;&nbsp;//!&lt; timeout to be used in the pcap_open()<br>&nbsp;&nbsp;&nbsp; #endif<br>&nbsp;/*! \brief '1' if we're the network client; needed by several functions (like pcap_setfilter() ) to know if <br>&nbsp;&nbsp;they have to use the socket or they have to open the local adapter. */<br>&nbsp;&nbsp;&nbsp;&nbsp; int rmt_clientside;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp; SOCKET rmt_sockctrl;&nbsp;&nbsp;//!&lt; socket ID of the socket used for the control connection<br>&nbsp;&nbsp;&nbsp;&nbsp; SOCKET rmt_sockdata;&nbsp;&nbsp;//!&lt; socket ID of the socket used for the data connection<br>&nbsp;&nbsp;&nbsp; &nbsp;int rmt_flags;&nbsp;&nbsp;&nbsp;&nbsp;//!&lt; we have to save flags, since they are passed by the pcap_open_live(), but they are used by the pcap_startcapture()<br>&nbsp;&nbsp;&nbsp;&nbsp; int rmt_capstarted;&nbsp;&nbsp;&nbsp;//!&lt; 'true' if the capture is already started (needed to knoe if we have to call the pcap_startcapture()<br>&nbsp;&nbsp;&nbsp;&nbsp; struct pcap_samp rmt_samp;&nbsp;//!&lt; Keeps the parameters related to the sampling process.<br>&nbsp;&nbsp;&nbsp; &nbsp;char *currentfilter;&nbsp;&nbsp;//!&lt; Pointer to a buffer (allocated at run-time) that stores the current filter. Needed when flag PCAP_OPENFLAG_NOCAPTURE_RPCAP is&nbsp;&nbsp;&nbsp; turned on.<br>#endif /* HAVE_REMOTE */<br>};<br><br>// 通信方向的枚举结构<br>typedef enum {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PCAP_D_INOUT = 0, // <span style="COLOR: #800080"><strong>这个定义为0，下面的怎么不给个值?</strong></span><br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PCAP_D_IN,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PCAP_D_OUT<br>} pcap_direction_t;<br><br>// 数据包头<br>struct pcap_pkthdr {<br>&nbsp;&nbsp;&nbsp;&nbsp;struct timeval ts;&nbsp;/* time stamp */<br>&nbsp;&nbsp;&nbsp;&nbsp;bpf_u_int32 caplen;&nbsp;// 展现的长度？<br>&nbsp;&nbsp;&nbsp;&nbsp;bpf_u_int32 len;&nbsp;// 包的长度，bpf_u其实就是unsigned int,&nbsp;&nbsp;&nbsp;&nbsp; 类型定义还经过了一个中间层，即u_int，<span style="FONT-SIZE: 10pt; COLOR: #0000ff">这样以后修改数据类型会比较方便</span>。<br>};<br><br>一层层代码看下来，还是比较繁琐的 </p>
<img src ="http://www.cppblog.com/thinke365/aggbug/96878.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/thinke365/" target="_blank">thinke365</a> 2009-09-21 21:03 <a href="http://www.cppblog.com/thinke365/articles/96878.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>