]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/ipcp.c
pppd: Remove unused rcsid variables
[ppp.git] / pppd / ipcp.c
index 5962c4720a39ea6924b383463eaecaf513c73a7f..ed6cd4b7b86926bca2b991a4f49a91171128c933 100644 (file)
@@ -40,7 +40,7 @@
  * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 
-#define RCSID  "$Id: ipcp.c,v 1.70 2005/08/25 23:59:34 paulus Exp $"
+#define RCSID  "$Id: ipcp.c,v 1.73 2008/05/26 08:33:22 paulus Exp $"
 
 /*
  * TODO:
@@ -61,7 +61,6 @@
 #include "ipcp.h"
 #include "pathnames.h"
 
-static const char rcsid[] = RCSID;
 
 /* global vars */
 ipcp_options ipcp_wantoptions[NUM_PPP];        /* Options that we want to request */
@@ -72,6 +71,7 @@ ipcp_options ipcp_hisoptions[NUM_PPP];        /* Options that we ack'd */
 u_int32_t netmask = 0;         /* IP netmask to set on interface */
 
 bool   disable_defaultip = 0;  /* Don't use hostname for default IP adrs */
+bool   noremoteip = 0;         /* Let him have no IP address */
 
 /* Hook for a plugin to know when IP protocol has come up */
 void (*ip_up_hook) __P((void)) = NULL;
