Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to bind to interface #229

Merged
merged 2 commits into from
Jul 18, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions src/netio.c
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ int get_sock_port(int sock) {
* failure, if errstring wasn't NULL, it'll be a newly malloced error
* string.*/
int dropbear_listen(const char* address, const char* port,
int *socks, unsigned int sockcount, char **errstring, int *maxfd) {
int *socks, unsigned int sockcount, char **errstring, int *maxfd, const char* interface) {

struct addrinfo hints, *res = NULL, *res0 = NULL;
int err;
Expand Down Expand Up @@ -497,7 +497,11 @@ int dropbear_listen(const char* address, const char* port,
TRACE(("dropbear_listen: local loopback"))
} else {
if (address[0] == '\0') {
TRACE(("dropbear_listen: all interfaces"))
if (interface) {
TRACE(("dropbear_listen: %s", interface))
} else {
TRACE(("dropbear_listen: all interfaces"))
}
address = NULL;
}
hints.ai_flags = AI_PASSIVE;
Expand Down Expand Up @@ -551,6 +555,11 @@ int dropbear_listen(const char* address, const char* port,
/* set to reuse, quick timeout */
setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (void*) &val, sizeof(val));

if(interface && setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, interface, strlen(interface)) < 0) {
dropbear_log(LOG_WARNING, "Couldn't set SO_BINDTODEVICE");
TRACE(("Failed setsockopt with errno failure, %d %s", errno, strerror(errno)))
}

#if defined(IPPROTO_IPV6) && defined(IPV6_V6ONLY)
if (res->ai_family == AF_INET6) {
int on = 1;
Expand Down
2 changes: 1 addition & 1 deletion src/netio.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ void get_socket_address(int fd, char **local_host, char **local_port,
void getaddrstring(struct sockaddr_storage* addr,
char **ret_host, char **ret_port, int host_lookup);
int dropbear_listen(const char* address, const char* port,
int *socks, unsigned int sockcount, char **errstring, int *maxfd);
int *socks, unsigned int sockcount, char **errstring, int *maxfd, const char* interface);

struct dropbear_progress_connection;

Expand Down
1 change: 1 addition & 0 deletions src/runopts.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ typedef struct svr_runopts {
char * pidfile;

char * forced_command;
char* interface;

#if DROPBEAR_PLUGIN
/* malloced */
Expand Down
2 changes: 1 addition & 1 deletion src/svr-main.c
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,7 @@ static size_t listensockets(int *socks, size_t sockcount, int *maxfd) {

nsock = dropbear_listen(svr_opts.addresses[i], svr_opts.ports[i], &socks[sockpos],
sockcount - sockpos,
&errstring, maxfd);
&errstring, maxfd, svr_opts.interface);

if (nsock < 0) {
dropbear_log(LOG_WARNING, "Failed listening on '%s': %s",
Expand Down
9 changes: 9 additions & 0 deletions src/svr-runopts.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ static void printhelp(const char * progname) {
" (default port is %s if none specified)\n"
"-P PidFile Create pid file PidFile\n"
" (default %s)\n"
"-l <interface>\n"
" interface to bind on\n"
#if INETD_MODE
"-i Start for inetd\n"
#endif
Expand Down Expand Up @@ -265,6 +267,9 @@ void svr_getopts(int argc, char ** argv) {
case 'P':
next = &svr_opts.pidfile;
break;
case 'l':
next = &svr_opts.interface;
break;
#if DO_MOTD
/* motd is displayed by default, -m turns it off */
case 'm':
Expand Down Expand Up @@ -438,6 +443,10 @@ void svr_getopts(int argc, char ** argv) {
dropbear_log(LOG_INFO, "Forced command set to '%s'", svr_opts.forced_command);
}

if (svr_opts.interface) {
dropbear_log(LOG_INFO, "Binding to interface '%s'", svr_opts.interface);
}

if (reexec_fd_arg) {
if (m_str_to_uint(reexec_fd_arg, &svr_opts.reexec_childpipe) == DROPBEAR_FAILURE
|| svr_opts.reexec_childpipe < 0) {
Expand Down
1 change: 1 addition & 0 deletions src/svr-tcpfwd.c
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ static int svr_remotetcpreq(int *allocated_listen_port) {
tcpinfo->listenport = port;
tcpinfo->chantype = &svr_chan_tcpremote;
tcpinfo->tcp_type = forwarded;
tcpinfo->interface = svr_opts.interface;

tcpinfo->request_listenaddr = request_addr;
if (!opts.listen_fwd_all || (strcmp(request_addr, "localhost") == 0) ) {
Expand Down
2 changes: 1 addition & 1 deletion src/tcp-accept.c
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ int listen_tcpfwd(struct TCPListener* tcpinfo, struct Listener **ret_listener) {
snprintf(portstring, sizeof(portstring), "%u", tcpinfo->listenport);

nsocks = dropbear_listen(tcpinfo->listenaddr, portstring, socks,
DROPBEAR_MAX_SOCKS, &errstring, &ses.maxfd);
DROPBEAR_MAX_SOCKS, &errstring, &ses.maxfd, tcpinfo->interface);
if (nsocks < 0) {
dropbear_log(LOG_INFO, "TCP forward failed: %s", errstring);
m_free(errstring);
Expand Down
1 change: 1 addition & 0 deletions src/tcpfwd.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ struct TCPListener {
unsigned int listenport;
/* The address that the remote host asked to listen on */
char *request_listenaddr;
char* interface;

const struct ChanType *chantype;
enum {direct, forwarded} tcp_type;
Expand Down
Loading