]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/sys-linux.c
Describe environment variables set for scripts.
[ppp.git] / pppd / sys-linux.c
index e92f6845a825b75d6fe043ef8ee52715677bab25..f99282b5d59c431bdc6d2c8c22e45260ac08ca93 100644 (file)
@@ -25,6 +25,7 @@
 #include <sys/errno.h>
 #include <sys/file.h>
 #include <sys/stat.h>
 #include <sys/errno.h>
 #include <sys/file.h>
 #include <sys/stat.h>
+#include <sys/utsname.h>
 
 #include <stdio.h>
 #include <stdlib.h>
 
 #include <stdio.h>
 #include <stdlib.h>
@@ -37,6 +38,8 @@
 #include <signal.h>
 #include <fcntl.h>
 #include <ctype.h>
 #include <signal.h>
 #include <fcntl.h>
 #include <ctype.h>
+#include <termios.h>
+#include <unistd.h>
 
 /* This is in netdevice.h. However, this compile will fail miserably if
    you attempt to include netdevice.h because it has so many references
 
 /* This is in netdevice.h. However, this compile will fail miserably if
    you attempt to include netdevice.h because it has so many references
 #define MAX_ADDR_LEN 7
 #endif
 
 #define MAX_ADDR_LEN 7
 #endif
 
-#include <linux/version.h>
-#include <net/if.h>
 #include <linux/ppp_defs.h>
 #include <linux/ppp_defs.h>
-#include <net/if_arp.h>
 #include <linux/if_ppp.h>
 #include <linux/if_ppp.h>
+
+#if __GLIBC__ >= 2
+#include <net/if_arp.h>
 #include <net/route.h>
 #include <net/route.h>
+#include <netinet/if_ether.h>
+#else
+#include <linux/if.h>
+#include <linux/if_arp.h>
+#include <linux/route.h>
 #include <linux/if_ether.h>
 #include <linux/if_ether.h>
+#endif
 #include <netinet/in.h>
 #include <netinet/in.h>
+#include <arpa/inet.h>
 
 #include "pppd.h"
 #include "fsm.h"
 #include "ipcp.h"
 
 #include "pppd.h"
 #include "fsm.h"
 #include "ipcp.h"
-
-#ifndef RTF_DEFAULT  /* Normally in <linux/route.h> from <net/route.h> */
-#define RTF_DEFAULT  0
-#endif
+#include "patchlevel.h"
 
 #ifdef IPX_CHANGE
 #include "ipxcp.h"
 
 #ifdef IPX_CHANGE
 #include "ipxcp.h"
-#endif
+#include <linux/ipx.h>
+#endif /* IPX_CHANGE */
 
 #ifdef LOCKLIB
 #include <sys/locks.h>
 #endif
 
 
 #ifdef LOCKLIB
 #include <sys/locks.h>
 #endif
 
+#ifndef RTF_DEFAULT  /* Normally in <linux/route.h> from <net/route.h> */
+#define RTF_DEFAULT  0
+#endif
+
 #define ok_error(num) ((num)==EIO)
 
 static int tty_disc = N_TTY;   /* The TTY discipline */
 #define ok_error(num) ((num)==EIO)
 
 static int tty_disc = N_TTY;   /* The TTY discipline */
@@ -99,6 +111,8 @@ static u_int32_t proxy_arp_addr;     /* Addr for proxy arp entry added */
 
 static char *lock_file;
 
 
 static char *lock_file;
 
+static struct utsname utsname; /* for the kernel version */
+
 #define MAX_IFS                100
 
 #define FLAGS_GOOD (IFF_UP          | IFF_BROADCAST)
 #define MAX_IFS                100
 
 #define FLAGS_GOOD (IFF_UP          | IFF_BROADCAST)
@@ -135,22 +149,27 @@ extern u_char     inpacket_buf[]; /* borrowed from main.c */
  */
 
 extern int hungup;
  */
 
 extern int hungup;