@@ -174,10 +174,10 @@ static option_t ipcp_option_list[] = {
     { "noipdefault", o_bool, &disable_defaultip,
       "Don't use name for default IP adrs", 1 },
 
-    { "ms-dns", 1, (void *)setdnsaddr,
-      "DNS address for the peer's use" },
-    { "ms-wins", 1, (void *)setwinsaddr,
-      "Nameserver for SMB over TCP/IP for peer" },
+    { "ms-dns", o_special, (void *)setdnsaddr,
+      "DNS address for the peer's use", OPT_A2LIST },
+    { "ms-wins", o_special, (void *)setwinsaddr,
+      "Nameserver for SMB over TCP/IP for peer", OPT_A2LIST },
 
     { "ipcp-restart", o_int, &ipcp_fsm[0].timeouttime,
       "Set timeout for IPCP", OPT_PRIO },
@@ -218,6 +218,13 @@ static option_t ipcp_option_list[] = {
     { "ipcp-no-address", o_bool, &ipcp_wantoptions[0].neg_addr,
       "Disable IP-Address usage", OPT_A2CLR,
       &ipcp_allowoptions[0].neg_addr },
+#ifdef __linux__
+    { "noremoteip", o_bool, &noremoteip,
+      "Allow peer to have no IP address", 1 },
+#endif
+    { "nosendip", o_bool, &ipcp_wantoptions[0].neg_addr,
+      "Don't send our IP address to peer", OPT_A2CLR,
+      &ipcp_wantoptions[0].old_addrs},
 
     { "IP addresses", o_wild, (void *) &setipaddr,
       "set local and remote IP addresses",
@@ -567,6 +574,14 @@ ipcp_init(unit)
     f->callbacks = &ipcp_callbacks;
     fsm_init(&ipcp_fsm[unit]);
 
+    /*
+     * Some 3G modems use repeated IPCP NAKs as a way of stalling
+     * until they can contact a server on the network, so we increase
+     * the default number of NAKs we accept before we start treating
+     * them as rejects.
+     */
+    f->maxnakloops = 100;
+
     memset(wo, 0, sizeof(*wo));
     memset(ao, 0, sizeof(*ao));
 
@@ -715,7 +730,8 @@ ipcp_cilen(f)
 #define LENCIADDRS(neg)                (neg ? CILEN_ADDRS : 0)
 #define LENCIVJ(neg, old)      (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)
 #define LENCIADDR(neg)         (neg ? CILEN_ADDR : 0)
-#define LENCIDNS(neg)          (neg ? (CILEN_ADDR) : 0)
+#define LENCIDNS(neg)          LENCIADDR(neg)
+#define LENCIWINS(neg)         LENCIADDR(neg)
 
     /*
      * First see if we want to change our options to the old
@@ -737,7 +753,9 @@ ipcp_cilen(f)
            LENCIVJ(go->neg_vj, go->old_vj) +
            LENCIADDR(go->neg_addr) +
            LENCIDNS(go->req_dns1) +
-           LENCIDNS(go->req_dns2)) ;
+           LENCIDNS(go->req_dns2) +
+           LENCIWINS(go->winsaddr[0]) +
+           LENCIWINS(go->winsaddr[1])) ;
 }
 
 
@@ -811,6 +829,19 @@ ipcp_addci(f, ucp, lenp)
            neg = 0; \
     }
 
+#define ADDCIWINS(opt, addr) \
+    if (addr) { \
+       if (len >= CILEN_ADDR) { \
+           u_int32_t l; \
+           PUTCHAR(opt, ucp); \
+           PUTCHAR(CILEN_ADDR, ucp); \
+           l = ntohl(addr); \
+           PUTLONG(l, ucp); \
+           len -= CILEN_ADDR; \
+       } else \
+           addr = 0; \
+    }
+
     ADDCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr,
               go->hisaddr);
 
@@ -823,6 +854,10 @@ ipcp_addci(f, ucp, lenp)
 
     ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
 
+    ADDCIWINS(CI_MS_WINS1, go->winsaddr[0]);
+
+    ADDCIWINS(CI_MS_WINS2, go->winsaddr[1]);
+    
     *lenp -= len;
 }
 
@@ -926,6 +961,21 @@ ipcp_ackci(f, p, len)
            goto bad; \
     }
 
+#define ACKCIWINS(opt, addr) \
+    if (addr) { \
+       u_int32_t l; \
+       if ((len -= CILEN_ADDR) < 0) \
+           goto bad; \
+       GETCHAR(citype, p); \
+       GETCHAR(cilen, p); \
+       if (cilen != CILEN_ADDR || citype != opt) \
+           goto bad; \
+       GETLONG(l, p); \
+       cilong = htonl(l); \
+       if (addr != cilong) \
+           goto bad; \
+    }
+
     ACKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr,
               go->hisaddr);
 
@@ -938,6 +988,10 @@ ipcp_ackci(f, p, len)
 
     ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
 
+    ACKCIWINS(CI_MS_WINS1, go->winsaddr[0]);
+
+    ACKCIWINS(CI_MS_WINS2, go->winsaddr[1]);
+
     /*
      * If there are any remaining CIs, then this packet is bad.
      */
@@ -1117,6 +1171,8 @@ ipcp_nakci(f, p, len, treat_as_reject)
      * on an option that we didn't include in our request packet.
      * If they want to negotiate about IP addresses, we comply.
      * If they want us to ask for compression, we refuse.
+     * If they want us to ask for ms-dns, we do that, since some
+     * peers get huffy if we don't.
      */
     while (len >= CILEN_VOID) {
        GETCHAR(citype, p);
@@ -1159,6 +1215,31 @@ ipcp_nakci(f, p, len, treat_as_reject)
                try.neg_addr = 1;
            no.neg_addr = 1;
            break;
+       case CI_MS_DNS1:
+           if (go->req_dns1 || no.req_dns1 || cilen != CILEN_ADDR)
+               goto bad;
+           GETLONG(l, p);
+           try.dnsaddr[0] = htonl(l);
+           try.req_dns1 = 1;
+           no.req_dns1 = 1;
+           break;
+       case CI_MS_DNS2:
+           if (go->req_dns2 || no.req_dns2 || cilen != CILEN_ADDR)
+               goto bad;
+           GETLONG(l, p);
+           try.dnsaddr[1] = htonl(l);
+           try.req_dns2 = 1;
+           no.req_dns2 = 1;
+           break;
+       case CI_MS_WINS1:
+       case CI_MS_WINS2:
+           if (cilen != CILEN_ADDR)
+               goto bad;
+           GETLONG(l, p);
+           ciaddr1 = htonl(l);
+           if (ciaddr1)
+               try.winsaddr[citype == CI_MS_WINS2] = ciaddr1;
+           break;
        }
        p = next;
     }
@@ -1275,6 +1356,21 @@ ipcp_rejci(f, p, len)
        try.neg = 0; \
     }
 
+#define REJCIWINS(opt, addr) \
+    if (addr && \
+       ((cilen = p[1]) == CILEN_ADDR) && \
+       len >= cilen && \
+       p[0] == opt) { \
+       u_int32_t l; \
+       len -= cilen; \
+       INCPTR(2, p); \
+       GETLONG(l, p); \
+       cilong = htonl(l); \
+       /* Check rejected value. */ \
+       if (cilong != addr) \
+           goto bad; \
+       try.winsaddr[opt == CI_MS_WINS2] = 0; \
+    }
 
     REJCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs,
               go->ouraddr, go->hisaddr);
@@ -1288,6 +1384,10 @@ ipcp_rejci(f, p, len)
 
     REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]);
 
+    REJCIWINS(CI_MS_WINS1, go->winsaddr[0]);
+
+    REJCIWINS(CI_MS_WINS2, go->winsaddr[1]);
+
     /*
      * If there are any remaining CIs, then this packet is bad.
      */
