diff options
-rw-r--r-- | pcap2tzsp.c | 79 |
1 files changed, 66 insertions, 13 deletions
diff --git a/pcap2tzsp.c b/pcap2tzsp.c index 701944c..e548ed9 100644 --- a/pcap2tzsp.c +++ b/pcap2tzsp.c @@ -1,8 +1,12 @@ +/* Library dependencies : + libpcap (sudo apt-get install libpcap0.8-dev) +*/ /* Basics */ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <signal.h> /* Args parsing and basename() for usage */ #include <getopt.h> @@ -19,13 +23,15 @@ #include <pcap.h> #include <sys/time.h> +/* Time management (for bwlimit) */ +#include <time.h> + +/* Option default values (as strings) */ #define DEFAULT_FILTER "not ( icmp[icmptype]=icmp-unreach or (udp and dst %s and port %s) )" #define DEFAULT_HOST "127.0.0.1" #define DEFAULT_PORT "37008" #define DEFAULT_SNAPLEN "70" -/* 70 bytes captured packets will to sent in ~128 bytes frames when encapsulated */ -#define UDP_SEND_BUFLEN 1500 /* MAX_TZSP_PAYLOAD is for not trying to send TZSP packets greater than the interface MTU MAX_TZSP_PAYLOAD = MTU - IP header - UDP header - TZSP header I am assuming the following : @@ -33,12 +39,15 @@ - MTU is assumed to be 1500 for now */ #define MAX_TZSP_PAYLOAD (1500-20-8-16) +#define UDP_SEND_BUFLEN 1500 #define MIN_BYTES_TO_CAPTURE 16 #define MAX_BYTES_TO_CAPTURE (1500-20-8-16) /* TODO List + * Crash at exit if no -i supplied + * TZSP TAGPACKET_COUNT field * Resolution DNS host -> IP (c'est l'ip qu'il faut dans le filtre et pas le host !!) * Stats nombre de packets loupés ? * Implémenter une bwlimit en sortie (ptks/s et/ou bytes/s) @@ -57,7 +66,8 @@ void process_packet(u_char *void_args, const struct pcap_pkthdr* pkthdr, const u /* Custom types definition */ typedef struct _process_packet_args { - uint64_t pkt_count; + uint64_t captured_pkt_count; + uint64_t sent_pkt_count; int udp_socket; struct sockaddr_in udp_sockaddr; } process_packet_args_t; @@ -74,6 +84,7 @@ static char *opt_host=NULL; static char *opt_port=NULL; static char *opt_snaplen=NULL; +pcap_t *pcap_handle = NULL; void usage(char progname[]) { printf("Usage : %s [--verbose] [--brief] [-i <iface>] [-h <host>] [-p <port>] [custom_pcap_filter]\n", progname); @@ -84,6 +95,22 @@ void usage(char progname[]) { exit(1); } +void sig_handler(int signo) { + static int pcap_break=0; + + switch (signo) { + case SIGINT: + if (pcap_break==0) { + pcap_break=1; + //fprintf(stderr, "DEBUG : pcap_breakloop(pcap_handle);\n"); + pcap_breakloop(pcap_handle); + } + break; + default: + fprintf(stderr, "Catched an unhandled signal : %i\n", signo); + } +} + int main(int argc, char *argv[]) { /* Command line args parsing */ @@ -170,6 +197,7 @@ int main(int argc, char *argv[]) { //printf ("Capture filter will be : '%s' (pcap_filter_len-j==%i)\n", pcap_filter, pcap_filter_len-j); + signal(SIGINT, sig_handler); /* Run the capture loop */ capture_loop(pcap_filter); @@ -186,10 +214,12 @@ int main(int argc, char *argv[]) { void capture_loop(char pcap_filter[]) { - pcap_t *pcap_handle = NULL; + //Global for signal handling + //pcap_t *pcap_handle = NULL; static char *pcap_device=NULL; char pcap_errbuf[PCAP_ERRBUF_SIZE]; struct bpf_program pcap_filter_prog; + struct pcap_stat stat; process_packet_args_t process_packet_args; int snaplen; @@ -213,7 +243,7 @@ void capture_loop(char pcap_filter[]) { exit(12); } - //Already done : memset((char *) &(process_packet_args.udp_sockaddr), 0, sockaddr_len); + /* Already done : memset((char *) &(process_packet_args.udp_sockaddr), 0, sockaddr_len); */ process_packet_args.udp_sockaddr.sin_family = AF_INET; process_packet_args.udp_sockaddr.sin_port = htons(atoi(opt_port)); if (inet_aton(opt_host, &(process_packet_args.udp_sockaddr.sin_addr))==0) { @@ -253,13 +283,23 @@ void capture_loop(char pcap_filter[]) { exit(10); } - /* Loop forever & call process_packet() for every received packet*/ + /* Loop forever & call process_packet() for every received packet */ /* For valgrind tests : if ( pcap_loop(pcap_handle, 1000000, process_packet, (u_char *)&process_packet_args) == -1){ */ if ( pcap_loop(pcap_handle, -1, process_packet, (u_char *)&process_packet_args) == -1) { fprintf(stderr, "ERROR: %s\n", pcap_geterr(pcap_handle) ); exit(25); } + fprintf(stderr, "\n%llu packets captured\n%llu TZSP packets sent\n", + process_packet_args.captured_pkt_count, process_packet_args.sent_pkt_count); + + if (pcap_stats(pcap_handle, &stat) == -1) { + fprintf(stderr, "ERROR: %s\n", pcap_geterr(pcap_handle) ); + exit(26); + } + fprintf(stderr, "%u packets received by filter\n%u packets dropped by kernel\n", + stat.ps_recv, stat.ps_drop); + pcap_close(pcap_handle); close(process_packet_args.udp_socket); } @@ -271,7 +311,7 @@ void capture_loop(char pcap_filter[]) { void process_packet(u_char *void_args, const struct pcap_pkthdr* pkthdr, const u_char * packet) { static time_t old_tv_sec=0; - static uint64_t old_pkt_count=0; + static uint64_t old_captured_pkt_count=0; int res; double throughput; @@ -279,21 +319,26 @@ void process_packet(u_char *void_args, const struct pcap_pkthdr* pkthdr, const u uint32_t ts; /* In network byte order */ uint16_t len; /* In network byte order */ char buf[UDP_SEND_BUFLEN]; + /* struct timespec ts_reqsleep; For simulation */ process_packet_args_t *args=(process_packet_args_t *)void_args; - /* Packet counting and displaying (max once by second) */ - args->pkt_count++; + /* Catpured packet counting and displaying (max once by second) */ + args->captured_pkt_count++; if (old_tv_sec != pkthdr->ts.tv_sec) { - //printf("DEBUG : throughput=((double) %llu - %llu ) / ( %u - %u )\n", args->pkt_count, old_pkt_count, pkthdr->ts.tv_sec, old_tv_sec); - throughput=((double) args->pkt_count - old_pkt_count ) / (pkthdr->ts.tv_sec - old_tv_sec); - printf("\rPacket Count: %20llu (%8.1f pkt/s)", args->pkt_count, throughput); + /*printf("DEBUG : throughput=((double) %llu - %llu ) / ( %u - %u )\n", + args->captured_pkt_count, old_captured_pkt_count, pkthdr->ts.tv_sec, old_tv_sec); + */ + throughput=((double) args->captured_pkt_count - old_captured_pkt_count ) / (pkthdr->ts.tv_sec - old_tv_sec); + printf("\rPacket Count: %20llu (%8.1f pkt/s)", args->captured_pkt_count, throughput); fflush(stdout); old_tv_sec=pkthdr->ts.tv_sec; - old_pkt_count= args->pkt_count; + old_captured_pkt_count= args->captured_pkt_count; } + //TODO : bwlimit HERE (not before, no after) + /* Variable fields for TZSP packet */ ts=htonl((uint32_t) pkthdr->ts.tv_sec); /* TODO : this cast is bullshit ? */ len=htons((uint16_t) pkthdr->len); @@ -327,6 +372,14 @@ void process_packet(u_char *void_args, const struct pcap_pkthdr* pkthdr, const u res=sendto(args->udp_socket, buf, 16+pkthdr->caplen, 0, (struct sockaddr *)&(args->udp_sockaddr), sockaddr_len); if (res==-1) { fprintf(stderr, "sendto() error\n"); + } else { + args->sent_pkt_count++; } + + /* Slow sending simulation + ts_reqsleep.tv_sec=0; + ts_reqsleep.tv_nsec=10000; + nanosleep(&ts_reqsleep, NULL); + */ } |