Subject: pppd bug in 1.0
To: None <netbsd-bugs@NetBSD.ORG>
From: ERANIAN Stephane <eranian@mountain.ufr-info-p7.ibp.fr>
List: netbsd-bugs
Date: 12/28/1994 11:02:56
Hello NetBSD maintainer,

I would like to report a serious bug in the current source
of the PPP daemon as distributed in the sources tree of
version 1.0.

I have isolated two problems:

Both apply to the get_ether_addr() and only appear when using
the proxyarp flag on the command line.

  - the first for() loop in not well constructed. The third part of
    the loop is missing. Thus when used in conjunction with continue
    statements it causes an inifinite loop. And the pppd daemon 
    starts eating up all the CPU time !!

  - the second problem concerns the way the netmask is tested in the same
    for() loop. There is a variable typo just after the ioctl() to get
    the mask. One must replace the ifr->... by ifreq. 

Correcting these two bugs will permit a successfull initialization 
of the ARP table and thus allow connections from other hosts on the net
to the PPP client.

The corresponding diff follows.

Best regards,

--------------------------------------------------------------------
St'ephane ERANIAN			| Email	eranian@litp.ibp.fr
Universit'e PARIS VII			|
LITP - Laboratoire d'Informatique	|
Th'eorique et Programmation		|
--------------------------------------------------------------------

# ---- cut here ----- cut here -----
--- sys-bsd.c	Mon May 30 01:45:15 1994
+++ sys-bsd.c.new	Mon Dec 26 12:39:56 1994
@@ -597,7 +597,8 @@
      * address on the same subnet as `ipaddr'.
      */
     ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);
-    for (ifr = ifc.ifc_req; ifr < ifend; ) {
+    for (ifr = ifc.ifc_req; ifr < ifend; 
+	ifr = (struct ifreq *) ((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len) ) {
 	if (ifr->ifr_addr.sa_family == AF_INET) {
 	    ina = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
 	    strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));
@@ -616,13 +617,12 @@
 	     */
 	    if (ioctl(s, SIOCGIFNETMASK, &ifreq) < 0)
 		continue;
-	    mask = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr.s_addr;
+	    mask = ((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr.s_addr;
 	    if ((ipaddr & mask) != (ina & mask))
 		continue;
 
 	    break;
 	}
-	ifr = (struct ifreq *) ((char *)&ifr->ifr_addr + ifr->ifr_addr.sa_len);
     }
 
     if (ifr >= ifend)