@@ -1581,7 +1681,7 @@ endswitch:
      * option safely.
      */
     if (rc != CONFREJ && !ho->neg_addr && !ho->old_addrs &&
-       wo->req_addr && !reject_if_disagree) {
+       wo->req_addr && !reject_if_disagree && !noremoteip) {
        if (rc == CONFACK) {
            rc = CONFNAK;
            ucp = inp;                  /* reset pointer */
@@ -1641,7 +1741,7 @@ ip_demand_conf(u)
 {
     ipcp_options *wo = &ipcp_wantoptions[u];
 
-    if (wo->hisaddr == 0) {
+    if (wo->hisaddr == 0 && !noremoteip) {
        /* make up an arbitrary address for the peer */
        wo->hisaddr = htonl(0x0a707070 + ifunit);
        wo->accept_remote = 1;
@@ -1667,7 +1767,8 @@ ip_demand_conf(u)
            proxy_arp_set[u] = 1;
 
     notice("local  IP address %I", wo->ouraddr);
-    notice("remote IP address %I", wo->hisaddr);
+    if (wo->hisaddr)
+       notice("remote IP address %I", wo->hisaddr);
 
     return 1;
 }
@@ -1706,14 +1807,19 @@ ipcp_up(f)
        ipcp_close(f->unit, "Could not determine local IP address");
        return;
     }
-    if (ho->hisaddr == 0) {
+    if (ho->hisaddr == 0 && !noremoteip) {
        ho->hisaddr = htonl(0x0a404040 + ifunit);
        warn("Could not determine remote IP address: defaulting to %I",
             ho->hisaddr);
     }
     script_setenv("IPLOCAL", ip_ntoa(go->ouraddr), 0);
-    script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr), 1);
+    if (ho->hisaddr != 0)
+       script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr), 1);
 
+    if (!go->req_dns1)
+           go->dnsaddr[0] = 0;
+    if (!go->req_dns2)
+           go->dnsaddr[1] = 0;
     if (go->dnsaddr[0])
        script_setenv("DNS1", ip_ntoa(go->dnsaddr[0]), 0);
     if (go->dnsaddr[1])
@@ -1726,7 +1832,7 @@ ipcp_up(f)
     /*
      * Check that the peer is allowed to use the IP address it wants.
      */
-    if (!auth_ip_addr(f->unit, ho->hisaddr)) {
+    if (ho->hisaddr != 0 && !auth_ip_addr(f->unit, ho->hisaddr)) {
        error("Peer is not authorized to use remote address %I", ho->hisaddr);
        ipcp_close(f->unit, "Unauthorized remote IP address");
        return;
@@ -1749,7 +1855,7 @@ ipcp_up(f)
                wo->ouraddr = go->ouraddr;
            } else
                script_unsetenv("OLDIPLOCAL");
-           if (ho->hisaddr != wo->hisaddr) {
+           if (ho->hisaddr != wo->hisaddr && wo->hisaddr != 0) {
                warn("Remote IP address changed to %I", ho->hisaddr);
                script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0);
                wo->hisaddr = ho->hisaddr;
@@ -1771,7 +1877,7 @@ ipcp_up(f)
                    default_route_set[f->unit] = 1;
 
            /* Make a proxy ARP entry if requested. */
-           if (ipcp_wantoptions[f->unit].proxy_arp)
+           if (ho->hisaddr != 0 && ipcp_wantoptions[f->unit].proxy_arp)
                if (sifproxyarp(f->unit, ho->hisaddr))
                    proxy_arp_set[f->unit] = 1;
 
@@ -1821,14 +1927,15 @@ ipcp_up(f)
                default_route_set[f->unit] = 1;
 
        /* Make a proxy ARP entry if requested. */
-       if (ipcp_wantoptions[f->unit].proxy_arp)
+       if (ho->hisaddr != 0 && ipcp_wantoptions[f->unit].proxy_arp)
            if (sifproxyarp(f->unit, ho->hisaddr))
                proxy_arp_set[f->unit] = 1;
 
        ipcp_wantoptions[0].ouraddr = go->ouraddr;
 
        notice("local  IP address %I", go->ouraddr);
-       notice("remote IP address %I", ho->hisaddr);
+       if (ho->hisaddr != 0)
+           notice("remote IP address %I", ho->hisaddr);
        if (go->dnsaddr[0])
            notice("primary   DNS address %I", go->dnsaddr[0]);
        if (go->dnsaddr[1])
@@ -2114,7 +2221,7 @@ ipcp_printpkt(p, plen, printer, arg)
            case CI_MS_DNS2:
                p += 2;
                GETLONG(cilong, p);
-               printer(arg, "ms-dns%d %I", code - CI_MS_DNS1 + 1,
+               printer(arg, "ms-dns%d %I", (code == CI_MS_DNS1? 1: 2),
                        htonl(cilong));
                break;
            case CI_MS_WINS1: