Projects/Software/TunTapIO/pcap.c
Jump to navigation
Jump to search
/**********************************************************************
* rsfio - filtered raw socket to stdin/out proxy *
* Written by: Ivo Smits <Ivo@UFO-Net.nl> *
* *
* Compile using: gcc pcap.c -o lpcio -lpcap *
* *
* Many thanks to: *
* - http://www.blug.linux.no/rfc1149/ *
* - http://linux.about.com/od/commands/l/blcmdl2_select.htm *
* - http://www.linuxjournal.com/article/4659 *
* - http://www.tcpdump.org/pcap.htm *
* - http://www.winpcap.org/docs/man/html/ *
* - http://www.tcpdump.org/lists/workers/2005/06/msg00102.html *
* *
**********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#ifndef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
#include <sys/ioctl.h>
#include <errno.h>
#include <dirent.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netpacket/packet.h>
#include <netinet/in.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <linux/types.h>
#include <linux/filter.h>
#include <linux/if_ether.h>
#include <pcap.h>
int DumpStats = 1;
int IncludePLen = 1;
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet);
// The main program, this is where all the magic happens
int main(int argc, char** argv) {
//Parse command line arguments
if (argc > 1) {
if (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0) {
fprintf(stderr, "rsio - raw socket to stdio proxy\n");
fprintf(stderr, "Usage: %s INTF [CLEN] [FILTR]\n", argv[0]);
fprintf(stderr, " INTF: the name of the network interface to connect to\n");
fprintf(stderr, " CLEN: capture size (should be the same as the mtu, default: %d)\n", ETH_FRAME_LEN);
fprintf(stderr, " FILTR: tcpdump style filter expression (man tcpdump)\n");
fprintf(stderr, "Note that the arguments should be in exactly THIS order.\n");
fprintf(stderr, "Report bugs to <Ivo@UFO-Net.nl>\n");
exit(0);
}
} else {
//Application won't run without arguments
//fprintf(stderr, "Try: %s -h\n", argv[0]);
//exit(1);
}
int CaptureLen = ETH_FRAME_LEN;
//Different capture length?
if (argc > 2) CaptureLen = atoi(argv[2]);
if (CaptureLen < 1) {
fprintf(stderr, "Capture length %d invalid!\n", CaptureLen);
exit(1);
}
fprintf(stderr, "Max packet length: %d\n", CaptureLen);
char *dev, errbuf[PCAP_ERRBUF_SIZE];
if (argc > 1) {
dev = argv[1];
} else {
if ((dev = pcap_lookupdev(errbuf)) == NULL) {
fprintf(stderr, "Couldn't find default device: %s\n", errbuf);
exit(1);
}
}
fprintf(stderr, "Device: %s\n", dev);
pcap_t *pcap;
if ((pcap = pcap_open_live(dev, CaptureLen, 1, 0, errbuf)) == NULL) {
fprintf(stderr, "Couldn't open device: %s\n", errbuf);
exit(1);
}
if (argc > 3) {
fprintf(stderr, "Filter: %s\n", argv[3]);
struct bpf_program *bpfprog;
if (pcap_compile(pcap, &bpfprog, argv[3], 0, 0) == -1) {
fprintf(stderr, "Couldn't compile filter: %s\n", pcap_geterr(pcap));
exit(1);
}
if (pcap_setfilter(pcap, &bpfprog) == -1) {
fprintf(stderr, "Couldn't install filter: %s\n", pcap_geterr(pcap));
exit(1);
}
}
fprintf(stderr, "Starting capture!\n");
pcap_loop(pcap, -1, got_packet, NULL);
fprintf(stderr, "PCap finished: shutting down!\n");
pcap_close(pcap);
}
void got_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *packet) {
if (DumpStats != 0) fprintf(stderr, "R: %d\n", header->caplen);
if (IncludePLen == 1) write(1, &header->caplen, 4);
write(1, packet, header->caplen);
}