version 1.98, 2010/07/03 04:44:51 |
version 1.99, 2011/01/08 00:44:19 |
|
|
|
|
#define PORT_MAX 65535 |
#define PORT_MAX 65535 |
#define PORT_MAX_LEN 6 |
#define PORT_MAX_LEN 6 |
|
#define UNIX_DG_TMP_SOCKET_SIZE 19 |
|
|
/* Command Line Options */ |
/* Command Line Options */ |
int dflag; /* detached, no stdin */ |
int dflag; /* detached, no stdin */ |
|
|
int timeout = -1; |
int timeout = -1; |
int family = AF_UNSPEC; |
int family = AF_UNSPEC; |
char *portlist[PORT_MAX+1]; |
char *portlist[PORT_MAX+1]; |
|
char *unix_dg_tmp_socket; |
|
|
void atelnet(int, unsigned char *, unsigned int); |
void atelnet(int, unsigned char *, unsigned int); |
void build_ports(char *); |
void build_ports(char *); |
|
|
int socks_connect(const char *, const char *, struct addrinfo, |
int socks_connect(const char *, const char *, struct addrinfo, |
const char *, const char *, struct addrinfo, int, const char *); |
const char *, const char *, struct addrinfo, int, const char *); |
int udptest(int); |
int udptest(int); |
|
int unix_bind(char *); |
int unix_connect(char *); |
int unix_connect(char *); |
int unix_listen(char *); |
int unix_listen(char *); |
void set_common_sockopts(int); |
void set_common_sockopts(int); |
|
|
char *proxy; |
char *proxy; |
const char *errstr, *proxyhost = "", *proxyport = NULL; |
const char *errstr, *proxyhost = "", *proxyport = NULL; |
struct addrinfo proxyhints; |
struct addrinfo proxyhints; |
|
char unix_dg_tmp_socket_buf[UNIX_DG_TMP_SOCKET_SIZE]; |
|
|
ret = 1; |
ret = 1; |
s = 0; |
s = 0; |
|
|
|
|
/* Cruft to make sure options are clean, and used properly. */ |
/* Cruft to make sure options are clean, and used properly. */ |
if (argv[0] && !argv[1] && family == AF_UNIX) { |
if (argv[0] && !argv[1] && family == AF_UNIX) { |
if (uflag) |
|
errx(1, "cannot use -u and -U"); |
|
host = argv[0]; |
host = argv[0]; |
uport = NULL; |
uport = NULL; |
} else if (argv[0] && !argv[1]) { |
} else if (argv[0] && !argv[1]) { |
|
|
if (!lflag && kflag) |
if (!lflag && kflag) |
errx(1, "must use -l with -k"); |
errx(1, "must use -l with -k"); |
|
|
|
/* Get name of temporary socket for unix datagram client */ |
|
if ((family == AF_UNIX) && uflag && !lflag) { |
|
if (sflag) { |
|
unix_dg_tmp_socket = sflag; |
|
} else { |
|
strlcpy(unix_dg_tmp_socket_buf, "/tmp/nc.XXXXXXXXXX", |
|
UNIX_DG_TMP_SOCKET_SIZE); |
|
if (mktemp(unix_dg_tmp_socket_buf) == NULL) |
|
err(1, "mktemp"); |
|
unix_dg_tmp_socket = unix_dg_tmp_socket_buf; |
|
} |
|
} |
|
|
/* Initialize addrinfo structure. */ |
/* Initialize addrinfo structure. */ |
if (family != AF_UNIX) { |
if (family != AF_UNIX) { |
memset(&hints, 0, sizeof(struct addrinfo)); |
memset(&hints, 0, sizeof(struct addrinfo)); |
|
|
int connfd; |
int connfd; |
ret = 0; |
ret = 0; |
|
|
if (family == AF_UNIX) |
if (family == AF_UNIX) { |
s = unix_listen(host); |
if (uflag) |
|
s = unix_bind(host); |
|
else |
|
s = unix_listen(host); |
|
} |
|
|
/* Allow only one connection at a time, but stay alive. */ |
/* Allow only one connection at a time, but stay alive. */ |
for (;;) { |
for (;;) { |
|
|
if (rv < 0) |
if (rv < 0) |
err(1, "connect"); |
err(1, "connect"); |
|
|
connfd = s; |
readwrite(s); |
} else { |
} else { |
len = sizeof(cliaddr); |
len = sizeof(cliaddr); |
connfd = accept(s, (struct sockaddr *)&cliaddr, |
connfd = accept(s, (struct sockaddr *)&cliaddr, |
&len); |
&len); |
|
readwrite(connfd); |
|
close(connfd); |
} |
} |
|
|
readwrite(connfd); |
|
close(connfd); |
|
if (family != AF_UNIX) |
if (family != AF_UNIX) |
close(s); |
close(s); |
|
else if (uflag) { |
|
if (connect(s, NULL, 0) < 0) |
|
err(1, "connect"); |
|
} |
|
|
if (!kflag) |
if (!kflag) |
break; |
break; |
|
|
} else |
} else |
ret = 1; |
ret = 1; |
|
|
|
if (uflag) |
|
unlink(unix_dg_tmp_socket); |
exit(ret); |
exit(ret); |
|
|
} else { |
} else { |
|
|
} |
} |
|
|
/* |
/* |
* unix_connect() |
* unix_bind() |
* Returns a socket connected to a local unix socket. Returns -1 on failure. |
* Returns a unix socket bound to the given path |
*/ |
*/ |
int |
int |
unix_connect(char *path) |
unix_bind(char *path) |
{ |
{ |
struct sockaddr_un sun; |
struct sockaddr_un sun; |
int s; |
int s; |
|
|
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) |
/* Create unix domain socket. */ |
|
if ((s = socket(AF_UNIX, uflag ? SOCK_DGRAM : SOCK_STREAM, |
|
0)) < 0) |
return (-1); |
return (-1); |
(void)fcntl(s, F_SETFD, 1); |
|
|
|
memset(&sun, 0, sizeof(struct sockaddr_un)); |
memset(&sun, 0, sizeof(struct sockaddr_un)); |
sun.sun_family = AF_UNIX; |
sun.sun_family = AF_UNIX; |
|
|
errno = ENAMETOOLONG; |
errno = ENAMETOOLONG; |
return (-1); |
return (-1); |
} |
} |
if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { |
|
|
if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { |
close(s); |
close(s); |
return (-1); |
return (-1); |
} |
} |
return (s); |
return (s); |
|
|
} |
} |
|
|
/* |
/* |
* unix_listen() |
* unix_connect() |
* Create a unix domain socket, and listen on it. |
* Returns a socket connected to a local unix socket. Returns -1 on failure. |
*/ |
*/ |
int |
int |
unix_listen(char *path) |
unix_connect(char *path) |
{ |
{ |
struct sockaddr_un sun; |
struct sockaddr_un sun; |
int s; |
int s; |
|
|
/* Create unix domain socket. */ |
if (uflag) { |
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) |
if ((s = unix_bind(unix_dg_tmp_socket)) < 0) |
return (-1); |
return (-1); |
|
} else { |
|
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) |
|
return (-1); |
|
} |
|
(void)fcntl(s, F_SETFD, 1); |
|
|
memset(&sun, 0, sizeof(struct sockaddr_un)); |
memset(&sun, 0, sizeof(struct sockaddr_un)); |
sun.sun_family = AF_UNIX; |
sun.sun_family = AF_UNIX; |
|
|
errno = ENAMETOOLONG; |
errno = ENAMETOOLONG; |
return (-1); |
return (-1); |
} |
} |
|
if (connect(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { |
if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { |
|
close(s); |
close(s); |
return (-1); |
return (-1); |
} |
} |
|
return (s); |
|
|
|
} |
|
|
|
/* |
|
* unix_listen() |
|
* Create a unix domain socket, and listen on it. |
|
*/ |
|
int |
|
unix_listen(char *path) |
|
{ |
|
int s; |
|
if ((s = unix_bind(path)) < 0) |
|
return (-1); |
|
|
if (listen(s, 5) < 0) { |
if (listen(s, 5) < 0) { |
close(s); |
close(s); |