]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/lcp.c
make establish/disestablish_ppp members of the channel struct,
[ppp.git] / pppd / lcp.c
index 1241bfbe6a3b787ecd93382390b193a950a007c5..d708c2709eacab958780c41e703942ed73957261 100644 (file)
@@ -17,7 +17,7 @@
  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  */
 
-#define RCSID  "$Id: lcp.c,v 1.50 2000/04/05 00:58:28 paulus Exp $";
+#define RCSID  "$Id: lcp.c,v 1.57 2001/03/08 05:11:14 paulus Exp $"
 
 /*
  * TODO:
 
 static const char rcsid[] = RCSID;
 
+/*
+ * When the link comes up we want to be able to wait for a short while,
+ * or until seeing some input from the peer, before starting to send
+ * configure-requests.  We do this by delaying the fsm_lowerup call.
+ */
+/* steal a bit in fsm flags word */
+#define DELAYED_UP     0x100
+
+static void lcp_delayed_up __P((void *));
+
 /*
  * LCP-related command-line options.
  */
 int    lcp_echo_interval = 0;  /* Interval between LCP echo-requests */
 int    lcp_echo_fails = 0;     /* Tolerance to unanswered echo-requests */
 bool   lax_recv = 0;           /* accept control chars in asyncmap */
+bool   noendpoint = 0;         /* don't send/accept endpoint discriminator */
 
-static int setescape __P((char **));
+static int noopt __P((char **));
 
 #ifdef HAVE_MULTILINK
-bool   noendpoint = 0;         /* don't send/accept endpoint discriminator */
 static int setendpoint __P((char **));
+static void printendpoint __P((option_t *, void (*)(void *, char *, ...),
+                              void *));
 #endif /* HAVE_MULTILINK */
 
 static option_t lcp_option_list[] = {
     /* LCP options */
+    { "-all", o_special_noarg, (void *)noopt,
+      "Don't request/allow any LCP options" },
+
     { "noaccomp", o_bool, &lcp_wantoptions[0].neg_accompression,
       "Disable address/control compression",
-      OPT_A2COPY, &lcp_allowoptions[0].neg_accompression },
+      OPT_A2CLR, &lcp_allowoptions[0].neg_accompression },
     { "-ac", o_bool, &lcp_wantoptions[0].neg_accompression,
       "Disable address/control compression",
-      OPT_A2COPY, &lcp_allowoptions[0].neg_accompression },
-    { "default-asyncmap", o_bool, &lcp_wantoptions[0].neg_asyncmap,
-      "Disable asyncmap negotiation",
-      OPT_A2COPY, &lcp_allowoptions[0].neg_asyncmap },
-    { "-am", o_bool, &lcp_wantoptions[0].neg_asyncmap,
-      "Disable asyncmap negotiation",
-      OPT_A2COPY, &lcp_allowoptions[0].neg_asyncmap },
+      OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_accompression },
+
     { "asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap,
       "Set asyncmap (for received packets)",
       OPT_OR, &lcp_wantoptions[0].neg_asyncmap },
     { "-as", o_uint32, &lcp_wantoptions[0].asyncmap,
       "Set asyncmap (for received packets)",
-      OPT_OR, &lcp_wantoptions[0].neg_asyncmap },
+      OPT_ALIAS | OPT_OR, &lcp_wantoptions[0].neg_asyncmap },
+    { "default-asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap,
+      "Disable asyncmap negotiation",
+      OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR,
+      &lcp_allowoptions[0].neg_asyncmap },
+    { "-am", o_uint32, &lcp_wantoptions[0].asyncmap,
+      "Disable asyncmap negotiation",
+      OPT_ALIAS | OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR,
+      &lcp_allowoptions[0].neg_asyncmap },
+
     { "nomagic", o_bool, &lcp_wantoptions[0].neg_magicnumber,
       "Disable magic number negotiation (looped-back line detection)",
-      OPT_A2COPY, &lcp_allowoptions[0].neg_magicnumber },
+      OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber },
     { "-mn", o_bool, &lcp_wantoptions[0].neg_magicnumber,
       "Disable magic number negotiation (looped-back line detection)",
-      OPT_A2COPY, &lcp_allowoptions[0].neg_magicnumber },
+      OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber },
+
+    { "mru", o_int, &lcp_wantoptions[0].mru,
+      "Set MRU (maximum received packet size) for negotiation",
+      OPT_PRIO, &lcp_wantoptions[0].neg_mru },
     { "default-mru", o_bool, &lcp_wantoptions[0].neg_mru,
       "Disable MRU negotiation (use default 1500)",
-      OPT_A2COPY, &lcp_allowoptions[0].neg_mru },
+      OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru },
     { "-mru", o_bool, &lcp_wantoptions[0].neg_mru,
       "Disable MRU negotiation (use default 1500)",
-      OPT_A2COPY, &lcp_allowoptions[0].neg_mru },
-    { "mru", o_int, &lcp_wantoptions[0].mru,
-      "Set MRU (maximum received packet size) for negotiation",
-      0, &lcp_wantoptions[0].neg_mru },
+      OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru },
+
+    { "mtu", o_int, &lcp_allowoptions[0].mru,
+      "Set our MTU", OPT_LIMITS, NULL, MAXMRU, MINMRU },
+
     { "nopcomp", o_bool, &lcp_wantoptions[0].neg_pcompression,
       "Disable protocol field compression",
-      OPT_A2COPY, &lcp_allowoptions[0].neg_pcompression },
+      OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression },
     { "-pc", o_bool, &lcp_wantoptions[0].neg_pcompression,
       "Disable protocol field compression",
-      OPT_A2COPY, &lcp_allowoptions[0].neg_pcompression },
-    { "-p", o_bool, &lcp_wantoptions[0].passive,
-      "Set passive mode", 1 },
+      OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression },
+
     { "passive", o_bool, &lcp_wantoptions[0].passive,
       "Set passive mode", 1 },
