jtavares has uploaded this change for review. (
https://gerrit.osmocom.org/c/osmo-remsim/+/30139 )
Change subject: bankd: Add GSMTAP functionality for SIM traffic
......................................................................
bankd: Add GSMTAP functionality for SIM traffic
If a --gsmtap-host (-g) address is specified on the command line, trace
SIM ATRs and APDUs to the given IP. If --gsmtap-slot (-G) is provided,
limit tracing to the specified bank slot number. This feature may be
useful when diagnosing issues with the remote SIM framework.
Also, cleaned up alignment in bankd --help output.
Change-Id: I05b599858d8758633aa56c3f12f258c27cf42d08
---
M src/bankd/Makefile.am
M src/bankd/bankd.h
M src/bankd/bankd_main.c
A src/bankd/gsmtap.c
A src/bankd/gsmtap.h
5 files changed, 151 insertions(+), 16 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/osmo-remsim refs/changes/39/30139/1
diff --git a/src/bankd/Makefile.am b/src/bankd/Makefile.am
index 42c9bd3..4899aef 100644
--- a/src/bankd/Makefile.am
+++ b/src/bankd/Makefile.am
@@ -3,7 +3,7 @@
$(OSMOCORE_CFLAGS) $(OSMOGSM_CFLAGS) $(OSMOABIS_CFLAGS) \
$(PCSC_CFLAGS)
-noinst_HEADERS = bankd.h internal.h
+noinst_HEADERS = bankd.h internal.h gsmtap.h
bin_PROGRAMS = osmo-remsim-bankd
noinst_PROGRAMS = pcsc_test
@@ -13,7 +13,7 @@
$(PCSC_LIBS) $(top_builddir)/src/libosmo-rspro.la
osmo_remsim_bankd_SOURCES = ../slotmap.c ../rspro_client_fsm.c ../debug.c \
- bankd_main.c bankd_pcsc.c
+ bankd_main.c bankd_pcsc.c gsmtap.c
osmo_remsim_bankd_LDADD = $(OSMOCORE_LIBS) $(OSMOGSM_LIBS) $(OSMOABIS_LIBS) \
$(PCSC_LIBS) $(CSV_LIBS) $(top_builddir)/src/libosmo-rspro.la
diff --git a/src/bankd/bankd.h b/src/bankd/bankd.h
index 0f94818..ce23135 100644
--- a/src/bankd/bankd.h
+++ b/src/bankd/bankd.h
@@ -133,6 +133,8 @@
struct {
bool permit_shared_pcsc;
+ char* gsmtap_host;
+ int gsmtap_slot;
} cfg;
};
diff --git a/src/bankd/bankd_main.c b/src/bankd/bankd_main.c
index b3b8dff..8e3ed91 100644
--- a/src/bankd/bankd_main.c
+++ b/src/bankd/bankd_main.c
@@ -47,6 +47,7 @@
#include "rspro_client_fsm.h"
#include "debug.h"
#include "rspro_util.h"
+#include "gsmtap.h"
/* signal indicates to worker thread that its map has been deleted */
#define SIGMAPDEL SIGRTMIN+1
@@ -100,6 +101,8 @@
INIT_LLIST_HEAD(&bankd->pcsc_slot_names);
bankd->cfg.permit_shared_pcsc = false;
+ bankd->cfg.gsmtap_host = NULL;
+ bankd->cfg.gsmtap_slot = -1;
}
/* create + start a new bankd_worker thread */
@@ -282,18 +285,20 @@
static void printf_help()
{
printf(
-" -h --help Print this help message\n"
-" -V --version Print the version of the program\n"
-" -d --debug option Enable debug logging (e.g. DMAIN:DST2)\n"
-" -i --server-host A.B.C.D remsim-server IP address (default: 127.0.0.1)\n"
-" -p --server-port <1-65535> remsim-server TCP port (default: 9998)\n"
-" -b --bank-id <1-1023> Bank Identifier of this SIM bank (default:
1)\n"
-" -n --num-slots <1-1023> Number of Slots in this SIM bank (default:
8)\n"
-" -I --bind-ip A.B.C.D Local IP address to bind for incoming client\n"
-" connections (default: INADDR_ANY)\n"
-" -P --bind-port <1-65535> Local TCP port to bind for incoming
client\n"
-" connectionss (default: 9999)\n"
-" -s --permit-shared-pcsc Permit SHARED access to PC/SC readers (default:
exclusive)\n"
+" -h --help Print this help message\n"
+" -V --version Print the version of the program\n"
+" -d --debug option Enable debug logging (e.g. DMAIN:DST2)\n"
+" -i --server-host A.B.C.D remsim-server IP address (default:
127.0.0.1)\n"
+" -p --server-port <1-65535> remsim-server TCP port (default:
9998)\n"
+" -b --bank-id <1-1023> Bank Identifier of this SIM bank (default:
1)\n"
+" -n --num-slots <1-1023> Number of Slots in this SIM bank (default:
8)\n"
+" -I --bind-ip A.B.C.D Local IP address to bind for incoming
client\n"
+" connections (default: INADDR_ANY)\n"
+" -P --bind-port <1-65535> Local TCP port to bind for incoming
client\n"
+" connections (default: 9999)\n"
+" -s --permit-shared-pcsc Permit SHARED access to PC/SC readers (default:
exclusive)\n"
+" -g --gsmtap-ip A.B.C.D Enable GSMTAP and send APDU traces to given
IP\n"
+" -G --gsmtap-slot <0-1023> Limit tracing to given bank slot, only
(default: all slots)\n"
);
}
@@ -316,10 +321,12 @@
{ "bind-ip", 1, 0, 'I' },
{ "bind-port", 1, 0, 'P' },
{ "permit-shared-pcsc", 0, 0, 's' },
+ { "gsmtap-ip", 1, 0, 'g' },
+ { "gsmtap-slot", 1, 0, 'G' },
{ 0, 0, 0, 0 }
};
- c = getopt_long(argc, argv, "hVd:i:o:b:n:N:I:P:s", long_options,
&option_index);
+ c = getopt_long(argc, argv, "hVd:i:o:b:n:N:I:P:sg:G:", long_options,
&option_index);
if (c == -1)
break;
@@ -359,6 +366,12 @@
case 's':
g_bankd->cfg.permit_shared_pcsc = true;
break;
+ case 'g':
+ g_bankd->cfg.gsmtap_host = optarg;
+ break;
+ case 'G':
+ g_bankd->cfg.gsmtap_slot = atoi(optarg);
+ break;
}
}
}
@@ -416,6 +429,15 @@
}
g_bankd->accept_fd = rc;
+ /* initialize gsmtap, if required */
+ if (g_bankd->cfg.gsmtap_host) {
+ rc = osmo_bankd_gsmtap_init(g_bankd->cfg.gsmtap_host);
+ if (rc < 0) {
+ fprintf(stderr, "Unable to open GSMTAP");
+ exit(1);
+ }
+ }
+
/* create worker threads: One per reader/slot! */
for (i = 0; i < g_bankd->srvc.bankd.num_slots; i++) {
struct bankd_worker *w;
@@ -659,6 +681,14 @@
set_atr = rspro_gen_SetAtrReq(worker->client.clslot.client_id,
worker->client.clslot.slot_nr,
worker->card.atr, worker->card.atr_len);
+
+ /* trace ATR to GSMTAP, if configured */
+ if (g_bankd->cfg.gsmtap_host && (g_bankd->cfg.gsmtap_slot == -1 ||
+ g_bankd->cfg.gsmtap_slot == worker->slot.slot_nr)) {
+ osmo_bankd_gsmtap_send_apdu(GSMTAP_SIM_ATR, worker->card.atr,
worker->card.atr_len,
+ NULL, 0);
+ }
+
if (!set_atr)
return -1;
return worker_send_rspro(worker, set_atr);
@@ -759,6 +789,12 @@
rx_buf, rx_buf_len);
worker_send_rspro(worker, pdu_resp);
+ /* trace APDU to GSMTAP, if configured */
+ if (g_bankd->cfg.gsmtap_host && (g_bankd->cfg.gsmtap_slot == -1 ||
+ g_bankd->cfg.gsmtap_slot == worker->slot.slot_nr)) {
+ osmo_bankd_gsmtap_send_apdu(GSMTAP_SIM_APDU, mdm2sim->data.buf,
mdm2sim->data.size, rx_buf,
+ rx_buf_len);
+ }
return 0;
}
@@ -808,7 +844,7 @@
break;
}
- return rc;
+ return rc;
}
static int wait_for_fd_or_timeout(int fd, unsigned int timeout_secs)
diff --git a/src/bankd/gsmtap.c b/src/bankd/gsmtap.c
new file mode 100644
index 0000000..1bbb9dc
--- /dev/null
+++ b/src/bankd/gsmtap.c
@@ -0,0 +1,90 @@
+/* gsmtap - How to encapsulate SIM protocol traces in GSMTAP
+ *
+ * (C) 2016-2019 by Harald Welte <hwelte(a)hmw-consulting.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <osmocom/core/gsmtap.h>
+#include <osmocom/core/gsmtap_util.h>
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+
+/*! global GSMTAP instance */
+static struct gsmtap_inst *g_gti;
+
+/*! initialize the global GSMTAP instance for SIM traces */
+int osmo_bankd_gsmtap_init(const char *gsmtap_host)
+{
+ if (g_gti)
+ return -EEXIST;
+
+ g_gti = gsmtap_source_init(gsmtap_host, GSMTAP_UDP_PORT, 0);
+ if (!g_gti) {
+ perror("unable to open GSMTAP");
+ return -EIO;
+ }
+ gsmtap_source_add_sink(g_gti);
+
+ return 0;
+}
+
+/*! Log one APDU via the global GSMTAP instance by concatenating mdm_tpdu and sim_tpdu.
+ *
+ * \param[in] sub_type GSMTAP sub-type (GSMTAP_SIM_* constant)
+ * \param[in] mdm_tpdu User-provided buffer with ModemToCard TPDU to log. May be
NULL.
+ * \param[in] mdm_tpdu_len Length of ModemToCard TPDU, in bytes.
+ * \param[in] sim_tpdu User-provided buffer with CardToModem TPDU to log. May be
NULL.
+ * \param[in] sim_tpdu_len Length of CardToModem TPDU, in bytes.
+ */
+int osmo_bankd_gsmtap_send_apdu(uint8_t sub_type, const uint8_t *mdm_tpdu, unsigned int
mdm_tpdu_len,
+ const uint8_t *sim_tpdu, unsigned int sim_tpdu_len)
+{
+ struct gsmtap_hdr *gh;
+ const unsigned int gross_len = sizeof(*gh) + mdm_tpdu_len + sim_tpdu_len;
+ uint8_t *buf = malloc(gross_len);
+ size_t offset = 0;
+ int rc;
+
+ if (!buf)
+ return -ENOMEM;
+
+ memset(buf + offset, 0, sizeof(*gh));
+ gh = (struct gsmtap_hdr *) buf;
+ gh->version = GSMTAP_VERSION;
+ gh->hdr_len = sizeof(*gh)/4;
+ gh->type = GSMTAP_TYPE_SIM;
+ gh->sub_type = sub_type;
+ offset += sizeof(*gh);
+
+ if (mdm_tpdu && mdm_tpdu_len) {
+ memcpy(buf + offset, mdm_tpdu, mdm_tpdu_len);
+ offset += mdm_tpdu_len;
+ }
+
+ if (sim_tpdu && sim_tpdu_len) {
+ memcpy(buf + offset, sim_tpdu, sim_tpdu_len);
+ offset += sim_tpdu_len;
+ }
+
+ rc = write(gsmtap_inst_fd(g_gti), buf, offset);
+ if (rc < 0) {
+ perror("write gsmtap");
+ free(buf);
+ return rc;
+ }
+
+ free(buf);
+ return 0;
+}
diff --git a/src/bankd/gsmtap.h b/src/bankd/gsmtap.h
new file mode 100644
index 0000000..f6b136a
--- /dev/null
+++ b/src/bankd/gsmtap.h
@@ -0,0 +1,7 @@
+#pragma once
+#include <stdint.h>
+#include <osmocom/core/gsmtap.h>
+
+int osmo_bankd_gsmtap_init(const char *gsmtap_host);
+int osmo_bankd_gsmtap_send_apdu(uint8_t sub_type, const uint8_t *mdm_tpdu, unsigned int
mdm_tpdu_len,
+ const uint8_t *sim_tpdu, unsigned int sim_tpdu_len);
\ No newline at end of file
--
To view, visit
https://gerrit.osmocom.org/c/osmo-remsim/+/30139
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings
Gerrit-Project: osmo-remsim
Gerrit-Branch: master
Gerrit-Change-Id: I05b599858d8758633aa56c3f12f258c27cf42d08
Gerrit-Change-Number: 30139
Gerrit-PatchSet: 1
Gerrit-Owner: jtavares <jtavares(a)kvh.com>
Gerrit-MessageType: newchange