This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
Jan Hrach gerrit-no-reply at lists.osmocom.orgJan Hrach has uploaded this change for review. ( https://gerrit.osmocom.org/10265 Change subject: allow dumping GSMTAP to PCAP file ...................................................................... allow dumping GSMTAP to PCAP file When lots of packets are streamed to loopback, some of them get mixed up and lost. Add an option to write GSMTAP frames to a file (or a pipe for realtime processing). Also add an option to disable streaming them via network. Change-Id: I955589a1d576f180fc4b80dba8ed8dc364e43d8b --- A src/pcap.h M src/tetra-rx-tests.sh M src/tetra-rx.c M src/tetra_common.h M src/tetra_gsmtap.c M src/tetra_gsmtap.h 6 files changed, 132 insertions(+), 7 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmo-tetra refs/changes/65/10265/1 diff --git a/src/pcap.h b/src/pcap.h new file mode 100644 index 0000000..f3efe07 --- /dev/null +++ b/src/pcap.h @@ -0,0 +1,51 @@ +#ifndef PCAP_H +#define PCAP_H +#include <inttypes.h> + +typedef uint32_t guint32; +typedef uint16_t guint16; +typedef int32_t gint32; + +typedef struct __attribute__ ((__packed__)) pcap_hdr_s { + guint32 magic_number; /* magic number */ + guint16 version_major; /* major version number */ + guint16 version_minor; /* minor version number */ + gint32 thiszone; /* GMT to local correction */ + guint32 sigfigs; /* accuracy of timestamps */ + guint32 snaplen; /* max length of captured packets, in octets */ + guint32 network; /* data link type */ +} pcap_hdr_t; + +typedef struct __attribute__ ((__packed__)) pcaprec_hdr_s { + guint32 ts_sec; /* timestamp seconds */ + guint32 ts_usec; /* timestamp microseconds */ + guint32 incl_len; /* number of octets of packet saved in file */ + guint32 orig_len; /* actual length of packet */ +} pcaprec_hdr_t; + +#define PCAP_MAGIC 0xa1b2c3d4 +#define PCAP_MAJOR 2 +#define PCAP_MINOR 4 +#define PCAP_SNAPLEN 65535 +#define PCAP_ETHERNET 1 + +unsigned char fake_frame_header[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Ethernet frame, dst and src MAC + 0x08, 0x00, // EtherType 0800 = IPv4 + 0x45, // IPv4 (0x4_), 20B header (0x_5) + 0x00, // no diffserv + 0x00, 0xff, // length + 0xc6, 0xd1, // some random frag + 0x40, 0x00, // don't frag + 0x3f, // TTL + 0x11, // IP proto = UDP + 0x00, 0x00, // checksum + 0x7f, 0x00, 0x00, 0x01, // src = 127.0.0.1 + 0x7f, 0x00, 0x00, 0x01, // dst = 127.0.0.1 + 0xbb, 0x13, // source port + 0x12, 0x79, // dst port = 4729 + 0x00, 0xeb, // length = iplen-20 + 0x00, 0x00 // checksum +}; +#endif + diff --git a/src/tetra-rx-tests.sh b/src/tetra-rx-tests.sh index f84a1ad..d841f0c 100755 --- a/src/tetra-rx-tests.sh +++ b/src/tetra-rx-tests.sh @@ -53,7 +53,7 @@ tmpdir=`mktemp -d /tmp/tetraXXX` for f in $@; do - corrects=`"time" -o "$tmpdir/time" ./tetra-rx "$f" $t 2>/dev/null | grep -E "^CRC COMP: 0x.+ OK" | wc -l` + corrects=`"time" -o "$tmpdir/time" ./tetra-rx -n "$f" $t 2>/dev/null | grep -E "^CRC COMP: 0x.+ OK" | wc -l` tt=`grep user "$tmpdir/time" | head -n 1 | cut -d u -f 1` echo "$f: $corrects frames, $tt s" hash=`sha256sum "$f" | cut -c 1-20` diff --git a/src/tetra-rx.c b/src/tetra-rx.c index ed4d252..8498f8c 100644 --- a/src/tetra-rx.c +++ b/src/tetra-rx.c @@ -22,6 +22,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <stdbool.h> #include <fcntl.h> #include <sys/stat.h> @@ -43,24 +44,42 @@ struct tetra_rx_state *trs; struct tetra_mac_state *tms; + char *pcap_file_path = NULL; + bool no_udp_tap = false; + bool err = false; + tms = talloc_zero(tetra_tall_ctx, struct tetra_mac_state); tetra_mac_state_init(tms); trs = talloc_zero(tetra_tall_ctx, struct tetra_rx_state); trs->burst_cb_priv = tms; - while ((opt = getopt(argc, argv, "d:")) != -1) { + while ((opt = getopt(argc, argv, "a:t:d:n")) != -1) { switch (opt) { + case 'a': + tms->arfcn = atoi(optarg); + break; + case 't': + pcap_file_path = strdup(optarg); + break; case 'd': tms->dumpdir = strdup(optarg); break; + case 'n': + no_udp_tap = 1; + break; default: fprintf(stderr, "Unknown option %c\n", opt); + err = true; } } - if (argc <= optind) { - fprintf(stderr, "Usage: %s [-d DUMPDIR] <file_with_1_byte_per_bit>\n", argv[0]); + if (argc <= optind || err) { + fprintf(stderr, "Usage: %s [params] <file_with_1_byte_per_bit>\n", argv[0]); + fprintf(stderr, " -a arfcn .. set ARFCN used in GSMTAP\n"); + fprintf(stderr, " -t filename .. output PCAP to file\n"); + fprintf(stderr, " -d directory .. dump traffic channel to directory\n"); + fprintf(stderr, " -n .. disable GSMTAP over UDP\n"); exit(1); } @@ -70,7 +89,11 @@ exit(2); } - tetra_gsmtap_init("localhost", 0); + if (!no_udp_tap) + tetra_gsmtap_init_network("localhost", 0); + + if (pcap_file_path) + tetra_gsmtap_init_file(pcap_file_path); while (1) { uint8_t buf[64]; diff --git a/src/tetra_common.h b/src/tetra_common.h index d141e9b..a270a26 100644 --- a/src/tetra_common.h +++ b/src/tetra_common.h @@ -52,6 +52,7 @@ char *dumpdir; /* Where to save traffic channel dump */ int ssi; /* SSI */ int tsn; /* Timeslon number */ + int arfcn; }; void tetra_mac_state_init(struct tetra_mac_state *tms); diff --git a/src/tetra_gsmtap.c b/src/tetra_gsmtap.c index 79b48a7..b656ff6 100644 --- a/src/tetra_gsmtap.c +++ b/src/tetra_gsmtap.c @@ -4,6 +4,7 @@ #include <unistd.h> #include <stdio.h> #include <errno.h> +#include <time.h> #include <osmocom/core/msgb.h> #include <osmocom/core/gsmtap.h> @@ -13,6 +14,9 @@ #include "tetra_common.h" #include "tetra_tdma.h" +#include "pcap.h" + +static FILE * pcap_file; static struct gsmtap_inst *g_gti = NULL; @@ -62,15 +66,38 @@ return msg; } +static void pcap_file_write(void *buf, size_t n) +{ + if (pcap_file) { + fwrite(buf, n, 1, pcap_file); + fflush(pcap_file); + } +} + int tetra_gsmtap_sendmsg(struct msgb *msg) { + pcaprec_hdr_t hdr = {0}; + + struct timespec now; + + clock_gettime(CLOCK_REALTIME, &now); + + hdr.ts_sec = now.tv_sec; + hdr.ts_usec = now.tv_nsec/1000; + hdr.incl_len = msg->len + sizeof(fake_frame_header); + hdr.orig_len = hdr.incl_len; + + pcap_file_write(&hdr, sizeof(hdr)); + pcap_file_write(&fake_frame_header, sizeof(fake_frame_header)); + pcap_file_write(msg->data, msg->len); + if (g_gti) return gsmtap_sendmsg(g_gti, msg); else return 0; } -int tetra_gsmtap_init(const char *host, uint16_t port) +int tetra_gsmtap_init_network(const char *host, uint16_t port) { g_gti = gsmtap_source_init(host, port, 0); if (!g_gti) @@ -79,3 +106,25 @@ return 0; } + +int tetra_gsmtap_init_file(const char *filename) +{ + pcap_hdr_t hdr; + + memset(&hdr, 0, sizeof(hdr)); + + hdr.magic_number = PCAP_MAGIC; + hdr.version_major = PCAP_MAJOR; + hdr.version_minor = PCAP_MINOR; + hdr.snaplen = PCAP_SNAPLEN; + hdr.network = PCAP_ETHERNET; + + pcap_file = fopen(filename, "wb"); + if (!pcap_file) { + perror("pcap file open"); + exit(1); + } + pcap_file_write(&hdr, sizeof(pcap_hdr_t)); + + return 0; +} diff --git a/src/tetra_gsmtap.h b/src/tetra_gsmtap.h index 34963d0..6f77240 100644 --- a/src/tetra_gsmtap.h +++ b/src/tetra_gsmtap.h @@ -8,6 +8,7 @@ int tetra_gsmtap_sendmsg(struct msgb *msg); -int tetra_gsmtap_init(const char *host, uint16_t port); +int tetra_gsmtap_init_network(const char *host, uint16_t port); +int tetra_gsmtap_init_file(const char *filename); #endif -- To view, visit https://gerrit.osmocom.org/10265 To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: osmo-tetra Gerrit-Branch: master Gerrit-MessageType: newchange Gerrit-Change-Id: I955589a1d576f180fc4b80dba8ed8dc364e43d8b Gerrit-Change-Number: 10265 Gerrit-PatchSet: 1 Gerrit-Owner: Jan Hrach <jenda.2vf9h at hrach.eu> -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20180730/f81be5d1/attachment.htm>