summaryrefslogtreecommitdiff
path: root/gsm-tvoid
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2008-11-27 08:35:42 +0530
committerHarald Welte <laforge@gnumonks.org>2008-11-27 08:35:42 +0530
commit6c274198ad9ed182545125fb6bfde2a99114cc0a (patch)
tree2326727068ef0c3412915d2b0a485a6ecec89ed3 /gsm-tvoid
parenteb13897566ab93c56462b327b75bfd8eb317abc9 (diff)
Add PCAP (LINKTYPE GSM incl. gsmtap hdr) support
Diffstat (limited to 'gsm-tvoid')
-rw-r--r--gsm-tvoid/src/lib/Makefile.am7
-rw-r--r--gsm-tvoid/src/lib/gsmstack.c19
-rw-r--r--gsm-tvoid/src/lib/gsmstack.h2
-rw-r--r--gsm-tvoid/src/lib/gsmtap.h26
-rw-r--r--gsm-tvoid/src/lib/out_pcap.c105
-rw-r--r--gsm-tvoid/src/lib/out_pcap.h7
6 files changed, 162 insertions, 4 deletions
diff --git a/gsm-tvoid/src/lib/Makefile.am b/gsm-tvoid/src/lib/Makefile.am
index d8d504f..4f2ba65 100644
--- a/gsm-tvoid/src/lib/Makefile.am
+++ b/gsm-tvoid/src/lib/Makefile.am
@@ -51,7 +51,8 @@ _gsm_la_SOURCES = \
mm_f.cc \
gsm_burst_cf.cc \
gsm_burst_sink_c.cc \
- tun.c
+ tun.c \
+ out_pcap.c
# magic flags
@@ -82,7 +83,9 @@ grinclude_HEADERS = \
gsm_burst_cf.h \
gsm_burst_sink_c.h \
gsm_constants.h \
- tun.h
+ tun.h \
+ out_pcap.h \
+ gsmtap.h
# These swig headers get installed in ${prefix}/include/gnuradio/swig
diff --git a/gsm-tvoid/src/lib/gsmstack.c b/gsm-tvoid/src/lib/gsmstack.c
index ecea4f9..e09420c 100644
--- a/gsm-tvoid/src/lib/gsmstack.c
+++ b/gsm-tvoid/src/lib/gsmstack.c
@@ -5,6 +5,7 @@
#include "system.h"
#include <stdlib.h>
#include <stdio.h>
+#include <errno.h>
#include <string.h>
#include "gsmstack.h"
#include "gsm_constants.h"
@@ -12,6 +13,8 @@
#include "sch.h"
#include "cch.h"
+#include "out_pcap.h"
+
static void out_gsmdecode(char type, int arfcn, int ts, int fn, char *data, int len);
#if 0
@@ -46,9 +49,14 @@ GS_new(GS_CTX *ctx)
interleave_init(&ctx->interleave_ctx, 456, 114);
ctx->fn = -1;
ctx->bsic = -1;
+
ctx->tun_fd = mktun("gsm", ctx->ether_addr);
if (ctx->tun_fd < 0)
- return -1;
+ fprintf(stderr, "cannot open 'gsm' tun device, did you create it?\n");
+
+ ctx->pcap_fd = open_pcap_file("tvoid.pcap");
+ if (ctx->pcap_fd < 0)
+ fprintf(stderr, "cannot open PCAP file: %s\n", strerror(errno));
return 0;
}
@@ -65,8 +73,14 @@ GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src)
unsigned char *data;
int len;
- if (ts != 0)
+ if (ts != 0) {
+ /* non-0 timeslots should end up in PCAP */
+ data = decode_cch(ctx, ctx->burst, &len);
+ if (data == NULL)
+ return -1;
+ write_pcap_packet(ctx->pcap_fd, 0 /* arfcn */, ts, 0, data, len);
return;
+ }
if (type == SCH)
{
@@ -111,6 +125,7 @@ GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src)
out_gsmdecode(0, 0, ts, ctx->fn - 4, data, len);
write_interface(ctx->tun_fd, data+1, len-1, ctx->ether_addr);
+ write_pcap_packet(ctx->pcap_fd, 0 /* arfcn */, ts, fn, data, len);
#if 0
if (ctx->fn % 51 != 0) && ( (((ctx->fn % 51 + 5) % 10 == 0) || (((ctx->fn % 51) + 1) % 10 ==0) ) )
ready = 1;
diff --git a/gsm-tvoid/src/lib/gsmstack.h b/gsm-tvoid/src/lib/gsmstack.h
index 8230442..b4a5c96 100644
--- a/gsm-tvoid/src/lib/gsmstack.h
+++ b/gsm-tvoid/src/lib/gsmstack.h
@@ -23,6 +23,8 @@ typedef struct
int tun_fd;
unsigned char ether_addr[ETH_ALEN];
+
+ int pcap_fd;
} GS_CTX;
int GS_new(GS_CTX *ctx);
diff --git a/gsm-tvoid/src/lib/gsmtap.h b/gsm-tvoid/src/lib/gsmtap.h
new file mode 100644
index 0000000..6676d9a
--- /dev/null
+++ b/gsm-tvoid/src/lib/gsmtap.h
@@ -0,0 +1,26 @@
+#ifndef _GSMTAP_H
+#define _GSMTAP_H
+
+/* gsmtap header, pseudo-header in front of the actua GSM payload*/
+
+#include <sys/types.h>
+
+#define GSMTAP_VERSION 0x02
+
+#define GSMTAP_TYPE_UM 0x01
+#define GSMTAP_TYPE_ABIS 0x02
+
+struct gsmtap_hdr {
+ u_int8_t version; /* version, set to 0x01 currently */
+ u_int8_t hdr_len; /* length in number of 32bit words */
+ u_int8_t type; /* see GSMTAP_TYPE_* */
+ u_int8_t timeslot; /* timeslot (0..7 on Um) */
+
+ u_int16_t arfcn; /* ARFCN (frequency) */
+ u_int8_t noise_db;
+ u_int8_t signal_db;
+
+ u_int32_t frame_number;
+
+} __attribute__((packed));
+#endif /* _GSMTAP_H */
diff --git a/gsm-tvoid/src/lib/out_pcap.c b/gsm-tvoid/src/lib/out_pcap.c
new file mode 100644
index 0000000..95f24f5
--- /dev/null
+++ b/gsm-tvoid/src/lib/out_pcap.c
@@ -0,0 +1,105 @@
+/* PCAP support for gsm-tvoid
+ * (C) 2008 by Harald Welte <laforge@gnumonks.org>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <pcap.h>
+#include <errno.h>
+#include <time.h>
+
+#include "out_pcap.h"
+#include "gsmtap.h"
+
+#ifndef LINKTYPE_GSMTAP
+#define LINKTYPE_GSMTAP 2342
+#endif
+
+#define TCPDUMP_MAGIC 0xa1b2c3d4
+
+struct pcap_timeval {
+ int32_t tv_sec;
+ int32_t tv_usec;
+};
+
+struct pcap_sf_pkthdr {
+ struct pcap_timeval ts; /* time stamp */
+ u_int32_t caplen; /* lenght of portion present */
+ u_int32_t len; /* length of this packet */
+};
+
+static int write_pcap_file_header(int fd)
+{
+ struct pcap_file_header pfh;
+
+ pfh.magic = TCPDUMP_MAGIC;
+ pfh.version_major = PCAP_VERSION_MAJOR;
+ pfh.version_minor = PCAP_VERSION_MINOR;
+ pfh.thiszone = timezone;
+ pfh.sigfigs = 0;
+ pfh.snaplen = 1024; /* FIXME */
+ pfh.linktype = LINKTYPE_GSMTAP;
+
+ if (write(fd, &pfh, sizeof(pfh)) < sizeof(pfh))
+ return -1;
+
+ return 0;
+}
+
+/* open pcap file and write header */
+int open_pcap_file(char *fname)
+{
+ int fd;
+ int rc;
+
+ fd = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0660);
+ if (fd < 0)
+ return fd;
+
+ rc = write_pcap_file_header(fd);
+ if (rc < 0) {
+ close(fd);
+ fd = -EIO;
+ }
+
+ return fd;
+}
+
+int write_pcap_packet(int fd, int arfcn, int ts, int fn,
+ char *data, unsigned int len)
+{
+ unsigned char buf[8192];
+ struct pcap_sf_pkthdr *ph;
+ struct gsmtap_hdr *gh;
+ struct timeval tv;
+ int rc;
+
+ printf("writing pcap packet fd=%d len=%d\n", fd, len);
+
+ ph = (struct pcap_sf_pkthdr *) &buf[0];
+ gh = (struct gsmtap_hdr *) &buf[sizeof(struct pcap_sf_pkthdr)];
+
+ gettimeofday(&tv, NULL);
+
+ ph->ts.tv_sec = tv.tv_sec;
+ ph->ts.tv_usec = tv.tv_usec;
+ ph->caplen = ph->len = len + sizeof(struct gsmtap_hdr);
+
+ gh->version = GSMTAP_VERSION;
+ gh->hdr_len = sizeof(struct gsmtap_hdr)>>2;
+ gh->type = GSMTAP_TYPE_UM;
+ gh->timeslot = ts;
+ gh->arfcn = htons(arfcn);
+ /* we don't support signal/noise yet */
+ gh->noise_db = gh->signal_db = 0;
+ gh->frame_number = htonl(fn);
+
+ memcpy(buf + sizeof(*ph) + sizeof(*gh), data, len);
+
+ rc = write(fd, buf, sizeof(*ph) + sizeof(*gh) + len);
+
+ fsync(fd);
+
+ return rc;
+}
diff --git a/gsm-tvoid/src/lib/out_pcap.h b/gsm-tvoid/src/lib/out_pcap.h
new file mode 100644
index 0000000..e8d4b3c
--- /dev/null
+++ b/gsm-tvoid/src/lib/out_pcap.h
@@ -0,0 +1,7 @@
+#ifndef _PCAP_IF_H
+#define _PCAP_IF_H
+
+extern int open_pcap_file(char *fname);
+int write_pcap_packet(int fd, int arfcn, int ts, int fn, char *data, unsigned int len);
+
+#endif
personal git repositories of Harald Welte. Your mileage may vary