summaryrefslogtreecommitdiff
path: root/src/usr.bin/nc/netcat.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/usr.bin/nc/netcat.c')
-rw-r--r--src/usr.bin/nc/netcat.c90
1 files changed, 67 insertions, 23 deletions
diff --git a/src/usr.bin/nc/netcat.c b/src/usr.bin/nc/netcat.c
index e471182b2a..7b9fe41ba4 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.98 2010/07/03 04:44:51 guenther Exp $ */ 1/* $OpenBSD: netcat.c,v 1.99 2011/01/08 00:44:19 jeremy Exp $ */
2/* 2/*
3 * Copyright (c) 2001 Eric Jackson <ericj@monkey.org> 3 * Copyright (c) 2001 Eric Jackson <ericj@monkey.org>
4 * 4 *
@@ -62,6 +62,7 @@
62 62
63#define PORT_MAX 65535 63#define PORT_MAX 65535
64#define PORT_MAX_LEN 6 64#define PORT_MAX_LEN 6
65#define UNIX_DG_TMP_SOCKET_SIZE 19
65 66
66/* Command Line Options */ 67/* Command Line Options */
67int dflag; /* detached, no stdin */ 68int dflag; /* detached, no stdin */
@@ -89,6 +90,7 @@ u_int rtableid;
89int timeout = -1; 90int timeout = -1;
90int family = AF_UNSPEC; 91int family = AF_UNSPEC;
91char *portlist[PORT_MAX+1]; 92char *portlist[PORT_MAX+1];
93char *unix_dg_tmp_socket;
92 94
93void atelnet(int, unsigned char *, unsigned int); 95void atelnet(int, unsigned char *, unsigned int);
94void build_ports(char *); 96void build_ports(char *);
@@ -99,6 +101,7 @@ int remote_connect(const char *, const char *, struct addrinfo);
99int socks_connect(const char *, const char *, struct addrinfo, 101int socks_connect(const char *, const char *, struct addrinfo,
100 const char *, const char *, struct addrinfo, int, const char *); 102 const char *, const char *, struct addrinfo, int, const char *);
101int udptest(int); 103int udptest(int);
104int unix_bind(char *);
102int unix_connect(char *); 105int unix_connect(char *);
103int unix_listen(char *); 106int unix_listen(char *);
104void set_common_sockopts(int); 107void set_common_sockopts(int);
@@ -117,6 +120,7 @@ main(int argc, char *argv[])
117 char *proxy; 120 char *proxy;
118 const char *errstr, *proxyhost = "", *proxyport = NULL; 121 const char *errstr, *proxyhost = "", *proxyport = NULL;
119 struct addrinfo proxyhints; 122 struct addrinfo proxyhints;
123 char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE];
120 124
121 ret = 1; 125 ret = 1;
122 s = 0; 126 s = 0;
@@ -241,8 +245,6 @@ main(int argc, char *argv[])
241 245
242 /* Cruft to make sure options are clean, and used properly. */ 246 /* Cruft to make sure options are clean, and used properly. */
243 if (argv[0] && !argv[1] && family == AF_UNIX) { 247 if (argv[0] && !argv[1] && family == AF_UNIX) {
244 if (uflag)
245 errx(1, "cannot use -u and -U");
246 host = argv[0]; 248 host = argv[0];
247 uport = NULL; 249 uport = NULL;
248 } else if (argv[0] && !argv[1]) { 250 } else if (argv[0] && !argv[1]) {
@@ -265,6 +267,19 @@ main(int argc, char *argv[])
265 if (!lflag && kflag) 267 if (!lflag && kflag)
266 errx(1, "must use -l with -k"); 268 errx(1, "must use -l with -k");
267 269
270 /* Get name of temporary socket for unix datagram client */
271 if ((family == AF_UNIX) && uflag && !lflag) {
272 if (sflag) {
273 unix_dg_tmp_socket = sflag;
274 } else {
275 strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc.XXXXXXXXXX",
276 UNIX_DG_TMP_SOCKET_SIZE);
277 if (mktemp(unix_dg_tmp_socket_buf) == NULL)
278 err(1, "mktemp");
279 unix_dg_tmp_socket = unix_dg_tmp_socket_buf;
280 }
281 }
282
268 /* Initialize addrinfo structure. */ 283 /* Initialize addrinfo structure. */
269 if (family != AF_UNIX) { 284 if (family != AF_UNIX) {
270 memset(&hints, 0, sizeof(struct addrinfo)); 285 memset(&hints, 0, sizeof(struct addrinfo));
@@ -307,8 +322,12 @@ main(int argc, char *argv[])
307 int connfd; 322 int connfd;
308 ret = 0; 323 ret = 0;
309 324
310 if (family == AF_UNIX) 325 if (family == AF_UNIX) {
311 s = unix_listen(host); 326 if (uflag)
327 s = unix_bind(host);
328 else
329 s = unix_listen(host);
330 }
312 331
313 /* Allow only one connection at a time, but stay alive. */ 332 /* Allow only one connection at a time, but stay alive. */
314 for (;;) { 333 for (;;) {
@@ -337,17 +356,21 @@ main(int argc, char *argv[])
337 if (rv < 0) 356 if (rv < 0)
338 err(1, "connect"); 357 err(1, "connect");
339 358
340 connfd = s; 359 readwrite(s);
341 } else { 360 } else {
342 len = sizeof(cliaddr); 361 len = sizeof(cliaddr);
343 connfd = accept(s, (struct sockaddr *)&cliaddr, 362 connfd = accept(s, (struct sockaddr *)&cliaddr,
344 &len); 363 &len);
364 readwrite(connfd);
365 close(connfd);
345 } 366 }
346 367
347 readwrite(connfd);
348 close(connfd);
349 if (family != AF_UNIX) 368 if (family != AF_UNIX)
350 close(s); 369 close(s);
370 else if (uflag) {
371 if (connect(s, NULL, 0) < 0)
372 err(1, "connect");
373 }
351 374
352 if (!kflag) 375 if (!kflag)
353 break; 376 break;
@@ -361,6 +384,8 @@ main(int argc, char *argv[])
361 } else 384 } else
362 ret = 1; 385 ret = 1;
363 386
387 if (uflag)
388 unlink(unix_dg_tmp_socket);
364 exit(ret); 389 exit(ret);
365 390
366 } else { 391 } else {
@@ -421,18 +446,19 @@ main(int argc, char *argv[])
421} 446}
422 447
423/* 448/*
424 * unix_connect() 449 * unix_bind()
425 * Returns a socket connected to a local unix socket. Returns -1 on failure. 450 * Returns a unix socket bound to the given path
426 */ 451 */
427int 452int
428unix_connect(char *path) 453unix_bind(char *path)
429{ 454{
430 struct sockaddr_un sun; 455 struct sockaddr_un sun;
431 int s; 456 int s;
432 457
433 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) 458 /* Create unix domain socket. */
459 if ((s = socket(AF_UNIX, uflag ? SOCK_DGRAM : SOCK_STREAM,
460 0)) < 0)
434 return (-1); 461 return (-1);
435 (void)fcntl(s, F_SETFD, 1);
436 462
437 memset(&sun, 0, sizeof(struct sockaddr_un)); 463 memset(&sun, 0, sizeof(struct sockaddr_un));
438 sun.sun_family = AF_UNIX; 464 sun.sun_family = AF_UNIX;
@@ -443,27 +469,32 @@ unix_connect(char *path)
443 errno = ENAMETOOLONG; 469 errno = ENAMETOOLONG;
444 return (-1); 470 return (-1);
445 } 471 }
446 if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { 472
473 if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
447 close(s); 474 close(s);
448 return (-1); 475 return (-1);
449 } 476 }
450 return (s); 477 return (s);
451
452} 478}
453 479
454/* 480/*
455 * unix_listen() 481 * unix_connect()
456 * Create a unix domain socket, and listen on it. 482 * Returns a socket connected to a local unix socket. Returns -1 on failure.
457 */ 483 */
458int 484int
459unix_listen(char *path) 485unix_connect(char *path)
460{ 486{
461 struct sockaddr_un sun; 487 struct sockaddr_un sun;
462 int s; 488 int s;
463 489
464 /* Create unix domain socket. */ 490 if (uflag) {
465 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) 491 if ((s = unix_bind(unix_dg_tmp_socket)) < 0)
466 return (-1); 492 return (-1);
493 } else {
494 if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
495 return (-1);
496 }
497 (void)fcntl(s, F_SETFD, 1);
467 498
468 memset(&sun, 0, sizeof(struct sockaddr_un)); 499 memset(&sun, 0, sizeof(struct sockaddr_un));
469 sun.sun_family = AF_UNIX; 500 sun.sun_family = AF_UNIX;
@@ -474,11 +505,24 @@ unix_listen(char *path)
474 errno = ENAMETOOLONG; 505 errno = ENAMETOOLONG;
475 return (-1); 506 return (-1);
476 } 507 }
477 508 if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
478 if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) {
479 close(s); 509 close(s);
480 return (-1); 510 return (-1);
481 } 511 }
512 return (s);
513
514}
515
516/*
517 * unix_listen()
518 * Create a unix domain socket, and listen on it.
519 */
520int
521unix_listen(char *path)
522{
523 int s;
524 if ((s = unix_bind(path)) < 0)
525 return (-1);
482 526
483 if (listen(s, 5) < 0) { 527 if (listen(s, 5) < 0) {
484 close(s); 528 close(s);