home *** CD-ROM | disk | FTP | other *** search
/ Super Net 1 / SUPERNET_1.iso / PC / OTROS / SUN / PPP / SUNOS_OL / DDP_PPP.TAR / ppp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-01-03  |  26.6 KB  |  1,269 lines

  1. /*
  2.  * ppp.c - Point-to-Point Protocol.
  3.  *
  4.  * Copyright (c) 1989 Carnegie Mellon University.
  5.  * All rights reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms are permitted
  8.  * provided that the above copyright notice and this paragraph are
  9.  * duplicated in all such forms and that any documentation,
  10.  * advertising materials, and other materials related to such
  11.  * distribution and use acknowledge that the software was developed
  12.  * by Carnegie Mellon University.  The name of the
  13.  * University may not be used to endorse or promote products derived
  14.  * from this software without specific prior written permission.
  15.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  16.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  17.  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  18.  */
  19.  
  20. /*
  21.  * TODO:
  22.  * Don't prompt for passwd on /dev/tty (go into server mode).
  23.  * Might want to choose IP addresses from config file based on user id
  24.  * if the server, or based on remote host if tip'd client.
  25.  * Way to set asyncmap.
  26.  * Wait for tty queue to empty before exiting in quit.
  27.  */
  28.  
  29. /*
  30.  * There are three scenarios:
  31.  * 1.  ppp used as daemon started from /etc/rc or perhaps /etc/ttys.
  32.  *    a.  server
  33.  *    b.  authentication necessary
  34.  *    c.  want to use constant local ip addr
  35.  *    d.  want to use constant remote ip addr, constant ip addr based on
  36.  *        authenticated user, or request ip addr
  37.  * 2.  ppp used on /dev/tty after remote login.
  38.  *    a.  server
  39.  *    b.  no authentication necessary or allowed
  40.  *    c.  want to use constant local ip addr
  41.  *    d.  want to use constant remote ip addr, constant ip addr based on
  42.  *        authenticated user, or request ip addr
  43.  * 3.  ppp used on line after tip'ing out.
  44.  *    a.  client
  45.  *    b.  remote end may request authentication
  46.  *    c.  want to use constant local ip addr or request ip addr
  47.  *    d.  want to use constant remote ip addr based on tip'd host, or
  48.  *        request remote ip addr
  49.  */
  50.  
  51. #include <stdio.h>
  52. #include <signal.h>
  53. #include <errno.h>
  54. #include <fcntl.h>
  55. #include <sgtty.h>
  56. #include <pwd.h>
  57. #include <syslog.h>
  58. #include <netdb.h>
  59. #include <utmp.h>
  60.  
  61. #include <sys/param.h>
  62. #include <sys/types.h>
  63. #include <sys/stat.h>
  64. #include <sys/socket.h>
  65. #include <sys/time.h>
  66. #include <sys/callout.h>
  67.  
  68. #include <net/if.h>
  69.  
  70. #include "magic.h"
  71. #include "ppp.h"
  72. #include "fsm.h"
  73. #include "lcp.h"
  74. #include "ipcp.h"
  75. #include "upap.h"
  76.  
  77.  
  78. #define PPPHOSTS    "/etc/hosts.ppp"
  79.  
  80. int debug = 0;            /* Debug flag */
  81. int fsm_debug = 0;        /* FSM debug flag */
  82. int lcp_debug = 0;        /* LCP debug flag */
  83. int ipcp_debug = 0;        /* IPCP debug flag */
  84. int upap_debug = 0;        /* UPAP debug flag */
  85.  
  86. char *progname;            /* Name of this program */
  87. char devname[32] = "/dev/tty";    /* Device name */
  88. char ifname[IFNAMSIZ];        /* Interface name */
  89. int ifunit;            /* Interface unit number */
  90. char inspeed = 0, outspeed = 0;    /* Input/Output speed */
  91. int fd;                /* Device file descriptor */
  92. int s;                /* Socket file descriptor */
  93. int initdisc;            /* Initial TTY discipline */
  94. struct sgttyb initsgttyb;    /* Initial TTY sgttyb */
  95. int initfdflags;        /* Initial file descriptor flags */
  96. int pid;            /* Our pid */
  97. char user[80];            /* User name */
  98.  
  99.  
  100. int hup(), intr(), term(), alrm(), io(), incdebug(), nodebug();
  101. int setdebug(), setpassive(), noopt(), novj(), noupap(), requpap();
  102. int setspeed(), noaccomp(), noasyncmap(), noipaddr(), nomagicnumber();
  103. int nomru(), nopcomp();
  104. void getuserpasswd();
  105.  
  106.  
  107. /*
  108.  * Valid arguments.
  109.  */
  110. struct cmd {
  111.     char *cmd_name;
  112.     int (*cmd_func)();
  113. } cmds[] = {
  114.     "-all", noopt,            /* Don't request/allow any options */
  115.     "-ac", noaccomp,            /* Disable Address/Control compress */
  116.     "-am", noasyncmap,            /* Disable asyncmap negotiation */
  117.     "-d", setdebug,            /* Increase debugging level */
  118.     "debug", setdebug,            /* Increase debugging level */
  119.     "-ip", noipaddr,            /* Disable IP address negotiation */
  120.     "-mn", nomagicnumber,        /* Disable magic number negotiation */
  121.     "-mru", nomru,            /* Disable mru negotiation */
  122.     "-p", setpassive,            /* Set passive mode */
  123.     "-pc", nopcomp,            /* Disable protocol field compress */
  124.     "passive", setpassive,        /* Set passive mode */
  125.     "+ua", requpap,            /* Require UPAP authentication */
  126.     "-ua", noupap,            /* Don't allow UPAP authentication */
  127.     "-vj", novj,            /* Disable VJ compression */
  128. #if 0
  129.     "local", setlocalipaddr,
  130.     "remote", setremoteipaddr,
  131.     "test", enabletestline,
  132. #endif
  133.     NULL
  134. };
  135.  
  136.  
  137. /*
  138.  * PPP Data Link Layer "protocol" table.
  139.  * One entry per supported protocol.
  140.  */
  141. struct protent {
  142.     u_short protocol;
  143.     void (*init)();
  144.     void (*input)();
  145.     void (*protrej)();
  146. } prottbl[] = {
  147.     { LCP, lcp_init, lcp_input, lcp_protrej },
  148.     { IPCP, ipcp_init, ipcp_input, ipcp_protrej },
  149.     { UPAP, upap_init, upap_input, upap_protrej },
  150. };
  151.  
  152.  
  153. char *usage = "usage: %s [-d] [-vj] [mru #]\n\
  154. \t[local ipaddr] [remote ipaddr]\n\
  155. \t[ttyname] [speed] [test]\n";
  156.  
  157.  
  158. main(argc, argv)
  159.     int argc;
  160.     char *argv[];
  161. {
  162.     int pppdisc = PPPDISC;
  163.     int mask, i;
  164.     struct sgttyb sgttyb;
  165.     struct sigvec sv;
  166.     struct cmd *cmdp;
  167.  
  168.     /*
  169.      * Initialize syslog system and magic number package.
  170.      */
  171. #if BSD >= 43
  172.     openlog("ppp", LOG_PID | LOG_ODELAY, LOG_DAEMON);
  173.     setlogmask(LOG_UPTO(LOG_WARNING));
  174. #else
  175.     openlog("ppp", LOG_PID);
  176. #define LOG_UPTO(x) (x)
  177. #define setlogmask(x) (x)
  178. #endif
  179.     magic_init();
  180.  
  181.     /*
  182.      * Initialize to the standard option set and then parse the command
  183.      * line arguments.
  184.      */
  185.     for (i = 0; i < sizeof (prottbl) / sizeof (struct protent); i++)
  186.     (*prottbl[i].init)(0);
  187.  
  188.     progname = *argv;
  189.     for (argc--, argv++; argc; ) {
  190.     /*
  191.      * First see if it's a command.
  192.      */
  193.     for (cmdp = cmds; cmdp->cmd_name; cmdp++)
  194.         if (!strcmp(*argv, cmdp->cmd_name) &&
  195.         (*cmdp->cmd_func)(&argc, &argv))
  196.         break;
  197.  
  198.     /*
  199.      * Maybe a tty name, speed or IP address?
  200.      */
  201.     if (cmdp->cmd_name == NULL &&
  202.         !setdevname(&argc, &argv) &&
  203.         !setspeed(&argc, &argv) &&
  204.         !setipaddr(&argc, &argv)) {
  205.         fprintf(stderr, usage, progname);
  206.         exit(1);
  207.     }
  208.     }
  209.  
  210.     /*
  211.      * Initialize state.
  212.      */
  213.     if ((fd = open(devname, O_RDWR /*| O_NDELAY*/)) < 0) {
  214.     perror(devname);
  215.     exit(1);
  216.     }
  217.     if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
  218.     perror("ppp: socket");
  219.     exit(1);
  220.     }
  221.  
  222.     /*
  223.      * Put the tty in raw mode and set the discipline to PPP.
  224.      */
  225.     if (ioctl(fd, TIOCGETP, &initsgttyb) < 0) {
  226.     perror("ppp: ioctl(TIOCGETP)");
  227.     exit(1);
  228.     }
  229.     sgttyb = initsgttyb;
  230.     sgttyb.sg_flags = RAW | ANYP;
  231.     if (inspeed)
  232.     sgttyb.sg_ispeed = inspeed;
  233.     if (outspeed)
  234.     sgttyb.sg_ospeed = outspeed;
  235.     if (ioctl(fd, TIOCSETP, &sgttyb) < 0) {
  236.     perror("ppp: ioctl(TIOCSETP)");
  237.     exit(1);
  238.     }
  239.  
  240.     if (ioctl(fd, TIOCGETD, &initdisc) < 0) {
  241.     perror("ppp: ioctl(TIOCGETD)");
  242.     exit(1);
  243.     }
  244.     if (ioctl(fd, TIOCSETD, &pppdisc) < 0) {
  245.     perror("ppp: ioctl(TIOCSETD)");
  246.     exit(1);
  247.     }
  248.  
  249.     /*
  250.      * Find out which interface we were given.
  251.      */
  252.     if (ioctl(fd, TIOCGETD, &ifunit) < 0) {
  253.     perror("ppp: ioctl(TIOCGETD)");
  254.     exit(1);
  255.     }
  256.     sprintf(ifname, "ppp%d", ifunit);
  257.     if (debug)
  258.     printf("Interface %s.\n", ifname);
  259.  
  260.     pid = getpid();
  261.     if (debug)
  262.     printf("Pid %d.\n", pid);
  263.     if (ioctl(fd, TIOCSPGRP, &pid) < 0) {
  264.     perror("ppp: ioctl(TIOCSPGRP)");
  265.     exit(1);
  266.     }
  267.  
  268.     /*
  269.      * Compute mask of all interesting signals and install signal handlers
  270.      * for each.  Only one signal handler may be active at a time.  Therefore,
  271.      * all other signals should be masked when any handler is executing.
  272.      */
  273.     mask = sigmask(SIGHUP) | sigmask(SIGINT) | sigmask(SIGALRM) |
  274.     sigmask(SIGIO);
  275.     sv.sv_handler = hup;        /* Hangup */
  276.     sv.sv_mask = mask;
  277.     sv.sv_flags = 0;
  278.     if (sigvec(SIGHUP, &sv, NULL)) {
  279.     perror("ppp: sigvec(SIGHUP)");
  280.     exit(1);
  281.     }
  282.     sv.sv_handler = intr;        /* Interrupt */
  283.     sv.sv_mask = mask;
  284.     sv.sv_flags = 0;
  285.     if (sigvec(SIGINT, &sv, NULL)) {
  286.     perror("ppp: sigvec(SIGINT)");
  287.     exit(1);
  288.     }
  289.     sv.sv_handler = term;        /* Terminate */
  290.     sv.sv_mask = mask;
  291.     sv.sv_flags = 0;
  292.     if (sigvec(SIGTERM, &sv, NULL)) {
  293.     perror("ppp: sigvec(SIGTERM)");
  294.     exit(1);
  295.     }
  296.     sv.sv_handler = alrm;        /* Timeout */
  297.     sv.sv_mask = mask;
  298.     sv.sv_flags = 0;
  299.     if (sigvec(SIGALRM, &sv, NULL)) {
  300.     perror("ppp: sigvec(SIGALRM)");
  301.     exit(1);
  302.     }
  303.     sv.sv_handler = io;            /* Input available */
  304.     sv.sv_mask = mask;
  305.     sv.sv_flags = 0;
  306.     if (sigvec(SIGIO, &sv, NULL)) {
  307.     perror("ppp: sigvec(SIGIO)");
  308.     exit(1);
  309.     }
  310.  
  311.     (void) signal(SIGUSR1, incdebug);    /* Increment debug flag */
  312.     (void) signal(SIGUSR2, nodebug);    /* Reset debug flag */
  313.  
  314.     /*
  315.      * Record initial device flags, then set device to cause SIGIO
  316.      * signals to be generated.
  317.      */
  318.     if ((initfdflags = fcntl(fd, F_GETFL)) == -1) {
  319.     perror("ppp: fcnt(F_GETFL)");
  320.     exit(1);
  321.     }
  322.     if (fcntl(fd, F_SETFL, FNDELAY | FASYNC) == -1) {
  323.     perror("ppp: fcnt(F_SETFL, FNDELAY | FASYNC)");
  324.     exit(1);
  325.     }
  326.  
  327.     /*
  328.      * Block all signals, start opening the connection, and  wait for
  329.      * incoming signals (reply, timeout, etc.).
  330.      */
  331.     sigblock(mask);            /* Block signals now */
  332.     lcp_lowerup(0);            /* XXX Well, sort of... */
  333.     if (lcp_wantoptions[0].passive)
  334.     lcp_passiveopen(0);        /* Start protocol in passive mode */
  335.     else
  336.     lcp_activeopen(0);        /* Start protocol in active mode */
  337.     for (;;) {
  338.     sigpause(0);            /* Wait for next signal */
  339.  
  340.     /* Need to read user/passwd? */
  341.     if (upap[0].us_flags & UPAPF_UPPENDING) {
  342.         sigsetmask(0);        /* Allow other signals to occur */
  343.         getuserpasswd();        /* Get user and passwd */
  344.         upap[0].us_flags &= ~UPAPF_UPPENDING;
  345.         upap[0].us_flags |= UPAPF_UPVALID;
  346.         sigsetmask(mask);        /* Diallow signals */
  347.         upap_authwithpeer(0);
  348.     }
  349.     }
  350. }
  351.  
  352.  
  353. /*
  354.  * quit - Clean up state and exit.
  355.  */
  356. void quit()
  357. {
  358.     if (fcntl(fd, F_SETFL, initfdflags) == -1) {
  359.     perror("ppp: fcnt(F_SETFL, fdflags)");
  360.     exit(1);
  361.     }
  362.     if (ioctl(fd, TIOCSETP, &initsgttyb) < 0) {
  363.     perror("ppp: ioctl(TIOCSETP)");
  364.     exit(1);
  365.     }
  366.     if (ioctl(fd, TIOCSETD, &initdisc) < 0) {
  367.     perror("ppp: ioctl(TIOCSETD)");
  368.     exit(1);
  369.     }
  370.     close(fd);
  371.     exit(0);
  372. }
  373.  
  374.  
  375. struct callout *callout = NULL;        /* Callout list */
  376. struct timeval schedtime;        /* Time last timeout was set */
  377.  
  378.  
  379. /*
  380.  * timeout - Schedule a timeout.
  381.  *
  382.  * Note that this timeout takes the number of seconds, NOT hz (as in
  383.  * the kernel).
  384.  */
  385. void timeout(func, arg, time)
  386.     int (*func)();
  387.     caddr_t arg;
  388.     int time;
  389. {
  390.     struct itimerval itv;
  391.     struct callout *newp, **oldpp;
  392.     
  393.     if (debug > 2)
  394.     printf("Timeout %x:%x in %d seconds.\n", (int) func, (int) arg, time);
  395.  
  396.     /*
  397.      * Allocate timeout.
  398.      */
  399.     if ((newp = (struct callout *) malloc(sizeof(struct callout))) == NULL) {
  400.     fprintf(stderr, "ppp: Out of memory!\n");
  401.     exit(1);
  402.     }
  403.     newp->c_arg = arg;
  404.     newp->c_func = func;
  405.  
  406.     /*
  407.      * Find correct place to link it in and decrement its time by the
  408.      * amount of time used by preceding timeouts.
  409.      */
  410.     for (oldpp = &callout;
  411.      *oldpp && (*oldpp)->c_time <= time;
  412.      oldpp = &(*oldpp)->c_next)
  413.     time -= (*oldpp)->c_time;
  414.     newp->c_time = time;
  415.     newp->c_next = *oldpp;
  416.     if (*oldpp)
  417.     (*oldpp)->c_time -= time;
  418.     *oldpp = newp;
  419.  
  420.     /*
  421.      * If this is now the first callout then we have to set a new
  422.      * itimer.
  423.      */
  424.     if (callout == newp) {
  425.     itv.it_interval.tv_sec = itv.it_interval.tv_usec =
  426.         itv.it_value.tv_usec = 0;
  427.     itv.it_value.tv_sec = callout->c_time;
  428.     if (debug > 2)
  429.         printf("Setting itimer for %d seconds.\n", itv.it_value.tv_sec);
  430.     if (setitimer(ITIMER_REAL, &itv, NULL)) {
  431.         perror("ppp: setitimer(ITIMER_REAL)");
  432.         exit(1);
  433.     }
  434.     if (gettimeofday(&schedtime, NULL)) {
  435.         perror("ppp: gettimeofday");
  436.         exit(1);
  437.     }
  438.     }
  439. }
  440.  
  441.  
  442. /*
  443.  * untimeout - Unschedule a timeout.
  444.  */
  445. void untimeout(func, arg)
  446.     int (*func)();
  447.     caddr_t arg;
  448. {
  449.  
  450.     struct itimerval itv;
  451.     struct callout **copp, *freep;
  452.     int reschedule = 0;
  453.  
  454.     if (debug > 2)
  455.     printf("Untimeout %x:%x.\n", (int) func, (int) arg);
  456.  
  457.     /*
  458.      * If the first callout is unscheduled then we have to set a new
  459.      * itimer.
  460.      */
  461.     if (callout &&
  462.     callout->c_func == func &&
  463.     callout->c_arg == arg)
  464.     reschedule = 1;
  465.  
  466.     /*
  467.      * Find first matching timeout.  Add its time to the next timeouts
  468.      * time.
  469.      */
  470.     for (copp = &callout; *copp; copp = &(*copp)->c_next)
  471.     if ((*copp)->c_func == func &&
  472.         (*copp)->c_arg == arg) {
  473.         freep = *copp;
  474.         *copp = freep->c_next;
  475.         if (*copp)
  476.         (*copp)->c_time += freep->c_time;
  477.         free(freep);
  478.         break;
  479.     }
  480.  
  481.     if (reschedule) {
  482.     itv.it_interval.tv_sec = itv.it_interval.tv_usec =
  483.         itv.it_value.tv_usec = 0;
  484.     itv.it_value.tv_sec = callout ? callout->c_time : 0;
  485.     if (debug > 2)
  486.         printf("Setting itimer for %d seconds.\n", itv.it_value.tv_sec);
  487.     if (setitimer(ITIMER_REAL, &itv, NULL)) {
  488.         perror("ppp: setitimer(ITIMER_REAL)");
  489.         exit(1);
  490.     }
  491.     if (gettimeofday(&schedtime, NULL)) {
  492.         perror("ppp: gettimeofday");
  493.         exit(1);
  494.     }
  495.     }
  496. }
  497.  
  498.  
  499. /*
  500.  * adjtimeout - Decrement the first timeout by the amount of time since
  501.  * it was scheduled.
  502.  */
  503. void adjtimeout()
  504. {
  505.     struct timeval tv;
  506.     int timediff;
  507.  
  508.     if (callout == NULL)
  509.     return;
  510.     /*
  511.      * Make sure that the clock hasn't been warped dramatically.
  512.      * Account for recently expired, but blocked timer by adding
  513.      * small fudge factor.
  514.      */
  515.     if (gettimeofday(&tv, NULL)) {
  516.     perror("ppp: gettimeofday");
  517.     exit(1);
  518.     }
  519.     timediff = tv.tv_sec - schedtime.tv_sec;
  520.     if (timediff < 0 ||
  521.     timediff > callout->c_time + 1)
  522.     return;
  523.  
  524.     callout->c_time -= timediff;    /* OK, Adjust time */
  525. }
  526.  
  527.  
  528. /*
  529.  * output - Output PPP packet.
  530.  */
  531. void output(unit, p, len)
  532.     int unit;
  533.     u_char *p;
  534.     int len;
  535. {
  536.     if (unit != 0) {
  537.     fprintf(stderr, "ppp: output: unit != 0!\n");
  538.     abort();
  539.     }
  540.     if (write(fd, p, len) < 0) {
  541.     perror("ppp: write");
  542.     exit(1);
  543.     }
  544.     free(p);
  545. }
  546.  
  547.  
  548. /*
  549.  * hup - Catch SIGHUP signal.
  550.  *
  551.  * Indicates that the physical layer has been disconnected.
  552.  */
  553. hup()
  554. {
  555.     if (debug > 1)
  556.     printf("Hangup\n");
  557.     adjtimeout();        /* Adjust timeouts */
  558.     lcp_lowerdown(0);        /* Reset connection */
  559. }
  560.  
  561.  
  562. /*
  563.  * term - Catch SIGTERM signal.
  564.  *
  565.  * Indicates that we should initiate a graceful disconnect and exit.
  566.  */
  567. term()
  568. {
  569.     if (debug > 1)
  570.     printf("Terminate\n");
  571.     adjtimeout();        /* Adjust timeouts */
  572.     lcp_close(0);        /* Close connection */
  573. }
  574.  
  575.  
  576. /*
  577.  * intr - Catch SIGINT signal (DEL/^C).
  578.  *
  579.  * Indicates that we should initiate a graceful disconnect and exit.
  580.  */
  581. intr()
  582. {
  583.     if (debug > 1)
  584.     printf("Interrupt\n");
  585.     adjtimeout();        /* Adjust timeouts */
  586.     lcp_close(0);        /* Close connection */
  587. }
  588.  
  589.  
  590. /*
  591.  * alrm - Catch SIGALRM signal.
  592.  *
  593.  * Indicates a timeout.
  594.  */
  595. alrm()
  596. {
  597.     struct itimerval itv;
  598.     struct callout *freep;
  599.  
  600.     if (debug > 1)
  601.     printf("Alarm\n");
  602.  
  603.     /*
  604.      * Call and free first scheduled timeout and any that were scheduled
  605.      * for the same time.
  606.      */
  607.     while (callout) {
  608.     freep = callout;    /* Remove entry before calling */
  609.     callout = freep->c_next;
  610.     (*freep->c_func)(freep->c_arg);
  611.     free(freep);
  612.     if (callout->c_time)
  613.         break;
  614.     }
  615.  
  616.     /*
  617.      * Set a new itimer if there are more timeouts scheduled.
  618.      */
  619.     if (callout) {
  620.     itv.it_interval.tv_sec = itv.it_interval.tv_usec =
  621.         itv.it_value.tv_usec = 0;
  622.     itv.it_value.tv_sec = callout->c_time;
  623.     if (debug > 2)
  624.         printf("Setting itimer for %d seconds.\n", itv.it_value.tv_sec);
  625.     if (setitimer(ITIMER_REAL, &itv, NULL)) {
  626.         perror("ppp: setitimer(ITIMER_REAL)");
  627.         exit(1);
  628.     }
  629.     if (gettimeofday(&schedtime, NULL)) {
  630.         perror("ppp: gettimeofday");
  631.         exit(1);
  632.     }
  633.     }
  634. }
  635.  
  636.  
  637. /*
  638.  * io - Catch SIGIO signal.
  639.  *
  640.  * Indicates that incoming data is available.
  641.  */
  642. io()
  643. {
  644.     int len, i;
  645.     u_char *p;
  646.     u_short protocol;
  647.  
  648.     if (debug > 1)
  649.     printf("IO\n");
  650.     adjtimeout();        /* Adjust timeouts */
  651.  
  652.     for (;;) {            /* Read all available packets */
  653.     p = (u_char *) malloc(MTU + DLLHEADERLEN);
  654.     if ((len = read(fd, p, MTU + DLLHEADERLEN)) < 0) {
  655.         if (errno == EWOULDBLOCK) {
  656.         if (debug > 2)
  657.             perror("ppp: read(fd)");
  658.         return;
  659.         }
  660.         else {
  661.         perror("ppp: read(fd)");
  662.         exit(1);
  663.         }
  664.     }
  665.     else if (len == 0) {
  666.         fprintf(stderr, "ppp: End of file on fd!\n");
  667.         exit(1);
  668.     }
  669.     
  670.     if (len < DLLHEADERLEN) {
  671.         if (debug)
  672.         fprintf(stderr, "ppp: input: Received short packet.\n");
  673.         return;
  674.     }
  675.  
  676.     p += 2;                /* Skip address and control */
  677.     GETSHORT(protocol, p);
  678.     len -= DLLHEADERLEN;
  679.  
  680.     /*
  681.      * Toss all non-LCP packets unless LCP is OPEN.
  682.      */
  683.     if (protocol != LCP &&
  684.         lcp_fsm[0].state != OPEN) {
  685.         free(p);
  686.         return;
  687.     }
  688.  
  689.     /*
  690.      * Upcall the proper protocol input routine.
  691.      */
  692.     for (i = 0; i < sizeof (prottbl) / sizeof (struct protent); i++)
  693.         if (prottbl[i].protocol == protocol) {
  694.         (*prottbl[i].input)(0, p, len);
  695.         break;
  696.         }
  697.  
  698.     if (i == sizeof (prottbl) / sizeof (struct protent)) {
  699.         if (debug)
  700.         fprintf(stderr,
  701.             "ppp: input: Unknown protocol (%x) received!\n",
  702.             protocol);
  703.         p -= DLLHEADERLEN;
  704.         len += DLLHEADERLEN;
  705.         lcp_sprotrej(0, p, len);
  706.     }
  707.     }
  708. }
  709.  
  710.  
  711. /*
  712.  * demuxprotrej - Demultiplex a Protocol-Reject.
  713.  */
  714. void demuxprotrej(unit, protocol)
  715.     int unit;
  716.     u_short protocol;
  717. {
  718.     int i;
  719.  
  720.     /*
  721.      * Upcall the proper Protocol-Reject routine.
  722.      */
  723.     for (i = 0; i < sizeof (prottbl) / sizeof (struct protent); i++)
  724.     if (prottbl[i].protocol == protocol) {
  725.         (*prottbl[i].protrej)(unit);
  726.         return;
  727.     }
  728.     if (debug)
  729.     fprintf(stderr,
  730.         "ppp: demuxprotrej: Unrecognized Protocol-Reject!\n");
  731. }
  732.  
  733.  
  734. /*
  735.  * incdebug - Catch SIGUSR1 signal.
  736.  *
  737.  * Increment debug flag.
  738.  */
  739. incdebug()
  740. {
  741.     debug++;
  742. }
  743.  
  744.  
  745. /*
  746.  * nodebug - Catch SIGUSR2 signal.
  747.  *
  748.  * Turn off debugging.
  749.  */
  750. nodebug()
  751. {
  752.     debug = 0;
  753. }
  754.  
  755.  
  756. /*
  757.  * setdebug - Set debug (command line argument).
  758.  */
  759. int setdebug(argcp, argvp)
  760.     int *argcp;
  761.     char ***argvp;
  762. {
  763.     debug++;
  764.     fsm_debug++;
  765.     lcp_debug++;
  766.     ipcp_debug++;
  767.     upap_debug++;
  768.     --*argcp, ++*argvp;
  769.     return (1);
  770. }
  771.  
  772.  
  773. /*
  774.  * noopt - Disable all options.
  775.  */
  776. int noopt(argcp, argvp)
  777.     int *argcp;
  778.     char ***argvp;
  779. {
  780.     bzero(&lcp_wantoptions[0], sizeof (struct lcp_options));
  781.     bzero(&lcp_allowoptions[0], sizeof (struct lcp_options));
  782.     bzero(&ipcp_wantoptions[0], sizeof (struct ipcp_options));
  783.     bzero(&ipcp_allowoptions[0], sizeof (struct ipcp_options));
  784.     --*argcp, ++*argvp;
  785.     return (1);
  786. }
  787.  
  788.  
  789. /*
  790.  * noaccomp - Disable Address/Control field compression negotiation.
  791.  */
  792. int noaccomp(argcp, argvp)
  793.     int *argcp;
  794.     char ***argvp;
  795. {
  796.     lcp_wantoptions[0].neg_accompression = 0;
  797.     lcp_allowoptions[0].neg_accompression = 0;
  798.     --*argcp, ++*argvp;
  799.     return (1);
  800. }
  801.  
  802.  
  803. /*
  804.  * noasyncmap - Disable async map negotiation.
  805.  */
  806. int noasyncmap(argcp, argvp)
  807.     int *argcp;
  808.     char ***argvp;
  809. {
  810.     lcp_wantoptions[0].neg_asyncmap = 0;
  811.     lcp_allowoptions[0].neg_asyncmap = 0;
  812.     --*argcp, ++*argvp;
  813.     return (1);
  814. }
  815.  
  816.  
  817. /*
  818.  * noipaddr - Disable IP address negotiation.
  819.  */
  820. int noipaddr(argcp, argvp)
  821.     int *argcp;
  822.     char ***argvp;
  823. {
  824.     ipcp_wantoptions[0].neg_addrs = 0;
  825.     ipcp_allowoptions[0].neg_addrs = 0;
  826.     --*argcp, ++*argvp;
  827.     return (1);
  828. }
  829.  
  830.  
  831. /*
  832.  * nomagicnumber - Disable magic number negotiation.
  833.  */
  834. int nomagicnumber(argcp, argvp)
  835.     int *argcp;
  836.     char ***argvp;
  837. {
  838.     lcp_wantoptions[0].neg_magicnumber = 0;
  839.     lcp_allowoptions[0].neg_magicnumber = 0;
  840.     --*argcp, ++*argvp;
  841.     return (1);
  842. }
  843.  
  844.  
  845. /*
  846.  * nomru - Disable mru negotiation.
  847.  */
  848. int nomru(argcp, argvp)
  849.     int *argcp;
  850.     char ***argvp;
  851. {
  852.     lcp_wantoptions[0].neg_mru = 0;
  853.     lcp_allowoptions[0].neg_mru = 0;
  854.     --*argcp, ++*argvp;
  855.     return (1);
  856. }
  857.  
  858.  
  859. /*
  860.  * nopcomp - Disable Protocol field compression negotiation.
  861.  */
  862. int nopcomp(argcp, argvp)
  863.     int *argcp;
  864.     char ***argvp;
  865. {
  866.     lcp_wantoptions[0].neg_pcompression = 0;
  867.     lcp_allowoptions[0].neg_pcompression = 0;
  868.     --*argcp, ++*argvp;
  869.     return (1);
  870. }
  871.  
  872.  
  873. /*
  874.  * setpassive - Set passive mode.
  875.  */
  876. int setpassive(argcp, argvp)
  877.     int *argcp;
  878.     char ***argvp;
  879. {
  880.     lcp_wantoptions[0].passive = 1;
  881.     --*argcp, ++*argvp;
  882.     return (1);
  883. }
  884.  
  885.  
  886. /*
  887.  * noupap - Disable UPAP authentication.
  888.  */
  889. int noupap(argcp, argvp)
  890.     int *argcp;
  891.     char ***argvp;
  892. {
  893.     lcp_allowoptions[0].neg_upap = 0;
  894.     --*argcp, ++*argvp;
  895.     return (1);
  896. }
  897.  
  898.  
  899. /*
  900.  * requpap - Require UPAP authentication.
  901.  */
  902. int requpap(argcp, argvp)
  903.     int *argcp;
  904.     char ***argvp;
  905. {
  906.     lcp_wantoptions[0].neg_upap = 1;
  907.     lcp_allowoptions[0].neg_upap = 0;
  908.     --*argcp, ++*argvp;
  909.     return (1);
  910. }
  911.  
  912.  
  913. /*
  914.  * novj - Disable Van Jacobson style IP header compression.
  915.  */
  916. int novj(argcp, argvp)
  917.     int *argcp;
  918.     char ***argvp;
  919. {
  920.     ipcp_wantoptions[0].neg_vj = 0;
  921.     ipcp_allowoptions[0].neg_vj = 0;
  922.     --*argcp, ++*argvp;
  923.     return (1);
  924. }
  925.  
  926.  
  927. /*
  928.  * Valid speeds.
  929.  */
  930. struct speed {
  931.     int speed_int, speed_val;
  932. } speeds[] = {
  933. #ifdef B50
  934.     { 50, B50 },
  935. #endif
  936. #ifdef B75
  937.     { 75, B75 },
  938. #endif
  939. #ifdef B110
  940.     { 110, B110 },
  941. #endif
  942. #ifdef B150
  943.     { 150, B150 },
  944. #endif
  945. #ifdef B200
  946.     { 200, B200 },
  947. #endif
  948. #ifdef B300
  949.     { 300, B300 },
  950. #endif
  951. #ifdef B600
  952.     { 600, B600 },
  953. #endif
  954. #ifdef B1200
  955.     { 1200, B1200 },
  956. #endif
  957. #ifdef B1800
  958.     { 1800, B1800 },
  959. #endif
  960. #ifdef B2000
  961.     { 2000, B2000 },
  962. #endif
  963. #ifdef B2400
  964.     { 2400, B2400 },
  965. #endif
  966. #ifdef B3600
  967.     { 3600, B3600 },
  968. #endif
  969. #ifdef B4800
  970.     { 4800, B4800 },
  971. #endif
  972. #ifdef B7200
  973.     { 7200, B7200 },
  974. #endif
  975. #ifdef B9600
  976.     { 9600, B9600 },
  977. #endif
  978. #ifdef EXTA
  979.     { 19200, EXTA },
  980. #endif
  981. #ifdef EXTB
  982.     { 38400, EXTB },
  983. #endif
  984.     { 0, 0 }
  985. };
  986.  
  987. /*
  988.  * setspeed - Set the speed.
  989.  */
  990. int setspeed(argcp, argvp)
  991.     int *argcp;
  992.     char ***argvp;
  993. {
  994.     int speed;
  995.     struct speed *speedp;
  996.  
  997.     speed = atoi(**argvp);
  998.     for (speedp = speeds; speedp->speed_int; speedp++)
  999.     if (speed == speedp->speed_int) {
  1000.         inspeed = speedp->speed_val;
  1001.         --*argcp, ++*argvp;
  1002.         return (1);
  1003.     }
  1004.     return (0);
  1005. }
  1006.  
  1007.  
  1008. /*
  1009.  * setdevname - Set the device name.
  1010.  */
  1011. int setdevname(argcp, argvp)
  1012.     int *argcp;
  1013.     char ***argvp;
  1014. {
  1015.     char dev[32];
  1016.     char *cp = **argvp;
  1017.     struct stat statbuf;
  1018.     char *tty, *ttyname();
  1019.  
  1020.     if (strncmp("/dev/", cp, sizeof ("/dev/") - 1)) {
  1021.     (void) sprintf(dev, "/dev/%s", cp);
  1022.     cp = dev;
  1023.     }
  1024.  
  1025.     /*
  1026.      * Check if there is a device by this name.
  1027.      */
  1028.     if (stat(cp, &statbuf) < 0) {
  1029.     if (errno == ENOENT)
  1030.         return (0);
  1031.     perror(cp);
  1032.     exit(1);
  1033.     }
  1034.  
  1035.     strcpy(devname, cp);
  1036.     --*argcp, ++*argvp;
  1037.  
  1038.     /*
  1039.      * If we haven't already decided to require authentication,
  1040.      * or we are running ppp on the control terminal, then we can
  1041.      * allow authentication to be requested.
  1042.      */
  1043.     tty = ttyname(fileno(stdin));
  1044.     if (lcp_wantoptions[0].neg_upap == 0 &&
  1045.     strcmp(devname, "/dev/tty") &&
  1046.     strcmp(devname, tty)) {
  1047.     lcp_wantoptions[0].neg_upap = 0;
  1048.     lcp_allowoptions[0].neg_upap = 1;
  1049.     }
  1050.     return (1);
  1051. }
  1052.  
  1053.  
  1054. /*
  1055.  * setipaddr - Set the speed.
  1056.  */
  1057. int setipaddr(argcp, argvp)
  1058.     int *argcp;
  1059.     char ***argvp;
  1060. {
  1061.     u_long local, remote;
  1062.     struct hostent *hp;
  1063.     char *colon, *index();
  1064.  
  1065.     /*
  1066.      * IP address pair separated by ":".
  1067.      */
  1068.     if ((colon = index(**argvp, ':')) == NULL)
  1069.     return (0);
  1070.     
  1071.     /*
  1072.      * If colon first character, then no local addr.
  1073.      */
  1074.     if (colon == **argvp) {
  1075.     local = 0l;
  1076.     ++colon;
  1077.     }
  1078.     else {
  1079.     *colon++ = '\0';
  1080.     if ((local = inet_addr(**argvp)) == -1) {
  1081.         if ((hp = gethostbyname(**argvp)) == NULL) {
  1082.         fprintf(stderr, "unknown host: %s\n", **argvp);
  1083.         goto ret;
  1084.         }
  1085.         bcopy(hp->h_addr, (char *) &local, hp->h_length);
  1086.     }
  1087.     }
  1088.  
  1089.     /*
  1090.      * If colon last character, then no remote addr.
  1091.      */
  1092.     if (*colon == '\0')
  1093.     remote = 0l;
  1094.     else {
  1095.     if ((remote = inet_addr(colon)) == -1) {
  1096.         if ((hp = gethostbyname(colon)) == NULL) {
  1097.         fprintf(stderr, "unknown host: %s\n", colon);
  1098.         goto ret;
  1099.         }
  1100.         bcopy(hp->h_addr, (char *) &remote, hp->h_length);
  1101.     }
  1102.     }
  1103.  
  1104.     ipcp_wantoptions[0].neg_addrs = 1;
  1105.     ipcp_wantoptions[0].ouraddr = local;
  1106.     ipcp_wantoptions[0].hisaddr = remote;
  1107.  
  1108. ret:
  1109.     --*argcp, ++*argvp;
  1110.     return (1);
  1111. }
  1112.  
  1113.  
  1114. /*
  1115.  * getuserpasswd - Get the user name and passwd.
  1116.  */
  1117. void getuserpasswd()
  1118. {
  1119.     struct passwd *pw, *getpwuid();
  1120.     char *getlogin(), *getpass();
  1121.  
  1122.     /*
  1123.      * Prompt for user name with a default value.  Default is
  1124.      * the last value if any, or the login name or the user name.
  1125.      */
  1126.     if (upap[0].us_user == NULL &&
  1127.     (upap[0].us_user = getlogin()) == NULL &&
  1128.     (pw = getpwuid(getuid())) != NULL)
  1129.     upap[0].us_user = pw->pw_name;
  1130.  
  1131.     printf("Login (%s): ", upap[0].us_user);
  1132.     fgets(user, sizeof (user) - 1, stdin);
  1133.     user[strlen(user) - 1] = '\0';
  1134.     if (user[0] != '\0')        /* Choosing the default? */
  1135.     upap[0].us_user = user;
  1136.     upap[0].us_userlen = strlen(upap[0].us_user);
  1137.  
  1138.     upap[0].us_passwd = getpass("Password: ");
  1139.     upap[0].us_passwdlen = strlen(upap[0].us_passwd);
  1140. }
  1141.  
  1142.  
  1143. /*
  1144.  * login - Check the user name and passwd and login the user.
  1145.  *
  1146.  * returns:
  1147.  *    UPAP_AUTHNAK: Login failed.
  1148.  *    UPAP_AUTHACK: Login succeeded.
  1149.  * In either case, msg points to an appropriate message.
  1150.  */
  1151. u_char login(user, userlen, passwd, passwdlen, msg, msglen)
  1152.     char *user;
  1153.     int userlen;
  1154.     char *passwd;
  1155.     int passwdlen;
  1156.     char **msg;
  1157.     int *msglen;
  1158. {
  1159.     struct passwd *pw;
  1160.     char *epasswd, *crypt();
  1161.     static int attempts = 0;
  1162.     char *tty, *rindex();
  1163.  
  1164.     *(user + userlen) = '\0';
  1165.     *(passwd + passwdlen) = '\0';
  1166.  
  1167.     if ((pw = getpwnam(user)) == NULL) {
  1168.     *msg = "Login incorrect";
  1169.     *msglen = strlen(*msg);
  1170.     return (UPAP_AUTHNAK);
  1171.     }
  1172.  
  1173.     /*
  1174.      * XXX If no passwd, let them login without one.
  1175.      */
  1176.     if (pw->pw_passwd == '\0') {
  1177.     *msg = "Login ok";
  1178.     *msglen = strlen(*msg);
  1179.     return (UPAP_AUTHACK);
  1180.     }
  1181.  
  1182.     epasswd = crypt(passwd, pw->pw_passwd);
  1183.     if (strcmp(epasswd, pw->pw_passwd)) {
  1184.     *msg = "Login incorrect";
  1185.     *msglen = strlen(*msg);
  1186.  
  1187.     /*
  1188.      * Frustrate passwd stealer programs.
  1189.      * Allow 10 tries, but start backing off after 3 (stolen from login).
  1190.      * On 10'th, drop the connection.
  1191.      */
  1192.     if (attempts++ >= 10) {
  1193.         syslog(LOG_NOTICE, "%d LOGIN FAILURES ON %s, %s",
  1194.            attempts, devname, user);
  1195.         lcp_close(0);        /* Drop DTR? */
  1196.     }
  1197.     if (attempts > 3)
  1198.         sleep((u_int) (attempts - 3) * 5);
  1199.     return (UPAP_AUTHNAK);
  1200.     }
  1201.  
  1202.     attempts = 0;            /* Reset count */
  1203.     *msg = "Login ok";
  1204.     *msglen = strlen(*msg);
  1205.  
  1206.     tty = rindex(devname, '/');
  1207.     if (tty == NULL)
  1208.     tty = devname;
  1209.     else
  1210.     tty++;
  1211.     logwtmp(tty, user, "");        /* Add wtmp login entry */
  1212.  
  1213.     return (UPAP_AUTHACK);
  1214. }
  1215.  
  1216.  
  1217. /*
  1218.  * logout - Logout the user.
  1219.  */
  1220. void logout()
  1221. {
  1222.     char *tty;
  1223.  
  1224.     tty = rindex(devname, '/');
  1225.     if (tty == NULL)
  1226.     tty = devname;
  1227.     else
  1228.     tty++;
  1229.     logwtmp(tty, "", "");        /* Add wtmp logout entry */
  1230. }
  1231.  
  1232.  
  1233. /*
  1234.  * getuseropt - Get the options from /etc/hosts.ppp for this user.
  1235.  */
  1236. int getuseropt(user)
  1237.     char *user;
  1238. {
  1239.     char buf[1024], *s;
  1240.     FILE *fp;
  1241.     int rc = 0;
  1242.  
  1243.     if ((fp = fopen(PPPHOSTS, "r")) == NULL)
  1244.     return (0);;
  1245.  
  1246.     /*
  1247.      * Loop till we find an entry for this user.
  1248.      */
  1249.     for (;;) {
  1250.     if (fgets(buf, sizeof (buf), fp)) {
  1251.         if (feof(fp))
  1252.         break;
  1253.         else {
  1254.         perror("fgets");
  1255.         exit(1);
  1256.         }
  1257.     }
  1258.     if ((s = index(buf, ' ')) == NULL)
  1259.         continue;
  1260.     *s++ = '\0';
  1261.     if (!strcmp(user, buf)) {
  1262.         rc = 1;
  1263.         break;
  1264.     }
  1265.     }
  1266.     fclose(fp);
  1267.     return (rc);
  1268. }
  1269.