summaryrefslogtreecommitdiffstats
path: root/usr.sbin/pppctl
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/pppctl')
-rw-r--r--usr.sbin/pppctl/pppctl.c204
1 files changed, 115 insertions, 89 deletions
diff --git a/usr.sbin/pppctl/pppctl.c b/usr.sbin/pppctl/pppctl.c
index cfc4912..1ff63b3 100644
--- a/usr.sbin/pppctl/pppctl.c
+++ b/usr.sbin/pppctl/pppctl.c
@@ -332,6 +332,29 @@ Monitor(void *v)
return NULL;
}
+static const char *
+sockaddr_ntop(const struct sockaddr *sa)
+{
+ const void *addr;
+ static char addrbuf[INET6_ADDRSTRLEN];
+
+ switch (sa->sa_family) {
+ case AF_INET:
+ addr = &((const struct sockaddr_in *)sa)->sin_addr;
+ break;
+ case AF_UNIX:
+ addr = &((const struct sockaddr_un *)sa)->sun_path;
+ break;
+ case AF_INET6:
+ addr = &((const struct sockaddr_in6 *)sa)->sin6_addr;
+ break;
+ default:
+ return NULL;
+ }
+ inet_ntop(sa->sa_family, addr, addrbuf, sizeof(addrbuf));
+ return addrbuf;
+}
+
/*
* Connect to ppp using either a local domain socket or a tcp socket.
*
@@ -341,12 +364,8 @@ Monitor(void *v)
int
main(int argc, char **argv)
{
- struct servent *s;
- struct hostent *h;
- struct sockaddr *sock;
- struct sockaddr_in ifsin;
struct sockaddr_un ifsun;
- int n, socksz, arg, fd, len, verbose, save_errno, hide1, hide1off, hide2;
+ int n, arg, fd, len, verbose, save_errno, hide1, hide1off, hide2;
unsigned TimeoutVal;
char *DoneWord = "x", *next, *start;
struct sigaction act, oact;
@@ -424,9 +443,6 @@ main(int argc, char **argv)
}
if (*argv[arg] == '/') {
- sock = (struct sockaddr *)&ifsun;
- socksz = sizeof ifsun;
-
memset(&ifsun, '\0', sizeof ifsun);
ifsun.sun_len = strlen(argv[arg]);
if (ifsun.sun_len > sizeof ifsun.sun_path - 1) {
@@ -440,88 +456,98 @@ main(int argc, char **argv)
warnx("cannot create local domain socket");
return 2;
}
+ if (connect(fd, (struct sockaddr *)&ifsun, sizeof(ifsun)) < 0) {
+ if (errno)
+ warn("cannot connect to socket %s", argv[arg]);
+ else
+ warnx("cannot connect to socket %s", argv[arg]);
+ close(fd);
+ return 3;
+ }
} else {
- char *port, *host, *colon;
- int hlen;
-
- colon = strchr(argv[arg], ':');
- if (colon) {
- port = colon + 1;
- *colon = '\0';
- host = argv[arg];
- } else {
- port = argv[arg];
- host = "127.0.0.1";
- }
- sock = (struct sockaddr *)&ifsin;
- socksz = sizeof ifsin;
- hlen = strlen(host);
-
- memset(&ifsin, '\0', sizeof ifsin);
- if (strspn(host, "0123456789.") == hlen) {
- if (!inet_aton(host, &ifsin.sin_addr)) {
- warnx("cannot translate %s", host);
- return 1;
- }
- } else if ((h = gethostbyname(host)) == 0) {
- warnx("cannot resolve %s", host);
- return 1;
- }
- else
- ifsin.sin_addr.s_addr = *(u_long *)h->h_addr_list[0];
-
- if (colon)
- *colon = ':';
-
- if (strspn(port, "0123456789") == strlen(port))
- ifsin.sin_port = htons(atoi(port));
- else if (s = getservbyname(port, "tcp"), !s) {
- warnx("%s isn't a valid port or service!", port);
- usage();
- }
- else
- ifsin.sin_port = s->s_port;
-
- ifsin.sin_len = sizeof(ifsin);
- ifsin.sin_family = AF_INET;
-
- if (fd = socket(AF_INET, SOCK_STREAM, 0), fd < 0) {
- warnx("cannot create internet socket");
- return 2;
- }
- }
-
- TimedOut = 0;
- if (TimeoutVal) {
- act.sa_handler = Timeout;
- sigemptyset(&act.sa_mask);
- act.sa_flags = 0;
- sigaction(SIGALRM, &act, &oact);
- alarm(TimeoutVal);
- }
-
- if (connect(fd, sock, socksz) < 0) {
- if (TimeoutVal) {
- save_errno = errno;
- alarm(0);
- sigaction(SIGALRM, &oact, 0);
- errno = save_errno;
- }
- if (TimedOut)
- warnx("timeout: cannot connect to socket %s", argv[arg]);
- else {
- if (errno)
- warn("cannot connect to socket %s", argv[arg]);
- else
- warnx("cannot connect to socket %s", argv[arg]);
- }
- close(fd);
- return 3;
- }
-
- if (TimeoutVal) {
- alarm(0);
- sigaction(SIGALRM, &oact, 0);
+ char *addr, *p, *port;
+ const char *caddr;
+ struct addrinfo hints, *res, *pai;
+ int gai;
+ char local[] = "localhost";
+
+ addr = argv[arg];
+ if (addr[strspn(addr, "0123456789")] == '\0') {
+ /* port on local machine */
+ port = addr;
+ addr = local;
+ } else if (*addr == '[') {
+ /* [addr]:port */
+ if ((p = strchr(addr, ']')) == NULL) {
+ warnx("%s: mismatched '['", addr);
+ return 1;
+ }
+ addr++;
+ *p++ = '\0';
+ if (*p != ':') {
+ warnx("%s: missing port", addr);
+ return 1;
+ }
+ port = ++p;
+ } else {
+ /* addr:port */
+ p = addr + strcspn(addr, ":");
+ if (*p != ':') {
+ warnx("%s: missing port", addr);
+ return 1;
+ }
+ *p++ = '\0';
+ port = p;
+ }
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_socktype = SOCK_STREAM;
+ gai = getaddrinfo(addr, port, &hints, &res);
+ if (gai != 0) {
+ warnx("%s: %s", addr, gai_strerror(gai));
+ return 1;
+ }
+ for (pai = res; pai != NULL; pai = pai->ai_next) {
+ if (fd = socket(pai->ai_family, pai->ai_socktype,
+ pai->ai_protocol), fd < 0) {
+ warnx("cannot create socket");
+ continue;
+ }
+ TimedOut = 0;
+ if (TimeoutVal) {
+ act.sa_handler = Timeout;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = 0;
+ sigaction(SIGALRM, &act, &oact);
+ alarm(TimeoutVal);
+ }
+ if (connect(fd, pai->ai_addr, pai->ai_addrlen) == 0)
+ break;
+ if (TimeoutVal) {
+ save_errno = errno;
+ alarm(0);
+ sigaction(SIGALRM, &oact, 0);
+ errno = save_errno;
+ }
+ caddr = sockaddr_ntop(pai->ai_addr);
+ if (caddr == NULL)
+ caddr = argv[arg];
+ if (TimedOut)
+ warnx("timeout: cannot connect to %s", caddr);
+ else {
+ if (errno)
+ warn("cannot connect to %s", caddr);
+ else
+ warnx("cannot connect to %s", caddr);
+ }
+ close(fd);
+ }
+ freeaddrinfo(res);
+ if (pai == NULL)
+ return 1;
+ if (TimeoutVal) {
+ alarm(0);
+ sigaction(SIGALRM, &oact, 0);
+ }
}
len = 0;
OpenPOWER on IntegriCloud