-#define still_ppp() (hungup == 0)
 
 #ifndef LOCK_PREFIX
 #define LOCK_PREFIX    "/var/lock/LCK.."
 #endif
 
 
 #ifndef LOCK_PREFIX
 #define LOCK_PREFIX    "/var/lock/LCK.."
 #endif
 
-/********************************************************************
- *
- * Functions to read and set the flags value in the device driver
- */
-
 static void set_ppp_fd (int new_fd)
 static void set_ppp_fd (int new_fd)
-  {    
-    SYSDEBUG ((LOG_DEBUG, "setting ppp_fd to %d\n", ppp_fd));
-    ppp_fd = new_fd;
-  }
+{    
+       SYSDEBUG ((LOG_DEBUG, "setting ppp_fd to %d\n", ppp_fd));
+       ppp_fd = new_fd;
+}
+
+static int still_ppp(void)
+{
+       if (!hungup || ppp_fd == slave_fd)
+               return 1;
+       if (slave_fd >= 0) {
+               set_ppp_fd(slave_fd);
+               return 1;
+       }
+       return 0;
+}
 
 /********************************************************************
  *
 
 /********************************************************************
  *
@@ -218,6 +237,8 @@ void sys_init(void)
            die(1);
          }
       }
            die(1);
          }
       }
+
+    uname(&utsname);
   }
 
 /********************************************************************
   }
 
 /********************************************************************
@@ -229,7 +250,6 @@ void sys_init(void)
 
 void sys_cleanup(void)
   {
 
 void sys_cleanup(void)
   {
-    struct ifreq ifr;
 /*
  * Take down the device
  */
 /*
  * Take down the device
  */
@@ -402,9 +422,6 @@ void establish_ppp (int tty_fd)
 
 void disestablish_ppp(int tty_fd)
   {
 
 void disestablish_ppp(int tty_fd)
   {
-    int x;
-    char *s;
-
 /*
  * Attempt to restore the previous tty settings
  */
 /*
  * Attempt to restore the previous tty settings
  */
@@ -565,6 +582,12 @@ struct speed {
 #endif
 #ifdef EXTB
     { 38400, EXTB },
 #endif
 #ifdef EXTB
     { 38400, EXTB },
+#endif
+#ifdef B230400
+    { 230400, B230400 },
+#endif
+#ifdef B460800
+    { 460800, B460800 },
 #endif
     { 0, 0 }
 };
 #endif
     { 0, 0 }
 };
@@ -623,7 +646,7 @@ static int baud_rate_of (int speed)
 
 void set_up_tty (int tty_fd, int local)
   {
 
 void set_up_tty (int tty_fd, int local)
   {
-    int speed, x;
+    int speed;
     struct termios tios;
     
     if (tcgetattr(tty_fd, &tios) < 0)
     struct termios tios;
     
     if (tcgetattr(tty_fd, &tios) < 0)
@@ -1107,7 +1130,10 @@ static int path_to_procfs (void)
          }
        fclose (fp);
       }
          }
        fclose (fp);
       }
