ExamplesProgramThe functions and effects are very similar to those described above (enable the adapter and capture data packets). However, this document uses the pcap_next_ex () function to replace the pcap_loop () function mentioned above.
The pcap_loop () function captures data based on the callback principle. It is a subtle method and is a good choice in some scenarios. However, processing callback is sometimes not practical-it increases the complexity of the program, especially in a multi-threaded C ++ program.
You can call the pcap_next_ex () function directly to obtain a data packet. Only when the programmer uses the pcap_next_ex () function can the data packet be received.
The parameters of this function are the same as those of the capture callback function-it contains a network adapter Descriptor and two pointers that can be initialized and returned to the user (one pointing to the pcap_pkthdr struct, another buffer pointing to the datagram data ).
In the following program, we will use the callbackCodeBut we put it into the main () function, and then call the pcap_next_ex () function.
Code
# Include " Pcap. h "
Main ()
{
Pcap_if_t * Alldevs;
Pcap_if_t * D;
Int Inum;
Int I = 0 ;
Pcap_t * Adhandle;
Int Res;
Char Errbuf [pcap_errbuf_size];
Struct TM * Ltime;
Char Timestr [ 16 ];
Struct Pcap_pkthdr * Header;
Const U_char * Pkt_data;
Time_t local_ TV _sec;
/* Get the list of local devices */
If (Pcap_findalldevs_ex (pcap_src_if_string, null, & Alldevs, errbuf) = - 1 )
{
Fprintf (stderr, " Error in pcap_findalldevs: % s \ n " , Errbuf );
Exit ( 1 );
}
/* Print list */
For (D = Alldevs; D; d = D -> Next)
{
Printf ( " % D. % s " , ++ I, d -> Name );
If (D -> Description)
Printf ( " (% S) \ n " , D -> Description );
Else
Printf ( " (No description available) \ n " );
}
If (I = 0 )
{
Printf ( " \ Nno interfaces found! Make sure Winpcap is installed. \ n " );
Return - 1 ;
}
Printf ( " Enter the interface number (1-% d ): " , I );
Scanf ( " % D " , & Inum );
If (Inum < 1 | Inum > I)
{
Printf ( " \ Ninterface number out of range. \ n " );
/* Release Device List */
Pcap_freealldevs (alldevs );
Return - 1 ;
}
/* Jump to the selected Adapter */
For (D = Alldevs, I = 0 ; I < Inum - 1 ; D = D -> Next, I ++ );
/* Enable the device */
If (Adhandle = Pcap_open (d -> Name, // Device Name
65536 , // Part of the data packet to be captured
// 65535 ensure that all contents of each data packet on different data link layers can be captured
Pcap_openflag_promiscuous, // Hybrid mode
1000 , // Read timeout
Null, // Remote machine Verification
Errbuf // Error Buffer Pool
)) = Null)
{
Fprintf (stderr, " \ Nunable to open the adapter. % s is not supported by Winpcap \ n " , D -> Name );
/* Release settings list */
Pcap_freealldevs (alldevs );
Return - 1 ;
}
Printf ( " \ Nlistening on % s... \ n " , D -> Description );
/* Release Device List */
Pcap_freealldevs (alldevs );
/* Get data packets */
While (Res = Pcap_next_ex (adhandle, & Header, & Pkt_data )) > = 0 ){
If (Res = 0 )
/* Timeout time */
Continue ;
/* Converts a timestamp to a recognizable format */
Local_ TV _sec = Header -> TS. TV _sec;
Ltime = Localtime ( & Local_ TV _sec );
Strftime (timestr, Sizeof Timestr, " % H: % m: % s " , Ltime );
Printf ( " % S, %. 6D Len: % d \ n " , Timestr, Header -> TS. TV _usec, Header -> Len );
}
If (Res = - 1 ){
Printf ( " Error reading the packets: % s \ n " , Pcap_geterr (adhandle ));
Return - 1 ;
}
Return 0 ;
}
Why should we use pcap_next_ex () instead of the previous pcap_next ()? Because pcap_next () has some disadvantages. First, it is inefficient. Although it hides the callback method, it still depends on the pcap_dispatch () function (). Second, it cannot detect the state (EOF) at the end of the file. Therefore, if the data packet is read from the file, it is not so useful.
It is worth noting that pcap_next_ex () returns different values when it is successful, time-out, error, or EOF.
Author: the Winpcap team home: http://www.winpcap.org