allow specifying gsmtap dest ip

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".
This commit is contained in:
Eric Wild 2020-12-09 04:24:13 +01:00
parent 4846c50521
commit acb80088b3
3 changed files with 48 additions and 5 deletions

5
README
View File

@ -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 to capture, i.e. on ubuntu this can be conveniently achieved by
sudo setcap cap_net_raw,cap_net_admin=ep /usr/sbin/tcpdump 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 Additionally wireshark needs Edit->Preferences->Protocols->NAS-EPS
"Force dissect as plain EPS" set to true, since capturing encrypted NAS "Force dissect as plain EPS" set to true, since capturing encrypted NAS
messages is fairly useless (although possible), so unencrypted messages is fairly useless (although possible), so unencrypted

View File

@ -3,6 +3,7 @@
while [[ "$#" -gt 0 ]]; do while [[ "$#" -gt 0 ]]; do
case $1 in case $1 in
-s|--serialpath) serialpath="$2"; shift ;; -s|--serialpath) serialpath="$2"; shift ;;
-i|--ip) gsmtapip="$2"; shift ;;
-f|--filename) filename="$2"; shift ;; -f|--filename) filename="$2"; shift ;;
-Q|--qcdebug) qcdebug=1 ;; -Q|--qcdebug) qcdebug=1 ;;
*) echo "unknown parameter: $1"; exit 1 ;; *) echo "unknown parameter: $1"; exit 1 ;;
@ -10,8 +11,16 @@ while [[ "$#" -gt 0 ]]; do
shift shift
done 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 -i any udp port 4729 -w $filename &
tcpdump_pid=$! tcpdump_pid=$!
./src/osmo-qcdiag-log -s $serialpath -G ./src/osmo-qcdiag-log -s $serialpath -G
fi
kill -9 $tcpdump_pid kill -9 $tcpdump_pid

View File

@ -38,6 +38,7 @@
#include <osmocom/core/serial.h> #include <osmocom/core/serial.h>
#include <osmocom/core/gsmtap_util.h> #include <osmocom/core/gsmtap_util.h>
#include <osmocom/core/gsmtap.h> #include <osmocom/core/gsmtap.h>
#include <osmocom/core/socket.h>
#include <osmocom/core/logging.h> #include <osmocom/core/logging.h>
#include "diag_io.h" #include "diag_io.h"
@ -52,6 +53,7 @@
struct diag_instance di; struct diag_instance di;
static char *serial_path = 0; static char *serial_path = 0;
static uint32_t cfg_flags = 0; static uint32_t cfg_flags = 0;
static char *gsmtap_ip = "localhost";
static void do_configure(struct diag_instance *di) static void do_configure(struct diag_instance *di)
{ {
@ -184,6 +186,7 @@ static void print_help()
" -G --gsmtap GSMTAP messages sent to localhost\n" " -G --gsmtap GSMTAP messages sent to localhost\n"
" -Q --qcomdbg plain QC DIAG GSMTAP messages\n" " -Q --qcomdbg plain QC DIAG GSMTAP messages\n"
" -H --hexdump console output of rx/tx 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' }, { "qcomdbg", 0, 0, 'Q' },
{ "hexdump", 0, 0, 'H' }, { "hexdump", 0, 0, 'H' },
{ "serial-path", 1, 0, 's' }, { "serial-path", 1, 0, 's' },
{ "ip", 1, 0, 'i' },
{ 0, 0, 0, 0 } { 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) if (c == -1)
break; break;
@ -220,10 +224,36 @@ static void handle_options(int argc, char **argv)
case 's': case 's':
serial_path = optarg; serial_path = optarg;
break; 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) int main(int argc, char **argv)
{ {
@ -258,15 +288,14 @@ int main(int argc, char **argv)
tio.c_cc[VTIME] = 0; tio.c_cc[VTIME] = 0;
rc = tcsetattr(di.fd, TCSANOW, &tio); rc = tcsetattr(di.fd, TCSANOW, &tio);
di.gsmtap = gsmtap_source_init(gsmtap_ip, GSMTAP_UDP_PORT, 0);
di.gsmtap = gsmtap_source_init("localhost", GSMTAP_UDP_PORT, 0);
if (di.gsmtap == 0) { if (di.gsmtap == 0) {
printf("error initializing gsmtap source!\n"); printf("error initializing gsmtap source!\n");
return EXIT_FAILURE; return EXIT_FAILURE;
} }
di.flags = cfg_flags; di.flags = cfg_flags;
rc = gsmtap_source_add_sink(di.gsmtap); rc = gsmtap_source_add_local_sink(di.gsmtap);
if (rc < 0) { if (rc < 0) {
printf("error initializing gsmtap sink!\n"); printf("error initializing gsmtap sink!\n");
return EXIT_FAILURE; return EXIT_FAILURE;