X-Git-Url: http://git.ozlabs.org/?p=ppp.git;a=blobdiff_plain;f=pppd%2Fsys-linux.c;h=abe71ce58cec1098533a020fb9b4861e0b93fdcc;hp=29aa77fef300b9d3ef69334848723bb359825452;hb=49464ac3690f1a89de335d99b64c7e846ca6fcd1;hpb=e83a47e71a92bb5a6180e6c939bd5301c8c8412a diff --git a/pppd/sys-linux.c b/pppd/sys-linux.c index 29aa77f..abe71ce 100644 --- a/pppd/sys-linux.c +++ b/pppd/sys-linux.c @@ -165,8 +165,8 @@ extern int hungup; #endif static void set_ppp_fd (int new_fd) -{ - SYSDEBUG ((LOG_DEBUG, "setting ppp_fd to %d\n", ppp_fd)); +{ + SYSDEBUG ((LOG_DEBUG, "setting ppp_fd to %d\n", new_fd)); ppp_fd = new_fd; } @@ -659,11 +659,12 @@ static int baud_rate_of (int speed) * regardless of whether the modem option was specified. */ -void set_up_tty (int tty_fd, int local) +void set_up_tty(int tty_fd, int local) { int speed; struct termios tios; - + + setdtr(tty_fd, 1); if (tcgetattr(tty_fd, &tios) < 0) { syslog(LOG_ERR, "tcgetattr: %m(%d)", errno); @@ -740,6 +741,14 @@ void set_up_tty (int tty_fd, int local) restore_term = TRUE; } +/* + * hangup_modem - hang up the modem by clearing DTR. + */ +void hangup_modem(int ttyfd) +{ + setdtr(ttyfd, 0); +} + /******************************************************************** * * setdtr - control the DTR line on the serial port. @@ -799,14 +808,13 @@ void output (int unit, unsigned char *p, int len) if (write(ppp_fd, p, len) < 0) { if (errno == EWOULDBLOCK || errno == ENOBUFS - || errno == ENXIO || errno == EIO) + || errno == ENXIO || errno == EIO || errno == EINTR) { - syslog(LOG_WARNING, "write: warning: %m(%d)", errno); + syslog(LOG_WARNING, "write: warning: %m (%d)", errno); } else { - syslog(LOG_ERR, "write: %m(%d)", errno); - die(1); + syslog(LOG_ERR, "write: %m (%d)", errno); } } } @@ -1096,18 +1104,21 @@ get_idle_time(u, ip) */ int ccp_fatal_error (int unit) - { +{ int x = get_flags(); return x & SC_DC_FERROR; - } +} /* * path_to_route - determine the path to the proc file system data */ - +#define ROUTE_MAX_COLS 12 FILE *route_fd = (FILE *) 0; static char route_buffer [512]; +static int route_dev_col, route_dest_col, route_gw_col; +static int route_flags_col, route_mask_col; +static int route_num_cols; static char *path_to_route (void); static int open_route_table (void); @@ -1120,36 +1131,31 @@ static int read_route_table (struct rtentry *rt); */ static int path_to_procfs (void) - { +{ struct mntent *mntent; FILE *fp; - fp = fopen (MOUNTED, "r"); - if (fp != 0) - { - mntent = getmntent (fp); - while (mntent != (struct mntent *) 0) - { - if (strcmp (mntent->mnt_type, MNTTYPE_IGNORE) != 0) - { - if (strcmp (mntent->mnt_type, "proc") == 0) - { - strncpy (route_buffer, mntent->mnt_dir, - sizeof (route_buffer)-10); - route_buffer [sizeof (route_buffer)-10] = '\0'; - fclose (fp); - return 1; - } - } - mntent = getmntent (fp); - } - fclose (fp); - } + fp = fopen(MOUNTED, "r"); + if (fp == NULL) { + /* Default the mount location of /proc */ + strncpy (route_buffer, "/proc", sizeof (route_buffer)-10); + return 1; + } + + while ((mntent = getmntent(fp)) != NULL) { + if (strcmp(mntent->mnt_type, MNTTYPE_IGNORE) == 0) + continue; + if (strcmp(mntent->mnt_type, "proc") == 0) + break; + } + fclose (fp); + if (mntent == 0) + return 0; - /* Default the mount location of /proc */ - strncpy (route_buffer, "/proc", sizeof (route_buffer)-10); + strncpy(route_buffer, mntent->mnt_dir, sizeof (route_buffer)-10); + route_buffer [sizeof (route_buffer)-10] = '\0'; return 1; - } +} /******************************************************************** * @@ -1157,15 +1163,14 @@ static int path_to_procfs (void) */ static char *path_to_route (void) - { - if (! path_to_procfs()) - { +{ + if (!path_to_procfs()) { syslog (LOG_ERR, "proc file system not mounted"); return 0; - } + } strcat (route_buffer, "/net/route"); return (route_buffer); - } +} /******************************************************************** * @@ -1173,89 +1178,107 @@ static char *path_to_route (void) */ static void close_route_table (void) - { - if (route_fd != (FILE *) 0) - { +{ + if (route_fd != (FILE *) 0) { fclose (route_fd); route_fd = (FILE *) 0; - } - } + } +} /******************************************************************** * * open_route_table - open the interface to the route table */ +static char route_delims[] = " \t\n"; static int open_route_table (void) - { +{ char *path; close_route_table(); path = path_to_route(); if (path == NULL) - { return 0; - } route_fd = fopen (path, "r"); - if (route_fd == (FILE *) 0) - { - syslog (LOG_ERR, "can not open %s: %m(%d)", path, errno); + if (route_fd == NULL) { + syslog (LOG_ERR, "can't open %s: %m (%d)", path, errno); return 0; - } + } + + route_dev_col = 0; /* default to usual columns */ + route_dest_col = 1; + route_gw_col = 2; + route_flags_col = 3; + route_mask_col = 7; + route_num_cols = 8; + + /* parse header line */ + if (fgets(route_buffer, sizeof(route_buffer), route_fd) != 0) { + char *p = route_buffer, *q; + int col; + for (col = 0; col < ROUTE_MAX_COLS; ++col) { + int used = 1; + if ((q = strtok(p, route_delims)) == 0) + break; + if (strcasecmp(q, "iface") == 0) + route_dev_col = col; + else if (strcasecmp(q, "destination") == 0) + route_dest_col = col; + else if (strcasecmp(q, "gateway") == 0) + route_gw_col = col; + else if (strcasecmp(q, "flags") == 0) + route_flags_col = col; + else if (strcasecmp(q, "mask") == 0) + route_mask_col = col; + else + used = 0; + if (used && col >= route_num_cols) + route_num_cols = col + 1; + p = NULL; + } + } + return 1; - } +} /******************************************************************** * * read_route_table - read the next entry from the route table */ -static int read_route_table (struct rtentry *rt) - { - static char delims[] = " \t\n"; - char *dev_ptr, *dst_ptr, *gw_ptr, *flag_ptr; +static int read_route_table(struct rtentry *rt) +{ + char *cols[ROUTE_MAX_COLS], *p; + int col; memset (rt, '\0', sizeof (struct rtentry)); - for (;;) - { - if (fgets (route_buffer, sizeof (route_buffer), route_fd) == - (char *) 0) - { - return 0; - } + if (fgets (route_buffer, sizeof (route_buffer), route_fd) == (char *) 0) + return 0; - dev_ptr = strtok (route_buffer, delims); /* interface name */ - dst_ptr = strtok (NULL, delims); /* destination address */ - gw_ptr = strtok (NULL, delims); /* gateway */ - flag_ptr = strtok (NULL, delims); /* flags */ - - if (flag_ptr == (char *) 0) /* assume that we failed, somewhere. */ - { - return 0; - } - - /* Discard that stupid header line which should never - * have been there in the first place !! */ - if (isxdigit (*dst_ptr) && isxdigit (*gw_ptr) && isxdigit (*flag_ptr)) - { - break; - } - } + p = route_buffer; + for (col = 0; col < route_num_cols; ++col) { + cols[col] = strtok(p, route_delims); + if (cols[col] == NULL) + return 0; /* didn't get enough columns */ + } ((struct sockaddr_in *) &rt->rt_dst)->sin_addr.s_addr = - strtoul (dst_ptr, NULL, 16); + strtoul(cols[route_dest_col], NULL, 16); ((struct sockaddr_in *) &rt->rt_gateway)->sin_addr.s_addr = - strtoul (gw_ptr, NULL, 16); + strtoul(cols[route_gw_col], NULL, 16); + + ((struct sockaddr_in *) &rt->rt_genmask)->sin_addr.s_addr = + strtoul(cols[route_mask_col], NULL, 16); - rt->rt_flags = (short) strtoul (flag_ptr, NULL, 16); - rt->rt_dev = dev_ptr; + rt->rt_flags = (short) strtoul(cols[route_flags_col], NULL, 16); + rt->rt_dev = cols[route_dev_col]; return 1; - } +} /******************************************************************** * @@ -1263,31 +1286,51 @@ static int read_route_table (struct rtentry *rt) */ static int defaultroute_exists (struct rtentry *rt) - { - int result = 0; +{ + int result = 0; if (!open_route_table()) - { return 0; - } - while (read_route_table(rt) != 0) - { + while (read_route_table(rt) != 0) { if ((rt->rt_flags & RTF_UP) == 0) - { continue; - } - if (((struct sockaddr_in *) (&rt->rt_dst))->sin_addr.s_addr == 0L) - { + if (((struct sockaddr_in *) (&rt->rt_dst))->sin_addr.s_addr == 0L) { result = 1; break; - } - } + } + } close_route_table(); return result; - } +} + +/* + * have_route_to - determine if the system has any route to + * a given IP address. + */ +int have_route_to(u_int32_t addr) +{ + struct rtentry rt; + int result = 0; + + if (!open_route_table()) + return -1; /* don't know */ + + while (read_route_table(&rt)) { + if ((rt.rt_flags & RTF_UP) == 0) + continue; + if ((addr & ((struct sockaddr_in *)&rt.rt_genmask)->sin_addr.s_addr) + == ((struct sockaddr_in *)&rt.rt_genmask)->sin_addr.s_addr) { + result = 1; + break; + } + } + + close_route_table(); + return result; +} /******************************************************************** * @@ -1298,7 +1341,7 @@ int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) { struct rtentry rt; - if (defaultroute_exists(&rt)) + if (defaultroute_exists(&rt) && strcmp(rt.rt_dev, ifname) != 0) { struct in_addr old_gateway = ((struct sockaddr_in *) (&rt.rt_gateway))-> sin_addr; @@ -1307,8 +1350,7 @@ int sifdefaultroute (int unit, u_int32_t ouraddr, u_int32_t gateway) { syslog (LOG_ERR, "not replacing existing default route to %s [%s]", - rt.rt_dev, - inet_ntoa (old_gateway)); + rt.rt_dev, inet_ntoa (old_gateway)); } return 0; } @@ -1830,7 +1872,7 @@ int ppp_available(void) } /* The modification levels must be legal */ - if (driver_modification < my_modification) + if (driver_modification < 3) { if (driver_modification >= 2) { /* we can cope with 2.2.0 and above */ @@ -2615,7 +2657,7 @@ get_host_seed() * sys_check_options - check the options that the user specified */ -void +int sys_check_options(void) { #ifdef IPX_CHANGE @@ -2644,6 +2686,7 @@ sys_check_options(void) option_error("demand dialling is not supported by kernel driver version " "%d.%d.%d", driver_version, driver_modification, driver_patch); - demand = 0; + return 0; } + return 1; }