summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/winpcap/docs/html/group__wpcap__tut4.html
blob: ef5ef03f3af3eaa17fd127cf83f649fb1c99ec8a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<title>WinPcap: Capturing the packets without the callback</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<link href="style.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<!-- Generated by Doxygen 1.6.1 -->
<div class="navigation" id="top">
  <div class="tabs">
    <ul>
      <li><a href="main.html"><span>Main&nbsp;Page</span></a></li>
      <li><a href="pages.html"><span>Related&nbsp;Pages</span></a></li>
      <li><a href="modules.html"><span>Modules</span></a></li>
      <li><a href="annotated.html"><span>Data&nbsp;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">
</table>
<p>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#ga439439c2eae61161dc1efb1e03a81133" 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#ga6bcb7c5c59d76ec16b8a699da136b5de" title="Collect a group of packets.">pcap_loop()</a>.</p>
<p>The callback-based capture mechanism of <a class="el" href="group__wpcapfunc.html#ga6bcb7c5c59d76ec16b8a699da136b5de" 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>
<p>In these cases, <a class="el" href="group__wpcapfunc.html#ga439439c2eae61161dc1efb1e03a81133" 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#ga439439c2eae61161dc1efb1e03a81133" 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>
<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>
<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#ga439439c2eae61161dc1efb1e03a81133" 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 &quot;pcap.h&quot;</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#ga4711d025f83503ce692efa5e45ec60a7" 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#gacd448353957d92c98fccc29e1fc8d927" 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#ga98f36e62c95c6ad81eaa8b2bbeb8f16e" 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#ga6d7103b8a7e1eca8c325bd8f32c361c3" title="String that will be used to determine the type of source in use (file, remote/local...">PCAP_SRC_IF_STRING</a>, NULL, &amp;alldevs, errbuf) == -1)
    {
        fprintf(stderr,<span class="stringliteral">&quot;Error in pcap_findalldevs: %s\n&quot;</span>, errbuf);
        exit(1);
    }
    
    <span class="comment">/* Print the list */</span>
    <span class="keywordflow">for</span>(d=alldevs; d; d=d-&gt;<a class="code" href="structpcap__if.html#a81508e6e4e41ca4235c8d6b51913c536" title="if not NULL, a pointer to the next element in the list; NULL for the last element...">next</a>)
    {
        printf(<span class="stringliteral">&quot;%d. %s&quot;</span>, ++i, d-&gt;<a class="code" href="structpcap__if.html#a5ac083a645d964373f022d03df4849c8" 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-&gt;<a class="code" href="structpcap__if.html#a8444d6e0dfe2bbab0b5e7b24308f1559" title="if not NULL, a pointer to a string giving a human-readable description of the device...">description</a>)
            printf(<span class="stringliteral">&quot; (%s)\n&quot;</span>, d-&gt;<a class="code" href="structpcap__if.html#a8444d6e0dfe2bbab0b5e7b24308f1559" 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">&quot; (No description available)\n&quot;</span>);
    }
    
    <span class="keywordflow">if</span>(i==0)
    {
        printf(<span class="stringliteral">&quot;\nNo interfaces found! Make sure WinPcap is installed.\n&quot;</span>);
        <span class="keywordflow">return</span> -1;
    }
    
    printf(<span class="stringliteral">&quot;Enter the interface number (1-%d):&quot;</span>,i);
    scanf_s(<span class="stringliteral">&quot;%d&quot;</span>, &amp;inum);
    
    <span class="keywordflow">if</span>(inum &lt; 1 || inum &gt; i)
    {
        printf(<span class="stringliteral">&quot;\nInterface number out of range.\n&quot;</span>);
        <span class="comment">/* Free the device list */</span>
        <a class="code" href="group__wpcapfunc.html#ga346b4b0b7fd1cda4abb9a39f767dbeb1" 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&lt; inum-1 ;d=d-&gt;<a class="code" href="structpcap__if.html#a81508e6e4e41ca4235c8d6b51913c536" 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#ga2b64c7b6490090d1d37088794f1f1791" title="Open a generic source in order to capture / send (WinPcap only) traffic.">pcap_open</a>(d-&gt;<a class="code" href="structpcap__if.html#a5ac083a645d964373f022d03df4849c8" 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#ga9134ce51a9a6a7d497c3dee5affdc3b9" 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">&quot;\nUnable to open the adapter. %s is not supported by WinPcap\n&quot;</span>, d-&gt;<a class="code" href="structpcap__if.html#a5ac083a645d964373f022d03df4849c8" 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#ga346b4b0b7fd1cda4abb9a39f767dbeb1" title="Free an interface list returned by pcap_findalldevs().">pcap_freealldevs</a>(alldevs);
        <span class="keywordflow">return</span> -1;
    }
    
    printf(<span class="stringliteral">&quot;\nlistening on %s...\n&quot;</span>, d-&gt;<a class="code" href="structpcap__if.html#a8444d6e0dfe2bbab0b5e7b24308f1559" 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&apos;t need any more the device list. Free it */</span>
    <a class="code" href="group__wpcapfunc.html#ga346b4b0b7fd1cda4abb9a39f767dbeb1" 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#ga439439c2eae61161dc1efb1e03a81133" title="Read a packet from an interface or from an offline capture.">pcap_next_ex</a>( adhandle, &amp;header, &amp;pkt_data)) &gt;= 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-&gt;<a class="code" href="structpcap__pkthdr.html#a21be78b2818c91cb205885b8a6f5aed8" title="time stamp">ts</a>.tv_sec;
        localtime_s(&amp;ltime, &amp;local_tv_sec);
        strftime( timestr, <span class="keyword">sizeof</span> timestr, <span class="stringliteral">&quot;%H:%M:%S&quot;</span>, &amp;ltime);
        
        printf(<span class="stringliteral">&quot;%s,%.6d len:%d\n&quot;</span>, timestr, header-&gt;<a class="code" href="structpcap__pkthdr.html#a21be78b2818c91cb205885b8a6f5aed8" title="time stamp">ts</a>.tv_usec, header-&gt;<a class="code" href="structpcap__pkthdr.html#a728f264db4f5cc304742565a2bcdbeea" title="length this packet (off wire)">len</a>);
    }
    
    <span class="keywordflow">if</span>(res == -1){
        printf(<span class="stringliteral">&quot;Error reading the packets: %s\n&quot;</span>, <a class="code" href="group__wpcapfunc.html#ga81305cb154e4497e95bbb9b708631a3a" 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#ga439439c2eae61161dc1efb1e03a81133" 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#gadf60257f650aaf869671e0a163611fc3" title="Return the next available packet.">pcap_next()</a>? Because <a class="el" href="group__wpcapfunc.html#gadf60257f650aaf869671e0a163611fc3" 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#ga60ce104cdf28420d3361cd36d15be44c" 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>
<p>Notice also that <a class="el" href="group__wpcapfunc.html#ga439439c2eae61161dc1efb1e03a81133" 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>
<p><a class="el" href="group__wpcap__tut3.html">&lt;&lt;&lt; Previous</a> <a class="el" href="group__wpcap__tut5.html">Next &gt;&gt;&gt;</a> </p>
</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-2009
CACE Technologies. All rights reserved.</p>