aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Wild <ewild@sysmocom.de>2020-12-09 04:24:13 +0100
committerEric Wild <ewild@sysmocom.de>2020-12-09 04:27:20 +0100
commitacb80088b33c35340bbd372ba664060afcbdcda3 (patch)
tree26cf56fdc87ce4098e49e483a66a9254aca2085a
parent4846c5052102e7a66b990b70747b5eaaf19cc61c (diff)
allow specifying gsmtap dest iphoernchen/gsmtap
This allows distinguishing multiple modems by specifying another loopback ip i.e. -i 127.0.0.4 Linux has a default local route for 127.0.0.0/8 so it "just works".
-rw-r--r--README5
-rwxr-xr-xcapture.sh11
-rw-r--r--src/osmo-qcdiag-log.c37
3 files changed, 48 insertions, 5 deletions
diff --git a/README b/README
index 66179a1..c8d9987 100644
--- a/README
+++ b/README
@@ -16,6 +16,11 @@ This requires tcpdump, as well as the required permissions
to capture, i.e. on ubuntu this can be conveniently achieved by
sudo setcap cap_net_raw,cap_net_admin=ep /usr/sbin/tcpdump
+In order to distinguish multiple different modems in the capture file
+passing a GSMTAP destination ip is possible with the -i parameter, i.e.
+./capture.sh -s /dev/ttyUSB0 -f outfilename.pcap -i 127.0.0.4
+This will "just work" on linux, since there is a default 127.0.0.0/8 route.
+
Additionally wireshark needs Edit->Preferences->Protocols->NAS-EPS
"Force dissect as plain EPS" set to true, since capturing encrypted NAS
messages is fairly useless (although possible), so unencrypted
diff --git a/capture.sh b/capture.sh
index 299df69..5ea53eb 100755
--- a/capture.sh
+++ b/capture.sh
@@ -3,6 +3,7 @@
while [[ "$#" -gt 0 ]]; do
case $1 in
-s|--serialpath) serialpath="$2"; shift ;;
+ -i|--ip) gsmtapip="$2"; shift ;;
-f|--filename) filename="$2"; shift ;;
-Q|--qcdebug) qcdebug=1 ;;
*) echo "unknown parameter: $1"; exit 1 ;;
@@ -10,8 +11,16 @@ while [[ "$#" -gt 0 ]]; do
shift
done
-killall tcpdump
+#killall tcpdump
+
+if [ -n "$gsmtapip" ]; then
+tcpdump -i any udp port 4729 and dst $gsmtapip -w $filename &
+tcpdump_pid=$!
+./src/osmo-qcdiag-log -s $serialpath -G -i $gsmtapip
+else
tcpdump -i any udp port 4729 -w $filename &
tcpdump_pid=$!
./src/osmo-qcdiag-log -s $serialpath -G
+fi
+
kill -9 $tcpdump_pid
diff --git a/src/osmo-qcdiag-log.c b/src/osmo-qcdiag-log.c
index 89f9164..072a05a 100644
--- a/src/osmo-qcdiag-log.c
+++ b/src/osmo-qcdiag-log.c
@@ -38,6 +38,7 @@
#include <osmocom/core/serial.h>
#include <osmocom/core/gsmtap_util.h>
#include <osmocom/core/gsmtap.h>
+#include <osmocom/core/socket.h>
#include <osmocom/core/logging.h>
#include "diag_io.h"
@@ -52,6 +53,7 @@
struct diag_instance di;
static char *serial_path = 0;
static uint32_t cfg_flags = 0;
+static char *gsmtap_ip = "localhost";
static void do_configure(struct diag_instance *di)
{
@@ -184,6 +186,7 @@ static void print_help()
" -G --gsmtap GSMTAP messages sent to localhost\n"
" -Q --qcomdbg plain QC DIAG GSMTAP messages\n"
" -H --hexdump console output of rx/tx messages\n"
+ " -i --ip address the GSMTAP packets should be sent to (default 127.0.0.1)\n"
);
}
@@ -197,10 +200,11 @@ static void handle_options(int argc, char **argv)
{ "qcomdbg", 0, 0, 'Q' },
{ "hexdump", 0, 0, 'H' },
{ "serial-path", 1, 0, 's' },
+ { "ip", 1, 0, 'i' },
{ 0, 0, 0, 0 }
};
- c = getopt_long(argc, argv, "hGQHs:", long_options, &option_index);
+ c = getopt_long(argc, argv, "hGQHs:i:", long_options, &option_index);
if (c == -1)
break;
@@ -220,10 +224,36 @@ static void handle_options(int argc, char **argv)
case 's':
serial_path = optarg;
break;
+ case 'i':
+ gsmtap_ip = optarg;
+ break;
}
}
}
+/* special function that allows to bind to local nonlocal ips like 127.0.0.x with x != 1 */
+static int gsmtap_source_add_local_sink(struct gsmtap_inst *gti)
+{
+ int rc;
+ struct sockaddr_storage ss;
+ socklen_t ss_len = sizeof(ss);
+
+ if (gti->ofd_wq_mode)
+ return -1;
+
+ rc = getpeername(gsmtap_inst_fd(gti), (struct sockaddr *)&ss, &ss_len);
+ if (rc < 0)
+ return rc;
+
+ rc = osmo_sock_init_sa((struct sockaddr *)&ss, SOCK_DGRAM,
+ IPPROTO_UDP,
+ OSMO_SOCK_F_BIND |
+ OSMO_SOCK_F_UDP_REUSEADDR);
+ if (rc >= 0)
+ return rc;
+
+ return -ENODEV;
+}
int main(int argc, char **argv)
{
@@ -258,15 +288,14 @@ int main(int argc, char **argv)
tio.c_cc[VTIME] = 0;
rc = tcsetattr(di.fd, TCSANOW, &tio);
-
- di.gsmtap = gsmtap_source_init("localhost", GSMTAP_UDP_PORT, 0);
+ di.gsmtap = gsmtap_source_init(gsmtap_ip, GSMTAP_UDP_PORT, 0);
if (di.gsmtap == 0) {
printf("error initializing gsmtap source!\n");
return EXIT_FAILURE;
}
di.flags = cfg_flags;
- rc = gsmtap_source_add_sink(di.gsmtap);
+ rc = gsmtap_source_add_local_sink(di.gsmtap);
if (rc < 0) {
printf("error initializing gsmtap sink!\n");
return EXIT_FAILURE;