> I'd like to generate pcap format capture files,
> on a system that hasn't a raw socket api.

Note that a raw socket API is not a requirement for libpcap.  BSD
systems don't use the raw socket API for packet capture, they use
another mechanism; the same applies to systems using a System V-style
DLPI mechanism.

> we have another api with which we can 
> capture raw frames, one I'd like to try 
> hacking into a variant of lipcap. 

What OS is this?  (If it has "Windows" in the name, note that there *is*
a port of libpcap to Windows 9x/ME and NT/2000/XP:

        http://netgroup-serv.polito.it/winpcap/

.)

> (10mb ethernet, is all we're concerned with at the moment)

Note that libpcap handles *all* flavors of Ethernet in the same fashion.
The "10MB" in "DLT_EN10MB" is just a historical artifact from the days
when there were 3 megabit experimental Ethernet (DLT_EN3MB) and 10
megabit Ethernet (DLT_EN10MB); it does *NOT* indicate that DLT_EN10MB
can be used only for 10 megabit Ethernet.  The only reason why libpcap
distinguishes between 3Mb and 10Mb Ethernet is that 3Mb Ethernet had a
different link-layer header from 10Mb Ethernet; 100Mb, 1Gb, and 10Gb
Ethernet all have exactly the same link-layer header (as seen by hosts)
as 10Mb Ethernet, so DLT_EN10MB is what is used for all flavors of
Ethernet (other than the 3Mb experimental Ethernet).

> I'm a bit fuzzy on the best place to 
> start (pcap_next(), and on up?). 

No.

"pcap_open_live()"/"pcap_read()", and on down.

The platform-dependent parts of packet capturing in libpcap are in the
"pcap-XXX.c" files, e.g. "pcap-bpf.c", "pcap-dlpi.c", etc..

The interfaces exported by those files are:

    "pcap_open_live()":

        takes a "char *" device name, a snapshot length, a "promiscuous
        mode" flag, a buffering timeout, and a pointer to an error
        buffer.

        The device name specifies the interface on which you're trying
        to capture.  That routine should open that device using whatever
        raw packet capture API your system supplies, and fill in the
        "pcap_t" as appropriate.

        The snapshot length is a length to which to truncate received
        packets; if a program isn't interested in the entire packet,
        trimming the data may, on some platforms, save CPU time by
        copying less data from the OS kernel to userland.  On at least
        some of those platforms, the packet capture API supplied by the
        system lets you set a "snapshot length" to do that.  Note that
        if your capture API supports such a mechanism, but rejects
        attempts to set the snapshot length larger than the maximum
        packet size, you should hide that from applications using
        libpcap by arranging that too-large snapshot lengths be
        truncated to the maximum allowed (as applications might, for
        example, use a large snapshot length as a way of saying "show me
        the entire packet).

        The promiscuous mode flag is 1 if the application wants to
        capture in promiscuous mode and 0 if it doesn't.

        The timeout is for use with packet capture APIs that can specify
        that packets shouldn't be delivered immediately to the
        application, but that the capture mechanism should wait some
        amount of time, in the hopes of supplying more than one packet
        to the application.  There is no requirement that the timer
        start as soon as an application tries to read packets; it can
        start as soon as the first packet is read (that's how the
        timeout works in Solaris, for example).  I.e., there is no
        requirement that this timer expire even if no packets have
        arrived (it doesn't do so on Solaris, for example).  It can be
        ignored if the packet capture API doesn't offer such a
        mechanism.

    "pcap_read()":

        takes as an argument a "pcap_t *", a count, a
        pointer to a "pcap_handler" routine, and a "u_char" pointer that
        should be handed to the "pcap_handler" routine.

        "pcap_read()" should read from the "pcap_t" using whatever API
        your system supplies and, for each packet it reads (and that
        passes the packet filter), call the callback routine, supplying
        it, as arguments:

                the "u_char" pointer;

                a pointer to a "struct pcap_pkthdr" containing:

                        a UNIX-style "struct timeval" giving a packet
                        time stamp, with microsecond resolution (not
                        nanosecond, please);

                        the length of packet data being supplied (which
                        may have been cut short by the snapshot length);

                        the length of the packet on the wire (which may
                        include data not supplied, due to the snapshot
                        length cutting the packet short);

                a pointer to the raw packet data.

        "pcap_read" shouldn't read more than one bufferful of packets. 
        If "cnt" is greater than 0, it should supply to the application
        no more than that number of packets, *and*, if a bufferful of
        packets contains more than one packet, should arrange that a
        subsequent call, if any, return the first of the packets *not*
        supplied.

        "pcap_read()" should return the number of packets supplied.

    "pcap_setfilter()":

        takes as an argument a "pcap_t *" and a "struct bpf_program *",
        and sets the packet filter code for the "pcap_t" to the
        specified program.

        If the packet capture API supports BPF-style packet filtering,
        this should set the filter.

        If the packet capture API doesn't support BPF-style packet
        filtering, the filtering will have to be done in user mode by
        "pcap_read()"; packets that don't pass the filter should not be
        supplied to the application.  See "pcap-snoop.c" for an example
        of how that's done on systems where the API doesn't support BPF.

    "pcap_stats()":

        takes as an argument a "pcap_t *" and a "struct pcap_stat *",
        and supplies packet capture statistics, if possible.  Return -1
        and set "p->errbuf" to an error message if it's not possible.

Some additional routines you might need to modify:

    "pcap_getnonblock()" and "pcap_setnonblock()" - if your OS isn't a
    UNIX-style OS with UNIX-style non-blocking I/O, or it is but your
    packet capture API doesn't use a UNIX-style file descriptor or
    doesn't support UNIX-style non-blocking I/O on that descriptor,
    *but* it can support non-blocking I/O (i.e., if an attempt to read
    packets can be made to return a "no packets available now, try again
    later" indication rather than blocking until packets are available),
    those routines should be made to, on your platform, call a
    platform-dependent routine to set non-blocking I/O and get the
    current blocking/non-blocking state.

    In non-blocking mode, "pcap_read()" should return 0 if a "no packets
    available now, try again later" indication is returned.

    "pcap_findalldevs()", "pcap_lookupdev()", "pcap_lookupnet()" - if
    the standard UNIX mechanisms to get lists of interfaces and
    addresses for those interfaces can't be used on your system, but
    another mechanism can, versions of those routines that use that
    mechanism should be provided.
-
This is the TCPDUMP workers list. It is archived at
http://www.tcpdump.org/lists/workers/index.html
To unsubscribe use mailto:[EMAIL PROTECTED]?body=unsubscribe

Reply via email to