]> git.ozlabs.org Git - ppp.git/commitdiff
Merge pull request #297 from mjeveritt/patch-11-test-pr
authorPaul Mackerras <paulus@ozlabs.org>
Sat, 16 Oct 2021 03:01:46 +0000 (14:01 +1100)
committerGitHub <noreply@github.com>
Sat, 16 Oct 2021 03:01:46 +0000 (14:01 +1100)
pppd: Add option to ask peer for WINS address

This adds a 'usepeerwins' option, analogous to the usepeerdns option,
to ask the peer for WINS server addresses.  Nothing is done with
the addresses provided other than to pass them to the ip-up
script in environment variables.

With this, if the peer sends an IPCP Configure-NAK containing
WINS addresses, we will request them in the following IPCP
Configure-Request.

Co-authored-by: Mike Frysinger <vapier@gentoo.org>
Signed-off-by: Michael Everitt <gentoo@veremit.xyz>
Signed-off-by: Lars Wendler <polynomial-c@gentoo.org>
Signed-off-by: Michael Everitt <michael@2e0cer.net>
1  2 
pppd/ipcp.c
pppd/ipcp.h
pppd/pppd.8

diff --combined pppd/ipcp.c
index 6bcdf74e9410295b5353a6c144ab7b2fbf84c308,6e0d5f66f57c86b5572b315cb434a65166caabd2..0dc251e503d725f4bec5f7f81953fafcc0f04168
   * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   */
  
 +#ifdef HAVE_CONFIG_H
 +#include "config.h"
 +#endif
 +
  /*
   * TODO:
   */
@@@ -93,6 -89,7 +93,7 @@@ struct notifier *ip_down_notifier = NUL
  static int default_route_set[NUM_PPP];        /* Have set up a default route */
  static int proxy_arp_set[NUM_PPP];    /* Have created proxy arp entry */
  static bool usepeerdns;                       /* Ask peer for DNS addrs */
+ static bool usepeerwins;              /* Ask peer for WINS addrs */
  static int ipcp_is_up;                        /* have called np_up() */
  static int ipcp_is_open;              /* haven't called np_finished() */
  static bool ask_for_local;            /* request our address from peer */
@@@ -221,6 -218,9 +222,9 @@@ static option_t ipcp_option_list[] = 
      { "usepeerdns", o_bool, &usepeerdns,
        "Ask peer for DNS address(es)", 1 },
  
+     { "usepeerwins", o_bool, &usepeerwins,
+       "Ask peer for WINS address(es)", 1 },
      { "netmask", o_special, (void *)setnetmask,
        "set netmask", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, netmask_str },
  
@@@ -682,15 -682,16 +686,17 @@@ ipcp_resetci(fsm *f
      ipcp_options *go = &ipcp_gotoptions[f->unit];
      ipcp_options *ao = &ipcp_allowoptions[f->unit];
  
 -    wo->req_addr = (wo->neg_addr || wo->old_addrs) &&
 -      (ao->neg_addr || ao->old_addrs);
 +    wo->req_addr = ((wo->neg_addr || wo->old_addrs) &&
 +      (ao->neg_addr || ao->old_addrs)) ||
 +      (wo->hisaddr && !wo->accept_remote);
      if (wo->ouraddr == 0)
        wo->accept_local = 1;
      if (wo->hisaddr == 0)
        wo->accept_remote = 1;
      wo->req_dns1 = usepeerdns;        /* Request DNS addresses from the peer */
      wo->req_dns2 = usepeerdns;
+     wo->req_wins1 = usepeerwins; /* Request WINS addresses from the peer */
+     wo->req_wins2 = usepeerwins;
      *go = *wo;
      if (!ask_for_local)
        go->ouraddr = 0;
@@@ -742,8 -743,8 +748,8 @@@ ipcp_cilen(fsm *f
            LENCIADDR(go->neg_addr) +
            LENCIDNS(go->req_dns1) +
            LENCIDNS(go->req_dns2) +
-           LENCIWINS(go->winsaddr[0]) +
-           LENCIWINS(go->winsaddr[1])) ;
+           LENCIWINS(go->req_wins1) +
+           LENCIWINS(go->req_wins2)) ;
  }
  
  
