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
    ",errbuf);
    exit(1);
    }

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

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

    if(ret == -1)
    {
    printf("%s
    ",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
    ",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
    ",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: eth0NET: 192.168.12.0MASK: 255.255.255.0Now 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!!!