mirror of
https://github.com/holub/mame
synced 2025-04-29 11:30:28 +03:00
280 lines
21 KiB
HTML
280 lines
21 KiB
HTML
<!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: Interpreting the packets</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 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>Interpreting the packets</h1><table border="0" cellpadding="0" cellspacing="0">
|
|
</table>
|
|
<p>Now that we are able to capture and filter network traffic, we want to put our knowledge to work with a simple "real world" application.</p>
|
|
<p>In this lesson we will take code from the previous lessons and use these pieces to build a more useful program. the main purpose of the current program is to show how the protocol headers of a captured packet can be parsed and interpreted. The resulting application, called UDPdump, prints a summary of the UDP traffic on our network.</p>
|
|
<p>We have chosen to parse and display the UDP protocol because it is more accessible than other protocols such as TCP and consequently is an excellent initial example. Let's look at the code:</p>
|
|
<div class="fragment"><pre class="fragment"><span class="comment">/*</span>
|
|
<span class="comment"> * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)</span>
|
|
<span class="comment"> * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California)</span>
|
|
<span class="comment"> * All rights reserved.</span>
|
|
<span class="comment"> *</span>
|
|
<span class="comment"> * Redistribution and use in source and binary forms, with or without</span>
|
|
<span class="comment"> * modification, are permitted provided that the following conditions</span>
|
|
<span class="comment"> * are met:</span>
|
|
<span class="comment"> *</span>
|
|
<span class="comment"> * 1. Redistributions of source code must retain the above copyright</span>
|
|
<span class="comment"> * notice, this list of conditions and the following disclaimer.</span>
|
|
<span class="comment"> * 2. Redistributions in binary form must reproduce the above copyright</span>
|
|
<span class="comment"> * notice, this list of conditions and the following disclaimer in the</span>
|
|
<span class="comment"> * documentation and/or other materials provided with the distribution.</span>
|
|
<span class="comment"> * 3. Neither the name of the Politecnico di Torino, CACE Technologies </span>
|
|
<span class="comment"> * nor the names of its contributors may be used to endorse or promote </span>
|
|
<span class="comment"> * products derived from this software without specific prior written </span>
|
|
<span class="comment"> * permission.</span>
|
|
<span class="comment"> *</span>
|
|
<span class="comment"> * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS</span>
|
|
<span class="comment"> * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT</span>
|
|
<span class="comment"> * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR</span>
|
|
<span class="comment"> * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT</span>
|
|
<span class="comment"> * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,</span>
|
|
<span class="comment"> * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT</span>
|
|
<span class="comment"> * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,</span>
|
|
<span class="comment"> * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY</span>
|
|
<span class="comment"> * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT</span>
|
|
<span class="comment"> * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE</span>
|
|
<span class="comment"> * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</span>
|
|
<span class="comment"> *</span>
|
|
<span class="comment"> */</span>
|
|
|
|
<span class="preprocessor">#include "pcap.h"</span>
|
|
|
|
<span class="comment">/* 4 bytes IP address */</span>
|
|
<span class="keyword">typedef</span> <span class="keyword">struct </span>ip_address{
|
|
u_char byte1;
|
|
u_char byte2;
|
|
u_char byte3;
|
|
u_char byte4;
|
|
}ip_address;
|
|
|
|
<span class="comment">/* IPv4 header */</span>
|
|
<span class="keyword">typedef</span> <span class="keyword">struct </span>ip_header{
|
|
u_char ver_ihl; <span class="comment">// Version (4 bits) + Internet header length (4 bits)</span>
|
|
u_char tos; <span class="comment">// Type of service </span>
|
|
u_short tlen; <span class="comment">// Total length </span>
|
|
u_short identification; <span class="comment">// Identification</span>
|
|
u_short flags_fo; <span class="comment">// Flags (3 bits) + Fragment offset (13 bits)</span>
|
|
u_char ttl; <span class="comment">// Time to live</span>
|
|
u_char proto; <span class="comment">// Protocol</span>
|
|
u_short crc; <span class="comment">// Header checksum</span>
|
|
ip_address saddr; <span class="comment">// Source address</span>
|
|
ip_address daddr; <span class="comment">// Destination address</span>
|
|
u_int op_pad; <span class="comment">// Option + Padding</span>
|
|
}ip_header;
|
|
|
|
<span class="comment">/* UDP header*/</span>
|
|
<span class="keyword">typedef</span> <span class="keyword">struct </span>udp_header{
|
|
u_short sport; <span class="comment">// Source port</span>
|
|
u_short dport; <span class="comment">// Destination port</span>
|
|
u_short len; <span class="comment">// Datagram length</span>
|
|
u_short crc; <span class="comment">// Checksum</span>
|
|
}udp_header;
|
|
|
|
<span class="comment">/* prototype of the packet handler */</span>
|
|
<span class="keywordtype">void</span> packet_handler(u_char *param, <span class="keyword">const</span> <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);
|
|
|
|
|
|
<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">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>];
|
|
u_int netmask;
|
|
<span class="keywordtype">char</span> packet_filter[] = <span class="stringliteral">"ip and udp"</span>;
|
|
<span class="keyword">struct </span>bpf_program fcode;
|
|
|
|
<span class="comment">/* Retrieve the device list */</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, &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#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">"%d. %s"</span>, ++i, d-><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-><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">" (%s)\n"</span>, d-><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">" (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#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< inum-1 ;d=d-><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 adapter */</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-><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 grants that the whole packet will be captured on all the MACs.</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">// remote authentication</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>);
|
|
<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">/* Check the link layer. We support only Ethernet for simplicity. */</span>
|
|
<span class="keywordflow">if</span>(<a class="code" href="group__wpcapfunc.html#ga64c019f851f7da6892d51cca15f12ace" title="Return the link layer of an adapter.">pcap_datalink</a>(adhandle) != DLT_EN10MB)
|
|
{
|
|
fprintf(stderr,<span class="stringliteral">"\nThis program works only on Ethernet networks.\n"</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="keywordflow">if</span>(d-><a class="code" href="structpcap__if.html#a3910004677550db6d9b09792ba3e2cca" title="a pointer to the first element of a list of addresses for the interface">addresses</a> != NULL)
|
|
<span class="comment">/* Retrieve the mask of the first address of the interface */</span>
|
|
netmask=((<span class="keyword">struct </span>sockaddr_in *)(d-><a class="code" href="structpcap__if.html#a3910004677550db6d9b09792ba3e2cca" title="a pointer to the first element of a list of addresses for the interface">addresses</a>-><a class="code" href="structpcap__addr.html#ac43963e42e4d901e55e433ab9c3ea686" title="if not NULL, a pointer to a struct sockaddr that contains the netmask corresponding...">netmask</a>))->sin_addr.S_un.S_addr;
|
|
<span class="keywordflow">else</span>
|
|
<span class="comment">/* If the interface is without addresses we suppose to be in a C class network */</span>
|
|
netmask=0xffffff;
|
|
|
|
|
|
<span class="comment">//compile the filter</span>
|
|
if (<a class="code" href="group__wpcapfunc.html#ga363bdc6f6b39b4979ddcf15ecb830c5c" title="Compile a packet filter, converting an high level filtering expression (see Filtering...">pcap_compile</a>(adhandle, &fcode, packet_filter, 1, netmask) <0 )
|
|
{
|
|
fprintf(stderr,<span class="stringliteral">"\nUnable to compile the packet filter. Check the syntax.\n"</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">//set the filter</span>
|
|
<span class="keywordflow">if</span> (<a class="code" href="group__wpcapfunc.html#gaf5f9cfe85dad0967ff607e5159b1ba61" title="Associate a filter to a capture.">pcap_setfilter</a>(adhandle, &fcode)<0)
|
|
{
|
|
fprintf(stderr,<span class="stringliteral">"\nError setting the filter.\n"</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;
|
|
}
|
|
|
|
printf(<span class="stringliteral">"\nlistening on %s...\n"</span>, d-><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'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">/* start the capture */</span>
|
|
<a class="code" href="group__wpcapfunc.html#ga6bcb7c5c59d76ec16b8a699da136b5de" title="Collect a group of packets.">pcap_loop</a>(adhandle, 0, packet_handler, NULL);
|
|
|
|
<span class="keywordflow">return</span> 0;
|
|
}
|
|
|
|
<span class="comment">/* Callback function invoked by libpcap for every incoming packet */</span>
|
|
<span class="keywordtype">void</span> packet_handler(u_char *param, <span class="keyword">const</span> <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)
|
|
{
|
|
<span class="keyword">struct </span>tm ltime;
|
|
<span class="keywordtype">char</span> timestr[16];
|
|
ip_header *ih;
|
|
udp_header *uh;
|
|
u_int ip_len;
|
|
u_short sport,dport;
|
|
time_t local_tv_sec;
|
|
|
|
<span class="comment">/*</span>
|
|
<span class="comment"> * Unused variable</span>
|
|
<span class="comment"> */</span>
|
|
(VOID)(param);
|
|
|
|
<span class="comment">/* convert the timestamp to readable format */</span>
|
|
local_tv_sec = header-><a class="code" href="structpcap__pkthdr.html#a21be78b2818c91cb205885b8a6f5aed8" 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);
|
|
|
|
<span class="comment">/* print timestamp and length of the packet */</span>
|
|
printf(<span class="stringliteral">"%s.%.6d len:%d "</span>, timestr, header-><a class="code" href="structpcap__pkthdr.html#a21be78b2818c91cb205885b8a6f5aed8" title="time stamp">ts</a>.tv_usec, header-><a class="code" href="structpcap__pkthdr.html#a728f264db4f5cc304742565a2bcdbeea" title="length this packet (off wire)">len</a>);
|
|
|
|
<span class="comment">/* retireve the position of the ip header */</span>
|
|
ih = (ip_header *) (pkt_data +
|
|
14); <span class="comment">//length of ethernet header</span>
|
|
|
|
<span class="comment">/* retireve the position of the udp header */</span>
|
|
ip_len = (ih->ver_ihl & 0xf) * 4;
|
|
uh = (udp_header *) ((u_char*)ih + ip_len);
|
|
|
|
<span class="comment">/* convert from network byte order to host byte order */</span>
|
|
sport = ntohs( uh->sport );
|
|
dport = ntohs( uh->dport );
|
|
|
|
<span class="comment">/* print ip addresses and udp ports */</span>
|
|
printf(<span class="stringliteral">"%d.%d.%d.%d.%d -> %d.%d.%d.%d.%d\n"</span>,
|
|
ih->saddr.byte1,
|
|
ih->saddr.byte2,
|
|
ih->saddr.byte3,
|
|
ih->saddr.byte4,
|
|
sport,
|
|
ih->daddr.byte1,
|
|
ih->daddr.byte2,
|
|
ih->daddr.byte3,
|
|
ih->daddr.byte4,
|
|
dport);
|
|
}
|
|
</pre></div><p>First of all, we set the filter to "ip and udp". In this way we are sure that packet_handler() will receive only UDP packets over IPv4: this simplifies the parsing and increases the efficiency of the program.</p>
|
|
<p>We have also created a couple of structs that describe the IP and UDP headers. These structs are used by packet_handler() to properly locate the various header fields.</p>
|
|
<p>packet_handler(), although limited to a single protocol dissector (UDP over IPv4), shows how complex "sniffers" like tcpdump/WinDump decode the network traffic. Since we aren't interested in the MAC header, we skip it. For simplicity and before starting the capture, we check the MAC layer with <a class="el" href="group__wpcapfunc.html#ga64c019f851f7da6892d51cca15f12ace" title="Return the link layer of an adapter.">pcap_datalink()</a> to make sure that we are dealing with an Ethernet network. This way we can be sure that the MAC header is exactly 14 bytes.</p>
|
|
<p>The IP header is located just after the MAC header. We will extract the IP source and destination addresses from the IP header.</p>
|
|
<p>Reaching the UDP header is a bit more complicated, because the IP header doesn't have a fixed length. Therefore, we use the IP header's length field to know its size. Once we know the location of the UDP header, we extract the source and destination ports.</p>
|
|
<p>The extracted values are printed on the screen, and the result is something like:</p>
|
|
<p><code> 1. \Device\Packet_{A7FD048A-5D4B-478E-B3C1-34401AC3B72F} (Xircom t 10/100 Adapter) <br/>
|
|
Enter the interface number (1-2):1<br/>
|
|
</code></p>
|
|
<p><code>listening on Xircom CardBus Ethernet 10/100 Adapter... <br/>
|
|
16:13:15.312784 len:87 130.192.31.67.2682 -> 130.192.3.21.53 <br/>
|
|
16:13:15.314796 len:137 130.192.3.21.53 -> 130.192.31.67.2682 <br/>
|
|
16:13:15.322101 len:78 130.192.31.67.2683 -> 130.192.3.21.53 <br/>
|
|
</code></p>
|
|
<p>Each of the final 3 lines represents a different packet.</p>
|
|
<p><a class="el" href="group__wpcap__tut5.html"><<< Previous</a> <a class="el" href="group__wpcap__tut7.html">Next >>></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>
|