summaryrefslogtreecommitdiff
path: root/channels.c
diff options
context:
space:
mode:
authorDamien Miller <djm@mindrot.org>2005-12-13 19:29:02 +1100
committerDamien Miller <djm@mindrot.org>2005-12-13 19:29:02 +1100
commitd27b947178df3689bfb7fdfb62a5f1337ef73481 (patch)
treec8678325c355b3602bdabca16da1baa8707818eb /channels.c
parent6dbdb6afeec1820b2799c2693fc8e8b364be8228 (diff)
downloadopenssh-git-d27b947178df3689bfb7fdfb62a5f1337ef73481.tar.gz
- reyk@cvs.openbsd.org 2005/12/06 22:38:28
[auth-options.c auth-options.h channels.c channels.h clientloop.c] [misc.c misc.h readconf.c readconf.h scp.c servconf.c servconf.h] [serverloop.c sftp.c ssh.1 ssh.c ssh_config ssh_config.5 sshconnect.c] [sshconnect.h sshd.8 sshd_config sshd_config.5] Add support for tun(4) forwarding over OpenSSH, based on an idea and initial channel code bits by markus@. This is a simple and easy way to use OpenSSH for ad hoc virtual private network connections, e.g. administrative tunnels or secure wireless access. It's based on a new ssh channel and works similar to the existing TCP forwarding support, except that it depends on the tun(4) network interface on both ends of the connection for layer 2 or layer 3 tunneling. This diff also adds support for LocalCommand in the ssh(1) client. ok djm@, markus@, jmc@ (manpages), tested and discussed with others
Diffstat (limited to 'channels.c')
-rw-r--r--channels.c42
1 files changed, 40 insertions, 2 deletions
diff --git a/channels.c b/channels.c
index 9607717c..b4fd89f9 100644
--- a/channels.c
+++ b/channels.c
@@ -39,7 +39,7 @@
*/
#include "includes.h"
-RCSID("$OpenBSD: channels.c,v 1.227 2005/10/14 02:29:37 stevesk Exp $");
+RCSID("$OpenBSD: channels.c,v 1.228 2005/12/06 22:38:27 reyk Exp $");
#include "ssh.h"
#include "ssh1.h"
@@ -1414,6 +1414,8 @@ channel_handle_rfd(Channel *c, fd_set * readset, fd_set * writeset)
debug2("channel %d: filter stops", c->self);
chan_read_failed(c);
}
+ } else if (c->datagram) {
+ buffer_put_string(&c->input, buf, len);
} else {
buffer_append(&c->input, buf, len);
}
@@ -1432,6 +1434,23 @@ channel_handle_wfd(Channel *c, fd_set * readset, fd_set * writeset)
if (c->wfd != -1 &&
FD_ISSET(c->wfd, writeset) &&
buffer_len(&c->output) > 0) {
+ if (c->datagram) {
+ data = buffer_get_string(&c->output, &dlen);
+ /* ignore truncated writes, datagrams might get lost */
+ c->local_consumed += dlen + 4;
+ len = write(c->wfd, data, dlen);
+ xfree(data);
+ if (len < 0 && (errno == EINTR || errno == EAGAIN))
+ return 1;
+ if (len <= 0) {
+ if (c->type != SSH_CHANNEL_OPEN)
+ chan_mark_dead(c);
+ else
+ chan_write_failed(c);
+ return -1;
+ }
+ return 1;
+ }
data = buffer_ptr(&c->output);
dlen = buffer_len(&c->output);
#ifdef _AIX
@@ -1792,6 +1811,22 @@ channel_output_poll(void)
if ((c->istate == CHAN_INPUT_OPEN ||
c->istate == CHAN_INPUT_WAIT_DRAIN) &&
(len = buffer_len(&c->input)) > 0) {
+ if (c->datagram) {
+ if (len > 0) {
+ u_char *data;
+ u_int dlen;
+
+ data = buffer_get_string(&c->input,
+ &dlen);
+ packet_start(SSH2_MSG_CHANNEL_DATA);
+ packet_put_int(c->remote_id);
+ packet_put_string(data, dlen);
+ packet_send();
+ c->remote_window -= dlen + 4;
+ xfree(data);
+ }
+ continue;
+ }
/*
* Send some data for the other side over the secure
* connection.
@@ -1914,7 +1949,10 @@ channel_input_data(int type, u_int32_t seq, void *ctxt)
c->local_window -= data_len;
}
packet_check_eom();
- buffer_append(&c->output, data, data_len);
+ if (c->datagram)
+ buffer_put_string(&c->output, data, data_len);
+ else
+ buffer_append(&c->output, data, data_len);
xfree(data);
}