📄 group__wpcap__tut4.html
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"><title>WinPcap: Capturing the packets without the callback</title><link href="style.css" rel="stylesheet" type="text/css"><link href="tabs.css" rel="stylesheet" type="text/css"></head><body><!-- Generated by Doxygen 1.5.6 --><div class="navigation" id="top"> <div class="tabs"> <ul> <li><a href="main.html"><span>Main Page</span></a></li> <li><a href="pages.html"><span>Related Pages</span></a></li> <li><a href="modules.html"><span>Modules</span></a></li> <li><a href="annotated.html"><span>Data Structures</span></a></li> <li><a href="files.html"><span>Files</span></a></li> </ul> </div></div><div class="contents"><h1>Capturing the packets without the callback</h1><table border="0" cellpadding="0" cellspacing="0"><tr><td></td></tr></table>The example program in this lesson behaves exactly like the previous program (<a class="el" href="group__wpcap__tut3.html">Opening an adapter and capturing the packets</a>), but it uses <a class="el" href="group__wpcapfunc.html#g439439c2eae61161dc1efb1e03a81133" title="Read a packet from an interface or from an offline capture.">pcap_next_ex()</a> instead of <a class="el" href="group__wpcapfunc.html#g6bcb7c5c59d76ec16b8a699da136b5de" title="Collect a group of packets.">pcap_loop()</a>.<p>The callback-based capture mechanism of <a class="el" href="group__wpcapfunc.html#g6bcb7c5c59d76ec16b8a699da136b5de" title="Collect a group of packets.">pcap_loop()</a> is elegant and it could be a good choice in some situations. However, handling a callback is sometimes not practical -- it often makes the program more complex especially in situations with multithreaded applications or C++ classes.<p>In these cases, <a class="el" href="group__wpcapfunc.html#g439439c2eae61161dc1efb1e03a81133" title="Read a packet from an interface or from an offline capture.">pcap_next_ex()</a> retrievs a packet with a direct call -- using <a class="el" href="group__wpcapfunc.html#g439439c2eae61161dc1efb1e03a81133" title="Read a packet from an interface or from an offline capture.">pcap_next_ex()</a> packets are received only when the programmer wants them.<p>The parameters of this function are the same as a capture callback -- it takes an adapter descriptor and a couple of pointers that will be initialized and returned to the user (one to a <a class="el" href="structpcap__pkthdr.html" title="Header of a packet in the dump file.">pcap_pkthdr</a> structure and another to a buffer with the packet data).<p>In the following program, we recycle the callback code of the previous lesson's example and move it inside main() right after the call to <a class="el" href="group__wpcapfunc.html#g439439c2eae61161dc1efb1e03a81133" title="Read a packet from an interface or from an offline capture.">pcap_next_ex()</a>.<p><div class="fragment"><pre class="fragment"><span class="preprocessor">#include "pcap.h"</span><span class="keywordtype">int</span> main(){<a class="code" href="structpcap__if.html" title="Item in a list of interfaces, used by pcap_findalldevs().">pcap_if_t</a> *alldevs;<a class="code" href="structpcap__if.html" title="Item in a list of interfaces, used by pcap_findalldevs().">pcap_if_t</a> *d;<span class="keywordtype">int</span> inum;<span class="keywordtype">int</span> i=0;<a class="code" href="group__wpcap__def.html#g4711d025f83503ce692efa5e45ec60a7" title="Descriptor of an open capture instance. This structure is opaque to the user, that...">pcap_t</a> *adhandle;<span class="keywordtype">int</span> res;<span class="keywordtype">char</span> errbuf[<a class="code" href="group__wpcap__def.html#gcd448353957d92c98fccc29e1fc8d927" title="Size to use when allocating the buffer that contains the libpcap errors.">PCAP_ERRBUF_SIZE</a>];<span class="keyword">struct </span>tm ltime;<span class="keywordtype">char</span> timestr[16];<span class="keyword">struct </span><a class="code" href="structpcap__pkthdr.html" title="Header of a packet in the dump file.">pcap_pkthdr</a> *header;<span class="keyword">const</span> u_char *pkt_data;time_t local_tv_sec; <span class="comment">/* Retrieve the device list on the local machine */</span> <span class="keywordflow">if</span> (<a class="code" href="group__wpcapfunc.html#g98f36e62c95c6ad81eaa8b2bbeb8f16e" title="Create a list of network devices that can be opened with pcap_open().">pcap_findalldevs_ex</a>(<a class="code" href="group__remote__source__string.html#g6d7103b8a7e1eca8c325bd8f32c361c3" title="String that will be used to determine the type of source in use (file, remote/local...">PCAP_SRC_IF_STRING</a>, NULL, &alldevs, errbuf) == -1) { fprintf(stderr,<span class="stringliteral">"Error in pcap_findalldevs: %s\n"</span>, errbuf); exit(1); } <span class="comment">/* Print the list */</span> <span class="keywordflow">for</span>(d=alldevs; d; d=d-><a class="code" href="structpcap__if.html#81508e6e4e41ca4235c8d6b51913c536" title="if not NULL, a pointer to the next element in the list; NULL for the last element...">next</a>) { printf(<span class="stringliteral">"%d. %s"</span>, ++i, d-><a class="code" href="structpcap__if.html#5ac083a645d964373f022d03df4849c8" title="a pointer to a string giving a name for the device to pass to pcap_open_live()">name</a>); <span class="keywordflow">if</span> (d-><a class="code" href="structpcap__if.html#8444d6e0dfe2bbab0b5e7b24308f1559" title="if not NULL, a pointer to a string giving a human-readable description of the device...">description</a>) printf(<span class="stringliteral">" (%s)\n"</span>, d-><a class="code" href="structpcap__if.html#8444d6e0dfe2bbab0b5e7b24308f1559" title="if not NULL, a pointer to a string giving a human-readable description of the device...">description</a>); <span class="keywordflow">else</span> printf(<span class="stringliteral">" (No description available)\n"</span>); } <span class="keywordflow">if</span>(i==0) { printf(<span class="stringliteral">"\nNo interfaces found! Make sure WinPcap is installed.\n"</span>); <span class="keywordflow">return</span> -1; } printf(<span class="stringliteral">"Enter the interface number (1-%d):"</span>,i); scanf_s(<span class="stringliteral">"%d"</span>, &inum); <span class="keywordflow">if</span>(inum < 1 || inum > i) { printf(<span class="stringliteral">"\nInterface number out of range.\n"</span>); <span class="comment">/* Free the device list */</span> <a class="code" href="group__wpcapfunc.html#g346b4b0b7fd1cda4abb9a39f767dbeb1" title="Free an interface list returned by pcap_findalldevs().">pcap_freealldevs</a>(alldevs); <span class="keywordflow">return</span> -1; } <span class="comment">/* Jump to the selected adapter */</span> <span class="keywordflow">for</span>(d=alldevs, i=0; i< inum-1 ;d=d-><a class="code" href="structpcap__if.html#81508e6e4e41ca4235c8d6b51913c536" title="if not NULL, a pointer to the next element in the list; NULL for the last element...">next</a>, i++); <span class="comment">/* Open the device */</span> <span class="keywordflow">if</span> ( (adhandle= <a class="code" href="group__wpcapfunc.html#g2b64c7b6490090d1d37088794f1f1791" title="Open a generic source in order to capture / send (WinPcap only) traffic.">pcap_open</a>(d-><a class="code" href="structpcap__if.html#5ac083a645d964373f022d03df4849c8" title="a pointer to a string giving a name for the device to pass to pcap_open_live()">name</a>, <span class="comment">// name of the device</span> 65536, <span class="comment">// portion of the packet to capture. </span> <span class="comment">// 65536 guarantees that the whole packet will be captured on all the link layers</span> <a class="code" href="group__remote__open__flags.html#g9134ce51a9a6a7d497c3dee5affdc3b9" title="Defines if the adapter has to go in promiscuous mode.">PCAP_OPENFLAG_PROMISCUOUS</a>, <span class="comment">// promiscuous mode</span> 1000, <span class="comment">// read timeout</span> NULL, <span class="comment">// authentication on the remote machine</span> errbuf <span class="comment">// error buffer</span> ) ) == NULL) { fprintf(stderr,<span class="stringliteral">"\nUnable to open the adapter. %s is not supported by WinPcap\n"</span>, d-><a class="code" href="structpcap__if.html#5ac083a645d964373f022d03df4849c8" title="a pointer to a string giving a name for the device to pass to pcap_open_live()">name</a>); <span class="comment">/* Free the device list */</span> <a class="code" href="group__wpcapfunc.html#g346b4b0b7fd1cda4abb9a39f767dbeb1" title="Free an interface list returned by pcap_findalldevs().">pcap_freealldevs</a>(alldevs); <span class="keywordflow">return</span> -1; } printf(<span class="stringliteral">"\nlistening on %s...\n"</span>, d-><a class="code" href="structpcap__if.html#8444d6e0dfe2bbab0b5e7b24308f1559" title="if not NULL, a pointer to a string giving a human-readable description of the device...">description</a>); <span class="comment">/* At this point, we don't need any more the device list. Free it */</span> <a class="code" href="group__wpcapfunc.html#g346b4b0b7fd1cda4abb9a39f767dbeb1" title="Free an interface list returned by pcap_findalldevs().">pcap_freealldevs</a>(alldevs); <span class="comment">/* Retrieve the packets */</span> <span class="keywordflow">while</span>((res = <a class="code" href="group__wpcapfunc.html#g439439c2eae61161dc1efb1e03a81133" title="Read a packet from an interface or from an offline capture.">pcap_next_ex</a>( adhandle, &header, &pkt_data)) >= 0){ <span class="keywordflow">if</span>(res == 0) <span class="comment">/* Timeout elapsed */</span> <span class="keywordflow">continue</span>; <span class="comment">/* convert the timestamp to readable format */</span> local_tv_sec = header-><a class="code" href="structpcap__pkthdr.html#21be78b2818c91cb205885b8a6f5aed8" title="time stamp">ts</a>.tv_sec; localtime_s(&ltime, &local_tv_sec); strftime( timestr, <span class="keyword">sizeof</span> timestr, <span class="stringliteral">"%H:%M:%S"</span>, &ltime); printf(<span class="stringliteral">"%s,%.6d len:%d\n"</span>, timestr, header-><a class="code" href="structpcap__pkthdr.html#21be78b2818c91cb205885b8a6f5aed8" title="time stamp">ts</a>.tv_usec, header-><a class="code" href="structpcap__pkthdr.html#728f264db4f5cc304742565a2bcdbeea" title="length this packet (off wire)">len</a>); } <span class="keywordflow">if</span>(res == -1){ printf(<span class="stringliteral">"Error reading the packets: %s\n"</span>, <a class="code" href="group__wpcapfunc.html#g81305cb154e4497e95bbb9b708631a3a" title="return the error text pertaining to the last pcap library error.">pcap_geterr</a>(adhandle)); <span class="keywordflow">return</span> -1; } <span class="keywordflow">return</span> 0;}</pre></div><p>Why do we use <a class="el" href="group__wpcapfunc.html#g439439c2eae61161dc1efb1e03a81133" title="Read a packet from an interface or from an offline capture.">pcap_next_ex()</a> instead of the old <a class="el" href="group__wpcapfunc.html#gdf60257f650aaf869671e0a163611fc3" title="Return the next available packet.">pcap_next()</a>? Because <a class="el" href="group__wpcapfunc.html#gdf60257f650aaf869671e0a163611fc3" title="Return the next available packet.">pcap_next()</a> has some drawbacks. First of all, it is inefficient because it hides the callback method but still relies on <a class="el" href="group__wpcapfunc.html#g60ce104cdf28420d3361cd36d15be44c" title="Collect a group of packets.">pcap_dispatch()</a>. Second, it is not able to detect EOF, so it's not very useful when gathering packets from a file.<p>Notice also that <a class="el" href="group__wpcapfunc.html#g439439c2eae61161dc1efb1e03a81133" title="Read a packet from an interface or from an offline capture.">pcap_next_ex()</a> returns different values for success, timeout elapsed, error and EOF conditions.<p><a class="el" href="group__wpcap__tut3.html"><<< Previous</a> <a class="el" href="group__wpcap__tut5.html">Next >>></a> </div><hr><p align="right"><img border="0" src="winpcap_small.gif" align="absbottom" width="91" height="27">documentation. Copyright (c) 2002-2005 Politecnico di Torino. Copyright (c) 2005-2008CACE Technologies. All rights reserved.</p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -