From 0a0dd2d52212764edd0b6fbe649c64abf120f937 Mon Sep 17 00:00:00 2001 From: Oliver Kurth Date: Sun, 10 May 2009 19:43:50 +0200 Subject: add ipv6 support --- src/Makefile.am | 4 +- src/bidilink.c | 2 + src/client-tcp6.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++ src/client-tcp6.h | 28 +++++++++++++ src/server-tcp6.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/server-tcp6.h | 28 +++++++++++++ src/stream.c | 6 +++ 7 files changed, 297 insertions(+), 2 deletions(-) create mode 100644 src/client-tcp6.c create mode 100644 src/client-tcp6.h create mode 100644 src/server-tcp6.c create mode 100644 src/server-tcp6.h diff --git a/src/Makefile.am b/src/Makefile.am index d1f03cd..a434eea 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -19,8 +19,8 @@ bin_PROGRAMS = bidilink bidilink_SOURCES = bidilink.c client-tty.h exec.h server-tty.h std.h \ - client-tcp.c client-unix.c server-tcp.c server-unix.c stream.c \ - client-tcp.h client-unix.h server-tcp.h server-unix.h stream.h \ + client-tcp.c client-tcp6.c client-unix.c server-tcp.c server-tcp6.c server-unix.c stream.c \ + client-tcp.h client-tcp6.h client-unix.h server-tcp.h server-tcp6.h server-unix.h stream.h \ client-tty.c exec.c server-tty.c std.c bidilink_CFLAGS = -DLOCKDIR="\"$(LOCKDIR)\"" diff --git a/src/bidilink.c b/src/bidilink.c index 1224bc5..2e077e0 100644 --- a/src/bidilink.c +++ b/src/bidilink.c @@ -54,6 +54,8 @@ static void usage(FILE *f, const char *argv0) { "\tpty:[PTYSYMLINK]\n" "\ttcp-client:HOSTNAME:PORT\n" "\ttcp-server:[IPADDRESS:]PORT\n" + "\ttcp6-client:HOSTNAME:PORT\n" + "\ttcp6-server:[IPADDRESS:]PORT\n" "\tunix-client:SOCKNAME\n" "\tunix-server:SOCKNAME\n", argv0); diff --git a/src/client-tcp6.c b/src/client-tcp6.c new file mode 100644 index 0000000..537700f --- /dev/null +++ b/src/client-tcp6.c @@ -0,0 +1,109 @@ +/* -*- linux-c -*- */ +/* $Id$ */ + +/*** + This file is part of bidilink. + + bidilink is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + bidilink is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with bidilink; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "client-tcp6.h" + +struct stream* stream_client_tcp6(const char *args) { + struct stream *s = NULL; + int fd = -1; + struct addrinfo hints, *res, *ressave; + size_t l; + const char *port = "23"; + char hn[256]; + int n, save_errno = 0; + + l = strcspn(args, "/"); + if (l > sizeof(hn)-1) + l = sizeof(hn)-1; + strncpy(hn, args, l); + hn[l] = 0; + + if (args[l] == '/') + port = args+l+1; + + s = malloc(sizeof(struct stream)); + assert(s); + memset(s, 0, sizeof(struct stream));\ + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + n = getaddrinfo(hn, port, &hints, &res); + + if (n < 0) { + fprintf(stderr, + "getaddrinfo error:: [%s]\n", + strerror(errno)); + goto fail; + } + + ressave = res; + + fd =- 1; + while (res) { + fd = socket(res->ai_family, + res->ai_socktype, + res->ai_protocol); + + if (!(fd < 0)) { + if(connect(fd, res->ai_addr, res->ai_addrlen) == 0) + break; + save_errno = errno; + close(fd); + fd = -1; + } + res = res->ai_next; + } + + freeaddrinfo(ressave); + if(fd < 0){ + fprintf(stderr, "connect(): %s\n", strerror(save_errno)); + goto fail; + } + + s->input_fd = s->output_fd = fd; + return s; + +fail: + free(s); + if (fd >= 0) + close(fd); + + return NULL; +} diff --git a/src/client-tcp6.h b/src/client-tcp6.h new file mode 100644 index 0000000..f596d42 --- /dev/null +++ b/src/client-tcp6.h @@ -0,0 +1,28 @@ +#ifndef fooclienttcp6hfoo +#define fooclienttcp6hfoo + +/* $Id$ */ + +/*** + This file is part of bidilink. + + bidilink is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + bidilink is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with bidilink; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +***/ + +#include "stream.h" + +struct stream* stream_client_tcp6(const char *args); + +#endif diff --git a/src/server-tcp6.c b/src/server-tcp6.c new file mode 100644 index 0000000..7793bea --- /dev/null +++ b/src/server-tcp6.c @@ -0,0 +1,122 @@ +/* -*- linux-c -*- */ +/* $Id: server-tcp.c 4 2004-01-14 18:14:29Z lennart $ */ + +/*** + This file is part of bidilink. + + bidilink is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + bidilink is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with bidilink; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +***/ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "server-tcp6.h" + +struct stream* stream_server_tcp6(const char *args) { + struct stream *s = NULL; + int fd = -1, cfd; + struct addrinfo hints, *res, *ressave; + size_t l; + const char *port = "23"; + char hn[256] = ""; + int n; + + l = strcspn(args, "/"); + if (l > sizeof(hn)-1) + l = sizeof(hn)-1; + + if (args[l] == '/') { + strncpy(hn, args, l); + hn[l] = 0; + + port = args+l+1; + } + + s = malloc(sizeof(struct stream)); + assert(s); + memset(s, 0, sizeof(struct stream)); + + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + fprintf(stderr, "hn = %s, port = %s\n", hn, port); + n = getaddrinfo(hn[0] ? hn : "::", port, &hints, &res); + + if (n < 0) { + fprintf(stderr, + "getaddrinfo error:: [%s]\n", + strerror(errno)); + goto fail; + } + + ressave = res; + + fd=-1; + while (res) { + fd = socket(res->ai_family, + res->ai_socktype, + res->ai_protocol); + + if (!(fd < 0)) { + if (bind(fd, res->ai_addr, res->ai_addrlen) == 0) + break; + + close(fd); + fd = -1; + } + res = res->ai_next; + } + + freeaddrinfo(ressave); + if(fd < 0) + goto fail; + + if (listen(fd, 1) < 0) { + fprintf(stderr, "listen(): %s\n", strerror(errno)); + goto fail; + } + + if ((cfd = accept(fd, NULL, 0)) < 0) { + fprintf(stderr, "accept(): %s\n", strerror(errno)); + goto fail; + } + + close(fd); + s->input_fd = s->output_fd = cfd; + + return s; + +fail: + free(s); + if (fd >= 0) + close(fd); + + return NULL; +} diff --git a/src/server-tcp6.h b/src/server-tcp6.h new file mode 100644 index 0000000..74cd725 --- /dev/null +++ b/src/server-tcp6.h @@ -0,0 +1,28 @@ +#ifndef fooservertcphfoo +#define fooservertcphfoo + +/* $Id: server-tcp.h 4 2004-01-14 18:14:29Z lennart $ */ + +/*** + This file is part of bidilink. + + bidilink is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + bidilink is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public + License for more details. + + You should have received a copy of the GNU General Public License + along with bidilink; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +***/ + +#include "stream.h" + +struct stream* stream_server_tcp6(const char *args); + +#endif diff --git a/src/stream.c b/src/stream.c index 72bc7a1..ec2ac6b 100644 --- a/src/stream.c +++ b/src/stream.c @@ -34,7 +34,9 @@ #include "client-tty.h" #include "server-tty.h" #include "client-tcp.h" +#include "client-tcp6.h" #include "server-tcp.h" +#include "server-tcp6.h" #include "client-unix.h" #include "server-unix.h" @@ -49,8 +51,12 @@ struct stream* stream_open(const char *spec) { return stream_server_tty(spec+4); else if (!strncmp(spec, "tcp-client:", 11)) return stream_client_tcp(spec+11); + else if (!strncmp(spec, "tcp6-client:", 12)) + return stream_client_tcp6(spec+12); else if (!strncmp(spec, "tcp-server:", 11)) return stream_server_tcp(spec+11); + else if (!strncmp(spec, "tcp6-server:", 12)) + return stream_server_tcp6(spec+12); else if (!strncmp(spec, "unix-client:", 12)) return stream_client_unix(spec+12); else if (!strncmp(spec, "unix-server:", 12)) -- cgit