From f7460f5292e155461f341319c08386223ec58c76 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Wed, 30 Jun 2010 12:32:00 +0200 Subject: [gsm-receiver] Update to new GSMTAP version In wireshark mainline, there is a UDP-based GSMTAP version which is much different from our pcap-file / link-type based one. This commit updates the gsmtap support in gsm-receiver to use the same format as understood by wireshark mainline. However, it introduces a build and runtime dependency to libosmocore (git://git.osmocom.org/libosmocore.git). --- gsm-receiver/configure.ac | 10 +-- gsm-receiver/src/lib/Makefile.am | 1 + gsm-receiver/src/lib/decoder/Makefile.am | 2 - gsm-receiver/src/lib/decoder/gsmstack.c | 61 +++++++++++------ gsm-receiver/src/lib/decoder/gsmstack.h | 3 +- gsm-receiver/src/lib/decoder/gsmtap.h | 59 ++++++++++++---- gsm-receiver/src/lib/decoder/out_pcap.c | 111 ------------------------------- 7 files changed, 92 insertions(+), 155 deletions(-) delete mode 100644 gsm-receiver/src/lib/decoder/out_pcap.c diff --git a/gsm-receiver/configure.ac b/gsm-receiver/configure.ac index e309304..0c4cb7a 100644 --- a/gsm-receiver/configure.ac +++ b/gsm-receiver/configure.ac @@ -25,7 +25,7 @@ AC_CONFIG_SRCDIR([src/lib/gsm.i]) AM_CONFIG_HEADER(config.h) AC_CANONICAL_TARGET([]) AC_CONFIG_AUX_DIR([.]) -AM_INIT_AUTOMAKE(gsm-receiver,0.0.1) +AM_INIT_AUTOMAKE(gsm-receiver,0.0.2) AC_CONFIG_MACRO_DIR([config]) GR_X86_64 @@ -93,14 +93,14 @@ GR_PWIN32 PKG_CHECK_MODULES(GNURADIO_CORE, gnuradio-core >= 3) dnl LIBS="$LIBS $GNURADIO_CORE_LIBS" -dnl Check for boost, version 1.35 (or higher I guess - this was taken from GNU Radio's configure.ac) -AX_BOOST_BASE([1.35]) -CXXFLAGS="$CXXFLAGS $BOOST_CXXFLAGS" -CFLAGS="$CFLAGS $BOOST_CXXFLAGS" +dnl Define where to find boost includes +GR_REQUIRE_BOOST_INCLUDES STD_DEFINES_AND_INCLUDES="$GNURADIO_CORE_CFLAGS $BOOST_CFLAGS" AC_SUBST(STD_DEFINES_AND_INCLUDES) +dnl Check for libosmocore (gsmtap support) +PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.1.13) AC_CONFIG_FILES([\ Makefile \ diff --git a/gsm-receiver/src/lib/Makefile.am b/gsm-receiver/src/lib/Makefile.am index 925eaca..71ea8fe 100644 --- a/gsm-receiver/src/lib/Makefile.am +++ b/gsm-receiver/src/lib/Makefile.am @@ -79,6 +79,7 @@ _gsm_la_LDFLAGS = $(NO_UNDEFINED) -module -avoid-version _gsm_la_LIBADD = \ $(PYTHON_LDFLAGS) \ libgsmdemod.la \ + $(LIBOSMOCORE_LIBS) \ -lstdc++ \ $(DECODER_LA) diff --git a/gsm-receiver/src/lib/decoder/Makefile.am b/gsm-receiver/src/lib/decoder/Makefile.am index 1726d68..2fcadbb 100644 --- a/gsm-receiver/src/lib/decoder/Makefile.am +++ b/gsm-receiver/src/lib/decoder/Makefile.am @@ -36,7 +36,6 @@ libdecoder_la_SOURCES = \ fire_crc.c \ gsmstack.c \ interleave.c \ - out_pcap.c \ tun.c # tch.c \ # conv.c @@ -47,7 +46,6 @@ noinst_HEADERS = \ fire_crc.h \ gsmstack.h \ interleave.h \ - out_pcap.h \ tun.h \ system.h \ gsmtap.h \ diff --git a/gsm-receiver/src/lib/decoder/gsmstack.c b/gsm-receiver/src/lib/decoder/gsmstack.c index c3f1921..6c91395 100644 --- a/gsm-receiver/src/lib/decoder/gsmstack.c +++ b/gsm-receiver/src/lib/decoder/gsmstack.c @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "gsmstack.h" //#include "gsm_constants.h" @@ -13,9 +14,16 @@ //#include "sch.h" #include "cch.h" +#include +#include +#include + +#include +#include +#include + static const int USEFUL_BITS = 142; -//#include "out_pcap.h" enum BURST_TYPE { UNKNOWN, FCCH, @@ -79,22 +87,31 @@ diff_decode(char *dst, char *src, int len) int GS_new(GS_CTX *ctx) { + int rc; + struct sockaddr_in sin; + + sin.sin_family = AF_INET; + sin.sin_port = htons(GSMTAP_UDP_PORT); + inet_aton("127.0.0.1", &sin.sin_addr); + memset(ctx, 0, sizeof *ctx); interleave_init(&ctx->interleave_ctx, 456, 114); ctx->fn = -1; ctx->bsic = -1; + ctx->gsmtap_fd = -1; - ctx->tun_fd = mktun("gsm", ctx->ether_addr); - if (ctx->tun_fd < 0) - fprintf(stderr, "cannot open 'gsm' tun device, did you create it?\n"); - - ctx->pcap_fd = open_pcap_file("gsm-receiver.pcap"); - if (ctx->pcap_fd < 0) - fprintf(stderr, "cannot open PCAP file: %s\n", strerror(errno)); - - ctx->burst_pcap_fd = open_pcap_file("gsm-receiver-burst.pcap"); - if (ctx->burst_pcap_fd < 0) - fprintf(stderr, "cannot open burst PCAP file: %s\n", strerror(errno)); + rc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (rc < 0) { + perror("creating UDP socket\n"); + return rc; + } + ctx->gsmtap_fd = rc; + rc = connect(rc, (struct sockaddr *)&sin, sizeof(sin)); + if (rc < 0) { + perror("connectiong UDP socket"); + close(ctx->gsmtap_fd); + return rc; + } return 0; } @@ -112,15 +129,9 @@ GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src, int fn) unsigned char *data; int len; struct gs_ts_ctx *ts_ctx = &ctx->ts_ctx[ts]; - unsigned char octified[BURST_BYTES]; memset(ctx->msg, 0, sizeof(ctx->msg)); - /* write burst to burst PCAP file */ - burst_octify(octified, src, USEFUL_BITS); - write_pcap_packet(ctx->burst_pcap_fd, 0 /* arfcn */, ts, ctx->fn, - 1, type, octified, BURST_BYTES); - #if 0 if (ts != 0) { /* non-0 timeslots should end up in PCAP */ @@ -177,9 +188,17 @@ GS_process(GS_CTX *ctx, int ts, int type, const unsigned char *src, int fn) //DEBUGF("OK TS %d, len %d\n", ts, len); 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, ctx->fn, - 0, NORMAL, data, len); + + if (ctx->gsmtap_fd >= 0) { + struct msgb *msg; + /* arfcn, ts, chan_type, ss, fn, signal, snr, data, len */ + msg = gsmtap_makemsg(0, ts, GSMTAP_CHANNEL_BCCH, 0, + ctx->fn-4, 0, 0, data, len); + if (msg) + write(ctx->gsmtap_fd, msg->data, + msg->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-receiver/src/lib/decoder/gsmstack.h b/gsm-receiver/src/lib/decoder/gsmstack.h index 9355785..d02440c 100644 --- a/gsm-receiver/src/lib/decoder/gsmstack.h +++ b/gsm-receiver/src/lib/decoder/gsmstack.h @@ -29,8 +29,7 @@ typedef struct int tun_fd; unsigned char ether_addr[ETH_ALEN]; - int pcap_fd; - int burst_pcap_fd; + int gsmtap_fd; } GS_CTX; int GS_new(GS_CTX *ctx); diff --git a/gsm-receiver/src/lib/decoder/gsmtap.h b/gsm-receiver/src/lib/decoder/gsmtap.h index 1022194..dcd64bd 100644 --- a/gsm-receiver/src/lib/decoder/gsmtap.h +++ b/gsm-receiver/src/lib/decoder/gsmtap.h @@ -1,11 +1,20 @@ #ifndef _GSMTAP_H #define _GSMTAP_H -/* gsmtap header, pseudo-header in front of the actua GSM payload*/ +/* gsmtap header, pseudo-header in front of the actua GSM payload */ -#include +/* GSMTAP is a generic header format for GSM protocol captures, + * it uses the IANA-assigned UDP port number 4729 and carries + * payload in various formats of GSM interfaces such as Um MAC + * blocks or Um bursts. + * + * Example programs generating GSMTAP data are airprobe + * (http://airprobe.org/) or OsmocomBB (http://bb.osmocom.org/) + */ -#define GSMTAP_VERSION 0x01 +#include + +#define GSMTAP_VERSION 0x02 #define GSMTAP_TYPE_UM 0x01 #define GSMTAP_TYPE_ABIS 0x02 @@ -20,22 +29,44 @@ #define GSMTAP_BURST_NORMAL 0x06 #define GSMTAP_BURST_DUMMY 0x07 #define GSMTAP_BURST_ACCESS 0x08 +#define GSMTAP_BURST_NONE 0x09 + +#define GSMTAP_CHANNEL_UNKNOWN 0x00 +#define GSMTAP_CHANNEL_BCCH 0x01 +#define GSMTAP_CHANNEL_CCCH 0x02 +#define GSMTAP_CHANNEL_RACH 0x03 +#define GSMTAP_CHANNEL_AGCH 0x04 +#define GSMTAP_CHANNEL_PCH 0x05 +#define GSMTAP_CHANNEL_SDCCH 0x06 +#define GSMTAP_CHANNEL_SDCCH4 0x07 +#define GSMTAP_CHANNEL_SDCCH8 0x08 +#define GSMTAP_CHANNEL_TCH_F 0x09 +#define GSMTAP_CHANNEL_TCH_H 0x0a +#define GSMTAP_CHANNEL_ACCH 0x80 + +#define GSMTAP_ARFCN_F_PCS 0x8000 +#define GSMTAP_ARFCN_F_UPLINK 0x4000 +#define GSMTAP_ARFCN_MASK 0x3fff + +#define GSMTAP_UDP_PORT 4729 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) */ + uint8_t version; /* version, set to 0x01 currently */ + uint8_t hdr_len; /* length in number of 32bit words */ + uint8_t type; /* see GSMTAP_TYPE_* */ + uint8_t timeslot; /* timeslot (0..7 on Um) */ - u_int16_t arfcn; /* ARFCN (frequency) */ - u_int8_t noise_db; /* noise figure in dB */ - u_int8_t signal_db; /* signal level in dB */ + uint16_t arfcn; /* ARFCN (frequency) */ + int8_t signal_dbm; /* signal level in dBm */ + int8_t snr_db; /* signal/noise ratio in dB */ - u_int32_t frame_number; /* GSM Frame Number (FN) */ + uint32_t frame_number; /* GSM Frame Number (FN) */ - u_int8_t burst_type; /* Type of burst, see above */ - u_int8_t antenna_nr; /* Antenna Number */ - u_int16_t res; /* reserved for future use (RFU) */ + uint8_t sub_type; /* Type of burst/channel, see above */ + uint8_t antenna_nr; /* Antenna Number */ + uint8_t sub_slot; /* sub-slot within timeslot */ + uint8_t res; /* reserved for future use (RFU) */ } __attribute__((packed)); + #endif /* _GSMTAP_H */ diff --git a/gsm-receiver/src/lib/decoder/out_pcap.c b/gsm-receiver/src/lib/decoder/out_pcap.c deleted file mode 100644 index 4da5fd6..0000000 --- a/gsm-receiver/src/lib/decoder/out_pcap.c +++ /dev/null @@ -1,111 +0,0 @@ -/* PCAP support for gsm-tvoid - * (C) 2008 by Harald Welte - */ - -#include -#include -#include -#include -#include -#include - -#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, - int burst, int burst_type, - const unsigned char *data, unsigned int len) -{ - unsigned char buf[8192]; - struct pcap_sf_pkthdr *ph; - struct gsmtap_hdr *gh; - struct timeval tv; - int rc; - - if (fd < 0) - return -EINVAL; - - 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; - if (burst) - gh->type = GSMTAP_TYPE_UM_BURST; - else - 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); - gh->burst_type = burst_type & 0xff; - - memcpy(buf + sizeof(*ph) + sizeof(*gh), data, len); - - rc = write(fd, buf, sizeof(*ph) + sizeof(*gh) + len); - - //fsync(fd); - - return rc; -} -- cgit v1.2.3