]> git.ozlabs.org Git - ppp.git/blobdiff - pppd/ipcp.c
Linux isn't special any more; SVR4 may be.
[ppp.git] / pppd / ipcp.c
index d8f1933ba98ac8dd3542d819ab2016ea798570ac..227e16a0e61ff4065d9f95184c9e25975537ce9d 100644 (file)
@@ -18,7 +18,7 @@
  */
 
 #ifndef lint
-static char rcsid[] = "$Id: ipcp.c,v 1.26 1996/07/01 01:13:53 paulus Exp $";
+static char rcsid[] = "$Id: ipcp.c,v 1.29 1996/09/26 06:21:33 paulus Exp $";
 #endif
 
 /*
@@ -33,9 +33,6 @@ static char rcsid[] = "$Id: ipcp.c,v 1.26 1996/07/01 01:13:53 paulus Exp $";
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/tcp.h>
 
 #include "pppd.h"
 #include "fsm.h"
@@ -1062,13 +1059,11 @@ ip_check_options()
     }
 
     if (demand && wo->hisaddr == 0) {
-       fprintf(stderr, "%s: remote IP address required for demand-dialling\n",
-               progname);
+       option_error("remote IP address required for demand-dialling\n");
        exit(1);
     }
     if (demand && wo->accept_remote) {
-       fprintf(stderr, "%s: ipcp-accept-remote is incompatible with demand\n",
-               progname);
+       option_error("ipcp-accept-remote is incompatible with demand\n");
        exit(1);
     }
 }
@@ -1086,10 +1081,10 @@ ip_demand_conf(u)
 
     if (!sifaddr(u, wo->ouraddr, wo->hisaddr, GetMask(wo->ouraddr)))
        return 0;
-    if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE))
-       return 0;
     if (!sifup(u))
        return 0;
+    if (!sifnpmode(u, PPP_IP, NPMODE_QUEUE))
+       return 0;
     if (wo->default_route)
        if (sifdefaultroute(u, wo->hisaddr))
            default_route_set[u] = 1;
@@ -1164,20 +1159,20 @@ ipcp_up(f)
        }
        demand_rexmit(PPP_IP);
        sifnpmode(f->unit, PPP_IP, NPMODE_PASS);
-    }
-#ifndef _linux_  /* Linux destroys routes when the device goes down. */
-    else         /* always use the code which adds the routes. */
-#endif
-    {
+
+    } else {
        /*
         * Set IP addresses and (if specified) netmask.
         */
        mask = GetMask(go->ouraddr);
+
+#if !(defined(SVR4) && (defined(SNI) || defined(__USLC__)))
        if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {
            IPCPDEBUG((LOG_WARNING, "sifaddr failed"));
            ipcp_close(f->unit, "Interface configuration failed");
            return;
        }
+#endif
 
        /* bring the interface up for IP */
        if (!sifup(f->unit)) {
@@ -1185,6 +1180,14 @@ ipcp_up(f)
            ipcp_close(f->unit, "Interface configuration failed");
            return;
        }
+
+#if (defined(SVR4) && (defined(SNI) || defined(__USLC__)))
+       if (!sifaddr(f->unit, go->ouraddr, ho->hisaddr, mask)) {
+           IPCPDEBUG((LOG_WARNING, "sifaddr failed"));
+           ipcp_close(f->unit, "Interface configuration failed");
+           return;
+       }
+#endif
        sifnpmode(f->unit, PPP_IP, NPMODE_PASS);
 
        /* assign a default route through the interface if required */
@@ -1222,8 +1225,9 @@ ipcp_down(f)
 {
     u_int32_t ouraddr, hisaddr;
 
-    np_down(f->unit, PPP_IP);
     IPCPDEBUG((LOG_INFO, "ipcp: down"));
+    np_down(f->unit, PPP_IP);
+    sifvjcomp(f->unit, 0, 0, 0);
 
     /*
      * If we are doing dial-on-demand, set the interface
@@ -1409,31 +1413,45 @@ ipcp_printpkt(p, plen, printer, arg)
  * We don't bring the link up for IP fragments or for TCP FIN packets
  * with no data.
  */
-#ifndef IP_OFFMASK
+#define IP_HDRLEN      20      /* bytes */
 #define IP_OFFMASK     0x1fff
-#endif
+#define IPPROTO_TCP    6
+#define TCP_HDRLEN     20
+#define TH_FIN         0x01
+
+/*
+ * We use these macros because the IP header may be at an odd address,
+ * and some compilers might use word loads to get th_off or ip_hl.
+ */
+
+#define net_short(x)   (((x)[0] << 8) + (x)[1])
+#define get_iphl(x)    (((unsigned char *)(x))[0] & 0xF)
+#define get_ipoff(x)   net_short((unsigned char *)(x) + 6)
+#define get_ipproto(x) (((unsigned char *)(x))[9])
+#define get_tcpoff(x)  (((unsigned char *)(x))[12] >> 4)
+#define get_tcpflags(x)        (((unsigned char *)(x))[13])
 
 static int
 ip_active_pkt(pkt, len)
     u_char *pkt;
     int len;
 {
-    struct ip *ip;
-    struct tcphdr *tcp;
+    u_char *tcp;
     int hlen;
 
-    if (len < sizeof(struct ip) + PPP_HDRLEN)
+    len -= PPP_HDRLEN;
+    pkt += PPP_HDRLEN;
+    if (len < IP_HDRLEN)
        return 0;
-    ip = (struct ip *) (pkt + PPP_HDRLEN);
-    if ((ntohs(ip->ip_off) & IP_OFFMASK) != 0)
+    if ((get_ipoff(pkt) & IP_OFFMASK) != 0)
        return 0;
-    if (ip->ip_p != IPPROTO_TCP)
+    if (get_ipproto(pkt) != IPPROTO_TCP)
        return 1;
-    hlen = ip->ip_hl * 4;
-    if (len < hlen + sizeof(struct tcphdr) + PPP_HDRLEN)
+    hlen = get_iphl(pkt) * 4;
+    if (len < hlen + TCP_HDRLEN)
        return 0;
-    tcp = (struct tcphdr *) (pkt + PPP_HDRLEN + hlen);
-    if ((tcp->th_flags & TH_FIN) != 0 && hlen + tcp->th_off * 4 == len)
+    tcp = pkt + hlen;
+    if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4)
        return 0;
     return 1;
 }