#include <sys/errno.h>
#include <sys/file.h>
#include <sys/stat.h>
+#include <sys/utsname.h>
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <fcntl.h>
#include <ctype.h>
+#include <termios.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
#define MAX_ADDR_LEN 7
#endif
-#include <linux/version.h>
-#include <net/if.h>
+#include <linux/if.h>
#include <linux/ppp_defs.h>
-#include <net/if_arp.h>
+#include <linux/if_arp.h>
#include <linux/if_ppp.h>
-#include <net/route.h>
+#include <linux/route.h>
#include <linux/if_ether.h>
#include <netinet/in.h>
static int driver_version = 0;
static int driver_modification = 0;
static int driver_patch = 0;
+static int driver_is_old = 0;
static int restore_term = 0; /* 1 => we've munged the terminal */
static struct termios inittermios; /* Initial TTY termios */
static char *lock_file;
+static struct utsname utsname; /* for the kernel version */
+
#define MAX_IFS 100
#define FLAGS_GOOD (IFF_UP | IFF_BROADCAST)
die(1);
}
}
+
+ uname(&utsname);
}
/********************************************************************
if (defaultroute_exists(&rt))
{
- u_int32_t old_gateway = ((struct sockaddr_in *) (&rt.rt_gateway))->
- sin_addr.s_addr;
+ struct in_addr old_gateway =
+ ((struct sockaddr_in *) (&rt.rt_gateway))-> sin_addr;
- if (old_gateway != gateway)
+ if (old_gateway.s_addr != gateway)
{
syslog (LOG_ERR,
- "ppp not replacing existing default route to %s[%s]",
+ "not replacing existing default route to %s [%s]",
rt.rt_dev,
inet_ntoa (old_gateway));
}
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;
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;
if (!ok)
{
no_ppp_msg =
- "This system lacks kernel support for PPP. To include PPP support\n"
- "in the kernel, please follow the steps detailed in the "
- "README.linux\nfile in the ppp-2.3 distribution.\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.2 distribution.\n";
}
/*
* This is the PPP device. Validate the version of the driver at this
/* The modification levels must be legal */
if (driver_modification < my_modification)
{
- ok = 0;
+ if (driver_modification >= 2) {
+ /* we can cope with 2.2.0 and above */
+ driver_is_old = 1;
+ } else {
+ ok = 0;
+ }
}
close (s);
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;
/*
* 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;
+ 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;
- ((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;
+ ((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 LINUX_VERSION_CODE > 0x020100
- 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);
+ 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;
}
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;
+
+ if (strcmp(utsname.release, "2.1.16") < 0) {
/*
* Delete the route through the device
*/
- memset (&rt, '\0', sizeof (rt));
+ 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;
-
- ((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;
}
break;
}
#endif
+ if (demand && driver_is_old) {
+ option_error("demand dialling is not supported by kernel driver version "
+ "%d.%d.%d", driver_version, driver_modification,
+ driver_patch);
+ demand = 0;
+ }
}