summaryrefslogtreecommitdiff
path: root/svr-tcpfwd.c
diff options
context:
space:
mode:
authorMatt Johnston <matt@ucc.asn.au>2004-08-12 13:48:42 +0000
committerMatt Johnston <matt@ucc.asn.au>2004-08-12 13:48:42 +0000
commit935e9c32f4d95278bf951024fda447553ac77db5 (patch)
tree4908aee50c5555c9964030148934641fba2c1a51 /svr-tcpfwd.c
parent09d419bc31dc598240ed03cdf9168d7d0ae6a98f (diff)
downloaddropbear-935e9c32f4d95278bf951024fda447553ac77db5.tar.gz
TCP forwarding works.
Diffstat (limited to 'svr-tcpfwd.c')
-rw-r--r--svr-tcpfwd.c72
1 files changed, 69 insertions, 3 deletions
diff --git a/svr-tcpfwd.c b/svr-tcpfwd.c
index 46c7129..0eccae4 100644
--- a/svr-tcpfwd.c
+++ b/svr-tcpfwd.c
@@ -1,7 +1,6 @@
#include "includes.h"
#include "ssh.h"
-#include "tcp-accept.h"
-#include "tcp-connect.h"
+#include "tcpfwd.h"
#include "dbutil.h"
#include "session.h"
#include "buffer.h"
@@ -15,6 +14,7 @@ static void send_msg_request_success();
static void send_msg_request_failure();
static int svr_cancelremotetcp();
static int svr_remotetcpreq();
+static int newtcpdirect(struct Channel * channel);
const struct ChanType svr_chan_tcpdirect = {
@@ -178,8 +178,8 @@ static int svr_remotetcpreq() {
tcpinfo = (struct TCPListener*)m_malloc(sizeof(struct TCPListener));
tcpinfo->sendaddr = bindaddr;
- TRACE(("sendport = %d", port));
tcpinfo->sendport = port;
+ tcpinfo->listenport = port;
tcpinfo->chantype = &svr_chan_tcpremote;
/* Note: bindaddr is actually ignored by listen_tcpfwd, since
@@ -196,4 +196,70 @@ out:
TRACE(("leave remotetcpreq"));
return ret;
}
+
+/* Called upon creating a new direct tcp channel (ie we connect out to an
+ * address */
+static int newtcpdirect(struct Channel * channel) {
+
+ unsigned char* desthost = NULL;
+ unsigned int destport;
+ unsigned char* orighost = NULL;
+ unsigned int origport;
+ char portstring[NI_MAXSERV];
+ int sock;
+ int len;
+ int ret = DROPBEAR_FAILURE;
+
+ if (opts.nolocaltcp) {
+ TRACE(("leave newtcpdirect: local tcp forwarding disabled"));
+ goto out;
+ }
+
+ desthost = buf_getstring(ses.payload, &len);
+ if (len > MAX_HOST_LEN) {
+ TRACE(("leave newtcpdirect: desthost too long"));
+ goto out;
+ }
+
+ destport = buf_getint(ses.payload);
+
+ orighost = buf_getstring(ses.payload, &len);
+ if (len > MAX_HOST_LEN) {
+ TRACE(("leave newtcpdirect: orighost too long"));
+ goto out;
+ }
+
+ origport = buf_getint(ses.payload);
+
+ /* best be sure */
+ if (origport > 65535 || destport > 65535) {
+ TRACE(("leave newtcpdirect: port > 65535"));
+ goto out;
+ }
+
+ snprintf(portstring, sizeof(portstring), "%d", destport);
+ sock = connect_remote(desthost, portstring, 1, NULL);
+ if (sock < 0) {
+ TRACE(("leave newtcpdirect: sock failed"));
+ goto out;
+ }
+
+ ses.maxfd = MAX(ses.maxfd, sock);
+
+ /* Note that infd is actually the "outgoing" direction on the
+ * tcp connection, vice versa for outfd.
+ * We don't set outfd, that will get set after the connection's
+ * progress succeeds */
+ channel->infd = sock;
+ channel->initconn = 1;
+
+ ret = DROPBEAR_SUCCESS;
+
+out:
+ m_free(desthost);
+ m_free(orighost);
+ TRACE(("leave newtcpdirect: ret %d", ret));
+ return ret;
+}
+
#endif