summaryrefslogtreecommitdiff
path: root/src/usr.bin/nc/netcat.c
diff options
context:
space:
mode:
authorericj <>2002-02-17 03:03:06 +0000
committerericj <>2002-02-17 03:03:06 +0000
commit8826d7883ec6326a3a6b98ef8edf16a2ff71670d (patch)
treeb6564616b7785e681830ec49eaeaaaf8fa48f686 /src/usr.bin/nc/netcat.c
parent131f4764acf303e6e9d5eec5ddf32eb4009cc255 (diff)
downloadopenbsd-8826d7883ec6326a3a6b98ef8edf16a2ff71670d.tar.gz
openbsd-8826d7883ec6326a3a6b98ef8edf16a2ff71670d.tar.bz2
openbsd-8826d7883ec6326a3a6b98ef8edf16a2ff71670d.zip
add support for connecting too and listening on AF_UNIX sockets.
connect support from dave@arbor.net.. rest by me
Diffstat (limited to '')
-rw-r--r--src/usr.bin/nc/netcat.c114
1 files changed, 103 insertions, 11 deletions
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\