Subject: Re: ppp(4) made clonable
To: Martin Husemann <martin@duskware.de>
From: Quentin Garnier <cube@cubidou.net>
List: tech-net
Date: 08/14/2003 10:39:23
On Wed, 13 Aug 2003 22:10:00 +0200
Martin Husemann <martin@duskware.de> wrote:

> On Wed, Aug 13, 2003 at 09:54:16PM +0200, Quentin Garnier wrote:
> > Couldn't it be removed, maybe
> > with a more explicit message if TIOCSETD(pppdisc) returns ENXIO?
> 
> Well, the test could use SIOCIFGCLONERS and look for "ppp" in the
> list.(See sbin/ifconfig/ifconfig.c::list_cloners)

Right. With this pppd is completely happy with a clonable ppp(4), and
former behaviour is kept in case ppp(4) is not clonable.

Quentin Garnier.

Index: sys-bsd.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/pppd/pppd/sys-bsd.c,v
retrieving revision 1.43
diff -u -r1.43 sys-bsd.c
--- sys-bsd.c	2003/06/09 13:35:10	1.43
+++ sys-bsd.c	2003/08/14 08:35:50
@@ -291,15 +291,12 @@
 {
     int s, ok;
     struct ifreq ifr;
+    struct if_clonereq ifcr;
     extern char *no_ppp_msg;
 
     if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
 	return 1;		/* can't tell */
 
-    strlcpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
-    ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
-    close(s);
-
 #ifdef __NetBSD__
     no_ppp_msg = "\
 This system lacks kernel support for PPP.  To include PPP support\n\
@@ -310,6 +307,35 @@
 in the kernel, please follow the steps detailed in the README.bsd\n\
 file in the ppp-2.2 distribution.\n";
 #endif
+
+    if (!ioctl(s, SIOCIFGCLONERS, &ifcr)) {
+	char *cp, *buf = malloc(ifcr.ifcr_total * IFNAMSIZ);
+	int idx;
+
+	if (buf == NULL)
+	    goto nocloners;
+
+	ifcr.ifcr_count = ifcr.ifcr_total;
+	ifcr.ifcr_buffer = buf;
+
+	if (ioctl(s, SIOCIFGCLONERS, &ifcr) == -1)
+	    goto nocloners;
+
+	if (ifcr.ifcr_count > ifcr.ifcr_total)
+	    ifcr.ifcr_count = ifcr.ifcr_total;
+
+	for (cp = buf, idx = 0; idx < ifcr.ifcr_count; idx++, cp += IFNAMSIZ)
+	    if (!strcmp("ppp", cp)) {
+		close(s);
+		return (1);
+	    }
+    }
+
+nocloners:
+    strlcpy(ifr.ifr_name, "ppp0", sizeof (ifr.ifr_name));
+    ok = ioctl(s, SIOCGIFFLAGS, (caddr_t) &ifr) >= 0;
+    close(s);
+
     return ok;
 }