aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/openocd.texi5
-rw-r--r--src/server/server.c46
2 files changed, 49 insertions, 2 deletions
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 94f1f315..1d517213 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -6731,6 +6731,11 @@ the initial log output channel is stderr.
Add @var{directory} to the file/script search path.
@end deffn
+@deffn Command bindto [name]
+Specify address by name on which to listen for incoming TCP/IP connections.
+By default, OpenOCD will listen on all available interfaces.
+@end deffn
+
@anchor{targetstatehandling}
@section Target State handling
@cindex reset
diff --git a/src/server/server.c b/src/server/server.c
index cdb62851..f6889a01 100644
--- a/src/server/server.c
+++ b/src/server/server.c
@@ -36,6 +36,10 @@
#include <signal.h>
+#ifdef HAVE_NETDB_H
+#include <netdb.h>
+#endif
+
#ifndef _WIN32
#include <netinet/tcp.h>
#endif
@@ -52,6 +56,9 @@ static int last_signal;
/* set the polling period to 100ms */
static int polling_period = 100;
+/* address by name on which to listen for incoming TCP/IP connections */
+static char *bindto_name;
+
static int add_connection(struct service *service, struct command_context *cmd_ctx)
{
socklen_t address_size;
@@ -194,6 +201,7 @@ int add_service(char *name,
void *priv)
{
struct service *c, **p;
+ struct hostent *hp;
int so_reuseaddr_option = 1;
c = malloc(sizeof(struct service));
@@ -240,11 +248,21 @@ int add_service(char *name,
memset(&c->sin, 0, sizeof(c->sin));
c->sin.sin_family = AF_INET;
- c->sin.sin_addr.s_addr = INADDR_ANY;
+
+ if (bindto_name == NULL)
+ c->sin.sin_addr.s_addr = INADDR_ANY;
+ else {
+ hp = gethostbyname(bindto_name);
+ if (hp == NULL) {
+ LOG_ERROR("couldn't resolve bindto address: %s", bindto_name);
+ exit(-1);
+ }
+ memcpy(&c->sin.sin_addr, hp->h_addr_list[0], hp->h_length);
+ }
c->sin.sin_port = htons(c->portnumber);
if (bind(c->fd, (struct sockaddr *)&c->sin, sizeof(c->sin)) == -1) {
- LOG_ERROR("couldn't bind to socket: %s", strerror(errno));
+ LOG_ERROR("couldn't bind %s to socket: %s", name, strerror(errno));
exit(-1);
}
@@ -632,6 +650,22 @@ COMMAND_HANDLER(handle_poll_period_command)
return ERROR_OK;
}
+COMMAND_HANDLER(handle_bindto_command)
+{
+ switch (CMD_ARGC) {
+ case 0:
+ command_print(CMD_CTX, "bindto name: %s", bindto_name);
+ break;
+ case 1:
+ free(bindto_name);
+ bindto_name = strdup(CMD_ARGV[0]);
+ break;
+ default:
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+ return ERROR_OK;
+}
+
static const struct command_registration server_command_handlers[] = {
{
.name = "shutdown",
@@ -647,6 +681,14 @@ static const struct command_registration server_command_handlers[] = {
.usage = "",
.help = "set the servers polling period",
},
+ {
+ .name = "bindto",
+ .handler = &handle_bindto_command,
+ .mode = COMMAND_ANY,
+ .usage = "[name]",
+ .help = "Specify address by name on which to listen for "
+ "incoming TCP/IP connections",
+ },
COMMAND_REGISTRATION_DONE
};