summaryrefslogtreecommitdiffstats
path: root/gnu/libexec/uucp
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2000-05-25 16:38:22 +0000
committerume <ume@FreeBSD.org>2000-05-25 16:38:22 +0000
commit96ab0c2c8f9f2ca7d3466f5a45d469ba0224c598 (patch)
tree0e4851a1c2d374b1d70b19f9c6d2ccc80b4ef33e /gnu/libexec/uucp
parentf8a289a9a13527f37032e3cb9b395ac7f9e6ffb5 (diff)
downloadFreeBSD-src-96ab0c2c8f9f2ca7d3466f5a45d469ba0224c598.zip
FreeBSD-src-96ab0c2c8f9f2ca7d3466f5a45d469ba0224c598.tar.gz
IPv6 support.
Add $FreeBSD$.
Diffstat (limited to 'gnu/libexec/uucp')
-rw-r--r--gnu/libexec/uucp/common_sources/config.h9
-rw-r--r--gnu/libexec/uucp/common_sources/uuconf.h4
-rw-r--r--gnu/libexec/uucp/doc/uucp.texi30
-rw-r--r--gnu/libexec/uucp/libunix/tcp.c227
-rw-r--r--gnu/libexec/uucp/libuuconf/hport.c14
-rw-r--r--gnu/libexec/uucp/libuuconf/tportc.c36
-rw-r--r--gnu/libexec/uucp/libuuconf/vsinfo.c14
7 files changed, 239 insertions, 95 deletions
diff --git a/gnu/libexec/uucp/common_sources/config.h b/gnu/libexec/uucp/common_sources/config.h
index fdd90125..504d011 100644
--- a/gnu/libexec/uucp/common_sources/config.h
+++ b/gnu/libexec/uucp/common_sources/config.h
@@ -1,6 +1,8 @@
/* config.h. Generated automatically by configure. */
/* Configuration header file for Taylor UUCP. -*- C -*- */
+/* $FreeBSD$ */
+
/* If your compiler does not use const correctly, then undefine it
here. This #undef is commented out by the configure script if it
determines that const is supported. */
@@ -217,6 +219,9 @@
is on AIX. */
#define HAVE_TXADDCD 0
+/* Set HAVE_SOCKADDR_SA_LEN to 1 if struct sockaddr has sa_len member. */
+#define HAVE_SOCKADDR_SA_LEN 1
+
/* There are now a number of functions to check for. For each of
these, the macro HAVE_FUNC should be set to 1 if your system has
FUNC. For example, HAVE_VFPRINTF should be set to 1 if your system
@@ -288,6 +293,10 @@
#define HAVE_STRRCHR 1
#define HAVE_RINDEX 1
+/* If neither of these functions exists, you should add getaddrinfo.o to
+ lib/Makefile. */
+#define HAVE_GETADDRINFO 1
+
/* There are also Unix specific functions which are replaced in the
subdirectory unix. If they are missing, the configure script will
automatically add them to unix/Makefile to force them to be
diff --git a/gnu/libexec/uucp/common_sources/uuconf.h b/gnu/libexec/uucp/common_sources/uuconf.h
index 3909888..32f653d 100644
--- a/gnu/libexec/uucp/common_sources/uuconf.h
+++ b/gnu/libexec/uucp/common_sources/uuconf.h
@@ -29,6 +29,8 @@
c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
*/
+/* $FreeBSD$ */
+
#ifndef UUCONF_H
#define UUCONF_H
@@ -417,6 +419,8 @@ struct uuconf_tcp_port
/* The TCP port number to use. May be a name or a number. May be
NULL, in which case "uucp" is looked up using getservbyname. */
char *uuconf_zport;
+ /* Address family to use for a TCP connection. */
+ int uuconf_zfamily;
/* A NULL terminated sequence of dialer/token pairs (element 0 is a
dialer name, element 1 is a token, etc.) May be NULL. */
char **uuconf_pzdialer;
diff --git a/gnu/libexec/uucp/doc/uucp.texi b/gnu/libexec/uucp/doc/uucp.texi
index 50ff556..a73d34b 100644
--- a/gnu/libexec/uucp/doc/uucp.texi
+++ b/gnu/libexec/uucp/doc/uucp.texi
@@ -1,4 +1,7 @@
\input texinfo @c -*-texinfo-*-
+
+@c $FreeBSD$
+
@c %**start of header
@setfilename uucp.info
@settitle Taylor UUCP
@@ -5204,6 +5207,13 @@ string @samp{uucp} is looked up in @file{/etc/services}. If it is not
found, port number 540 (the standard UUCP-over-TCP port number) will be
used.
+@item family @var{string} [ tcp only ]
+@findex family
+
+Name the protocol family to use. Available value is @samp{inet} for
+IPv4 only, @samp{inet6} for IPv6 only, or @samp{inet46} for both IPv4
+and IPv6. The default is @samp{inet46}.
+
@item push @var{strings} [ tli only ]
@findex push
@@ -5474,7 +5484,12 @@ Files}), add the line @samp{port type tcp} to the entry in the
@samp{uucp} in @file{/etc/services}; if the @samp{uucp} service is not
defined, port 540 will be used. You can set the port number to use with
the command @samp{port service @var{xxx}}, where @var{xxx} can be either
-a number or a name to look up in @file{/etc/services}. You can specify
+a number or a name to look up in @file{/etc/services}. By default UUCP
+will determine the protocol family by querying DNS; if the AAAA record
+is found, IPv6 will be used, and if not found, IPv4 will be used. You
+can set the protocol family to use with the command @samp{port family
+@var{xxx}}, where @var{xxx} can be @samp{inet} for IPv4 only,
+@samp{inet6} for IPv6 only or @samp{inet46} for both. You can specify
the address of the remote host with @samp{address @var{a.b.c}}; if you
don't give an address, the remote system name will be used. You should
give an explicit chat script for the system when you use TCP; the
@@ -5506,6 +5521,10 @@ be called at any time, over TCP, using port number @samp{uucp} (as found
in @file{/etc/services}; this may be specified as a number), using
remote host @file{@var{host}.@var{domain}}, with some chat script.
+@samp{port family @var{xxx}} command is not supported by V2
+configuration files or HDB configuration files. So, with these
+configuration files, IPv6 is disabled for compatibility reason.
+
@node TCP Server, , TCP Client, UUCP Over TCP
@subsection Running a TCP Server
@@ -5525,6 +5544,15 @@ child for each one. Each connection will be prompted with @samp{login:}
and @samp{Password:}; the results will be checked against the UUCP (not
the system) password file (@pxref{Configuration File Names}).
+By default UUCP will listen on both IPv4 and IPv6. You can set the
+protocol family to listen with the command @samp{port family @var{xxx}},
+where @var{xxx} can be @samp{inet} for IPv4 only, @samp{inet6} for IPv6
+only or @samp{inet46} for both IPv4 and IPv6.
+
+@samp{port family @var{xxx}} command is not supported by V2
+configuration files or HDB configuration files. So, with these
+configuration files, IPv6 is disabled for compatibility reason.
+
Another way to run a UUCP TCP server is to use the BSD @code{uucpd}
program.
diff --git a/gnu/libexec/uucp/libunix/tcp.c b/gnu/libexec/uucp/libunix/tcp.c
index 0791900..595b414 100644
--- a/gnu/libexec/uucp/libunix/tcp.c
+++ b/gnu/libexec/uucp/libunix/tcp.c
@@ -63,7 +63,7 @@ const char tcp_rcsid[] = "$FreeBSD$";
interface. */
/* The normal "uucp" port number. */
-#define IUUCP_PORT (540)
+#define IUUCP_PORT "540"
/* Local functions. */
static void utcp_free P((struct sconnection *qconn));
@@ -78,7 +78,9 @@ static boolean ftcp_dial P((struct sconnection *qconn, pointer puuconf,
const char *zphone,
struct uuconf_dialer *qdialer,
enum tdialerfound *ptdialer));
-static int itcp_port_number P((const char *zport));
+static int itcp_getaddrinfo P((const char *zhost, const char *zport,
+ const struct addrinfo *hints,
+ struct addrinfo **res));
/* The command table for a TCP connection. */
static const struct sconncmds stcpcmds =
@@ -131,34 +133,13 @@ utcp_free (qconn)
{
xfree (qconn->psysdep);
}
-
-/* Open a TCP connection. If the fwait argument is TRUE, we are
- running as a server. Otherwise we are just trying to reach another
- system. */
static boolean
-ftcp_open (qconn, ibaud, fwait)
- struct sconnection *qconn;
- long ibaud;
- boolean fwait;
+utcp_init (qsysdep)
+ struct ssysdep_conn *qsysdep;
{
- struct ssysdep_conn *qsysdep;
- struct sockaddr_in s;
- const char *zport;
- uid_t ieuid;
- boolean fswap;
-
- ulog_device ("TCP");
-
- qsysdep = (struct ssysdep_conn *) qconn->psysdep;
-
- qsysdep->o = socket (AF_INET, SOCK_STREAM, 0);
- if (qsysdep->o < 0)
- {
- ulog (LOG_ERROR, "socket: %s", strerror (errno));
- return FALSE;
- }
-
+ if (!qsysdep)
+ return FALSE;
if (fcntl (qsysdep->o, F_SETFD,
fcntl (qsysdep->o, F_GETFD, 0) | FD_CLOEXEC) < 0)
{
@@ -176,6 +157,32 @@ ftcp_open (qconn, ibaud, fwait)
qsysdep->o = -1;
return FALSE;
}
+}
+
+/* Open a TCP connection. If the fwait argument is TRUE, we are
+ running as a server. Otherwise we are just trying to reach another
+ system. */
+
+static boolean
+ftcp_open (qconn, ibaud, fwait)
+ struct sconnection *qconn;
+ long ibaud;
+ boolean fwait;
+{
+ struct ssysdep_conn *qsysdep;
+ struct addrinfo hints, *res, *res0;
+ struct sockaddr_storage s;
+ const char *zport;
+ int zfamily;
+ uid_t ieuid;
+ boolean fswap;
+ int err;
+
+ ulog_device ("TCP");
+
+ qsysdep = (struct ssysdep_conn *) qconn->psysdep;
+
+ qsysdep->o = -1;
/* We save our process ID in the qconn structure. This is checked
in ftcp_close. */
@@ -190,11 +197,68 @@ ftcp_open (qconn, ibaud, fwait)
From this point on if the server gets an error we exit; we only
return if we have received a connection. It would be more robust
to respawn the server if it fails; someday. */
- bzero ((pointer) &s, sizeof s);
- s.sin_family = AF_INET;
zport = qconn->qport->uuconf_u.uuconf_stcp.uuconf_zport;
- s.sin_port = itcp_port_number (zport);
- s.sin_addr.s_addr = htonl (INADDR_ANY);
+ zfamily = qconn->qport->uuconf_u.uuconf_stcp.uuconf_zfamily;
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_family = zfamily;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_flags = AI_PASSIVE;
+ if ((err = itcp_getaddrinfo (NULL, zport, &hints, &res0)) != 0)
+ {
+ ulog (LOG_ERROR, "getaddrinfo (NULL, %s): %s",
+ zport, gai_strerror (err));
+ return FALSE;
+ }
+#if HAVE_GETADDRINFO
+ if (zfamily == PF_UNSPEC)
+ {
+ for (res = res0; res; res = res->ai_next)
+ {
+ if (res->ai_family == AF_INET6)
+ {
+ qsysdep->o = socket (res->ai_family, res->ai_socktype,
+ res->ai_protocol);
+ if (qsysdep->o >= 0)
+ break;
+ }
+ }
+ }
+#endif
+ if (qsysdep->o < 0)
+ {
+ for (res = res0; res; res = res->ai_next)
+ {
+ qsysdep->o = socket (res->ai_family, res->ai_socktype,
+ res->ai_protocol);
+ if (qsysdep->o >= 0)
+ break;
+ }
+ if (qsysdep->o < 0)
+ {
+ freeaddrinfo (res);
+ ulog (LOG_ERROR, "socket: %s", strerror (errno));
+ return FALSE;
+ }
+ }
+#ifdef IPV6_BINDV6ONLY
+ if (res->ai_family == AF_INET6)
+ {
+ int flag = (zfamily == PF_UNSPEC) ? 0 : 1;
+
+ if (setsockopt (qsysdep->o, IPPROTO_IPV6, IPV6_BINDV6ONLY,
+ (char *)&flag, sizeof (flag)) < 0)
+ {
+ freeaddrinfo (res);
+ ulog (LOG_FATAL, "setsockopt: %s", strerror (errno));
+ return FALSE;
+ }
+ }
+#endif
+ if (!utcp_init (qsysdep))
+ {
+ freeaddrinfo (res);
+ return FALSE;
+ }
/* Swap to our real user ID when doing the bind call. This will
permit the server to use privileged TCP ports when invoked by
@@ -208,16 +272,19 @@ ftcp_open (qconn, ibaud, fwait)
{
(void) close (qsysdep->o);
qsysdep->o = -1;
+ freeaddrinfo (res);
return FALSE;
}
}
- if (bind (qsysdep->o, (struct sockaddr *) &s, sizeof s) < 0)
+ if (bind (qsysdep->o, res->ai_addr, res->ai_addrlen) < 0)
{
+ freeaddrinfo (res);
if (fswap)
(void) fsuucp_perms ((long) ieuid);
ulog (LOG_FATAL, "bind: %s", strerror (errno));
}
+ freeaddrinfo (res);
/* Now swap back to the uucp user ID. */
if (fswap)
@@ -333,8 +400,8 @@ ftcp_dial (qconn, puuconf, qsys, zphone, qdialer, ptdialer)
{
struct ssysdep_conn *qsysdep;
const char *zhost;
- struct hostent *q;
- struct sockaddr_in s;
+ struct addrinfo hints, *res, *res0;
+ int err, connected = FALSE;
const char *zport;
char **pzdialer;
@@ -354,37 +421,38 @@ ftcp_dial (qconn, puuconf, qsys, zphone, qdialer, ptdialer)
}
errno = 0;
- q = gethostbyname ((char *) zhost);
- if (q != NULL)
+ zport = qconn->qport->uuconf_u.uuconf_stcp.uuconf_zport;
+ memset (&hints, 0, sizeof(hints));
+ hints.ai_family = qconn->qport->uuconf_u.uuconf_stcp.uuconf_zfamily;
+ hints.ai_socktype = SOCK_STREAM;
+ hints.ai_protocol = 0;
+ if ((err = itcp_getaddrinfo (zhost, zport, &hints, &res0)) != 0)
{
- s.sin_family = q->h_addrtype;
- memcpy (&s.sin_addr.s_addr, q->h_addr, (size_t) q->h_length);
+ ulog (LOG_ERROR, "getaddrinfo (%s, %s): %s",
+ zhost, zport, gai_strerror (err));
+ return FALSE;
}
- else
- {
- if (errno != 0)
- {
- ulog (LOG_ERROR, "gethostbyname (%s): %s", zhost, strerror (errno));
- return FALSE;
- }
- s.sin_family = AF_INET;
- s.sin_addr.s_addr = inet_addr ((char *) zhost);
- if ((long) s.sin_addr.s_addr == (long) -1)
- {
- ulog (LOG_ERROR, "%s: unknown host name", zhost);
- return FALSE;
+ for (res = res0; res; res = res->ai_next)
+ {
+ qsysdep->o = socket (res->ai_family, res->ai_socktype, res->ai_protocol);
+ if (qsysdep->o < 0)
+ continue;
+ if (connect (qsysdep->o, res->ai_addr, res->ai_addrlen) >= 0)
+ {
+ connected = TRUE;
+ break;
}
+ close (qsysdep->o);
}
-
- zport = qconn->qport->uuconf_u.uuconf_stcp.uuconf_zport;
- s.sin_port = itcp_port_number (zport);
-
- if (connect (qsysdep->o, (struct sockaddr *) &s, sizeof s) < 0)
+ freeaddrinfo (res0);
+ if (!connected)
{
ulog (LOG_ERROR, "connect: %s", strerror (errno));
return FALSE;
}
+ if (!utcp_init (qsysdep))
+ return FALSE;
/* Handle the dialer sequence, if any. */
pzdialer = qconn->qport->uuconf_u.uuconf_stcp.uuconf_pzdialer;
@@ -398,47 +466,18 @@ ftcp_dial (qconn, puuconf, qsys, zphone, qdialer, ptdialer)
return TRUE;
}
-/* Get the port number given a name. The argument will almost always
- be "uucp" so we cache that value. The return value is always in
- network byte order. This returns -1 on error. */
-
static int
-itcp_port_number (zname)
- const char *zname;
+itcp_getaddrinfo (zhost, zport, hints, res)
+ const char *zhost, *zport;
+ const struct addrinfo *hints;
+ struct addrinfo **res;
{
- boolean fuucp;
- static int iuucp;
- int i;
- char *zend;
- struct servent *q;
-
- fuucp = strcmp (zname, "uucp") == 0;
- if (fuucp && iuucp != 0)
- return iuucp;
-
- /* Try it as a number first. */
- i = strtol ((char *) zname, &zend, 10);
- if (i != 0 && *zend == '\0')
- return htons (i);
-
- q = getservbyname ((char *) zname, (char *) "tcp");
- if (q == NULL)
- {
- /* We know that the "uucp" service should be 540, even if isn't
- in /etc/services. */
- if (fuucp)
- {
- iuucp = htons (IUUCP_PORT);
- return iuucp;
- }
- ulog (LOG_ERROR, "getservbyname (%s): %s", zname, strerror (errno));
- return -1;
- }
-
- if (fuucp)
- iuucp = q->s_port;
+ int err;
- return q->s_port;
+ if ((err = getaddrinfo (zhost, zport, hints, res)) != EAI_SERVICE ||
+ strcmp(zport, "uucp") != 0)
+ return err;
+ return getaddrinfo (zhost, IUUCP_PORT, hints, res);
}
#endif /* HAVE_TCP */
diff --git a/gnu/libexec/uucp/libuuconf/hport.c b/gnu/libexec/uucp/libuuconf/hport.c
index 23d59ab..2836fbc 100644
--- a/gnu/libexec/uucp/libuuconf/hport.c
+++ b/gnu/libexec/uucp/libuuconf/hport.c
@@ -29,6 +29,7 @@
const char _uuconf_hport_rcsid[] = "$FreeBSD$";
#endif
+#include <sys/socket.h>
#include <errno.h>
#include <ctype.h>
@@ -217,6 +218,19 @@ uuconf_hdb_find_port (pglobal, zname, ibaud, ihighbaud, pifn, pinfo, qport)
| UUCONF_RELIABLE_EIGHT | UUCONF_RELIABLE_FULLDUPLEX
| UUCONF_RELIABLE_SPECIFIED);
qport->uuconf_u.uuconf_stcp.uuconf_zport = pzsplit[1];
+
+ /* I leave with IPv4 only for compatibility reason. If
+ you wish to use IPv6, please try Taylor UUCP
+ configuration instead. If you still wish to use IPv6
+ with HDB configuration, re-make with INET6 defined.
+ In this case, you cannot specify the protocol family
+ in HDB configuration file. */
+#ifdef INET6
+ qport->uuconf_u.uuconf_stcp.uuconf_zfamily = PF_UNSPEC;
+#else
+ qport->uuconf_u.uuconf_stcp.uuconf_zfamily = PF_INET;
+#endif
+
ppzdialer = &qport->uuconf_u.uuconf_stcp.uuconf_pzdialer;
}
else if (ctoks >= 5
diff --git a/gnu/libexec/uucp/libuuconf/tportc.c b/gnu/libexec/uucp/libuuconf/tportc.c
index b07d49a..60467bc 100644
--- a/gnu/libexec/uucp/libuuconf/tportc.c
+++ b/gnu/libexec/uucp/libuuconf/tportc.c
@@ -29,6 +29,7 @@
const char _uuconf_tportc_rcsid[] = "$FreeBSD$";
#endif
+#include <sys/socket.h>
#include <errno.h>
static int ipproto_param P((pointer pglobal, int argc, char **argv,
@@ -37,6 +38,8 @@ static int ipbaud_range P((pointer pglobal, int argc, char **argv,
pointer pvar, pointer pinfo));
static int ipdialer P((pointer pglobal, int argc, char **argv, pointer pvar,
pointer pinfo));
+static int ipfamily P((pointer pglobal, int argc, char **argv, pointer pvar,
+ pointer pinfo));
static int ipcunknown P((pointer pglobal, int argc, char **argv,
pointer pvar, pointer pinfo));
@@ -151,6 +154,9 @@ static const struct cmdtab_offset asPtcp_cmds[] =
{ "service", UUCONF_CMDTABTYPE_STRING,
offsetof (struct uuconf_port, uuconf_u.uuconf_stcp.uuconf_zport),
NULL },
+ { "family", UUCONF_CMDTABTYPE_FN | 0,
+ offsetof (struct uuconf_port, uuconf_u.uuconf_stcp.uuconf_zfamily),
+ ipfamily },
{ "dialer-sequence", UUCONF_CMDTABTYPE_FULLSTRING,
offsetof (struct uuconf_port, uuconf_u.uuconf_stcp.uuconf_pzdialer),
NULL },
@@ -279,6 +285,7 @@ _uuconf_iport_cmd (qglobal, argc, argv, qport)
break;
case UUCONF_PORTTYPE_TCP:
qport->uuconf_u.uuconf_stcp.uuconf_zport = (char *) "uucp";
+ qport->uuconf_u.uuconf_stcp.uuconf_zfamily = PF_UNSPEC;
qport->uuconf_u.uuconf_stcp.uuconf_pzdialer = NULL;
qport->uuconf_ireliable = (UUCONF_RELIABLE_SPECIFIED
| UUCONF_RELIABLE_ENDTOEND
@@ -489,6 +496,35 @@ ipdialer (pglobal, argc, argv, pvar, pinfo)
return iret;
}
}
+
+/* Handle a "family" commands. The first argument is "inet" for
+ PF_INET or "inet6" for PF_INET6 */
+
+/*ARGSUSED*/
+static int
+ipfamily (pglobal, argc, argv, pvar, pinfo)
+ pointer pglobal;
+ int argc;
+ char **argv;
+ pointer pvar;
+ pointer pinfo;
+{
+ int *pzfamily = (int *) pvar;
+
+ if (argc < 2)
+ return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT;
+ if (!strcmp(argv[1], "inet"))
+ *pzfamily = PF_INET;
+#if HAVE_GETADDRINFO
+ else if (!strcmp(argv[1], "inet6"))
+ *pzfamily = PF_INET6;
+#endif
+ else if (!strcmp(argv[1], "inet46"))
+ *pzfamily = PF_UNSPEC;
+ else
+ return UUCONF_SYNTAX_ERROR | UUCONF_CMDTABRET_EXIT;
+ return UUCONF_CMDTABRET_KEEP;
+}
/* Give an error for an unknown port command. */
diff --git a/gnu/libexec/uucp/libuuconf/vsinfo.c b/gnu/libexec/uucp/libuuconf/vsinfo.c
index 4ca8005..853ae70 100644
--- a/gnu/libexec/uucp/libuuconf/vsinfo.c
+++ b/gnu/libexec/uucp/libuuconf/vsinfo.c
@@ -29,6 +29,7 @@
const char _uuconf_vsinfo_rcsid[] = "$FreeBSD$";
#endif
+#include <sys/socket.h>
#include <errno.h>
#include <ctype.h>
@@ -271,6 +272,19 @@ _uuconf_iv2_system_internal (qglobal, zsystem, qsys)
else
qset->uuconf_qport->uuconf_u.uuconf_stcp.uuconf_zport
= pzsplit[3];
+
+ /* I leave with IPv4 only for compatibility reason. If you
+ wish to use IPv6, please try Taylor UUCP configuration
+ instead. If you still wish to use IPv6 with V2
+ configuration, re-make with INET6 defined. In this case,
+ you cannot specify the protocol family in V2
+ configuration file. */
+#ifdef INET6
+ qset->uuconf_qport->uuconf_u.uuconf_stcp.uuconf_zfamily = PF_UNSPEC;
+#else
+ qset->uuconf_qport->uuconf_u.uuconf_stcp.uuconf_zfamily = PF_INET;
+#endif
+
qset->uuconf_qport->uuconf_u.uuconf_stcp.uuconf_pzdialer = NULL;
}
OpenPOWER on IntegriCloud