version 1.41, 2002/02/17 02:04:57 |
version 1.42, 2002/02/17 03:03:06 |
|
|
#include <sys/types.h> |
#include <sys/types.h> |
#include <sys/socket.h> |
#include <sys/socket.h> |
#include <sys/time.h> |
#include <sys/time.h> |
|
#include <sys/un.h> |
|
|
#include <netinet/in.h> |
#include <netinet/in.h> |
#include <arpa/telnet.h> |
#include <arpa/telnet.h> |
|
|
#include <stdlib.h> |
#include <stdlib.h> |
#include <string.h> |
#include <string.h> |
#include <unistd.h> |
#include <unistd.h> |
|
#include <fcntl.h> |
|
|
#define PORT_MAX 65535 |
#define PORT_MAX 65535 |
|
|
|
|
void readwrite(int); |
void readwrite(int); |
int remote_connect(char *, char *, struct addrinfo); |
int remote_connect(char *, char *, struct addrinfo); |
int udptest(int); |
int udptest(int); |
|
int unix_connect(char *); |
|
int unix_listen(char *); |
void usage(int); |
void usage(int); |
|
|
int |
int |
|
|
endp = NULL; |
endp = NULL; |
sv = NULL; |
sv = NULL; |
|
|
while ((ch = getopt(argc, argv, "46hi:klnp:rs:tuvw:x:z")) != -1) { |
while ((ch = getopt(argc, argv, "46Uhi:klnp:rs:tuvw:x:z")) != -1) { |
switch (ch) { |
switch (ch) { |
case '4': |
case '4': |
family = AF_INET; |
family = AF_INET; |
|
|
case '6': |
case '6': |
family = AF_INET6; |
family = AF_INET6; |
break; |
break; |
|
case 'U': |
|
family = AF_UNIX; |
|
break; |
case 'h': |
case 'h': |
help(); |
help(); |
break; |
break; |
|
|
argv += optind; |
argv += optind; |
|
|
/* 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]) { |
if (argv[0] && !argv[1] && family == AF_UNIX) { |
|
if (uflag) |
|
errx(1, "cannot use -u and -U"); |
|
host = argv[0]; |
|
uport = NULL; |
|
} else if (argv[0] && !argv[1]) { |
if (!lflag) |
if (!lflag) |
usage(1); |
usage(1); |
uport = argv[0]; |
uport = argv[0]; |
|
|
errx(1, "must use -l with -k"); |
errx(1, "must use -l with -k"); |
|
|
/* Initialize addrinfo structure */ |
/* Initialize addrinfo structure */ |
memset(&hints, 0, sizeof(struct addrinfo)); |
if (family != AF_UNIX) { |
hints.ai_family = family; |
memset(&hints, 0, sizeof(struct addrinfo)); |
hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; |
hints.ai_family = family; |
hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; |
hints.ai_socktype = uflag ? SOCK_DGRAM : SOCK_STREAM; |
if (nflag) |
hints.ai_protocol = uflag ? IPPROTO_UDP : IPPROTO_TCP; |
hints.ai_flags |= AI_NUMERICHOST; |
if (nflag) |
|
hints.ai_flags |= AI_NUMERICHOST; |
|
} |
|
|
|
|
if (xflag) { |
if (xflag) { |
if (uflag) |
if (uflag) |
|
|
if (lflag) |
if (lflag) |
errx(1, "no proxy support for listen"); |
errx(1, "no proxy support for listen"); |
|
|
|
if (family == AF_UNIX) |
|
errx(1, "no proxy support for unix sockets"); |
|
|
/* XXX IPv6 transport to proxy would probably work */ |
/* XXX IPv6 transport to proxy would probably work */ |
if (family == AF_INET6) |
if (family == AF_INET6) |
errx(1, "no proxy support for IPv6"); |
errx(1, "no proxy support for IPv6"); |
|
|
int connfd; |
int connfd; |
ret = 0; |
ret = 0; |
|
|
|
if (family == AF_UNIX) |
|
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 ((s = local_listen(host, uport, hints)) < 0) |
if (family != AF_UNIX) |
|
s = local_listen(host, uport, hints); |
|
if (s < 0) |
err(1, NULL); |
err(1, NULL); |
/* |
/* |
* For UDP, we will use recvfrom() initially |
* For UDP, we will use recvfrom() initially |
|
|
|
|
readwrite(connfd); |
readwrite(connfd); |
close(connfd); |
close(connfd); |
close(s); |
if (family != AF_UNIX) |
|
close(s); |
|
|
if (!kflag) |
if (!kflag) |
break; |
break; |
} |
} |
|
} else if (family == AF_UNIX) { |
|
ret = 0; |
|
|
|
if ((s = unix_connect(host)) > 0 && !zflag) { |
|
readwrite(s); |
|
close(s); |
|
} else |
|
ret = 1; |
|
|
|
exit(ret); |
|
|
} else { |
} else { |
int i = 0; |
int i = 0; |
|
|
|
|
} |
} |
|
|
/* |
/* |
|
* unix_connect() |
|
* Return's a socket connected to a local unix socket. Return's -1 on failure. |
|
*/ |
|
int |
|
unix_connect(char *path) |
|
{ |
|
struct sockaddr_un sun; |
|
int s; |
|
|
|
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) |
|
return (-1); |
|
(void)fcntl(s, F_SETFD, 1); |
|
|
|
memset(&sun, 0, sizeof(struct sockaddr_un)); |
|
sun.sun_len = sizeof(path); |
|
sun.sun_family = AF_UNIX; |
|
strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); |
|
|
|
if (connect(s, (struct sockaddr *)&sun, sizeof(sun)) < 0) { |
|
close(s); |
|
return (-1); |
|
} |
|
return (s); |
|
|
|
} |
|
|
|
/* |
|
* unix_listen() |
|
* create a unix domain socket, and listen on it. |
|
*/ |
|
int |
|
unix_listen(char *path) |
|
{ |
|
struct sockaddr_un sun; |
|
int s; |
|
|
|
/* create unix domain socket */ |
|
if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) |
|
return (-1); |
|
|
|
sun.sun_family = AF_UNIX; |
|
strlcpy(sun.sun_path, path, sizeof(sun.sun_path)); |
|
|
|
if (bind(s, (struct sockaddr *)&sun, SUN_LEN(&sun)) < 0) { |
|
close(s); |
|
return (-1); |
|
} |
|
|
|
if (listen(s, 5) < 0) { |
|
close(s); |
|
return (-1); |
|
} |
|
return (s); |
|
} |
|
|
|
/* |
* remote_connect() |
* remote_connect() |
* Return's a socket connected to a remote host. Properly bind's to a local |
* Return's a socket connected to a remote host. Properly bind's to a local |
* port or source address if needed. Return's -1 on failure. |
* port or source address if needed. Return's -1 on failure. |
|
|
fprintf(stderr, "\tCommand Summary:\n\ |
fprintf(stderr, "\tCommand Summary:\n\ |
\t-4 Use IPv4\n\ |
\t-4 Use IPv4\n\ |
\t-6 Use IPv6\n\ |
\t-6 Use IPv6\n\ |
|
\t-U Use UNIX domain socket\n\ |
\t-h This help text\n\ |
\t-h This help text\n\ |
\t-i secs\t Delay interval for lines sent, ports scanned\n\ |
\t-i secs\t Delay interval for lines sent, ports scanned\n\ |
\t-k Keep inbound sockets open for multiple connects\n\ |
\t-k Keep inbound sockets open for multiple connects\n\ |