📄 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=iso-8859-1"><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.1 --><div class="tabs"> <ul> <li><a href="main.html"><span>Main Page</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> <li><a href="pages.html"><span>Related Pages</span></a></li> </ul></div><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">pcap_next_ex()</a> instead of <a class="el" href="group__wpcapfunc.html#g6bcb7c5c59d76ec16b8a699da136b5de">pcap_loop()</a>.<p>The callback-based capture mechanism of <a class="el" href="group__wpcapfunc.html#g6bcb7c5c59d76ec16b8a699da136b5de">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">pcap_next_ex()</a> retrievs a packet with a direct call -- using <a class="el" href="group__wpcapfunc.html#g439439c2eae61161dc1efb1e03a81133">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">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">pcap_next_ex()</a>.<p><div class="fragment"><pre class="fragment"><span class="preprocessor">#include "pcap.h"</span>main(){<a class="code" href="structpcap__if.html">pcap_if_t</a> *alldevs;<a class="code" href="structpcap__if.html">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">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">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">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">pcap_findalldevs_ex</a>(<a class="code" href="group__remote__source__string.html#g6d7103b8a7e1eca8c325bd8f32c361c3">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">next</a>) { printf(<span class="stringliteral">"%d. %s"</span>, ++i, d-><a class="code" href="structpcap__if.html#5ac083a645d964373f022d03df4849c8">name</a>); if (d-><a class="code" href="structpcap__if.html#8444d6e0dfe2bbab0b5e7b24308f1559">description</a>) printf(<span class="stringliteral">" (%s)\n"</span>, d-><a class="code" href="structpcap__if.html#8444d6e0dfe2bbab0b5e7b24308f1559">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(<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">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">next</a>, i++); <span class="comment">/* Open the device */</span> <span class="keywordflow">if</span> ( (adhandle= <a class="code" href="group__wpcapfunc.html#g2b64c7b6490090d1d37088794f1f1791">pcap_open</a>(d-><a class="code" href="structpcap__if.html#5ac083a645d964373f022d03df4849c8">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">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">name</a>); <span class="comment">/* Free the device list */</span> <a class="code" href="group__wpcapfunc.html#g346b4b0b7fd1cda4abb9a39f767dbeb1">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">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">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">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">ts</a>.tv_sec; ltime=localtime(&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">ts</a>.tv_usec, header-><a class="code" href="structpcap__pkthdr.html#728f264db4f5cc304742565a2bcdbeea">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">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">pcap_next_ex()</a> instead of the old <a class="el" href="group__wpcapfunc.html#gdf60257f650aaf869671e0a163611fc3">pcap_next()</a>? Because <a class="el" href="group__wpcapfunc.html#gdf60257f650aaf869671e0a163611fc3">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">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">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> <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-2007 CACE Technologies. All rights reserved.</p>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -