summaryrefslogtreecommitdiff
path: root/usr/src/lib/libdscp
diff options
context:
space:
mode:
authorjl139090 <none@none>2006-04-08 10:25:15 -0700
committerjl139090 <none@none>2006-04-08 10:25:15 -0700
commit25cf1a301a396c38e8adf52c15f537b80d2483f7 (patch)
treea76776c2cfbbe43c1ae252223c7ccfa5df15c21c /usr/src/lib/libdscp
parent918fadfadf0c235e6c65ca652caab042b6f05976 (diff)
downloadillumos-joyent-25cf1a301a396c38e8adf52c15f537b80d2483f7.tar.gz
PSARC 2004/750 Solaris for OPL
6379529 Solaris for OPL Project --HG-- rename : usr/src/cmd/sckmd/sparc/sun4u/sckm.sh => deleted_files/usr/src/cmd/sckmd/sparc/sun4u/sckm.sh
Diffstat (limited to 'usr/src/lib/libdscp')
-rw-r--r--usr/src/lib/libdscp/Makefile62
-rw-r--r--usr/src/lib/libdscp/Makefile.com68
-rw-r--r--usr/src/lib/libdscp/libdscp.c542
-rw-r--r--usr/src/lib/libdscp/libdscp.h72
-rw-r--r--usr/src/lib/libdscp/llib-ldscp32
-rw-r--r--usr/src/lib/libdscp/sparc/Makefile35
-rw-r--r--usr/src/lib/libdscp/spec/Makefile61
-rw-r--r--usr/src/lib/libdscp/spec/Makefile.targ35
-rw-r--r--usr/src/lib/libdscp/spec/libdscp.spec56
-rw-r--r--usr/src/lib/libdscp/spec/sparc/Makefile38
-rw-r--r--usr/src/lib/libdscp/spec/versions31
-rw-r--r--usr/src/lib/libdscp/svc/Makefile56
-rw-r--r--usr/src/lib/libdscp/svc/dscp.ppp.options112
-rw-r--r--usr/src/lib/libdscp/svc/dscp.xml121
-rw-r--r--usr/src/lib/libdscp/svc/svc-dscp111
15 files changed, 1432 insertions, 0 deletions
diff --git a/usr/src/lib/libdscp/Makefile b/usr/src/lib/libdscp/Makefile
new file mode 100644
index 0000000000..8eff9de752
--- /dev/null
+++ b/usr/src/lib/libdscp/Makefile
@@ -0,0 +1,62 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# 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.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# lib/libdscp/Makefile
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+include ../Makefile.lib
+
+SUBDIRS= spec .WAIT sparc svc
+
+all := TARGET= all
+install := TARGET= install
+clean := TARGET= clean
+clobber := TARGET= clobber
+lint := TARGET= lint
+
+# definitions for install_h target
+HDRS= libdscp.h
+ROOTHDRDIR= $(ROOT)/usr/include
+ROOTHDRS= $(HDRS:%=$(ROOTHDRDIR)/%)
+CHECKHDRS= $(HDRS:%.h=%.check)
+
+.KEEP_STATE:
+
+all install clean clobber lint: $(SUBDIRS)
+
+# install rule for install_h target
+
+$(ROOTHDRDIR)/%: %
+ $(INS.file)
+
+install_h: $(ROOTHDRS)
+
+check: $(CHECKHDRS)
+
+spec sparc svc: FRC
+ @cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
diff --git a/usr/src/lib/libdscp/Makefile.com b/usr/src/lib/libdscp/Makefile.com
new file mode 100644
index 0000000000..5c9e76421c
--- /dev/null
+++ b/usr/src/lib/libdscp/Makefile.com
@@ -0,0 +1,68 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# 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.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# lib/libdscp/Makefile.com
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+LIBRARY= libdscp.a
+VERS= .1
+MANIFEST= dscp.xml
+OBJECTS= libdscp.o
+
+include ../../Makefile.lib
+include ../../Makefile.rootfs
+
+LIBS = $(DYNLIB) $(LINTLIB)
+LDLIBS += -lc -lsocket -lnsl
+$(LINTLIB) := SRCS = $(SRCDIR)/$(LINTSRC)
+
+SRCDIR = ..
+MAPDIR = ../spec/$(TRANSMACH)
+SPECMAPFILE = $(MAPDIR)/mapfile
+
+CPPFLAGS += -I..
+CFLAGS += $(CCVERBOSE)
+
+.KEEP_STATE:
+
+# Defintions for installation of the library
+USR_PLAT_DIR = $(ROOT)/usr/platform
+USR_PSM_DIR = $(USR_PLAT_DIR)/SUNW,SPARC-Enterprise
+USR_PSM_LIB_DIR = $(USR_PSM_DIR)/lib
+ROOTLIBDIR= $(USR_PSM_LIB_DIR)
+
+$(ROOTLIBDIR):
+ $(INS.dir)
+
+.KEEP_STATE:
+
+all: $(LIBS)
+
+install: all .WAIT $(ROOTLIBDIR) $(ROOTLIB)
+
+lint: lintcheck
+
+include ../../Makefile.targ
diff --git a/usr/src/lib/libdscp/libdscp.c b/usr/src/lib/libdscp/libdscp.c
new file mode 100644
index 0000000000..63c49383d0
--- /dev/null
+++ b/usr/src/lib/libdscp/libdscp.c
@@ -0,0 +1,542 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * 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.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+#include <net/if.h>
+#include <net/pfkeyv2.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <libdscp.h>
+
+/*
+ * Define the file containing the configured DSCP interface name
+ */
+#define DSCP_CONFIGFILE "/var/run/dscp.ifname"
+
+/*
+ * Forward declarations
+ */
+static int get_ifname(char *);
+static int convert_ipv6(struct sockaddr_in6 *, uint32_t *);
+static int convert_ipv4(struct sockaddr_in *,
+ struct sockaddr_in6 *, int *);
+
+/*
+ * dscpBind()
+ *
+ * Properly bind a socket to the local DSCP address.
+ * Optionally bind it to a specific port.
+ */
+int
+dscpBind(int domain_id, int sockfd, int port)
+{
+ int len;
+ int len6;
+ int error;
+ struct sockaddr_in addr;
+ struct sockaddr_in6 addr6;
+
+ /* Check arguments */
+ if ((sockfd < 0) || (port >= IPPORT_RESERVED)) {
+ return (DSCP_ERROR_INVALID);
+ }
+
+ /* Get the local DSCP address used to communicate with the SP */
+ error = dscpAddr(domain_id, DSCP_ADDR_LOCAL,
+ (struct sockaddr *)&addr, &len);
+
+ if (error != DSCP_OK) {
+ return (error);
+ }
+
+ /*
+ * If the caller specified a port, then update the socket address
+ * to also specify the same port.
+ */
+ if (port != 0) {
+ addr.sin_port = htons(port);
+ }
+
+ /*
+ * Bind the socket.
+ *
+ * EINVAL means it is already bound.
+ * EAFNOSUPPORT means try again using IPv6.
+ */
+ if (bind(sockfd, (struct sockaddr *)&addr, len) < 0) {
+
+ if (errno == EINVAL) {
+ return (DSCP_ERROR_ALREADY);
+ }
+
+ if (errno != EAFNOSUPPORT) {
+ return (DSCP_ERROR);
+ }
+
+ if (convert_ipv4(&addr, &addr6, &len6) < 0) {
+ return (DSCP_ERROR);
+ }
+
+ if (bind(sockfd, (struct sockaddr *)&addr6, len6) < 0) {
+ if (errno == EINVAL) {
+ return (DSCP_ERROR_ALREADY);
+ }
+ return (DSCP_ERROR);
+ }
+ }
+
+ return (DSCP_OK);
+}
+
+/*
+ * dscpSecure()
+ *
+ * Enable DSCP security mechanisms on a socket.
+ *
+ * DSCP uses the IPSec AH (Authentication Headers) protocol with
+ * the SHA-1 algorithm.
+ */
+/*ARGSUSED*/
+int
+dscpSecure(int domain_id, int sockfd)
+{
+ ipsec_req_t opt;
+
+ /* Check arguments */
+ if (sockfd < 0) {
+ return (DSCP_ERROR_INVALID);
+ }
+
+ /*
+ * Construct a socket option argument that specifies the protocols
+ * and algorithms required for DSCP's use of IPSec.
+ */
+ (void) memset(&opt, 0, sizeof (opt));
+ opt.ipsr_ah_req = IPSEC_PREF_REQUIRED;
+ opt.ipsr_esp_req = IPSEC_PREF_NEVER;
+ opt.ipsr_self_encap_req = IPSEC_PREF_NEVER;
+ opt.ipsr_auth_alg = SADB_AALG_MD5HMAC;
+
+ /*
+ * Set the socket option that enables IPSec usage upon the socket,
+ * using the socket option argument constructed above.
+ */
+ if (setsockopt(sockfd, IPPROTO_IP, IP_SEC_OPT, (const char *)&opt,
+ sizeof (opt)) < 0) {
+ return (DSCP_ERROR);
+ }
+
+ return (DSCP_OK);
+}
+
+/*
+ * dscpAuth()
+ *
+ * Test whether a connection should be accepted or refused.
+ * The address of the connection request is compared against
+ * the remote address of the specified DSCP link.
+ */
+/*ARGSUSED*/
+int
+dscpAuth(int domain_id, struct sockaddr *saddr, int len)
+{
+ int dlen;
+ struct sockaddr daddr;
+ struct sockaddr_in *sin;
+ struct sockaddr_in6 *sin6;
+ uint32_t spaddr;
+ uint32_t reqaddr;
+
+ /* Check arguments */
+ if (saddr == NULL) {
+ return (DSCP_ERROR_INVALID);
+ }
+
+ /*
+ * Get the remote IP address associated with the SP.
+ */
+ if (dscpAddr(0, DSCP_ADDR_REMOTE, &daddr, &dlen) != DSCP_OK) {
+ return (DSCP_ERROR_DB);
+ }
+
+ /*
+ * Convert the request's address to a 32-bit integer.
+ *
+ * This may require a conversion if the caller is
+ * using an IPv6 socket.
+ */
+ switch (saddr->sa_family) {
+ case AF_INET:
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
+ sin = (struct sockaddr_in *)saddr;
+ reqaddr = ntohl(*((uint32_t *)&(sin->sin_addr)));
+ break;
+ case AF_INET6:
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
+ sin6 = (struct sockaddr_in6 *)saddr;
+ if (convert_ipv6(sin6, &reqaddr) < 0) {
+ return (DSCP_ERROR);
+ }
+ break;
+ default:
+ return (DSCP_ERROR);
+ }
+
+ /*
+ * Convert the SP's address to a 32-bit integer.
+ */
+ /* LINTED E_BAD_PTR_CAST_ALIGN */
+ sin = (struct sockaddr_in *)&daddr;
+ spaddr = ntohl(*((uint32_t *)&(sin->sin_addr)));
+
+ /*
+ * Compare the addresses. Reject if they don't match.
+ */
+ if (reqaddr != spaddr) {
+ return (DSCP_ERROR_REJECT);
+ }
+
+ return (DSCP_OK);
+}
+
+/*
+ * dscpAddr()
+ *
+ * Get the addresses associated with a specific DSCP link.
+ */
+/*ARGSUSED*/
+int
+dscpAddr(int domain_id, int which, struct sockaddr *saddr, int *lenp)
+{
+ int error;
+ int sockfd;
+ uint64_t flags;
+ char ifname[LIFNAMSIZ];
+ struct lifreq lifr;
+
+ /* Check arguments */
+ if (((saddr == NULL) || (lenp == NULL)) ||
+ ((which != DSCP_ADDR_LOCAL) && (which != DSCP_ADDR_REMOTE))) {
+ return (DSCP_ERROR_INVALID);
+ }
+
+ /*
+ * Get the DSCP interface name.
+ */
+ if (get_ifname(ifname) != 0) {
+ return (DSCP_ERROR_DB);
+ }
+
+ /*
+ * Open a socket.
+ */
+ if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) {
+ return (DSCP_ERROR_DB);
+ }
+
+ /*
+ * Get the interface flags.
+ */
+ (void) memset(&lifr, 0, sizeof (lifr));
+ (void) strncpy(lifr.lifr_name, ifname, sizeof (lifr.lifr_name));
+ if (ioctl(sockfd, SIOCGLIFFLAGS, (char *)&lifr) < 0) {
+ (void) close(sockfd);
+ return (DSCP_ERROR_DB);
+ }
+ flags = lifr.lifr_flags;
+
+ /*
+ * The interface must be a PPP link using IPv4.
+ */
+ if (((flags & IFF_IPV4) == 0) ||
+ ((flags & IFF_POINTOPOINT) == 0)) {
+ (void) close(sockfd);
+ return (DSCP_ERROR_DB);
+ }
+
+ /*
+ * Get the local or remote address, depending upon 'which'.
+ */
+ (void) strncpy(lifr.lifr_name, ifname, sizeof (lifr.lifr_name));
+ if (which == DSCP_ADDR_LOCAL) {
+ error = ioctl(sockfd, SIOCGLIFADDR, (char *)&lifr);
+ } else {
+ error = ioctl(sockfd, SIOCGLIFDSTADDR, (char *)&lifr);
+ }
+ if (error < 0) {
+ (void) close(sockfd);
+ return (DSCP_ERROR_DB);
+ }
+
+ /*
+ * Copy the sockaddr value back to the caller.
+ */
+ (void) memset(saddr, 0, sizeof (struct sockaddr));
+ (void) memcpy(saddr, &lifr.lifr_addr, sizeof (struct sockaddr_in));
+ *lenp = sizeof (struct sockaddr_in);
+
+ (void) close(sockfd);
+ return (DSCP_OK);
+}
+
+/*
+ * dscpIdent()
+ *
+ * Determine the domain of origin associated with a sockaddr.
+ * (Map a sockaddr to a domain ID.)
+ *
+ * In the Solaris version, the remote socket address should always
+ * be the SP. A call to dscpAuth() is used to confirm this, and
+ * then DSCP_IDENT_SP is returned as a special domain ID.
+ */
+int
+dscpIdent(struct sockaddr *saddr, int len, int *domainp)
+{
+ int error;
+
+ /* Check arguments */
+ if ((saddr == NULL) || (domainp == NULL)) {
+ return (DSCP_ERROR_INVALID);
+ }
+
+ /* Confirm that the address is the SP */
+ error = dscpAuth(0, saddr, len);
+ if (error != DSCP_OK) {
+ if (error == DSCP_ERROR_REJECT) {
+ return (DSCP_ERROR);
+ }
+ return (error);
+ }
+
+ *domainp = DSCP_IDENT_SP;
+ return (DSCP_OK);
+}
+
+/*
+ * get_ifname()
+ *
+ * Retrieve the interface name used by DSCP.
+ * It should be available from a file in /var/run.
+ *
+ * Returns: 0 upon success, -1 upon failure.
+ */
+static int
+get_ifname(char *ifname)
+{
+ int i;
+ int fd;
+ int len;
+ int size;
+ int count;
+ int end;
+ int begin;
+ struct stat stbuf;
+
+ /*
+ * Initialize the interface name.
+ */
+ (void) memset(ifname, 0, LIFNAMSIZ);
+
+ /*
+ * Test for a a valid configuration file.
+ */
+ if ((stat(DSCP_CONFIGFILE, &stbuf) < 0) ||
+ (S_ISREG(stbuf.st_mode) == 0) ||
+ (stbuf.st_size > LIFNAMSIZ)) {
+ return (-1);
+ }
+
+ /*
+ * Open the configuration file and read its contents
+ */
+
+ if ((fd = open(DSCP_CONFIGFILE, O_RDONLY)) < 0) {
+ return (-1);
+ }
+
+ count = 0;
+ size = stbuf.st_size;
+ do {
+ i = read(fd, &ifname[count], size - count);
+ if (i <= 0) {
+ (void) close(fd);
+ return (-1);
+ }
+ count += i;
+ } while (count < size);
+
+ (void) close(fd);
+
+ /*
+ * Analyze the interface name that was just read,
+ * and clean it up as necessary. The result should
+ * be a simple NULL terminated string such as "sppp0"
+ * with no extra whitespace or other characters.
+ */
+
+ /* Detect the beginning of the interface name */
+ for (begin = -1, i = 0; i < size; i++) {
+ if (isalnum(ifname[i]) != 0) {
+ begin = i;
+ break;
+ }
+ }
+
+ /* Fail if no such beginning was found */
+ if (begin < 0) {
+ return (-1);
+ }
+
+ /* Detect the end of the interface name */
+ for (end = size - 1, i = begin; i < size; i++) {
+ if (isalnum(ifname[i]) == 0) {
+ end = i;
+ break;
+ }
+ }
+
+ /* Compute the length of the name */
+ len = end - begin;
+
+ /* Remove leading whitespace */
+ if (begin > 0) {
+ (void) memmove(ifname, &ifname[begin], len);
+ }
+
+ /* Clear out any remaining garbage */
+ if (len < size) {
+ (void) memset(&ifname[len], 0, size - len);
+ }
+
+ return (0);
+}
+
+/*
+ * convert_ipv6()
+ *
+ * Converts an IPv6 socket address into an equivalent IPv4
+ * address. The conversion is to a 32-bit integer because
+ * that is sufficient for how libdscp uses IPv4 addresses.
+ *
+ * The IPv4 address is additionally converted from network
+ * byte order to host byte order.
+ *
+ * Returns: 0 upon success, with 'addrp' updated.
+ * -1 upon failure, with 'addrp' undefined.
+ */
+static int
+convert_ipv6(struct sockaddr_in6 *addr6, uint32_t *addrp)
+{
+ uint32_t addr;
+ char *ipv4str;
+ char ipv6str[INET6_ADDRSTRLEN];
+
+ /*
+ * Convert the IPv6 address into a string.
+ */
+ if (inet_ntop(AF_INET6, &addr6->sin6_addr, ipv6str,
+ sizeof (ipv6str)) == NULL) {
+ return (-1);
+ }
+
+ /*
+ * Use the IPv6 string to construct an IPv4 string.
+ */
+ if ((ipv4str = strrchr(ipv6str, ':')) != NULL) {
+ ipv4str++;
+ } else {
+ return (-1);
+ }
+
+ /*
+ * Convert the IPv4 string into a 32-bit integer.
+ */
+ if (inet_pton(AF_INET, ipv4str, &addr) <= 0) {
+ return (-1);
+ }
+
+ *addrp = ntohl(addr);
+ return (0);
+}
+
+/*
+ * convert_ipv4()
+ *
+ * Convert an IPv4 socket address into an equivalent IPv6 address.
+ *
+ * Returns: 0 upon success, with 'addr6' and 'lenp' updated.
+ * -1 upon failure, with 'addr6' and 'lenp' undefined.
+ */
+static int
+convert_ipv4(struct sockaddr_in *addr, struct sockaddr_in6 *addr6, int *lenp)
+{
+ int len;
+ uint32_t ipv4addr;
+ char ipv4str[INET_ADDRSTRLEN];
+ char ipv6str[INET6_ADDRSTRLEN];
+
+ /*
+ * Convert the IPv4 socket address into a string.
+ */
+ ipv4addr = *((uint32_t *)&(addr->sin_addr));
+ if (inet_ntop(AF_INET, &ipv4addr, ipv4str, sizeof (ipv4str)) == NULL) {
+ return (-1);
+ }
+
+ /*
+ * Use the IPv4 string to construct an IPv6 string.
+ */
+ len = snprintf(ipv6str, INET6_ADDRSTRLEN, "::ffff:%s", ipv4str);
+ if (len >= INET6_ADDRSTRLEN) {
+ return (-1);
+ }
+
+ /*
+ * Convert the IPv6 string to an IPv6 socket address.
+ */
+ (void) memset(addr6, 0, sizeof (*addr6));
+ addr6->sin6_family = AF_INET6;
+ addr6->sin6_port = addr->sin_port;
+ if (inet_pton(AF_INET6, ipv6str, &addr6->sin6_addr) <= 0) {
+ return (-1);
+ }
+
+ *lenp = sizeof (struct sockaddr_in6);
+
+ return (0);
+}
diff --git a/usr/src/lib/libdscp/libdscp.h b/usr/src/lib/libdscp/libdscp.h
new file mode 100644
index 0000000000..aa3b76cdde
--- /dev/null
+++ b/usr/src/lib/libdscp/libdscp.h
@@ -0,0 +1,72 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * 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.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _LIBDSCP_H
+#define _LIBDSCP_H
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * DSCP Error Codes
+ */
+typedef enum {
+ DSCP_OK = 0, /* Success */
+ DSCP_ERROR, /* General Error */
+ DSCP_ERROR_ALREADY, /* Socket Already Bound */
+ DSCP_ERROR_INVALID, /* Invalid Arguments */
+ DSCP_ERROR_NOENT, /* Lookup Failure From dscpIdent() */
+ DSCP_ERROR_DB, /* Error Reading Database */
+ DSCP_ERROR_REJECT /* Rejection From dscpAuth() */
+} dscp_err_t;
+
+/*
+ * Possible values for the 'which' parameter to dscpAddr().
+ */
+#define DSCP_ADDR_LOCAL (1) /* Get the domain's local IP address */
+#define DSCP_ADDR_REMOTE (2) /* Get the SP's remote IP address */
+
+/*
+ * Define a special value used to represent the SP as a domain ID.
+ */
+#define DSCP_IDENT_SP (-1)
+
+int dscpBind(int domain, int sockfd, int port);
+int dscpSecure(int domain, int sockfd);
+int dscpAuth(int domain, struct sockaddr *saddr, int len);
+int dscpAddr(int domain, int which, struct sockaddr *saddr, int *lenp);
+int dscpIdent(struct sockaddr *saddr, int len, int *domainp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _LIBDSCP_H */
diff --git a/usr/src/lib/libdscp/llib-ldscp b/usr/src/lib/libdscp/llib-ldscp
new file mode 100644
index 0000000000..b4ce6b9926
--- /dev/null
+++ b/usr/src/lib/libdscp/llib-ldscp
@@ -0,0 +1,32 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * 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.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*LINTLIBRARY*/
+/*PROTOLIB1*/
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ * usr/src/lib/libdscp/llib-ldscp
+ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+#include <libdscp.h>
diff --git a/usr/src/lib/libdscp/sparc/Makefile b/usr/src/lib/libdscp/sparc/Makefile
new file mode 100644
index 0000000000..22bf606d7a
--- /dev/null
+++ b/usr/src/lib/libdscp/sparc/Makefile
@@ -0,0 +1,35 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# 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.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# lib/libdscp/sparc/Makefile
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+MAPDIR= ../spec/sparc
+include ../Makefile.com
+
+all: $(LIBS)
+
+install: all $(ROOTLIBS) $(ROOTLINKS)
diff --git a/usr/src/lib/libdscp/spec/Makefile b/usr/src/lib/libdscp/spec/Makefile
new file mode 100644
index 0000000000..048c9a5306
--- /dev/null
+++ b/usr/src/lib/libdscp/spec/Makefile
@@ -0,0 +1,61 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# 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.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# lib/libdscp/spec/Makefile
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+SUBDIRS= sparc
+
+all := TARGET= all
+install := TARGET= install
+clean := TARGET= clean
+clobber := TARGET= clobber
+lint := TARGET= lint
+
+.KEEP_STATE:
+
+all install clean clobber: ${SUBDIRS}
+
+${SUBDIRS}: FRC
+ @cd $@; pwd; ${MAKE} ${TARGET}
+
+#
+# This will make sure that any target not
+# explicitly defined will not break the build.
+#
+# XXX pmake on intel does not like the following rules
+# %: ignore_and_exit_quietly
+# ignore_and_exit_quietly:
+#
+# So here it is manually
+#
+IGNORE= _msg catalog install_h delete \
+ package tcov debug private_t \
+ check analyze test dynamic lint
+
+${IGNORE}:
+
+FRC:
diff --git a/usr/src/lib/libdscp/spec/Makefile.targ b/usr/src/lib/libdscp/spec/Makefile.targ
new file mode 100644
index 0000000000..c9f02d8818
--- /dev/null
+++ b/usr/src/lib/libdscp/spec/Makefile.targ
@@ -0,0 +1,35 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# 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.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# lib/libdscp/spec/Makefile.targ
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+LIBRARY = libdscp.a
+VERS = .1
+
+OBJECTS = libdscp.o
+
+SPECCPP = -I../..
diff --git a/usr/src/lib/libdscp/spec/libdscp.spec b/usr/src/lib/libdscp/spec/libdscp.spec
new file mode 100644
index 0000000000..91cdd7c540
--- /dev/null
+++ b/usr/src/lib/libdscp/spec/libdscp.spec
@@ -0,0 +1,56 @@
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# 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.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# lib/libdscp/spec/libdscp.spec
+#
+#ident "%Z%%M% %I% %E% SMI"
+
+function dscpBind
+include <libdscp.h>
+declaration int dscpBind(int, int, int)
+version SUNWprivate_1.1
+end
+
+function dscpSecure
+include <libdscp.h>
+declaration int dscpSecure(int, int)
+version SUNWprivate_1.1
+end
+
+function dscpAuth
+include <libdscp.h>
+declaration int dscpAuth(int, struct sockaddr *, int)
+version SUNWprivate_1.1
+end
+
+function dscpAddr
+include <libdscp.h>
+declaration int dscpAddr(int, int, struct sockaddr *, int *)
+version SUNWprivate_1.1
+end
+
+function dscpIdent
+include <libdscp.h>
+declaration int dscpIdent(struct sockaddr *, int, int *)
+version SUNWprivate_1.1
+end
diff --git a/usr/src/lib/libdscp/spec/sparc/Makefile b/usr/src/lib/libdscp/spec/sparc/Makefile
new file mode 100644
index 0000000000..79205aad21
--- /dev/null
+++ b/usr/src/lib/libdscp/spec/sparc/Makefile
@@ -0,0 +1,38 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# 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.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# lib/libdscp/spec/sparc/Makefile
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+.KEEP_STATE:
+
+include ../Makefile.targ
+
+include $(SRC)/lib/Makefile.lib
+
+include $(SRC)/lib/Makefile.spec
+
+install: $(ROOTABILIB)
diff --git a/usr/src/lib/libdscp/spec/versions b/usr/src/lib/libdscp/spec/versions
new file mode 100644
index 0000000000..bbebe2a784
--- /dev/null
+++ b/usr/src/lib/libdscp/spec/versions
@@ -0,0 +1,31 @@
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# 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.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# usr/src/lib/libdscp/spec/versions
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+sparc {
+ SUNWprivate_1.1;
+}
diff --git a/usr/src/lib/libdscp/svc/Makefile b/usr/src/lib/libdscp/svc/Makefile
new file mode 100644
index 0000000000..8a34b10cca
--- /dev/null
+++ b/usr/src/lib/libdscp/svc/Makefile
@@ -0,0 +1,56 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# 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.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# lib/libdscp/svc/Makefile.com
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+MANIFEST= dscp.xml
+SVCMETHOD= svc-dscp
+
+include ../../../cmd/Makefile.cmd
+
+.KEEP_STATE:
+
+# definitions for installing the manifest
+ROOTMANIFESTDIR = $(ROOTSVCPLATFORMSUN4U)
+$(ROOTMANIFEST) := FILEMODE = 0444
+
+# definitions for installing the PPP options
+OPTIONS = dscp.ppp.options
+ROOTOPTIONSDIR = $(ROOT)/usr/platform/SUNW,SPARC-Enterprise/lib
+ROOTOPTIONS = $(OPTIONS:%=$(ROOTOPTIONSDIR)/%)
+
+$(ROOTOPTIONSDIR):
+ $(INS.dir)
+
+$(ROOTOPTIONSDIR)/%: %
+ $(INS.file)
+
+all clean clobber lint:
+
+install: $(ROOTMANIFEST) $(ROOTSVCMETHOD) $(ROOTOPTIONS)
+
+check: $(CHKMANIFEST)
diff --git a/usr/src/lib/libdscp/svc/dscp.ppp.options b/usr/src/lib/libdscp/svc/dscp.ppp.options
new file mode 100644
index 0000000000..d46df31de3
--- /dev/null
+++ b/usr/src/lib/libdscp/svc/dscp.ppp.options
@@ -0,0 +1,112 @@
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# 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.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+# dscp.ppp.options
+#
+#ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# These are options for running pppd(1M) to provide a DSCP
+# link between a service processor and a domain in OPL. All
+# options are explicitly set here so that site customizations
+# of the global options files will not affect DSCP.
+#
+
+#
+# Generic pppd options.
+#
+persist
+noplink
+lock
+nolog
+maxfail 0
+holdoff 5
+noproxyarp
+linkname dscp
+
+#
+# Physical link properties.
+#
+sync
+local
+nocrtscts
+nocdtrcts
+default-fcs
+mtu 1500
+mru 1500
+
+#
+# Configure LCP.
+#
+passive
+noendpoint
+lcp-echo-failure 6
+lcp-echo-interval 5
+lcp-max-configure 10
+lcp-max-failure 10
+lcp-max-terminate 3
+lcp-restart 3
+
+#
+# Configure the IPv4 NCP.
+# IP addresses are given by the peer.
+#
+0:0
+noipv6
+noipdefault
+nodefaultroute
+ipcp-accept-local
+ipcp-accept-remote
+ipcp-max-configure 10
+ipcp-max-failure 10
+ipcp-max-terminate 3
+ipcp-restart 3
+
+#
+# Disable all authentication.
+#
+noauth
+noident
+nopam
+refuse-pap
+refuse-chap
+refuse-mschap
+refuse-mschapv2
+
+#
+# Disable all compression.
+#
+novj
+noccp
+nopcomp
+noaccomp
+nobsdcomp
+
+#
+# Disable all scripts.
+#
+init /bin/true
+welcome /bin/true
+connect /bin/true
+disconnect /bin/true
diff --git a/usr/src/lib/libdscp/svc/dscp.xml b/usr/src/lib/libdscp/svc/dscp.xml
new file mode 100644
index 0000000000..f3f6565098
--- /dev/null
+++ b/usr/src/lib/libdscp/svc/dscp.xml
@@ -0,0 +1,121 @@
+<?xml version="1.0"?>
+<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
+<!--
+ Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ Use is subject to license terms.
+
+ CDDL HEADER START
+
+ The contents of this file are subject to the terms of the
+ 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.
+ See the License for the specific language governing permissions
+ and limitations under the License.
+
+ When distributing Covered Code, include this CDDL HEADER in each
+ file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ If applicable, add the following below this CDDL HEADER, with the
+ fields enclosed by brackets "[]" replaced with your own identifying
+ information: Portions Copyright [yyyy] [name of copyright owner]
+
+ CDDL HEADER END
+
+ ident "%Z%%M% %I% %E% SMI"
+
+ NOTE: This service manifest is not editable; its contents will
+ be overwritten by package or patch operations, including
+ operating system upgrade. Make customizations in a different
+ file.
+-->
+
+<service_bundle type='manifest' name='SUNW:dscp'>
+
+<service
+ name='platform/sun4u/dscp'
+ type='service'
+ version='1'>
+
+ <create_default_instance enabled='false' />
+
+ <single_instance />
+
+ <dependency
+ name='network'
+ grouping='require_any'
+ restart_on='error'
+ type='service'>
+ <service_fmri value='svc:/milestone/network' />
+ </dependency>
+
+ <dependency
+ name='local-filesystems'
+ type='service'
+ grouping='require_all'
+ restart_on='none'>
+ <service_fmri value='svc:/system/filesystem/local' />
+ </dependency>
+
+ <dependency
+ name='sckmd'
+ type='service'
+ grouping='optional_all'
+ restart_on='none'>
+ <service_fmri value='svc:/platform/sun4u/sckmd:default' />
+ </dependency>
+
+ <dependent
+ name='dcs'
+ grouping='optional_all'
+ restart_on='none'>
+ <service_fmri value='svc:/platform/sun4u/dcs:default' />
+ </dependent>
+
+ <dependent
+ name='fmd'
+ grouping='optional_all'
+ restart_on='none'>
+ <service_fmri value='svc:/system/fmd:default' />
+ </dependent>
+
+ <exec_method
+ type='method'
+ name='start'
+ exec='/lib/svc/method/svc-dscp %m'
+ timeout_seconds='60' />
+
+ <exec_method
+ type='method'
+ name='refresh'
+ exec='/lib/svc/method/svc-dscp %m'
+ timeout_seconds='60' />
+
+ <exec_method
+ type='method'
+ name='stop'
+ exec='/lib/svc/method/svc-dscp %m'
+ timeout_seconds='60' />
+
+ <property_group name='application' type='framework'>
+ <stability value='Evolving' />
+ <propval name='auto_enable' type='boolean' value='true' />
+ </property_group>
+
+ <stability value='Evolving' />
+
+ <template>
+ <common_name>
+ <loctext xml:lang='C'>
+ DSCP Service
+ </loctext>
+ </common_name>
+ <documentation>
+ <manpage title='??' section='1M'
+ manpath='/usr/share/man' />
+ </documentation>
+ </template>
+</service>
+
+</service_bundle>
diff --git a/usr/src/lib/libdscp/svc/svc-dscp b/usr/src/lib/libdscp/svc/svc-dscp
new file mode 100644
index 0000000000..f8f79e81a2
--- /dev/null
+++ b/usr/src/lib/libdscp/svc/svc-dscp
@@ -0,0 +1,111 @@
+#!/bin/sh
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# 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.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Use is subject to license terms.
+#
+# ident "%Z%%M% %I% %E% SMI"
+#
+
+#
+# Start script for the SPARC-Enterprise DSCP service.
+#
+
+. /lib/svc/share/smf_include.sh
+
+OPL=SUNW,SPARC-Enterprise
+FJOPL=FJSV,SPARC-Enterprise
+TMPOPL=SUNW,OPL-Enterprise
+OPL_LIB=/usr/platform/${OPL}/lib
+DM2S_DEVICE=/dev/dm2s0
+PPP_OPTIONS=${OPL_LIB}/dscp.ppp.options
+DSCP_IFNAME=/var/run/dscp.ifname
+PRTDSCP=/usr/platform/${OPL}/sbin/prtdscp
+PLATFORM=`/sbin/uname -i`
+SLEEP=/bin/sleep
+PKILL=/bin/pkill
+
+LD_LIBRARY_PATH=/lib:${OPL_LIB}; export LD_LIBRARY_PATH
+
+# This service can only run on OPL.
+if [ "${PLATFORM}" != "${OPL}" -a \
+ "${PLATFORM}" != "${FJOPL}" -a \
+ "${PLATFORM}" != "${TMPOPL}" ]; then
+
+ exit $SMF_EXIT_ERR_CONFIG
+fi
+
+case "$1" in
+'start')
+
+ if [ ! -x /usr/bin/pppd ]; then
+ exit $SMF_EXIT_ERR_CONFIG
+ fi
+
+ if [ ! -c $DM2S_DEVICE ]; then
+ exit $SMF_EXIT_ERR_CONFIG
+ fi
+
+ if [ ! -f $PPP_OPTIONS ]; then
+ exit $SMF_EXIT_ERR_CONFIG
+ fi
+
+ SUCCESS=0
+ for UNIT in 0 1 2 3 4 5 6 7 8 9; do
+ /usr/bin/pppd $DM2S_DEVICE unit $UNIT file $PPP_OPTIONS
+ if [ ! "$?" = "1" ]; then
+ echo "sppp$UNIT" > $DSCP_IFNAME
+ SUCCESS=1
+ break
+ fi
+ done
+
+ if [ $SUCCESS -ne 1 ]; then
+ exit $SMF_EXIT_ERR_FATAL
+ fi
+
+ # Wait for the DSCP link to come up, but only for 30 seconds
+ for RETRY in 0 1 2 3 4 5; do
+ ${PRTDSCP} >/dev/null 2>&1
+ if [ $? -eq 0 ]; then
+ exit $SMF_EXIT_OK
+ fi
+ ${SLEEP} 5
+ done
+
+ # Stop pppd before we return failure
+ ${PKILL} -TERM -f "pppd ${DM2S_DEVICE}"
+ ${SLEEP} 1
+ ${PKILL} -KILL -f "pppd ${DM2S_DEVICE}"
+ rm -f $DSCP_IFNAME
+ exit $SMF_EXIT_ERR_FATAL
+ ;;
+
+'stop')
+ # First try SIGTERM and then SIGKILL
+ ${PKILL} -TERM -f "pppd ${DM2S_DEVICE}"
+ ${SLEEP} 1
+ ${PKILL} -KILL -f "pppd ${DM2S_DEVICE}"
+ rm -f $DSCP_IFNAME
+ exit $SMF_EXIT_OK
+ ;;
+esac