ipa-proxy: Add option to locally listen to GPRS...

This is just the boilerplate code, the rest is not implemted yet.
diff --git a/openbsc/src/ipaccess/ipaccess-proxy.c b/openbsc/src/ipaccess/ipaccess-proxy.c
index ea78e87..0a7b18b 100644
--- a/openbsc/src/ipaccess/ipaccess-proxy.c
+++ b/openbsc/src/ipaccess/ipaccess-proxy.c
@@ -55,6 +55,9 @@
 	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 @@
 
 static char *listen_ipaddr;
 static char *bsc_ipaddr;
+static char *gprs_ns_ipaddr;
 
 #define PROXY_ALLOC_SIZE	1200
 
@@ -982,6 +986,11 @@
 	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 @@
 	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 @@
 	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 @@
 	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 @@
 			{"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 @@
 		case 'b':
 			bsc_ipaddr = optarg;
 			break;
+		case 'g':
+			gprs_ns_ipaddr = optarg;
+			break;
 		case 's':
 			log_set_use_color(stderr_target, 0);
 			break;