-    return 0;
+
+    /* Default the mount location of /proc */
+    strncpy (route_buffer, "/proc", sizeof (route_buffer)-10);
+    return 1;
   }
 
 /********************************************************************
   }
 
 /********************************************************************
@@ -1174,7 +1200,7 @@ static int open_route_table (void)
 static int read_route_table (struct rtentry *rt)
   {
     static char delims[] = " \t\n";
 static int read_route_table (struct rtentry *rt)
   {
     static char delims[] = " \t\n";
-    char *dev_ptr, *ptr, *dst_ptr, *gw_ptr, *flag_ptr;
+    char *dev_ptr, *dst_ptr, *gw_ptr, *flag_ptr;
        
     memset (rt, '\0', sizeof (struct rtentry));
 
        
     memset (rt, '\0', sizeof (struct rtentry));
 
@@ -1276,10 +1302,10 @@ int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
     SET_SA_FAMILY (rt.rt_dst,     AF_INET);
     SET_SA_FAMILY (rt.rt_gateway, AF_INET);
 
     SET_SA_FAMILY (rt.rt_dst,     AF_INET);
     SET_SA_FAMILY (rt.rt_gateway, AF_INET);
 
-#if LINUX_VERSION_CODE > 0x020100
-    SET_SA_FAMILY (rt.rt_genmask, AF_INET);
-    ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = 0L;
-#endif
+    if (strcmp(utsname.release, "2.1.0") > 0) {
+      SET_SA_FAMILY (rt.rt_genmask, AF_INET);
+      ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = 0L;
+    }
 
     ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway;
     
 
     ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway;
     
@@ -1312,10 +1338,10 @@ int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway)
     SET_SA_FAMILY (rt.rt_dst,     AF_INET);
     SET_SA_FAMILY (rt.rt_gateway, AF_INET);
 
     SET_SA_FAMILY (rt.rt_dst,     AF_INET);
     SET_SA_FAMILY (rt.rt_gateway, AF_INET);
 
-#if LINUX_VERSION_CODE > 0x020100
-    SET_SA_FAMILY (rt.rt_genmask, AF_INET);
-    ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = 0L;
-#endif
+    if (strcmp(utsname.release, "2.1.0") > 0) {
+      SET_SA_FAMILY (rt.rt_genmask, AF_INET);
+      ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = 0L;
+    }
 
     ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway;
     
 
     ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway;
     
@@ -1416,8 +1442,7 @@ static int get_ether_addr (u_int32_t ipaddr,
                           struct sockaddr *hwaddr,
                           char *name)
   {
                           struct sockaddr *hwaddr,
                           char *name)
   {
-    struct ifreq *ifr, *ifend, *ifp;
-    int i;
+    struct ifreq *ifr, *ifend;
     u_int32_t ina, mask;
     struct ifreq ifreq;
     struct ifconf ifc;
     u_int32_t ina, mask;
     struct ifreq ifreq;
     struct ifconf ifc;
@@ -1641,7 +1666,7 @@ static void decode_version (char *buf, int *version,
 
 /********************************************************************
  *
 
 /********************************************************************
  *
- * Procedure to determine if the PPP line dicipline is registered.
+ * Procedure to determine if the PPP line discipline is registered.
  */
 
 int
  */
 
 int
@@ -1753,7 +1778,7 @@ int ppp_available(void)
          "This system lacks kernel support for PPP.  This could be because\n"
          "the PPP kernel module is not loaded, or because the kernel is\n"
          "not configured for PPP.  See the README.linux file in the\n"
          "This system lacks kernel support for PPP.  This could be because\n"
          "the PPP kernel module is not loaded, or because the kernel is\n"
          "not configured for PPP.  See the README.linux file in the\n"
-         "ppp-2.3.1 distribution.\n";
+         "ppp-2.3.3 distribution.\n";
       }
 /*
  *  This is the PPP device. Validate the version of the driver at this
       }
 /*
  *  This is the PPP device. Validate the version of the driver at this
@@ -1784,7 +1809,7 @@ int ppp_available(void)
 /*
  * Validate the version of the driver against the version that we used.
  */
 /*
  * Validate the version of the driver against the version that we used.
  */
-       decode_version (PPP_VERSION,
+       decode_version (VERSION,
                        &my_version,
                        &my_modification,
                        &my_patch);
                        &my_version,
                        &my_modification,
                        &my_patch);
@@ -2075,7 +2100,7 @@ int sifvjcomp (int u, int vjcomp, int cidcomp, int maxcid)
          {
            if (! ok_error (errno))
              {
          {
            if (! ok_error (errno))
              {
-               syslog (LOG_ERR, "ioctl(PPPIOCSFLAGS): %m(%d)", errno);
+               syslog (LOG_ERR, "ioctl(PPPIOCSMAXCID): %m(%d)", errno);
              }
            vjcomp = 0;
          }
              }
            vjcomp = 0;
          }