+    { "-p", o_bool, &lcp_wantoptions[0].passive,
+      "Set passive mode", OPT_ALIAS | 1 },
+
     { "silent", o_bool, &lcp_wantoptions[0].silent,
       "Set silent mode", 1 },
-    { "escape", o_special, setescape,
-      "List of character codes to escape on transmission" },
+
     { "lcp-echo-failure", o_int, &lcp_echo_fails,
-      "Set number of consecutive echo failures to indicate link failure" },
+      "Set number of consecutive echo failures to indicate link failure",
+      OPT_PRIO },
     { "lcp-echo-interval", o_int, &lcp_echo_interval,
-      "Set time in seconds between LCP echo requests" },
+      "Set time in seconds between LCP echo requests", OPT_PRIO },
     { "lcp-restart", o_int, &lcp_fsm[0].timeouttime,
-      "Set time in seconds between LCP retransmissions" },
+      "Set time in seconds between LCP retransmissions", OPT_PRIO },
     { "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits,
-      "Set maximum number of LCP terminate-request transmissions" },
+      "Set maximum number of LCP terminate-request transmissions", OPT_PRIO },
     { "lcp-max-configure", o_int, &lcp_fsm[0].maxconfreqtransmits,
-      "Set maximum number of LCP configure-request transmissions" },
+      "Set maximum number of LCP configure-request transmissions", OPT_PRIO },
     { "lcp-max-failure", o_int, &lcp_fsm[0].maxnakloops,
-      "Set limit on number of LCP configure-naks" },
+      "Set limit on number of LCP configure-naks", OPT_PRIO },
+
     { "receive-all", o_bool, &lax_recv,
       "Accept all received control characters", 1 },
+
 #ifdef HAVE_MULTILINK
     { "mrru", o_int, &lcp_wantoptions[0].mrru,
       "Maximum received packet size for multilink bundle",
-      0, &lcp_wantoptions[0].neg_mrru },
+      OPT_PRIO, &lcp_wantoptions[0].neg_mrru },
+
     { "mpshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf,
       "Use short sequence numbers in multilink headers",
-      OPT_A2COPY | 1, &lcp_allowoptions[0].neg_ssnhf },
+      OPT_PRIO | 1, &lcp_allowoptions[0].neg_ssnhf },
     { "nompshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf,
       "Don't use short sequence numbers in multilink headers",
-      OPT_A2COPY, &lcp_allowoptions[0].neg_ssnhf },
-    { "endpoint", o_special, setendpoint,
-      "Endpoint discriminator for multilink" },
+      OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_ssnhf },
+
+    { "endpoint", o_special, (void *) setendpoint,
+      "Endpoint discriminator for multilink",
+      OPT_PRIO | OPT_A2PRINTER, (void *) printendpoint },
+#endif /* HAVE_MULTILINK */
+
     { "noendpoint", o_bool, &noendpoint,
       "Don't send or accept multilink endpoint discriminator", 1 },
-#endif /* HAVE_MULTILINK */
+
     {NULL}
 };
 
