diff options
author | James Carlson <james.d.carlson@sun.com> | 2009-05-29 08:53:34 -0400 |
---|---|---|
committer | James Carlson <james.d.carlson@sun.com> | 2009-05-29 08:53:34 -0400 |
commit | f53eecf557986dac6ededb388fedd6ca63be0350 (patch) | |
tree | fc7a51aa1700243330df3d0b104adb4d5a5097a1 | |
parent | 00ba712d889cedd6eb0c7de606f61b180572b600 (diff) | |
download | illumos-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.
39 files changed, 713 insertions, 573 deletions
diff --git a/usr/src/cmd/cmd-inet/etc/init.d/pppd b/usr/src/cmd/cmd-inet/etc/init.d/pppd index e820e6b15e..5644724154 100644 --- a/usr/src/cmd/cmd-inet/etc/init.d/pppd +++ b/usr/src/cmd/cmd-inet/etc/init.d/pppd @@ -43,10 +43,12 @@ case "$1" in if [ -f $PPPDIR/pppoe.if ] && [ -x /usr/sbin/sppptun ]; then sed -e 's/^#.*//;s/\([^\\]\)#.*/\1/;s/[ ]*$//;s/^[ ]*//' \ $PPPDIR/pppoe.if | \ - while read intf; do + while read intf saps sapd; do if [ "$intf" ]; then - /usr/sbin/sppptun plumb pppoe $intf - /usr/sbin/sppptun plumb pppoed $intf + [ -z "$saps" ] || saps="-s $saps" + /usr/sbin/sppptun plumb $saps pppoe $intf + [ -z "$sapd" ] || sapd="-s $sapd" + /usr/sbin/sppptun plumb $sapd pppoed $intf fi done fi @@ -76,7 +78,7 @@ case "$1" in if [ -f $PPPDIR/pppoe.if ] && [ -x /usr/sbin/sppptun ]; then sed -e 's/^#.*//;s/\([^\\]\)#.*/\1/;s/[ ]*$//;s/^[ ]*//' \ $PPPDIR/pppoe.if | \ - while read intf; do + while read intf rest; do if [ "$intf" ]; then /usr/sbin/sppptun unplumb ${intf}:pppoe /usr/sbin/sppptun unplumb ${intf}:pppoed diff --git a/usr/src/cmd/cmd-inet/etc/ppp/Makefile b/usr/src/cmd/cmd-inet/etc/ppp/Makefile index 18bd5ada7b..8027f48d2f 100644 --- a/usr/src/cmd/cmd-inet/etc/ppp/Makefile +++ b/usr/src/cmd/cmd-inet/etc/ppp/Makefile @@ -2,9 +2,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -19,17 +18,14 @@ # # CDDL HEADER END # -# -#ident "%Z%%M% %I% %E% SMI" -# -# Copyright (c) 2000 by Sun Microsystems, Inc. -# All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. # # cmd/cmd-inet/etc/ppp/Makefile # PPPDIR= ppp -PEERSDIR= peers +SUBDIRS= peers plugins ETCPROGROOT= pap-secrets chap-secrets ETCPROG= options.tmpl options.ttya.tmpl myisp-chat.tmpl ETCPEERS= myisp.tmpl @@ -37,7 +33,8 @@ ETCPEERS= myisp.tmpl include ../../../Makefile.cmd ETCPPPDIR= $(ROOTETC)/$(PPPDIR) -ETCPEERSDIR= $(ETCPPPDIR)/$(PEERSDIR) +ETCPPPSUBDIRS= $(SUBDIRS:%=$(ETCPPPDIR)/%) +ETCPEERSDIR= $(ETCPPPDIR)/peers ETCPPPPROG= $(ETCPROG:%=$(ETCPPPDIR)/%) $(ETCPEERS:%=$(ETCPEERSDIR)/%) ETCPPPPROGROOT= $(ETCPROGROOT:%=$(ETCPPPDIR)/%) @@ -55,21 +52,16 @@ $(ETCPPPPROGROOT) := FILEMODE = $(SECRETSMODE) all: -install: all $(ETCPPPDIR) $(ETCPEERSDIR) \ +install: all $(ETCPPPDIR) .WAIT $(ETCPPPSUBDIRS) .WAIT \ $(ETCPPPPROG) $(ETCPPPPROGROOT) $(ETCPPPDIR)/% : % $(INS.file) -$(ETCPPPDIR): +$(ETCPPPDIR) $(ETCPPPSUBDIRS): $(INS.dir) $(ETCPEERSDIR)/% : % $(INS.file) -$(ETCPEERSDIR): - $(INS.dir) - -FRC: - clean clobber lint: diff --git a/usr/src/cmd/cmd-inet/usr.bin/pppd/Makefile b/usr/src/cmd/cmd-inet/usr.bin/pppd/Makefile index d69524afd7..19502f8b10 100644 --- a/usr/src/cmd/cmd-inet/usr.bin/pppd/Makefile +++ b/usr/src/cmd/cmd-inet/usr.bin/pppd/Makefile @@ -1,7 +1,5 @@ # -# ident "%Z%%M% %I% %E% SMI" -# -# Copyright 2008 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # cmd/cmd-inet/usr.bin/pppd/Makefile @@ -78,8 +76,6 @@ mschap_test: mschap_test.o chap_ms.o @echo " xx xx xx xx xx xx xx xx" @echo " 00" -LINTFLAGS += -erroff=E_NAME_USED_NOT_DEF2 -LINTFLAGS += -erroff=E_GLOBAL_COULD_BE_STATIC2 LINTFLAGS += -erroff=E_NAME_DEF_NOT_USED2 SRCS= $(OBJS:%.o=%.c) diff --git a/usr/src/cmd/cmd-inet/usr.bin/pppd/chap.c b/usr/src/cmd/cmd-inet/usr.bin/pppd/chap.c index e9fb56605e..707b9f7a71 100644 --- a/usr/src/cmd/cmd-inet/usr.bin/pppd/chap.c +++ b/usr/src/cmd/cmd-inet/usr.bin/pppd/chap.c @@ -1,8 +1,8 @@ /* * chap.c - Challenge Handshake Authentication Protocol. * - * Copyright (c) 2000 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * * Copyright (c) 1993 The Australian National University. * All rights reserved. @@ -36,7 +36,6 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#pragma ident "%Z%%M% %I% %E% SMI" #define RCSID "$Id: chap.c,v 1.24 1999/11/15 01:51:50 paulus Exp $" /* @@ -495,9 +494,17 @@ ChapReceiveChallenge(cstate, inp, id, len) (void) strlcpy(cstate->peercname, rhostname, sizeof (cstate->peercname)); } else if (strcmp(rhostname, cstate->peercname) != 0) { - fake_response = 1; - warn("CHAP: peer challenge name changed from '%q' to '%q'", - cstate->peercname, rhostname); + if (++cstate->rename_count == 1) { + info("CHAP: peer challenge name changed from '%q' to '%q'", + cstate->peercname, rhostname); + (void) strlcpy(cstate->peercname, rhostname, + sizeof (cstate->peercname)); + } else { + fake_response = 1; + if (cstate->rename_count == 2) + warn("CHAP: peer challenge name changed again to '%q'", + rhostname); + } } /* get secret for authenticating ourselves with the specified host */ diff --git a/usr/src/cmd/cmd-inet/usr.bin/pppd/chap.h b/usr/src/cmd/cmd-inet/usr.bin/pppd/chap.h index 56a894c140..f61a66c794 100644 --- a/usr/src/cmd/cmd-inet/usr.bin/pppd/chap.h +++ b/usr/src/cmd/cmd-inet/usr.bin/pppd/chap.h @@ -1,8 +1,8 @@ /* * chap.h - Challenge Handshake Authentication Protocol definitions. * - * Copyright (c) 2000 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * * Copyright (c) 1993 The Australian National University. * All rights reserved. @@ -36,8 +36,6 @@ * $Id: chap.h,v 1.8 1999/11/15 01:44:41 paulus Exp $ */ -#pragma ident "%Z%%M% %I% %E% SMI" - #ifndef __CHAP_INCLUDE__ #define __CHAP_INCLUDE__ @@ -96,6 +94,7 @@ typedef struct chap_state { u_char stat_length; /* Length of status message (MS-CHAP) */ char *resp_name; /* Our name to send with response */ char *stat_message; /* per-algorithm status message (MS-CHAP) */ + int rename_count; /* number of peer renames seen */ } chap_state; diff --git a/usr/src/cmd/cmd-inet/usr.bin/pppd/demand.c b/usr/src/cmd/cmd-inet/usr.bin/pppd/demand.c index 4c007175e0..a5e04eb90b 100644 --- a/usr/src/cmd/cmd-inet/usr.bin/pppd/demand.c +++ b/usr/src/cmd/cmd-inet/usr.bin/pppd/demand.c @@ -1,7 +1,7 @@ /* * demand.c - Support routines for demand-dialling. * - * Copyright 2000-2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * Copyright (c) 1993 The Australian National University. @@ -20,7 +20,6 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#pragma ident "%Z%%M% %I% %E% SMI" #define RCSID "$Id: demand.c,v 1.13 2000/04/15 01:27:11 masputra Exp $" #include <stdio.h> @@ -360,12 +359,15 @@ active_packet(p, len) return 0; } if (protp->active_pkt == NULL) { - dbglog("%s: no active test; bringing up link", protp->name); + notice("%s: no active test; bringing up link", protp->name); return 1; } i = (*protp->active_pkt)(p, len); - dbglog("%s: active test; %sbringing up link", protp->name, - i != 0 ? "" : "not "); + if (i != 0) + notice("%s: active test; bringing up link", protp->name); + else + dbglog("%s: active test; not bringing up link", + protp->name); return i; } } 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; } diff --git a/usr/src/cmd/cmd-inet/usr.bin/pppd/ipcp.h b/usr/src/cmd/cmd-inet/usr.bin/pppd/ipcp.h index d993d1265e..cb8c9b62e2 100644 --- a/usr/src/cmd/cmd-inet/usr.bin/pppd/ipcp.h +++ b/usr/src/cmd/cmd-inet/usr.bin/pppd/ipcp.h @@ -1,8 +1,8 @@ /* * ipcp.h - IP Control Protocol definitions. * - * Copyright (c) 2000 by 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. * All rights reserved. @@ -22,8 +22,6 @@ * $Id: ipcp.h,v 1.13 1999/03/02 05:35:09 paulus Exp $ */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Options. */ @@ -75,6 +73,7 @@ extern ipcp_options ipcp_allowoptions[]; extern ipcp_options ipcp_hisoptions[]; extern char *ip_ntoa __P((u_int32_t)); +extern char *tcp_flag_decode __P((int)); extern struct protent ipcp_protent; extern bool ipcp_from_hostname; diff --git a/usr/src/cmd/cmd-inet/usr.bin/pppd/ipv6cp.c b/usr/src/cmd/cmd-inet/usr.bin/pppd/ipv6cp.c index bf94434288..9338b4f0b9 100644 --- a/usr/src/cmd/cmd-inet/usr.bin/pppd/ipv6cp.c +++ b/usr/src/cmd/cmd-inet/usr.bin/pppd/ipv6cp.c @@ -1,5 +1,5 @@ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * ipv6cp.c - PPP IPV6 Control Protocol. @@ -96,7 +96,6 @@ * $Id: ipv6cp.c,v 1.9 2000/04/15 01:27:11 masputra Exp $ */ -#pragma ident "%Z%%M% %I% %E% SMI" #define RCSID "$Id: ipv6cp.c,v 1.9 2000/04/15 01:27:11 masputra Exp $" /* @@ -1119,7 +1118,6 @@ ipv6_demand_conf(u) if (!sifnpmode(u, PPP_IPV6, NPMODE_QUEUE)) return 0; - notice("ipv6_demand_conf"); notice("local LL address %s", llv6_ntoa(wo->ourid)); notice("remote LL address %s", llv6_ntoa(wo->hisid)); @@ -1496,41 +1494,50 @@ ipv6cp_printpkt(p, plen, printer, arg) * We don't bring the link up for IP fragments or for TCP FIN packets * with no data. */ -#define IP6_HDRLEN 40 /* bytes */ -#define IP6_NHDR_FRAG 44 /* fragment IPv6 header */ -#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 get_ip6nh(x) (((unsigned char *)(x))[6]) -#define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) -#define get_tcpflags(x) (((unsigned char *)(x))[13]) - static int ipv6_active_pkt(pkt, len) u_char *pkt; int len; { u_char *tcp; + struct in6_addr addr; + char fromstr[26]; + char tostr[26]; len -= PPP_HDRLEN; pkt += PPP_HDRLEN; - if (len < IP6_HDRLEN) + if (len < IP6_HDRLEN) { + dbglog("IPv6 packet of length %d is not activity", len); return 0; - if (get_ip6nh(pkt) == IP6_NHDR_FRAG) + } + (void) BCOPY(get_ip6src(pkt), &addr, sizeof (addr)); + (void) inet_ntop(AF_INET6, &addr, fromstr, 26); + (void) BCOPY(get_ip6dst(pkt), &addr, sizeof (addr)); + (void) inet_ntop(AF_INET6, &addr, tostr, 26); + if (get_ip6nh(pkt) == IPPROTO_FRAGMENT) { + dbglog("IPv6 fragment from %s->%s is not activity", fromstr, tostr); return 0; - if (get_ip6nh(pkt) != IPPROTO_TCP) + } + if (get_ip6nh(pkt) != IPPROTO_TCP) { + info("IPv6 proto %d from %s->%s is activity", get_ip6nh(pkt), fromstr, + tostr); return 1; - if (len < IP6_HDRLEN + TCP_HDRLEN) + } + if (len < IP6_HDRLEN + TCP_HDRLEN) { + dbglog("Bad TCP length %d<%d+%d %s->%s is not activity", len, + IP6_HDRLEN, TCP_HDRLEN, fromstr, tostr); return 0; + } tcp = pkt + IP6_HDRLEN; if ((get_tcpflags(tcp) & TH_FIN) != 0 && - len == IP6_HDRLEN + get_tcpoff(tcp) * 4) + len == IP6_HDRLEN + get_tcpoff(tcp) * 4) { + dbglog("Empty TCP FIN %s->%s is not activity", fromstr, tostr); return 0; + } + info("TCP %d data %s%s->%s is activity", len - IP6_HDRLEN - TCP_HDRLEN, + tcp_flag_decode(get_tcpflags(tcp)), fromstr, tostr); return 1; } diff --git a/usr/src/cmd/cmd-inet/usr.bin/pppd/ipv6cp.h b/usr/src/cmd/cmd-inet/usr.bin/pppd/ipv6cp.h index 7194e2abd5..3e87c07145 100644 --- a/usr/src/cmd/cmd-inet/usr.bin/pppd/ipv6cp.h +++ b/usr/src/cmd/cmd-inet/usr.bin/pppd/ipv6cp.h @@ -1,4 +1,7 @@ /* + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * ipv6cp.h - PPP IPV6 Control Protocol. Copyright (C) 1999 Tommi Komulainen <Tommi.Komulainen@iki.fi> @@ -93,7 +96,7 @@ * $Id: ipv6cp.h,v 1.3 1999/09/30 19:57:45 masputra Exp $ */ -#pragma ident "%Z%%M% %I% %E% SMI" +#include <netinet/ip6.h> /* * Options. @@ -126,3 +129,5 @@ extern ipv6cp_options ipv6cp_allowoptions[]; extern ipv6cp_options ipv6cp_hisoptions[]; extern struct protent ipv6cp_protent; + +#define IP6_HDRLEN (sizeof (struct ip6_hdr)) /* bytes */ diff --git a/usr/src/cmd/cmd-inet/usr.bin/pppd/lcp.c b/usr/src/cmd/cmd-inet/usr.bin/pppd/lcp.c index 48ca25485a..306dac1421 100644 --- a/usr/src/cmd/cmd-inet/usr.bin/pppd/lcp.c +++ b/usr/src/cmd/cmd-inet/usr.bin/pppd/lcp.c @@ -1,7 +1,7 @@ /* * lcp.c - PPP Link Control Protocol. * - * Copyright 2000-2002 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: lcp.c,v 1.54 2000/04/27 03:51:18 masputra Exp $" /* @@ -248,6 +247,7 @@ int absmax_mtu = PPP_MAXMTU; static int lcp_echos_pending = 0; /* Number of outstanding echo msgs */ static int lcp_echo_number = 0; /* ID number of next echo frame */ static int lcp_echo_timer_running = 0; /* set if a timer is running */ +static bool lcp_echo_accm_test = 0; /* flag if still testing ACCM */ static int lcp_echo_badreplies = 0; /* number of bad replies from peer */ /* * The maximum number of bad replies we tolerate before bringing the @@ -2849,24 +2849,22 @@ LcpLinkFailure (f) char *close_message; if (f->state == OPENED) { + if (lcp_echo_badreplies > LCP_ECHO_MAX_BADREPLIES) { + info("Received %d bad echo-replies", lcp_echo_badreplies); + close_message = "Receiving malformed Echo-Replies"; + } else if (lcp_echo_accm_test) { /* * If this is an asynchronous line and we've missed all of * the initial echo requests, then this is probably due to * a bad ACCM. */ - if (!sync_serial && lcp_echos_pending >= ACCM_TEST_FAILS && - lcp_echo_number <= ACCM_TEST_FAILS && use_accm_test != 0) { notice("Peer not responding to initial Echo-Requests."); notice("Negotiated asyncmap may be incorrect for this link."); close_message = "Peer not responding; perhaps bad asyncmap"; - } else if (lcp_echo_fails != 0 && - lcp_echos_pending >= lcp_echo_fails) { + } else { info("No response to %d echo-requests", lcp_echos_pending); notice("Serial link appears to be disconnected."); close_message = "Peer not responding"; - } else { - info("Received %d bad echo-replies", lcp_echo_badreplies); - close_message = "Receiving malformed Echo-Replies"; } lcp_close(f->unit, close_message); @@ -2922,7 +2920,6 @@ lcp_received_echo_reply (f, id, inp, len) int len; { u_int32_t magic; - static int sayonce = 1; /* Check the magic number - don't count replies from ourselves. */ if (len < 4) { @@ -2939,10 +2936,9 @@ lcp_received_echo_reply (f, id, inp, len) /* Reset the number of outstanding echo frames */ lcp_echos_pending = 0; - if (!sync_serial && lcp_echo_number <= ACCM_TEST_FAILS && sayonce && - use_accm_test != 0) { + if (lcp_echo_accm_test) { dbglog("lcp: validated asyncmap setting"); - sayonce = 0; + lcp_echo_accm_test = 0; if (lcp_echo_fails == 0) lcp_echo_interval = 0; } @@ -2962,11 +2958,17 @@ LcpSendEchoRequest (f) int i; /* - * Detect the failure of the peer at this point. + * Detect the failure of the peer at this point. If we're not currently + * performing the ACCM test, then we just check for the user's echo-failure + * point. If we are performing the ACCM test, then use ACCM_TEST_FAILS if + * the user hasn't specified a different failure point. */ - if ((lcp_echo_fails != 0 && lcp_echos_pending >= lcp_echo_fails) || - (!sync_serial && lcp_echos_pending >= ACCM_TEST_FAILS && - use_accm_test != 0)) { + i = lcp_echo_fails; + if (i == 0) + i = ACCM_TEST_FAILS; + if ((!lcp_echo_accm_test && lcp_echo_fails != 0 && + lcp_echos_pending >= lcp_echo_fails) || + (lcp_echo_accm_test && lcp_echos_pending >= i)) { LcpLinkFailure(f); lcp_echos_pending = 0; lcp_echo_badreplies = 0; @@ -2980,7 +2982,7 @@ LcpSendEchoRequest (f) pktp = pkt; PUTLONG(lcp_magic, pktp); /* Send some test packets so we can fail the link early. */ - if (!sync_serial && lcp_echo_number <= ACCM_TEST_FAILS) { + if (lcp_echo_accm_test) { switch (use_accm_test) { case 1: /* Only the characters covered by negotiated ACCM */ @@ -3013,7 +3015,8 @@ lcp_echo_lowerup (unit) lcp_echos_pending = 0; lcp_echo_number = 0; lcp_echo_timer_running = 0; - + lcp_echo_accm_test = !sync_serial && use_accm_test; + /* If a timeout interval is specified then start the timer */ LcpEchoCheck(f); } diff --git a/usr/src/cmd/cmd-inet/usr.bin/pppd/main.c b/usr/src/cmd/cmd-inet/usr.bin/pppd/main.c index 5a64ea5bf9..750dc72d93 100644 --- a/usr/src/cmd/cmd-inet/usr.bin/pppd/main.c +++ b/usr/src/cmd/cmd-inet/usr.bin/pppd/main.c @@ -1,7 +1,7 @@ /* * main.c - Point-to-Point Protocol main module * - * Copyright 2000-2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * Permission to use, copy, modify, and distribute this software and its @@ -31,7 +31,6 @@ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. */ -#pragma ident "%Z%%M% %I% %E% SMI" #define RCSID "$Id: main.c,v 1.97 2000/04/24 02:54:16 masputra Exp $" #include <stdio.h> @@ -1079,12 +1078,14 @@ setup_signals() * Install a handler for other signals which would otherwise * cause pppd to exit without cleaning up. */ -/*CONSTANTCONDITION*/ SIGNAL(SIGABRT, bad_signal); /*CONSTANTCONDITION*/ SIGNAL(SIGALRM, bad_signal); +/*CONSTANTCONDITION*/ SIGNAL(SIGQUIT, bad_signal); + +/* Do not hook any of these signals on Solaris; allow core dump instead */ +#ifndef SOL2 +/*CONSTANTCONDITION*/ SIGNAL(SIGABRT, bad_signal); /*CONSTANTCONDITION*/ SIGNAL(SIGFPE, bad_signal); /*CONSTANTCONDITION*/ SIGNAL(SIGILL, bad_signal); -/*CONSTANTCONDITION*/ SIGNAL(SIGPIPE, bad_signal); -/*CONSTANTCONDITION*/ SIGNAL(SIGQUIT, bad_signal); #ifndef DEBUG /*CONSTANTCONDITION*/ SIGNAL(SIGSEGV, bad_signal); #endif @@ -1115,6 +1116,7 @@ setup_signals() #ifdef SIGXFSZ /*CONSTANTCONDITION*/ SIGNAL(SIGXFSZ, bad_signal); #endif +#endif /* * Apparently we can get a SIGPIPE when we call syslog, if diff --git a/usr/src/cmd/cmd-inet/usr.bin/pppd/plugins/pppoe.c b/usr/src/cmd/cmd-inet/usr.bin/pppd/plugins/pppoe.c index 6a46df6896..1ed472461c 100644 --- a/usr/src/cmd/cmd-inet/usr.bin/pppd/plugins/pppoe.c +++ b/usr/src/cmd/cmd-inet/usr.bin/pppd/plugins/pppoe.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -403,6 +403,26 @@ handle_pppoe_input(const ppptun_atype *pma, struct strbuf *ctrl, } /* + * Handle an action code passed up from the driver. + */ +static int +handle_action(struct ppptun_control *ptc, struct strbuf *ctrl, + struct strbuf *data) +{ + switch (ptc->ptc_action) { + case PTCA_CONTROL: + return (handle_pppoe_input(&ptc->ptc_address, ctrl, data)); + + case PTCA_BADCTRL: + warn("bad control message; session %u on %s", ptc->ptc_rsessid, + ptc->ptc_name); + return (0); + } + + return (-1); +} + +/* * sys-solaris has just read in a packet; grovel through it and see if * it's something we need to handle ourselves. */ @@ -418,10 +438,8 @@ pppoe_sys_read_packet(int retv, struct strbuf *ctrl, struct strbuf *data, /* ptc_discrim is the first uint32_t of the structure. */ if (ptc->ptc_discrim == PPPOE_DISCRIM) { retv = -1; - if (ctrl->len == sizeof (*ptc) && - ptc->ptc_action == PTCA_CONTROL) - retv = handle_pppoe_input(&ptc->ptc_address, - ctrl, data); + if (ctrl->len == sizeof (*ptc)) + retv = handle_action(ptc, ctrl, data); if (retv < 0) errno = EAGAIN; return (retv); diff --git a/usr/src/cmd/cmd-inet/usr.bin/pppd/pppd.h b/usr/src/cmd/cmd-inet/usr.bin/pppd/pppd.h index 01e263529e..8c14c1f6ad 100644 --- a/usr/src/cmd/cmd-inet/usr.bin/pppd/pppd.h +++ b/usr/src/cmd/cmd-inet/usr.bin/pppd/pppd.h @@ -1,7 +1,7 @@ /* * pppd.h - PPP daemon global declarations. * - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * Permission to use, copy, modify, and distribute this software and its @@ -33,8 +33,6 @@ * $Id: pppd.h,v 1.54 2000/04/15 10:10:25 paulus Exp $ */ -#pragma ident "%Z%%M% %I% %E% SMI" - #ifndef __PPPD_H__ #define __PPPD_H__ @@ -912,15 +910,18 @@ extern void (*device_pipe_hook) __P((int pipefd)); */ #define net_short(x) (((x)[0] << 8) + (x)[1]) -#define net_long(x) ((net_short(x) << 16) + \ - net_short((unsigned char *)(x) + 2)) +#define native_long(x) (htonl((net_short(x) << 16) + \ + net_short((unsigned char *)(x) + 2))) #define get_ipv(x) ((((unsigned char *)(x))[0] >> 4) & 0xF) #define get_iphl(x) (((unsigned char *)(x))[0] & 0xF) #define get_iplen(x) net_short((unsigned char *)(x) + 2) #define get_ipoff(x) net_short((unsigned char *)(x) + 6) #define get_ipproto(x) (((unsigned char *)(x))[9]) -#define get_ipsrc(x) net_long((unsigned char *)(x) + 12) -#define get_ipdst(x) net_long((unsigned char *)(x) + 16) +#define get_ipsrc(x) native_long((unsigned char *)(x) + 12) +#define get_ipdst(x) native_long((unsigned char *)(x) + 16) +#define get_ip6nh(x) (((unsigned char *)(x))[6]) +#define get_ip6src(x) (((unsigned char *)(x))+8) +#define get_ip6dst(x) (((unsigned char *)(x))+24) /* Ports for both UDP and TCP are first */ #define get_sport(x) net_short(x) #define get_dport(x) net_short((unsigned char *)(x) + 2) diff --git a/usr/src/cmd/cmd-inet/usr.bin/pppd/sys-solaris.c b/usr/src/cmd/cmd-inet/usr.bin/pppd/sys-solaris.c index a0d76768e5..d728fef890 100644 --- a/usr/src/cmd/cmd-inet/usr.bin/pppd/sys-solaris.c +++ b/usr/src/cmd/cmd-inet/usr.bin/pppd/sys-solaris.c @@ -78,6 +78,7 @@ #include <sys/ethernet.h> #include <sys/ser_sync.h> #include <libdlpi.h> +#include <arpa/inet.h> #include "pppd.h" #include "fsm.h" @@ -1553,9 +1554,12 @@ dump_packet(uchar_t *buf, int len) char sbuf[32]; uint32_t src, dst; struct protoent *pep; + struct in6_addr addr; + char fromstr[INET6_ADDRSTRLEN]; + char tostr[INET6_ADDRSTRLEN]; if (len < 4) { - dbglog("strange link activity: %.*B", len, buf); + notice("strange link activity: %.*B", len, buf); return; } bp = buf; @@ -1565,9 +1569,10 @@ dump_packet(uchar_t *buf, int len) if (!(proto & 1)) proto = (proto << 8) + *bp++; len -= bp-buf; - if (proto == PPP_IP) { - if (len < 20 || get_ipv(bp) != 4 || get_iphl(bp) < 5) { - dbglog("strange IP packet activity: %16.*B", len, buf); + switch (proto) { + case PPP_IP: + if (len < IP_HDRLEN || get_ipv(bp) != 4 || get_iphl(bp) < 5) { + notice("strange IP packet activity: %16.*B", len, buf); return; } src = get_ipsrc(bp); @@ -1583,7 +1588,7 @@ dump_packet(uchar_t *buf, int len) if ((get_ipoff(bp) & IP_OFFMASK) != 0) { len -= get_iphl(bp) * 4; bp += get_iphl(bp) * 4; - dbglog("%s fragment from %I->%I: %8.*B", cp, src, dst, + notice("%s fragment from %I->%I: %8.*B", cp, src, dst, len, bp); } else { if (len > get_iplen(bp)) @@ -1592,20 +1597,60 @@ dump_packet(uchar_t *buf, int len) bp += get_iphl(bp) * 4; offs = proto == IPPROTO_TCP ? (get_tcpoff(bp)*4) : 8; if (proto == IPPROTO_TCP || proto == IPPROTO_UDP) - dbglog("%s data:%d %I:%d->%I:%d: %8.*B", cp, - len-offs, src, get_sport(bp), dst, - get_dport(bp), len-offs, bp+offs); + notice("%s data:%d %s%I:%d->%I:%d: %8.*B", cp, + len-offs, + proto == IPPROTO_TCP ? + tcp_flag_decode(get_tcpflags(bp)) : "", + src, get_sport(bp), dst, get_dport(bp), + len-offs, bp+offs); else - dbglog("%s %d bytes %I->%I: %8.*B", cp, len, + notice("%s %d bytes %I->%I: %8.*B", cp, len, src, dst, len, bp); } return; + + case PPP_IPV6: + if (len < IP6_HDRLEN) { + notice("strange IPv6 activity: %16.*B", len, buf); + return; + } + (void) BCOPY(get_ip6src(bp), &addr, sizeof (addr)); + (void) inet_ntop(AF_INET6, &addr, fromstr, sizeof (fromstr)); + (void) BCOPY(get_ip6dst(bp), &addr, sizeof (addr)); + (void) inet_ntop(AF_INET6, &addr, tostr, sizeof (tostr)); + proto = get_ip6nh(bp); + if (proto == IPPROTO_FRAGMENT) { + notice("IPv6 fragment from %s->%s", fromstr, + tostr); + return; + } + if ((pep = getprotobynumber(proto)) != NULL) { + cp = pep->p_name; + } else { + (void) slprintf(sbuf, sizeof (sbuf), "IPv6 proto %d", + proto); + cp = sbuf; + } + len -= IP6_HDRLEN; + bp += IP6_HDRLEN; + offs = proto == IPPROTO_TCP ? (get_tcpoff(bp)*4) : 8; + if (proto == IPPROTO_TCP || proto == IPPROTO_UDP) + notice("%s data:%d %s[%s]%d->[%s]%d: %8.*B", cp, + len-offs, + proto == IPPROTO_TCP ? + tcp_flag_decode(get_tcpflags(bp)) : "", + fromstr, get_sport(bp), tostr, get_dport(bp), + len-offs, bp+offs); + else + notice("%s %d bytes %s->%s: %8.*B", cp, len, + fromstr, tostr, len, bp); + return; } if ((cp = protocol_name(proto)) == NULL) { (void) slprintf(sbuf, sizeof (sbuf), "0x#X", proto); cp = (const char *)sbuf; } - dbglog("link activity: %s %16.*B", cp, len, bp); + notice("link activity: %s %16.*B", cp, len, bp); } /* @@ -1785,7 +1830,7 @@ read_packet(buf) lcp_lowerup(0); return (0); case PPP_LINKSTAT_NEEDUP: - if (data.len > 0 && debug) + if (data.len > 0) dump_packet(buf, data.len); return (-1); /* Demand dial */ case PPP_LINKSTAT_IPV4_UNBOUND: diff --git a/usr/src/cmd/cmd-inet/usr.lib/pppoe/options.c b/usr/src/cmd/cmd-inet/usr.lib/pppoe/options.c index 24e69c8edd..de1602ce6e 100644 --- a/usr/src/cmd/cmd-inet/usr.lib/pppoe/options.c +++ b/usr/src/cmd/cmd-inet/usr.lib/pppoe/options.c @@ -21,12 +21,10 @@ /* * PPPoE Server-mode daemon option parsing. * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -851,7 +849,7 @@ dispatch_keyword(struct parse_state *psp, const char *keybuf) for (kep = key_list; kep->kwe_word != NULL; kep++) { if (kep->kwe_in == psp->ps_state && (*kep->kwe_word == '\0' || - strcasecmp(kep->kwe_word, keybuf) == 0)) { + strcasecmp(kep->kwe_word, keybuf) == 0)) { if (kep->kwe_func != NULL) retv = (*kep->kwe_func)(psp->ps_csvc, keybuf); psp->ps_state = kep->kwe_out; @@ -1419,9 +1417,8 @@ organize_state(struct parse_state *psp) if ((*se2pp)->se_name == slp->sl_entry.se_name || strcmp((*se2pp)-> - se_name, - slp->sl_entry. - se_name) == 0) + se_name, slp->sl_entry. + se_name) == 0) break; /* * We retain a service if it's @@ -1627,7 +1624,7 @@ get_device_list(struct parse_state *psp, int tunfd) for (dlpp = &psp->ps_star; (dlp = *dlpp) != NULL; ) { for (dla = dlalt; dla != NULL; dla = dla->dl_next) if (strcmp(dla->dl_name, dlp->dl_name) == 0) - break; + break; if (dla == NULL) { *dlpp = dlp->dl_next; free(dlp); @@ -1959,10 +1956,6 @@ locate_service(poep_t *poep, int plen, const char *iname, ppptun_atype *pap, break; } seppe = sepp + dep->de_nservices; - /* Clients's requested service must appear in reply. */ - if (tlen != 0 || (ispadi && - !(glob_svc.se_flags & SEF_NOWILD))) - (void) poe_tag_copy(opoe, tagp); if (tlen == 0) { /* * If config specifies "nowild" in a @@ -1976,29 +1969,43 @@ locate_service(poep_t *poep, int plen, const char *iname, ppptun_atype *pap, sepp = seppe; while (sepp < seppe) { sep = *sepp++; - if ((ispadi || !(sep->se_flags & - SEF_NOWILD)) && - allow_service(sep, pap)) { - nsvcs++; - *srvp = (void *)sep; - if (poep->poep_code == - POECODE_PADR) - break; - if (sep->se_name[0] == '\0') - continue; - (void) poe_add_str(opoe, - POETT_SERVICE, - sep->se_name); - } + if (sep->se_name[0] == '\0' || + (sep->se_flags & SEF_NOWILD) || + !allow_service(sep, pap)) + continue; + *srvp = (void *)sep; + /* + * RFC requires that PADO includes the + * wildcard service request in response + * to PADI. + */ + if (ispadi && nsvcs == 0 && + !(glob_svc.se_flags & SEF_NOWILD)) + (void) poe_tag_copy(opoe, tagp); + nsvcs++; + (void) poe_add_str(opoe, POETT_SERVICE, + sep->se_name); + /* If PADR, then one is enough */ + if (!ispadi) + break; } + /* Just for generating error messages */ + if (nsvcs == 0) + (void) poe_tag_copy(opoe, tagp); } else { + /* + * Clients's requested service must appear in + * reply. + */ + (void) poe_tag_copy(opoe, tagp); + /* Requested specific service; find it. */ cp = (char *)POET_DATA(tagp); while (sepp < seppe) { sep = *sepp++; if (strlen(sep->se_name) == tlen && strncasecmp(sep->se_name, cp, - tlen) == 0) { + tlen) == 0) { if (allow_service(sep, pap)) { nsvcs++; *srvp = (void *)sep; @@ -2276,7 +2283,7 @@ dump_configuration(FILE *fp) "Global debug level %d, log to %s; current level %d\n", glob_svc.se_debug, ((glob_svc.se_log == NULL || *glob_svc.se_log == '\0') ? - "syslog" : glob_svc.se_log), + "syslog" : glob_svc.se_log), log_level); if (cur_options == NULL) { (void) fprintf(fp, "No current configuration.\n"); diff --git a/usr/src/cmd/cmd-inet/usr.lib/pppoe/pppoec.c b/usr/src/cmd/cmd-inet/usr.lib/pppoe/pppoec.c index f306b718e4..30f9744d26 100644 --- a/usr/src/cmd/cmd-inet/usr.lib/pppoe/pppoec.c +++ b/usr/src/cmd/cmd-inet/usr.lib/pppoe/pppoec.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -22,12 +21,10 @@ /* * PPPoE Client-mode "chat" utility for use with Solaris PPP 4.0. * - * Copyright 2000-2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -623,7 +620,7 @@ send_padi(int localid) ppptun_atype destaddr; poep = poe_mkheader(pkt_output, POECODE_PADI, 0); - (void) poe_add_str(poep, POETT_SERVICE, ""); + (void) poe_add_str(poep, POETT_SERVICE, service); (void) poe_add_long(poep, POETT_UNIQ, localid); (void) memset(&destaddr, '\0', sizeof (destaddr)); (void) memcpy(destaddr.pta_pppoe.ptma_mac, ether_bcast, @@ -802,7 +799,7 @@ save_message(const poemsg_t *pmsg) char *cp; newmsg = (poemsg_t *)malloc(sizeof (*pmsg) + pmsg->poemsg_len + - strlen(pmsg->poemsg_iname) + 1); + strlen(pmsg->poemsg_iname) + 1); if (newmsg != NULL) { newmsg->poemsg_next = NULL; newmsg->poemsg_data = (const poep_t *)(newmsg + 1); @@ -868,7 +865,7 @@ send_padr(poesm_t *psm, const poemsg_t *pado) } if (service[0] == '\0' || (tlen == strlen(service) && - memcmp(service, POET_DATA(tagp), tlen) == 0)) { + memcmp(service, POET_DATA(tagp), tlen) == 0)) { (void) poe_tag_copy(poep, tagp); hassvc = B_TRUE; } @@ -895,7 +892,7 @@ send_padr(poesm_t *psm, const poemsg_t *pado) tagp = POET_NEXT(tagp); } if (!hassvc) { - if (haswild) + if (haswild && service[0] == '\0') (void) poe_add_str(poep, POETT_SERVICE, ""); else return (1); @@ -1313,7 +1310,7 @@ get_sequence(const poemsg_t *pmsg) * events occur. */ static int -use_server(poemsg_t *pado) +use_server(poemsg_t *pado, const ppptun_atype *pap) { struct server_filter *sfp; const uchar_t *sndp; @@ -1321,6 +1318,7 @@ use_server(poemsg_t *pado) const uchar_t *maskp; int i; int passmatched; + int tlen; const uint8_t *tagp; int ttyp; @@ -1331,12 +1329,29 @@ use_server(poemsg_t *pado) ttyp = POETT_END; while (poe_tagcheck(pado->poemsg_data, pado->poemsg_len, tagp)) { ttyp = POET_GET_TYPE(tagp); - if (ttyp == POETT_END || ttyp == POETT_SERVICE) + if (ttyp == POETT_END) break; + if (ttyp == POETT_SERVICE) { + /* + * If the user has requested a specific service, then + * this selection is exclusive. We never use the + * wildcard for this. + */ + tlen = POET_GET_LENG(tagp); + if (service[0] == '\0' || (strlen(service) == tlen && + memcmp(service, POET_DATA(tagp), tlen) == 0)) + break; + /* just in case we run off the end */ + ttyp = POETT_END; + } tagp = POET_NEXT(tagp); } - if (ttyp != POETT_SERVICE) + if (ttyp != POETT_SERVICE) { + if (verbose) + logerr("%s: Discard unusable offer from %s; service " + "'%s' not seen\n", myname, ehost(pap), service); return (-1); + } passmatched = 0; for (sfp = sfhead; sfp != NULL; sfp = sfp->sf_next) { @@ -1365,8 +1380,12 @@ use_server(poemsg_t *pado) if (!sfp->sf_isexcept) return (PCSME_RPADOP); } - if (onlyflag) + if (onlyflag) { + if (verbose) + logerr("%s: Discard unusable offer from %s; server not " + "matched\n", myname, ehost(pap)); return (-1); + } return (PCSME_RPADO); } @@ -1480,9 +1499,8 @@ find_server(int localid) if ((poep->poep_code == POECODE_PADT || poep->poep_code == POECODE_PADS) && (psm.poesm_firstoff == NULL || - memcmp(&psm.poesm_firstoff->poemsg_sender, - &pmsg.poemsg_sender, - sizeof (pmsg.poemsg_sender)) != 0)) { + memcmp(&psm.poesm_firstoff->poemsg_sender, + &pmsg.poemsg_sender, sizeof (pmsg.poemsg_sender)) != 0)) { if (verbose) { logerr("%s: Unexpected peer %s", myname, ehost(&ptc->ptc_address)); @@ -1534,7 +1552,7 @@ find_server(int localid) if (retv != 0) break; /* Ignore offers from servers we don't want. */ - if ((retv = use_server(&pmsg)) < 0) + if ((retv = use_server(&pmsg, &ptc->ptc_address)) < 0) break; /* Dispatch either RPADO or RAPDO+ event. */ handle_event(&psm, retv, &pmsg); diff --git a/usr/src/cmd/cmd-inet/usr.lib/pppoe/pppoed.c b/usr/src/cmd/cmd-inet/usr.lib/pppoe/pppoed.c index 294a04d824..a9479ab178 100644 --- a/usr/src/cmd/cmd-inet/usr.lib/pppoe/pppoed.c +++ b/usr/src/cmd/cmd-inet/usr.lib/pppoe/pppoed.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -22,12 +21,10 @@ /* * PPPoE Server-mode daemon for use with Solaris PPP 4.0. * - * Copyright (c) 2000-2001 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> @@ -305,6 +302,11 @@ handle_input(uint32_t *ctrlbuf, int ctrllen, uint32_t *databuf, int datalen) logdbg("%s unplumbed", ptc->ptc_name); return; + case PTCA_BADCTRL: + logwarn("bad control data on %s for session %u", ptc->ptc_name, + ptc->ptc_rsessid); + return; + default: logdbg("unexpected code %d from driver", ptc->ptc_action); return; diff --git a/usr/src/cmd/cmd-inet/usr.sbin/sppptun/sppptun.c b/usr/src/cmd/cmd-inet/usr.sbin/sppptun/sppptun.c index 87dd053ca5..70292b1cbc 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/sppptun/sppptun.c +++ b/usr/src/cmd/cmd-inet/usr.sbin/sppptun/sppptun.c @@ -22,12 +22,10 @@ * sppptun.c - Solaris STREAMS PPP multiplexing tunnel driver * installer. * - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -55,6 +53,7 @@ struct attach_data { ppptun_lname appstr; /* String to append to interface name (PPA) */ ppptun_atype localaddr; /* Local interface address */ uint_t locallen; /* Length of local address */ + uint_t sap; /* SAP for PPPoE */ }; /* Per-protocol plumbing data */ @@ -75,7 +74,7 @@ static void usage(void) { (void) fprintf(stderr, gettext( - "Usage:\n\t%s plumb [<protocol> <device>]\n" + "Usage:\n\t%s plumb [-s <sap>] [<protocol> <device>]\n" "\t%s unplumb <interface-name>\n" "\t%s query\n"), myname, myname, myname); exit(1); @@ -85,11 +84,11 @@ usage(void) * General DLPI function. This is called indirectly through * the protos structure for the selected lower stream protocol. */ +/* ARGSUSED */ static int sppp_dlpi(struct protos *prot, char *linkname, struct attach_data *adata) { int retv; - uint_t ppa; dlpi_handle_t dh; if (verbose) @@ -102,10 +101,11 @@ sppp_dlpi(struct protos *prot, char *linkname, struct attach_data *adata) if (verbose) { (void) printf(gettext("binding to Ethertype %04X\n"), - prot->protval); + adata->sap); } - if ((retv = dlpi_bind(dh, prot->protval, NULL)) != DLPI_SUCCESS) { - (void) fprintf(stderr, gettext("%s: failed binding on %s: %s"), + if ((retv = dlpi_bind(dh, adata->sap, NULL)) != DLPI_SUCCESS) { + (void) fprintf(stderr, + gettext("%s: failed binding on %s: %s\n"), myname, linkname, dlpi_strerror(retv)); dlpi_close(dh); return (-1); @@ -115,22 +115,21 @@ sppp_dlpi(struct protos *prot, char *linkname, struct attach_data *adata) if ((retv = dlpi_get_physaddr(dh, DL_CURR_PHYS_ADDR, &adata->localaddr, &adata->locallen)) != DLPI_SUCCESS) { (void) fprintf(stderr, gettext("%s: failed getting physical" - " address on %s: %s"), myname, linkname, + " address on %s: %s\n"), myname, linkname, dlpi_strerror(retv)); dlpi_close(dh); return (-1); } - /* Store ppa to append to interface name. */ - if ((retv = dlpi_parselink(linkname, NULL, &ppa)) != DLPI_SUCCESS) { - (void) fprintf(stderr, gettext("%s: failed parsing linkname on" - " %s: %s"), myname, linkname, dlpi_strerror(retv)); + if (strlcpy(adata->appstr, linkname, sizeof (adata->appstr)) >= + sizeof (adata->appstr)) { + (void) fprintf(stderr, + gettext("%s: interface name too long: %s\n"), + myname, linkname); dlpi_close(dh); return (-1); } - (void) snprintf(adata->appstr, sizeof (adata->appstr), "%d", ppa); - return (dlpi_fd(dh)); } @@ -184,11 +183,12 @@ strioctl(int fd, int cmd, void *ptr, int ilen, int olen, const char *iocname) static int plumb_it(int argc, char **argv) { - int devfd, muxfd, muxid; + int opt, devfd, muxfd, muxid; struct ppptun_info pti; char *cp, *linkname; struct protos *prot; struct attach_data adata; + uint_t sap = 0; /* If no protocol requested, then list known protocols. */ if (optind == argc) { @@ -198,6 +198,17 @@ plumb_it(int argc, char **argv) return (0); } + /* Parse plumbing flags */ + while ((opt = getopt(argc, argv, "s:")) != EOF) { + switch (opt) { + case 's': + sap = strtoul(optarg, NULL, 16); + break; + default: + usage(); + } + } + /* If missing protocol or device, then abort. */ if (optind != argc-2) usage(); @@ -213,6 +224,8 @@ plumb_it(int argc, char **argv) return (1); } + adata.sap = sap == 0 ? prot->protval : sap; + /* Get interface. */ linkname = argv[optind]; /* Call per-protocol attach routine to open device */ @@ -238,21 +251,14 @@ plumb_it(int argc, char **argv) return (1); } - /* Get the name of the newly-created lower stream. */ - if (verbose) - (void) printf(gettext("getting new interface name\n")); - if (strioctl(devfd, PPPTUN_GNAME, pti.pti_name, 0, - sizeof (pti.pti_name), "PPPTUN_GNAME") < 0) - return (1); - if (verbose) - (void) printf(gettext("got interface %s\n"), pti.pti_name); - /* Convert stream name to protocol-specific name. */ - if ((cp = strchr(pti.pti_name, ':')) != NULL) - *cp = '\0'; - (void) snprintf(pti.pti_name+strlen(pti.pti_name), - sizeof (pti.pti_name)-strlen(pti.pti_name), "%s:%s", adata.appstr, - prot->name); + if (snprintf(pti.pti_name, sizeof (pti.pti_name), "%s:%s", + adata.appstr, prot->name) >= sizeof (pti.pti_name)) { + (void) fprintf(stderr, + gettext("%s: stream name too long: %s:%s\n"), + myname, adata.appstr, prot->name); + return (1); + } /* Change the lower stream name. */ if (verbose) @@ -276,6 +282,15 @@ plumb_it(int argc, char **argv) 0, "PPPTUN_LCLADDR") < 0) return (1); + /* + * And set the SAP value. + */ + if (verbose) + (void) printf(gettext("send down SAP %x\n"), adata.sap); + if (strioctl(devfd, PPPTUN_SSAP, &adata.sap, sizeof (adata.sap), 0, + "PPPTUN_SSAP") < 0) + return (1); + /* Link the lower stream under the tunnel device. */ if (verbose) (void) printf(gettext("doing I_PLINK\n")); diff --git a/usr/src/cmd/mdb/common/modules/sppp/sppp.c b/usr/src/cmd/mdb/common/modules/sppp/sppp.c index 83cbe031b9..5314d94b2c 100644 --- a/usr/src/cmd/mdb/common/modules/sppp/sppp.c +++ b/usr/src/cmd/mdb/common/modules/sppp/sppp.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,12 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/stropts.h> #include <sys/stream.h> @@ -94,12 +91,12 @@ sps_format(uintptr_t addr, const spppstr_t *sps, uint_t *qfmt) if (*qfmt) mdb_printf("%?p ", sps->sps_rq); if (sps->sps_ppa == NULL) { - mdb_printf("unset "); + mdb_printf("? unset "); } else if (mdb_vread(&ppa, sizeof (ppa), (uintptr_t)sps->sps_ppa) == -1) { - mdb_printf("?%p ", sps->sps_ppa); + mdb_printf("? ?%p ", sps->sps_ppa); } else { - mdb_printf("sppp%-5d ", ppa.ppa_ppa_id); + mdb_printf("%-6d sppp%-5d ", ppa.ppa_zoneid, ppa.ppa_ppa_id); } if (IS_SPS_CONTROL(sps)) { mdb_printf("Control\n"); @@ -124,7 +121,7 @@ sps_format(uintptr_t addr, const spppstr_t *sps, uint_t *qfmt) if (illaddr != 0) { if (mdb_vread(&ill, sizeof (ill), illaddr) == -1 || mdb_vread(&ipif, sizeof (ipif), - (uintptr_t)ill.ill_ipif) == -1) { + (uintptr_t)ill.ill_ipif) == -1) { illaddr = 0; } } @@ -186,11 +183,11 @@ sppp(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) { if (qfmt) { - mdb_printf("%<u>%?s %?s %9s %s%</u>\n", "Address", - "RecvQ", "Interface", "Type"); + mdb_printf("%<u>%?s %?s %-6s %-9s %s%</u>\n", "Address", + "RecvQ", "ZoneID", "Interface", "Type"); } else { - mdb_printf("%<u>%?s %9s %s%</u>\n", "Address", - "Interface", "Type"); + mdb_printf("%<u>%?s %-6s %-9s %s%</u>\n", "Address", + "ZoneID", "Interface", "Type"); } } @@ -240,8 +237,8 @@ sppa_walk_step(mdb_walk_state_t *wsp) static int ppa_format(uintptr_t addr, const sppa_t *ppa, uint_t *qfmt) { - mdb_printf("%?p sppp%-5d %?p %?p\n", addr, ppa->ppa_ppa_id, - ppa->ppa_ctl, ppa->ppa_lower_wq); + mdb_printf("%?p %-6d sppp%-5d %?p %?p\n", addr, ppa->ppa_zoneid, + ppa->ppa_ppa_id, ppa->ppa_ctl, ppa->ppa_lower_wq); return (WALK_NEXT); } @@ -254,8 +251,8 @@ sppa(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) sppa_t ppa; if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) { - mdb_printf("%<u>%?s %9s %?s %?s%</u>\n", "Address", - "Interface", "Control", "LowerQ"); + mdb_printf("%<u>%?s %-6s %-9s %?s %?s%</u>\n", "Address", + "ZoneID", "Interface", "Control", "LowerQ"); } if (flags & DCMD_ADDRSPEC) { @@ -417,7 +414,8 @@ tuncl_walk_step(mdb_walk_state_t *wsp) static int tuncl_format(uintptr_t addr, const tuncl_t *tcl, uint_t *qfmt) { - mdb_printf("%?p %?p %?p", addr, tcl->tcl_data_tll, tcl->tcl_ctrl_tll); + mdb_printf("%?p %-6d %?p %?p", addr, tcl->tcl_zoneid, tcl->tcl_data_tll, + tcl->tcl_ctrl_tll); mdb_printf(" %-2d %04X %04X ", tcl->tcl_style, tcl->tcl_lsessid, tcl->tcl_rsessid); if (tcl->tcl_flags & TCLF_DAEMON) { @@ -437,8 +435,8 @@ tuncl(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) tuncl_t tcl; if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) { - mdb_printf("%<u>%?s %?s %?s Ty LSes RSes %s%</u>\n", "Address", - "Data", "Control", "Interface"); + mdb_printf("%<u>%?s %-6s %?s %?s Ty LSes RSes %s%</u>\n", + "Address", "ZoneID", "Data", "Control", "Interface"); } if (flags & DCMD_ADDRSPEC) { @@ -536,7 +534,8 @@ tunll_walk_step(mdb_walk_state_t *wsp) static int tunll_format(uintptr_t addr, const tunll_t *tll, uint_t *qfmt) { - mdb_printf("%?p %-14s %?p", addr, tll->tll_name, tll->tll_defcl); + mdb_printf("%?p %-6d %-14s %?p", addr, tll->tll_zoneid, tll->tll_name, + tll->tll_defcl); if (tll->tll_style == PTS_PPPOE) { mdb_printf(" %x:%x:%x:%x:%x:%x", tll->tll_lcladdr.pta_pppoe.ptma_mac[0], @@ -559,8 +558,8 @@ tunll(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv) tunll_t tll; if ((flags & DCMD_LOOPFIRST) || !(flags & DCMD_LOOP)) { - mdb_printf("%<u>%?s %-14s %?s %s%</u>\n", "Address", - "Interface Name", "Daemon", "Local Address"); + mdb_printf("%<u>%?s %-6s %-14s %?s %s%</u>\n", "Address", + "ZoneID", "Interface Name", "Daemon", "Local Address"); } if (flags & DCMD_ADDRSPEC) { diff --git a/usr/src/lib/brand/native/zone/config.xml b/usr/src/lib/brand/native/zone/config.xml index abf94577d2..9ede6178dc 100644 --- a/usr/src/lib/brand/native/zone/config.xml +++ b/usr/src/lib/brand/native/zone/config.xml @@ -80,6 +80,7 @@ <privilege set="default" name="sys_mount" /> <privilege set="default" name="sys_nfs" /> <privilege set="default" name="sys_resource" /> + <privilege set="default" name="sys_ppp_config" ip-type="exclusive" /> <privilege set="prohibited" name="dtrace_kernel" /> <privilege set="prohibited" name="proc_zone" /> @@ -92,6 +93,7 @@ <privilege set="prohibited" name="sys_suser_compat" /> <privilege set="prohibited" name="xvm_control" /> <privilege set="prohibited" name="virt_manage" /> + <privilege set="prohibited" name="sys_ppp_config" ip-type="shared" /> <privilege set="required" name="proc_exec" /> <privilege set="required" name="proc_fork" /> diff --git a/usr/src/lib/brand/native/zone/platform.xml b/usr/src/lib/brand/native/zone/platform.xml index 69e86cefd2..4970516328 100644 --- a/usr/src/lib/brand/native/zone/platform.xml +++ b/usr/src/lib/brand/native/zone/platform.xml @@ -112,6 +112,8 @@ <device match="sctp" ip-type="exclusive" /> <device match="sctp6" ip-type="exclusive" /> <device match="spdsock" ip-type="exclusive" /> + <device match="sppp" ip-type="exclusive" /> + <device match="sppptun" ip-type="exclusive" /> <!-- Renamed devices to create under /dev --> <device match="zcons/%z/zoneconsole" name="zconsole" /> diff --git a/usr/src/lib/brand/sn1/zone/config.xml b/usr/src/lib/brand/sn1/zone/config.xml index 1d559dd2f6..c32690afcf 100644 --- a/usr/src/lib/brand/sn1/zone/config.xml +++ b/usr/src/lib/brand/sn1/zone/config.xml @@ -20,7 +20,7 @@ CDDL HEADER END - Copyright 2008 Sun Microsystems, Inc. All rights reserved. + Copyright 2009 Sun Microsystems, Inc. All rights reserved. Use is subject to license terms. DO NOT EDIT THIS FILE. @@ -74,6 +74,7 @@ <privilege set="default" name="sys_mount" /> <privilege set="default" name="sys_nfs" /> <privilege set="default" name="sys_resource" /> + <privilege set="default" name="sys_ppp_config" ip-type="exclusive" /> <privilege set="prohibited" name="dtrace_kernel" /> <privilege set="prohibited" name="proc_zone" /> @@ -86,6 +87,7 @@ <privilege set="prohibited" name="sys_suser_compat" /> <privilege set="prohibited" name="xvm_control" /> <privilege set="prohibited" name="virt_manage" /> + <privilege set="prohibited" name="sys_ppp_config" ip-type="shared" /> <privilege set="required" name="proc_exec" /> <privilege set="required" name="proc_fork" /> diff --git a/usr/src/lib/brand/sn1/zone/platform.xml b/usr/src/lib/brand/sn1/zone/platform.xml index b3bb0d7962..2d5fb2eea0 100644 --- a/usr/src/lib/brand/sn1/zone/platform.xml +++ b/usr/src/lib/brand/sn1/zone/platform.xml @@ -116,6 +116,8 @@ <device match="sctp" ip-type="exclusive" /> <device match="sctp6" ip-type="exclusive" /> <device match="spdsock" ip-type="exclusive" /> + <device match="sppp" ip-type="exclusive" /> + <device match="sppptun" ip-type="exclusive" /> <!-- Renamed devices to create under /dev --> <device match="zcons/%z/zoneconsole" name="zconsole" /> diff --git a/usr/src/pkgdefs/SUNWpppdr/pkginfo.tmpl b/usr/src/pkgdefs/SUNWpppdr/pkginfo.tmpl index 7db5ebf433..fe4dbe5f95 100644 --- a/usr/src/pkgdefs/SUNWpppdr/pkginfo.tmpl +++ b/usr/src/pkgdefs/SUNWpppdr/pkginfo.tmpl @@ -1,9 +1,7 @@ # -# Copyright 2006 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# # # This required package information file describes characteristics of the @@ -27,7 +25,7 @@ CLASSES="none preserve initd" BASEDIR=/ SUNW_PKGVERS="1.0" SUNW_PKG_ALLZONES="true" -SUNW_PKG_HOLLOW="true" +SUNW_PKG_HOLLOW="false" SUNW_PKG_THISZONE="false" #VSTOCK="<reserved by Release Engineering for package part #>" #ISTATES="<developer defined>" diff --git a/usr/src/pkgdefs/SUNWpppdr/prototype_com b/usr/src/pkgdefs/SUNWpppdr/prototype_com index 7dda3f754c..133db85642 100644 --- a/usr/src/pkgdefs/SUNWpppdr/prototype_com +++ b/usr/src/pkgdefs/SUNWpppdr/prototype_com @@ -1,9 +1,7 @@ # -# Copyright 2000, 2002 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -#ident "%Z%%M% %I% %E% SMI" -# # This required package information file contains a list of package contents. # The 'pkgmk' command uses this file to identify the contents of a package # and their location on the development machine when building the package. @@ -36,6 +34,7 @@ e preserve etc/ppp/pap-secrets 0600 root sys e preserve etc/ppp/chap-secrets 0600 root sys d none etc/ppp/peers 0755 root sys f none etc/ppp/peers/myisp.tmpl 0644 root sys +d none etc/ppp/plugins 0755 root sys d none etc/init.d 755 root sys e initd etc/init.d/pppd 744 root sys d none etc/rc0.d 755 root sys diff --git a/usr/src/pkgdefs/SUNWpppdt/preremove b/usr/src/pkgdefs/SUNWpppdt/preremove index 015981b248..3c8fe611a8 100644 --- a/usr/src/pkgdefs/SUNWpppdt/preremove +++ b/usr/src/pkgdefs/SUNWpppdt/preremove @@ -3,9 +3,8 @@ # CDDL HEADER START # # The contents of this file are subject to the terms of the -# Common Development and Distribution License, Version 1.0 only -# (the "License"). You may not use this file except in compliance -# with the License. +# Common Development and Distribution License (the "License"). +# You may not use this file except in compliance with the License. # # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE # or http://www.opensolaris.org/os/licensing. @@ -21,10 +20,8 @@ # CDDL HEADER END # # -#ident "%Z%%M% %I% %E% SMI" -# -# Copyright (c) 2000-2001 by Sun Microsystems, Inc. -# All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. +# Use is subject to license terms. # # Remove Solaris PPP 4.0 tunneling support # @@ -32,8 +29,7 @@ PATH="/usr/bin:/usr/sbin:${PATH}" export PATH -if [ -x /usr/sbin/sppptun ] -then +if [ "${BASEDIR:=/}" = / -a -x /usr/sbin/sppptun -a -c /dev/sppptun ]; then for dev in `sppptun query` do sppptun unplumb $dev diff --git a/usr/src/pkgdefs/SUNWpppdu/depend b/usr/src/pkgdefs/SUNWpppdu/depend index 999d23cc83..ff3b22f462 100644 --- a/usr/src/pkgdefs/SUNWpppdu/depend +++ b/usr/src/pkgdefs/SUNWpppdu/depend @@ -1,9 +1,7 @@ # -# Copyright 2003 Sun Microsystems, Inc. All rights reserved. +# Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # -# ident "%Z%%M% %I% %E% SMI" -# # This package information file defines software dependencies associated # with the pkg. You can define three types of pkg dependencies with this file: # P indicates a prerequisite for installation @@ -31,3 +29,4 @@ P SUNWcsu Core Solaris, (Usr) P SUNWcsd Core Solaris Devices P SUNWcsl Core Solaris Libraries P SUNWpppd Solaris PPP Device Drivers +P SUNWperl584core Perl 5.8.4 (core) diff --git a/usr/src/uts/common/io/ppp/sppp/sppp.c b/usr/src/uts/common/io/ppp/sppp/sppp.c index 147cd04a20..c810a37dec 100644 --- a/usr/src/uts/common/io/ppp/sppp/sppp.c +++ b/usr/src/uts/common/io/ppp/sppp/sppp.c @@ -1,7 +1,7 @@ /* * sppp.c - Solaris STREAMS PPP multiplexing pseudo-driver * - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * Permission to use, copy, modify, and distribute this software and its @@ -65,6 +65,7 @@ #include <sys/strsun.h> #include <sys/ethernet.h> #include <sys/policy.h> +#include <sys/zone.h> #include <net/ppp_defs.h> #include <net/pppio.h> #include "sppp.h" @@ -182,6 +183,7 @@ sppp_open(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *credp) sps->sps_sap = -1; /* no sap bound to stream */ sps->sps_dlstate = DL_UNATTACHED; /* dlpi state is unattached */ sps->sps_npmode = NPMODE_DROP; /* drop all packets initially */ + sps->sps_zoneid = crgetzoneid(credp); q->q_ptr = WR(q)->q_ptr = (caddr_t)sps; /* * We explicitly disable the automatic queue scheduling for the @@ -229,7 +231,7 @@ sppp_free_ppa(sppa_t *ppa) * Create a new PPA. Caller must be exclusive on outer perimeter. */ sppa_t * -sppp_create_ppa(uint32_t ppa_id) +sppp_create_ppa(uint32_t ppa_id, zoneid_t zoneid) { sppa_t *ppa; sppa_t *curppa; @@ -267,6 +269,7 @@ sppp_create_ppa(uint32_t ppa_id) } ppa->ppa_kstats = ksp; /* chain kstat structure */ ppa->ppa_ppa_id = ppa_id; /* record ppa id */ + ppa->ppa_zoneid = zoneid; /* zone that owns this PPA */ ppa->ppa_mtu = PPP_MAXMTU; /* 65535-(PPP_HDRLEN+PPP_FCSLEN) */ ppa->ppa_mru = PPP_MAXMRU; /* 65000 */ @@ -779,7 +782,7 @@ sppp_uwput(queue_t *q, mblk_t *mp) break; /* 32 bit interface gone */ default: if (iop->ioc_cr == NULL || - secpolicy_net_config(iop->ioc_cr, B_FALSE) != 0) { + secpolicy_ppp_config(iop->ioc_cr) != 0) { error = EPERM; break; } else if ((ppa == NULL) || @@ -1051,6 +1054,11 @@ sppp_inner_ioctl(queue_t *q, mblk_t *mp) error = ENOENT; break; } + if (iop->ioc_cr == NULL || + ppa->ppa_zoneid != crgetzoneid(iop->ioc_cr)) { + error = EPERM; + break; + } /* * Preallocate the hangup message so that we're always * able to send this upstream in the event of a @@ -1084,7 +1092,7 @@ sppp_inner_ioctl(queue_t *q, mblk_t *mp) case PPPIO_BLOCKNP: case PPPIO_UNBLOCKNP: if (iop->ioc_cr == NULL || - secpolicy_net_config(iop->ioc_cr, B_FALSE) != 0) { + secpolicy_ppp_config(iop->ioc_cr) != 0) { error = EPERM; break; } @@ -1116,7 +1124,7 @@ sppp_inner_ioctl(queue_t *q, mblk_t *mp) break; case PPPIO_DEBUG: if (iop->ioc_cr == NULL || - secpolicy_net_config(iop->ioc_cr, B_FALSE) != 0) { + secpolicy_ppp_config(iop->ioc_cr) != 0) { error = EPERM; break; } else if (iop->ioc_count != sizeof (uint32_t)) { @@ -1293,7 +1301,7 @@ sppp_inner_ioctl(queue_t *q, mblk_t *mp) static void sppp_outer_ioctl(queue_t *q, mblk_t *mp) { - spppstr_t *sps; + spppstr_t *sps = q->q_ptr; spppstr_t *nextsib; queue_t *lwq; sppa_t *ppa; @@ -1302,9 +1310,7 @@ sppp_outer_ioctl(queue_t *q, mblk_t *mp) int count = 0; uint32_t ppa_id; mblk_t *nmp; - - ASSERT(q != NULL && q->q_ptr != NULL); - ASSERT(mp != NULL && mp->b_rptr != NULL); + zoneid_t zoneid; sps = (spppstr_t *)q->q_ptr; ppa = sps->sps_ppa; @@ -1340,6 +1346,14 @@ sppp_outer_ioctl(queue_t *q, mblk_t *mp) qenable(WR(nextsib->sps_rq)); } } + + /* + * Also unblock (run once) our lower read-side queue. This is + * where packets received while doing the I_LINK may be + * languishing; see sppp_lrsrv. + */ + qenable(RD(lwq)); + /* * Send useful information down to the modules which are now * linked below this driver (for this particular ppa). Only @@ -1412,7 +1426,7 @@ sppp_outer_ioctl(queue_t *q, mblk_t *mp) * a control stream. */ if (iop->ioc_cr == NULL || - secpolicy_net_config(iop->ioc_cr, B_FALSE) != 0) { + secpolicy_ppp_config(iop->ioc_cr) != 0) { error = EPERM; break; } else if (IS_SPS_CONTROL(sps) || IS_SPS_PIOATTACH(sps) || @@ -1440,9 +1454,11 @@ sppp_outer_ioctl(queue_t *q, mblk_t *mp) */ if (ppa_id == (uint32_t)-1) ppa_id = 0; + zoneid = crgetzoneid(iop->ioc_cr); for (ppa = ppa_list; ppa != NULL; ppa = ppa->ppa_nextppa) { if (ppa_id == (uint32_t)-2) { - if (ppa->ppa_ctl == NULL) + if (ppa->ppa_ctl == NULL && + ppa->ppa_zoneid == zoneid) break; } else { if (ppa_id < ppa->ppa_ppa_id) @@ -1459,7 +1475,7 @@ sppp_outer_ioctl(queue_t *q, mblk_t *mp) /* Clear timestamp and lastmod flags */ ppa->ppa_flags = 0; } else { - ppa = sppp_create_ppa(ppa_id); + ppa = sppp_create_ppa(ppa_id, zoneid); if (ppa == NULL) { error = ENOMEM; break; @@ -1804,6 +1820,26 @@ sppp_lrput(queue_t *q, mblk_t *mp) } /* + * sppp_lrsrv() + * + * MT-Perimeters: + * exclusive inner, shared outer. + * + * Description: + * Lower read-side service procedure. This is run once after the I_LINK + * occurs in order to clean up any packets that came in while we were + * transferring in the lower stream. Otherwise, it's not used. + */ +void +sppp_lrsrv(queue_t *q) +{ + mblk_t *mp; + + while ((mp = getq(q)) != NULL) + sppp_lrput(q, mp); +} + +/* * sppp_recv_nondata() * * MT-Perimeters: diff --git a/usr/src/uts/common/io/ppp/sppp/sppp.h b/usr/src/uts/common/io/ppp/sppp/sppp.h index 2daa8aceac..d3056a4fd2 100644 --- a/usr/src/uts/common/io/ppp/sppp/sppp.h +++ b/usr/src/uts/common/io/ppp/sppp/sppp.h @@ -1,7 +1,7 @@ /* * sppp.h - Solaris STREAMS PPP multiplexing pseudo-driver definitions * - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * Permission to use, copy, modify, and distribute this software and its @@ -82,7 +82,7 @@ extern "C" { */ struct sppp_dlpi_pinfo_t { int pi_minlen; /* minimum primitive length */ - uint_t pi_state; /* acceptable starting state */ + int pi_state; /* acceptable starting state */ int (*pi_funcp)(); /* function() to call */ }; @@ -204,6 +204,8 @@ typedef struct spppstr { */ t_uscalar_t sps_dlstate; /* current DLPI state */ mblk_t *sps_hangup; /* preallocated M_HANGUP message */ + + zoneid_t sps_zoneid; /* zone in which we were opened */ } spppstr_t; /* @@ -322,6 +324,8 @@ typedef struct sppa { kmutex_t ppa_npmutex; /* protects the 2 fields below */ uint32_t ppa_npflag; /* network protocols blocked */ uint32_t ppa_holdpkts[3]; /* # of packets blocked per np */ + + zoneid_t ppa_zoneid; /* zone where PPA is in use */ } sppa_t; /* bit position (in ppa_npflag) for each ppp_protocol that can be blocked */ @@ -360,6 +364,7 @@ extern mblk_t *sppp_dladdud(spppstr_t *, mblk_t *, t_scalar_t, boolean_t); extern void sppp_dlpi_pinfoinit(void); extern void sppp_dlprsendup(spppstr_t *, mblk_t *, t_scalar_t, boolean_t); extern void sppp_lrput(queue_t *, mblk_t *); +extern void sppp_lrsrv(queue_t *); extern void sppp_lwsrv(queue_t *); extern int sppp_mproto(queue_t *, mblk_t *, spppstr_t *); extern int sppp_open(queue_t *, dev_t *, int, int, cred_t *); @@ -367,7 +372,7 @@ extern void sppp_uwput(queue_t *, mblk_t *); extern void sppp_uwsrv(queue_t *); extern void sppp_remove_ppa(spppstr_t *sps); extern sppa_t *sppp_find_ppa(uint32_t ppa_id); -extern sppa_t *sppp_create_ppa(uint32_t ppa_id); +extern sppa_t *sppp_create_ppa(uint32_t ppa_id, zoneid_t zoneid); #ifdef __cplusplus } diff --git a/usr/src/uts/common/io/ppp/sppp/sppp_dlpi.c b/usr/src/uts/common/io/ppp/sppp/sppp_dlpi.c index 9acaa6323a..9905a5dbda 100644 --- a/usr/src/uts/common/io/ppp/sppp/sppp_dlpi.c +++ b/usr/src/uts/common/io/ppp/sppp/sppp_dlpi.c @@ -1,7 +1,7 @@ /* * sppp_dlpi.c - Solaris STREAMS PPP multiplexing pseudo-driver DLPI handlers * - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * Permission to use, copy, modify, and distribute this software and its @@ -45,7 +45,6 @@ * for improved performance and scalability. */ -#pragma ident "%Z%%M% %I% %E% SMI" #define RCSID "$Id: sppp_dlpi.c,v 1.0 2000/05/08 01:10:12 masputra Exp $" #include <sys/types.h> @@ -60,6 +59,7 @@ #include <sys/dlpi.h> #include <sys/ddi.h> #include <sys/kstat.h> +#include <sys/strsubr.h> #include <sys/strsun.h> #include <sys/ethernet.h> #include <net/ppp_defs.h> @@ -269,7 +269,7 @@ sppp_dlpi_pinfoinit(void) dl_pinfo[DL_UNBIND_REQ].pi_funcp = sppp_dlunbindreq; dl_pinfo[DL_INFO_REQ].pi_minlen = sizeof (dl_info_req_t); - dl_pinfo[DL_INFO_REQ].pi_state = 0; /* special handling */ + dl_pinfo[DL_INFO_REQ].pi_state = -1; /* special handling */ dl_pinfo[DL_INFO_REQ].pi_funcp = sppp_dlinforeq; dl_pinfo[DL_UNITDATA_REQ].pi_minlen = sizeof (dl_unitdata_req_t); @@ -277,15 +277,15 @@ sppp_dlpi_pinfoinit(void) dl_pinfo[DL_UNITDATA_REQ].pi_funcp = sppp_dlunitdatareq; dl_pinfo[DL_PROMISCON_REQ].pi_minlen = sizeof (dl_promiscon_req_t); - dl_pinfo[DL_PROMISCON_REQ].pi_state = 0; /* special handling */ + dl_pinfo[DL_PROMISCON_REQ].pi_state = -1; /* special handling */ dl_pinfo[DL_PROMISCON_REQ].pi_funcp = sppp_dlpromisconreq; dl_pinfo[DL_PROMISCOFF_REQ].pi_minlen = sizeof (dl_promiscoff_req_t); - dl_pinfo[DL_PROMISCOFF_REQ].pi_state = 0; /* special handling */ + dl_pinfo[DL_PROMISCOFF_REQ].pi_state = -1; /* special handling */ dl_pinfo[DL_PROMISCOFF_REQ].pi_funcp = sppp_dlpromiscoffreq; dl_pinfo[DL_PHYS_ADDR_REQ].pi_minlen = sizeof (dl_phys_addr_req_t); - dl_pinfo[DL_PHYS_ADDR_REQ].pi_state = 0; /* special handling */ + dl_pinfo[DL_PHYS_ADDR_REQ].pi_state = -1; /* special handling */ dl_pinfo[DL_PHYS_ADDR_REQ].pi_funcp = sppp_dlphyreq; } @@ -330,8 +330,8 @@ sppp_mproto(queue_t *q, mblk_t *mp, spppstr_t *sps) "bad mproto: primitive len %d < %d\n", len, dpi->pi_minlen)); error = DL_BADPRIM; - } else if ((dpi->pi_state != 0) && - (sps->sps_dlstate != dpi->pi_state)) { + } else if (dpi->pi_state != -1 && + sps->sps_dlstate != dpi->pi_state) { DBGERROR((CE_CONT, "bad state %d != %d for primitive %d\n", sps->sps_dlstate, dpi->pi_state, prim)); @@ -404,13 +404,13 @@ static void sppp_dl_attach_upper(queue_t *q, mblk_t *mp) { sppa_t *ppa; - spppstr_t *sps; + spppstr_t *sps = q->q_ptr; union DL_primitives *dlp; + int err = ENOMEM; + cred_t *cr; + zoneid_t zoneid; - ASSERT(q != NULL && q->q_ptr != NULL); - sps = (spppstr_t *)q->q_ptr; ASSERT(!IS_SPS_PIOATTACH(sps)); - ASSERT(mp != NULL && mp->b_rptr != NULL); dlp = (union DL_primitives *)mp->b_rptr; /* If there's something here, it's detached. */ @@ -418,20 +418,27 @@ sppp_dl_attach_upper(queue_t *q, mblk_t *mp) sppp_remove_ppa(sps); } + if ((cr = msg_getcred(mp, NULL)) == NULL) + zoneid = sps->sps_zoneid; + else + zoneid = crgetzoneid(cr); + ppa = sppp_find_ppa(dlp->attach_req.dl_ppa); - if (ppa == NULL) - ppa = sppp_create_ppa(dlp->attach_req.dl_ppa); + if (ppa == NULL) { + ppa = sppp_create_ppa(dlp->attach_req.dl_ppa, zoneid); + } else if (ppa->ppa_zoneid != zoneid) { + ppa = NULL; + err = EPERM; + } /* - * If we can't find it, then it's either because the requestor - * has supplied a wrong dl_ppa to be attached to, or because - * the control stream for the specified ppa has been closed - * before we get here. + * If we can't find or create it, then it's either because we're out of + * memory or because the requested PPA is owned by a different zone. */ if (ppa == NULL) { DBGERROR((CE_CONT, "DLPI attach: cannot create ppa %u\n", dlp->attach_req.dl_ppa)); - dlerrorack(q, mp, dlp->dl_primitive, DL_SYSERR, ENOMEM); + dlerrorack(q, mp, dlp->dl_primitive, DL_SYSERR, err); return; } /* @@ -548,7 +555,7 @@ sppp_dlbindreq(queue_t *q, mblk_t *mp, spppstr_t *sps) DBGERROR((CE_CONT, "DLPI bind: no attached ppa\n")); error = DL_OUTSTATE; } else if ((req_sap != ETHERTYPE_IP) && (req_sap != ETHERTYPE_IPV6) && - (req_sap != ETHERTYPE_ALLSAP)) { + (req_sap != ETHERTYPE_ALLSAP)) { DBGERROR((CE_CONT, "DLPI bind: unknown SAP %x\n", req_sap)); error = DL_BADADDR; } @@ -588,7 +595,7 @@ sppp_dl_bind(queue_t *q, mblk_t *mp) ASSERT(ppa != NULL); req_sap = dlp->bind_req.dl_sap; ASSERT((req_sap == ETHERTYPE_IP) || (req_sap == ETHERTYPE_IPV6) || - (req_sap == ETHERTYPE_ALLSAP)); + (req_sap == ETHERTYPE_ALLSAP)); if (req_sap == ETHERTYPE_IP) { sap = PPP_IP; @@ -701,7 +708,7 @@ sppp_dl_unbind(queue_t *q, mblk_t *mp) msg = NULL; saydown = (ppa->ppa_ctl != NULL && (sps->sps_npmode == NPMODE_PASS || - sps->sps_npmode == NPMODE_QUEUE)); + sps->sps_npmode == NPMODE_QUEUE)); if (sap == PPP_IP) { ppa->ppa_ip_cache = NULL; if (saydown) diff --git a/usr/src/uts/common/io/ppp/sppp/sppp_mod.c b/usr/src/uts/common/io/ppp/sppp/sppp_mod.c index e0c1ecc4f7..168cf17f49 100644 --- a/usr/src/uts/common/io/ppp/sppp/sppp_mod.c +++ b/usr/src/uts/common/io/ppp/sppp/sppp_mod.c @@ -1,7 +1,7 @@ /* * sppp_mod.c - modload support for PPP pseudo-device driver. * - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * Permission to use, copy, modify, and distribute this software and its @@ -104,7 +104,7 @@ static struct qinit sppp_uwinit = { static struct qinit sppp_lrinit = { (int (*)())sppp_lrput, /* qi_putp */ - NULL, /* qi_srvp */ + (int (*)())sppp_lrsrv, /* qi_srvp */ NULL, /* qi_qopen */ NULL, /* qi_qclose */ NULL, /* qi_qadmin */ @@ -209,6 +209,7 @@ _mi_driver_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) if (cmd != DDI_ATTACH) { return (DDI_FAILURE); } + _mi_dip = dip; if (ddi_create_minor_node(dip, PPP_DRV_NAME, S_IFCHR, 0, DDI_PSEUDO, CLONE_DEV) == DDI_FAILURE) { ddi_remove_minor_node(dip, NULL); @@ -231,6 +232,7 @@ _mi_driver_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) return (DDI_FAILURE); } ddi_remove_minor_node(dip, NULL); + _mi_dip = NULL; return (DDI_SUCCESS); } @@ -243,7 +245,7 @@ _mi_driver_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) /* ARGSUSED */ static int _mi_driver_info(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, - void **result) + void **result) { int rc; diff --git a/usr/src/uts/common/io/ppp/spppcomp/spppcomp.c b/usr/src/uts/common/io/ppp/spppcomp/spppcomp.c index c097f225bc..1179d817de 100644 --- a/usr/src/uts/common/io/ppp/spppcomp/spppcomp.c +++ b/usr/src/uts/common/io/ppp/spppcomp/spppcomp.c @@ -1,7 +1,7 @@ /* * spppcomp.c - STREAMS module for kernel-level compression and CCP support. * - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * Permission to use, copy, modify, and distribute this software and its @@ -46,7 +46,6 @@ * performance and scalability. */ -#pragma ident "%Z%%M% %I% %E% SMI" #define RCSID "$Id: spppcomp.c,v 1.0 2000/05/08 01:10:12 masputra Exp $" #include <sys/types.h> @@ -102,10 +101,10 @@ static const char buildtime[] = "Built " __DATE__ " at " __TIME__ static int spppcomp_open(queue_t *, dev_t *, int, int, cred_t *); static int spppcomp_close(queue_t *, int, cred_t *); -static int spppcomp_rput(queue_t *, mblk_t *); -static int spppcomp_rsrv(queue_t *); -static int spppcomp_wput(queue_t *, mblk_t *); -static int spppcomp_wsrv(queue_t *); +static void spppcomp_rput(queue_t *, mblk_t *); +static void spppcomp_rsrv(queue_t *); +static void spppcomp_wput(queue_t *, mblk_t *); +static void spppcomp_wsrv(queue_t *); #define PPPCOMP_MI_MINPSZ (0) #define PPPCOMP_MI_MAXPSZ (INFPSZ) @@ -122,8 +121,8 @@ static struct module_info spppcomp_modinfo = { }; static struct qinit spppcomp_rinit = { - spppcomp_rput, /* qi_putp */ - spppcomp_rsrv, /* qi_srvp */ + (int (*)())spppcomp_rput, /* qi_putp */ + (int (*)())spppcomp_rsrv, /* qi_srvp */ spppcomp_open, /* qi_qopen */ spppcomp_close, /* qi_qclose */ NULL, /* qi_qadmin */ @@ -132,8 +131,8 @@ static struct qinit spppcomp_rinit = { }; static struct qinit spppcomp_winit = { - spppcomp_wput, /* qi_putp */ - spppcomp_wsrv, /* qi_srvp */ + (int (*)())spppcomp_wput, /* qi_putp */ + (int (*)())spppcomp_wsrv, /* qi_srvp */ NULL, /* qi_qopen */ NULL, /* qi_qclose */ NULL, /* qi_qadmin */ @@ -236,17 +235,13 @@ spppcomp_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp) { sppp_comp_t *cp; - ASSERT(q != NULL); - ASSERT(devp != NULL); - if (q->q_ptr != NULL) { return (0); } if (sflag != MODOPEN) { return (EINVAL); } - cp = (sppp_comp_t *)kmem_zalloc(sizeof (sppp_comp_t), KM_SLEEP); - ASSERT(cp != NULL); + cp = kmem_zalloc(sizeof (sppp_comp_t), KM_SLEEP); q->q_ptr = WR(q)->q_ptr = (caddr_t)cp; cp->cp_mru = PPP_MRU; @@ -274,11 +269,7 @@ spppcomp_open(queue_t *q, dev_t *devp, int flag, int sflag, cred_t *credp) static int spppcomp_close(queue_t *q, int flag, cred_t *credp) { - sppp_comp_t *cp; - - ASSERT(q != NULL); - ASSERT(q->q_ptr != NULL); - cp = (sppp_comp_t *)q->q_ptr; + sppp_comp_t *cp = q->q_ptr; qprocsoff(q); @@ -321,17 +312,12 @@ spppcomp_close(queue_t *q, int flag, cred_t *credp) * most processing will be performed here in-line, and deferral * occurs only when necessary. */ -static int +static void spppcomp_wput(queue_t *q, mblk_t *mp) { - sppp_comp_t *cp; + sppp_comp_t *cp = q->q_ptr; int flag; - ASSERT(q != NULL); - ASSERT(q->q_ptr != NULL); - cp = (sppp_comp_t *)q->q_ptr; - ASSERT(mp != NULL && mp->b_rptr != NULL); - switch (MTYPE(mp)) { case M_DATA: if (q->q_first != NULL || !bcanputnext(q, mp->b_band) || @@ -340,14 +326,14 @@ spppcomp_wput(queue_t *q, mblk_t *mp) #ifdef SPC_DEBUG cp->cp_out_queued++; #endif - (void) putq(q, mp); + if (!putq(q, mp)) + freemsg(mp); } else { #ifdef SPC_DEBUG cp->cp_out_handled++; #endif - if ((mp = spppcomp_outpkt(q, mp)) != NULL) { + if ((mp = spppcomp_outpkt(q, mp)) != NULL) putnext(q, mp); - } } break; case M_IOCTL: @@ -382,10 +368,12 @@ spppcomp_wput(queue_t *q, mblk_t *mp) putnext(q, mp); break; default: - putnext(q, mp); + if (bcanputnext(q, mp->b_band)) + putnext(q, mp); + else if (!putq(q, mp)) + freemsg(mp); break; } - return (0); } /* @@ -397,17 +385,12 @@ spppcomp_wput(queue_t *q, mblk_t *mp) * Description: * Write-side service procedure. */ -static int +static void spppcomp_wsrv(queue_t *q) { mblk_t *mp; - ASSERT(q != NULL); - ASSERT(q->q_ptr != NULL); - while ((mp = getq(q)) != NULL) { - /* We should only place M_DATA on the service queue. */ - ASSERT(MTYPE(mp) == M_DATA); /* * If the module below us is flow-controlled, then put * this message back on the queue again. @@ -416,11 +399,10 @@ spppcomp_wsrv(queue_t *q) (void) putbq(q, mp); break; } - if ((mp = spppcomp_outpkt(q, mp)) != NULL) { + if (MTYPE(mp) != M_DATA || + (mp = spppcomp_outpkt(q, mp)) != NULL) putnext(q, mp); - } } - return (0); } /* @@ -440,12 +422,7 @@ spppcomp_outpkt(queue_t *q, mblk_t *mp) mblk_t *zmp; int len; ushort_t proto; - sppp_comp_t *cp; - - ASSERT(q != NULL); - ASSERT(mp != NULL); - cp = (sppp_comp_t *)q->q_ptr; - ASSERT(cp != NULL); + sppp_comp_t *cp = q->q_ptr; /* * If the entire data size of the mblk is less than the length of the @@ -716,7 +693,7 @@ msg_oerror: static int spppcomp_inner_ioctl(queue_t *q, mblk_t *mp) { - sppp_comp_t *cp; + sppp_comp_t *cp = q->q_ptr; int flags; int mask; int rc; @@ -732,12 +709,6 @@ spppcomp_inner_ioctl(queue_t *q, mblk_t *mp) struct iocblk *iop; void *xtemp; - ASSERT(q != NULL); - ASSERT(q->q_ptr != NULL); - cp = (sppp_comp_t *)q->q_ptr; - ASSERT(mp != NULL); - ASSERT(mp->b_rptr != NULL); - iop = (struct iocblk *)mp->b_rptr; rc = EINVAL; len = 0; @@ -966,10 +937,6 @@ spppcomp_getcstat(queue_t *q, mblk_t *mp, sppp_comp_t *cp) mblk_t *mpnext; struct ppp_comp_stats *csp; - ASSERT(q != NULL); - ASSERT(q->q_ptr != NULL); - ASSERT(mp != NULL); - ASSERT(mp->b_rptr != NULL); ASSERT(cp != NULL); mpnext = allocb(sizeof (struct ppp_comp_stats), BPRI_MED); @@ -1011,10 +978,6 @@ spppcomp_ioctl(queue_t *q, mblk_t *mp, sppp_comp_t *cp) struct iocblk *iop; int flag; - ASSERT(q != NULL); - ASSERT(q->q_ptr != NULL); - ASSERT(mp != NULL); - ASSERT(mp->b_rptr != NULL); ASSERT(cp != NULL); iop = (struct iocblk *)mp->b_rptr; @@ -1080,18 +1043,12 @@ spppcomp_ioctl(queue_t *q, mblk_t *mp, sppp_comp_t *cp) static int spppcomp_mctl(queue_t *q, mblk_t *mp) { - sppp_comp_t *cp; + sppp_comp_t *cp = q->q_ptr; kstat_t *ksp; char unit[32]; const char **cpp; kstat_named_t *knt; - ASSERT(q != NULL); - ASSERT(q->q_ptr != NULL); - cp = (sppp_comp_t *)q->q_ptr; - ASSERT(mp != NULL); - ASSERT(mp->b_rptr != NULL); - switch (*mp->b_rptr) { case PPPCTL_MTU: if (MBLKL(mp) < 4) { @@ -1187,20 +1144,15 @@ spppcomp_mctl(queue_t *q, mblk_t *mp) * more and we're in an interrupt context (on the theory that * we're hogging the CPU in this case). */ -static int +static void spppcomp_rput(queue_t *q, mblk_t *mp) { - sppp_comp_t *cp; + sppp_comp_t *cp = q->q_ptr; struct iocblk *iop; struct ppp_stats64 *psp; boolean_t inter; hrtime_t curtime; - ASSERT(q != NULL); - ASSERT(q->q_ptr != NULL); - cp = (sppp_comp_t *)q->q_ptr; - ASSERT(mp != NULL); - switch (MTYPE(mp)) { case M_DATA: inter = servicing_interrupt(); @@ -1239,12 +1191,12 @@ spppcomp_rput(queue_t *q, mblk_t *mp) #ifdef SPC_DEBUG cp->cp_in_queued++; #endif - (void) putq(q, mp); + if (!putq(q, mp)) + freemsg(mp); } break; case M_IOCACK: iop = (struct iocblk *)mp->b_rptr; - ASSERT(iop != NULL); /* * Bundled with pppstats; no need to handle PPPIO_GETSTAT * here since we'll never see it. @@ -1308,10 +1260,12 @@ spppcomp_rput(queue_t *q, mblk_t *mp) break; default: - putnext(q, mp); + if (bcanputnext(q, mp->b_band)) + putnext(q, mp); + else if (!putq(q, mp)) + freemsg(mp); break; } - return (0); } /* @@ -1329,17 +1283,12 @@ spppcomp_rput(queue_t *q, mblk_t *mp) * it will put the unprocessed data on the queue for later * handling. */ -static int +static void spppcomp_rsrv(queue_t *q) { mblk_t *mp; - ASSERT(q != NULL); - ASSERT(q->q_ptr != NULL); - while ((mp = getq(q)) != NULL) { - /* We should only place M_DATA on the service queue. */ - ASSERT(MTYPE(mp) == M_DATA); /* * If the module above us is flow-controlled, then put * this message back on the queue again. @@ -1348,10 +1297,10 @@ spppcomp_rsrv(queue_t *q) (void) putbq(q, mp); break; } - if ((mp = spppcomp_inpkt(q, mp)) != NULL) + if (MTYPE(mp) != M_DATA || + (mp = spppcomp_inpkt(q, mp)) != NULL) putnext(q, mp); } - return (0); } /* @@ -1373,12 +1322,7 @@ spppcomp_inpkt(queue_t *q, mblk_t *mp) uchar_t *dp; int len; int hlen; - sppp_comp_t *cp; - - ASSERT(q != NULL); - ASSERT(mp != NULL); - cp = (sppp_comp_t *)q->q_ptr; - ASSERT(cp != NULL); + sppp_comp_t *cp = q->q_ptr; len = msgsize(mp); @@ -1685,11 +1629,6 @@ comp_ccp(queue_t *q, mblk_t *mp, sppp_comp_t *cp, boolean_t rcvd) int clen; uchar_t *dp; - ASSERT(q != NULL); - ASSERT(q->q_ptr != NULL); - ASSERT(mp != NULL); - ASSERT(cp != NULL); - len = msgsize(mp); if (len < PPP_HDRLEN + CCP_HDRLEN) { return; @@ -1771,19 +1710,16 @@ comp_ccp(queue_t *q, mblk_t *mp, sppp_comp_t *cp, boolean_t rcvd) static int spppcomp_kstat_update(kstat_t *ksp, int rw) { - register sppp_comp_t *cp; - register spppcomp_kstats_t *cpkp; - register struct vjstat *sp; - register struct pppstat64 *psp; + sppp_comp_t *cp = ksp->ks_private; + spppcomp_kstats_t *cpkp; + struct vjstat *sp; + struct pppstat64 *psp; struct ppp_comp_stats csp; if (rw == KSTAT_WRITE) { return (EACCES); } - cp = (sppp_comp_t *)ksp->ks_private; - ASSERT(cp != NULL); - cpkp = (spppcomp_kstats_t *)ksp->ks_data; bzero((caddr_t)&csp, sizeof (struct ppp_comp_stats)); diff --git a/usr/src/uts/common/io/ppp/sppptun/sppptun.c b/usr/src/uts/common/io/ppp/sppptun/sppptun.c index 18e124c07b..18a729a1db 100644 --- a/usr/src/uts/common/io/ppp/sppptun/sppptun.c +++ b/usr/src/uts/common/io/ppp/sppptun/sppptun.c @@ -20,7 +20,7 @@ */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -448,7 +448,7 @@ sppptun_open(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *credp) char *cp; /* ordinary users have no need to push this module */ - if (secpolicy_net_config(credp, B_FALSE) != 0) + if (secpolicy_ppp_config(credp) != 0) return (EPERM); tll = kmem_zalloc(sizeof (tunll_t), KM_SLEEP); @@ -456,6 +456,7 @@ sppptun_open(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *credp) tll->tll_index = tunll_index++; tll->tll_wq = WR(q); + tll->tll_zoneid = crgetzoneid(credp); /* Insert at end of list */ insque(&tll->tll_next, tunll_list.q_back); @@ -514,6 +515,7 @@ sppptun_open(queue_t *q, dev_t *devp, int oflag, int sflag, cred_t *credp) return (ENOSR); tcl->tcl_rq = q; /* save read queue pointer */ tcl->tcl_flags |= TCLF_ISCLIENT; /* sanity check */ + tcl->tcl_zoneid = crgetzoneid(credp); q->q_ptr = WR(q)->q_ptr = (caddr_t)tcl; *devp = makedevice(getmajor(*devp), tcl->tcl_lsessid); @@ -539,17 +541,18 @@ make_control(tuncl_t *tclabout, tunll_t *tllabout, int action, tuncl_t *tclto) if (mp != NULL) { MTYPE(mp) = M_PROTO; ptc = (struct ppptun_control *)mp->b_wptr; + bzero(ptc, sizeof (*ptc)); mp->b_wptr += sizeof (*ptc); if (tclabout != NULL) { ptc->ptc_rsessid = tclabout->tcl_rsessid; ptc->ptc_address = tclabout->tcl_address; - } else { - bzero(ptc, sizeof (*ptc)); } ptc->ptc_discrim = tclto->tcl_ctlval; ptc->ptc_action = action; - (void) strncpy(ptc->ptc_name, tllabout->tll_name, - sizeof (ptc->ptc_name)); + if (tllabout != NULL) { + (void) strncpy(ptc->ptc_name, tllabout->tll_name, + sizeof (ptc->ptc_name)); + } } return (mp); } @@ -797,7 +800,8 @@ sppptun_outpkt(queue_t *q, mblk_t **mpp) *mpp = NULL; if (!(tcl->tcl_flags & TCLF_ISCLIENT)) { - merror(q, mp, EINVAL); + /* This should never happen on a lower layer stream */ + freemsg(mp); return (NULL); } @@ -815,7 +819,8 @@ sppptun_outpkt(queue_t *q, mblk_t **mpp) KCINCR(cks_octrl_drop); DTRACE_PROBE2(sppptun__bad__control, tuncl_t *, tcl, mblk_t *, mp); - merror(q, mp, EINVAL); + send_control(tcl, tcl->tcl_ctrl_tll, PTCA_BADCTRL, tcl); + freemsg(mp); return (NULL); } ptc = (struct ppptun_control *)mp->b_rptr; @@ -846,18 +851,22 @@ sppptun_outpkt(queue_t *q, mblk_t **mpp) } /* Don't allow empty control packets. */ + tll = tcl->tcl_ctrl_tll; if (mp->b_cont == NULL) { KCINCR(cks_octrl_drop); - merror(q, mp, EINVAL); + DTRACE_PROBE2(sppptun__bad__control, tuncl_t *, tcl, + mblk_t *, mp); + send_control(tcl, tll, PTCA_BADCTRL, tcl); + freemsg(mp); return (NULL); } - tll = tcl->tcl_ctrl_tll; } if (tll == NULL || (lowerq = tll->tll_wq) == NULL) { DTRACE_PROBE3(sppptun__cannot__send, tuncl_t *, tcl, tunll_t *, tll, mblk_t *, mp); - merror(q, mp, ENXIO); + send_control(tcl, tll, PTCA_UNPLUMB, tcl); + freemsg(mp); if (isdata) { tcl->tcl_stats.ppp_oerrors++; } else { @@ -919,7 +928,7 @@ sppptun_outpkt(queue_t *q, mblk_t **mpp) ether_copy(tcl->tcl_address.pta_pppoe.ptma_mac, edestp->addr); /* DLPI SAPs are in host byte order! */ - edestp->type = ETHERTYPE_PPPOES; + edestp->type = tll->tll_sap; /* Make sure the protocol field isn't compressed. */ len = (*mp->b_rptr & 1); @@ -969,7 +978,7 @@ sppptun_outpkt(queue_t *q, mblk_t **mpp) edestp = (ether_dest_t *)(dur + 1); /* DLPI SAPs are in host byte order! */ - edestp->type = ETHERTYPE_PPPOED; + edestp->type = tll->tll_sap; /* * If destination isn't set yet, then we have to @@ -1070,13 +1079,14 @@ save_for_close(tunll_t *tll, mblk_t *mp) * perimeters. */ static tunll_t * -tll_lookup_on_name(char *dname) +tll_lookup_on_name(const char *dname, zoneid_t zoneid) { tunll_t *tll; tll = TO_TLL(tunll_list.q_forw); for (; tll != TO_TLL(&tunll_list); tll = TO_TLL(tll->tll_next)) - if (strcmp(dname, tll->tll_name) == 0) + if (tll->tll_zoneid == zoneid && + strcmp(dname, tll->tll_name) == 0) return (tll); return (NULL); } @@ -1106,6 +1116,7 @@ sppptun_inner_ioctl(queue_t *q, mblk_t *mp) mblk_t *mptmp; ppptun_atype *pap; struct ppp_stats64 *psp; + zoneid_t zoneid; iop = (struct iocblk *)mp->b_rptr; tcl = NULL; @@ -1163,7 +1174,8 @@ sppptun_inner_ioctl(queue_t *q, mblk_t *mp) ptn = (union ppptun_name *)mp->b_cont->b_rptr; ptn->ptn_name[sizeof (ptn->ptn_name) - 1] = '\0'; - if ((tll = tll_lookup_on_name(ptn->ptn_name)) != NULL) { + tll = tll_lookup_on_name(ptn->ptn_name, tll->tll_zoneid); + if (tll != NULL) { rc = EEXIST; break; } @@ -1171,23 +1183,6 @@ sppptun_inner_ioctl(queue_t *q, mblk_t *mp) (void) strcpy(tll->tll_name, ptn->ptn_name); break; - case PPPTUN_GNAME: - /* This is done on the *module* (lower level) side. */ - if (tll == NULL) { - rc = EINVAL; - break; - } - if (mp->b_cont != NULL) - freemsg(mp->b_cont); - if ((mp->b_cont = allocb(sizeof (*ptn), BPRI_HI)) == NULL) { - rc = ENOSR; - break; - } - ptn = (union ppptun_name *)mp->b_cont->b_rptr; - bcopy(tll->tll_name, ptn->ptn_name, sizeof (ptn->ptn_name)); - len = sizeof (*ptn); - break; - case PPPTUN_SINFO: case PPPTUN_GINFO: /* Either side */ @@ -1197,7 +1192,8 @@ sppptun_inner_ioctl(queue_t *q, mblk_t *mp) } pti = (struct ppptun_info *)mp->b_cont->b_rptr; if (pti->pti_name[0] != '\0') - tll = tll_lookup_on_name(pti->pti_name); + tll = tll_lookup_on_name(pti->pti_name, + tcl == NULL ? tll->tll_zoneid : tcl->tcl_zoneid); if (tll == NULL) { /* Driver (client) side must have name */ if (tcl != NULL && pti->pti_name[0] == '\0') @@ -1246,11 +1242,15 @@ sppptun_inner_ioctl(queue_t *q, mblk_t *mp) rc = EINVAL; break; } + zoneid = tcl == NULL ? tll->tll_zoneid : tcl->tcl_zoneid; ptn = (union ppptun_name *)mp->b_cont->b_rptr; i = ptn->ptn_index; tll = TO_TLL(tunll_list.q_forw); - while (--i >= 0 && tll != TO_TLL(&tunll_list)) + while (tll != TO_TLL(&tunll_list)) { + if (tll->tll_zoneid == zoneid && --i < 0) + break; tll = TO_TLL(tll->tll_next); + } if (tll != TO_TLL(&tunll_list)) { bcopy(tll->tll_name, ptn->ptn_name, sizeof (ptn->ptn_name)); @@ -1384,7 +1384,7 @@ sppptun_inner_ioctl(queue_t *q, mblk_t *mp) } ptn = (union ppptun_name *)mp->b_cont->b_rptr; ptn->ptn_name[sizeof (ptn->ptn_name) - 1] = '\0'; - tll = tll_lookup_on_name(ptn->ptn_name); + tll = tll_lookup_on_name(ptn->ptn_name, tcl->tcl_zoneid); if (tll == NULL) { rc = ESRCH; break; @@ -1462,7 +1462,7 @@ sppptun_inner_ioctl(queue_t *q, mblk_t *mp) } ptn = (union ppptun_name *)mp->b_cont->b_rptr; ptn->ptn_name[sizeof (ptn->ptn_name) - 1] = '\0'; - tll = tll_lookup_on_name(ptn->ptn_name); + tll = tll_lookup_on_name(ptn->ptn_name, tcl->tcl_zoneid); if (tll == NULL || tll->tll_defcl != tcl) { rc = ESRCH; break; @@ -1470,6 +1470,17 @@ sppptun_inner_ioctl(queue_t *q, mblk_t *mp) tll->tll_defcl = NULL; break; + case PPPTUN_SSAP: + /* This is done on the *module* (lower level) side. */ + if (tll == NULL || mp->b_cont == NULL || + iop->ioc_count != sizeof (uint_t)) { + rc = EINVAL; + break; + } + + tll->tll_sap = *(uint_t *)mp->b_cont->b_rptr; + break; + default: /* Caller should already have checked command value */ ASSERT(0); @@ -1508,7 +1519,6 @@ sppptun_ioctl(queue_t *q, mblk_t *mp) case PPPIO_GETSTAT: case PPPIO_GETSTAT64: case PPPTUN_SNAME: - case PPPTUN_GNAME: case PPPTUN_SINFO: case PPPTUN_GINFO: case PPPTUN_GNNAME: @@ -1520,6 +1530,7 @@ sppptun_ioctl(queue_t *q, mblk_t *mp) case PPPTUN_SCTL: case PPPTUN_GCTL: case PPPTUN_DCTL: + case PPPTUN_SSAP: qwriter(q, mp, sppptun_inner_ioctl, PERIM_INNER); return; diff --git a/usr/src/uts/common/io/ppp/sppptun/sppptun_impl.h b/usr/src/uts/common/io/ppp/sppptun/sppptun_impl.h index 444d19e293..58480ae60c 100644 --- a/usr/src/uts/common/io/ppp/sppptun/sppptun_impl.h +++ b/usr/src/uts/common/io/ppp/sppptun/sppptun_impl.h @@ -20,7 +20,7 @@ */ /* - * Copyright 2007 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -107,6 +107,10 @@ struct tunll_s { tll_kstats_t tll_kstats; /* current statistics */ kstat_t *tll_ksp; /* pointer to kstats allocation */ + + uint_t tll_sap; /* SAP for PPPoE */ + + zoneid_t tll_zoneid; }; /* @@ -141,6 +145,8 @@ struct tuncl_s { struct pppstat64 tcl_stats; /* Standard PPP statistics */ tcl_kstats_t tcl_kstats; /* current statistics */ kstat_t *tcl_ksp; /* pointer to kstats allocation */ + + zoneid_t tcl_zoneid; }; #define TO_TLL(p) \ diff --git a/usr/src/uts/common/net/sppptun.h b/usr/src/uts/common/net/sppptun.h index 0ffeb1dd40..ae6e170c6f 100644 --- a/usr/src/uts/common/net/sppptun.h +++ b/usr/src/uts/common/net/sppptun.h @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -23,7 +22,7 @@ * sppptun.h - ioctl and other miscellaneous definitions for PPP * tunneling STREAMS module * - * Copyright 2000-2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * See also: @@ -36,8 +35,6 @@ #ifndef __SPPPTUN_H #define __SPPPTUN_H -#pragma ident "%Z%%M% %I% %E% SMI" - #include <sys/types.h> #include <sys/socket.h> #include <sys/ethernet.h> @@ -59,7 +56,6 @@ extern "C" { * of the PPP tunnel multiplexor. */ #define PPPTUN_SNAME _PPPTUN(1) /* set interface name (mod) */ -#define PPPTUN_GNAME _PPPTUN(2) /* get interface name (mod) */ #define PPPTUN_SINFO _PPPTUN(3) /* set multiplex ID/style */ #define PPPTUN_GINFO _PPPTUN(4) /* get multiplex ID/style */ #define PPPTUN_GNNAME _PPPTUN(5) /* get Nth interface name */ @@ -71,6 +67,7 @@ extern "C" { #define PPPTUN_SCTL _PPPTUN(11) /* set control channel by name */ #define PPPTUN_GCTL _PPPTUN(12) /* get control channel name */ #define PPPTUN_DCTL _PPPTUN(13) /* remove control channel */ +#define PPPTUN_SSAP _PPPTUN(14) /* set SAP value; uint_t */ /* Lower layer link name size */ #define PPPTUNNAMSIZ 32 @@ -160,6 +157,7 @@ struct ppptun_control { #define PTCA_CONTROL 2 /* Inbound control message */ #define PTCA_DISCONNECT 3 /* Client disconnected */ #define PTCA_UNPLUMB 4 /* Lower stream unplumbed (no addr) */ +#define PTCA_BADCTRL 5 /* Malformed control message */ #ifdef __cplusplus } diff --git a/usr/src/uts/common/os/policy.c b/usr/src/uts/common/os/policy.c index b71b956f8a..608bb4f338 100644 --- a/usr/src/uts/common/os/policy.c +++ b/usr/src/uts/common/os/policy.c @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -2288,3 +2288,17 @@ secpolicy_dld_ioctl(const cred_t *cr, const char *dld_priv, const char *msg) return (-rv); } + +/* + * secpolicy_ppp_config + * + * Determine if the subject has sufficient privileges to configure PPP and + * PPP-related devices. + */ +int +secpolicy_ppp_config(const cred_t *cr) +{ + if (PRIV_POLICY_ONLY(cr, PRIV_SYS_NET_CONFIG, B_FALSE)) + return (secpolicy_net_config(cr, B_FALSE)); + return (PRIV_POLICY(cr, PRIV_SYS_PPP_CONFIG, B_FALSE, EPERM, NULL)); +} diff --git a/usr/src/uts/common/os/priv_defs b/usr/src/uts/common/os/priv_defs index 430218de55..8875ddccab 100644 --- a/usr/src/uts/common/os/priv_defs +++ b/usr/src/uts/common/os/priv_defs @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * INSERT COMMENT @@ -390,7 +390,8 @@ privilege PRIV_SYS_IP_CONFIG privilege PRIV_SYS_NET_CONFIG - Allows all that PRIV_SYS_IP_CONFIG and PRIV_SYS_DL_CONFIG allow. + Allows all that PRIV_SYS_IP_CONFIG, PRIV_SYS_DL_CONFIG, and + PRIV_SYS_PPP_CONFIG allow. Allows a process to push the rpcmod STREAMs module. Allows a process to INSERT/REMOVE STREAMs modules on locations other than the top of the module stack. @@ -401,6 +402,11 @@ privilege PRIV_SYS_NFS Allows a process to bind to ports reserved by NFS: ports 2049 (nfs) and port 4045 (lockd). +privilege PRIV_SYS_PPP_CONFIG + + Allows a process to create and destroy PPP (sppp) interfaces. + Allows a process to configure PPP tunnels (sppptun). + privilege PRIV_SYS_RES_CONFIG Allows a process to create and delete processor sets, assign diff --git a/usr/src/uts/common/sys/policy.h b/usr/src/uts/common/sys/policy.h index 8d93c7780e..9d9baab3e1 100644 --- a/usr/src/uts/common/sys/policy.h +++ b/usr/src/uts/common/sys/policy.h @@ -19,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. + * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -120,6 +120,7 @@ int secpolicy_pcfs_modify_bootpartition(const cred_t *); int secpolicy_ponline(const cred_t *); int secpolicy_pool(const cred_t *); int secpolicy_power_mgmt(const cred_t *); +int secpolicy_ppp_config(const cred_t *); int secpolicy_proc_access(const cred_t *); int secpolicy_proc_excl_open(const cred_t *); int secpolicy_proc_owner(const cred_t *, const cred_t *, int); |