@@ -2207,8 +2232,11 @@ int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
        return (0);
       } 
 /*
        return (0);
       } 
 /*
- *  Set the netmask
+ *  Set the netmask.
+ *  For recent kernels, force the netmask to 255.255.255.255.
  */
  */
+    if (strcmp(utsname.release, "2.1.16") >= 0)
+      net_mask = ~0L;
     if (net_mask != 0)
       {
        ((struct sockaddr_in *) &ifr.ifr_netmask)->sin_addr.s_addr = net_mask;
     if (net_mask != 0)
       {
        ((struct sockaddr_in *) &ifr.ifr_netmask)->sin_addr.s_addr = net_mask;
@@ -2224,29 +2252,29 @@ int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
 /*
  *  Add the device route
  */
 /*
  *  Add the device route
  */
-#if LINUX_VERSION_CODE < 0x020100+16           /* 2.1.16 */
-    SET_SA_FAMILY (rt.rt_dst,     AF_INET);
-    SET_SA_FAMILY (rt.rt_gateway, AF_INET);
-    rt.rt_dev = ifname;
-
-    ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = 0L;
-    ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr     = his_adr;
-    rt.rt_flags = RTF_UP | RTF_HOST;
+    if (strcmp(utsname.release, "2.1.16") < 0) {
+      SET_SA_FAMILY (rt.rt_dst,     AF_INET);
+      SET_SA_FAMILY (rt.rt_gateway, AF_INET);
+      rt.rt_dev = ifname;
 
 
-#if LINUX_VERSION_CODE > 0x020100
-    SET_SA_FAMILY (rt.rt_genmask, AF_INET);
-    ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = -1L;
-#endif
+      ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = 0L;
+      ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr     = his_adr;
+      rt.rt_flags = RTF_UP | RTF_HOST;
 
 
-    if (ioctl(sock_fd, SIOCADDRT, &rt) < 0)
-      {
-       if (! ok_error (errno))
-         {
-           syslog (LOG_ERR, "ioctl(SIOCADDRT) device route: %m(%d)", errno);
-         }
-        return (0);
+      if (strcmp(utsname.release, "2.1.0") > 0) {
+       SET_SA_FAMILY (rt.rt_genmask, AF_INET);
+       ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = -1L;
       }
       }
-#endif
+
+      if (ioctl(sock_fd, SIOCADDRT, &rt) < 0)
+       {
+         if (! ok_error (errno))
+           {
+             syslog (LOG_ERR, "ioctl(SIOCADDRT) device route: %m(%d)", errno);
+           }
+         return (0);
+       }
+    }
     return 1;
   }
 
     return 1;
   }
 
@@ -2258,35 +2286,36 @@ int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr,
 
 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
   {
 
 int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr)
   {
-#if LINUX_VERSION_CODE < 0x020100+16           /* 2.1.16 */
     struct rtentry rt;
     struct rtentry rt;
+
+    if (strcmp(utsname.release, "2.1.16") < 0) {
 /*
  *  Delete the route through the device
  */
 /*
  *  Delete the route through the device
  */
-    memset (&rt, '\0', sizeof (rt));
-
-    SET_SA_FAMILY (rt.rt_dst,     AF_INET);
-    SET_SA_FAMILY (rt.rt_gateway, AF_INET);
-    rt.rt_dev = ifname;
+      memset (&rt, '\0', sizeof (rt));
 
 
-    ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = 0;
-    ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr     = his_adr;
-    rt.rt_flags = RTF_UP | RTF_HOST;
+      SET_SA_FAMILY (rt.rt_dst,     AF_INET);
+      SET_SA_FAMILY (rt.rt_gateway, AF_INET);
+      rt.rt_dev = ifname;
 
 
-#if LINUX_VERSION_CODE > 0x020100
-    SET_SA_FAMILY (rt.rt_genmask, AF_INET);
-    ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = -1L;
-#endif
+      ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = 0;
+      ((struct sockaddr_in *) &rt.rt_dst)->sin_addr.s_addr     = his_adr;
+      rt.rt_flags = RTF_UP | RTF_HOST;
 
 
-    if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH)
-      {
-       if (still_ppp() && ! ok_error (errno))
-         {
-           syslog (LOG_ERR, "ioctl(SIOCDELRT) device route: %m(%d)", errno);
-         }
-       return (0);
+      if (strcmp(utsname.release, "2.1.0") > 0) {
+       SET_SA_FAMILY (rt.rt_genmask, AF_INET);
+       ((struct sockaddr_in *) &rt.rt_genmask)->sin_addr.s_addr = -1L;
       }
       }
-#endif
+
+      if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH)
+       {
+         if (still_ppp() && ! ok_error (errno))
+           {
+             syslog (LOG_ERR, "ioctl(SIOCDELRT) device route: %m(%d)", errno);
+           }
+         return (0);
+       }
+    }
     return 1;
   }
 
     return 1;
   }
 
