libpcap 使用(1)

计算机网络自顶向下 一书中,介绍了ethereal。 该软件开源,用于抓包分析。版本最新的更名为wireshark,是目前最好的网络抓包分析工具。ethereal主要使用了gtk+ 和 libpcap来进行设计。gtk +提供用户界面,而libpcap是unix/linux平台下的网络数据包捕获函数包,大多数网络监控软件都以它为基础。Libpcap可以在绝大多数类unix平台下工作,提供了网络监控和包捕获的功能。入侵检测系统及一些网络sniffer都是依靠它来进行的。Libpcap本身是开源的,有时间可以好好学学。

官网:http://www.tcpdump.org, 上面资料丰富。


转一简单介绍:

Who this is for: Allright peeps, this tutorial assumes at least a cursory knowledge in networks in general. For example, what a packet is, how packets are sent, physical vs datalink vs network layers etc. However, I am not assuming any previous knowledge in network programming, just a basic familiarity with c. If you already are a c/c++ master, then you might as well just man 3 pcap so you can skip my annoying writing style. You should have a working c compiler on your system and libpcap installed. We are only going to concern ourselves with Ethernet datalink layer.. so if you are using some funky network card like token ring... then you are on your own as to finding your way around the datalink headers. Finally, all source in this section was written and tested on linux, kernel 2.2.14, while it should be mostly portable (hehe) I can't guarantee that it will compile or run on other operating systems. You are going to want to run as root so be careful and be sure not to break your box in the meantime. Oh, and though I have tested and run all the code presented in this tutorial with no problems, I am NOT responsible if your shit breaks and has to be quarantined by the health department... aka play at your own risk.... (*eerie ghost sound*)

Intro: Well here it is, the beginning of my packet capture tutorial a la libpcap. Inevitably the questions will arise.. "what the hell is packet capture?!" or "Who is libpcap!?" ... so I guess I'll start off by answering these questions...

  • Packet Capture, simply means to "grab packets".
    "Gee thanks Martin :-P"..you blurt.
    No, really, all we are trying to do here is to get access to the underlying facility provided by the operating system so we can grab packets in their raw form. For example, assume your ethercard picks up a packet from the network. Once the packet is handed off to the OS, the OS must determine what type of packet it is, to do so it strips off the Ethernet header of the packet and looks at the next layer. Perhaps it is an ip packet... well the OS must now strip of the IP header and determine which type of IP packet it is. Finally, lets say it is determined that the packet is a UDP packet, the UDP header is stripped off and the packet payload is handed over to the application that the packet is sent for (notice this is an GROSSLY oversimplified version of what really goes on, but I trying to illustrate a point). Packet capture allows us to intercept any packet that is seen by the network device, and grab it in its entirety headers and all! Regardless of which port is being sent to, or even which HOST! for that matter!!!
  • libpcap "provides implementation-independent access to the underlying packet capture facility provided by the operating system" (Stevens, UNP page. 707). So pretty much, libpcap is the library we are going to use to grab packets from the network card directly. Let me quickly note that there are other ways of doing this, including BPF (Berkeley Packet Filter), DLPI (Data Link Provider Interface) and SOCKET_PACKET type sockets (Linux only).

Getting Started Well there is an awful lot to cover.. so lets just get familiar with libpcap. Like I stated before, all the code in this section is assuming that you are sitting on an Ethernet. If this is not the case, then the tutorial basics are still pertinent, but the code presented later on involving decoding the Ethernet header obviously isn't :-( *sorry*. Allright... crack your knuckles *crunch* and lets get ready to code our FIRST LIBPCAP PROGRAM!!!!. Go ahead and copy the following program into your favorite editor (which should be vim if you have any sense :-) save, and compile with...

%>gcc ldev.c -lpcap


/* ldev.c
Martin Casado

To compile:
>gcc ldev.c -lpcap

Looks for an interface, and lists the network ip
and mask associated with that interface.
*/
#include <stdio.h>
#include <stdlib.h>
#include <pcap.h> /* GIMME a libpcap plz! */
#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
int main(int argc, char **argv)
{
char *dev; /* name of the device to use */
char *net; /* dot notation of the network address */
char *mask;/* dot notation of the network mask */
int ret; /* return code */
char errbuf[PCAP_ERRBUF_SIZE];
bpf_u_int32 netp; /* ip */
bpf_u_int32 maskp;/* subnet mask */
struct in_addr addr;

/* ask pcap to find a valid device for use to sniff on */
dev = pcap_lookupdev(errbuf);

/* error checking */
if(dev == NULL)
{
printf("%s\n",errbuf);
exit(1);
}

/* print out device name */
printf("DEV: %s\n",dev);

/* ask pcap for the network address and mask of the device */
ret = pcap_lookupnet(dev,&netp,&maskp,errbuf);

if(ret == -1)
{
printf("%s\n",errbuf);
exit(1);
}

/* get the network address in a human readable form */
addr.s_addr = netp;
net = inet_ntoa(addr);

if(net == NULL)/* thanks Scott :-P */
{
perror("inet_ntoa");
exit(1);
}

printf("NET: %s\n",net);

/* do the same as above for the device's mask */
addr.s_addr = maskp;
mask = inet_ntoa(addr);

if(mask == NULL)
{
perror("inet_ntoa");
exit(1);
}

printf("MASK: %s\n",mask);

return 0;
}

Did you run the program? If not, run it :-) Assuming it compiled, and ran correctly your output should be something like...

DEV: eth0
NET: 192.168.12.0
MASK: 255.255.255.0

Now if your DEV is not eth0, or eth1 or eth followed by some number then we are going to have problems because this document is geared toward sniffing ethernet packets. Obviously the NET and MASK numbers will be different than the ones I posted, however the actual values are not important to this discussion.

"So what did we just do?", you ask. Well, we just asked libpcap to give us some specs on an interface to listen on.
"Whats an interface?"
Just think of an interface as your computers hardware connection to whatever network your computer is connected to. In Unix, eth0 denotes the first ethernet card in your computer this is the network interface that I am going to use to demonstrate libpcap. All you really have to be concerned with right now is that we grabbed the device name "eth0", since this is what we have to pass to libpcap to tell where to grab packets from. The NET and MASK are simply the network number and mask associated with the card which are for informative purposes only. There are much better ways to enumerate and list the specifications of the system interfaces than going through libpcap which I'll hopefully write about someday :-).

Allright, by now you should know how to write, run and compile a libpcap program, grab the name of the interface card we are going to capture packets from, and have a basic understanding of what we are doing. Next, we'll grab our very first packet.. WohoO!!!


你可能感兴趣的:(C++,.net,linux,OS,C#)