summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/usr.bin/nc/nc.110
-rw-r--r--src/usr.bin/nc/netcat.c114
2 files changed, 111 insertions, 13 deletions
diff --git a/src/usr.bin/nc/nc.1 b/src/usr.bin/nc/nc.1
index 3025e99c4b..721a2c4896 100644
--- a/src/usr.bin/nc/nc.1
+++ b/src/usr.bin/nc/nc.1
@@ -1,4 +1,4 @@
1.\" $OpenBSD: nc.1,v 1.19 2001/09/02 18:45:41 jakob Exp $ 1.\" $OpenBSD: nc.1,v 1.20 2002/02/17 03:03:06 ericj Exp $
2.\" 2.\"
3.\" Copyright (c) 1996 David Sacerdote 3.\" Copyright (c) 1996 David Sacerdote
4.\" All rights reserved. 4.\" All rights reserved.
@@ -33,7 +33,7 @@
33.Nd "arbitrary TCP and UDP connections and listens" 33.Nd "arbitrary TCP and UDP connections and listens"
34.Sh SYNOPSIS 34.Sh SYNOPSIS
35.Nm nc 35.Nm nc
36.Op Fl 46hklnrtuvz 36.Op Fl 46hklnrtuvzU
37.Op Fl i Ar interval 37.Op Fl i Ar interval
38.Op Fl p Ar source port 38.Op Fl p Ar source port
39.Op Fl s Ar source ip address 39.Op Fl s Ar source ip address
@@ -139,6 +139,8 @@ If port is not specified, port 1080 is used.
139Specifies that 139Specifies that
140.Nm 140.Nm
141should just scan for listening daemons, without sending any data to them. 141should just scan for listening daemons, without sending any data to them.
142.It Fl U
143Specifies to use Unix Domain Sockets.
142.El 144.El
143.Sh EXAMPLES 145.Sh EXAMPLES
144.Bl -tag -width x 146.Bl -tag -width x
@@ -176,6 +178,10 @@ the remote host, and send data from the remote host to stdout.
176Connect to port 1000 of hostname, send the string "foobar" 178Connect to port 1000 of hostname, send the string "foobar"
177followed by a newline, and move data from port 1000 of hostname to 179followed by a newline, and move data from port 1000 of hostname to
178stdout until hostname closes the connection. 180stdout until hostname closes the connection.
181.It Li "nc -U /var/tmp/dsocket"
182Connect to a Unix Domain Socket.
183.It Li "nc -lU /var/tmp/dsocket"
184Create and listen on a Unix Domain Socket.
179.El 185.El
180.Sh SEE ALSO 186.Sh SEE ALSO
181.Xr cat 1 , 187.Xr cat 1 ,
diff --git a/src/usr.bin/nc/netcat.c b/src/usr.bin/nc/netcat.c
index 51d2501ccb..f95eb16e09 100644
--- a/src/usr.bin/nc/netcat.c
+++ b/src/usr.bin/nc/netcat.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: netcat.c,v 1.41 2002/02/17 02:04:57 ericj Exp $ */ 1/* $OpenBSD: netcat.c,v 1.42 2002/02/17 03:03:06 ericj Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> 3 * Copyright (c) 2001 Eric Jackson <ericj@monkey.org>
4 * 4 *
@@ -34,6 +34,7 @@
34#include <sys/types.h> 34#include <sys/types.h>
35#include <sys/socket.h> 35#include <sys/socket.h>
36#include <sys/time.h> 36#include <sys/time.h>
37#include <sys/un.h>
37 38
38#include <netinet/in.h> 39#include <netinet/in.h>
39#include <arpa/telnet.h> 40#include <arpa/telnet.h>
@@ -47,6 +48,7 @@
47#include <stdlib.h> 48#include <stdlib.h>
48#include <string.h> 49#include <string.h>
49#include <unistd.h> 50#include <unistd.h>
51#include <fcntl.h>
50 52
51#define PORT_MAX 65535 53#define PORT_MAX 65535
52 54
@@ -76,6 +78,8 @@ int local_listen(char *, char *, struct addrinfo);
76void readwrite(int); 78void readwrite(int);
77int remote_connect(char *, char *, struct addrinfo); 79int remote_connect(char *, char *, struct addrinfo);
78int udptest(int); 80int udptest(int);
81int unix_connect(char *);
82int unix_listen(char *);
79void usage(int); 83void usage(int);
80 84
81int 85int
@@ -98,7 +102,7 @@ main(int argc, char *argv[])
98 endp = NULL; 102 endp = NULL;
99 sv = NULL; 103 sv = NULL;
100 104
101 while ((ch = getopt(argc, argv, "46hi:klnp:rs:tuvw:x:z")) != -1) { 105 while ((ch = getopt(argc, argv, "46Uhi:klnp:rs:tuvw:x:z")) != -1) {
102 switch (ch) { 106 switch (ch) {
103 case '4': 107 case '4':
104 family = AF_INET; 108 family = AF_INET;
@@ -106,6 +110,9 @@ main(int argc, char *argv[])
106 case '6': 110 case '6':
107 family = AF_INET6; 111 family = AF_INET6;
108 break; 112 break;
113 case 'U':
114 family = AF_UNIX;
115 break;
109 case 'h': 116 case 'h':
110 help(); 117 help();
111 break; 118 break;
@@ -161,7 +168,12 @@ main(int argc, char *argv[])
161 argv += optind; 168 argv += optind;
162 169
163 /* Cruft to make sure options are clean, and used properly. */ 170 /* Cruft to make sure options are clean, and used properly. */
164 if (argv[0] && !argv[1]) { 171 if (argv[0] && !argv[1] && family == AF_UNIX) {
172 if (uflag)
173 errx(1, "cannot use -u and -U");
174 host = argv[0];
175 uport = NULL;
176 } else if (argv[0] && !argv[1]) {
165 if (!lflag) 177 if (!lflag)
166 usage(1); 178 usage(1);
167 uport = argv[0]; 179 uport = argv[0];
@@ -182,12 +194,15 @@ main(int argc, char *argv[])
182 errx(1, "must use -l with -k"); 194 errx(1, "must use -l with -k");
183 195
184 /* Initialize addrinfo structure */ 196 /* Initialize addrinfo structure */
185 memset(&hints, 0, sizeof(struct addrinfo)); 197 if (family != AF_UNIX) {
186 hints.ai_family = family; 198 memset(&hints, 0, sizeof(struct addrinfo));
187 hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; 199 hints.ai_family = family;
188 hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; 200 hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM;
189 if (nflag) 201 hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP;
190 hints.ai_flags |= AI_NUMERICHOST; 202 if (nflag)
203 hints.ai_flags |= AI_NUMERICHOST;
204 }
205
191 206
192 if (xflag) { 207 if (xflag) {
193 if (uflag) 208 if (uflag)
@@ -196,6 +211,9 @@ main(int argc, char *argv[])
196 if (lflag) 211 if (lflag)
197 errx(1, "no proxy support for listen"); 212 errx(1, "no proxy support for listen");
198 213
214 if (family == AF_UNIX)
215 errx(1, "no proxy support for unix sockets");
216
199 /* XXX IPv6 transport to proxy would probably work */ 217 /* XXX IPv6 transport to proxy would probably work */
200 if (family == AF_INET6) 218 if (family == AF_INET6)
201 errx(1, "no proxy support for IPv6"); 219 errx(1, "no proxy support for IPv6");
@@ -218,9 +236,14 @@ main(int argc, char *argv[])
218 int connfd; 236 int connfd;
219 ret = 0; 237 ret = 0;
220 238
239 if (family == AF_UNIX)
240 s = unix_listen(host);
241
221 /* Allow only one connection at a time, but stay alive */ 242 /* Allow only one connection at a time, but stay alive */
222 for (;;) { 243 for (;;) {
223 if ((s = local_listen(host, uport, hints)) < 0) 244 if (family != AF_UNIX)
245 s = local_listen(host, uport, hints);
246 if (s < 0)
224 err(1, NULL); 247 err(1, NULL);
225 /* 248 /*
226 * For UDP, we will use recvfrom() initially 249 * For UDP, we will use recvfrom() initially
@@ -250,11 +273,23 @@ main(int argc, char *argv[])
250 273
251 readwrite(connfd); 274 readwrite(connfd);
252 close(connfd); 275 close(connfd);
253 close(s); 276 if (family != AF_UNIX)
277 close(s);
254 278
255 if (!kflag) 279 if (!kflag)
256 break; 280 break;
257 } 281 }
282 } else if (family == AF_UNIX) {
283 ret = 0;
284
285 if ((s = unix_connect(host)) > 0 && !zflag) {
286 readwrite(s);
287 close(s);
288 } else
289 ret = 1;
290
291 exit(ret);
292
258 } else { 293 } else {
259 int i = 0; 294 int i = 0;
260 295
@@ -311,6 +346,62 @@ main(int argc, char *argv[])
311} 346}
312 347
313/* 348/*
349 * unix_connect()
350 * Return's a socket connected to a local unix socket. Return's -1 on failure.
351 */
352int
353unix_connect(char *path)
354{
355 struct sockaddr_un sun;
356 int s;
357
358 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
359 return (-1);
360 (void)fcntl(s, F_SETFD, 1);
361
362 memset(&sun, 0, sizeof(struct sockaddr_un));
363 sun.sun_len = sizeof(path);
364 sun.sun_family = AF_UNIX;
365 strlcpy(sun.sun_path, path, sizeof(sun.sun_path));
366
367 if (connect(s, (struct sockaddr *)&sun, sizeof(sun)) < 0) {
368 close(s);
369 return (-1);
370 }
371 return (s);
372
373}
374
375/*
376 * unix_listen()
377 * create a unix domain socket, and listen on it.
378 */
379int
380unix_listen(char *path)
381{
382 struct sockaddr_un sun;
383 int s;
384
385 /* create unix domain socket */
386 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
387 return (-1);
388
389 sun.sun_family = AF_UNIX;
390 strlcpy(sun.sun_path, path, sizeof(sun.sun_path));
391
392 if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
393 close(s);
394 return (-1);
395 }
396
397 if (listen(s, 5) < 0) {
398 close(s);
399 return (-1);
400 }
401 return (s);
402}
403
404/*
314 * remote_connect() 405 * remote_connect()
315 * Return's a socket connected to a remote host. Properly bind's to a local 406 * Return's a socket connected to a remote host. Properly bind's to a local
316 * port or source address if needed. Return's -1 on failure. 407 * port or source address if needed. Return's -1 on failure.
@@ -598,6 +689,7 @@ help()
598 fprintf(stderr, "\tCommand Summary:\n\ 689 fprintf(stderr, "\tCommand Summary:\n\
599 \t-4 Use IPv4\n\ 690 \t-4 Use IPv4\n\
600 \t-6 Use IPv6\n\ 691 \t-6 Use IPv6\n\
692 \t-U Use UNIX domain socket\n\
601 \t-h This help text\n\ 693 \t-h This help text\n\
602 \t-i secs\t Delay interval for lines sent, ports scanned\n\ 694 \t-i secs\t Delay interval for lines sent, ports scanned\n\
603 \t-k Keep inbound sockets open for multiple connects\n\ 695 \t-k Keep inbound sockets open for multiple connects\n\