@@ -2305,7 +2334,7 @@ open_ppp_loopback(void)
     master_fd = -1;
     for (i = 0; i < 64; ++i) {
       sprintf(loop_name, "/dev/pty%c%x", 'p' + i / 16, i % 16);
     master_fd = -1;
     for (i = 0; i < 64; ++i) {
       sprintf(loop_name, "/dev/pty%c%x", 'p' + i / 16, i % 16);
-      master_fd = open(loop_name, O_RDWR, 0);
+      master_fd = open(loop_name, O_RDWR | O_NOCTTY, 0);
       if (master_fd >= 0)
        break;
     }
       if (master_fd >= 0)
        break;
     }
@@ -2315,7 +2344,7 @@ open_ppp_loopback(void)
     }
     SYSDEBUG((LOG_DEBUG, "using %s for loopback", loop_name));
     loop_name[5] = 't';
     }
     SYSDEBUG((LOG_DEBUG, "using %s for loopback", loop_name));
     loop_name[5] = 't';
-    slave_fd = open(loop_name, O_RDWR, 0);
+    slave_fd = open(loop_name, O_RDWR | O_NOCTTY, 0);
     if (slave_fd < 0) {
       syslog(LOG_ERR, "Couldn't open %s for loopback: %m", loop_name);
       die(1);
     if (slave_fd < 0) {
       syslog(LOG_ERR, "Couldn't open %s for loopback: %m", loop_name);
       die(1);
@@ -2421,8 +2450,6 @@ sifnpmode(u, proto, mode)
   }
 
 \f
   }
 
 \f
-#include <linux/ipx.h>
-
 /********************************************************************
  *
  * sipxfaddr - Config the interface IPX networknumber
 /********************************************************************
  *
  * sipxfaddr - Config the interface IPX networknumber
@@ -2434,7 +2461,6 @@ int sipxfaddr (int unit, unsigned long int network, unsigned char * node )
 
 #ifdef IPX_CHANGE
     int    skfd; 
 
 #ifdef IPX_CHANGE
     int    skfd; 
-    struct sockaddr_ipx  ipx_addr;
     struct ifreq         ifr;
     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
 
     struct ifreq         ifr;
     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
 
@@ -2497,7 +2523,6 @@ int cipxfaddr (int unit)
 
 #ifdef IPX_CHANGE
     int    skfd; 
 
 #ifdef IPX_CHANGE
     int    skfd; 
-    struct sockaddr_ipx  ipx_addr;
     struct ifreq         ifr;
     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
 
     struct ifreq         ifr;
     struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr;
 
@@ -2560,6 +2585,21 @@ daemon(nochdir, noclose)
     return 0;
 }
 
     return 0;
 }
 
+/*
+ * Use the hostname as part of the random number seed.
+ */
+int
+get_host_seed()
+{
+    int h;
+    char *p = hostname;
+
+    h = 407;
+    for (p = hostname; *p != 0; ++p)
+       h = h * 37 + *p;
+    return h;
+}
+
 /********************************************************************
  *
  * sys_check_options - check the options that the user specified
 /********************************************************************
  *
  * sys_check_options - check the options that the user specified