From 8000b9241650fc01778c2a89cfae0184e424703f Mon Sep 17 00:00:00 2001 From: Paul Mackerras Date: Tue, 11 Jul 1995 06:37:00 +0000 Subject: [PATCH] Updates from Al Longyear --- README.linux | 51 +++++++++- pppd/sys-linux.c | 243 ++++++++++++++++++++++++++++++++--------------- 2 files changed, 213 insertions(+), 81 deletions(-) diff --git a/README.linux b/README.linux index ce51d7b..6df8c66 100644 --- a/README.linux +++ b/README.linux @@ -82,8 +82,10 @@ The pppd program comes from the free distribution of PPP for Suns and Chris Torek. Jim Freeman added the code to support a ppp module and to dynamically -extend the number of ppp devices. The Space.c module should not have -any devices defined for this logic to work. +extend the number of ppp devices. All ppp devices listed in the Space.c +will be unlinked when the kernel is loaded. This feature makes the use +of '16 channel' support obsolete. + CHANGES FROM THE PREVIOUS VERSION @@ -136,6 +138,7 @@ CHANGES FROM THE PREVIOUS VERSION devices, it will remain at that level until you next reload the kernel. + FUTURE PLANS The IPX support is still minimal. There is code which will only work with @@ -145,6 +148,7 @@ enable/disable the IPX frames. Jim Freeman is reportily working on the IPX support. + INSTALLATION This version of PPP has been tested on 1.1.x (x>=14) It will probably @@ -171,8 +175,8 @@ joining the PPP channel of linux-activists: You can send to the list by mailing to linux-ppp@vger.rutgers.edu. This is a majordomo mailing list and is unlike the earlier version on hut.fi. There is no magic header - required for this list. In addition, it is mirrored to the usenet - group linux.act.ppp. You may choose to read the few messages posted + required for this list. In addition, it is gated to the usenet + group linux.dev.ppp. You may choose to read the few messages posted there. Usenet News Groups @@ -278,6 +282,13 @@ not work with the older kernel driver. If you don't know how to build a kernel, then you should read the README file in the kernel source directory. +If you wish module support then you need to have the 'modules-1.1.87' +package installed as the minimum version. Earlier versions of the module +support will not work properly. + +Instructions on building the kernel with modules are given in the +README.modules in the kernel source directory. + 4. Build the programs. The programs are built next. The command to build the programs is fairly @@ -303,6 +314,30 @@ file 'linux/Makefile.linux'. After building the new kernel, you will need to actually use it. Reboot the Linux system and you may then use the new pppd program. +7. Load optional modules. + +If you are using loadable modules for the ppp or bsd compression then +you must load them after the kernel has been started. The following +relative order must be maintained. + +Sequence Module Description + 1 slhc.o VJ header compression + 2 ppp.o PPP driver + 3 bsd_comp.o BSD compression for PPP's compression protocol. + +You may elect not to load the BSD compression module if you desire. There +is a controversy regarding a Motorola software patent and while it is +believed that this code does not infringe upon the patent, it is however +an optional component. + +In addition, if memory is a premium, do not run the BSD compression. It +may take large amounts of memory (up to 2.6 meg) for high compression +lengths to hold the compression dictionaries. + +Without the BSD compression module, the PPP driver will not accept PPP's +compression control protocol for BSD compression. + + GENERAL NETWORK CONFIGURATION @@ -366,6 +401,7 @@ right domain name to use and the IP numbers of nameservers from whoever's providing your PPP link. + CONNECTING TO A PPP SERVER To use PPP, you invoke the pppd program with appropriate options. @@ -651,6 +687,7 @@ is to use ifconfig ppp0 to get the interface address and then edit /etc/hosts appropriately. + SETTING UP A MACHINE FOR INCOMING PPP CONNECTIONS Suppose you want to permit another machine to call yours up and start @@ -738,6 +775,7 @@ this means that chelseapc can communicate just as if it was directly connected to the Ethernet. + SETTING UP A MACHINE FOR INCOMING PPP CONNECTIONS WITH DYNAMIC IP The use of dynamic IP assignments is not much different from that @@ -812,6 +850,11 @@ Then you may secure the binaries so that they are executable from the owner (which should be root) and the group only. All other users would be denied all access to the files and executables. +d) Prevent the motd file from being sent to the ppp user. +touch ~ppp/.hushlogin +chown root ~ppp/.hushlogin +chmod 444 ~ppp/.hushlogin + ADDITIONAL INFORMATION diff --git a/pppd/sys-linux.c b/pppd/sys-linux.c index 335f8a1..ade0894 100644 --- a/pppd/sys-linux.c +++ b/pppd/sys-linux.c @@ -52,16 +52,16 @@ #include "ipcp.h" static int initdisc = -1; /* Initial TTY discipline */ -static int prev_kdebugflag = 0; - -static int restore_term; /* 1 => we've munged the terminal */ -static struct termios inittermios; /* Initial TTY termios */ - -int sockfd; /* socket for doing interface ioctls */ - +static int prev_kdebugflag = 0; +static int has_default_route = 0; +static int has_proxy_arp = 0; static int driver_version = 0; static int driver_modification = 0; static int driver_patch = 0; +static int restore_term = 0; /* 1 => we've munged the terminal */ +static struct termios inittermios; /* Initial TTY termios */ + +int sockfd; /* socket for doing interface ioctls */ static char *lock_file; @@ -80,11 +80,18 @@ static char *lock_file; memset ((char *) &(addr), '\0', sizeof(addr)); \ addr.sa_family = (family); +/* + * Determine if the PPP connection should still be present. + */ + +extern int hungup; +#define still_ppp() (hungup == 0) + /* * Functions to read and set the flags value in the device driver */ -int get_flags (void) +static int get_flags (void) { int flags; @@ -98,9 +105,10 @@ int get_flags (void) return flags; } -void set_flags (int flags) +static void set_flags (int flags) { MAINDEBUG ((LOG_DEBUG, "set flags = %x\n", flags)); + if (ioctl(fd, PPPIOCSFLAGS, (caddr_t) &flags) < 0) { syslog(LOG_ERR, "ioctl(PPPIOCSFLAGS, %x): %m", flags); @@ -221,6 +229,15 @@ void disestablish_ppp(void) { int x; char *s; +/* + * If this is no longer PPP mode then there is nothing that can be done + * about restoring the previous mode. + */ + if (!still_ppp()) + { + initdisc = -1; + return; + } /* * Check whether the link seems not to be 8-bit clean. */ @@ -365,7 +382,7 @@ int translate_speed (int bps) { struct speed *speedp; - if (bps == 0) + if (bps != 0) { for (speedp = speeds; speedp->speed_int; speedp++) { @@ -521,7 +538,7 @@ void restore_tty (void) if (tcsetattr(fd, TCSAFLUSH, &inittermios) < 0) { - if (errno != ENXIO) + if (errno != EIO) { syslog(LOG_WARNING, "tcsetattr: %m"); } @@ -606,6 +623,17 @@ void ppp_send_config (int unit,int mtu,u_int32_t asyncmap,int pcomp,int accomp) struct ifreq ifr; MAINDEBUG ((LOG_DEBUG, "send_config: mtu = %d\n", mtu)); +/* + * If we were called because the link has gone down then there is nothing + * which may be done. Just return without incident. + */ + if (!still_ppp()) + { + return; + } +/* + * Set the MTU and other parameters for the ppp device + */ strncpy(ifr.ifr_name, ifname, sizeof (ifr.ifr_name)); ifr.ifr_mtu = mtu; @@ -653,6 +681,17 @@ void ppp_recv_config (int unit,int mru,u_int32_t asyncmap,int pcomp,int accomp) u_int x; MAINDEBUG ((LOG_DEBUG, "recv_config: mru = %d\n", mru)); +/* + * If we were called because the link has gone down then there is nothing + * which may be done. Just return without incident. + */ + if (!still_ppp()) + { + return; + } +/* + * Set the receiver parameters + */ if (ioctl(fd, PPPIOCSMRU, (caddr_t) &mru) < 0) { syslog(LOG_ERR, "ioctl(PPPIOCSMRU): %m"); @@ -692,10 +731,13 @@ int ccp_test (int unit, u_char *opt_ptr, int opt_len, int for_transmit) void ccp_flags_set (int unit, int isopen, int isup) { - int x = get_flags(); - x = isopen? x | SC_CCP_OPEN : x &~ SC_CCP_OPEN; - x = isup? x | SC_CCP_UP : x &~ SC_CCP_UP; - set_flags (x); + if (still_ppp()) + { + int x = get_flags(); + x = isopen? x | SC_CCP_OPEN : x &~ SC_CCP_OPEN; + x = isup? x | SC_CCP_UP : x &~ SC_CCP_UP; + set_flags (x); + } } /* @@ -1061,22 +1103,26 @@ int sifdefaultroute (int unit, int gateway) { struct rtentry rt; - if (defaultroute_exists()) + if (has_default_route == 0) { - return 0; - } + if (defaultroute_exists()) + { + return 0; + } - memset (&rt, '\0', sizeof (rt)); - SET_SA_FAMILY (rt.rt_dst, AF_INET); - SET_SA_FAMILY (rt.rt_gateway, AF_INET); - ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway; + memset (&rt, '\0', sizeof (rt)); + SET_SA_FAMILY (rt.rt_dst, AF_INET); + SET_SA_FAMILY (rt.rt_gateway, AF_INET); + ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway; - rt.rt_flags = RTF_UP | RTF_GATEWAY; - if (ioctl(sockfd, SIOCADDRT, &rt) < 0) - { - syslog (LOG_ERR, "default route ioctl(SIOCADDRT): %m"); - return 0; + rt.rt_flags = RTF_UP | RTF_GATEWAY; + if (ioctl(sockfd, SIOCADDRT, &rt) < 0) + { + syslog (LOG_ERR, "default route ioctl(SIOCADDRT): %m"); + return 0; + } } + has_default_route = 1; return 1; } @@ -1087,17 +1133,24 @@ int sifdefaultroute (int unit, int gateway) int cifdefaultroute (int unit, int gateway) { struct rtentry rt; - - SET_SA_FAMILY (rt.rt_dst, AF_INET); - SET_SA_FAMILY (rt.rt_gateway, AF_INET); - ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway; - - rt.rt_flags = RTF_UP | RTF_GATEWAY; - if (ioctl(sockfd, SIOCDELRT, &rt) < 0) + + if (has_default_route) { - syslog (LOG_ERR, "default route ioctl(SIOCDELRT): %m"); - return 0; + SET_SA_FAMILY (rt.rt_dst, AF_INET); + SET_SA_FAMILY (rt.rt_gateway, AF_INET); + ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway; + + rt.rt_flags = RTF_UP | RTF_GATEWAY; + if (ioctl(sockfd, SIOCDELRT, &rt) < 0) + { + if (errno != ENOENT || still_ppp()) + { + syslog (LOG_ERR, "default route ioctl(SIOCDELRT): %m"); + return 0; + } + } } + has_default_route = 0; return 1; } @@ -1109,26 +1162,31 @@ int sifproxyarp (int unit, u_int32_t his_adr) { struct arpreq arpreq; - memset (&arpreq, '\0', sizeof(arpreq)); + if (has_proxy_arp == 0) + { + memset (&arpreq, '\0', sizeof(arpreq)); /* * Get the hardware address of an interface on the same subnet * as our local address. */ - if (!get_ether_addr(his_adr, &arpreq.arp_ha)) - { - syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP"); - return 0; - } - - SET_SA_FAMILY(arpreq.arp_pa, AF_INET); - ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = his_adr; - arpreq.arp_flags = ATF_PERM | ATF_PUBL; + if (!get_ether_addr(his_adr, &arpreq.arp_ha)) + { + syslog(LOG_ERR, "Cannot determine ethernet address for proxy ARP"); + return 0; + } - if (ioctl(sockfd, SIOCSARP, (caddr_t)&arpreq) < 0) - { - syslog(LOG_ERR, "ioctl(SIOCSARP): %m"); - return 0; + SET_SA_FAMILY(arpreq.arp_pa, AF_INET); + ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = his_adr; + arpreq.arp_flags = ATF_PERM | ATF_PUBL; + + if (ioctl(sockfd, SIOCSARP, (caddr_t)&arpreq) < 0) + { + syslog(LOG_ERR, "ioctl(SIOCSARP): %m"); + return 0; + } } + + has_proxy_arp = 1; return 1; } @@ -1139,16 +1197,20 @@ int sifproxyarp (int unit, u_int32_t his_adr) int cifproxyarp (int unit, u_int32_t his_adr) { struct arpreq arpreq; - - memset (&arpreq, '\0', sizeof(arpreq)); - SET_SA_FAMILY(arpreq.arp_pa, AF_INET); - - ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = his_adr; - if (ioctl(sockfd, SIOCDARP, (caddr_t)&arpreq) < 0) + + if (has_proxy_arp == 1) { - syslog(LOG_WARNING, "ioctl(SIOCDARP): %m"); - return 0; + memset (&arpreq, '\0', sizeof(arpreq)); + SET_SA_FAMILY(arpreq.arp_pa, AF_INET); + + ((struct sockaddr_in *) &arpreq.arp_pa)->sin_addr.s_addr = his_adr; + if (ioctl(sockfd, SIOCDARP, (caddr_t)&arpreq) < 0) + { + syslog(LOG_WARNING, "ioctl(SIOCDARP): %m"); + return 0; + } } + has_proxy_arp = 0; return 1; } @@ -1192,7 +1254,7 @@ int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr) ifreq.ifr_name)); /* * Check that the interface is up, and not point-to-point - * or loopback. + * nor loopback. */ if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) { @@ -1232,6 +1294,7 @@ int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr) /* * Now get the hardware address. */ +#if 0 /* old code */ if (ioctl (sockfd, SIOCGIFHWADDR, &ifreq) < 0) { syslog(LOG_ERR, "SIOCGIFHWADDR(%s): %m", ifreq.ifr_name); @@ -1249,6 +1312,29 @@ int get_ether_addr (u_int32_t ipaddr, struct sockaddr *hwaddr) (int) ((unsigned char *) &hwaddr->sa_data)[3], (int) ((unsigned char *) &hwaddr->sa_data)[4], (int) ((unsigned char *) &hwaddr->sa_data)[5])); +#else /* the 'proper' code */ + memset (&ifreq.ifr_hwaddr, 0, sizeof (struct sockaddr)); + if (ioctl (sockfd, SIOCGIFHWADDR, &ifreq) < 0) + { + syslog(LOG_ERR, "SIOCGIFHWADDR(%s): %m", ifreq.ifr_name); + return 0; + } + + memcpy (hwaddr, + &ifreq.ifr_hwaddr, + sizeof (struct sockaddr)); + + MAINDEBUG ((LOG_DEBUG, + "proxy arp: found hwaddr %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + (int) ((unsigned char *) &hwaddr->sa_data)[0], + (int) ((unsigned char *) &hwaddr->sa_data)[1], + (int) ((unsigned char *) &hwaddr->sa_data)[2], + (int) ((unsigned char *) &hwaddr->sa_data)[3], + (int) ((unsigned char *) &hwaddr->sa_data)[4], + (int) ((unsigned char *) &hwaddr->sa_data)[5], + (int) ((unsigned char *) &hwaddr->sa_data)[6], + (int) ((unsigned char *) &hwaddr->sa_data)[7])); +#endif return 1; } @@ -1315,7 +1401,7 @@ u_int32_t GetMask (u_int32_t addr) continue; } /* - * Check that the interface is up, and not point-to-point or loopback. + * Check that the interface is up, and not point-to-point nor loopback. */ strncpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name)); if (ioctl(sockfd, SIOCGIFFLAGS, &ifreq) < 0) @@ -1337,7 +1423,6 @@ u_int32_t GetMask (u_int32_t addr) mask |= ((struct sockaddr_in *)&ifreq.ifr_addr)->sin_addr.s_addr; break; } - return mask; } @@ -1348,7 +1433,6 @@ u_int32_t GetMask (u_int32_t addr) static void decode_version (char *buf, int *version, int *modification, int *patch) { - *version = (int) strtoul (buf, &buf, 10); *modification = 0; *patch = 0; @@ -1439,7 +1523,9 @@ int ppp_available(void) { int s, ok; struct ifreq ifr; - int my_version, my_modification, my_patch; + char abBuffer [1024]; + int size; + int my_version, my_modification, my_patch; /* * Open a socket for doing the ioctl operations. */ @@ -1476,26 +1562,25 @@ int ppp_available(void) { ok = 0; } + + if (!ok) + { + return 0; + } /* * This is the PPP device. Validate the version of the driver at this * point to ensure that this program will work with the driver. */ + ifr.ifr_data = abBuffer; + size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr); + ok = size >= 0; + if (ok) { - char abBuffer [1024]; - int size; - - ifr.ifr_data = abBuffer; - size = ioctl (s, SIOCGPPPVER, (caddr_t) &ifr); - ok = size >= 0; - - if (ok) - { - decode_version (abBuffer, - &driver_version, - &driver_modification, - &driver_patch); - } + decode_version (abBuffer, + &driver_version, + &driver_modification, + &driver_patch); } if (!ok) @@ -1536,6 +1621,10 @@ int ppp_available(void) return ok; } +/* + * Update the wtmp file with the appropriate user name and tty device. + */ + int logwtmp (char *line, char *name, char *host) { struct utmp ut; -- 2.39.2