You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
304 lines
8.0 KiB
304 lines
8.0 KiB
--- a/docs/nc6.1.in
|
|
+++ b/docs/nc6.1.in
|
|
@@ -160,6 +160,10 @@
|
|
With this option set, netcat6 will use UDP as the transport protocol (TCP is
|
|
the default).
|
|
.TP 13
|
|
+.I \-U, --unix
|
|
+With this option set, netcat6 will connect to a unix domain socket.
|
|
+The listen mode has not been implemented yet.
|
|
+.TP 13
|
|
.I \-v
|
|
Enable verbose mode. This gives some basic information about what netcat6
|
|
is doing. Use it twice for extra verbosity.
|
|
|
|
--- a/src/Makefile.am
|
|
+++ b/src/Makefile.am
|
|
@@ -6,6 +6,7 @@
|
|
network.h \
|
|
afindep.h \
|
|
bluez.h \
|
|
+ unixsocket.h \
|
|
netsupport.h \
|
|
parser.h \
|
|
readwrite.h \
|
|
@@ -20,6 +21,7 @@
|
|
afindep.c \
|
|
netsupport.c \
|
|
parser.c \
|
|
+ unixsocket.c \
|
|
readwrite.c \
|
|
io_stream.c \
|
|
connection.c
|
|
|
|
--- a/src/connection.c
|
|
+++ b/src/connection.c
|
|
@@ -109,6 +109,9 @@
|
|
fatal_internal("unavailable bluez support required");
|
|
#endif
|
|
break;
|
|
+ case PROTO_UNIX:
|
|
+ ainfo->ai_family = PF_UNIX;
|
|
+ break;
|
|
default:
|
|
fatal_internal("unknown socket domain");
|
|
}
|
|
@@ -144,6 +147,10 @@
|
|
fatal_internal("unavailable bluez support required");
|
|
#endif
|
|
break;
|
|
+ case UNIX_PROTOCOL:
|
|
+ ainfo->ai_protocol = 0;
|
|
+ ainfo->ai_socktype = SOCK_STREAM;
|
|
+ break;
|
|
default:
|
|
fatal_internal("unknown socket type");
|
|
}
|
|
|
|
--- a/src/connection.h
|
|
+++ b/src/connection.h 2008-10-25 14:17:09 +0000
|
|
@@ -31,12 +31,14 @@
|
|
PROTO_UNSPECIFIED,
|
|
PROTO_IPv6,
|
|
PROTO_IPv4,
|
|
+ PROTO_UNIX,
|
|
PROTO_BLUEZ
|
|
} sock_family_t;
|
|
|
|
typedef enum sock_protocol {
|
|
TCP_PROTOCOL,
|
|
UDP_PROTOCOL,
|
|
+ UNIX_PROTOCOL,
|
|
SCO_PROTOCOL,
|
|
L2CAP_PROTOCOL
|
|
} sock_protocol_t;
|
|
|
|
--- a/src/network.c
|
|
+++ b/src/network.c
|
|
@@ -23,6 +23,7 @@
|
|
#include "network.h"
|
|
#include "connection.h"
|
|
#include "afindep.h"
|
|
+#include "unixsocket.h"
|
|
#ifdef ENABLE_BLUEZ
|
|
#include "bluez.h"
|
|
#endif/*ENABLE_BLUEZ*/
|
|
@@ -113,6 +114,11 @@
|
|
|
|
/* invoke the appropriate connector for the protocol family */
|
|
switch (ca_family(attrs)) {
|
|
+ case PROTO_UNIX:
|
|
+ fd = unixsocket_connect(&hints,
|
|
+ remote->address,
|
|
+ timeout, &socktype);
|
|
+ break;
|
|
#ifdef ENABLE_BLUEZ
|
|
case PROTO_BLUEZ:
|
|
fd = bluez_connect(&hints,
|
|
|
|
--- a/src/parser.c
|
|
+++ b/src/parser.c
|
|
@@ -109,7 +109,9 @@
|
|
{"bluetooth", no_argument, NULL, 'b'},
|
|
#define OPT_SCO 24
|
|
{"sco", no_argument, NULL, 0 },
|
|
-#define OPT_MAX 25
|
|
+#define OPT_UNIX_SOCKET 25
|
|
+ {"unix", no_argument, NULL, 'U'},
|
|
+#define OPT_MAX 26
|
|
{0, 0, 0, 0}
|
|
};
|
|
|
|
@@ -160,7 +162,7 @@
|
|
_verbosity_level = 0;
|
|
|
|
/* option recognition loop */
|
|
- while ((c = getopt_long(argc, argv, "46be:hlnp:q:s:uvw:xX",
|
|
+ while ((c = getopt_long(argc, argv, "46be:hlnp:q:s:uUvw:xX",
|
|
long_options, &option_index)) >= 0)
|
|
{
|
|
switch (c) {
|
|
@@ -231,6 +233,9 @@
|
|
family = PROTO_IPv6;
|
|
ca_set_flag(attrs, CA_STRICT_IPV6);
|
|
break;
|
|
+ case 'U':
|
|
+ family = PROTO_UNIX;
|
|
+ break;
|
|
case 'b':
|
|
family = PROTO_BLUEZ;
|
|
break;
|
|
@@ -330,6 +335,9 @@
|
|
/* set default protocols */
|
|
if (protocol == PROTO_UNSPECIFIED) {
|
|
switch (family) {
|
|
+ case PROTO_UNIX:
|
|
+ protocol = UNIX_PROTOCOL;
|
|
+ break;
|
|
case PROTO_BLUEZ:
|
|
protocol = L2CAP_PROTOCOL;
|
|
break;
|
|
@@ -344,6 +352,11 @@
|
|
fatal(_("cannot specify UDP protocol and bluetooth"));
|
|
if (protocol == SCO_PROTOCOL && family != PROTO_BLUEZ)
|
|
fatal(_("--sco requires --bluetooth (-b)"));
|
|
+ if (protocol == UNIX_PROTOCOL && family != PROTO_UNIX)
|
|
+ fatal(_("--unix does not need protocol specifications"));
|
|
+
|
|
+ if (family == PROTO_UNIX && listen_mode)
|
|
+ fatal(_("--unix cannot --listen yet"));
|
|
|
|
/* check compiled options */
|
|
#ifndef ENABLE_BLUEZ
|
|
@@ -380,6 +393,10 @@
|
|
fatal_internal("unknown/unsupported bluetooth "
|
|
"protocol %d", protocol);
|
|
break;
|
|
+ case PROTO_UNIX:
|
|
+ if (protocol != UNIX_PROTOCOL)
|
|
+ fatal_internal("unknown/unsupported UNIX protocol %d", protocol);
|
|
+ break;
|
|
default:
|
|
fatal_internal("invalid protocol family %d", family);
|
|
}
|
|
@@ -425,18 +442,18 @@
|
|
fatal(_("cannot set both --recv-only and --send-only"));
|
|
}
|
|
|
|
- /* check ports have not been specified with --sco */
|
|
- if (protocol == SCO_PROTOCOL) {
|
|
+ /* check ports have not been specified with --sco and --unix */
|
|
+ if (protocol == SCO_PROTOCOL || protocol == UNIX_PROTOCOL) {
|
|
if (remote_address.service != NULL)
|
|
- fatal(_("--sco does not support remote port"));
|
|
+ fatal(_("--sco and --unix do not support remote port"));
|
|
if (local_address.service != NULL)
|
|
- fatal(_("--sco does not support local port (-p)"));
|
|
+ fatal(_("--sco and --unix do not support local port (-p)"));
|
|
}
|
|
|
|
/* check mode specific option availability and interactions */
|
|
if (listen_mode == true) {
|
|
/* check port has been specified (except with sco) */
|
|
- if (local_address.service == NULL && protocol != SCO_PROTOCOL) {
|
|
+ if (local_address.service == NULL && protocol != SCO_PROTOCOL && protocol != UNIX_PROTOCOL) {
|
|
fatal(_("in listen mode you must specify a port "
|
|
"with the -p switch"));
|
|
}
|
|
@@ -450,6 +467,7 @@
|
|
/* check port has been specified (except with sco) */
|
|
if (remote_address.address == NULL ||
|
|
(remote_address.service == NULL &&
|
|
+ protocol != UNIX_PROTOCOL &&
|
|
protocol != SCO_PROTOCOL))
|
|
{
|
|
fatal(_("you must specify the address/port couple "
|
|
@@ -553,6 +571,8 @@
|
|
fprintf(fp, " -6 %s\n", _("Use only IPv6"));
|
|
fprintf(fp, " -b, --bluetooth %s\n",
|
|
_("Use Bluetooth (defaults to L2CAP protocol)"));
|
|
+ fprintf(fp, " -U, --unix %s\n",
|
|
+ _("Connect to unix domain sockets"));
|
|
fprintf(fp, " --buffer-size=BYTES %s\n", _("Set buffer size"));
|
|
fprintf(fp, " --continuous %s\n",
|
|
_("Continuously accept connections\n"
|
|
|
|
--- a/src/unixsocket.c
|
|
+++ b/src/unixsocket.c
|
|
@@ -0,0 +1,78 @@
|
|
+/*
|
|
+ * unixsocket.c - address family independant networking functions
|
|
+ */
|
|
+#include "system.h"
|
|
+#include "unixsocket.h"
|
|
+#include "misc.h"
|
|
+#include "netsupport.h"
|
|
+#include "parser.h"
|
|
+
|
|
+#include <assert.h>
|
|
+#include <errno.h>
|
|
+#include <string.h>
|
|
+#include <stdlib.h>
|
|
+#include <sys/types.h>
|
|
+#include <sys/socket.h>
|
|
+#include <sys/un.h>
|
|
+#include <unistd.h>
|
|
+#include <limits.h>
|
|
+
|
|
+RCSID("@(#) $Header: /var/cvsroot/gentoo-x86/net-analyzer/netcat6/files/netcat6-1.0-unix-sockets.patch,v 1.2 2014/07/14 21:39:15 jer Exp $");
|
|
+
|
|
+
|
|
+int unixsocket_connect(const struct addrinfo *hints,
|
|
+ const char *remote_address,
|
|
+ time_t timeout, int *rt_socktype)
|
|
+{
|
|
+ int err, fd = -1;
|
|
+ struct sockaddr_un sa;
|
|
+ const struct addrinfo *ptr = hints;
|
|
+
|
|
+ /* make sure arguments are valid and preconditions are respected */
|
|
+ assert(hints != NULL);
|
|
+ assert(remote_address != NULL && strlen(remote_address) > 0);
|
|
+ assert(sizeof(sa.sun_path) >= strlen(remote_address));
|
|
+
|
|
+ sa.sun_family = ptr->ai_family;
|
|
+ strncpy(sa.sun_path, remote_address, sizeof(sa.sun_path));
|
|
+
|
|
+
|
|
+ /* create the socket */
|
|
+ fd = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol);
|
|
+ if (fd < 0) {
|
|
+ warning("cannot create the socket: %s", strerror(errno));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ /* attempt the connection */
|
|
+ err = connect_with_timeout(fd, (struct sockaddr *)&sa, sizeof(sa), timeout);
|
|
+
|
|
+ if (err != 0)
|
|
+ {
|
|
+ /* check error code */
|
|
+ if (verbose_mode()) {
|
|
+ /* use different error message for timeout */
|
|
+ if (errno == ETIMEDOUT) {
|
|
+ /* connection timed out */
|
|
+ warning(_("timeout while connecting to %s"), remote_address);
|
|
+ }
|
|
+ else {
|
|
+ /* connection failed */
|
|
+ warning(_("cannot connect to %s: %s"), remote_address, strerror(errno));
|
|
+ }
|
|
+ }
|
|
+ close(fd);
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ assert(ptr == NULL || fd >= 0);
|
|
+
|
|
+ /* let the user know the connection has been established */
|
|
+ if (verbose_mode()) warning(_("%s open"), remote_address);
|
|
+
|
|
+ /* return the socktype */
|
|
+ if (rt_socktype != NULL) *rt_socktype = ptr->ai_socktype;
|
|
+
|
|
+ return fd;
|
|
+}
|
|
+
|
|
|
|
--- a/src/unixsocket.h
|
|
+++ b/src/unixsocket.h
|
|
@@ -0,0 +1,12 @@
|
|
+#ifndef UNIXSOCKET_H
|
|
+#define UNIXSOCKET_H
|
|
+
|
|
+#include <netdb.h>
|
|
+#include <sys/types.h>
|
|
+
|
|
+/* establish a connection and return a new fd and socktype */
|
|
+int unixsocket_connect(const struct addrinfo *hints,
|
|
+ const char *remote_address,
|
|
+ time_t timeout, int *socktype);
|
|
+
|
|
+#endif
|
|
|