diff options
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); |