@@@ -814,8 -815,8 +820,8 @@@ ipcp_addci(fsm *f, u_char *ucp, int *le
            neg = 0; \
      }
  
- #define ADDCIWINS(opt, addr) \
-     if (addr) { \
+ #define ADDCIWINS(opt, neg, addr) \
+     if (neg) { \
        if (len >= CILEN_ADDR) { \
            u_int32_t l; \
            PUTCHAR(opt, ucp); \
            PUTLONG(l, ucp); \
            len -= CILEN_ADDR; \
        } else \
-           addr = 0; \
+           neg = 0; \
      }
  
      ADDCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr,
  
      ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
  
-     ADDCIWINS(CI_MS_WINS1, go->winsaddr[0]);
+     ADDCIWINS(CI_MS_WINS1, go->req_wins1, go->winsaddr[0]);
  
-     ADDCIWINS(CI_MS_WINS2, go->winsaddr[1]);
+     ADDCIWINS(CI_MS_WINS2, go->req_wins2, go->winsaddr[1]);
      
      *lenp -= len;
  }
@@@ -943,8 -944,8 +949,8 @@@ ipcp_ackci(fsm *f, u_char *p, int len
            goto bad; \
      }
  
- #define ACKCIWINS(opt, addr) \
-     if (addr) { \
+ #define ACKCIWINS(opt, neg, addr) \
+     if (neg) { \
        u_int32_t l; \
        if ((len -= CILEN_ADDR) < 0) \
            goto bad; \
  
      ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
  
-     ACKCIWINS(CI_MS_WINS1, go->winsaddr[0]);
+     ACKCIWINS(CI_MS_WINS1, go->req_wins1, go->winsaddr[0]);
  
-     ACKCIWINS(CI_MS_WINS2, go->winsaddr[1]);
+     ACKCIWINS(CI_MS_WINS2, go->req_wins2, go->winsaddr[1]);
  
      /*
       * If there are any remaining CIs, then this packet is bad.
  static int
  ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject)
  {
 +    ipcp_options *wo = &ipcp_wantoptions[f->unit];
      ipcp_options *go = &ipcp_gotoptions[f->unit];
      u_char cimaxslotindex, cicflag;
      u_char citype, cilen, *next;
      u_short cishort;
-     u_int32_t ciaddr1, ciaddr2, l, cidnsaddr;
+     u_int32_t ciaddr1, ciaddr2, l, cidnsaddr, ciwinsaddr;
      ipcp_options no;          /* options we've seen Naks for */
      ipcp_options try;         /* options to request next time */
  
        code \
      }
  
+ #define NAKCIWINS(opt, neg, code) \
+     if (go->neg && \
+       ((cilen = p[1]) == CILEN_ADDR) && \
+       len >= cilen && \
+       p[0] == opt) { \
+       len -= cilen; \
+       INCPTR(2, p); \
+       GETLONG(l, p); \
+       ciwinsaddr = htonl(l); \
+       no.neg = 1; \
+       code \
+     }
      /*
       * Accept the peer's idea of {our,his} address, if different
       * from our idea, only if the accept_{local,remote} flag is set.
             }
             );
  
+     NAKCIWINS(CI_MS_WINS1, req_wins1,
+            if (treat_as_reject) {
+                try.req_wins1 = 0;
+            } else {
+                try.winsaddr[0] = ciwinsaddr;
+            }
+            );
+     NAKCIWINS(CI_MS_WINS2, req_wins2,
+            if (treat_as_reject) {
+                try.req_wins2 = 0;
+            } else {
+                try.winsaddr[1] = ciwinsaddr;
+            }
+            );
      /*
       * There may be remaining CIs, if the peer is requesting negotiation
       * on an option that we didn't include in our request packet.
            GETLONG(l, p);
            ciaddr1 = htonl(l);
            if (ciaddr1 && go->accept_local)
 -              try.ouraddr = ciaddr1;
 +              try.ouraddr = wo->old_addrs ? ciaddr1 : 0;
            GETLONG(l, p);
            ciaddr2 = htonl(l);
            if (ciaddr2 && go->accept_remote)
            ciaddr1 = htonl(l);
            if (ciaddr1 && go->accept_local)
                try.ouraddr = ciaddr1;
 -          if (try.ouraddr != 0)
 +          if (try.ouraddr != 0 && wo->neg_addr)
                try.neg_addr = 1;
            no.neg_addr = 1;
            break;
            no.req_dns2 = 1;
            break;
        case CI_MS_WINS1:
+           if (go->req_wins1 || no.req_wins1 || cilen != CILEN_ADDR)
+               goto bad;
+           GETLONG(l, p);
+           try.winsaddr[0] = htonl(l);
+           try.req_wins1 = 1;
+           no.req_wins1 = 1;
+           break;
        case CI_MS_WINS2:
-           if (cilen != CILEN_ADDR)
+           if (go->req_wins2 || no.req_wins2 || cilen != CILEN_ADDR)
                goto bad;
            GETLONG(l, p);
-           ciaddr1 = htonl(l);
-           if (ciaddr1)
-               try.winsaddr[citype == CI_MS_WINS2] = ciaddr1;
+           try.winsaddr[1] = htonl(l);
+           try.req_wins2 = 1;
+           no.req_wins2 = 1;
            break;
        }
        p = next;
@@@ -1237,7 -1273,6 +1279,6 @@@ bad
      return 0;
  }
  
  /*
   * ipcp_rejci - Reject some of our CIs.
   * Callback from fsm_rconfnakrej.
@@@ -1332,8 -1367,8 +1373,8 @@@ ipcp_rejci(fsm *f, u_char *p, int len
        try.neg = 0; \
      }
  
- #define REJCIWINS(opt, addr) \
-     if (addr && \
+ #define REJCIWINS(opt, neg, addr) \
+     if (go->neg && \
        ((cilen = p[1]) == CILEN_ADDR) && \
        len >= cilen && \
        p[0] == opt) { \
        /* Check rejected value. */ \
        if (cilong != addr) \
            goto bad; \
-       try.winsaddr[opt == CI_MS_WINS2] = 0; \
+       try.neg = 0; \
      }
  
      REJCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs,
  
      REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]);
  
