diff --git a/doc/openocd.texi b/doc/openocd.texi index 94f1f315e..1d517213d 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 cdb62851e..f6889a01a 100644 --- a/src/server/server.c +++ b/src/server/server.c @@ -36,6 +36,10 @@ #include +#ifdef HAVE_NETDB_H +#include +#endif + #ifndef _WIN32 #include #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 };