summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Pouzenc <ludovic@pouzenc.fr>2012-10-21 07:59:54 +0000
committerLudovic Pouzenc <ludovic@pouzenc.fr>2012-10-21 07:59:54 +0000
commitbc947900ab280adc5bb8f46214436c9b51d0ba5f (patch)
tree5fedefe8ed23192a46a1cbca858f4fa8512fd682
parent65dcddc76d50230e2f8f209131724ae97ef7b4d3 (diff)
download2012-tzsp-bc947900ab280adc5bb8f46214436c9b51d0ba5f.tar.gz
2012-tzsp-bc947900ab280adc5bb8f46214436c9b51d0ba5f.tar.bz2
2012-tzsp-bc947900ab280adc5bb8f46214436c9b51d0ba5f.zip
Signal handling and statistics at exit
git-svn-id: file:///var/svn/2012-tzsp/trunk@7 147d2d3d-d0bd-48ea-923a-d90ac20f5906
-rw-r--r--pcap2tzsp.c79
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);
+ */
}