-     REJCIWINS(CI_MS_WINS1, go->winsaddr[0]);
+     REJCIWINS(CI_MS_WINS1, req_wins1, go->winsaddr[0]);
  
-     REJCIWINS(CI_MS_WINS2, go->winsaddr[1]);
+     REJCIWINS(CI_MS_WINS2, req_wins2, go->winsaddr[1]);
  
      /*
       * If there are any remaining CIs, then this packet is bad.
@@@ -1476,7 -1511,7 +1517,7 @@@ ipcp_reqci(fsm *f, u_char *inp, int *le
            if (ciaddr2 != wo->ouraddr) {
                if (ciaddr2 == 0 || !wo->accept_local) {
                    orc = CONFNAK;
 -                  if (!reject_if_disagree) {
 +                  if (!reject_if_disagree && wo->old_addrs) {
                        DECPTR(sizeof(u_int32_t), p);
                        tl = ntohl(wo->ouraddr);
                        PUTLONG(tl, p);
            /* Microsoft primary or secondary WINS request */
            d = citype == CI_MS_WINS2;
  
-           /* If we do not have a DNS address then we cannot send it */
+           /* If we do not have a WINS address then we cannot send it */
            if (ao->winsaddr[d] == 0 ||
                cilen != CILEN_ADDR) {  /* Check CI length */
                orc = CONFREJ;          /* Reject CI */
@@@ -1653,8 -1688,7 +1694,8 @@@ endswitch
       * option safely.
       */
      if (rc != CONFREJ && !ho->neg_addr && !ho->old_addrs &&
 -      wo->req_addr && !reject_if_disagree && !noremoteip) {
 +      wo->req_addr && !reject_if_disagree &&
 +      ((wo->hisaddr && !wo->accept_remote) || !noremoteip)) {
        if (rc == CONFACK) {
            rc = CONFNAK;
            ucp = inp;                  /* reset pointer */
@@@ -1766,12 -1800,6 +1807,12 @@@ ipcp_up(fsm *f
      /*
       * We must have a non-zero IP address for both ends of the link.
       */
 +
 +    if (wo->hisaddr && !wo->accept_remote && (!(ho->neg_addr || ho->old_addrs) || ho->hisaddr != wo->hisaddr)) {
 +      error("Peer refused to agree to his IP address");
 +      ipcp_close(f->unit, "Refused his IP address");
 +      return;
 +    }
      if (!ho->neg_addr && !ho->old_addrs)
        ho->hisaddr = wo->hisaddr;
  
        create_resolv(go->dnsaddr[0], go->dnsaddr[1]);
      }
  
+     if (go->winsaddr[0])
+         script_setenv("WINS1", ip_ntoa(go->winsaddr[0]), 0);
+     if (go->winsaddr[1])
+         script_setenv("WINS2", ip_ntoa(go->winsaddr[1]), 0);
+     if (usepeerwins && (go->winsaddr[0] || go->winsaddr[1]))
+         script_setenv("USEPEERWINS", "1", 0);
      /*
       * Check that the peer is allowed to use the IP address it wants.
       */
                wo->ouraddr = go->ouraddr;
            } else
                script_unsetenv("OLDIPLOCAL");
 -          if (ho->hisaddr != wo->hisaddr && wo->hisaddr != 0) {
 +          if (ho->hisaddr != wo->hisaddr) {
                warn("Remote IP address changed to %I", ho->hisaddr);
 -              script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0);
 +              if (wo->hisaddr != 0)
 +                  script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0);
                wo->hisaddr = ho->hisaddr;
            } else
                script_unsetenv("OLDIPREMOTE");
diff --combined pppd/ipcp.h
index 52d2b22e9e6e4cdd78dbe820ef9377bc918926ba,2ec8190cd53bde1a163997bfb757b71cf9c94b7e..90336c4013cd1aaddb27409db28e9cef7c21f8a9
@@@ -39,7 -39,6 +39,7 @@@
   * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
   * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
   */
 +#include "pppdconf.h"
  
  /*
   * Options.
@@@ -77,6 -76,8 +77,8 @@@ typedef struct ipcp_options 
      bool accept_remote;               /* accept peer's value for hisaddr */
      bool req_dns1;            /* Ask peer to send primary DNS address? */
      bool req_dns2;            /* Ask peer to send secondary DNS address? */
+     bool req_wins1;           /* Ask peer to send primary WINS address? */
+     bool req_wins2;           /* Ask peer to send secondary WINS address? */
      int  vj_protocol;         /* protocol value to use in VJ option */
      int  maxslotindex;                /* values for RFC1332 VJ compression neg. */
      bool cflag;
diff --combined pppd/pppd.8
index b0074062097e930bec31532d99401378a4ccc35e,b5790d9b3d1e6f3af6cf55db4eafbe63dd83da05..7417a36ed2632ae4172a2776b1c4d574c62f8d2e
@@@ -55,8 -55,8 +55,8 @@@ non-privileged user
  .I speed
  An option that is a decimal number is taken as the desired baud rate
  for the serial device.  On systems such as
 -4.4BSD and NetBSD, any speed can be specified.  Other systems
 -(e.g. Linux, SunOS) only support the commonly-used baud rates.
 +Linux, 4.4BSD and NetBSD, any speed can be specified.  Other systems
 +(e.g. SunOS) only support the commonly-used baud rates.
  .TP
  .B asyncmap \fImap
  This option sets the Async-Control-Character-Map (ACCM) for this end
@@@ -127,6 -127,12 +127,6 @@@ is no other default route with the sam
  value of -1, the route is only added if there is no default route at
  all.
  .TP
 -.B defaultroute6
 -Add a default IPv6 route to the system routing tables, using the peer as
 -the gateway, when IPv6CP negotiation is successfully completed.
 -This entry is removed when the PPP connection is broken.  This option
 -is privileged if the \fInodefaultroute6\fR option has been specified.
 -.TP
  .B replacedefaultroute
  This option is a flag to the defaultroute option. If defaultroute is
  set and this flag is also set, pppd replaces an existing default route
@@@ -260,16 -266,10 +260,16 @@@ compression in the corresponding direct
  \fIbsdcomp 0\fR to disable BSD-Compress compression entirely.
  .TP
  .B ca \fIca-file
 -(EAP-TLS) Use the file \fIca-file\fR as the X.509 Certificate Authority
 +(EAP-TLS, or PEAP) Use the file \fIca-file\fR as the X.509 Certificate Authority
  (CA) file (in PEM format), needed for setting up an EAP-TLS connection.
  This option is used on the client-side in conjunction with the \fBcert\fR
 -and \fBkey\fR options.
 +and \fBkey\fR options.  Either \fIca\fR, or \fIcapath\fR options are required
 +for PEAP. EAP-TLS may also use the entry in eaptls-client or eaptls-server
 +for a CA certificate associated with a particular peer.
 +.TP
 +.B capath \fIpath
 +(EAP-TLS, or PEAP) Specify a location that contains public CA certificates.
 +Either \fIca\fR, or \fIcapath\fR options are required for PEAP.
  .TP
  .B cdtrcts
  Use a non-standard hardware flow control (i.e. DTR/CTS) to control
@@@ -326,15 -326,15 +326,15 @@@ negotiation by sending its first LCP pa
  or \fBpty\fR option is used.
  .TP
  .B crl \fIfilename
 -(EAP-TLS) Use the file \fIfilename\fR as the Certificate Revocation List
 +(EAP-TLS, or PEAP) Use the file \fIfilename\fR as the Certificate Revocation List
  to check for the validity of the peer's certificate. This option is not
 -mandatory for setting up an EAP-TLS connection. Also see the \fBcrl-dir\fR
 +mandatory for setting up a TLS connection. Also see the \fBcrl-dir\fR
  option.
  .TP
  .B crl-dir \fIdirectory
 -(EAP-TLS) Use the directory \fIdirectory\fR to scan for CRL files in
 +(EAP-TLS, or PEAP) Use the directory \fIdirectory\fR to scan for CRL files in
  has format ($hash.r0) to check for the validity of the peer's certificate.
 -This option is not mandatory for setting up an EAP-TLS connection.
 +This option is not mandatory for setting up a TLS connection.
  Also see the \fBcrl\fR option.
  .TP
  .B debug
@@@ -354,17 -354,6 +354,17 @@@ Disable MRU [Maximum Receive Unit] nego
  pppd will use the default MRU value of 1500 bytes for both the
  transmit and receive direction.
  .TP
 +.B defaultroute6
 +Add a default IPv6 route to the system routing tables, using the peer as
 +the gateway, when IPv6CP negotiation is successfully completed.
 +This entry is removed when the PPP connection is broken.  This option
 +is privileged if the \fInodefaultroute6\fR option has been specified.
 +\fBWARNING: Do not enable this option by default\fR.  IPv6 routing tables
 +are managed by kernel (as apposite to IPv4) and IPv6 default route is
 +configured by kernel automatically too based on ICMPv6 Router Advertisement
 +packets.  This option may conflict with kernel IPv6 route setup and should
 +be used only for broken IPv6 networks.
 +.TP
  .B deflate \fInr,nt
  Request that the peer compress packets that it sends, using the
  Deflate scheme, with a maximum window size of \fI2**nr\fR bytes, and
@@@ -504,18 -493,6 +504,18 @@@ to send configure-Rejects instead to \f
  Set the maximum number of IPCP terminate-request transmissions to
  \fIn\fR (default 3).
  .TP
 +.B ipcp\-no\-address
 +Disable negotiation of addresses via IP-Address IPCP option.
 +.TP
 +.B ipcp\-no\-addresses
 +Disable negotiation of addresses via old-style deprecated IP-Addresses
 +IPCP option. pppd by default try to use new-style IP-Address IPCP option.
 +If new-style is not supported by peer or is disabled by \fBipcp\-no\-address\fR
 +option then pppd fallbacks to old-style deprecated IP-Addresses IPCP option.
 +When both new-style and old-style are disabled by both \fBipcp\-no\-address\fR
 +and \fBipcp\-no\-addresses\fR options then negotiation of IP addresses
 +is completely disabled.
 +.TP
  .B ipcp\-restart \fIn
  Set the IPCP restart interval (retransmission timeout) to \fIn\fR
  seconds (default 3).
@@@ -730,11 -707,6 +730,11 @@@ network control protocol comes up)
  Terminate after \fIn\fR consecutive failed connection attempts.  A
  value of 0 means no limit.  The default value is 10.
  .TP
 +.B max-tls-version \fIstring
 +(EAP-TLS, or PEAP) Configures the max allowed TLS version used during
 +negotiation with a peer.  The default value for this is \fI1.2\fR.  Values
 +allowed for this option is \fI1.0.\fR, \fI1.1\fR, \fI1.2\fR, \fI1.3\fR.
 +.TP
  .B modem
  Use the modem control lines.  This option is the default.  With this
  option, pppd will wait for the CD (Carrier Detect) signal from the
