summaryrefslogtreecommitdiff
path: root/usr/src/cmd/cmd-inet/usr.bin/pppd/ipcp.c
diff options
context:
space:
mode:
authorJames Carlson <james.d.carlson@sun.com>2009-05-29 08:53:34 -0400
committerJames Carlson <james.d.carlson@sun.com>2009-05-29 08:53:34 -0400
commitf53eecf557986dac6ededb388fedd6ca63be0350 (patch)
treefc7a51aa1700243330df3d0b104adb4d5a5097a1 /usr/src/cmd/cmd-inet/usr.bin/pppd/ipcp.c
parent00ba712d889cedd6eb0c7de606f61b180572b600 (diff)
downloadillumos-joyent-f53eecf557986dac6ededb388fedd6ca63be0350.tar.gz
PSARC 2009/317 Solaris PPP/PPPoE Updates
4695172 3COM has its own incompatible dialect of PPPoE 4704518 security checks on chap peer name cause interoperability problems 4711045 pppd should not be discarding debug information on fatal signals 4711046 pppoec should provide a way to limit match against wildcard service 4714306 sppptun should not use M_ERROR to signal protocol problems 4743677 pppd can trigger latent access server bug 4750809 pppd needs lint cleanup 4947676 spppcomp_wput() allows an unprivileged process to "hang" the system. 5058886 PPPD misses first LCP configuration request 5060749 need a way to log demand-dial action at higher priority 5093264 PPPoE server can omit Service-Name tag in PADS response 6291911 ugly preremove script in SUNWpppdt causes messages on pkgrm from zone 6589814 pppd disavows bad echo-reply count 6636684 PPP should work in non-global exclusive-stack zones 6637245 sppp driver has half-baked _mi_driver_info function 6704096 SUNWpppdu and SUNWpppdr package dependency and content issues 6753945 sppptun doesn't honor clearview vanity naming feature.
Diffstat (limited to 'usr/src/cmd/cmd-inet/usr.bin/pppd/ipcp.c')
-rw-r--r--usr/src/cmd/cmd-inet/usr.bin/pppd/ipcp.c273
1 files changed, 136 insertions, 137 deletions
diff --git a/usr/src/cmd/cmd-inet/usr.bin/pppd/ipcp.c b/usr/src/cmd/cmd-inet/usr.bin/pppd/ipcp.c
index 019178a4c1..2e26afbf1e 100644
--- a/usr/src/cmd/cmd-inet/usr.bin/pppd/ipcp.c
+++ b/usr/src/cmd/cmd-inet/usr.bin/pppd/ipcp.c
@@ -1,7 +1,7 @@
/*
* ipcp.c - PPP IP Control Protocol.
*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* Copyright (c) 1989 Carnegie Mellon University.
@@ -20,7 +20,6 @@
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
#define RCSID "$Id: ipcp.c,v 1.54 2000/04/15 01:27:11 masputra Exp $"
/*
@@ -382,13 +381,13 @@ ipcp_init(unit)
BZERO(wo, sizeof(*wo));
BZERO(ao, sizeof(*ao));
- wo->neg_addr = 1;
+ wo->neg_addr = wo->old_addrs = 1;
wo->neg_vj = 1;
wo->vj_protocol = IPCP_VJ_COMP;
wo->maxslotindex = MAX_STATES - 1; /* really max index */
wo->cflag = 1;
- ao->neg_addr = 1;
+ ao->neg_addr = ao->old_addrs = 1;
ao->neg_vj = 1;
ao->maxslotindex = MAX_STATES - 1;
ao->cflag = 1;
@@ -482,8 +481,10 @@ ipcp_resetci(f)
{
ipcp_options *wo = &ipcp_wantoptions[f->unit];
ipcp_options *go = &ipcp_gotoptions[f->unit];
+ ipcp_options *ao = &ipcp_allowoptions[f->unit];
- wo->req_addr = wo->neg_addr && ipcp_allowoptions[f->unit].neg_addr;
+ wo->req_addr = (wo->neg_addr || wo->old_addrs) &&
+ (ao->neg_addr || ao->old_addrs);
if (wo->ouraddr == 0 || disable_defaultip)
wo->accept_local = 1;
if (wo->hisaddr == 0)
@@ -506,19 +507,17 @@ ipcp_cilen(f)
ipcp_options *wo = &ipcp_wantoptions[f->unit];
ipcp_options *ho = &ipcp_hisoptions[f->unit];
+#define LENCIADDRS(neg) (neg ? CILEN_ADDRS : 0)
#define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0)
-#define LENCIADDR(neg, old) (neg ? (old? CILEN_ADDRS : CILEN_ADDR) : 0)
-#define LENCIDNS(neg) (neg ? (CILEN_ADDR) : 0)
+#define LENCIADDR(neg) (neg ? (CILEN_ADDR) : 0)
/*
* First see if we want to change our options to the old
* forms because we have received old forms from the peer.
*/
- if (wo->neg_addr && !go->neg_addr && !go->old_addrs) {
+ if (go->neg_addr && go->old_addrs && !ho->neg_addr && ho->old_addrs)
/* use the old style of address negotiation */
- go->neg_addr = 1;
- go->old_addrs = 1;
- }
+ go->neg_addr = 0;
if (wo->neg_vj && !go->neg_vj && !go->old_vj) {
/* try an older style of VJ negotiation */
/* use the old style only if the peer did */
@@ -529,10 +528,11 @@ ipcp_cilen(f)
}
}
- return (LENCIADDR(go->neg_addr, go->old_addrs) +
+ return (LENCIADDRS(!go->neg_addr && go->old_addrs) +
LENCIVJ(go->neg_vj, go->old_vj) +
- LENCIDNS(go->req_dns1) +
- LENCIDNS(go->req_dns2)) ;
+ LENCIADDR(go->neg_addr) +
+ LENCIADDR(go->req_dns1) +
+ LENCIADDR(go->req_dns2)) ;
}
@@ -549,6 +549,18 @@ ipcp_addci(f, ucp, lenp)
ipcp_options *go = &ipcp_gotoptions[f->unit];
int len = *lenp;
+#define ADDCIADDRS(opt, neg, val1, val2) \
+ if (neg) { \
+ if (len >= CILEN_ADDRS) { \
+ PUTCHAR(opt, ucp); \
+ PUTCHAR(CILEN_ADDRS, ucp); \
+ PUTNLONG(val1, ucp); \
+ PUTNLONG(val2, ucp); \
+ len -= CILEN_ADDRS; \
+ } else \
+ go->old_addrs = 0; \
+ }
+
#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \
if (neg) { \
int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
@@ -565,41 +577,28 @@ ipcp_addci(f, ucp, lenp)
neg = 0; \
}
-#define ADDCIADDR(opt, neg, old, val1, val2) \
- if (neg) { \
- int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
- if (len >= addrlen) { \
- PUTCHAR(opt, ucp); \
- PUTCHAR(addrlen, ucp); \
- PUTNLONG(val1, ucp); \
- if (old) { \
- PUTNLONG(val2, ucp); \
- } \
- len -= addrlen; \
- } else \
- neg = 0; \
- }
-
-#define ADDCIDNS(opt, neg, addr) \
+#define ADDCIADDR(opt, neg, val) \
if (neg) { \
if (len >= CILEN_ADDR) { \
PUTCHAR(opt, ucp); \
PUTCHAR(CILEN_ADDR, ucp); \
- PUTNLONG(addr, ucp); \
+ PUTNLONG(val, ucp); \
len -= CILEN_ADDR; \
} else \
neg = 0; \
}
- ADDCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,
- go->old_addrs, go->ouraddr, go->hisaddr);
+ ADDCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr,
+ go->hisaddr);
ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
go->maxslotindex, go->cflag);
- ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
+ ADDCIADDR(CI_ADDR, go->neg_addr, go->ouraddr);
- ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
+ ADDCIADDR(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
+
+ ADDCIADDR(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
*lenp -= len;
}
@@ -630,16 +629,30 @@ ipcp_ackci(f, p, len)
* If we find any deviations, then this packet is bad.
*/
-#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \
- if (neg) { \
- int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
- if ((len -= vjlen) < 0) \
+#define ACKCHECK(opt, olen) \
+ if ((len -= olen) < 0) \
goto bad; \
GETCHAR(citype, p); \
GETCHAR(cilen, p); \
- if (cilen != vjlen || \
- citype != opt) \
+ if (cilen != olen || \
+ citype != opt) \
+ goto bad;
+
+#define ACKCIADDRS(opt, neg, val1, val2) \
+ if (neg) { \
+ ACKCHECK(opt, CILEN_ADDRS) \
+ GETNLONG(cilong, p); \
+ if (val1 != cilong) \
goto bad; \
+ GETNLONG(cilong, p); \
+ if (val2 != cilong) \
+ goto bad; \
+ }
+
+#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \
+ if (neg) { \
+ int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \
+ ACKCHECK(opt, vjlen) \
GETSHORT(cishort, p); \
if (cishort != val) \
goto bad; \
@@ -653,48 +666,25 @@ ipcp_ackci(f, p, len)
} \
}
-#define ACKCIADDR(opt, neg, old, val1, val2) \
+#define ACKCIADDR(opt, neg, val) \
if (neg) { \
- int addrlen = (old? CILEN_ADDRS: CILEN_ADDR); \
- if ((len -= addrlen) < 0) \
- goto bad; \
- GETCHAR(citype, p); \
- GETCHAR(cilen, p); \
- if (cilen != addrlen || \
- citype != opt) \
- goto bad; \
+ ACKCHECK(opt, CILEN_ADDR) \
GETNLONG(cilong, p); \
- if (val1 != cilong) \
+ if (val != cilong) \
goto bad; \
- if (old) { \
- GETNLONG(cilong, p); \
- if (val2 != cilong) \
- goto bad; \
- } \
}
-#define ACKCIDNS(opt, neg, addr) \
- if (neg) { \
- if ((len -= CILEN_ADDR) < 0) \
- goto bad; \
- GETCHAR(citype, p); \
- GETCHAR(cilen, p); \
- if (cilen != CILEN_ADDR || citype != opt) \
- goto bad; \
- GETNLONG(cilong, p); \
- if (addr != cilong) \
- goto bad; \
- }
-
- ACKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), go->neg_addr,
- go->old_addrs, go->ouraddr, go->hisaddr);
+ ACKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr,
+ go->hisaddr);
ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj,
go->maxslotindex, go->cflag);
- ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
+ ACKCIADDR(CI_ADDR, go->neg_addr, go->ouraddr);
+
+ ACKCIADDR(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]);
- ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
+ ACKCIADDR(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]);
/*
* If there are any remaining CIs, then this packet is bad.
@@ -728,7 +718,7 @@ ipcp_nakci(f, p, len)
u_char cimaxslotindex, cicflag;
u_char citype, cilen, *next;
u_short cishort;
- u_int32_t ciaddr1, ciaddr2, cidnsaddr;
+ u_int32_t ciaddr1, ciaddr2;
ipcp_options no; /* options we've seen Naks for */
ipcp_options try; /* options to request next time */
@@ -740,20 +730,16 @@ ipcp_nakci(f, p, len)
* Check packet length and CI length at each step.
* If we find any deviations, then this packet is bad.
*/
-#define NAKCIADDR(opt, neg, old, code) \
- if (go->neg && \
- len >= (cilen = (old? CILEN_ADDRS: CILEN_ADDR)) && \
- p[1] == cilen && \
+#define NAKCIADDRS(opt, neg, code) \
+ if ((neg) && \
+ (cilen = p[1]) == CILEN_ADDRS && \
+ len >= cilen && \
p[0] == opt) { \
len -= cilen; \
INCPTR(2, p); \
GETNLONG(ciaddr1, p); \
- if (old) { \
- GETNLONG(ciaddr2, p); \
- no.old_addrs = 1; \
- } else \
- ciaddr2 = 0; \
- no.neg = 1; \
+ GETNLONG(ciaddr2, p); \
+ no.old_addrs = 1; \
code \
}
@@ -769,14 +755,14 @@ ipcp_nakci(f, p, len)
code \
}
-#define NAKCIDNS(opt, neg, code) \
+#define NAKCIADDR(opt, neg, code) \
if (go->neg && \
- ((cilen = p[1]) == CILEN_ADDR) && \
+ (cilen = p[1]) == CILEN_ADDR && \
len >= cilen && \
p[0] == opt) { \
len -= cilen; \
INCPTR(2, p); \
- GETNLONG(cidnsaddr, p); \
+ GETNLONG(ciaddr1, p); \
no.neg = 1; \
code \
}
@@ -785,7 +771,7 @@ ipcp_nakci(f, p, len)
* Accept the peer's idea of {our,his} address, if different
* from our idea, only if the accept_{local,remote} flag is set.
*/
- NAKCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr, go->old_addrs,
+ NAKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs,
if (go->accept_local && ciaddr1) { /* Do we know our address? */
try.ouraddr = ciaddr1;
}
@@ -823,13 +809,19 @@ ipcp_nakci(f, p, len)
}
);
- NAKCIDNS(CI_MS_DNS1, req_dns1,
- try.dnsaddr[0] = cidnsaddr;
- );
+ NAKCIADDR(CI_ADDR, neg_addr,
+ if (go->accept_local && ciaddr1) { /* Do we know our address? */
+ try.ouraddr = ciaddr1;
+ }
+ );
- NAKCIDNS(CI_MS_DNS2, req_dns2,
- try.dnsaddr[1] = cidnsaddr;
- );
+ NAKCIADDR(CI_MS_DNS1, req_dns1,
+ try.dnsaddr[0] = ciaddr1;
+ );
+
+ NAKCIADDR(CI_MS_DNS2, req_dns2,
+ try.dnsaddr[1] = ciaddr1;
+ );
/*
* There may be remaining CIs, if the peer is requesting negotiation
@@ -852,7 +844,7 @@ ipcp_nakci(f, p, len)
no.neg_vj = 1;
break;
case CI_ADDRS:
- if ((go->neg_addr && go->old_addrs) || no.old_addrs
+ if ((!go->neg_addr && go->old_addrs) || no.old_addrs
|| cilen != CILEN_ADDRS)
goto bad;
try.neg_addr = 1;
@@ -917,10 +909,10 @@ ipcp_rejci(f, p, len)
* Check packet length and CI length at each step.
* If we find any deviations, then this packet is bad.
*/
-#define REJCIADDR(opt, neg, old, val1, val2) \
- if (go->neg && \
- len >= (cilen = old? CILEN_ADDRS: CILEN_ADDR) && \
- p[1] == cilen && \
+#define REJCIADDRS(opt, neg, val1, val2) \
+ if ((neg) && \
+ (cilen = p[1]) == CILEN_ADDRS && \
+ len >= cilen && \
p[0] == opt) { \
len -= cilen; \
INCPTR(2, p); \
@@ -928,13 +920,11 @@ ipcp_rejci(f, p, len)
/* Check rejected value. */ \
if (cilong != val1) \
goto bad; \
- if (old) { \
- GETNLONG(cilong, p); \
- /* Check rejected value. */ \
- if (cilong != val2) \
- goto bad; \
- } \
- try.neg = 0; \
+ GETNLONG(cilong, p); \
+ /* Check rejected value. */ \
+ if (cilong != val2) \
+ goto bad; \
+ try.old_addrs = 0; \
}
#define REJCIVJ(opt, neg, val, old, maxslot, cflag) \
@@ -959,7 +949,7 @@ ipcp_rejci(f, p, len)
try.neg = 0; \
}
-#define REJCIDNS(opt, neg, dnsaddr) \
+#define REJCIADDR(opt, neg, addr) \
if (go->neg && \
((cilen = p[1]) == CILEN_ADDR) && \
len >= cilen && \
@@ -968,21 +958,22 @@ ipcp_rejci(f, p, len)
INCPTR(2, p); \
GETNLONG(cilong, p); \
/* Check rejected value. */ \
- if (cilong != dnsaddr) \
+ if (cilong != addr) \
goto bad; \
try.neg = 0; \
}
-
- REJCIADDR((go->old_addrs? CI_ADDRS: CI_ADDR), neg_addr,
- go->old_addrs, go->ouraddr, go->hisaddr);
+ REJCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs,
+ go->ouraddr, go->hisaddr);
REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj,
go->maxslotindex, go->cflag);
- REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]);
+ REJCIADDR(CI_ADDR, neg_addr, go->ouraddr);
+
+ REJCIADDR(CI_MS_DNS1, req_dns1, go->dnsaddr[0]);
- REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]);
+ REJCIADDR(CI_MS_DNS2, req_dns2, go->dnsaddr[1]);
/*
* If there are any remaining CIs, then this packet is bad.
@@ -1058,7 +1049,7 @@ ipcp_reqci(f, p, lenp, dont_nak)
switch (type) { /* Check CI type */
case CI_ADDRS:
- if (!ao->neg_addr) {
+ if (!ao->old_addrs || ho->neg_addr) {
newret = CODE_CONFREJ;
break;
}
@@ -1119,14 +1110,13 @@ ipcp_reqci(f, p, lenp, dont_nak)
PUTNLONG(ciaddr2, nakp);
}
- ho->neg_addr = 1;
ho->old_addrs = 1;
ho->hisaddr = ciaddr1;
ho->ouraddr = ciaddr2;
break;
case CI_ADDR:
- if (!ao->neg_addr) {
+ if (!ao->neg_addr || ho->old_addrs) {
newret = CODE_CONFREJ;
break;
}
@@ -1331,7 +1321,8 @@ ipcp_reqci(f, p, lenp, dont_nak)
* input buffer is long enough that we can append the extra
* option safely.
*/
- if (ret != CODE_CONFREJ && !ho->neg_addr && wo->req_addr && !dont_nak) {
+ if (ret != CODE_CONFREJ && !ho->neg_addr && !ho->old_addrs &&
+ wo->req_addr && !dont_nak) {
if (ret == CODE_CONFACK)
wo->req_addr = 0; /* don't ask again */
ret = CODE_CONFNAK;
@@ -1910,6 +1901,31 @@ ipcp_printpkt(p, plen, printer, arg)
return p - pstart;
}
+char *
+tcp_flag_decode(val)
+ int val;
+{
+ static char buf[32];
+ char *cp = buf;
+
+ if (val & TH_URG)
+ *cp++ = 'U';
+ if (val & TH_ACK)
+ *cp++ = 'A';
+ if (val & TH_PUSH)
+ *cp++ = 'P';
+ if (val & TH_RST)
+ *cp++ = 'R';
+ if (val & TH_SYN)
+ *cp++ = 'S';
+ if (val & TH_FIN)
+ *cp++ = 'F';
+ if (cp != buf)
+ *cp++ = ' ';
+ *cp = '\0';
+ return buf;
+}
+
/*
* ip_active_pkt - see if this IP packet is worth bringing the link up for.
* We don't bring the link up for IP fragments or for TCP FIN packets
@@ -1949,7 +1965,7 @@ ip_active_pkt(pkt, len)
(void) slprintf(buf, sizeof (buf), "IP proto %d", val);
cp = buf;
}
- dbglog("%s from %I->%I is activity", cp, src, dst);
+ info("%s from %I->%I is activity", cp, src, dst);
}
return 1;
}
@@ -1966,25 +1982,8 @@ ip_active_pkt(pkt, len)
dbglog("Empty TCP FIN %I->%I is not activity", src, dst);
return 0;
}
- if (debug) {
- cp = buf;
- if (val & TH_URG)
- *cp++ = 'U';
- if (val & TH_ACK)
- *cp++ = 'A';
- if (val & TH_PUSH)
- *cp++ = 'P';
- if (val & TH_RST)
- *cp++ = 'R';
- if (val & TH_SYN)
- *cp++ = 'S';
- if (val & TH_FIN)
- *cp++ = 'F';
- if (cp != buf)
- *cp++ = ' ';
- *cp = '\0';
- dbglog("TCP %d data %s%I->%I is activity", len - hlen, buf, src, dst);
- }
+ info("TCP %d data %s%I->%I is activity", len - hlen,
+ tcp_flag_decode(get_tcpflags(tcp)), src, dst);
return 1;
}