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".
diff --git a/README b/README
index 66179a1..c8d9987 100644
--- a/README
+++ b/README
@@ -16,6 +16,11 @@
 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 @@
     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 @@
 		"  -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 @@
 			{ "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 @@
 		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 @@
 	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;