introduce listen on specific interface

Signed-off-by: Andy Green <andy@warmcat.com>
diff --git a/lib/libwebsockets.c b/lib/libwebsockets.c
index cf814ec..f94b11c 100644
--- a/lib/libwebsockets.c
+++ b/lib/libwebsockets.c
@@ -20,6 +20,7 @@
  */
 
 #include "private-libwebsockets.h"
+#include <ifaddrs.h>
 
 /*
  * In-place str to lower case
@@ -101,6 +102,33 @@
 }
 #endif
 
+
+static int
+interface_to_sa(const char* ifname, struct sockaddr_in *addr, size_t addrlen)
+{
+	int rc = -1;
+	struct ifaddrs *ifr;
+	struct ifaddrs *ifc;
+	struct sockaddr_in *sin;
+
+	getifaddrs(&ifr);
+	for (ifc = ifr; ifc != NULL; ifc = ifc->ifa_next) {
+		if (strcmp(ifc->ifa_name, ifname))
+			continue;
+		if (ifc->ifa_addr == NULL)
+			continue;
+		sin = (struct sockaddr_in *)ifc->ifa_addr;
+		if (sin->sin_family != AF_INET)
+			continue;
+		memcpy(addr, sin, addrlen);
+		rc = 0; 
+	}
+
+	freeifaddrs(ifr);
+
+	return rc;
+}
+
 void
 libwebsocket_close_and_free_session(struct libwebsocket_context *this,
 						       struct libwebsocket *wsi)
@@ -1201,7 +1229,8 @@
  * libwebsocket_callback_on_writable() - Request a callback when this socket
  *					 becomes able to be written to without
  *					 blocking
- * *
+ *
+ * @this:	libwebsockets context
  * @wsi:	Websocket connection instance to get callback for
  */
 
@@ -1366,6 +1395,8 @@
  * @port:	Port to listen on... you can use 0 to suppress listening on
  *		any port, that's what you want if you are not running a
  *		websocket server at all but just using it as a client
+ * @interface:  NULL to bind the listen socket to all interfaces, or the
+ *		interface name, eg, "eth2"
  * @protocols:	Array of structures listing supported protocols and a protocol-
  *		specific callback for each one.  The list is ended with an
  *		entry that has a NULL callback pointer.
@@ -1406,7 +1437,7 @@
  */
 
 struct libwebsocket_context *
