diff options
-rw-r--r-- | src/usr.bin/nc/nc.1 | 10 | ||||
-rw-r--r-- | src/usr.bin/nc/netcat.c | 114 |
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. | |||
139 | Specifies that | 139 | Specifies that |
140 | .Nm | 140 | .Nm |
141 | should just scan for listening daemons, without sending any data to them. | 141 | should just scan for listening daemons, without sending any data to them. |
142 | .It Fl U | ||
143 | Specifies 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. | |||
176 | Connect to port 1000 of hostname, send the string "foobar" | 178 | Connect to port 1000 of hostname, send the string "foobar" |
177 | followed by a newline, and move data from port 1000 of hostname to | 179 | followed by a newline, and move data from port 1000 of hostname to |
178 | stdout until hostname closes the connection. | 180 | stdout until hostname closes the connection. |
181 | .It Li "nc -U /var/tmp/dsocket" | ||
182 | Connect to a Unix Domain Socket. | ||
183 | .It Li "nc -lU /var/tmp/dsocket" | ||
184 | Create 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); | |||
76 | void readwrite(int); | 78 | void readwrite(int); |
77 | int remote_connect(char *, char *, struct addrinfo); | 79 | int remote_connect(char *, char *, struct addrinfo); |
78 | int udptest(int); | 80 | int udptest(int); |
81 | int unix_connect(char *); | ||
82 | int unix_listen(char *); | ||
79 | void usage(int); | 83 | void usage(int); |
80 | 84 | ||
81 | int | 85 | int |
@@ -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 | */ | ||
352 | int | ||
353 | unix_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 | */ | ||
379 | int | ||
380 | unix_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\ |