diff options
-rw-r--r-- | include/osmocom/core/gsmtap_util.h | 4 | ||||
-rw-r--r-- | src/gsmtap_util.c | 57 |
2 files changed, 59 insertions, 2 deletions
diff --git a/include/osmocom/core/gsmtap_util.h b/include/osmocom/core/gsmtap_util.h index 96449443..785f5e58 100644 --- a/include/osmocom/core/gsmtap_util.h +++ b/include/osmocom/core/gsmtap_util.h @@ -18,4 +18,8 @@ int gsmtap_sendmsg(uint16_t arfcn, uint8_t ts, uint8_t chan_type, uint8_t ss, int gsmtap_init(uint32_t dst_ip); +/* Create a local 'gsmtap sink' avoiding the UDP packets being rejected + * with ICMP reject messages */ +int gsmtap_sink_init(uint32_t bind_ip); + #endif /* _GSMTAP_UTIL_H */ diff --git a/src/gsmtap_util.c b/src/gsmtap_util.c index 6d02d58f..b47f6e35 100644 --- a/src/gsmtap_util.c +++ b/src/gsmtap_util.c @@ -43,6 +43,7 @@ #include <errno.h> static struct bsc_fd gsmtap_bfd = { .fd = -1 }; +static struct bsc_fd gsmtap_sink_bfd = { .fd = -1 }; static LLIST_HEAD(gsmtap_txqueue); uint8_t chantype_rsl2gsmtap(uint8_t rsl_chantype, uint8_t link_id) @@ -175,7 +176,7 @@ int gsmtap_init(uint32_t dst_ip) sin.sin_port = htons(GSMTAP_UDP_PORT); sin.sin_addr.s_addr = htonl(dst_ip); - /* FIXME: create socket */ + /* create socket */ rc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (rc < 0) { perror("creating UDP socket"); @@ -186,7 +187,7 @@ int gsmtap_init(uint32_t dst_ip) if (rc < 0) { perror("connecting UDP socket"); close(gsmtap_bfd.fd); - gsmtap_bfd.fd = 0; + gsmtap_bfd.fd = -1; return rc; } @@ -197,4 +198,56 @@ int gsmtap_init(uint32_t dst_ip) return bsc_register_fd(&gsmtap_bfd); } +/* Callback from select layer if we can read from the sink socket */ +static int gsmtap_sink_fd_cb(struct bsc_fd *fd, unsigned int flags) +{ + int rc; + uint8_t buf[4096]; + + if (!(flags & BSC_FD_READ)) + return 0; + + rc = read(fd->fd, buf, sizeof(buf)); + if (rc < 0) { + perror("reading from gsmtap sink fd"); + return rc; + } + /* simply discard any data arriving on the socket */ + + return 0; +} + +/* Create a local 'gsmtap sink' avoiding the UDP packets being rejected + * with ICMP reject messages */ +int gsmtap_sink_init(uint32_t bind_ip) +{ + int rc; + struct sockaddr_in sin; + + sin.sin_family = AF_INET; + sin.sin_port = htons(GSMTAP_UDP_PORT); + sin.sin_addr.s_addr = htonl(bind_ip); + + rc = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (rc < 0) { + perror("creating UDP socket"); + return rc; + } + gsmtap_sink_bfd.fd = rc; + rc = bind(rc, (struct sockaddr *)&sin, sizeof(sin)); + if (rc < 0) { + perror("binding UDP socket"); + close(gsmtap_sink_bfd.fd); + gsmtap_sink_bfd.fd = -1; + return rc; + } + + gsmtap_sink_bfd.when = BSC_FD_READ; + gsmtap_sink_bfd.cb = gsmtap_sink_fd_cb; + gsmtap_sink_bfd.data = NULL; + + return bsc_register_fd(&gsmtap_sink_bfd); + +} + #endif /* HAVE_SYS_SELECT_H */ |