[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

ppp/pppctl protocol mismatch



Hello!

While playing with ppp(8), i learned the following:

Because /usr/src/usr.sbin/ppp/ppp is compiled with NOINET6 undefined,
creating a ppp-control-server with the command "set server <port> <passwd>"
results in ppp listening on a IPv6-socket. On the other side, pppctl(8)
doesn't speak IPv6. 
The following patch makes pppctl work for me.

Thanks,
Alf

--- usr.sbin/ppp/pppctl/pppctl.c.orig	Mon Mar 15 19:19:46 2004
+++ usr.sbin/ppp/pppctl/pppctl.c	Tue Mar 16 10:24:42 2004
@@ -197,19 +197,22 @@
 int
 main(int argc, char **argv)
 {
-    struct servent *s;
-    struct hostent *h;
     struct sockaddr *sock;
-    struct sockaddr_in ifsin;
+    struct addrinfo hints, *res, *ai;
     struct sockaddr_un ifsun;
-    int n, socksz, arg, fd, len, verbose, save_errno, hide1, hide1off, hide2;
+    int m, n, socksz, arg, fd, len, verbose, save_errno, hide1, hide1off, hide2;
     unsigned TimeoutVal;
+    char *port, *host, *colon;
     char *DoneWord = "x", *next, *start;
     struct sigaction act, oact;
+    char errbuf[NI_MAXHOST];
 
-    verbose = 0;
+    verbose = save_errno = 0;
     TimeoutVal = 2;
     hide1 = hide1off = hide2 = 0;
+    bzero(&hints, sizeof(struct addrinfo));
+    bzero(&errbuf, sizeof(errbuf));
+    port = host = colon = NULL;
 
     for (arg = 1; arg < argc; arg++)
         if (*argv[arg] == '-') {
@@ -293,10 +296,8 @@
             return 2;
         }
     } else {
-        char *port, *host, *colon;
-        int hlen;
 
-        colon = strchr(argv[arg], ':');
+        colon = strrchr(argv[arg], ':');
         if (colon) {
             port = colon + 1;
             *colon = '\0';
@@ -303,44 +304,8 @@
             host = argv[arg];
         } else {
             port = argv[arg];
-            host = "127.0.0.1";
+            host = "localhost";
         }
-        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;
@@ -351,25 +316,50 @@
         sigaction(SIGALRM, &act, &oact);
         alarm(TimeoutVal);
     }
+	
+    hints.ai_socktype = SOCK_STREAM;
+    
+    if ((m = getaddrinfo(host, port, &hints, &res)) < 0) {
+      fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(m));
+      return 1;
+    }
+    
+    fd = -1;
+    for(ai = res; ai != NULL; ai = ai->ai_next) {
 
-    if (connect(fd, sock, socksz) < 0) {
+      if ((fd = socket(ai->ai_family, ai->ai_socktype, 0)) == -1) {
+	warnx("cannot create tcp socket");
+	continue;
+      }
+
+      if (connect(fd, ai->ai_addr, ai->ai_addrlen) == -1) {
+	if (getnameinfo(ai->ai_addr, ai->ai_addrlen, errbuf, sizeof(errbuf),
+			NULL, 0, NI_NUMERICHOST) != 0) 
+	  strlcpy(errbuf, "(invalid)", sizeof(errbuf));
+	
+	if (errno == EINTR && TimedOut)
+	  errno = ETIMEDOUT;
+	warn("cannot connect to socket %s:%s", errbuf, port);
+
         if (TimeoutVal) {
             save_errno = errno;
-            alarm(0);
-            sigaction(SIGALRM, &oact, 0);
+            TimedOut = 0;
+            sigaction(SIGALRM, &act, 0);
+            alarm(TimeoutVal);
             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;
+
+	close(fd);
+	fd = -1;
+	continue;
+      }
+      break;
     }
+    
+    if (fd == -1) {
+      freeaddrinfo(res);
+      return 1;
+    }
 
     if (TimeoutVal) {
         alarm(0);
@@ -462,6 +452,6 @@
     }
 
     close(fd);
-
+    freeaddrinfo(res);
     return 0;
 }