@@@ -952,9 -924,6 +952,9 @@@ situation, the ppp interface can be use
  device routes, but the peer itself cannot be addressed directly for IP
  traffic.
  .TP
 +.B nosendip
 +Don't send our local IP address to peer during IP address negotiation.
 +.TP
  .B notty
  Normally, pppd requires a terminal device.  With this option, pppd
  will allocate itself a pseudo-tty master/slave pair and use the slave
@@@ -1184,16 -1153,6 +1184,16 @@@ The device used by pppd with this optio
  Currently supports Microgate SyncLink adapters
  under Linux and FreeBSD 2.2.8 and later.
  .TP
 +.B tls-verify-method \fIstring
 +(EAP-TLS, or PEAP) Match the value specified for \fIremotename\fR to that that
 +of the X509 certificates subject name, common name, or suffix of the common
 +name.  Respective values allowed for this option is: \fInone\fR, \fIsubject\fR,
 +\fIname\fR, or \fIsuffix\fR.  The default value for this option is \fIname\fR.
 +.TP
 +.B tls-verify-key-usage
 +(EAP-TLS, or PEAP) Enables examination of peer certificate's purpose, and
 +extended key usage attributes.
 +.TP
  .B unit \fInum
  Sets the ppp unit number (for a ppp0 or ppp1 etc interface name) for outbound
  connections.  If the unit is already in use a dynamically allocated number will