-libwebsocket_create_context(int port,
+libwebsocket_create_context(int port, const char *interface,
 			       struct libwebsocket_protocols *protocols,
 			       const char *ssl_cert_filepath,
 			       const char *ssl_private_key_filepath,
@@ -1622,7 +1653,11 @@
 
 		bzero((char *) &serv_addr, sizeof(serv_addr));
 		serv_addr.sin_family = AF_INET;
-		serv_addr.sin_addr.s_addr = INADDR_ANY;
+		if (interface == NULL)
+			serv_addr.sin_addr.s_addr = INADDR_ANY;
+		else
+			interface_to_sa(interface, &serv_addr,
+						sizeof(serv_addr));
 		serv_addr.sin_port = htons(port);
 
 		n = bind(sockfd, (struct sockaddr *) &serv_addr,
diff --git a/lib/libwebsockets.h b/lib/libwebsockets.h
index 927d93d..acb27b1 100644
--- a/lib/libwebsockets.h
+++ b/lib/libwebsockets.h
@@ -125,7 +125,7 @@
 /* document the generic callback (it's a fake prototype under this) */
 /**
  * callback() - User server actions
- * @this:	Websockets context
+ * @context:	Websockets context
  * @wsi:	Opaque websocket instance pointer
  * @reason:	The reason for the call
  * @user:	Pointer to per-session user data allocated by library
@@ -289,7 +289,7 @@
 };
 
 extern struct libwebsocket_context *
-libwebsocket_create_context(int port,
+libwebsocket_create_context(int port, const char * interface,
 		  struct libwebsocket_protocols *protocols,
 		  const char *ssl_cert_filepath,
 		  const char *ssl_private_key_filepath, int gid, int uid,
diff --git a/libwebsockets-api-doc.html b/libwebsockets-api-doc.html
index e351ab8..cd3e70d 100644
--- a/libwebsockets-api-doc.html
+++ b/libwebsockets-api-doc.html
@@ -120,13 +120,15 @@
 nothing is pending, or as soon as it services whatever was pending.
 </blockquote>
 <hr>
-<h2>libwebsocket_callback_on_writable - Request a callback when this socket becomes able to be written to without blocking *</h2>
+<h2>libwebsocket_callback_on_writable - Request a callback when this socket becomes able to be written to without blocking</h2>
 <i>int</i>
 <b>libwebsocket_callback_on_writable</b>
 (<i>struct libwebsocket_context *</i> <b>this</b>,
 <i>struct libwebsocket *</i> <b>wsi</b>)
 <h3>Arguments</h3>
 <dl>
+<dt><b>this</b>
+<dd>libwebsockets context
 <dt><b>wsi</b>
 <dd>Websocket connection instance to get callback for
 </dl>
@@ -217,6 +219,7 @@
 <i>struct libwebsocket_context *</i>
 <b>libwebsocket_create_context</b>
 (<i>int</i> <b>port</b>,
+<i>const char *</i> <b>interface</b>,
 <i>struct libwebsocket_protocols *</i> <b>protocols</b>,
 <i>const char *</i> <b>ssl_cert_filepath</b>,
 <i>const char *</i> <b>ssl_private_key_filepath</b>,
@@ -229,6 +232,9 @@
 <dd>Port to listen on... you can use 0 to suppress listening on
 any port, that's what you want if you are not running a
 websocket server at all but just using it as a client
+<dt><b>interface</b>
+<dd>NULL to bind the listen socket to all interfaces, or the
+interface name, eg, "eth2"
 <dt><b>protocols</b>
 <dd>Array of structures listing supported protocols and a protocol-
 specific callback for each one.  The list is ended with an
@@ -469,6 +475,8 @@
 <i>size_t</i> <b>len</b>)
 <h3>Arguments</h3>
 <dl>
+<dt><b>context</b>
+<dd>Websockets context
 <dt><b>wsi</b>
 <dd>Opaque websocket instance pointer
 <dt><b>reason</b>
diff --git a/test-server/test-client.c b/test-server/test-client.c
index e887971..09528c2 100644
--- a/test-server/test-client.c
+++ b/test-server/test-client.c
@@ -224,7 +224,7 @@
 	 * For this client-only demo, we tell it to not listen on any port.
 	 */
 
-	context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN,
+	context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, NULL,
 					      protocols, NULL, NULL, -1, -1, 0);
 	if (context == NULL) {
 		fprintf(stderr, "Creating libwebsocket context failed\n");
diff --git a/test-server/test-ping.c b/test-server/test-ping.c
index c04bb87..1ecfb4d 100644
--- a/test-server/test-ping.c
+++ b/test-server/test-ping.c
@@ -400,7 +400,7 @@
 			if (w.ws_col > 0)
 				screen_width = w.ws_col;
 
-	context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN,
+	context = libwebsocket_create_context(CONTEXT_PORT_NO_LISTEN, NULL,
 					      protocols, NULL, NULL, -1, -1, 0);
 	if (context == NULL) {
 		fprintf(stderr, "Creating libwebsocket context failed\n");
diff --git a/test-server/test-server-extpoll.c b/test-server/test-server-extpoll.c
index 74b1c02..29595a1 100644
--- a/test-server/test-server-extpoll.c
+++ b/test-server/test-server-extpoll.c
@@ -419,6 +419,7 @@
 	{ "port",	required_argument,	NULL, 'p' },
 	{ "ssl",	no_argument,		NULL, 's' },
 	{ "killmask",	no_argument,		NULL, 'k' },
+	{ "interface",  required_argument, 	NULL, 'i' },
 	{ NULL, 0, 0, 0 }
 };
 
@@ -436,13 +437,15 @@
 	struct libwebsocket_context *context;
 	int opts = 0;
 	unsigned int oldus = 0;
+	char interface_name[128] = "";
+	const char * interface = NULL;
 
 	fprintf(stderr, "libwebsockets test server with external poll()\n"
 			"(C) Copyright 2010-2011 Andy Green <andy@warmcat.com> "
 						    "licensed under LGPL2.1\n");
 
 	while (n >= 0) {
-		n = getopt_long(argc, argv, "khsp:", options, NULL);
+		n = getopt_long(argc, argv, "i:khsp:", options, NULL);
 		if (n < 0)
 			continue;
 		switch (n) {
@@ -455,6 +458,11 @@
 		case 'p':
 			port = atoi(optarg);
 			break;
+		case 'i':
+			strncpy(interface_name, optarg, sizeof interface_name);
+			interface_name[(sizeof interface_name) - 1] = '\0';
+			interface = interface_name;
+			break;
 		case 'h':
 			fprintf(stderr, "Usage: test-server "
 					     "[--port=<p>] [--ssl]\n");
@@ -465,8 +473,8 @@
 	if (!use_ssl)
 		cert_path = key_path = NULL;
 
-	context = libwebsocket_create_context(port, protocols, cert_path,
-						key_path, -1, -1, opts);
+	context = libwebsocket_create_context(port, interface, protocols,
+					cert_path, key_path, -1, -1, opts);
 	if (context == NULL) {
 		fprintf(stderr, "libwebsocket init failed\n");
 		return -1;
diff --git a/test-server/test-server.c b/test-server/test-server.c
index db22868..2620908 100644
--- a/test-server/test-server.c
+++ b/test-server/test-server.c
@@ -369,6 +369,7 @@
 	{ "port",	required_argument,	NULL, 'p' },
 	{ "ssl",	no_argument,		NULL, 's' },
 	{ "killmask",	no_argument,		NULL, 'k' },
+	{ "interface",  required_argument, 	NULL, 'i' },
 	{ NULL, 0, 0, 0 }
 };
 
@@ -385,6 +386,8 @@
 	int use_ssl = 0;
 	struct libwebsocket_context *context;
 	int opts = 0;
+	char interface_name[128] = "";
+	const char * interface = NULL;
 #ifdef LWS_NO_FORK
 	unsigned int oldus = 0;
 #endif
@@ -394,7 +397,7 @@
 						    "licensed under LGPL2.1\n");
 
 	while (n >= 0) {
-		n = getopt_long(argc, argv, "khsp:", options, NULL);
+		n = getopt_long(argc, argv, "i:khsp:", options, NULL);
 		if (n < 0)
 			continue;
 		switch (n) {
@@ -407,6 +410,11 @@
 		case 'p':
 			port = atoi(optarg);
 			break;
+		case 'i':
+			strncpy(interface_name, optarg, sizeof interface_name);
+			interface_name[(sizeof interface_name) - 1] = '\0';
+			interface = interface_name;
+			break;
 		case 'h':
 			fprintf(stderr, "Usage: test-server "
 					     "[--port=<p>] [--ssl]\n");
@@ -417,8 +425,8 @@
 	if (!use_ssl)
 		cert_path = key_path = NULL;
 
-	context = libwebsocket_create_context(port, protocols, cert_path,
-						key_path, -1, -1, opts);
+	context = libwebsocket_create_context(port, interface, protocols,
+				cert_path, key_path, -1, -1, opts);
 	if (context == NULL) {
 		fprintf(stderr, "libwebsocket init failed\n");
 		return -1;