Mercurial > dropbear
diff svr-tcpfwd.c @ 64:efb5e0b335cf
TCP forwarding works.
author | Matt Johnston <matt@ucc.asn.au> |
---|---|
date | Thu, 12 Aug 2004 13:48:42 +0000 |
parents | dcc43965928f |
children | b0316ce64e4b |
line wrap: on
line diff
--- a/svr-tcpfwd.c Wed Aug 11 17:26:47 2004 +0000 +++ b/svr-tcpfwd.c Thu Aug 12 13:48:42 2004 +0000 @@ -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_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 @@ 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 @@ 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