@@@ -1240,6 -1199,16 +1240,16 @@@ USEPEERDNS will be set to 1.  In additi
  /etc/ppp/resolv.conf file containing one or two nameserver lines with
  the address(es) supplied by the peer.
  .TP
+ .B usepeerwins
+ Ask the peer for up to 2 WINS server addresses.  The addresses supplied
+ by the peer (if any) are passed to the /etc/ppp/ip\-up script in the
+ environment variables WINS1 and WINS2, and the environment variable
+ USEPEERWINS will be set to 1.
+ .LP
+ Please note that some modems (like the Huawei E220) requires this option in
+ order to avoid a race condition that results in the incorrect DNS servers
+ being assigned.
+ .TP
  .B user \fIname
  Sets the name used for authenticating the local system to the peer to
  \fIname\fR.
@@@ -1791,14 -1760,6 +1801,14 @@@ IPCP has come up
  The IP address for the remote end of the link.  This is only set when
  IPCP has come up.
  .TP
 +.B LLLOCAL
 +The Link-Local IPv6 address for the local end of the link.  This is only
 +set when IPV6CP has come up.
 +.TP
 +.B LLREMOTE
 +The Link-Local IPv6 address for the remote end of the link.  This is only
 +set when IPV6CP has come up.
 +.TP
  .B PEERNAME
  The authenticated name of the peer.  This is only set if the peer
  authenticates itself.
@@@ -1842,6 -1803,15 +1852,15 @@@ option was given)
  If the peer supplies DNS server addresses, this variable is set to the
  second DNS server address supplied (whether or not the usepeerdns
  option was given).
+ .TP
+ .B WINS1
+ If the peer supplies WINS server addresses, this variable is set to the
+ first WINS server address supplied.
+ .TP
+ .B WINS2
+ If the peer supplies WINS server addresses, this variable is set to the
+ second WINS server address supplied.
+ .P
  .P
  Pppd invokes the following scripts, if they exist.  It is not an error
  if they don't exist.