@@ -136,7 +169,6 @@ lcp_options lcp_wantoptions[NUM_PPP];       /* Options that we want to request */
 lcp_options lcp_gotoptions[NUM_PPP];   /* Options that peer ack'd */
 lcp_options lcp_allowoptions[NUM_PPP]; /* Options we allow peer to request */
 lcp_options lcp_hisoptions[NUM_PPP];   /* Options that we ack'd */
-u_int32_t xmit_accm[NUM_PPP][8];       /* extended transmit ACCM */
 
 static int lcp_echos_pending = 0;      /* Number of outstanding echo msgs */
 static int lcp_echo_number   = 0;      /* ID number of next echo frame */
@@ -238,36 +270,17 @@ int lcp_loopbackfail = DEFLOOPBACKFAIL;
 #define CODENAME(x)    ((x) == CONFACK ? "ACK" : \
                         (x) == CONFNAK ? "NAK" : "REJ")
 
-
 /*
- * setescape - add chars to the set we escape on transmission.
+ * noopt - Disable all options (why?).
  */
 static int
-setescape(argv)
+noopt(argv)
     char **argv;
 {
-    int n, ret;
-    char *p, *endp;
-
-    p = *argv;
-    ret = 1;
-    while (*p) {
-       n = strtol(p, &endp, 16);
-       if (p == endp) {
-           option_error("escape parameter contains invalid hex number '%s'",
-                        p);
-           return 0;
-       }
-       p = endp;
-       if (n < 0 || n == 0x5E || n > 0xFF) {
-           option_error("can't escape character 0x%x", n);
-           ret = 0;
-       } else
-           xmit_accm[0][n >> 5] |= 1 << (n & 0x1F);
-       while (*p == ',' || *p == ' ')
-           ++p;
-    }
-    return ret;
+    BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options));
+    BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options));
+
+    return (1);
 }
 
 #ifdef HAVE_MULTILINK
@@ -282,6 +295,15 @@ setendpoint(argv)
     option_error("Can't parse '%s' as an endpoint discriminator", *argv);
     return 0;
 }
+
+static void
+printendpoint(opt, printer, arg)
+    option_t *opt;
+    void (*printer) __P((void *, char *, ...));
+    void *arg;
+{
+       printer(arg, "%s", epdisc_to_str(&lcp_wantoptions[0].endpoint));
+}
 #endif /* HAVE_MULTILINK */
 
 /*
@@ -323,12 +345,7 @@ lcp_init(unit)
 #ifdef CBCP_SUPPORT
     ao->neg_cbcp = 1;
 #endif
-#ifdef HAVE_MULTILINK
     ao->neg_endpoint = 1;
-#endif
-
-    BZERO(xmit_accm[unit], sizeof(xmit_accm[0]));
-    xmit_accm[unit][3] = 0x60000000;
 }
 
 
@@ -342,7 +359,7 @@ lcp_open(unit)
     fsm *f = &lcp_fsm[unit];
     lcp_options *wo = &lcp_wantoptions[unit];
 
-    f->flags = 0;
+    f->flags &= ~(OPT_PASSIVE | OPT_SILENT);
     if (wo->passive)
        f->flags |= OPT_PASSIVE;
     if (wo->silent)
@@ -386,20 +403,23 @@ lcp_lowerup(unit)
     int unit;
 {
     lcp_options *wo = &lcp_wantoptions[unit];
+    fsm *f = &lcp_fsm[unit];
 
     /*
      * Don't use A/C or protocol compression on transmission,
      * but accept A/C and protocol compressed packets
      * if we are going to ask for A/C and protocol compression.
      */
-    ppp_set_xaccm(unit, xmit_accm[unit]);
     ppp_send_config(unit, PPP_MRU, 0xffffffff, 0, 0);
     ppp_recv_config(unit, PPP_MRU, (lax_recv? 0: 0xffffffff),
                    wo->neg_pcompression, wo->neg_accompression);
     peer_mru[unit] = PPP_MRU;
-    lcp_allowoptions[unit].asyncmap = xmit_accm[unit][0];
 
-    fsm_lowerup(&lcp_fsm[unit]);
+    if (listen_time != 0) {
+       f->flags |= DELAYED_UP;
+       timeout(lcp_delayed_up, f, 0, listen_time * 1000);
+    } else
+       fsm_lowerup(f);
 }
 
 
