Libpcap steps (2) Simple packet capture implementation.

Source: Internet
Author: User
Tags types of functions

A simple process of packet capture using libpcap:
1. Obtain the device name: pcap_findalldevs. list all devices. Select the network devices to be listed and find them in the linked list. After obtaining the device name, release the linked list.
Or directly exist in the string
2. Use the device name pcap_open_live to open the device (another function is pcap_open_dead, which is slightly odd)

3. pcap_loop starts to capture packets. The hybrid mode is not used here. (The second parameter is 0)

4. Use the callback function to process captured data packets. This is written directly in pcap_loop. The imported data does not need to be free.

Note:

In fact, C is the most appropriate language in Linux. However, the phase between libpcap and C ++ is also good, without any pitfalls.

Originally, this program is pure C (So scanf/printf is available). In order to streamline it, I used the lambda function and changed it to C ++.

Revision 3: Try to use getopt_long to process command line parameters. If "% 02x" is used, Hex can be output correctly, and the preceding value is 0. I never expected to add 0 in the previous step. The output is the super complex function written by myself =. Removed the display device name and changed it to-I or -- iface. So it is still compressed to 50 rows.

# Include "iostream" # include "ctime" # include "cstdlib" # include "cstring" # include "getopt. H "# ifndef _ use_bsd # DEFINE _ use_bsd # endif # include <sys/types. h> // u_short types # include "pcap. H "# define STR _ (x) x // solves the format processing problem in C ++ # define debug (format ,...) fprintf (stderr, "% s: % d:" str _ (Format) "\ n", _ file __, _ line __, ##__ va_args __) # define assert _ (expr _, extra_op) do {If (! (Expr _) {debug ("in the function '% s': asserted error:" # expr _, _ function _); \ extra_op; exit (-1) ;}}while (0) # define pcap_try (func _) assert _ (func _! =-1, debug ("message: % s", errbuf) # define pcap_ptr_try (func _) assert _ (func _)! = 0, debug ("message: % s", errbuf) using namespace STD; static char Buf [10000], errbuf [10000]; // optionsoption options [] = {// Long Options {"iface", required_argument, 0, 'I'},}; // global argschar * ifname; int main (INT argc, char ** argv) {char OPT; while (-1! = (OPT = getopt_long (argc, argv, "I:", options, 0) {Switch (OPT) {Case 'I': ifname = optarg; break ;}} pcap_t * hdev; pcap_ptr_try (hdev = pcap_open_live (ifname, 0 xFFFF, 0, 1000, errbuf); debug ("START capture on % s... ", ifname); pcap_loop (hdev, 0, [Buf] (u_char * Param, const struct pcap_pkthdr * Header, const u_char * Data) {strftime (BUF, sizeof (BUF ), "% H: % m: % s", localtime (& header-> TS. TV _sec); debug ("% s, %. 6D us, Len: % d ", Buf, header-> TS. TV _usec, header-> Len); For (INT I = 0; I 

Run:

$ sudo ./capture -i eth0capture.cpp:41: Start capture on eth0...capture.cpp:45: 14:30:31,550031 us, len:12100-1e-c9-37-c8-10-a0-21-b7-ae-3e-fa-08-00-45-00-00-6b-05-8f-40-00-7b-06-49-ac-de-14-fc-cf-c0-a8-14-c5-0d-3d-a0-76-4a-89-f9-09-74-d1-8b-50-80-18-01-01-5c-22-00-00-01-01-08-0a-00-1f-1c-a0-00-15-f4-a0-80-37-86-6a-4c-a9-3a-b3-65-94-f1-92-a7-ed-0e-bd-0a-f6-4c-48-6d-75-8e-88-4f-7a-33-e4-99-1d-54-f1-ab-53-44-64-72-9c-8d-34-45-4b-53-04-69-f8-fd-9e-a7-74-f6-e1-ca-e9-adcapture.cpp:45: 14:30:31,550702 us, len:66a0-21-b7-ae-3e-fa-00-1e-c9-37-c8-10-08-00-45-00-00-34-34-bb-40-00-40-06-55-b7-c0-a8-14-c5-de-14-fc-cf-a0-76-0d-3d-74-d1-8b-50-4a-89-f9-40-80-10-39-f3-b0-78-00-00-01-01-08-0a-00-15-f4-b9-00-1f-1c-a0

Revision 2: The "# format" error in the macro definition is modified. See the note after the old version of the program at the end of the article.

