npcap-tutorial.html 63 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741
  1. <html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Npcap Development Tutorial</title><meta name="generator" content="DocBook XSL Stylesheets V1.79.2"><meta name="description" content="A step-by-step guide to writing software that uses Npcap to list network adapters, capture packets, and send network traffic."><link rel="home" href="index.html" title="Npcap Reference Guide"><link rel="up" href="index.html" title="Npcap Reference Guide"><link rel="prev" href="npcap-api.html" title="The Npcap API"><link rel="next" href="npcap-internals.html" title="Npcap internals"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Npcap Development Tutorial</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="npcap-api.html">Prev</a> </td><th width="60%" align="center"> </th><td width="20%" align="right"> <a accesskey="n" href="npcap-internals.html">Next</a></td></tr></table><hr></div><div class="sect1"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="npcap-tutorial"></a>Npcap Development Tutorial</h2></div><div><div class="abstract"><p class="title"><b>Abstract</b></p>
  2. <p>A step-by-step guide to writing software that uses Npcap to list
  3. network adapters, capture packets, and send network traffic.</p>
  4. </div></div></div></div>
  5. <p>This section shows how to use the features of the Npcap API. It is
  6. organized as a tutorial, subdivided into a set of lessons that will
  7. introduce the reader, in a step-by-step fashion, to program development
  8. using Npcap, from the basic functions (obtaining the adapter list,
  9. starting a capture, etc.) to the most advanced ones (handling send queues
  10. and gathering statistics about network traffic).</p>
  11. <p>The samples are written in plain C, so a basic knowledge of C
  12. programming is required. Also, since this is a tutorial about a library
  13. dealing with "raw" networking packets, good knowledge of networks and
  14. network protocols is assumed.</p>
  15. <p>The code in this section is copied from the <a class="xref" href="npcap-devguide.html#npcap-examples" title="Examples">the section called &#8220;Examples&#8221;</a> in the source
  16. distribution and the SDK. The code is released under a BSD-3-clause license and
  17. copyright: NetGroup, Politecnico di Torino (Italy); CACE Technologies,
  18. Davis (California); and Insecure.com, LLC. Full text of the code license
  19. can be found in each source file.</p>
  20. <div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="npcap-tutorial-devlist"></a>Obtaining the device list</h3></div></div></div>
  21. <p>Typically, the first thing that a Npcap-based application does is
  22. get a list of attached network adapters. Both libpcap and Npcap provide
  23. the <a class="ulink" href="wpcap/pcap_findalldevs.html" target="_top">pcap_findalldevs_ex()</a> function for this purpose:
  24. this function returns a linked list of <code class="literal">pcap_if</code> structures, each of which contains
  25. comprehensive information about an attached adapter. In particular, the
  26. fields <code class="literal">name</code> and <code class="literal">description</code> contain the name and a
  27. human readable description, respectively, of the corresponding
  28. device.</p>
  29. <p>The following code retrieves the adapter list and shows it on the
  30. screen, printing an error if no adapters are found.</p>
  31. <pre class="programlisting">
  32. #include "pcap.h"
  33. main()
  34. {
  35. pcap_if_t *alldevs;
  36. pcap_if_t *d;
  37. int i=0;
  38. char errbuf[PCAP_ERRBUF_SIZE];
  39. /* Retrieve the device list from the local machine */
  40. if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING,
  41. NULL /* auth is not needed */,
  42. &amp;alldevs, errbuf) == -1)
  43. {
  44. fprintf(stderr,
  45. "Error in pcap_findalldevs_ex: %s\n",
  46. errbuf);
  47. exit(1);
  48. }
  49. /* Print the list */
  50. for(d= alldevs; d != NULL; d= d-&gt;next)
  51. {
  52. printf("%d. %s", ++i, d-&gt;name);
  53. if (d-&gt;description)
  54. printf(" (%s)\n", d-&gt;description);
  55. else
  56. printf(" (No description available)\n");
  57. }
  58. if (i == 0)
  59. {
  60. printf("\nNo interfaces found! Make sure Npcap is installed.\n");
  61. return;
  62. }
  63. /* We don't need any more the device list. Free it */
  64. pcap_freealldevs(alldevs);
  65. }
  66. </pre>
  67. <p>Some comments about this code.</p>
  68. <p>First of all, <a class="ulink" href="./wpcap/pcap_findalldevs.html" target="_top">pcap_findalldevs_ex()</a>, like
  69. other libpcap functions, has an <code class="literal">errbuf</code> parameter. This
  70. parameter points to a string filled by libpcap with a description of the
  71. error if something goes wrong.</p>
  72. <p>Second, remember that not all the OSes supported by libpcap provide a
  73. description of the network interfaces, therefore if we want to write a
  74. portable application, we must consider the case in which
  75. <code class="literal">description</code> is null: we print the string "No
  76. description available" in that situation.</p>
  77. <p>Note finally that we free the list with <a class="ulink" href="wpcap/pcap_findalldevs.html" target="_top">pcap_freealldevs()</a> once when
  78. we have finished with it.</p>
  79. <p>Assuming we have compiled the program, let's try to run it. On a
  80. particular Windows workstation, the result we optained is</p>
  81. <pre class="screen">
  82. 1. \Device\NPF_{4E273621-5161-46C8-895A-48D0E52A0B83} (Realtek RTL8029(AS) Ethernet Adapter)
  83. 2. \Device\NPF_{5D24AE04-C486-4A96-83FB-8B5EC6C7F430} (3Com EtherLink PCI)</pre>
  84. <p>As you can see, the name of the network adapters (that will be passed
  85. to libpcap when opening the devices) under Windows are quite unreadable,
  86. so the parenthetical descriptions can be very helpful.</p>
  87. </div>
  88. <div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="npcap-tutorial-devdetails"></a>Obtaining advanced information about installed devices</h3></div></div></div>
  89. <p>Lesson 1 (<a class="xref" href="npcap-tutorial.html#npcap-tutorial-devlist" title="Obtaining the device list">the section called &#8220;Obtaining the device list&#8221;</a>) demonstrated how
  90. to get basic information (i.e. device name and description) about
  91. available adapters. Actually, Npcap provides also other advanced
  92. information. In particular, every <code class="literal">pcap_if</code> structure
  93. returned by <a class="ulink" href="wpcap/pcap_findalldevs.html" target="_top">pcap_findalldevs_ex()</a>
  94. contains also a list of <code class="literal">pcap_addr</code> structures,
  95. with:</p>
  96. <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">a list of addresses for that interface.</li><li class="listitem">a list of netmasks (each of which corresponds to an entry in
  97. the addresses list).</li><li class="listitem">a list of broadcast addresses (each of which corresponds to an
  98. entry in the addresses list).</li><li class="listitem">a list of destination addresses (each of which corresponds to
  99. an entry in the addresses list).</li></ul></div>
  100. <p>Additionally, <code class="literal">pcap_findalldevs_ex()</code> can also
  101. return remote adapters and a list of pcap files that are located in a
  102. given local folder.</p>
  103. <p>The following sample provides an ifprint() function that prints the
  104. complete contents of a <code class="literal">pcap_if</code> structure. It is
  105. invoked by the program for every entry returned by
  106. <code class="literal">pcap_findalldevs_ex()</code>.</p>
  107. <pre class="programlisting">
  108. /* Print all the available information on the given interface */
  109. void ifprint(pcap_if_t *d)
  110. {
  111. pcap_addr_t *a;
  112. char ip6str[128];
  113. /* Name */
  114. printf("%s\n",d-&gt;name);
  115. /* Description */
  116. if (d-&gt;description)
  117. printf("\tDescription: %s\n",d-&gt;description);
  118. /* Loopback Address*/
  119. printf("\tLoopback: %s\n",(d-&gt;flags &amp; PCAP_IF_LOOPBACK)?"yes":"no");
  120. /* IP addresses */
  121. for(a=d-&gt;addresses;a;a=a-&gt;next) {
  122. printf("\tAddress Family: #%d\n",a-&gt;addr-&gt;sa_family);
  123. switch(a-&gt;addr-&gt;sa_family)
  124. {
  125. case AF_INET:
  126. printf("\tAddress Family Name: AF_INET\n");
  127. if (a-&gt;addr)
  128. printf("\tAddress: %s\n",iptos(((struct sockaddr_in *)a-&gt;addr)-&gt;sin_addr.s_addr));
  129. if (a-&gt;netmask)
  130. printf("\tNetmask: %s\n",iptos(((struct sockaddr_in *)a-&gt;netmask)-&gt;sin_addr.s_addr));
  131. if (a-&gt;broadaddr)
  132. printf("\tBroadcast Address: %s\n",iptos(((struct sockaddr_in *)a-&gt;broadaddr)-&gt;sin_addr.s_addr));
  133. if (a-&gt;dstaddr)
  134. printf("\tDestination Address: %s\n",iptos(((struct sockaddr_in *)a-&gt;dstaddr)-&gt;sin_addr.s_addr));
  135. break;
  136. case AF_INET6:
  137. printf("\tAddress Family Name: AF_INET6\n");
  138. if (a-&gt;addr)
  139. printf("\tAddress: %s\n", ip6tos(a-&gt;addr, ip6str, sizeof(ip6str)));
  140. break;
  141. default:
  142. printf("\tAddress Family Name: Unknown\n");
  143. break;
  144. }
  145. }
  146. printf("\n");
  147. }
  148. </pre>
  149. </div>
  150. <div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="npcap-tutorial-openadapter"></a>Opening an adapter and capturing the packets</h3></div></div></div>
  151. <p>Now that we've seen how to obtain an adapter to play with, let's
  152. start the real job, opening an adapter and capturing some traffic. In
  153. this lesson we'll write a program that prints some information about each
  154. packet flowing through the adapter.</p>
  155. <p>The function that opens a capture device is <a class="ulink" href="wpcap/pcap_open.html" target="_top">pcap_open()</a>. The parameters,
  156. <code class="literal">snaplen</code>, <code class="literal">flags</code> and
  157. <code class="literal">to_ms</code> deserve some explanation.</p>
  158. <p><code class="literal">snaplen</code> specifies the portion of the packet to capture. On
  159. some OSes (like xBSD and Win32), the packet driver can be configured to
  160. capture only the initial part of any packet: this decreases the amount of
  161. data to copy to the application and therefore improves the efficiency of
  162. the capture. In this case we use the value 65536 which is higher than the
  163. greatest MTU that we could encounter. In this manner we ensure that the
  164. application will always receive the whole packet.</p>
  165. <p><code class="literal">flags:</code> the most important flag is the one that
  166. indicates if the adapter will be put in promiscuous mode. In normal
  167. operation, an adapter only captures packets from the network that are
  168. destined to it; the packets exchanged by other hosts are therefore
  169. ignored. Instead, when the adapter is in promiscuous mode it captures all
  170. packets whether they are destined to it or not. This means that on shared
  171. media (like non-switched Ethernet), Npcap will be able to capture the
  172. packets of other hosts. Promiscuous mode is the default for most capture
  173. applications, so we enable it in the following example.</p>
  174. <p><code class="literal">to_ms</code> specifies the read timeout, in milliseconds.
  175. A read on the adapter (for example, with <a class="ulink" href="wpcap/pcap_loop.html" target="_top">pcap_dispatch()</a> or <a class="ulink" href="wpcap/pcap_next_ex.html" target="_top">pcap_next_ex()</a>) will always
  176. return after <code class="literal">to_ms</code> milliseconds, even if no packets
  177. are available from the network. <code class="literal">to_ms</code> also defines the
  178. interval between statistical reports if the adapter is in statistical
  179. mode (see the lesson "\ref wpcap_tut9" for information about statistical
  180. mode). Setting <code class="literal">to_ms</code> to 0 means no timeout, a read on
  181. the adapter never returns if no packets arrive. A -1 timeout on the other
  182. side causes a read on the adapter to always return immediately.</p>
  183. <pre class="programlisting">
  184. #include &lt;pcap.h&gt;
  185. #include "misc.h" /* LoadNpcapDlls */
  186. /* prototype of the packet handler */
  187. void packet_handler(
  188. u_char *param,
  189. const struct pcap_pkthdr *header,
  190. const u_char *pkt_data);
  191. int main()
  192. {
  193. pcap_if_t *alldevs;
  194. pcap_if_t *d;
  195. int inum;
  196. int i=0;
  197. pcap_t *adhandle;
  198. char errbuf[PCAP_ERRBUF_SIZE];
  199. /* Load Npcap and its functions. */
  200. if (!LoadNpcapDlls())
  201. {
  202. fprintf(stderr, "Couldn't load Npcap\n");
  203. exit(1);
  204. }
  205. /* Retrieve the device list on the local machine */
  206. if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING,
  207. NULL, &amp;alldevs, errbuf) == -1)
  208. {
  209. fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
  210. exit(1);
  211. }
  212. /* Print the list */
  213. for(d=alldevs; d; d=d-&gt;next)
  214. {
  215. printf("%d. %s", ++i, d-&gt;name);
  216. if (d-&gt;description)
  217. printf(" (%s)\n", d-&gt;description);
  218. else
  219. printf(" (No description available)\n");
  220. }
  221. if(i==0)
  222. {
  223. printf("\nNo interfaces found! Make sure Npcap is installed.\n");
  224. return -1;
  225. }
  226. printf("Enter the interface number (1-%d):",i);
  227. scanf_s("%d", &amp;inum);
  228. if(inum &lt; 1 || inum &gt; i)
  229. {
  230. printf("\nInterface number out of range.\n");
  231. /* Free the device list */
  232. pcap_freealldevs(alldevs);
  233. return -1;
  234. }
  235. /* Jump to the selected adapter */
  236. for(d=alldevs, i=0; i&lt; inum-1 ;d=d-&gt;next, i++);
  237. /* Open the device */
  238. if ( (adhandle= pcap_open(d-&gt;name, // name of the device
  239. 65536, // portion of the packet to capture
  240. // 65536 guarantees that the whole packet will
  241. // be captured on all the link layers
  242. PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
  243. 1000, // read timeout
  244. NULL, // authentication on the remote machine
  245. errbuf // error buffer
  246. ) ) == NULL)
  247. {
  248. fprintf(stderr,
  249. "\nUnable to open the adapter. %s is not supported by Npcap\n",
  250. d-&gt;name);
  251. /* Free the device list */
  252. pcap_freealldevs(alldevs);
  253. return -1;
  254. }
  255. printf("\nlistening on %s...\n", d-&gt;description);
  256. /* At this point, we don't need any more the device list. Free it */
  257. pcap_freealldevs(alldevs);
  258. /* start the capture */
  259. pcap_loop(adhandle, 0, packet_handler, NULL);
  260. return 0;
  261. }
  262. /* Callback function invoked by libpcap for every incoming packet */
  263. void packet_handler(u_char *param,
  264. const struct pcap_pkthdr *header,
  265. const u_char *pkt_data)
  266. {
  267. struct tm ltime;
  268. char timestr[16];
  269. time_t local_tv_sec;
  270. /*
  271. * unused variables
  272. */
  273. (VOID)(param);
  274. (VOID)(pkt_data);
  275. /* convert the timestamp to readable format */
  276. local_tv_sec = header-&gt;ts.tv_sec;
  277. localtime_s(&amp;ltime, &amp;local_tv_sec);
  278. strftime( timestr, sizeof timestr, "%H:%M:%S", &amp;ltime);
  279. printf("%s,%.6d len:%d\n",
  280. timestr, header-&gt;ts.tv_usec, header-&gt;len);
  281. }
  282. </pre>
  283. <p>Once the adapter is opened, the capture can be started with <a class="ulink" href="wpcap/pcap_loop.html" target="_top">pcap_dispatch()</a> or <a class="ulink" href="wpcap/pcap_loop.html" target="_top">pcap_loop()</a>. These two functions are
  284. very similar, the difference is that <code class="literal">pcap_dispatch()</code>
  285. returns (although not guaranteed) when the timeout expires while
  286. <code class="literal">pcap_loop()</code> doesn't return until
  287. <code class="literal">cnt</code> packets have been captured, so it can block for an
  288. arbitrary period on an under-utilized network.
  289. <code class="literal">pcap_loop()</code> is enough for the purpose of this sample,
  290. while <code class="literal">pcap_dispatch()</code> is normally used in a more
  291. complex program.</p>
  292. <p>Both of these functions have a <code class="literal">callback</code> parameter,
  293. <code class="literal">packet_handler</code>, pointing to a function that will
  294. receive the packets. This function is invoked by libpcap for every new
  295. packet coming from the network and receives a generic status
  296. (corresponding to the <code class="literal">user</code> parameter of <a class="ulink" href="wpcap/pcap_loop.html" target="_top">pcap_loop()</a> and <a class="ulink" href="wpcap/pcap_loop.html" target="_top">pcap_dispatch()</a>), a header with some
  297. information on the packet like the timestamp and the length and the
  298. actual data of the packet including all the protocol headers. Note that
  299. the frame CRC is normally not present, because it is removed by the
  300. network adapter after frame validation. Note also that most adapters
  301. discard packets with wrong CRCs, therefore Npcap is normally not able
  302. to capture them.</p>
  303. <p>The above example extracts the timestamp and the length of every
  304. packet from the <code class="literal">pcap_pkthdr</code> header and prints them on
  305. the screen.</p>
  306. <p>Please note that there may be a drawback using <a class="ulink" href="wpcap/pcap_loop.html" target="_top">pcap_loop()</a> mainly related to the
  307. fact that the handler is called by the packet capture driver; therefore
  308. the user application does not have direct control over it. Another
  309. approach (and to have more readable programs) is to use the <a class="ulink" href="wpcap/pcap_next_ex.html" target="_top">pcap_next_ex()</a> function, which is
  310. presented in the next example (<a class="xref" href="npcap-tutorial.html#npcap-tutorial-pcap-next-ex" title="Capturing the packets without the callback">the section called &#8220;Capturing the packets without the callback&#8221;</a>).</p>
  311. </div>
  312. <div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="npcap-tutorial-pcap-next-ex"></a>Capturing the packets without the callback</h3></div></div></div>
  313. <p>The example program in this lesson behaves exactly like the previous
  314. program (<a class="xref" href="npcap-tutorial.html#npcap-tutorial-openadapter" title="Opening an adapter and capturing the packets">the section called &#8220;Opening an adapter and capturing the packets&#8221;</a>), but it uses
  315. <a class="ulink" href="wpcap/pcap_next_ex.html" target="_top">pcap_next_ex()</a> instead of
  316. <a class="ulink" href="wpcap/pcap_loop.html" target="_top">pcap_loop()</a>.</p>
  317. <p>The callback-based capture mechanism of <a class="ulink" href="wpcap/pcap_loop.html" target="_top">pcap_loop()</a> is elegant and it could
  318. be a good choice in some situations. However, handling a callback is
  319. sometimes not practical&#8212;it often makes the program more complex
  320. especially in situations with multithreaded applications or C++
  321. classes.</p>
  322. <p>In these cases, <a class="ulink" href="wpcap/pcap_next_ex.html" target="_top">pcap_next_ex()</a> retrievs a packet
  323. with a direct call&#8212;using <code class="literal">pcap_next_ex()</code>,
  324. packets are received only when the programmer wants them.</p>
  325. <p>The parameters of this function are the same as a capture callback.
  326. It takes an adapter descriptor and a couple of pointers that will be
  327. initialized and returned to the user (one to a
  328. <code class="literal">pcap_pkthdr</code> structure and another to a buffer with the
  329. packet data).</p>
  330. <p>In the following program, we recycle the callback code of the
  331. previous lesson's example and move it inside main() right after the call
  332. to <a class="ulink" href="wpcap/pcap_next_ex.html" target="_top">pcap_next_ex()</a>.</p>
  333. <pre class="programlisting">
  334. /* Open the device */
  335. if ( (adhandle= pcap_open(d-&gt;name, // name of the device
  336. 65536, // portion of the packet to capture.
  337. // 65536 guarantees that the whole packet will
  338. // be captured on all the link layers
  339. PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
  340. 1000, // read timeout
  341. NULL, // authentication on the remote machine
  342. errbuf // error buffer
  343. ) ) == NULL)
  344. {
  345. fprintf(stderr,
  346. "\nUnable to open the adapter. %s is not supported by Npcap\n",
  347. d-&gt;name);
  348. /* Free the device list */
  349. pcap_freealldevs(alldevs);
  350. return -1;
  351. }
  352. printf("\nlistening on %s...\n", d-&gt;description);
  353. /* At this point, we don't need any more the device list. Free it */
  354. pcap_freealldevs(alldevs);
  355. /* Retrieve the packets */
  356. while((res = pcap_next_ex( adhandle, &amp;header, &amp;pkt_data)) &gt;= 0){
  357. if(res == 0)
  358. /* Timeout elapsed */
  359. continue;
  360. /* convert the timestamp to readable format */
  361. local_tv_sec = header-&gt;ts.tv_sec;
  362. localtime_s(&amp;ltime, &amp;local_tv_sec);
  363. strftime( timestr, sizeof timestr, "%H:%M:%S", &amp;ltime);
  364. printf("%s,%.6d len:%d\n", timestr, header-&gt;ts.tv_usec, header-&gt;len);
  365. }
  366. if(res == -1){
  367. printf("Error reading the packets: %s\n", pcap_geterr(adhandle));
  368. return -1;
  369. }
  370. </pre>
  371. <p>Why do we use <a class="ulink" href="wpcap/pcap_next_ex.html" target="_top">pcap_next_ex()</a> instead of the old
  372. <a class="ulink" href="wpcap/pcap_loop.html" target="_top">pcap_next()</a>? Because
  373. <code class="literal">pcap_next()</code> has some drawbacks. First of all, it is
  374. inefficient because it hides the callback method but still relies on
  375. <code class="literal">pcap_dispatch()</code>. Second, it is not able to detect EOF,
  376. so it's not very useful when gathering packets from a file.</p>
  377. <p>Notice also that <code class="literal">pcap_next_ex()</code> returns different
  378. values for success, timeout elapsed, error and EOF conditions.</p>
  379. </div>
  380. <div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="npcap-tutorial-filtering"></a>Filtering the traffic</h3></div></div></div>
  381. <p>One of the most powerful features offered by Npcap (and by libpcap as
  382. well) is the filtering engine. It provides a very efficient way to
  383. receive subsets of the network traffic, and is (usually) integrated with
  384. the capture mechanism provided by Npcap. The functions used to filter
  385. packets are <a class="ulink" href="wpcap/pcap_compile.html" target="_top">pcap_compile()</a>
  386. and <a class="ulink" href="wpcap/pcap_setfilter.html" target="_top">pcap_setfilter()</a>.</p>
  387. <p><a class="ulink" href="wpcap/pcap_compile.html" target="_top">pcap_compile()</a> takes a
  388. string containing a high-level Boolean (filter) expression and produces a
  389. low-level byte code that can be interpreted by the fileter engine in the
  390. packet driver. The syntax of the boolean expression can be found in the
  391. <a class="ulink" href="wpcap/pcap-filter.html" target="_top">Filtering expression syntax</a>
  392. section of this documentation.</p>
  393. <p><a class="ulink" href="wpcap/pcap_setfilter.html" target="_top">pcap_setfilter()</a>
  394. associates a filter with a capture session in the kernel driver. Once
  395. <code class="literal">pcap_setfilter()</code> is called, the associated filter will
  396. be applied to all the packets coming from the network, and all the
  397. conformant packets (i.e., packets for which the Boolean expression
  398. evaluates to true) will be actually copied to the application.</p>
  399. <p>The following code shows how to compile and set a filter. Note that
  400. we must retrieve the netmask from the <code class="literal">pcap_if</code>
  401. structure that describes the adapter, because some filters created by
  402. <code class="literal">pcap_compile()</code> require it.</p>
  403. <p>The filter passed to <code class="literal">pcap_compile()</code> in this code
  404. snippet is "ip and tcp", which means to "keep only the packets that are
  405. both IPv4 and TCP and deliver them to the application".</p>
  406. <pre class="programlisting">
  407. if (d-&gt;addresses != NULL)
  408. /* Retrieve the mask of the first address of the interface */
  409. netmask=((struct sockaddr_in *)(d-&gt;addresses-&gt;netmask))-&gt;sin_addr.S_un.S_addr;
  410. else
  411. /* If the interface is without an address
  412. * we suppose to be in a C class network */
  413. netmask=0xffffff;
  414. //compile the filter
  415. if (pcap_compile(adhandle, &amp;fcode, "ip and tcp", 1, netmask) &lt; 0)
  416. {
  417. fprintf(stderr,
  418. "\nUnable to compile the packet filter. Check the syntax.\n");
  419. /* Free the device list */
  420. pcap_freealldevs(alldevs);
  421. return -1;
  422. }
  423. //set the filter
  424. if (pcap_setfilter(adhandle, &amp;fcode) &lt; 0)
  425. {
  426. fprintf(stderr,"\nError setting the filter.\n");
  427. /* Free the device list */
  428. pcap_freealldevs(alldevs);
  429. return -1;
  430. }
  431. </pre>
  432. <p>If you want to see some code that uses the filtering functions shown
  433. in this lesson, look at the example presented in the next Lesson, <a class="xref" href="npcap-tutorial.html#npcap-tutorial-interpreting" title="Interpreting the packets">the section called &#8220;Interpreting the packets&#8221;</a>.</p>
  434. </div>
  435. <div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="npcap-tutorial-interpreting"></a>Interpreting the packets</h3></div></div></div>
  436. <p>Now that we are able to capture and filter network traffic, we want
  437. to put our knowledge to work with a simple "real world"
  438. application.</p>
  439. <p>In this lesson we will take code from the previous lessons and use
  440. these pieces to build a more useful program. the main purpose of the
  441. current program is to show how the protocol headers of a captured packet
  442. can be parsed and interpreted. The resulting application, called UDPdump,
  443. prints a summary of the UDP traffic on our network.</p>
  444. <p>We have chosen to parse and display the UDP protocol because it is
  445. more accessible than other protocols such as TCP and consequently is an
  446. excellent initial example. Let's look at the code:</p>
  447. <pre class="programlisting">
  448. #include &lt;pcap.h&gt;
  449. #include &lt;Winsock2.h&gt;
  450. #include &lt;tchar.h&gt;
  451. BOOL LoadNpcapDlls()
  452. {
  453. _TCHAR npcap_dir[512];
  454. UINT len;
  455. len = GetSystemDirectory(npcap_dir, 480);
  456. if (!len) {
  457. fprintf(stderr, "Error in GetSystemDirectory: %x", GetLastError());
  458. return FALSE;
  459. }
  460. _tcscat_s(npcap_dir, 512, _T("\\Npcap"));
  461. if (SetDllDirectory(npcap_dir) == 0) {
  462. fprintf(stderr, "Error in SetDllDirectory: %x", GetLastError());
  463. return FALSE;
  464. }
  465. return TRUE;
  466. }
  467. /* 4 bytes IP address */
  468. typedef struct ip_address{
  469. u_char byte1;
  470. u_char byte2;
  471. u_char byte3;
  472. u_char byte4;
  473. }ip_address;
  474. /* IPv4 header */
  475. typedef struct ip_header{
  476. u_char ver_ihl; // Version (4 bits) + IP header length (4 bits)
  477. u_char tos; // Type of service
  478. u_short tlen; // Total length
  479. u_short identification; // Identification
  480. u_short flags_fo; // Flags (3 bits) + Fragment offset (13 bits)
  481. u_char ttl; // Time to live
  482. u_char proto; // Protocol
  483. u_short crc; // Header checksum
  484. ip_address saddr; // Source address
  485. ip_address daddr; // Destination address
  486. u_int op_pad; // Option + Padding
  487. }ip_header;
  488. /* UDP header*/
  489. typedef struct udp_header{
  490. u_short sport; // Source port
  491. u_short dport; // Destination port
  492. u_short len; // Datagram length
  493. u_short crc; // Checksum
  494. }udp_header;
  495. /* prototype of the packet handler */
  496. void packet_handler(u_char *param,
  497. const struct pcap_pkthdr *header,
  498. const u_char *pkt_data);
  499. int main()
  500. {
  501. pcap_if_t *alldevs;
  502. pcap_if_t *d;
  503. int inum;
  504. int i=0;
  505. pcap_t *adhandle;
  506. char errbuf[PCAP_ERRBUF_SIZE];
  507. u_int netmask;
  508. char packet_filter[] = "ip and udp";
  509. struct bpf_program fcode;
  510. /* Load Npcap and its functions. */
  511. if (!LoadNpcapDlls())
  512. {
  513. fprintf(stderr, "Couldn't load Npcap\n");
  514. exit(1);
  515. }
  516. /* Retrieve the device list */
  517. if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING,
  518. NULL, &amp;alldevs, errbuf) == -1)
  519. {
  520. fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
  521. exit(1);
  522. }
  523. /* Print the list */
  524. for(d=alldevs; d; d=d-&gt;next)
  525. {
  526. printf("%d. %s", ++i, d-&gt;name);
  527. if (d-&gt;description)
  528. printf(" (%s)\n", d-&gt;description);
  529. else
  530. printf(" (No description available)\n");
  531. }
  532. if(i==0)
  533. {
  534. printf("\nNo interfaces found! Make sure Npcap is installed.\n");
  535. return -1;
  536. }
  537. printf("Enter the interface number (1-%d):",i);
  538. scanf_s("%d", &amp;inum);
  539. if(inum &lt; 1 || inum &gt; i)
  540. {
  541. printf("\nInterface number out of range.\n");
  542. /* Free the device list */
  543. pcap_freealldevs(alldevs);
  544. return -1;
  545. }
  546. /* Jump to the selected adapter */
  547. for(d=alldevs, i=0; i&lt; inum-1 ;d=d-&gt;next, i++);
  548. /* Open the adapter */
  549. if ( (adhandle= pcap_open(d-&gt;name, // name of the device
  550. 65536, // portion of the packet to capture.
  551. // 65536 grants that the whole packet
  552. // will be captured on all the MACs.
  553. PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
  554. 1000, // read timeout
  555. NULL, // remote authentication
  556. errbuf // error buffer
  557. ) ) == NULL)
  558. {
  559. fprintf(stderr,
  560. "\nUnable to open the adapter. %s is not supported by Npcap\n",
  561. d-&gt;name);
  562. /* Free the device list */
  563. pcap_freealldevs(alldevs);
  564. return -1;
  565. }
  566. /* Check the link layer. We support only Ethernet for simplicity. */
  567. if(pcap_datalink(adhandle) != DLT_EN10MB)
  568. {
  569. fprintf(stderr,"\nThis program works only on Ethernet networks.\n");
  570. /* Free the device list */
  571. pcap_freealldevs(alldevs);
  572. return -1;
  573. }
  574. if(d-&gt;addresses != NULL)
  575. /* Retrieve the mask of the first address of the interface */
  576. netmask=((struct sockaddr_in *)(d-&gt;addresses-&gt;netmask))-&gt;sin_addr.S_un.S_addr;
  577. else
  578. /* If the interface is without addresses
  579. * we suppose to be in a C class network */
  580. netmask=0xffffff;
  581. //compile the filter
  582. if (pcap_compile(adhandle, &amp;fcode, packet_filter, 1, netmask) &lt;0 )
  583. {
  584. fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n");
  585. /* Free the device list */
  586. pcap_freealldevs(alldevs);
  587. return -1;
  588. }
  589. //set the filter
  590. if (pcap_setfilter(adhandle, &amp;fcode)&lt;0)
  591. {
  592. fprintf(stderr,"\nError setting the filter.\n");
  593. /* Free the device list */
  594. pcap_freealldevs(alldevs);
  595. return -1;
  596. }
  597. printf("\nlistening on %s...\n", d-&gt;description);
  598. /* At this point, we don't need any more the device list. Free it */
  599. pcap_freealldevs(alldevs);
  600. /* start the capture */
  601. pcap_loop(adhandle, 0, packet_handler, NULL);
  602. return 0;
  603. }
  604. /* Callback function invoked by libpcap for every incoming packet */
  605. void packet_handler(u_char *param,
  606. const struct pcap_pkthdr *header,
  607. const u_char *pkt_data)
  608. {
  609. struct tm ltime;
  610. char timestr[16];
  611. ip_header *ih;
  612. udp_header *uh;
  613. u_int ip_len;
  614. u_short sport,dport;
  615. time_t local_tv_sec;
  616. /*
  617. * Unused variable
  618. */
  619. (VOID)(param);
  620. /* convert the timestamp to readable format */
  621. local_tv_sec = header-&gt;ts.tv_sec;
  622. localtime_s(&amp;ltime, &amp;local_tv_sec);
  623. strftime( timestr, sizeof timestr, "%H:%M:%S", &amp;ltime);
  624. /* print timestamp and length of the packet */
  625. printf("%s.%.6d len:%d ", timestr, header-&gt;ts.tv_usec, header-&gt;len);
  626. /* retireve the position of the ip header */
  627. ih = (ip_header *) (pkt_data +
  628. 14); //length of ethernet header
  629. /* retireve the position of the udp header */
  630. ip_len = (ih-&gt;ver_ihl &amp; 0xf) * 4;
  631. uh = (udp_header *) ((u_char*)ih + ip_len);
  632. /* convert from network byte order to host byte order */
  633. sport = ntohs( uh-&gt;sport );
  634. dport = ntohs( uh-&gt;dport );
  635. /* print ip addresses and udp ports */
  636. printf("%d.%d.%d.%d.%d -&gt; %d.%d.%d.%d.%d\n",
  637. ih-&gt;saddr.byte1,
  638. ih-&gt;saddr.byte2,
  639. ih-&gt;saddr.byte3,
  640. ih-&gt;saddr.byte4,
  641. sport,
  642. ih-&gt;daddr.byte1,
  643. ih-&gt;daddr.byte2,
  644. ih-&gt;daddr.byte3,
  645. ih-&gt;daddr.byte4,
  646. dport);
  647. }
  648. </pre>
  649. <p>First of all, we set the filter to "ip and udp". In this way we are
  650. sure that packet_handler() will receive only UDP packets over IPv4: this
  651. simplifies the parsing and increases the efficiency of the
  652. program.</p>
  653. <p>We have also created a couple of structs that describe the IP and UDP
  654. headers. These structs are used by packet_handler() to properly locate
  655. the various header fields.</p>
  656. <p>packet_handler(), although limited to a single protocol dissector
  657. (UDP over IPv4), shows how complex "sniffers" like tcpdump/WinDump decode
  658. the network traffic. Since we aren't interested in the MAC header, we
  659. skip it. For simplicity and before starting the capture, we check the MAC
  660. layer with <a class="ulink" href="wpcap/pcap_datalink.html" target="_top">pcap_datalink()</a>
  661. to make sure that we are dealing with an Ethernet network. This way we
  662. can be sure that the MAC header is exactly 14 bytes.</p>
  663. <p>The IP header is located just after the MAC header. We will extract
  664. the IP source and destination addresses from the IP header.</p>
  665. <p>Reaching the UDP header is a bit more complicated, because the IP
  666. header doesn't have a fixed length. Therefore, we use the IP header's
  667. length field to know its size. Once we know the location of the UDP
  668. header, we extract the source and destination ports.</p>
  669. <p>The extracted values are printed on the screen, and the result is
  670. something like:</p>
  671. <pre class="screen">
  672. \Device\Packet_{A7FD048A-5D4B-478E-B3C1-34401AC3B72F} (Xircom t 10/100 Adapter)
  673. Enter the interface number (1-2):1
  674. listening on Xircom CardBus Ethernet 10/100 Adapter...
  675. 16:13:15.312784 len:87 130.192.31.67.2682 -&gt; 130.192.3.21.53
  676. 16:13:15.314796 len:137 130.192.3.21.53 -&gt; 130.192.31.67.2682
  677. 16:13:15.322101 len:78 130.192.31.67.2683 -&gt; 130.192.3.21.53</pre>
  678. <p>Each of the final 3 lines represents a different packet.</p>
  679. </div>
  680. <div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="npcap-tutorial-offline"></a>Handling offline dump files</h3></div></div></div>
  681. <p>In this lession we are going to learn how to handle packet capture to
  682. a file (dump to file). Npcap offers a wide range of functions to save
  683. the network traffic to a file and to read the content of
  684. dumps&#8212;this lesson will teach how to use all of these
  685. functions.</p>
  686. <p>The format for dump files is the libpcap one. This format contains
  687. the data of the captured packets in binary form and is a standard used by
  688. many network tools including WinDump, Wireshark and Snort.</p>
  689. <div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="npcap-tutorial-offline-saving"></a>Saving packets to a dump file</h4></div></div></div>
  690. <p>First of all, let's see how to write packets in libpcap
  691. format.</p>
  692. <p>The following example captures the packets from the selected
  693. interface and saves them on a file whose name is provided by the
  694. user.</p>
  695. <pre class="programlisting">
  696. #include &lt;pcap.h&gt;
  697. #include "misc.h" /* LoadNpcapDlls */
  698. /* prototype of the packet handler */
  699. void packet_handler(u_char *param,
  700. const struct pcap_pkthdr *header,
  701. const u_char *pkt_data);
  702. int main(int argc, char **argv)
  703. {
  704. pcap_if_t *alldevs;
  705. pcap_if_t *d;
  706. int inum;
  707. int i=0;
  708. pcap_t *adhandle;
  709. char errbuf[PCAP_ERRBUF_SIZE];
  710. pcap_dumper_t *dumpfile;
  711. /* Load Npcap and its functions. */
  712. if (!LoadNpcapDlls())
  713. {
  714. fprintf(stderr, "Couldn't load Npcap\n");
  715. exit(1);
  716. }
  717. /* Check command line */
  718. if(argc != 2)
  719. {
  720. printf("usage: %s filename", argv[0]);
  721. return -1;
  722. }
  723. /* Retrieve the device list on the local machine */
  724. if (pcap_findalldevs_ex(PCAP_SRC_IF_STRING,
  725. NULL, &amp;alldevs, errbuf) == -1)
  726. {
  727. fprintf(stderr,"Error in pcap_findalldevs: %s\n", errbuf);
  728. exit(1);
  729. }
  730. /* Print the list */
  731. for(d=alldevs; d; d=d-&gt;next)
  732. {
  733. printf("%d. %s", ++i, d-&gt;name);
  734. if (d-&gt;description)
  735. printf(" (%s)\n", d-&gt;description);
  736. else
  737. printf(" (No description available)\n");
  738. }
  739. if(i==0)
  740. {
  741. printf("\nNo interfaces found! Make sure Npcap is installed.\n");
  742. return -1;
  743. }
  744. printf("Enter the interface number (1-%d):",i);
  745. scanf_s("%d", &amp;inum);
  746. if(inum &lt; 1 || inum &gt; i)
  747. {
  748. printf("\nInterface number out of range.\n");
  749. /* Free the device list */
  750. pcap_freealldevs(alldevs);
  751. return -1;
  752. }
  753. /* Jump to the selected adapter */
  754. for(d=alldevs, i=0; i&lt; inum-1 ;d=d-&gt;next, i++);
  755. /* Open the device */
  756. if ( (adhandle= pcap_open(d-&gt;name, // name of the device
  757. 65536, // portion of the packet to capture
  758. // 65536 guarantees that the whole packet
  759. // will be captured on all the link layers
  760. PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
  761. 1000, // read timeout
  762. NULL, // authentication on the remote machine
  763. errbuf // error buffer
  764. ) ) == NULL)
  765. {
  766. fprintf(stderr,
  767. "\nUnable to open the adapter. %s is not supported by Npcap\n",
  768. d-&gt;name);
  769. /* Free the device list */
  770. pcap_freealldevs(alldevs);
  771. return -1;
  772. }
  773. /* Open the dump file */
  774. dumpfile = pcap_dump_open(adhandle, argv[1]);
  775. if(dumpfile==NULL)
  776. {
  777. fprintf(stderr,"\nError opening output file\n");
  778. return -1;
  779. }
  780. printf("\nlistening on %s... Press Ctrl+C to stop...\n", d-&gt;description);
  781. /* At this point, we no longer need the device list. Free it */
  782. pcap_freealldevs(alldevs);
  783. /* start the capture */
  784. pcap_loop(adhandle, 0, packet_handler, (unsigned char *)dumpfile);
  785. return 0;
  786. }
  787. /* Callback function invoked by libpcap for every incoming packet */
  788. void packet_handler(u_char *dumpfile,
  789. const struct pcap_pkthdr *header,
  790. const u_char *pkt_data)
  791. {
  792. /* save the packet on the dump file */
  793. pcap_dump(dumpfile, header, pkt_data);
  794. }
  795. </pre>
  796. <p>As you can see, the structure of the program is very similar to the
  797. ones we have seen in the previous lessons. The differences
  798. are:</p>
  799. <div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">a call to <a class="ulink" href="wpcap/pcap_dump_open.html" target="_top">pcap_dump_open()</a> is issued
  800. once the interface is opened. This call opens a dump file and
  801. associates it with the interface.</li><li class="listitem">the packets are written to this file with a <a class="ulink" href="wpcap/pcap_dump.html" target="_top">pcap_dump()</a> from the
  802. packet_handler() callback. The parameters of
  803. <code class="literal">pcap_dump()</code> are in 1-1 correspondence with the
  804. parameters of <a class="ulink" href="wpcap/pcap_loop.html" target="_top">pcap_handler()</a>.</li></ul></div>
  805. </div>
  806. <div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="npcap-tutorial-offline-reading"></a>Reading packets from a dump file</h4></div></div></div>
  807. <p>Now that we have a dump file available, we can try to read its
  808. content. The following code opens a Npcap/libpcap dump file and
  809. displays every packet contained in the file. The file is opened with
  810. <a class="ulink" href="wpcap/pcap_open_offline.html" target="_top">pcap_open_offline()</a>,
  811. then the usual <a class="ulink" href="wpcap/pcap_loop.html" target="_top">pcap_loop()</a> is
  812. used to sequence through the packets. As you can see, reading packets
  813. from an offline capture is nearly identical to receiving them from a
  814. physical interface.</p>
  815. <p>This example introduces another function:
  816. <code class="literal">pcap_createsrcstr()</code>. This function is required to
  817. create a source string that begins with a marker used to tell Npcap the
  818. type of the source, e.g. "rpcap://" if we are going to open an adapter,
  819. or "file://" if we are going to open a file. This step is not required
  820. when <code class="literal">pcap_findalldevs_ex()</code> is used (the returned
  821. values already contain these strings). However, it is required in this
  822. example because the name of the file is read from the user
  823. input.</p>
  824. <pre class="programlisting">
  825. #include &lt;stdio.h&gt;
  826. #include &lt;pcap.h&gt;
  827. #include "misc.h" /* LoadNpcapDlls */
  828. #define LINE_LEN 16
  829. void dispatcher_handler(u_char *,
  830. const struct pcap_pkthdr *,
  831. const u_char *);
  832. int main(int argc, char **argv)
  833. {
  834. pcap_t *fp;
  835. char errbuf[PCAP_ERRBUF_SIZE];
  836. char source[PCAP_BUF_SIZE];
  837. /* Load Npcap and its functions. */
  838. if (!LoadNpcapDlls())
  839. {
  840. fprintf(stderr, "Couldn't load Npcap\n");
  841. exit(1);
  842. }
  843. if(argc != 2){
  844. printf("usage: %s filename", argv[0]);
  845. return -1;
  846. }
  847. /* Create the source string according to the new Npcap syntax */
  848. if ( pcap_createsrcstr( source, // variable that will keep the source string
  849. PCAP_SRC_FILE, // we want to open a file
  850. NULL, // remote host
  851. NULL, // port on the remote host
  852. argv[1], // name of the file we want to open
  853. errbuf // error buffer
  854. ) != 0)
  855. {
  856. fprintf(stderr,"\nError creating a source string\n");
  857. return -1;
  858. }
  859. /* Open the capture file */
  860. if ( (fp= pcap_open(source, // name of the device
  861. 65536, // portion of the packet to capture
  862. // 65536 guarantees that the whole packet
  863. // will be captured on all the link layers
  864. PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
  865. 1000, // read timeout
  866. NULL, // authentication on the remote machine
  867. errbuf // error buffer
  868. ) ) == NULL)
  869. {
  870. fprintf(stderr,"\nUnable to open the file %s.\n", source);
  871. return -1;
  872. }
  873. // read and dispatch packets until EOF is reached
  874. pcap_loop(fp, 0, dispatcher_handler, NULL);
  875. return 0;
  876. }
  877. void dispatcher_handler(u_char *temp1,
  878. const struct pcap_pkthdr *header,
  879. const u_char *pkt_data)
  880. {
  881. u_int i=0;
  882. /*
  883. * Unused variable
  884. */
  885. (VOID)temp1;
  886. /* print pkt timestamp and pkt len */
  887. printf("%ld:%ld (%ld)\n", header-&gt;ts.tv_sec, header-&gt;ts.tv_usec, header-&gt;len);
  888. /* Print the packet */
  889. for (i=1; (i &lt; header-&gt;caplen + 1 ) ; i++)
  890. {
  891. printf("%.2x ", pkt_data[i-1]);
  892. if ( (i % LINE_LEN) == 0) printf("\n");
  893. }
  894. printf("\n\n");
  895. }
  896. </pre>
  897. <p>The following example has the same purpose of the last one, but
  898. <a class="ulink" href="wpcap/pcap_next_ex.html" target="_top">pcap_next_ex()</a> is used
  899. instead of the <a class="ulink" href="wpcap/pcap_loop.html" target="_top">pcap_loop()</a>
  900. callback method.</p>
  901. <pre class="programlisting">
  902. #include &lt;stdio.h&gt;
  903. #include &lt;pcap.h&gt;
  904. #include "misc.h" /* LoadNpcapDlls */
  905. #define LINE_LEN 16
  906. int main(int argc, char **argv)
  907. {
  908. pcap_t *fp;
  909. char errbuf[PCAP_ERRBUF_SIZE];
  910. char source[PCAP_BUF_SIZE];
  911. struct pcap_pkthdr *header;
  912. const u_char *pkt_data;
  913. u_int i=0;
  914. int res;
  915. /* Load Npcap and its functions. */
  916. if (!LoadNpcapDlls())
  917. {
  918. fprintf(stderr, "Couldn't load Npcap\n");
  919. exit(1);
  920. }
  921. if(argc != 2)
  922. {
  923. printf("usage: %s filename", argv[0]);
  924. return -1;
  925. }
  926. /* Create the source string according to the new Npcap syntax */
  927. if ( pcap_createsrcstr( source, // variable that will keep the source string
  928. PCAP_SRC_FILE, // we want to open a file
  929. NULL, // remote host
  930. NULL, // port on the remote host
  931. argv[1], // name of the file we want to open
  932. errbuf // error buffer
  933. ) != 0)
  934. {
  935. fprintf(stderr,"\nError creating a source string\n");
  936. return -1;
  937. }
  938. /* Open the capture file */
  939. if ( (fp= pcap_open(source, // name of the device
  940. 65536, // portion of the packet to capture
  941. // 65536 guarantees that the whole packet
  942. // will be captured on all the link layers
  943. PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
  944. 1000, // read timeout
  945. NULL, // authentication on the remote machine
  946. errbuf // error buffer
  947. ) ) == NULL)
  948. {
  949. fprintf(stderr,"\nUnable to open the file %s.\n", source);
  950. return -1;
  951. }
  952. /* Retrieve the packets from the file */
  953. while((res = pcap_next_ex( fp, &amp;header, &amp;pkt_data)) &gt;= 0)
  954. {
  955. /* print pkt timestamp and pkt len */
  956. printf("%ld:%ld (%ld)\n", header-&gt;ts.tv_sec, header-&gt;ts.tv_usec, header-&gt;len);
  957. /* Print the packet */
  958. for (i=1; (i &lt; header-&gt;caplen + 1 ) ; i++)
  959. {
  960. printf("%.2x ", pkt_data[i-1]);
  961. if ( (i % LINE_LEN) == 0) printf("\n");
  962. }
  963. printf("\n\n");
  964. }
  965. if (res == -1)
  966. {
  967. printf("Error reading the packets: %s\n", pcap_geterr(fp));
  968. }
  969. return 0;
  970. }
  971. </pre>
  972. </div>
  973. </div>
  974. <div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="npcap-tutorial-sending"></a>Sending Packets</h3></div></div></div>
  975. <p>Although the name <span class="emphasis"><em>Npcap</em></span> indicates clearly that the purpose
  976. of the library is packet capture, other useful features for raw
  977. networking are provided. Among them, the user can find a complete set of
  978. functions to send packets.</p>
  979. <div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="id582117"></a>Sending a single packet with <code class="literal">pcap_sendpacket()</code></h4></div></div></div>
  980. <p>The simplest way to send a packet is shown in the following code
  981. snippet. After opening an adapter, <a class="ulink" href="wpcap/pcap_inject.html" target="_top">pcap_sendpacket()</a> is called to
  982. send a hand-crafted packet. <code class="literal">pcap_sendpacket()</code> takes
  983. as arguments a buffer containing the data to send, the length of the
  984. buffer and the adapter that will send it. Notice that the buffer is
  985. sent to the net as is, without any manipulation. This means that the
  986. application has to create the correct protocol headers in order to send
  987. something meaningful.</p>
  988. <pre class="programlisting">
  989. #include &lt;stdlib.h&gt;
  990. #include &lt;stdio.h&gt;
  991. #include &lt;pcap.h&gt;
  992. #include "misc.h" /* LoadNpcapDlls */
  993. void main(int argc, char **argv)
  994. {
  995. pcap_t *fp;
  996. char errbuf[PCAP_ERRBUF_SIZE];
  997. u_char packet[100];
  998. int i;
  999. /* Load Npcap and its functions. */
  1000. if (!LoadNpcapDlls())
  1001. {
  1002. fprintf(stderr, "Couldn't load Npcap\n");
  1003. exit(1);
  1004. }
  1005. /* Check the validity of the command line */
  1006. if (argc != 2)
  1007. {
  1008. printf("usage: %s interface (e.g. 'rpcap://eth0')", argv[0]);
  1009. return;
  1010. }
  1011. /* Open the output device */
  1012. if ( (fp= pcap_open(argv[1], // name of the device
  1013. 100, // portion of the packet to capture
  1014. PCAP_OPENFLAG_PROMISCUOUS, // promiscuous mode
  1015. 1000, // read timeout
  1016. NULL, // authentication on the remote machine
  1017. errbuf // error buffer
  1018. ) ) == NULL)
  1019. {
  1020. fprintf(stderr,
  1021. "\nUnable to open the adapter. %s is not supported by Npcap\n",
  1022. argv[1]);
  1023. return;
  1024. }
  1025. /* Supposing to be on ethernet, set mac destination to 1:1:1:1:1:1 */
  1026. packet[0]=1;
  1027. packet[1]=1;
  1028. packet[2]=1;
  1029. packet[3]=1;
  1030. packet[4]=1;
  1031. packet[5]=1;
  1032. /* set mac source to 2:2:2:2:2:2 */
  1033. packet[6]=2;
  1034. packet[7]=2;
  1035. packet[8]=2;
  1036. packet[9]=2;
  1037. packet[10]=2;
  1038. packet[11]=2;
  1039. /* Fill the rest of the packet */
  1040. for(i=12;i&lt;100;i++)
  1041. {
  1042. packet[i]=(u_char)i;
  1043. }
  1044. /* Send down the packet */
  1045. if (pcap_sendpacket(fp, packet, 100 /* size */) != 0)
  1046. {
  1047. fprintf(stderr,"\nError sending the packet: %s\n", pcap_geterr(fp));
  1048. return;
  1049. }
  1050. return;
  1051. }
  1052. </pre>
  1053. </div>
  1054. <div class="sect3"><div class="titlepage"><div><div><h4 class="title"><a name="id582137"></a>Send queues</h4></div></div></div>
  1055. <p>While <a class="ulink" href="wpcap/pcap_inject.html" target="_top">pcap_sendpacket()</a>
  1056. offers a simple and immediate way to send a single packet,
  1057. <span class="emphasis"><em>send queues</em></span> provide an advanced, powerful and
  1058. optimized mechanism to send a collection of packets. A send queue is a
  1059. container for a variable number of packets that will be sent to the
  1060. network. It has a size, that represents the maximum amount of bytes it
  1061. can store.</p>
  1062. <p>A send queue is created calling the
  1063. <code class="literal">pcap_sendqueue_alloc()</code> function, specifying the size
  1064. of the new send queue.</p>
  1065. <p>Once the send queue is created,
  1066. <code class="literal">pcap_sendqueue_queue()</code> can be used to add a packet
  1067. to the send queue. This function takes a <code class="literal">pcap_pkthdr</code>
  1068. with the timestamp and the length and a buffer with the data of the
  1069. packet. These parameters are the same as those received by <a class="ulink" href="wpcap/pcap_next_ex.html" target="_top">pcap_next_ex()</a> and
  1070. <code class="literal">pcap_handler()</code>, therefore queuing a packet that was
  1071. just captured or read from a file is a matter of passing these
  1072. parameters to <code class="literal">pcap_sendqueue_queue()</code>.</p>
  1073. <p>To transmit a send queue, Npcap provides the
  1074. <code class="literal">pcap_sendqueue_transmit()</code> function. Note the third
  1075. parameter: if nonzero, the send will be
  1076. <span class="emphasis"><em>synchronized</em></span>, i.e. the relative timestamps of the
  1077. packets will be respected. This operation requires a remarkable amount
  1078. of CPU, because the synchronization takes place in the kernel driver
  1079. using "busy wait" loops. Although this operation is quite CPU
  1080. intensive, it often results in very high precision packet transmissions
  1081. (often around few microseconds or less).</p>
  1082. <p>Note that transmitting a send queue with
  1083. <code class="literal">pcap_sendqueue_transmit()</code> is much more efficient
  1084. than performing a series of <a class="ulink" href="wpcap/pcap_inject.html" target="_top">pcap_sendpacket()</a>, because the
  1085. send queue is buffered at kernel level drastically decreasing the
  1086. number of context switches.</p>
  1087. <p>When a queue is no longer needed, it can be deleted with
  1088. <code class="literal">pcap_sendqueue_destroy()</code> that frees all the buffers
  1089. associated with the send queue.</p>
  1090. <p>The next program shows how to use send queues. It opens a capture
  1091. file with <a class="ulink" href="wpcap/pcap_open_offline.html" target="_top">pcap_open_offline()</a>, then
  1092. it moves the packets from the file to a properly allocated send queue.
  1093. At his point it transmits the queue, synchronizing it if requested by
  1094. the user.</p>
  1095. <p>Note that the link-layer of the dumpfile is compared with the one
  1096. of the interface that will send the packets using <a class="ulink" href="wpcap/pcap_datalink.html" target="_top">pcap_datalink()</a>, and a warning
  1097. is printed if they are different&#8212;it is important that the
  1098. capture-file link-layer be the same as the adapter's link layer for
  1099. otherwise the transmission is pointless.</p>
  1100. <pre class="programlisting">
  1101. #include &lt;stdlib.h&gt;
  1102. #include &lt;stdio.h&gt;
  1103. #include &lt;pcap.h&gt;
  1104. #ifdef _WIN32
  1105. #include &lt;tchar.h&gt;
  1106. BOOL LoadNpcapDlls()
  1107. {
  1108. TCHAR npcap_dir[512];
  1109. UINT len;
  1110. len = GetSystemDirectory(npcap_dir, 480);
  1111. if (!len) {
  1112. fprintf(stderr, "Error in GetSystemDirectory: %x", GetLastError());
  1113. return FALSE;
  1114. }
  1115. _tcscat_s(npcap_dir, 512, TEXT("\\Npcap"));
  1116. if (SetDllDirectory(npcap_dir) == 0) {
  1117. fprintf(stderr, "Error in SetDllDirectory: %x", GetLastError());
  1118. return FALSE;
  1119. }
  1120. return TRUE;
  1121. }
  1122. #endif
  1123. void usage();
  1124. void main(int argc, char **argv)
  1125. {
  1126. pcap_t *indesc,*outdesc;
  1127. char errbuf[PCAP_ERRBUF_SIZE];
  1128. char source[PCAP_BUF_SIZE];
  1129. FILE *capfile;
  1130. int caplen, sync;
  1131. u_int res;
  1132. pcap_send_queue *squeue;
  1133. struct pcap_pkthdr *pktheader;
  1134. u_char *pktdata;
  1135. float cpu_time;
  1136. u_int npacks = 0;
  1137. errno_t fopen_error;
  1138. #ifdef _WIN32
  1139. /* Load Npcap and its functions. */
  1140. if (!LoadNpcapDlls())
  1141. {
  1142. fprintf(stderr, "Couldn't load Npcap\n");
  1143. exit(1);
  1144. }
  1145. #endif
  1146. /* Check the validity of the command line */
  1147. if (argc &lt;= 2 || argc &gt;= 5)
  1148. {
  1149. usage();
  1150. return;
  1151. }
  1152. /* Retrieve the length of the capture file */
  1153. fopen_error = fopen_s(&amp;capfile, argv[1],"rb");
  1154. if(fopen_error != 0){
  1155. printf("Error opening the file, errno %d.\n", fopen_error);
  1156. return;
  1157. }
  1158. fseek(capfile , 0, SEEK_END);
  1159. caplen= ftell(capfile)- sizeof(struct pcap_file_header);
  1160. fclose(capfile);
  1161. /* Chek if the timestamps must be respected */
  1162. if(argc == 4 &amp;&amp; argv[3][0] == 's')
  1163. sync = TRUE;
  1164. else
  1165. sync = FALSE;
  1166. /* Open the capture */
  1167. /* Create the source string according to the new WinPcap syntax */
  1168. if ( pcap_createsrcstr(
  1169. source, // variable that will keep the source string
  1170. PCAP_SRC_FILE, // we want to open a file
  1171. NULL, // remote host
  1172. NULL, // port on the remote host
  1173. argv[1], // name of the file we want to open
  1174. errbuf // error buffer
  1175. ) != 0)
  1176. {
  1177. fprintf(stderr,"\nError creating a source string\n");
  1178. return;
  1179. }
  1180. /* Open the capture file */
  1181. if ( (indesc= pcap_open(source, 65536, PCAP_OPENFLAG_PROMISCUOUS,
  1182. 1000, NULL, errbuf) ) == NULL)
  1183. {
  1184. fprintf(stderr,"\nUnable to open the file %s.\n", source);
  1185. return;
  1186. }
  1187. /* Open the output adapter */
  1188. if ( (outdesc= pcap_open(argv[2], 100, PCAP_OPENFLAG_PROMISCUOUS,
  1189. 1000, NULL, errbuf) ) == NULL)
  1190. {
  1191. fprintf(stderr,"\nUnable to open adapter %s.\n", source);
  1192. return;
  1193. }
  1194. /* Check the MAC type */
  1195. if (pcap_datalink(indesc) != pcap_datalink(outdesc))
  1196. {
  1197. printf("Warning: the datalink of the capture differs"
  1198. " from the one of the selected interface.\n");
  1199. printf("Press a key to continue, or CTRL+C to stop.\n");
  1200. getchar();
  1201. }
  1202. /* Allocate a send queue */
  1203. squeue = pcap_sendqueue_alloc(caplen);
  1204. /* Fill the queue with the packets from the file */
  1205. while ((res = pcap_next_ex( indesc, &amp;pktheader, &amp;pktdata)) == 1)
  1206. {
  1207. if (pcap_sendqueue_queue(squeue, pktheader, pktdata) == -1)
  1208. {
  1209. printf("Warning: packet buffer too small, not all the packets will be sent.\n");
  1210. break;
  1211. }
  1212. npacks++;
  1213. }
  1214. if (res == -1)
  1215. {
  1216. printf("Corrupted input file.\n");
  1217. pcap_sendqueue_destroy(squeue);
  1218. return;
  1219. }
  1220. /* Transmit the queue */
  1221. cpu_time = (float)clock ();
  1222. if ((res = pcap_sendqueue_transmit(outdesc, squeue, sync)) &lt; squeue-&gt;len)
  1223. {
  1224. printf("An error occurred sending the packets: %s."
  1225. " Only %d bytes were sent\n", pcap_geterr(outdesc), res);
  1226. }
  1227. cpu_time = (clock() - cpu_time)/CLK_TCK;
  1228. printf ("\n\nElapsed time: %5.3f\n", cpu_time);
  1229. printf ("\nTotal packets generated = %d", npacks);
  1230. printf ("\nAverage packets per second = %d", (int)((double)npacks/cpu_time));
  1231. printf ("\n");
  1232. /* free the send queue */
  1233. pcap_sendqueue_destroy(squeue);
  1234. /* Close the input file */
  1235. pcap_close(indesc);
  1236. /*
  1237. * close the output adapter
  1238. * IMPORTANT: remember to close the adapter, otherwise there will be no
  1239. * guarantee that all the packets will be sent!
  1240. */
  1241. pcap_close(outdesc);
  1242. return;
  1243. }
  1244. void usage()
  1245. {
  1246. printf("\nSendcap, sends a libpcap/tcpdump capture file to the net."
  1247. " Copyright (C) 2002 Loris Degioanni.\n");
  1248. printf("\nUsage:\n");
  1249. printf("\t sendcap file_name adapter [s]\n");
  1250. printf("\nParameters:\n");
  1251. printf("\nfile_name: the name of the dump file that will be sent to the network\n");
  1252. printf("\nadapter: the device to use. Use \"WinDump -D\" for a list of valid devices\n");
  1253. printf("\ns: if present, forces the packets to be sent synchronously,"
  1254. " i.e. respecting the timestamps in the dump file.\n\n");
  1255. exit(0);
  1256. }
  1257. </pre>
  1258. </div>
  1259. </div>
  1260. <div class="sect2"><div class="titlepage"><div><div><h3 class="title"><a name="npcap-tutorial-statistics"></a>Gathering Statistics on the network traffic</h3></div></div></div>
  1261. <p>This lesson shows another advanced feature of Npcap: the ability to
  1262. collect statistics about network traffic. The statistical engine makes
  1263. use of the kernel-level packet filter to efficiently classify the
  1264. incoming packet.</p>
  1265. <p>In order to use this feature, the programmer must open an adapter and
  1266. put it in <span class="emphasis"><em>statistical mode</em></span>. This can be done with
  1267. <code class="literal">pcap_setmode()</code>. In particular,
  1268. <code class="literal">MODE_STAT</code> must be used as the <code class="literal">mode</code>
  1269. argument of this function.</p>
  1270. <p>With statistical mode, making an application that monitors the TCP
  1271. traffic load is a matter of few lines of code. The following sample shows
  1272. how to do it.</p>
  1273. <pre class="programlisting">
  1274. #include &lt;stdlib.h&gt;
  1275. #include &lt;stdio.h&gt;
  1276. #include &lt;pcap.h&gt;
  1277. #include &lt;tchar.h&gt;
  1278. BOOL LoadNpcapDlls()
  1279. {
  1280. _TCHAR npcap_dir[512];
  1281. UINT len;
  1282. len = GetSystemDirectory(npcap_dir, 480);
  1283. if (!len) {
  1284. fprintf(stderr, "Error in GetSystemDirectory: %x", GetLastError());
  1285. return FALSE;
  1286. }
  1287. _tcscat_s(npcap_dir, 512, _T("\\Npcap"));
  1288. if (SetDllDirectory(npcap_dir) == 0) {
  1289. fprintf(stderr, "Error in SetDllDirectory: %x", GetLastError());
  1290. return FALSE;
  1291. }
  1292. return TRUE;
  1293. }
  1294. void usage();
  1295. void dispatcher_handler(u_char *, const struct pcap_pkthdr *, const u_char *);
  1296. void main(int argc, char **argv)
  1297. {
  1298. pcap_t *fp;
  1299. char errbuf[PCAP_ERRBUF_SIZE];
  1300. struct timeval st_ts;
  1301. u_int netmask;
  1302. struct bpf_program fcode;
  1303. /* Load Npcap and its functions. */
  1304. if (!LoadNpcapDlls())
  1305. {
  1306. fprintf(stderr, "Couldn't load Npcap\n");
  1307. exit(1);
  1308. }
  1309. /* Check the validity of the command line */
  1310. if (argc != 2)
  1311. {
  1312. usage();
  1313. return;
  1314. }
  1315. /* Open the output adapter */
  1316. if ( (fp= pcap_open(argv[1], 100, PCAP_OPENFLAG_PROMISCUOUS,
  1317. 1000, NULL, errbuf) ) == NULL)
  1318. {
  1319. fprintf(stderr,"\nUnable to open adapter %s.\n", errbuf);
  1320. return;
  1321. }
  1322. /* Don't care about netmask, it won't be used for this filter */
  1323. netmask=0xffffff;
  1324. //compile the filter
  1325. if (pcap_compile(fp, &amp;fcode, "tcp", 1, netmask) &lt;0 )
  1326. {
  1327. fprintf(stderr,"\nUnable to compile the packet filter. Check the syntax.\n");
  1328. /* Free the device list */
  1329. return;
  1330. }
  1331. //set the filter
  1332. if (pcap_setfilter(fp, &amp;fcode)&lt;0)
  1333. {
  1334. fprintf(stderr,"\nError setting the filter.\n");
  1335. pcap_close(fp);
  1336. /* Free the device list */
  1337. return;
  1338. }
  1339. /* Put the interface in statstics mode */
  1340. if (pcap_setmode(fp, MODE_STAT)&lt;0)
  1341. {
  1342. fprintf(stderr,"\nError setting the mode.\n");
  1343. pcap_close(fp);
  1344. /* Free the device list */
  1345. return;
  1346. }
  1347. printf("TCP traffic summary:\n");
  1348. /* Start the main loop */
  1349. pcap_loop(fp, 0, dispatcher_handler, (PUCHAR)&amp;st_ts);
  1350. pcap_close(fp);
  1351. return;
  1352. }
  1353. void dispatcher_handler(u_char *state,
  1354. const struct pcap_pkthdr *header,
  1355. const u_char *pkt_data)
  1356. {
  1357. struct timeval *old_ts = (struct timeval *)state;
  1358. u_int delay;
  1359. LARGE_INTEGER Bps,Pps;
  1360. struct tm ltime;
  1361. char timestr[16];
  1362. time_t local_tv_sec;
  1363. /* Calculate the delay in microseconds from the last sample. This value
  1364. * is obtained from the timestamp that the associated with the sample. */
  1365. delay = (header-&gt;ts.tv_sec - old_ts-&gt;tv_sec) * 1000000
  1366. - old_ts-&gt;tv_usec + header-&gt;ts.tv_usec;
  1367. /* Get the number of Bits per second */
  1368. Bps.QuadPart=(((*(LONGLONG*)(pkt_data + 8)) * 8 * 1000000) / (delay));
  1369. /* ^ ^
  1370. | |
  1371. | |
  1372. | |
  1373. converts bytes in bits -- |
  1374. |
  1375. delay is expressed in microseconds --
  1376. */
  1377. /* Get the number of Packets per second */
  1378. Pps.QuadPart=(((*(LONGLONG*)(pkt_data)) * 1000000) / (delay));
  1379. /* Convert the timestamp to readable format */
  1380. local_tv_sec = header-&gt;ts.tv_sec;
  1381. localtime_s(&amp;ltime, &amp;local_tv_sec);
  1382. strftime( timestr, sizeof timestr, "%H:%M:%S", &amp;ltime);
  1383. /* Print timestamp*/
  1384. printf("%s ", timestr);
  1385. /* Print the samples */
  1386. printf("BPS=%I64u ", Bps.QuadPart);
  1387. printf("PPS=%I64u\n", Pps.QuadPart);
  1388. //store current timestamp
  1389. old_ts-&gt;tv_sec=header-&gt;ts.tv_sec;
  1390. old_ts-&gt;tv_usec=header-&gt;ts.tv_usec;
  1391. }
  1392. void usage()
  1393. {
  1394. printf("\nShows the TCP traffic load, in bits per second and packets per second."
  1395. "\nCopyright (C) 2002 Loris Degioanni.\n");
  1396. printf("\nUsage:\n");
  1397. printf("\t tcptop adapter\n");
  1398. printf("\t You can use \"WinDump -D\" if you don't know the name of your adapters.\n");
  1399. exit(0);
  1400. }
  1401. </pre>
  1402. <p>Before enabling statistical mode, the user has the option to set a
  1403. filter that defines the subset of network traffic that will be monitored.
  1404. See the <a class="ulink" href="wpcap/pcap-filter.html" target="_top">Filtering expression
  1405. syntax</a> documentation for details. If no filter has been set,
  1406. all of the traffic will be monitored.</p>
  1407. <p>Once
  1408. </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem">the filter is set</li><li class="listitem"><code class="literal">pcap_setmode()</code> is called</li><li class="listitem">callback invocation is enabled with <a class="ulink" href="wpcap/pcap_loop.html" target="_top">pcap_loop()</a></li></ul></div><p>
  1409. the interface descriptor starts to work in statistical mode. Notice the
  1410. fourth parameter (<code class="literal">to_ms</code>) of <a class="ulink" href="wpcap/pcap_open.html" target="_top">pcap_open()</a>: it defines the interval
  1411. among the statistical samples. The callback function receives the samples
  1412. calculated by the driver every <code class="literal">to_ms</code> milliseconds.
  1413. These samples are encapsulated in the second and third parameters of the
  1414. callback function.
  1415. Two 64-bit counters are provided: the number of packets and the amount of
  1416. bytes received during the last interval.</p>
  1417. <p>In the example, the adapter is opened with a timeout of 1000 ms. This
  1418. means that dispatcher_handler() is called once per second. At this point
  1419. a filter that keeps only tcp packets is compiled and set. Then
  1420. <code class="literal">pcap_setmode()</code> and <code class="literal">pcap_loop()</code> are
  1421. called. Note that a struct timeval pointer is passed to
  1422. <code class="literal">pcap_loop()</code> as the <code class="literal">user</code> parameter.
  1423. This structure will be used to store a timestamp in order to calculate
  1424. the interval between two samples. dispatcher_handler()uses this interval
  1425. to obtain the bits per second and the packets per second and then prints
  1426. these values on the screen.</p>
  1427. <p>Note finally that this example is by far more efficient than a
  1428. program that captures the packets in the traditional way and calculates
  1429. statistics at user-level. Statistical mode requires the minumum amount of
  1430. data copies and context switches and therefore the CPU is optimized.
  1431. Moreover, a very small amount of memory is required.</p>
  1432. </div>
  1433. </div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="npcap-api.html">Prev</a> </td><td width="20%" align="center"> </td><td width="40%" align="right"> <a accesskey="n" href="npcap-internals.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">The Npcap API </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Npcap internals</td></tr></table></div></body></html>