@@ -410,7 +430,28 @@ void
 lcp_lowerdown(unit)
     int unit;
 {
-    fsm_lowerdown(&lcp_fsm[unit]);
+    fsm *f = &lcp_fsm[unit];
+
+    if (f->flags & DELAYED_UP)
+       f->flags &= ~DELAYED_UP;
+    else
+       fsm_lowerdown(&lcp_fsm[unit]);
+}
+
+
+/*
+ * lcp_delayed_up - Bring the lower layer up now.
+ */
+static void
+lcp_delayed_up(arg)
+    void *arg;
+{
+    fsm *f = arg;
+
+    if (f->flags & DELAYED_UP) {
+       f->flags &= ~DELAYED_UP;
+       fsm_lowerup(f);
+    }
 }
 
 
@@ -425,6 +466,10 @@ lcp_input(unit, p, len)
 {
     fsm *f = &lcp_fsm[unit];
 
+    if (f->flags & DELAYED_UP) {
+       f->flags &= ~DELAYED_UP;
+       fsm_lowerup(f);
+    }
     fsm_input(f, p, len);
 }
 
@@ -558,6 +603,7 @@ lcp_resetci(f)
 {
     lcp_options *wo = &lcp_wantoptions[f->unit];
     lcp_options *go = &lcp_gotoptions[f->unit];
+    lcp_options *ao = &lcp_allowoptions[f->unit];
 
     wo->magicnumber = magic();
     wo->numloops = 0;
@@ -567,6 +613,8 @@ lcp_resetci(f)
        go->neg_ssnhf = 0;
        go->neg_endpoint = 0;
     }
+    if (noendpoint)
+       ao->neg_endpoint = 0;
     peer_mru[f->unit] = PPP_MRU;
     auth_reset(f->unit);
 }
@@ -1640,7 +1688,7 @@ lcp_reqci(f, inp, lenp, reject_if_disagree)
            break;
 
        case CI_EPDISC:
-           if (!ao->neg_endpoint || !multilink ||
+           if (!ao->neg_endpoint ||
                cilen < CILEN_CHAR ||
                cilen > CILEN_CHAR + MAX_ENDP_LEN) {
                orc = CONFREJ;
@@ -1723,6 +1771,7 @@ lcp_up(f)
     lcp_options *ho = &lcp_hisoptions[f->unit];
     lcp_options *go = &lcp_gotoptions[f->unit];
     lcp_options *ao = &lcp_allowoptions[f->unit];
+    int mtu;
 
     if (!go->neg_magicnumber)
        go->magicnumber = 0;
@@ -1734,8 +1783,16 @@ lcp_up(f)
      * the MRU our peer wanted.  If we negotiated an MRU,
      * set our MRU to the larger of value we wanted and
      * the value we got in the negotiation.
+     * Note on the MTU: the link MTU can be the MRU the peer wanted,
+     * the interface MTU is set to the lower of that and the
+     * MTU we want to use.
      */
-    ppp_send_config(f->unit, MIN(ao->mru, (ho->neg_mru? ho->mru: PPP_MRU)),
+    mtu = ho->neg_mru? ho->mru: PPP_MRU;
+#ifdef HAVE_MULTILINK
+    if (!(multilink && go->neg_mrru && ho->neg_mrru))
+#endif /* HAVE_MULTILINK */
+       netif_set_mtu(f->unit, MIN(mtu, ao->mru));
+    ppp_send_config(f->unit, mtu,
                    (ho->neg_asyncmap? ho->asyncmap: 0xffffffff),
                    ho->neg_pcompression, ho->neg_accompression);
     ppp_recv_config(f->unit, (go->neg_mru? MAX(wo->mru, go->mru): PPP_MRU),
@@ -1955,6 +2012,7 @@ lcp_printpkt(p, plen, printer, arg)
                }
                break;
            case CI_EPDISC:
+#ifdef HAVE_MULTILINK
                if (olen >= CILEN_CHAR) {
                    struct epdisc epd;
                    p += 2;
@@ -1968,6 +2026,9 @@ lcp_printpkt(p, plen, printer, arg)
                    }
                    printer(arg, "endpoint [%s]", epdisc_to_str(&epd));
                }
+#else
+               printer(arg, "endpoint");
+#endif
                break;
            }
            while (p < optend) {
@@ -1982,7 +2043,7 @@ lcp_printpkt(p, plen, printer, arg)
     case TERMREQ:
        if (len > 0 && *p >= ' ' && *p < 0x7f) {
            printer(arg, " ");
-           print_string(p, len, printer, arg);
+           print_string((char *)p, len, printer, arg);
            p += len;
            len = 0;
        }