# Include <cstdio> # include <cstdlib> # include <ctime> # ifndef _ use_bsd # DEFINE _ use_bsd # endif # include <sys/types. h> // u_short types # include "pcap. H "# define STR _ (x) x // solves the format processing problem in C ++ # define debug (format ,...) fprintf (stderr, "% s: % d:" str _ (Format) "\ n", _ file __, _ line __, ##__ va_args __) # define assert _ (expr _, extra_op) do {If (! (Expr _) {debug ("in the function '% s': asserted error:" # expr _, _ function _); \ extra_op; exit (-1) ;}}while (0) # define pcap_try (func _) assert _ (func _! =-1, debug ("message: % s", errbuf) # define pcap_ptr_try (func _) assert _ (func _)! = 0, debug ("message: % s", errbuf) Static char Buf [10000], errbuf [10000]; int main () {int I = 0, devid; pcap_t * hdev; pcap_if_t * alldevs, * pdev; // get device listpcap_try (pcap_findalldevs (& alldevs, errbuf); For (pdev = alldevs; pdev; pdev = pdev-> next) printf ("# % d: % S % s \ n", ++ I, pdev-> name, pdev-> description? Pdev-> Description: ""); // select deviceprintf ("select a device:"); scanf ("% d", & devid); pdev = alldevs; while (-- devid) pdev = pdev-> next; printf ("Selected % s", pdev-> name); // open devicepcap_ptr_try (hdev = pcap_open_live (pdev-> name, 0 xFFFF, 0, 1000, errbuf); debug ("START capture on % s... ", pdev-> name); // free device listpcap_freealldevs (alldevs); // start capturepcap_loop (hdev, 0, [Buf] (u_char * Param, const struct pcap_pkthdr * Header, const u_char * Data) {/* converts the timestamp to a readable standard format */strftime (BUF, sizeof (BUF), "% H: % m: % s ", localtime (& header-> TS. TV _sec); debug ("% s, %. 6D us, Len: % d ", Buf, header-> TS. TV _usec, header-> Len) ;}, 0); Return 0 ;}

Run: sudo run

Viktor @ buxiang-OptiPlex-330 :~ /Proj/pcap $ sudo. /capture #1: peth0 #2: eth0 #3: USB mon1 USB Bus Number 1 #4: USB mon2 USB Bus Number 2 #5: USB mon3 USB Bus Number 3 #6: USB mon4 USB Bus Number 4 #7: USB mon5 USB Bus Number 5 #8: Any pseudo-device that captures on all interfaces #9: Lo select a device: 2capture_short.cpp: 42: start capture on B... // wipe memory capture_assist.cpp: 46: 09:35:39, 720743 us, Len: 79capture_assist.cpp: 46: 09:35:39, 721226 us, Len: 66capture_assist.cpp: 46: 09:35:39, 829933 us, Len: 79capture_assist.cpp: 46: 09:35:39, 830169 us, Len: 66capture_assist.cpp: 46: 09:35:39, 853439 us, Len: 60capture_assist.cpp: 46: 09:35:39, 939339 us, Len: 79

Related parts of yesterday's Program (Rev1:

# Define debug (format ,...) fprintf (stderr, "% s: % d:" # format "\ n", _ file __, _ line __, ##__va_args __) # define assert _ (expr _, extra_op) do {If (! (Expr _) {debug ("in the function '% s': asserted error:" # expr _, _ function _); \ extra_op; exit (-1) ;}}while (0) # define pcap_assert (func _) assert _ (func _! =-1, debug ("message: % s", errbuf) # define pcap_ptr_assert (func _) assert _ (func _)! = 0, debug ("message: % s", errbuf ))

There is a problem in macro definition:

fprintf(stderr, "%s:%d: " #format "\n", __FILE__, __LINE__, ##__VA_ARGS__)

If "% s: % d:" format "\ n" is written here, C compilation is normal (this is what I wrote in the first C code ), however, G ++ reports an error: Undefined string literal override (operator "" Format)

It seems that the feature "Custom literal suffix" for C ++ 0x is triggered, for example, 356f and 356adk -- it seems that I have identified the prepared connection as a literal ["% s: % d: "format]

If it is written as "% s: % d:" # format (that is, the above), a bunch of quotation marks will be added during output, which is ugly.

If it is written as # format, it will connect "% s: % d:" format into an identifier. It is still incorrect.

Note: The correct modification method is

#define str_(x) x#define Debug(format, ...) fprintf(stderr, "%s:%d: " str_(format) "\n", __FILE__, __LINE__, ##__VA_ARGS__)

Use a macro to set it up to avoid parse at the same time.

The number is reduced to 50 rows. I can only write 50 lines of valid code a day ......

Note: The macros of the above Code should be called try instead of assert.

If it is assert, you should set "! =-1 "this judgment condition is written in the call, so that the read program is clearer, like this

pcap_assert(func != -1)

However, I am writing a statement to replace the following:

retvar = func(...);if (retvar == -1){  fprintf(stderr, "error message!\n");  exit(-1)}

My statement:

pcap_try(func(...));

So to handle different error value ranges of different types of functions (for example, =-1 and = NULL are used here), I want to define different types of macros. It is for the convenience of calling.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.