summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrediano Ziglio <fziglio@redhat.com>2016-10-09 13:55:35 +0100
committerFrediano Ziglio <fziglio@redhat.com>2016-10-09 13:55:35 +0100
commitdfb61498187a2d4e8db3c65c218ed95d69b5f9a7 (patch)
treef2fb02e6ccdf6e58af604f31a9c83e8b2857bd94
parenteb67f87f7b7012572dbd2ed91ec3cb66aa3d85b0 (diff)
Allow to use a capture file to record packets
Signed-off-by: Frediano Ziglio <fziglio@redhat.com>
-rw-r--r--tun.c34
-rw-r--r--tun.h2
2 files changed, 35 insertions, 1 deletions
diff --git a/tun.c b/tun.c
index 2e9c645..e36d8f5 100644
--- a/tun.c
+++ b/tun.c
@@ -25,6 +25,7 @@
#include "tun.h"
#include "latency.h"
#include "utils.h"
+#include "pcap.h"
static int tun_fd = -1;
static int tun_fd_back = -1;
@@ -32,6 +33,9 @@ static int remote_sock = -1;
static struct sockaddr_in remote_addr;
static bool remote_connected = false;
static bool is_server = false;
+static pcap_file *pcap = NULL;
+
+const char *tun_log_filename = NULL;
/* Fake packets are used to send commands.
* A fake packet has a ip header with 0 check, saddr and daddr fields
@@ -210,6 +214,7 @@ tun_set_server(int port)
static pthread_mutex_t pkt_buf_mtx = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t pkt_cond_write = PTHREAD_COND_INITIALIZER;
static pthread_cond_t pkt_cond_read = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t log_mtx = PTHREAD_MUTEX_INITIALIZER;
typedef struct packet {
struct packet *next;
@@ -320,6 +325,16 @@ release_packet(packet_t *pkt)
free(pkt);
}
+static void
+log_write_ip(const void *raw_ip, size_t len)
+{
+ if (!pcap)
+ return;
+ pthread_mutex_lock(&log_mtx);
+ pcap_write_ip(pcap, raw_ip, len);
+ pthread_mutex_unlock(&log_mtx);
+}
+
static void*
writer_proc(void *ptr)
{
@@ -334,6 +349,8 @@ writer_proc(void *ptr)
sendto(remote_sock, pkt->data, pkt->len, MSG_NOSIGNAL,
&remote_addr, sizeof(remote_addr));
} else {
+ if (pkt->dest_tun == tun_fd)
+ log_write_ip(pkt->data, pkt->len);
write(pkt->dest_tun, pkt->data, pkt->len);
}
release_packet(pkt);
@@ -450,6 +467,14 @@ handle_tun(void)
bytes2time_ratio = (double) 1000000.0 / rate_bytes;
+ if (tun_log_filename) {
+ pcap = pcap_open(tun_log_filename);
+ if (!pcap) {
+ perror("error opening log file");
+ exit(EXIT_FAILURE);
+ }
+ }
+
pthread_create(&writer, NULL, writer_proc, NULL);
uint64_t old_time = get_time_us();
@@ -487,8 +512,10 @@ handle_tun(void)
remote_connected = true;
if (len < sizeof(struct iphdr))
continue;
- if (!handle_fake_packet(pkt->data, len))
+ if (!handle_fake_packet(pkt->data, len)) {
+ log_write_ip(pkt->data, pkt->len);
write(tun_fd, pkt->data, len);
+ }
}
if ((fds[1].revents & POLLIN) != 0 && tun_fd_back >= 0) {
@@ -507,6 +534,9 @@ handle_tun(void)
break;
pkt->len = len;
+ if (pkt->dest_tun == tun_fd_back)
+ log_write_ip(pkt->data, pkt->len);
+
struct iphdr *ip = (struct iphdr *) pkt->data;
if (ip->version != IPVERSION)
continue;
@@ -566,4 +596,6 @@ handle_tun(void)
/* wait writer termination */
pthread_join(writer, NULL);
+
+ pcap_close(pcap);
}
diff --git a/tun.h b/tun.h
index 28d90bc..207266f 100644
--- a/tun.h
+++ b/tun.h
@@ -1,5 +1,7 @@
#include <stdbool.h>
+extern const char *tun_log_filename;
+
void tun_setup(bool local_mode);
void tun_set_client(const char *ip, int port);
void tun_set_server(int port);