123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- /* $Id: libpcap.c 767 2004-10-06 12:48:49Z aturner $ */
- /*
- * Copyright (c) 2001-2004 Aaron Turner, Matt Bing.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the names of the copyright owners nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
- * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- #include "config.h"
- #include <stdio.h>
- #include <unistd.h>
- #include <sys/types.h>
- #include "capinfo.h"
- #include "libpcap.h"
- #include "err.h"
- #include "fakepcap.h"
- /* state of the current pcap file */
- struct pcap_file_header phdr;
- int modified;
- int swapped;
- /* return flag if this is a pcap file */
- int
- is_pcap(int fd)
- {
- if (lseek(fd, SEEK_SET, 0) != 0) {
- err(1, "Unable to seek to start of file");
- }
- if (read(fd, (void *)&phdr, sizeof(phdr)) != sizeof(phdr))
- return 0;
- switch (phdr.magic) {
- case PCAP_MAGIC:
- swapped = 0;
- modified = 0;
- break;
- case PCAP_SWAPPED_MAGIC:
- swapped = 1;
- modified = 0;
- break;
- case PCAP_MODIFIED_MAGIC:
- swapped = 0;
- modified = 1;
- break;
- case PCAP_SWAPPED_MODIFIED_MAGIC:
- swapped = 1;
- modified = 1;
- break;
- default:
- return 0;
- }
- /* ensure everything is in host-byte order */
- if (swapped) {
- phdr.version_major = SWAPSHORT(phdr.version_major);
- phdr.version_minor = SWAPSHORT(phdr.version_minor);
- phdr.snaplen = SWAPLONG(phdr.snaplen);
- phdr.linktype = SWAPLONG(phdr.linktype);
- }
- /* version, snaplen, & linktype magic */
- if (phdr.version_major != 2)
- return 0;
- return 1;
- }
- int
- get_next_pcap(int fd, struct packet *pkt)
- {
- struct pcap_pkthdr p1, *p;
- struct pcap_mod_pkthdr p2;
- if (modified) {
- if (read(fd, &p2, sizeof(p2)) != sizeof(p2))
- return 0;
- p = &p2.hdr;
- }
- else {
- if (read(fd, &p1, sizeof(p1)) != sizeof(p1))
- return 0;
- p = &p1;
- }
- if (swapped) {
- pkt->len = SWAPLONG(p->caplen);
- pkt->ts.tv_sec = SWAPLONG(p->ts.tv_sec);
- pkt->ts.tv_usec = SWAPLONG(p->ts.tv_usec);
- pkt->actual_len = SWAPLONG(p->len);
- }
- else {
- pkt->len = p->caplen;
- pkt->ts = p->ts;
- pkt->actual_len = p->len;
- }
- if (read(fd, &pkt->data, pkt->len) != pkt->len)
- return 0;
- return pkt->len;
- }
- /*
- * Print statistics about a pcap file. is_pcap() must be called first
- * to read the pcap header.
- */
- void
- stat_pcap(int fd, struct pcap_info *p)
- {
- struct packet pkt;
- char *endian[2];
- #ifdef LIBNET_LIL_ENDIAN
- endian[0] = "little endian";
- endian[1] = "big endian";
- #else
- endian[0] = "big endian";
- endian[1] = "little endian";
- #endif
- p->modified = modified;
- p->swapped = swapped ? endian[1] : endian[0];
- p->phdr = phdr;
- p->linktype = pcap_datalink_val_to_description(phdr.linktype);
- p->bytes = p->trunc = 0;
- for (p->cnt = 0; get_next_pcap(fd, &pkt); p->cnt++) {
- /* grab time of the first packet */
- if (p->cnt == 0)
- TIMEVAL_TO_TIMESPEC(&pkt.ts, &p->start_tm);
- /* count p->truncated packets */
- p->bytes += pkt.len;
- if (pkt.actual_len > phdr.snaplen)
- p->trunc++;
- }
- /* grab time of the last packet */
- TIMEVAL_TO_TIMESPEC(&pkt.ts, &p->finish_tm);
- }
|