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.
gentoo-overlay/net-analyzer/netcat6/files/netcat6-1.0-unix-sockets.patch

304 lines
7.9 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("@(#) $Id$");
+
+
+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