diff options
Diffstat (limited to 'src')
| -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\ |
