130 lines
3.5 KiB
C
130 lines
3.5 KiB
C
#include <stdio.h>
|
|
#include <time.h>
|
|
#include <pcap.h>
|
|
#include <netinet/in.h>
|
|
#include <netinet/if_ether.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
|
|
unsigned char *fp_file;
|
|
unsigned char *if_name;
|
|
unsigned char *pcap_file_name;
|
|
unsigned char *bpf_string;
|
|
|
|
int processed_packet;
|
|
|
|
void usage(void) {
|
|
fprintf(stderr,
|
|
"Usage: osfp_match [ ...options... ] [ 'filter rule' ]\n"
|
|
"\n"
|
|
"Network interface options:\n"
|
|
"\n"
|
|
" -i iface - listen on the specified network interface\n"
|
|
" -r file - read offline pcap data from a given file\n"
|
|
" -f file - read fingerprint database from 'file' (%s)\n"
|
|
);
|
|
exit(1);
|
|
}
|
|
|
|
void process_packet(char *user, struct pcap_pkthdr *h, u_char *pkt)
|
|
{
|
|
printf("packet count %d\n", ++processed_packet);
|
|
}
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
int r;
|
|
|
|
while ((r = getopt(argc, argv, "+f:i:r")) != -1) {
|
|
switch(r) {
|
|
case 'f':
|
|
if (fp_file) {
|
|
printf("Multiple -f options not supported.\n");
|
|
exit(1);
|
|
}
|
|
fp_file = (unsigned char*)optarg;
|
|
break;
|
|
case 'i':
|
|
if (if_name) {
|
|
printf("Multiple -i options not supported.\n");
|
|
exit(1);
|
|
}
|
|
if_name = (unsigned char*)optarg;
|
|
break;
|
|
case 'r':
|
|
if (pcap_file_name) {
|
|
printf("Multiple -r options not supported.\n");
|
|
exit(1);
|
|
}
|
|
pcap_file_name = (unsigned char*)optarg;
|
|
break;
|
|
default:
|
|
usage();
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (optind < argc) {
|
|
if (optind + 1 == argc) {
|
|
bpf_string = argv[optind];
|
|
} else {
|
|
printf("Filter rule must be a single parameter (use quotes).\n");
|
|
exit(1);
|
|
}
|
|
}
|
|
|
|
// prepare pcap handle
|
|
|
|
char pcap_err[PCAP_ERRBUF_SIZE];
|
|
pcap_t *pcap_handle;
|
|
|
|
if (pcap_file_name) {
|
|
if (access((char*)pcap_file_name, R_OK)) {
|
|
printf("No such file: %s\n", pcap_file_name);
|
|
exit(1);
|
|
}
|
|
pcap_handle = pcap_open_offline((char*)pcap_file_name, pcap_err);
|
|
if (pcap_handle == NULL ) {
|
|
printf("Pcap file open failed. File name: %s, Err: %s\n", pcap_file_name, pcap_err);
|
|
exit(1);
|
|
}
|
|
} else if (if_name) {
|
|
pcap_handle = pcap_open_live((char*)if_name, 65535, 1, 5, pcap_err);
|
|
if (pcap_handle == NULL) {
|
|
printf("Pcap live open failed. Interface name: %s, Err: %s\n", if_name, pcap_err);
|
|
exit(1);
|
|
}
|
|
} else {
|
|
usage();
|
|
}
|
|
|
|
// setup bpf filter
|
|
if (bpf_string) {
|
|
struct bpf_program bpf_filter;
|
|
|
|
if (pcap_compile(pcap_handle, &bpf_filter, bpf_string, 1, 0) < 0) {
|
|
printf("bpf compilation error %s", pcap_geterr(pcap_handle));
|
|
exit(1);
|
|
}
|
|
|
|
if (pcap_setfilter(pcap_handle, &bpf_filter) < 0) {
|
|
printf("could not set bpf filter %s", pcap_geterr(pcap_handle));
|
|
pcap_freecode(&bpf_filter);
|
|
exit(1);
|
|
}
|
|
pcap_freecode(&bpf_filter);
|
|
}
|
|
|
|
// loop
|
|
while (1) {
|
|
int r = pcap_dispatch(pcap_handle, 0, (pcap_handler)process_packet, NULL);
|
|
if (r < 0) {
|
|
printf("error code: %d, error: %s\n", r, pcap_geterr(pcap_handle));
|
|
break;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|