diff options
author | Oliver Kurth <okurth@gmail.com> | 2009-05-10 19:43:50 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2009-05-10 19:43:50 +0200 |
commit | 0a0dd2d52212764edd0b6fbe649c64abf120f937 (patch) | |
tree | 9b5ac81562682047afa2739bd41a04ddcbc8c1e7 | |
parent | 57a98200a7706950240ffb2bb672cb76f55a641a (diff) |
add ipv6 support
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/bidilink.c | 2 | ||||
-rw-r--r-- | src/client-tcp6.c | 109 | ||||
-rw-r--r-- | src/client-tcp6.h | 28 | ||||
-rw-r--r-- | src/server-tcp6.c | 122 | ||||
-rw-r--r-- | src/server-tcp6.h | 28 | ||||
-rw-r--r-- | src/stream.c | 6 |
7 files changed, 297 insertions, 2 deletions
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 <config.h> +#endif + +#include <sys/types.h> +#include <sys/socket.h> +#include <inttypes.h> +#include <string.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> +#include <netdb.h> +#include <unistd.h> + +#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 <config.h> +#endif + +#include <sys/types.h> +#include <sys/socket.h> +#include <inttypes.h> +#include <string.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> +#include <netdb.h> +#include <unistd.h> + +#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)) |