netcat: Local socket support
Denys Vlasenko
vda.linux at googlemail.com
Wed Apr 22 00:17:16 UTC 2009
Hi Ingo,
Sorry for the delay :(
On Thursday 19 March 2009 13:31, Ingo van Lil wrote:
> I have created a little patch to add support for local (Unix domain)
> socket connections to Busybox's netcat implementation. An equivalent
> feature is available in the OpenBSD version of netcat [1], which is
> packaged by Fedora.
Unfortunately, you patched nc.c instead of nc_bloaty.c,
and nc_bloaty.c is supposed to have "all bells and whistles"
and be compatible, not "small" nc.c
Adding 128-byte struct sockaddr_un to len_and_sockaddr like this:
typedef struct len_and_sockaddr {
socklen_t len;
union {
struct sockaddr sa;
+ struct sockaddr_un sun;
struct sockaddr_in sin;
will bloat stack and other data for many unrelated applets.
Since you malloc your lsa, you can work around this.
Connecting to UNIX domain socket like this:
- cfd = create_and_connect_stream_or_die(argv[0],
- argv[1] ? bb_lookup_port(argv[1], "tcp", 0) : 0);
+ if (do_local) {
+ lsa = xzalloc(sizeof(*lsa));
+ lsa->len = sizeof(lsa->u.sun);
+ lsa->u.sa.sa_family = AF_UNIX;
+ safe_strncpy(lsa->u.sun.sun_path,
+ argv[0], sizeof(lsa->u.sun.sun_path));
+ cfd = xsocket(AF_UNIX, SOCK_STREAM, 0);
+ xconnect(cfd, &lsa->u.sa, lsa->len);
+ free(lsa);
+ } else {
+ cfd = create_and_connect_stream_or_die(argv[0],
+ argv[1] ? bb_lookup_port(argv[1], "tcp", 0) : 0);
+ }
defeats the whole purpose of len_and_sockaddr data type
and create_and_connect_stream_or_die(name, port) function,
which is _supposed_ to_ derive the type of socket
(AF_INET? AF_INET6? AF_UNIX?...) by looking at its arguments.
Currently, it understands IP and IPv6.
In order to make _all_ network utilities AF_UNIX capable,
it's much better to teach create_and_connect_stream_or_die
to understand some sort of AF_UNIX name.
It can be "unix:" or "local:" prefix, and/or
special port value (although this feels more like a hack,
since port param should not have been there in the first place,
it can be specified in 1st argument, name: "1.2.3.4:56",
"[12:34::56:78]:90" (IPv6), and we do understand these forms)
Unfortunately there is no standard for this syntax. Pity.
We need to invent our own, and then shoehorn nc -U into using it
internally:
echo "hi syslog!" | nc -U /dev/log >/dev/null
and internally nc.c does:
if (option -U is given)
peer_name = xasprintf("local:%s", peer_name);
Tht's *all* what nc.c needs to do to support -U.
The rest is handled in create_and_connect_stream_or_die!
And then you also can do this:
echo "hi syslog!" | nc local:/dev/log >/dev/null
Or this:
httpd -p local:/var/run/httpd.socket
Or this:
tcpsvd -vE local:/var/run/telnet.socket 0 telnetd -i
> Additionally, the patch fixes a minor memleak in
> nc's server mode, where the sockaddr_and_len structure allocated by
> xsocket_stream() isn't freed.
Thanks, took this fix.
--
vda
More information about the busybox
mailing list