Subject: pkg/9946: fixes for mouse-ppoe pkg
To: None <gnats-bugs@gnats.netbsd.org>
From: Stephen Degler <sdegler@bauhaus.degler.net>
List: netbsd-bugs
Date: 04/20/2000 19:46:13
>Number:         9946
>Category:       pkg
>Synopsis:       bug fixes for packet length and added a signal handler
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    pkg-manager
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Apr 20 19:47:00 PDT 2000
>Closed-Date:
>Last-Modified:
>Originator:     Stephen Degler
>Release:        NetBSD-current Thu Apr 20 22:27:43 2000
>Organization:
very little at best
	
>Environment:
System: NetBSD bauhaus.degler.net 1.4X NetBSD 1.4X (BAUHAUS) #1: Thu Apr 20 01:10:01 EDT 2000 root@bauhaus.degler.net:/vol2/src/sys/arch/alpha/compile/BAUHAUS alpha


>Description:
	1) The output buffer is 1500 bytes, but a raw ethernet frame
	is 1514 bytes including mac addresses and ether type.  Fixed
	the output buffer length and the the length check function to
	reflect this.

	2) If the pppoe process it signaled, the pppd child dies without
	sending an lcp close.  Subsequent invocations see frames from the
	previous session, and it complans.  Also, no PADT is sent.  A
	signal handler is established to forward the signals to pppd,
	which then exits gracefully.

	3) The current pppd requires a speed argument.  Other options
	were changed to suit my environment.  Your mileage may vary.

>How-To-Repeat:
	1) ping -s 1500 host.at.other.end.of.pppoe (see output packet
	   overflow messages)
	2) ^Cpppoe. ; ./pppoe le0 foo (see complaints about the old session).
	3) ./pppoe le0 foo (see pppd usage message output).
>Fix:
--- pppoe.c.orig	Fri Apr 14 01:57:21 2000
+++ pppoe.c	Thu Apr 20 22:15:44 2000
@@ -4,6 +4,7 @@
 #include <stdlib.h>
 #include <stdarg.h>
 #include <unistd.h>
+#include <signal.h>
 #include <sys/socket.h>
 #include <net/if.h>
 #include <termios.h>
@@ -21,6 +22,7 @@
 
 #define UNIQLEN 8
 #define MAXPKTLEN 1500 /* forced by Ethernet MTU */
+#define MAXFRMLEN 1514 /* payload + 2 mac addresses + ether type */
 
 #define PPP_FLAG 0x7e
 #define PPP_ESC  0x7d
@@ -57,7 +59,7 @@
 static int ntags;
 static TAG *tags;
 static int tagsalloc;
-static unsigned char opkt[MAXPKTLEN];
+static unsigned char opkt[MAXFRMLEN];
 static int pktoff;
 static char ptymname[11];
 static int ptymfd;
@@ -65,6 +67,7 @@
 static int ptysfd;
 static int devnull;
 static int pppdeathpipe;
+static int ppp_pid;
 static unsigned char ppp_pty_frame[MAXPKTLEN+2];
 static int ppp_pty_flen;
 static int ppp_pty_fcs;
@@ -110,6 +113,8 @@
 #define P_DEBUG 4
 static int pppdebug = 0;
 
+void sig_handler(int);
+
 static void p(int, const char *, ...)
 	__attribute__((__format__(__printf__,2,3)));
 static void p(int level, const char *fmt, ...)
@@ -300,9 +305,9 @@
 
 static int pktlenchk(int len)
 {
- if (pktoff+len > MAXPKTLEN)
-  { if (pktoff <= MAXPKTLEN) p(P_WARN,"output packet overflow\n");
-    pktoff = MAXPKTLEN + 1;
+ if (pktoff+len > MAXFRMLEN)
+  { if (pktoff <= MAXFRMLEN) p(P_WARN,"output packet overflow %d\n",pktoff+len);
+    pktoff = MAXFRMLEN + 1;
     return(1);
   }
  return(0);
@@ -577,6 +582,8 @@
   }
  if (kid != 0)
   { for (i=getdtablesize()-1;i>2;i--) if (i != deathpipe[1]) close(i);
+    if ( write(deathpipe[1],(char *)&kid,sizeof(kid)) < 0 )
+      _exit(1);
     wait(&i);
     _exit(0);
   }
@@ -590,6 +597,7 @@
     const char **ap;
     ap = &args[0];
     *ap++ = "pppd";
+    *ap++ = "115200";
     *ap++ = "connect"; *ap++ = "/usr/bin/true";
     *ap++ = "ipcp-accept-local";
     *ap++ = "ipcp-accept-remote";
@@ -597,15 +605,16 @@
     *ap++ = "mru"; *ap++ = "1492";
     *ap++ = "mtu"; *ap++ = "1492";
     *ap++ = "name"; *ap++ = pppname;
+    *ap++ = "netmask"; *ap++ = "255.255.255.255";
     *ap++ = "noaccomp";
-    /* *ap++ = "noauth"; */
+    *ap++ = "noauth";
     *ap++ = "nobsdcomp";
     *ap++ = "noccp";
     *ap++ = "nodefaultroute";
     *ap++ = "nodeflate";
     *ap++ = "nodetach";
     *ap++ = "noipdefault";
-    *ap++ = "noipx";
+    /* *ap++ = "noipx"; */
     *ap++ = "nopcomp";
     *ap++ = "nopersist";
     *ap++ = "nopredictor1";
@@ -969,11 +978,32 @@
 
 static void process_ppp_death(void)
 {
- while (wait3(0,WNOHANG,0) > 0) ;
- p(P_INFO,"exiting on ppp death\n");
- close(pppdeathpipe);
- send_padt();
- exit(0);
+  int num;
+
+  if (( num = read(pppdeathpipe,&ppp_pid,sizeof(ppp_pid))) == sizeof(ppp_pid))
+  {
+    /* set up signal handlers to for gracefull exit */
+    signal(SIGHUP,(void (*)(int))sig_handler);
+    signal(SIGINT,(void (*)(int))sig_handler);
+    signal(SIGTERM,(void (*)(int))sig_handler);
+    return;
+  }
+  else if ( num == 0 )
+  {
+    while (wait3(0,WNOHANG,0) > 0) ;
+    p(P_INFO,"exiting on ppp death\n");
+    close(pppdeathpipe);
+    send_padt();
+    exit(0);
+  }
+  else
+  {
+    p(P_INFO,"exiting due to pipe problem\n");
+    close(pppdeathpipe);
+    send_padt();
+    exit(1);
+  }
+
 /*
  state = S_INITIATE;
  gettimeofday(&timeout,0);
@@ -1116,4 +1146,17 @@
 	}
      }
   }
+}
+
+void sig_handler(int sig)
+{
+ if ( ppp_pid != 0 )
+ {
+   p(P_INFO,"received signal %d, passing it onto pppd (pid %d)\n",sig,ppp_pid);
+   kill(ppp_pid, sig);
+ }
+ else
+ {
+   p(P_INFO,"signal %d, but pppd pid not defined\n",ppp_pid);
+ }
 }

>Release-Note:
>Audit-Trail:
>Unformatted: