aboutsummaryrefslogtreecommitdiff
path: root/package/network/services/dropbear/patches/011-add-option-to-bind-to-interface.patch
blob: d1c1fa4ccedf382709d3c5f33cb774a5ab48fe15 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
From fb64db9eac3fdc6434f2dc7b5ea407fe5df76e6f Mon Sep 17 00:00:00 2001
From: Diederik De Coninck <diederik.deconinck_ext@softathome.com>
Date: Tue, 11 Apr 2023 15:38:04 +0200
Subject: Add option to bind to interface

---
 netio.c       | 13 +++++++++++--
 netio.h       |  2 +-
 runopts.h     |  1 +
 svr-main.c    |  2 +-
 svr-runopts.c |  9 +++++++++
 svr-tcpfwd.c  |  1 +
 tcp-accept.c  |  2 +-
 tcpfwd.h      |  1 +
 8 files changed, 26 insertions(+), 5 deletions(-)

--- a/netio.c
+++ b/netio.c
@@ -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;
@@ -497,7 +497,11 @@ int dropbear_listen(const char* address,
 		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;
@@ -551,6 +555,11 @@ int dropbear_listen(const char* address,
 		/* 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;
--- a/netio.h
+++ b/netio.h
@@ -19,7 +19,7 @@ void get_socket_address(int fd, char **l
 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;
 
--- a/runopts.h
+++ b/runopts.h
@@ -128,6 +128,7 @@ typedef struct svr_runopts {
 	char * pidfile;
 
 	char * forced_command;
+	char* interface;
 
 #if DROPBEAR_PLUGIN 
 	/* malloced */
--- a/svr-main.c
+++ b/svr-main.c
@@ -488,7 +488,7 @@ static size_t listensockets(int *socks,
 
 		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", 
--- a/svr-runopts.c
+++ b/svr-runopts.c
@@ -98,6 +98,8 @@ static void printhelp(const char * progn
 					"		(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
@@ -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':
@@ -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) {
--- a/svr-tcpfwd.c
+++ b/svr-tcpfwd.c
@@ -205,6 +205,7 @@ static int svr_remotetcpreq(int *allocat
 	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) ) {
--- a/tcp-accept.c
+++ b/tcp-accept.c
@@ -117,7 +117,7 @@ int listen_tcpfwd(struct TCPListener* tc
 	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);
--- a/tcpfwd.h
+++ b/tcpfwd.h
@@ -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;