]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/ipcp.c
Nit: use _exit when exec fails and restrict values to 0-255 per POSIX.
[ppp.git] / pppd / ipcp.c
index 98a427c1137d259a64ac01e429ea93ddff61a59c..12bcc61be737f9d50b3ac3a6292f6c3c74d93b71 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.72 2008/03/26 11:34:23 paulus Exp $"
+#define RCSID  "$Id: ipcp.c,v 1.73 2008/05/26 08:33:22 paulus Exp $"
 
 /*
  * TODO:
@@ -575,6 +575,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));
 
@@ -723,7 +731,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
@@ -745,7 +754,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])) ;
 }
 
 
@@ -819,6 +830,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);
 
@@ -831,6 +855,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;
 }
 
@@ -1185,6 +1213,15 @@ ipcp_nakci(f, p, len, treat_as_reject)
            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;
     }
@@ -1301,6 +1338,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);
@@ -1314,6 +1366,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.
      */
@@ -1742,6 +1798,10 @@ ipcp_up(f)
     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])