X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fsys-linux.c;h=e23397b0e6f0c77290cd13d98bf60e3a8c8aed3e;hp=cf034eb8284c9713df8ff8a198bfbca81783a021;hb=54a510907ca30d8a1651fdb5f7c2c360f4ef7e27;hpb=ef42266dc1191f4ec2c858211544f568b4af4cdb diff --git a/pppd/sys-linux.c b/pppd/sys-linux.c index cf034eb..e23397b 100644 --- a/pppd/sys-linux.c +++ b/pppd/sys-linux.c @@ -47,6 +47,7 @@ #define MAX_ADDR_LEN 7 #endif +#include #include #include #include @@ -59,10 +60,18 @@ #include "fsm.h" #include "ipcp.h" +#ifndef RTF_DEFAULT /* Normally in from */ +#define RTF_DEFAULT 0 +#endif + #ifdef IPX_CHANGE #include "ipxcp.h" #endif +#ifdef LOCKLIB +#include +#endif + #define ok_error(num) ((num)==EIO) static int tty_disc = N_TTY; /* The TTY discipline */ @@ -232,7 +241,7 @@ void sys_cleanup(void) */ if (default_route_gateway != 0) { - cifdefaultroute(0, default_route_gateway); + cifdefaultroute(0, 0, default_route_gateway); } if (has_proxy_arp) @@ -745,7 +754,7 @@ void output (int unit, unsigned char *p, int len) { if (debug) { - log_packet(p, len, "sent "); + log_packet(p, len, "sent ", LOG_DEBUG); } if (write(ppp_fd, p, len) < 0) @@ -1243,7 +1252,7 @@ static int defaultroute_exists (struct rtentry *rt) * sifdefaultroute - assign a default route through the address given. */ -int sifdefaultroute (int unit, u_int32_t gateway) +int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) { struct rtentry rt; @@ -1265,9 +1274,15 @@ int sifdefaultroute (int unit, u_int32_t gateway) memset (&rt, '\0', sizeof (rt)); 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 + ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway; - rt.rt_flags = RTF_UP | RTF_GATEWAY; + rt.rt_flags = RTF_UP | RTF_GATEWAY | RTF_DEFAULT; if (ioctl(sock_fd, SIOCADDRT, &rt) < 0) { if ( ! ok_error ( errno )) @@ -1286,7 +1301,7 @@ int sifdefaultroute (int unit, u_int32_t gateway) * cifdefaultroute - delete a default route through the address given. */ -int cifdefaultroute (int unit, u_int32_t gateway) +int cifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) { struct rtentry rt; @@ -1295,9 +1310,15 @@ int cifdefaultroute (int unit, u_int32_t gateway) memset (&rt, '\0', sizeof (rt)); 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 + ((struct sockaddr_in *) &rt.rt_gateway)->sin_addr.s_addr = gateway; - rt.rt_flags = RTF_UP | RTF_GATEWAY; + rt.rt_flags = RTF_UP | RTF_GATEWAY | RTF_DEFAULT; if (ioctl(sock_fd, SIOCDELRT, &rt) < 0 && errno != ESRCH) { if (still_ppp()) @@ -1368,8 +1389,9 @@ int cifproxyarp (int unit, u_int32_t his_adr) { 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; + arpreq.arp_flags = ATF_PERM | ATF_PUBL; + if (ioctl(sock_fd, SIOCDARP, (caddr_t)&arpreq) < 0) { if ( ! ok_error ( errno )) @@ -1396,7 +1418,6 @@ static int get_ether_addr (u_int32_t ipaddr, struct ifreq *ifr, *ifend, *ifp; int i; u_int32_t ina, mask; - struct sockaddr_dl *dla; struct ifreq ifreq; struct ifconf ifc; struct ifreq ifs[MAX_IFS]; @@ -1796,7 +1817,7 @@ int ppp_available(void) * Update the wtmp file with the appropriate user name and tty device. */ -int logwtmp (char *line, char *name, char *host) +void logwtmp (const char *line, const char *name, const char *host) { int wtmp; struct utmp ut, *utp; @@ -1884,6 +1905,35 @@ int logwtmp (char *line, char *name, char *host) int lock (char *dev) { +#ifdef LOCKLIB + int result; + lock_file = malloc(strlen(dev) + 1); + if (lock_file == NULL) + { + novm("lock file name"); + } + strcpy (lock_file, dev); + result = mklock (dev, (void *) 0); + + if (result > 0) + { + syslog (LOG_NOTICE, "Device %s is locked by pid %d", dev, result); + free (lock_file); + lock_file = NULL; + result = -1; + } + else + { + if (result < 0) + { + syslog (LOG_ERR, "Can't create lock file %s", lock_file); + free (lock_file); + lock_file = NULL; + result = -1; + } + } + return (result); +#else char hdb_lock_buffer[12]; int fd, n; int pid = getpid(); @@ -1954,7 +2004,8 @@ int lock (char *dev) #else pid = ((int *) hdb_lock_buffer)[0]; #endif - if (pid == 0 || (kill(pid, 0) == -1 && errno == ESRCH)) + if (pid == 0 || pid == getpid() + || (kill(pid, 0) == -1 && errno == ESRCH)) { n = 0; } @@ -1979,6 +2030,7 @@ int lock (char *dev) free(lock_file); lock_file = NULL; return -1; +#endif } @@ -1991,7 +2043,11 @@ void unlock(void) { if (lock_file) { +#ifdef LOCKLIB + (void) rmlock (lock_file, (void *) 0); +#else unlink(lock_file); +#endif free(lock_file); lock_file = NULL; } @@ -2161,14 +2217,20 @@ int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, /* * 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; /* MJC */ + 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 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)) @@ -2177,6 +2239,7 @@ int sifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr, } return (0); } +#endif return 1; } @@ -2188,6 +2251,7 @@ 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) { +#if LINUX_VERSION_CODE < 0x020100+16 /* 2.1.16 */ struct rtentry rt; /* * Delete the route through the device @@ -2196,12 +2260,17 @@ int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) SET_SA_FAMILY (rt.rt_dst, AF_INET); SET_SA_FAMILY (rt.rt_gateway, AF_INET); - rt.rt_dev = ifname; /* MJC */ + 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; +#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, SIOCDELRT, &rt) < 0 && errno != ESRCH) { if (still_ppp() && ! ok_error (errno)) @@ -2210,6 +2279,7 @@ int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) } return (0); } +#endif return 1; } @@ -2222,15 +2292,27 @@ int cifaddr (int unit, u_int32_t our_adr, u_int32_t his_adr) void open_ppp_loopback(void) { - int flags; + int flags, i; struct termios tios; - if (openpty (&master_fd, &slave_fd, loop_name, NULL, NULL) < 0) - { - syslog(LOG_ERR, "No free pty for loopback"); - die(1); - } + 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); + if (master_fd >= 0) + break; + } + if (master_fd < 0) { + syslog(LOG_ERR, "No free pty for loopback"); + die(1); + } SYSDEBUG((LOG_DEBUG, "using %s for loopback", loop_name)); + loop_name[5] = 't'; + slave_fd = open(loop_name, O_RDWR, 0); + if (slave_fd < 0) { + syslog(LOG_ERR, "Couldn't open %s for loopback: %m", loop_name); + die(1); + } set_ppp_fd(slave_fd); @@ -2341,13 +2423,14 @@ sifnpmode(u, proto, mode) int sipxfaddr (int unit, unsigned long int network, unsigned char * node ) { - int skfd; int result = 1; + +#ifdef IPX_CHANGE + int skfd; struct sockaddr_ipx ipx_addr; struct ifreq ifr; struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr; -#ifdef IPX_CHANGE skfd = socket (AF_IPX, SOCK_DGRAM, 0); if (skfd < 0) { @@ -2403,13 +2486,14 @@ int sipxfaddr (int unit, unsigned long int network, unsigned char * node ) int cipxfaddr (int unit) { - int skfd; int result = 1; + +#ifdef IPX_CHANGE + int skfd; struct sockaddr_ipx ipx_addr; struct ifreq ifr; struct sockaddr_ipx *sipx = (struct sockaddr_ipx *) &ifr.ifr_addr; -#ifdef IPX_CHANGE skfd = socket (AF_IPX, SOCK_DGRAM, 0); if (skfd < 0) { @@ -2445,6 +2529,30 @@ int cipxfaddr (int unit) return result; } +/* + * daemon - Detach us from controlling terminal session. + */ +int +daemon(nochdir, noclose) + int nochdir, noclose; +{ + int pid; + + if ((pid = fork()) < 0) + return -1; + if (pid != 0) + exit(0); /* parent dies */ + setsid(); + if (!nochdir) + chdir("/"); + if (!noclose) { + fclose(stdin); /* don't need stdin, stdout, stderr */ + fclose(stdout); + fclose(stderr); + } + return 0; +} + /******************************************************************** * * sys_check_options - check the options that the user specified