aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/ipaccess/ipaccess-proxy.c
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <zecke@selfish.org>2010-06-09 16:20:39 +0800
committerHolger Hans Peter Freyther <zecke@selfish.org>2010-06-09 21:40:45 +0800
commit6147c5d7d0c6fee5e9c3f1868f9f4bcbd0e4c39c (patch)
treed1783f017a4b8a303c3006d249f3272732f73bb7 /openbsc/src/ipaccess/ipaccess-proxy.c
parent7670651f4941bab9cc72b3c908e47a7f6f2d9524 (diff)
ipa-proxy: Add option to locally listen to GPRS...
This is just the boilerplate code, the rest is not implemted yet.
Diffstat (limited to 'openbsc/src/ipaccess/ipaccess-proxy.c')
-rw-r--r--openbsc/src/ipaccess/ipaccess-proxy.c69
1 files changed, 67 insertions, 2 deletions
diff --git a/openbsc/src/ipaccess/ipaccess-proxy.c b/openbsc/src/ipaccess/ipaccess-proxy.c
index ea78e875d..0a7b18b47 100644
--- a/openbsc/src/ipaccess/ipaccess-proxy.c
+++ b/openbsc/src/ipaccess/ipaccess-proxy.c
@@ -55,6 +55,9 @@ struct ipa_proxy {
struct bsc_fd oml_listen_fd;
/* socket where we listen for incoming RSL from BTS */
struct bsc_fd rsl_listen_fd;
+ /* socket where we get the GPRS NS data */
+ struct bsc_fd gprs_ns_fd;
+ int gprs_port;
/* list of BTS's (struct ipa_bts_conn */
struct llist_head bts_list;
/* the BSC reconnect timer */
@@ -115,6 +118,7 @@ void *tall_bsc_ctx;
static char *listen_ipaddr;
static char *bsc_ipaddr;
+static char *gprs_ns_ipaddr;
#define PROXY_ALLOC_SIZE 1200
@@ -982,6 +986,11 @@ static int listen_fd_cb(struct bsc_fd *listen_bfd, unsigned int what)
return 0;
}
+static int gprs_ns_cb(struct bsc_fd *bfd, unsigned int what)
+{
+ return 0;
+}
+
static int make_listen_sock(struct bsc_fd *bfd, u_int16_t port, int priv_nr,
int (*cb)(struct bsc_fd *fd, unsigned int what))
{
@@ -1025,6 +1034,36 @@ static int make_listen_sock(struct bsc_fd *bfd, u_int16_t port, int priv_nr,
return 0;
}
+static int make_gprs_sock(struct bsc_fd *bfd, int (*cb)(struct bsc_fd*,unsigned int))
+{
+ struct sockaddr_in addr;
+ int ret;
+
+ bfd->fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+ bfd->cb = cb;
+ bfd->when = BSC_FD_READ;
+
+ memset(&addr, 0, sizeof(addr));
+ addr.sin_family = AF_INET;
+ addr.sin_port = 0;
+ inet_aton(listen_ipaddr, &addr.sin_addr);
+
+ ret = bind(bfd->fd, (struct sockaddr *) &addr, sizeof(addr));
+ if (ret < 0) {
+ LOGP(DINP, LOGL_ERROR,
+ "Could not bind n socket for IP %s with error: %s.\n",
+ listen_ipaddr, strerror(errno));
+ return -EIO;
+ }
+
+ ret = bsc_register_fd(bfd);
+ if (ret < 0) {
+ perror("register_listen_fd");
+ return ret;
+ }
+ return 0;
+}
+
/* Actively connect to a BSC. */
static struct ipa_proxy_conn *connect_bsc(struct sockaddr_in *sa, int priv_nr, void *data)
{
@@ -1088,6 +1127,26 @@ static int ipaccess_proxy_setup(void)
ret = make_listen_sock(&ipp->rsl_listen_fd, IPA_TCP_PORT_RSL,
RSL_FROM_BTS, listen_fd_cb);
+ if (ret < 0)
+ return ret;
+
+ /* Connect the GPRS NS Socket */
+ if (gprs_ns_ipaddr) {
+ struct sockaddr_in sock;
+ socklen_t len = sizeof(sock);
+ ret = make_gprs_sock(&ipp->gprs_ns_fd, gprs_ns_cb);
+ if (ret < 0)
+ return ret;
+
+ ret = getsockname(ipp->gprs_ns_fd.fd, (struct sockaddr* ) &sock, &len);
+ if (ret < 0)
+ return ret;
+ ipp->gprs_port = ntohs(sock.sin_port);
+ LOGP(DINP, LOGL_NOTICE,
+ "Created GPRS NS Socket. Listening on: %s:%d\n",
+ inet_ntoa(sock.sin_addr), ipp->gprs_port);
+ }
+
return ret;
}
@@ -1112,7 +1171,9 @@ static void print_help()
printf(" ipaccess-proxy is a proxy BTS.\n");
printf(" -h --help. This help text.\n");
printf(" -l --listen IP. The ip to listen to.\n");
- printf(" -b --bsc IP. The BSC IP address.\n\n");
+ printf(" -b --bsc IP. The BSC IP address.\n");
+ printf(" -g --gprs IP. Take GPRS NS from that IP.\n");
+ printf("\n");
printf(" -s --disable-color. Disable the color inside the logging message.\n");
printf(" -e --log-level number. Set the global loglevel.\n");
printf(" -T --timestamp. Prefix every log message with a timestamp.\n");
@@ -1135,10 +1196,11 @@ static void handle_options(int argc, char** argv)
{"log-level", 1, 0, 'e'},
{"listen", 1, 0, 'l'},
{"bsc", 1, 0, 'b'},
+ {"udp", 1, 0, 'u'},
{0, 0, 0, 0}
};
- c = getopt_long(argc, argv, "hsTe:l:b:",
+ c = getopt_long(argc, argv, "hsTe:l:b:g:",
long_options, &option_index);
if (c == -1)
break;
@@ -1154,6 +1216,9 @@ static void handle_options(int argc, char** argv)
case 'b':
bsc_ipaddr = optarg;
break;
+ case 'g':
+ gprs_ns_ipaddr = optarg;
+ break;
case 's':
log_set_use_color(stderr_target, 0);
break;