diff options
author | Eric Jackson <ericj@cvs.openbsd.org> | 2002-02-17 03:03:07 +0000 |
---|---|---|
committer | Eric Jackson <ericj@cvs.openbsd.org> | 2002-02-17 03:03:07 +0000 |
commit | 31dad924e534efcc96721b9bc79b973d72135366 (patch) | |
tree | 5c4a9c05b6b06bd200f073b9538229a0295a37da /usr.bin | |
parent | 7d77b876dd5f005f98482cdb1d04ff6e5eebf65e (diff) |
add support for connecting too and listening on AF_UNIX sockets.
connect support from dave@arbor.net.. rest by me
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/nc/nc.1 | 10 | ||||
-rw-r--r-- | usr.bin/nc/netcat.c | 114 |
2 files changed, 111 insertions, 13 deletions
diff --git a/usr.bin/nc/nc.1 b/usr.bin/nc/nc.1 index 3025e99c4b9..721a2c48963 100644 --- a/usr.bin/nc/nc.1 +++ b/usr.bin/nc/nc.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: nc.1,v 1.19 2001/09/02 18:45:41 jakob Exp $ +.\" $OpenBSD: nc.1,v 1.20 2002/02/17 03:03:06 ericj Exp $ .\" .\" Copyright (c) 1996 David Sacerdote .\" All rights reserved. @@ -33,7 +33,7 @@ .Nd "arbitrary TCP and UDP connections and listens" .Sh SYNOPSIS .Nm nc -.Op Fl 46hklnrtuvz +.Op Fl 46hklnrtuvzU .Op Fl i Ar interval .Op Fl p Ar source port .Op Fl s Ar source ip address @@ -139,6 +139,8 @@ If port is not specified, port 1080 is used. Specifies that .Nm should just scan for listening daemons, without sending any data to them. +.It Fl U +Specifies to use Unix Domain Sockets. .El .Sh EXAMPLES .Bl -tag -width x @@ -176,6 +178,10 @@ the remote host, and send data from the remote host to stdout. Connect to port 1000 of hostname, send the string "foobar" followed by a newline, and move data from port 1000 of hostname to stdout until hostname closes the connection. +.It Li "nc -U /var/tmp/dsocket" +Connect to a Unix Domain Socket. +.It Li "nc -lU /var/tmp/dsocket" +Create and listen on a Unix Domain Socket. .El .Sh SEE ALSO .Xr cat 1 , diff --git a/usr.bin/nc/netcat.c b/usr.bin/nc/netcat.c index 51d2501ccbb..f95eb16e099 100644 --- a/usr.bin/nc/netcat.c +++ b/usr.bin/nc/netcat.c @@ -1,4 +1,4 @@ -/* $OpenBSD: netcat.c,v 1.41 2002/02/17 02:04:57 ericj Exp $ */ +/* $OpenBSD: netcat.c,v 1.42 2002/02/17 03:03:06 ericj Exp $ */ /* * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> * @@ -34,6 +34,7 @@ #include <sys/types.h> #include <sys/socket.h> #include <sys/time.h> +#include <sys/un.h> #include <netinet/in.h> #include <arpa/telnet.h> @@ -47,6 +48,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <fcntl.h> #define PORT_MAX 65535 @@ -76,6 +78,8 @@ int local_listen(char *, char *, struct addrinfo); void readwrite(int); int remote_connect(char *, char *, struct addrinfo); int udptest(int); +int unix_connect(char *); +int unix_listen(char *); void usage(int); int @@ -98,7 +102,7 @@ main(int argc, char *argv[]) endp = NULL; sv = NULL; - while ((ch = getopt(argc, argv, "46hi:klnp:rs:tuvw:x:z")) != -1) { + while ((ch = getopt(argc, argv, "46Uhi:klnp:rs:tuvw:x:z")) != -1) { switch (ch) { case '4': family = AF_INET; @@ -106,6 +110,9 @@ main(int argc, char *argv[]) case '6': family = AF_INET6; break; + case 'U': + family = AF_UNIX; + break; case 'h': help(); break; @@ -161,7 +168,12 @@ main(int argc, char *argv[]) argv += optind; /* Cruft to make sure options are clean, and used properly. */ - if (argv[0] && !argv[1]) { + if (argv[0] && !argv[1] && family == AF_UNIX) { + if (uflag) + errx(1, "cannot use -u and -U"); + host = argv[0]; + uport = NULL; + } else if (argv[0] && !argv[1]) { if (!lflag) usage(1); uport = argv[0]; @@ -182,12 +194,15 @@ main(int argc, char *argv[]) errx(1, "must use -l with -k"); /* Initialize addrinfo structure */ - memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_family = family; - hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; - hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; - if (nflag) - hints.ai_flags |= AI_NUMERICHOST; + if (family != AF_UNIX) { + memset(&hints, 0, sizeof(struct addrinfo)); + hints.ai_family = family; + hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; + hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; + if (nflag) + hints.ai_flags |= AI_NUMERICHOST; + } + if (xflag) { if (uflag) @@ -196,6 +211,9 @@ main(int argc, char *argv[]) if (lflag) errx(1, "no proxy support for listen"); + if (family == AF_UNIX) + errx(1, "no proxy support for unix sockets"); + /* XXX IPv6 transport to proxy would probably work */ if (family == AF_INET6) errx(1, "no proxy support for IPv6"); @@ -218,9 +236,14 @@ main(int argc, char *argv[]) int connfd; ret = 0; + if (family == AF_UNIX) + s = unix_listen(host); + /* Allow only one connection at a time, but stay alive */ for (;;) { - if ((s = local_listen(host, uport, hints)) < 0) + if (family != AF_UNIX) + s = local_listen(host, uport, hints); + if (s < 0) err(1, NULL); /* * For UDP, we will use recvfrom() initially @@ -250,11 +273,23 @@ main(int argc, char *argv[]) readwrite(connfd); close(connfd); - close(s); + if (family != AF_UNIX) + close(s); if (!kflag) break; } + } else if (family == AF_UNIX) { + ret = 0; + + if ((s = unix_connect(host)) > 0 && !zflag) { + readwrite(s); + close(s); + } else + ret = 1; + + exit(ret); + } else { int i = 0; @@ -311,6 +346,62 @@ main(int argc, char *argv[]) } /* + * unix_connect() + * Return's a socket connected to a local unix socket. Return's -1 on failure. + */ +int +unix_connect(char *path) +{ + struct sockaddr_un sun; + int s; + + if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + return (-1); + (void)fcntl(s, F_SETFD, 1); + + memset(&sun, 0, sizeof(struct sockaddr_un)); + sun.sun_len = sizeof(path); + sun.sun_family = AF_UNIX; + strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); + + if (connect(s, (struct sockaddr *)&sun, sizeof(sun)) < 0) { + close(s); + return (-1); + } + return (s); + +} + +/* + * unix_listen() + * create a unix domain socket, and listen on it. + */ +int +unix_listen(char *path) +{ + struct sockaddr_un sun; + int s; + + /* create unix domain socket */ + if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + return (-1); + + sun.sun_family = AF_UNIX; + strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); + + if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { + close(s); + return (-1); + } + + if (listen(s, 5) < 0) { + close(s); + return (-1); + } + return (s); +} + +/* * remote_connect() * Return's a socket connected to a remote host. Properly bind's to a local * port or source address if needed. Return's -1 on failure. @@ -598,6 +689,7 @@ help() fprintf(stderr, "\tCommand Summary:\n\ \t-4 Use IPv4\n\ \t-6 Use IPv6\n\ + \t-U Use UNIX domain socket\n\ \t-h This help text\n\ \t-i secs\t Delay interval for lines sent, ports scanned\n\ \t-k Keep inbound sockets open for multiple connects\n\ |