--- old/exception_lists/packaging	2012-06-12 19:54:33.122508956 +0200
+++ new/exception_lists/packaging	2012-06-12 19:54:33.180842654 +0200
@@ -358,8 +358,6 @@
 usr/include/sys/net80211_proto.h
 usr/include/sys/net80211.h
 #
-usr/include/net/wpa.h
-#
 # PPPoE files not delivered to customers.
 #
 usr/include/net/pppoe.h
--- old/usr/src/Makefile.lint	2012-06-12 19:54:34.699965739 +0200
+++ new/usr/src/Makefile.lint	2012-06-12 19:54:34.723836845 +0200
@@ -79,7 +79,6 @@
 	cmd/cmd-inet/usr.lib/pppoe \
 	cmd/cmd-inet/usr.lib/slpd \
 	cmd/cmd-inet/usr.lib/vrrpd \
-	cmd/cmd-inet/usr.lib/wpad \
 	cmd/cmd-inet/usr.lib/wanboot \
 	cmd/cmd-inet/usr.sadm \
 	cmd/cmd-inet/usr.sbin \
--- old/usr/src/cmd/Makefile.check	2012-06-12 19:54:35.855666683 +0200
+++ new/usr/src/cmd/Makefile.check	2012-06-12 19:54:35.879456730 +0200
@@ -92,7 +92,7 @@
 	cmd-inet/usr.lib/mdnsd		\
 	cmd-inet/usr.lib/slpd		\
 	cmd-inet/usr.lib/vrrpd		\
-	cmd-inet/usr.lib/wpad		\
+	cmd-inet/usr.lib/wpa_supplicant	\
 	cmd-inet/usr.sbin		\
 	cmd-inet/usr.sbin/in.ftpd	\
 	cmd-inet/usr.sbin/in.rdisc	\
--- old/usr/src/cmd/cmd-inet/lib/nwamd/known_wlans.c	2012-06-12 19:54:36.774284973 +0200
+++ new/usr/src/cmd/cmd-inet/lib/nwamd/known_wlans.c	2012-06-12 19:54:36.797938701 +0200
@@ -275,8 +275,8 @@
 			nlog(LOG_DEBUG, "find_secobj_matching_prefix: "
 			    "got WEP key %s", nsa->nsa_keyname);
 			break;
-		case DLADM_SECOBJ_CLASS_WPA:
-			nsa->nsa_secmode = DLADM_WLAN_SECMODE_WPA;
+		case DLADM_SECOBJ_CLASS_PSK:
+			nsa->nsa_secmode = DLADM_WLAN_SECMODE_PSK;
 			nlog(LOG_DEBUG, "find_secobj_matching_prefix: "
 			    "got WPA key %s", nsa->nsa_keyname);
 			break;
--- old/usr/src/cmd/cmd-inet/lib/nwamd/ncu_phys.c	2012-06-12 19:54:37.804472336 +0200
+++ new/usr/src/cmd/cmd-inet/lib/nwamd/ncu_phys.c	2012-06-12 19:54:37.828329385 +0200
@@ -218,12 +218,17 @@
 	free(hwaddr);
 }
 
+/* not used */
 #define	WLAN_ENC(sec)						\
-	((sec == DLADM_WLAN_SECMODE_WPA ? "WPA" : 		\
+	((sec == DLADM_WLAN_SECMODE_PSK ? "WPA" : 		\
 	(sec == DLADM_WLAN_SECMODE_WEP ? "WEP" : "none")))
 
+/*
+ * NEED_END should return false and when DLADM_WLAN_AUTH_NONE is set
+ * (key_mgmt=NONE in wpa_s conf) (!not key_mgmt=WPA-NONE)
+ */
 #define	NEED_ENC(sec)						\
-	(sec == DLADM_WLAN_SECMODE_WPA || sec == DLADM_WLAN_SECMODE_WEP)
+	(sec == DLADM_WLAN_SECMODE_PSK || sec == DLADM_WLAN_SECMODE_WEP)
 
 #define	WIRELESS_LAN_INIT_COUNT	8
 
@@ -301,7 +306,7 @@
 	nlog(LOG_DEBUG, "after: key_string_to_secobj_value: buf_len = %d",
 	    buf_len);
 
-	if (class == DLADM_SECOBJ_CLASS_WPA) {
+	if (class == DLADM_SECOBJ_CLASS_PSK) {
 		/*
 		 * Per IEEE802.11i spec, the Pre-shared key (PSK) length should
 		 * be between 8 and 63.
@@ -428,7 +433,7 @@
 	nlog(LOG_DEBUG, "store_key: obj_name is %s", obj_name);
 
 	class = (security_mode == DLADM_WLAN_SECMODE_WEP ?
-	    DLADM_SECOBJ_CLASS_WEP : DLADM_SECOBJ_CLASS_WPA);
+	    DLADM_SECOBJ_CLASS_WEP : DLADM_SECOBJ_CLASS_PSK);
 	if (key_string_to_secobj_value(raw_key, obj_val, &obj_len,
 	    class) != 0) {
 		/* above function logs internally on failure */
@@ -573,8 +578,8 @@
 			if (security_mode == DLADM_WLAN_SECMODE_WEP)
 				return (cooked_key);
 			break;
-		case DLADM_SECOBJ_CLASS_WPA:
-			if (security_mode == DLADM_WLAN_SECMODE_WPA)
+		case DLADM_SECOBJ_CLASS_PSK:
+			if (security_mode == DLADM_WLAN_SECMODE_PSK)
 				return (cooked_key);
 			break;
 		default:
@@ -590,6 +595,8 @@
 		return (NULL);
 	}
 
+	cooked_key->wk_class = class;
+
 	return (cooked_key);
 }
 
@@ -1474,7 +1481,7 @@
 
 	scanconnect_entry();
 	status = dladm_wlan_connect(dld_handle, link_id, attrp,
-	    DLADM_WLAN_CONNECT_TIMEOUT_DEFAULT, key, keycount, flags);
+	    DLADM_WLAN_CONNECT_TIMEOUT_DEFAULT, key, keycount, flags, NULL);
 	scanconnect_exit();
 
 	nlog(LOG_DEBUG, "nwamd_do_connect: dladm_wlan_connect returned %s",
@@ -1585,8 +1592,7 @@
 
 	nwamd_object_release(ncu_obj);
 
-	status = do_connect(link_id, &attr, key, keycount,
-	    DLADM_WLAN_CONNECT_NOSCAN);
+	status = do_connect(link_id, &attr, key, keycount, 0);
 	if (status != DLADM_STATUS_OK) {
 		/* Connect failed, try autoconf */
 		if (!wireless_autoconf || (status = do_connect(link_id, &attr,
--- old/usr/src/cmd/cmd-inet/usr.lib/Makefile	2012-06-12 19:54:39.825821553 +0200
+++ new/usr/src/cmd/cmd-inet/usr.lib/Makefile	2012-06-12 19:54:39.849338727 +0200
@@ -26,7 +26,7 @@
 SUBDIRS=	bridged dhcp dsvclockd ilbd in.chargend in.daytimed \
 		in.discardd in.echod in.dhcpd in.mpathd in.ndpd \
 		in.ripngd in.timed inetd mdnsd ncaconfd pppoe \
-		slpd vrrpd wanboot wpad
+		slpd vrrpd wanboot wpa_supplicant
 
 MSGSUBDIRS=	dsvclockd ilbd in.dhcpd inetd ncaconfd vrrpd wanboot
 
--- /dev/null	2012-06-12 19:54:40.000000000 +0200
+++ new/usr/src/cmd/cmd-inet/usr.lib/wpa_supplicant/Makefile	2012-06-12 19:54:40.962330722 +0200
@@ -0,0 +1,52 @@
+#
+# 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 2012 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+include	../../../Makefile.cmd
+
+SUBDIR=		wpa_supplicant
+MANIFEST =	wpa_supplicant.xml
+
+ROOTMANIFESTDIR = $(ROOTSVCNETWORK)
+
+all:=		TARGET= all
+install:=	TARGET= install
+clean:=		TARGET= clean
+clobber:=	TARGET= clobber
+
+.KEEP_STATE:
+
+all lint clean clobber:	$(SUBDIR)
+
+include ../Makefile.lib
+
+install:	$(SUBDIR) $(ROOTMANIFEST)
+
+check:		$(CHKMANIFEST)
+
+$(SUBDIR):	FRC
+		@cd $@; pwd; $(MAKE) $(TARGET)
+
+FRC:
+
+include ../../../Makefile.targ
--- /dev/null	2012-06-12 19:54:41.000000000 +0200
+++ new/usr/src/cmd/cmd-inet/usr.lib/wpa_supplicant/wpa_supplicant.xml	2012-06-12 19:54:41.172027184 +0200
@@ -0,0 +1,130 @@
+<?xml version="1.0"?>
+<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
+<!--
+	Copyright 2007 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='SUNWsupr:wpa_supplicant'>
+
+<service
+	name='network/wpa_supplicant'
+	type='service'
+	version='1'>
+	<single_instance/>
+	<dependency
+	    name='cryptosvc'
+	    grouping='require_all'
+	    restart_on='none'
+	    type='service'>
+		<service_fmri value='svc:/system/cryptosvc' />
+	</dependency>
+
+	<!--
+	    The wpa service will require the crypto framework for
+	    PKCS #11 keystores/certificates configuration
+	-->
+
+	<!--
+	    If wpa_supplicant crashes for some reasons,
+	    it will replace any existing file named
+	    /var/run/wpa_supplicant-global. So we do not need to manage the
+	    cleanup of the global UNIX socket.
+	    Socket clients are cleaned up in libdlwlan.
+
+	    B=background
+	    dd=debugging
+	    f=use syslog
+	    t=print timestamp
+	    W=wait for libdlwlan/dladm to add an interface before doing anything
+	-->
+
+	<exec_method
+		type='method'
+		name='start'
+		exec='/usr/lib/inet/wpa_supplicant -B -f/var/log/wpa_supplicant.log -dd -K -W -g/var/run/wpa_supplicant-global'
+		timeout_seconds='60'>
+			<method_context>
+				<method_credential
+				user='root'
+				group='root'
+				limit_privileges=':default'
+				privileges='basic,sys_net_config,net_rawaccess'
+				/>
+			</method_context>
+	</exec_method>
+
+	<exec_method
+		type='method'
+		name='stop'
+		exec=':kill'
+		timeout_seconds='60'>
+			<method_context>
+				<method_credential
+				user='root'
+				group='root'
+				limit_privileges=':default'
+				privileges='basic,sys_net_config,net_rawaccess'
+				/>
+			</method_context>
+	</exec_method>
+
+<!--
+	<exec_method
+		type='method'
+		name='refresh'
+		exec=':kill'
+		timeout_seconds='60' />
+-->
+
+        <property_group name='general' type='framework'>
+                <!-- to start stop wpad -->
+                <propval name='action_authorization' type='astring'
+                        value='solaris.smf.manage.wpa' />
+        </property_group>
+
+       	<instance name="default" enabled="true">
+ 	</instance>
+
+	<stability value='External' />
+
+	<template>
+		<common_name>
+			<loctext xml:lang='C'>
+			Wireless WPA Supplicant
+			</loctext>
+		</common_name>
+		<documentation>
+			<manpage title='wpa_supplicant' section='1M'
+			    manpath='/usr/share/man' />
+		</documentation>
+	</template>
+</service>
+
+</service_bundle>
--- /dev/null	2012-06-12 19:54:41.000000000 +0200
+++ new/usr/src/cmd/cmd-inet/usr.lib/wpa_supplicant/wpa_supplicant/Makefile	2012-06-12 19:54:41.411541237 +0200
@@ -0,0 +1,86 @@
+#
+# 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 2012 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+PROG =		wpa_supplicant
+OBJS =		config.o notify.o bss.o eap_register.o ../src/utils/common.o \
+../src/utils/wpa_debug.o ../src/utils/wpabuf.o ../src/utils/os_unix.o \
+../src/utils/eloop.o config_file.o ../src/rsn_supp/wpa.o \
+../src/rsn_supp/preauth.o ../src/rsn_supp/pmksa_cache.o \
+../src/rsn_supp/peerkey.o ../src/rsn_supp/wpa_ie.o ../src/common/wpa_common.o \
+../src/eap_peer/eap_tls.o ../src/eap_peer/eap_peap.o \
+../src/eap_common/eap_peap_common.o ../src/eap_peer/eap_ttls.o \
+../src/eap_peer/eap_md5.o ../src/eap_peer/eap_mschapv2.o \
+../src/eap_peer/mschapv2.o ../src/eapol_supp/eapol_supp_sm.o \
+../src/eap_peer/eap.o ../src/eap_peer/eap_methods.o ../src/crypto/ms_funcs.o \
+../src/eap_common/chap.o ../src/eap_peer/eap_tls_common.o \
+../src/crypto/tls_openssl.o ../src/crypto/crypto_openssl.o \
+../src/crypto/aes-unwrap.o ../src/crypto/md5.o ../src/crypto/random.o \
+ctrl_iface.o ctrl_iface_unix.o ../src/utils/base64.o \
+../src/eap_common/eap_common.o ../src/crypto/sha1.o ../src/crypto/sha1-pbkdf2.o \
+../src/crypto/sha1-tlsprf.o ../src/drivers/driver_common.o wpa_supplicant.o \
+events.o blacklist.o wpas_glue.o scan.o main.o ../src/drivers/driver_solaris.o \
+../src/drivers/drivers.o ../src/l2_packet/l2_packet_solaris.o
+
+SRCS = 		$(OBJS:%.o=%.c)
+
+LINTME =	../src/drivers/driver_solaris.c
+
+include	../../../../Makefile.cmd
+
+MSGFILES=	$(OBJS)
+
+C99MODE =	$(C99_ENABLE)
+CFLAGS += 	-I../src -I../src/utils
+CFLAGS += 	-DCONFIG_BACKEND_FILE \
+ -DCONFIG_DRIVER_SOLARIS -DEAP_TLS -DEAP_PEAP -DEAP_TTLS -DEAP_MD5 \
+ -DEAP_MSCHAPv2 -DIEEE8021X_EAPOL -DPKCS12_FUNCS -DCONFIG_SMARTCARD \
+ -DEAP_TLS_OPENSSL -DCONFIG_CTRL_IFACE -DCONFIG_CTRL_IFACE_UNIX \
+ -DCONFIG_DEBUG_SYSLOG -DLOG_HOSTAPD="LOG_DAEMON" -DCONFIG_DEBUG_FILE
+
+LDLIBS += 	-lsocket -ldlpi -ldladm
+
+all install := LDLIBS += -lcrypto -lssl
+
+LINTFLAGS += 	-u
+
+.KEEP_STATE:
+
+all:		$(PROG)
+
+%.o:		%.c
+		$(COMPILE.c) -o $@ $<
+
+$(PROG):	$(OBJS)
+		$(LINK.c) -o $@ $(OBJS) $(LDLIBS)
+		$(POST_PROCESS)
+
+
+include ../../Makefile.lib
+
+install:	all $(ROOTLIBINETPROG)
+
+clean:
+		$(RM) $(OBJS)
+
+include ../../../../Makefile.targ
--- old/usr/src/cmd/cmd-inet/usr.sbin/Makefile	2012-06-12 19:54:41.616637020 +0200
+++ new/usr/src/cmd/cmd-inet/usr.sbin/Makefile	2012-06-12 19:54:41.640497653 +0200
@@ -68,11 +68,11 @@
 SUBDIRS=	bootconfchk htable ifconfig ilbadm in.ftpd in.rdisc in.routed \
 		in.talkd inetadm inetconv ipadm ipmpstat ipqosconf ipsecutils \
 		kssl/kssladm kssl/ksslcfg nwamadm nwamcfg ping routeadm \
-		snoop sppptun traceroute wificonfig
+		snoop sppptun traceroute
 
 MSGSUBDIRS=	bootconfchk htable ifconfig ilbadm in.ftpd in.routed in.talkd \
 		inetadm inetconv ipadm ipmpstat ipqosconf ipsecutils \
-		kssl/ksslcfg nwamadm nwamcfg routeadm sppptun snoop wificonfig
+		kssl/ksslcfg nwamadm nwamcfg routeadm sppptun snoop
 
 # As programs get lint-clean, add them here and to the 'lint' target.
 # Eventually this hack should go away, and all in PROG should be
@@ -86,8 +86,7 @@
 # for the lint rule.
 LINTSUBDIRS=	bootconfchk ilbadm in.rdisc in.routed in.talkd inetadm \
 		inetconv ipmpstat ipqosconf ipsecutils kssl/kssladm \
-		kssl/ksslcfg nwamadm nwamcfg ping routeadm sppptun traceroute \
-		wificonfig
+		kssl/ksslcfg nwamadm nwamcfg ping routeadm sppptun traceroute
 # And as programs are verified not to attempt to write into constants,
 # -xstrconst should be used to ensure they stay that way.
 CONSTCLEAN=
--- old/usr/src/cmd/dladm/dladm.c	2012-06-12 19:54:42.534757661 +0200
+++ new/usr/src/cmd/dladm/dladm.c	2012-06-12 19:54:42.585653814 +0200
@@ -290,8 +290,8 @@
 	{ "scan-wifi",		do_scan_wifi,
 	    "    scan-wifi        [-p] [-o <field>,...] [<link>]"	},
 	{ "connect-wifi",	do_connect_wifi,
-	    "    connect-wifi     [-e <essid>] [-i <bssid>] [-k <key>,...] "
-	    "[-s wep|wpa]\n"
+	    "    connect-wifi     [-e <essid>] [-i <bssid>] [-k <key>,...]\n"
+	    "\t\t     [-s wep|wpa] [-u <username>]\n"
 	    "\t\t     [-a open|shared] [-b bss|ibss] [-c] [-m a|b|g] "
 	    "[-T <time>]\n"
 	    "\t\t     [<link>]"						},
@@ -6264,10 +6264,11 @@
 	uint_t			flags = 0;
 	dladm_wlan_secmode_t	keysecmode = DLADM_WLAN_SECMODE_NONE;
 	char			buf[DLADM_STRSIZE];
+	char			identity[128];
 
 	opterr = 0;
 	(void) memset(&attr, 0, sizeof (attr));
-	while ((option = getopt_long(argc, argv, ":e:i:a:m:b:s:k:T:c",
+	while ((option = getopt_long(argc, argv, ":e:i:a:m:b:s:k:u:T:c",
 	    wifi_longopts, NULL)) != -1) {
 		switch (option) {
 		case 'e':
@@ -6276,10 +6277,6 @@
 				die("invalid ESSID '%s'", optarg);
 
 			attr.wa_valid |= DLADM_WLAN_ATTR_ESSID;
-			/*
-			 * Try to connect without doing a scan.
-			 */
-			flags |= DLADM_WLAN_CONNECT_NOSCAN;
 			break;
 		case 'i':
 			status = dladm_wlan_str2bssid(optarg, &attr.wa_bssid);
@@ -6324,8 +6321,14 @@
 
 			if (keys[0].wk_class == DLADM_SECOBJ_CLASS_WEP)
 				keysecmode = DLADM_WLAN_SECMODE_WEP;
+			else if (keys[0].wk_class == DLADM_SECOBJ_CLASS_PSK)
+				keysecmode = DLADM_WLAN_SECMODE_PSK;
 			else
-				keysecmode = DLADM_WLAN_SECMODE_WPA;
+				keysecmode = DLADM_WLAN_SECMODE_EAP;
+			break;
+		case 'u':
+			if (snprintf(identity, 131, "\"%s\"", optarg) <= 0)
+				die("invalid username", optarg);
 			break;
 		case 'T':
 			if (strcasecmp(optarg, "forever") == 0) {
@@ -6346,14 +6349,17 @@
 	}
 
 	if (keysecmode == DLADM_WLAN_SECMODE_NONE) {
-		if ((attr.wa_valid & DLADM_WLAN_ATTR_SECMODE) != 0) {
+		if ((attr.wa_valid & DLADM_WLAN_ATTR_SECMODE) != 0)
 			die("key required for security mode '%s'",
 			    dladm_wlan_secmode2str(&attr.wa_secmode, buf));
-		}
 	} else {
 		if ((attr.wa_valid & DLADM_WLAN_ATTR_SECMODE) != 0 &&
 		    attr.wa_secmode != keysecmode)
 			die("incompatible -s and -k options");
+		if ((keysecmode == DLADM_WLAN_SECMODE_EAP) != 0 &&
+		    identity == NULL)
+			die("username (-u) required for security mode '%s'",
+			    dladm_wlan_secmode2str(&attr.wa_secmode, buf));
 		attr.wa_valid |= DLADM_WLAN_ATTR_SECMODE;
 		attr.wa_secmode = keysecmode;
 	}
@@ -6384,17 +6390,9 @@
 		linkid = wcattr.wc_linkid;
 	}
 	attrp = (attr.wa_valid == 0) ? NULL : &attr;
-again:
-	if ((status = dladm_wlan_connect(handle, linkid, attrp, timeout, keys,
-	    key_count, flags)) != DLADM_STATUS_OK) {
-		if ((flags & DLADM_WLAN_CONNECT_NOSCAN) != 0) {
-			/*
-			 * Try again with scanning and filtering.
-			 */
-			flags &= ~DLADM_WLAN_CONNECT_NOSCAN;
-			goto again;
-		}
 
+	if ((status = dladm_wlan_connect(handle, linkid, attrp, timeout, keys,
+	    key_count, flags, identity)) != DLADM_STATUS_OK) {
 		if (status == DLADM_STATUS_NOTFOUND) {
 			if (attr.wa_valid == 0) {
 				die("no wifi networks are available");
@@ -7041,15 +7039,13 @@
 {
 	int error = 0;
 
-	if (class == DLADM_SECOBJ_CLASS_WPA) {
-		if (len < 8 || len > 63)
+	if (class != DLADM_SECOBJ_CLASS_WEP) {
+		if ((class == DLADM_SECOBJ_CLASS_PSK) && (len < 8 || len > 63))
 			return (EINVAL);
 		(void) memcpy(obj_val, buf, len);
 		*obj_lenp = len;
 		return (error);
-	}
-
-	if (class == DLADM_SECOBJ_CLASS_WEP) {
+	} else {
 		switch (len) {
 		case 5:			/* ASCII key sizes */
 		case 13:
--- old/usr/src/cmd/svc/milestone/net-physical	2012-06-12 19:54:49.403998569 +0200
+++ new/usr/src/cmd/svc/milestone/net-physical	2012-06-12 19:54:49.425248563 +0200
@@ -259,17 +259,6 @@
 	[ -n "$inet_failed" ] && warn_failed_ifs "plumb IPv4" "$inet_failed"
 fi
 
-# Run autoconf to connect to a WLAN if the interface is a wireless one
-if [ -x /sbin/wificonfig -a -n "$inet_plumbed" ]; then
-	set -- $inet_plumbed
-	while [ $# -gt 0 ]; do
-			if [ -r /dev/wifi/$1 ]; then
-				/sbin/wificonfig -i $1 startconf >/dev/null
-			fi
-		shift
-	done
-fi
-
 #
 # Step through the IPv6 interface list and plumb every interface.
 # Generate list of plumbed and failed IPv6 interfaces.  Each plumbed
--- old/usr/src/cmd/svc/milestone/network-physical.xml	2012-06-12 19:54:50.730859371 +0200
+++ new/usr/src/cmd/svc/milestone/network-physical.xml	2012-06-12 19:54:50.754700614 +0200
@@ -93,6 +93,20 @@
 
 	<instance name='nwam' enabled='false'>
 
+	<!--
+		wpa_supplicant just opens global control interface and waits for
+		wpa_ctrl to add an interface (could be wired OR wireless)
+	-->
+	<!--
+	<dependency
+		name='wpa_supplicant'
+		grouping='require_all'
+		restart_on='none'
+		type='service'>
+		<service_fmri value='svc:/network/wpa_supplicant' />
+	</dependency>
+	-->
+
 	<exec_method
 		type='method'
 		name='start'
--- old/usr/src/lib/libdladm/Makefile	2012-06-12 19:54:51.625722628 +0200
+++ new/usr/src/lib/libdladm/Makefile	2012-06-12 19:54:51.649221148 +0200
@@ -37,9 +37,9 @@
 $(BUILD64)SUBDIRS += $(MACH64)
 
 POFILE =	libdladm.po
-MSGFILES =	common/libdladm.c common/linkprop.c common/secobj.c	\
-		common/libdllink.c common/libdlaggr.c	\
-		common/libdlwlan.c common/libdlvnic.c	\
+MSGFILES =	common/libdladm.c common/linkprop.c common/secobj.c \
+		common/libdllink.c common/libdlaggr.c common/wpa_ie.c	\
+		common/wpa_if.c common/libdlwlan.c common/libdlvnic.c	\
 		common/libdlvlan.c common/libdlmgmt.c	\
 		common/flowattr.c common/flowprop.c	\
 		common/propfuncs.c common/libdlflow.c	\
--- old/usr/src/lib/libdladm/Makefile.com	2012-06-12 19:54:52.394883212 +0200
+++ new/usr/src/lib/libdladm/Makefile.com	2012-06-12 19:54:52.418447802 +0200
@@ -24,8 +24,8 @@
 
 LIBRARY = libdladm.a
 VERS    = .1
-OBJECTS = libdladm.o secobj.o linkprop.o libdllink.o libdlaggr.o \
-	libdlwlan.o libdlvnic.o libdlmgmt.o libdlvlan.o	libdlib.o\
+OBJECTS = libdladm.o secobj.o linkprop.o libdllink.o libdlaggr.o wpa_ie.o \
+	wpa_if.o libdlwlan.o libdlvnic.o libdlmgmt.o libdlvlan.o libdlib.o\
 	flowattr.o flowprop.o propfuncs.o libdlflow.o libdlstat.o \
 	usage.o libdlether.o libdlsim.o libdlbridge.o libdliptun.o
 
--- old/usr/src/lib/libdladm/common/libdladm.h	2012-06-12 19:54:53.150888451 +0200
+++ new/usr/src/lib/libdladm/common/libdladm.h	2012-06-12 19:54:53.174058640 +0200
@@ -181,6 +181,14 @@
 	DLADM_TYPE_UINT64
 } dladm_datatype_t;
 
+typedef enum {
+	DLADM_SECOBJ_CLASS_WEP = 0,
+	DLADM_SECOBJ_CLASS_PSK,
+	DLADM_SECOBJ_CLASS_TLS,
+	DLADM_SECOBJ_CLASS_TTLS,
+	DLADM_SECOBJ_CLASS_PEAP
+} dladm_secobj_class_t;
+
 typedef struct {
 	boolean_t	ds_readonly;
 	union {
--- old/usr/src/lib/libdladm/common/libdllink.h	2012-06-12 19:54:54.035583437 +0200
+++ new/usr/src/lib/libdladm/common/libdllink.h	2012-06-12 19:54:54.059327315 +0200
@@ -81,10 +81,6 @@
  */
 #define	DLADM_PROP_VAL_MAX	128
 
-#define		DLADM_SECOBJ_CLASS_WEP	0
-#define		DLADM_SECOBJ_CLASS_WPA	1
-typedef int	dladm_secobj_class_t;
-
 typedef int (dladm_walkcb_t)(const char *, void *);
 
 /* possible flags for ma_flags below */
--- old/usr/src/lib/libdladm/common/libdlwlan.c	2012-06-12 19:54:54.906974412 +0200
+++ new/usr/src/lib/libdladm/common/libdlwlan.c	2012-06-12 19:54:54.929856467 +0200
@@ -37,22 +37,17 @@
 #include <net/if_types.h>
 #include <libdlpi.h>
 #include <libdllink.h>
-#include <libscf.h>
 #include <libdlwlan.h>
 #include <libdladm_impl.h>
 #include <libdlwlan_impl.h>
-#include <net/wpa.h>
 
-static dladm_status_t	wpa_instance_create(dladm_handle_t, datalink_id_t,
-			    void *);
-static dladm_status_t	wpa_instance_delete(dladm_handle_t, datalink_id_t);
+static int wpa_instance_create(char *ifname);
+static int wpa_instance_delete(char *ifname);
+static int wpa_network_config(char *ifname, dladm_wlan_attr_t *attrp,
+	dladm_wlan_key_t *keys, boolean_t *create_ibss, char *identity);
 
 static dladm_status_t 	do_get_bsstype(dladm_handle_t, datalink_id_t, void *,
 			    int);
-static dladm_status_t 	do_get_essid(dladm_handle_t, datalink_id_t, void *,
-			    int);
-static dladm_status_t 	do_get_bssid(dladm_handle_t, datalink_id_t, void *,
-			    int);
 static dladm_status_t 	do_get_signal(dladm_handle_t, datalink_id_t, void *,
 			    int);
 static dladm_status_t 	do_get_encryption(dladm_handle_t, datalink_id_t, void *,
@@ -61,34 +56,13 @@
 			    int);
 static dladm_status_t 	do_get_linkstatus(dladm_handle_t, datalink_id_t, void *,
 			    int);
-static dladm_status_t	do_get_esslist(dladm_handle_t, datalink_id_t, void  *,
-			    int);
 static dladm_status_t 	do_get_rate(dladm_handle_t, datalink_id_t, void *, int);
 static dladm_status_t	do_get_mode(dladm_handle_t, datalink_id_t, void *, int);
-static dladm_status_t	do_get_capability(dladm_handle_t, datalink_id_t, void *,
-			    int);
 static dladm_status_t	do_get_wpamode(dladm_handle_t, datalink_id_t, void *,
 			    int);
-
-static dladm_status_t	do_set_bsstype(dladm_handle_t, datalink_id_t,
-			    dladm_wlan_bsstype_t *);
-static dladm_status_t	do_set_authmode(dladm_handle_t, datalink_id_t,
-			    dladm_wlan_auth_t *);
-static dladm_status_t	do_set_encryption(dladm_handle_t, datalink_id_t,
-			    dladm_wlan_secmode_t *);
-static dladm_status_t	do_set_essid(dladm_handle_t, datalink_id_t,
-			    dladm_wlan_essid_t *);
-static dladm_status_t	do_set_createibss(dladm_handle_t, datalink_id_t,
-			    boolean_t *);
 static dladm_status_t	do_set_key(dladm_handle_t, datalink_id_t,
 			    dladm_wlan_key_t *, uint_t);
-static dladm_status_t	do_set_channel(dladm_handle_t, datalink_id_t,
-			    dladm_wlan_channel_t *);
-
 static dladm_status_t	do_scan(dladm_handle_t, datalink_id_t, void *, int);
-static dladm_status_t	do_connect(dladm_handle_t, datalink_id_t, void *, int,
-			    dladm_wlan_attr_t *, boolean_t, void *, uint_t,
-			    int);
 static dladm_status_t	do_disconnect(dladm_handle_t, datalink_id_t, void *,
 			    int);
 static boolean_t	find_val_by_name(const char *, val_desc_t *,
@@ -105,9 +79,10 @@
 };
 
 static val_desc_t 	secmode_vals[] = {
-	{ "none",	DLADM_WLAN_SECMODE_NONE		},
-	{ "wep",	DLADM_WLAN_SECMODE_WEP		},
-	{ "wpa",	DLADM_WLAN_SECMODE_WPA		}
+	{ "none",	DLADM_WLAN_SECMODE_NONE	},
+	{ "wep",	DLADM_WLAN_SECMODE_WEP	},
+	{ "wpa-psk",	DLADM_WLAN_SECMODE_PSK	},
+	{ "wpa-eap",	DLADM_WLAN_SECMODE_EAP	}
 };
 
 static val_desc_t 	strength_vals[] = {
@@ -126,19 +101,17 @@
 	{ "n",		DLADM_WLAN_MODE_80211AN		}
 };
 
+/* capital chars*/
 static val_desc_t	auth_vals[] = {
-	{ "open",	DLADM_WLAN_AUTH_OPEN		},
-	{ "shared",	DLADM_WLAN_AUTH_SHARED		}
+	{ "OPEN",	DLADM_WLAN_AUTH_OPEN		},
+	{ "SHARED",	DLADM_WLAN_AUTH_SHARED		}
 };
 
 static val_desc_t	bsstype_vals[] = {
 	{ "bss",	DLADM_WLAN_BSSTYPE_BSS		},
-	{ "ibss",	DLADM_WLAN_BSSTYPE_IBSS		},
-	{ "any",	DLADM_WLAN_BSSTYPE_ANY		}
+	{ "ibss",	DLADM_WLAN_BSSTYPE_IBSS		}
 };
 
-#define	WLDP_BUFSIZE (MAX_BUF_LEN - WIFI_BUF_OFFSET)
-
 static dladm_status_t
 dladm_wlan_wlresult2status(wldp_t *gbuf)
 {
@@ -206,36 +179,75 @@
 	return (B_TRUE);
 }
 
-#define	IEEE80211_RATE	0x7f
 static void
 fill_wlan_attr(wl_ess_conf_t *wlp, dladm_wlan_attr_t *attrp)
 {
-	int		i;
+	int i;
 
 	(void) memset(attrp, 0, sizeof (*attrp));
 
-	(void) snprintf(attrp->wa_essid.we_bytes, DLADM_WLAN_MAX_ESSID_LEN,
-	    "%s", wlp->wl_ess_conf_essid.wl_essid_essid);
+	attrp->wa_essid.we_length = wlp->wl_ess_conf_essid.wl_essid_length;
+	(void) memcpy(attrp->wa_essid.we_bytes, wlp->wl_ess_conf_essid.wl_essid_essid,
+	    attrp->wa_essid.we_length);
 	attrp->wa_valid |= DLADM_WLAN_ATTR_ESSID;
 
+	/*
+	 * Note: SSID is an array of octets, i.e.,
+	 * it is not nul terminated and can, at least in theory,
+	 * contain control characters (including nul) and as such,
+	 * should be processed as binary data, not a printable string.
+	 *
+	 *the following call has been replaced with the one above:
+	 *(void) snprintf(attrp->wa_essid.we_bytes, DLADM_WLAN_MAX_ESSID_LEN,
+	 *   "%s", wlp->wl_ess_conf_essid.wl_essid_essid);
+	*/
+
 	(void) memcpy(attrp->wa_bssid.wb_bytes, wlp->wl_ess_conf_bssid,
 	    DLADM_WLAN_BSSID_LEN);
 	attrp->wa_valid |= DLADM_WLAN_ATTR_BSSID;
 
-	attrp->wa_secmode = (wlp->wl_ess_conf_wepenabled ==
-	    WL_ENC_WEP ? DLADM_WLAN_SECMODE_WEP : DLADM_WLAN_SECMODE_NONE);
-	if (wlp->wl_ess_conf_reserved[0] > 0)
-		attrp->wa_secmode = DLADM_WLAN_SECMODE_WPA;
+	/*
+	 * Open/Shared is simply not present in the AP's beacon.  It is a
+	 * deficiency of WEP, which WPA fixed by only allowing open
+	 * authentication for WPA connections. There is simply no way to tell
+	 * whether an AP is using shared auth or open system auth because a WEP
+	 * AP never broadcasts that information.
+	 * [net80211 sets it to 1 (OPEN) by default for scanned nodes]
+	 *
+	 * If wpa_ie is not present and IEEE80211_CAP_PRIVACY is on => WEP
+	 * If wpa_ie is not present and IEEE80211_CAP_PRIVACY is off => NONE
+	 */
+
+	if (wlp->wl_ess_conf_wpa_ie_len == 0) {
+		if (wlp->wl_ess_conf_caps & IEEE80211_CAP_PRIVACY) {
+			attrp->wa_auth = DLADM_WLAN_AUTH_SHARED;
+			attrp->wa_secmode = DLADM_WLAN_SECMODE_WEP;
+		} else {
+			attrp->wa_auth = DLADM_WLAN_AUTH_NONE;
+			attrp->wa_secmode = DLADM_WLAN_SECMODE_NONE;
+		}
+	} else {
+		attrp->wa_auth = DLADM_WLAN_AUTH_OPEN;
+		wpa_parse_wpa_ie(wlp->wl_ess_conf_wpa_ie,
+		    wlp->wl_ess_conf_wpa_ie_len, &attrp->wa_ie);
+		/*
+		 * check wpa_ie.c defines
+		 */
+		if (attrp->wa_ie.key_mgmt == 0)
+			attrp->wa_secmode = DLADM_WLAN_SECMODE_EAP;
+		if (attrp->wa_ie.key_mgmt == 2)
+			attrp->wa_secmode = DLADM_WLAN_SECMODE_PSK;
+	}
+	attrp->wa_valid |= DLADM_WLAN_ATTR_AUTH;
 	attrp->wa_valid |= DLADM_WLAN_ATTR_SECMODE;
 
-	attrp->wa_bsstype = (wlp->wl_ess_conf_bsstype == WL_BSS_BSS ?
-	    DLADM_WLAN_BSSTYPE_BSS : DLADM_WLAN_BSSTYPE_IBSS);
+	/* caps values are not mutually-exclusive here */
+	if (wlp->wl_ess_conf_caps & IEEE80211_CAP_IBSS)
+	    	attrp->wa_bsstype = DLADM_WLAN_BSSTYPE_IBSS;
+	if (wlp->wl_ess_conf_caps & IEEE80211_CAP_ESS)
+	    	attrp->wa_bsstype = DLADM_WLAN_BSSTYPE_BSS;
 	attrp->wa_valid |= DLADM_WLAN_ATTR_BSSTYPE;
 
-	attrp->wa_auth = (wlp->wl_ess_conf_authmode == 0 ?
-	    DLADM_WLAN_AUTH_OPEN : DLADM_WLAN_AUTH_SHARED);
-	attrp->wa_valid |= DLADM_WLAN_ATTR_AUTH;
-
 	attrp->wa_strength = DLADM_WLAN_SIGNAL2STRENGTH(wlp->wl_ess_conf_sl);
 	attrp->wa_valid |= DLADM_WLAN_ATTR_STRENGTH;
 
@@ -255,6 +267,8 @@
 		attrp->wa_valid |= DLADM_WLAN_ATTR_CHANNEL;
 }
 
+#define	WLDP_BUFSIZE	(MAX_BUF_LEN - WIFI_BUF_OFFSET)
+
 dladm_status_t
 dladm_wlan_scan(dladm_handle_t handle, datalink_id_t linkid, void *arg,
     boolean_t (*func)(void *, dladm_wlan_attr_t *))
@@ -291,7 +305,7 @@
 		goto done;
 	}
 
-	if ((status = do_get_esslist(handle, linkid, wls, WLDP_BUFSIZE))
+	if ((status = dladm_wlan_get_esslist(handle, linkid, wls, WLDP_BUFSIZE))
 	    != DLADM_STATUS_OK)
 		goto done;
 
@@ -380,8 +394,8 @@
 		return (B_TRUE);
 
 	if ((fattrp->wa_valid & DLADM_WLAN_ATTR_ESSID) != 0 &&
-	    strncmp(fattrp->wa_essid.we_bytes, attrp->wa_essid.we_bytes,
-	    DLADM_WLAN_MAX_ESSID_LEN) != 0)
+	    memcmp(fattrp->wa_essid.we_bytes, attrp->wa_essid.we_bytes,
+	    attrp->wa_essid.we_length) != 0)
 		return (B_TRUE);
 
 	if ((fattrp->wa_valid & DLADM_WLAN_ATTR_SECMODE) != 0 &&
@@ -426,149 +440,24 @@
 	return (B_TRUE);
 }
 
-#define	IEEE80211_C_WPA		0x01800000
-
-static dladm_status_t
-do_connect(dladm_handle_t handle, datalink_id_t linkid, void *buf, int bufsize,
-    dladm_wlan_attr_t *attrp, boolean_t create_ibss, void *keys,
-    uint_t key_count, int timeout)
-{
-	dladm_wlan_secmode_t	secmode;
-	dladm_wlan_auth_t	authmode;
-	dladm_wlan_bsstype_t	bsstype;
-	dladm_wlan_essid_t	essid;
-	boolean_t		essid_valid = B_FALSE;
-	dladm_status_t		status;
-	dladm_wlan_channel_t	channel;
-	hrtime_t		start;
-	wl_capability_t		*caps;
-	wl_linkstatus_t		wl_status;
-
-	if ((attrp->wa_valid & DLADM_WLAN_ATTR_CHANNEL) != 0) {
-		channel = attrp->wa_channel;
-		status = do_set_channel(handle, linkid, &channel);
-		if (status != DLADM_STATUS_OK)
-			goto fail;
-	}
-
-	secmode = ((attrp->wa_valid & DLADM_WLAN_ATTR_SECMODE) != 0) ?
-	    attrp->wa_secmode : DLADM_WLAN_SECMODE_NONE;
-
-	if ((status = do_set_encryption(handle, linkid, &secmode)) !=
-	    DLADM_STATUS_OK)
-		goto fail;
-
-	authmode = ((attrp->wa_valid & DLADM_WLAN_ATTR_AUTH) != 0) ?
-	    attrp->wa_auth : DLADM_WLAN_AUTH_OPEN;
-
-	if ((status = do_set_authmode(handle, linkid, &authmode)) !=
-	    DLADM_STATUS_OK)
-		goto fail;
-
-	bsstype = ((attrp->wa_valid & DLADM_WLAN_ATTR_BSSTYPE) != 0) ?
-	    attrp->wa_bsstype : DLADM_WLAN_BSSTYPE_BSS;
-
-	if ((status = do_set_bsstype(handle, linkid, &bsstype)) !=
-	    DLADM_STATUS_OK)
-		goto fail;
-
-	if (secmode == DLADM_WLAN_SECMODE_WEP) {
-		if (keys == NULL || key_count == 0 ||
-		    key_count > MAX_NWEPKEYS) {
-			status = DLADM_STATUS_BADARG;
-			goto fail;
-		}
-		status = do_set_key(handle, linkid, keys, key_count);
-		if (status != DLADM_STATUS_OK)
-			goto fail;
-	} else if (secmode == DLADM_WLAN_SECMODE_WPA) {
-		if (keys == NULL || key_count == 0 ||
-		    key_count > MAX_NWEPKEYS) {
-			status = DLADM_STATUS_BADARG;
-			goto fail;
-		}
-		status = do_get_capability(handle, linkid, buf, bufsize);
-		if (status != DLADM_STATUS_OK)
-			goto fail;
-		caps = (wl_capability_t *)buf;
-		if ((caps->caps & IEEE80211_C_WPA) == 0)
-			return (DLADM_STATUS_NOTSUP);
-	}
-
-	if (create_ibss) {
-		status = do_set_channel(handle, linkid, &channel);
-		if (status != DLADM_STATUS_OK)
-			goto fail;
-
-		status = do_set_createibss(handle, linkid, &create_ibss);
-		if (status != DLADM_STATUS_OK)
-			goto fail;
-
-		if ((attrp->wa_valid & DLADM_WLAN_ATTR_ESSID) == 0) {
-			generate_essid(&essid);
-			essid_valid = B_TRUE;
-		}
-	}
-
-	if ((attrp->wa_valid & DLADM_WLAN_ATTR_ESSID) != 0) {
-		essid = attrp->wa_essid;
-		essid_valid = B_TRUE;
-	}
-
-	if (!essid_valid) {
-		status = DLADM_STATUS_FAILED;
-		goto fail;
-	}
-
-	if ((status = do_set_essid(handle, linkid, &essid)) != DLADM_STATUS_OK)
-		goto fail;
-
-	/*
-	 * Because wpa daemon needs getting essid from driver,
-	 * we need call do_set_essid() first, then call wpa_instance_create().
-	 */
-	if (secmode == DLADM_WLAN_SECMODE_WPA && keys != NULL)
-		(void) wpa_instance_create(handle, linkid, keys);
-
-	start = gethrtime();
-	for (;;) {
-		status = do_get_linkstatus(handle, linkid, &wl_status,
-		    sizeof (wl_status));
-		if (status != DLADM_STATUS_OK)
-			goto fail;
-
-		if (wl_status == WL_CONNECTED)
-			break;
-
-		(void) poll(NULL, 0, DLADM_WLAN_CONNECT_POLLRATE);
-		if ((timeout >= 0) && (gethrtime() - start) /
-		    NANOSEC >= timeout) {
-			status = DLADM_STATUS_TIMEDOUT;
-			goto fail;
-		}
-	}
-	status = DLADM_STATUS_OK;
-fail:
-	return (status);
-}
-
 dladm_status_t
 dladm_wlan_connect(dladm_handle_t handle, datalink_id_t linkid,
-    dladm_wlan_attr_t *attrp, int timeout, void *keys, uint_t key_count,
-    uint_t flags)
+    dladm_wlan_attr_t *attrp, int timeout, void *keys,
+    uint_t key_count, uint_t flags, char *identity)
 {
-	int			i;
-	char 			buf[WLDP_BUFSIZE];
-	connect_state_t		state = {0, NULL, NULL};
-	attr_node_t		*nodep = NULL;
-	boolean_t		create_ibss, set_authmode;
-	dladm_wlan_attr_t	**wl_list = NULL;
+	char			ifname[MAXLINKNAMELEN];
+	boolean_t		create_ibss;
 	dladm_status_t		status;
 	wl_linkstatus_t		wl_status;
+	hrtime_t		start;
 
 	if ((status = dladm_wlan_validate(handle, linkid)) != DLADM_STATUS_OK)
 		return (status);
 
+	if ((status = dladm_datalink_id2info(handle, linkid, NULL, NULL, NULL,
+	    ifname, sizeof (ifname))) != DLADM_STATUS_OK)
+		goto done;
+
 	if ((status = do_get_linkstatus(handle, linkid, &wl_status,
 	    sizeof (wl_status))) != DLADM_STATUS_OK)
 		goto done;
@@ -578,80 +467,65 @@
 		goto done;
 	}
 
-	set_authmode = ((attrp != NULL) &&
-	    (attrp->wa_valid & DLADM_WLAN_ATTR_MODE) != 0);
+	if (wpa_instance_create(ifname))
+		goto done;
+
+	if (wpa_network_config(ifname, attrp, keys, &create_ibss, identity)) {
+		status = DLADM_STATUS_BADVAL;
+		goto done;
+	}
+
+	/*
+	 * DLADM_WLAN_CONNECT_CREATEIBSS:
+	 * If this flag is set and the bsstype attribute attr->wa_bsstype is
+	 * set to DLADM_WLAN_BSSTYPE_IBSS:
+	 * If the essid attribute attr->wa_essid is specified and there exists
+	 * no WLAN on the discovered WLAN with this particular essid, an adhoc
+	 * WLAN with essid equal to attr->wa_essid will be created.
+	 * If the essid attribute is not specified, an adhoc WLAN with a random
+	 * essid will be created, irrespective of which WLANs are available.
+	 */
+
+	/* we will manage this inside wpa_network config
 	create_ibss = ((flags & DLADM_WLAN_CONNECT_CREATEIBSS) != 0 &&
-	    attrp != NULL &&
-	    (attrp->wa_valid & DLADM_WLAN_ATTR_BSSTYPE) != 0 &&
+	    attrp != NULL && (attrp->wa_valid & DLADM_WLAN_ATTR_BSSTYPE) != 0 &&
 	    attrp->wa_bsstype == DLADM_WLAN_BSSTYPE_IBSS);
 
-	if ((flags & DLADM_WLAN_CONNECT_NOSCAN) != 0 ||
-	    (create_ibss && attrp != NULL &&
+	if ((create_ibss && attrp != NULL &&
 	    (attrp->wa_valid & DLADM_WLAN_ATTR_ESSID) == 0)) {
 		status = do_connect(handle, linkid, buf, sizeof (buf), attrp,
 		    create_ibss, keys, key_count, timeout);
 		goto done;
-	}
-
-	state.cs_attr = attrp;
-	state.cs_list = NULL;
-	state.cs_count = 0;
-
-	status = dladm_wlan_scan(handle, linkid, &state, connect_cb);
-	if (status != DLADM_STATUS_OK)
-		goto done;
 
 	if (state.cs_count == 0) {
 		if (!create_ibss) {
 			status = DLADM_STATUS_NOTFOUND;
 			goto done;
 		}
-		status = do_connect(handle, linkid, buf, sizeof (buf),
-		    attrp, create_ibss, keys, key_count, timeout);
-		goto done;
-	}
+	} */
 
-	wl_list = malloc(state.cs_count * sizeof (dladm_wlan_attr_t *));
-	if (wl_list == NULL) {
-		status = DLADM_STATUS_NOMEM;
-		goto done;
-	}
+	start = gethrtime();
+	for (;;) {
+		status = do_get_linkstatus(handle, linkid, &wl_status,
+		    sizeof (wl_status));
+		if (status != DLADM_STATUS_OK)
+			goto done;
 
-	nodep = state.cs_list;
-	for (i = 0; i < state.cs_count; i++) {
-		wl_list[i] = &nodep->an_attr;
-		nodep = nodep->an_next;
-	}
-	qsort(wl_list, state.cs_count, sizeof (dladm_wlan_attr_t *),
-	    attr_compare);
-
-	for (i = 0; i < state.cs_count; i++) {
-		dladm_wlan_attr_t	*ap = wl_list[i];
-
-		status = do_connect(handle, linkid, buf, sizeof (buf),
-		    ap, create_ibss, keys, key_count, timeout);
-		if (status == DLADM_STATUS_OK)
+		if (wl_status == WL_CONNECTED)
 			break;
 
-		if (!set_authmode) {
-			ap->wa_auth = DLADM_WLAN_AUTH_SHARED;
-			ap->wa_valid |= DLADM_WLAN_ATTR_AUTH;
-			status = do_connect(handle, linkid, buf, sizeof (buf),
-			    ap, create_ibss, keys, key_count, timeout);
-			if (status == DLADM_STATUS_OK)
-				break;
+		(void) poll(NULL, 0, DLADM_WLAN_CONNECT_POLLRATE);
+		if ((timeout >= 0) && (gethrtime() - start) /
+		    NANOSEC >= timeout) {
+			status = DLADM_STATUS_TIMEDOUT;
+			goto done;
 		}
 	}
+
 done:
 	if ((status != DLADM_STATUS_OK) && (status != DLADM_STATUS_ISCONN))
-		(void) do_disconnect(handle, linkid, buf, sizeof (buf));
+		(void) do_disconnect(handle, linkid, NULL, NULL);
 
-	while (state.cs_list != NULL) {
-		nodep = state.cs_list;
-		state.cs_list = nodep->an_next;
-		free(nodep);
-	}
-	free(wl_list);
 	return (status);
 }
 
@@ -699,11 +573,12 @@
 	wl_rssi_t		signal;
 	wl_bss_type_t		bsstype;
 	wl_authmode_t		authmode;
+	/* used only in dladm show-wifi */
 	wl_encryption_t		encryption;
 	wl_rates_t		*ratesp = NULL;
 	dladm_wlan_attr_t	*wl_attrp;
 	dladm_status_t		status;
-	char			buf[WLDP_BUFSIZE];
+	wl_bssid_t		wl_bssid;
 	wl_essid_t		wls;
 	wl_phy_conf_t		wl_phy_conf;
 	wl_linkstatus_t		wl_status;
@@ -727,21 +602,20 @@
 	else
 		attrp->la_status = DLADM_WLAN_LINK_CONNECTED;
 
-	if ((status = do_get_essid(handle, linkid, &wls, sizeof (wls)))
+	/* essid */
+	if ((status = dladm_wlan_get_essid(handle, linkid, &wls, sizeof (wls)))
 	    != DLADM_STATUS_OK)
 		goto done;
-
-	(void) strlcpy(wl_attrp->wa_essid.we_bytes, wls.wl_essid_essid,
-	    DLADM_WLAN_MAX_ESSID_LEN);
-
+	wl_attrp->wa_essid.we_length = wls.wl_essid_length;
+	(void) memcpy(wl_attrp->wa_essid.we_bytes, wls.wl_essid_essid,
+	    wls.wl_essid_length);
 	wl_attrp->wa_valid |= DLADM_WLAN_ATTR_ESSID;
 
-	if ((status = do_get_bssid(handle, linkid, buf, sizeof (buf)))
+	/* bssid */
+	if ((status = dladm_wlan_get_bssid(handle, linkid, wl_bssid, sizeof (wl_bssid)))
 	    != DLADM_STATUS_OK)
 		goto done;
-
-	(void) memcpy(wl_attrp->wa_bssid.wb_bytes, buf, DLADM_WLAN_BSSID_LEN);
-
+	(void) memcpy(wl_attrp->wa_bssid.wb_bytes, wl_bssid, DLADM_WLAN_BSSID_LEN);
 	wl_attrp->wa_valid |= DLADM_WLAN_ATTR_BSSID;
 
 	if (attrp->la_status == DLADM_WLAN_LINK_DISCONNECTED) {
@@ -750,12 +624,18 @@
 		goto done;
 	}
 
+	/* returned values used only in dladm show-wifi */
 	if ((status = do_get_encryption(handle, linkid, &encryption,
 	    sizeof (encryption))) != DLADM_STATUS_OK)
 		goto done;
 
 	wl_attrp->wa_valid |= DLADM_WLAN_ATTR_SECMODE;
 
+	/* !!!! FIX ME!!!! */
+	/*
+	 *  this should be alligned with protocol/scan results,
+	 * not types of keys used
+	 */
 	switch (encryption) {
 	case WL_NOENCRYPTION:
 		wl_attrp->wa_secmode = DLADM_WLAN_SECMODE_NONE;
@@ -764,7 +644,7 @@
 		wl_attrp->wa_secmode = DLADM_WLAN_SECMODE_WEP;
 		break;
 	case WL_ENC_WPA:
-		wl_attrp->wa_secmode = DLADM_WLAN_SECMODE_WPA;
+		wl_attrp->wa_secmode = DLADM_WLAN_SECMODE_PSK;
 		break;
 	default:
 		wl_attrp->wa_valid &= ~DLADM_WLAN_ATTR_SECMODE;
@@ -830,9 +710,6 @@
 	case WL_BSS_IBSS:
 		wl_attrp->wa_bsstype = DLADM_WLAN_BSSTYPE_IBSS;
 		break;
-	case WL_BSS_ANY:
-		wl_attrp->wa_bsstype = DLADM_WLAN_BSSTYPE_ANY;
-		break;
 	default:
 		wl_attrp->wa_valid &= ~DLADM_WLAN_ATTR_BSSTYPE;
 		break;
@@ -901,10 +778,12 @@
 	return (B_FALSE);
 }
 
+/* data to string */
+
 const char *
 dladm_wlan_essid2str(dladm_wlan_essid_t *essid, char *buf)
 {
-	(void) snprintf(buf, DLADM_STRSIZE, "%s", essid->we_bytes);
+	(void) snprintf(buf, essid->we_length+1, "%s", essid->we_bytes);
 	return (buf);
 }
 
@@ -927,6 +806,10 @@
 	return (buf);
 }
 
+/*
+ * SECMODE SHOULD NEVER BE PRINTED, in known-wlan.conf and secobj.conf we'll use
+ * secobj_class values, and for scan results wpa_s values
+ */
 const char *
 dladm_wlan_secmode2str(dladm_wlan_secmode_t *secmode, char *buf)
 {
@@ -977,13 +860,17 @@
 	    VALCNT(linkstatus_vals), buf));
 }
 
+/* string to data */
+
 dladm_status_t
 dladm_wlan_str2essid(const char *str, dladm_wlan_essid_t *essid)
 {
-	if (str[0] == '\0' || strlen(str) > DLADM_WLAN_MAX_ESSID_LEN - 1)
+	if (str[0] == '\0' || strnlen(str, DLADM_WLAN_MAX_ESSID_LEN + 2) ==
+	    DLADM_WLAN_MAX_ESSID_LEN + 2)
 		return (DLADM_STATUS_BADARG);
 
-	(void) strlcpy(essid->we_bytes, str, DLADM_WLAN_MAX_ESSID_LEN);
+	essid->we_length=strnlen(str, DLADM_WLAN_MAX_ESSID_LEN + 1);
+	(void) memcpy(essid->we_bytes, str, essid->we_length);
 	return (DLADM_STATUS_OK);
 }
 
@@ -1088,6 +975,8 @@
 	return (DLADM_STATUS_OK);
 }
 
+/* legacy ioctl for WL_SCAN and WL_DISASSOCIATE */
+
 dladm_status_t
 i_dladm_wlan_legacy_ioctl(dladm_handle_t handle, datalink_id_t linkid,
     wldp_t *gbuf, uint_t id, size_t len, uint_t cmd, size_t cmdlen)
@@ -1175,30 +1064,38 @@
 do_disconnect(dladm_handle_t handle, datalink_id_t linkid, void *buf,
     int buflen)
 {
-	if (do_get_wpamode(handle, linkid, buf, buflen) == 0 &&
-	    ((wl_wpa_t *)(buf))->wpa_flag > 0)
-		(void) wpa_instance_delete(handle, linkid);
+	char ifname[MAXLINKNAMELEN];
+	if ((dladm_datalink_id2info(handle, linkid, NULL, NULL, NULL, ifname,
+	    sizeof (ifname))) != DLADM_STATUS_OK)
+	    		return DLADM_STATUS_FAILED;
+		(void) wpa_instance_delete(ifname);
 
 	return (do_cmd_ioctl(handle, linkid, buf, buflen, WL_DISASSOCIATE));
 }
 
-static dladm_status_t
-do_get_esslist(dladm_handle_t handle, datalink_id_t linkid, void *buf,
+/*
+ * 'net80211' ioctls wrappers
+ * wlan properties are not currenlty merged into the Brussels framework.
+ * we should implement a common interface like this:http://pastebin.com/B05BkQJ2
+ */
+
+dladm_status_t
+dladm_wlan_get_esslist(dladm_handle_t handle, datalink_id_t linkid, void *buf,
     int buflen)
 {
 	return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_ESS_LIST,
 	    buflen, B_FALSE));
 }
 
-static dladm_status_t
-do_get_bssid(dladm_handle_t handle, datalink_id_t linkid, void *buf, int buflen)
+dladm_status_t
+dladm_wlan_get_bssid(dladm_handle_t handle, datalink_id_t linkid, void *buf, int buflen)
 {
 	return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_BSSID,
 	    buflen, B_FALSE));
 }
 
-static dladm_status_t
-do_get_essid(dladm_handle_t handle, datalink_id_t linkid, void *buf, int buflen)
+dladm_status_t
+dladm_wlan_get_essid(dladm_handle_t handle, datalink_id_t linkid, void *buf, int buflen)
 {
 	return (i_dladm_wlan_param(handle, linkid, buf, MAC_PROP_WL_ESSID,
 	    buflen, B_FALSE));
@@ -1258,8 +1155,8 @@
 	    buflen, B_FALSE));
 }
 
-static dladm_status_t
-do_set_bsstype(dladm_handle_t handle, datalink_id_t linkid,
+dladm_status_t
+dladm_wlan_set_bsstype(dladm_handle_t handle, datalink_id_t linkid,
     dladm_wlan_bsstype_t *bsstype)
 {
 	wl_bss_type_t	ibsstype;
@@ -1272,20 +1169,22 @@
 		ibsstype = WL_BSS_IBSS;
 		break;
 	default:
-		ibsstype = WL_BSS_ANY;
+		ibsstype = WL_BSS_BSS;
 		break;
 	}
 	return (i_dladm_wlan_param(handle, linkid, &ibsstype,
 	    MAC_PROP_WL_BSSTYPE, sizeof (ibsstype), B_TRUE));
 }
 
-static dladm_status_t
-do_set_authmode(dladm_handle_t handle, datalink_id_t linkid,
+dladm_status_t
+dladm_wlan_set_authmode(dladm_handle_t handle, datalink_id_t linkid,
     dladm_wlan_auth_t *auth)
 {
 	wl_authmode_t	auth_mode;
 
 	switch (*auth) {
+	case DLADM_WLAN_AUTH_NONE:
+		return (DLADM_STATUS_OK);
 	case DLADM_WLAN_AUTH_OPEN:
 		auth_mode = WL_OPENSYSTEM;
 		break;
@@ -1299,8 +1198,9 @@
 	    MAC_PROP_WL_AUTH_MODE, sizeof (auth_mode), B_TRUE));
 }
 
-static dladm_status_t
-do_set_encryption(dladm_handle_t handle, datalink_id_t linkid,
+/* should be renamed to a more appropriate name since it is only for WEP !!*/
+dladm_status_t
+dladm_wlan_set_encryption(dladm_handle_t handle, datalink_id_t linkid,
     dladm_wlan_secmode_t *secmode)
 {
 	wl_encryption_t	encryption;
@@ -1312,7 +1212,7 @@
 	case DLADM_WLAN_SECMODE_WEP:
 		encryption = WL_ENC_WEP;
 		break;
-	case DLADM_WLAN_SECMODE_WPA:
+	case DLADM_WLAN_SECMODE_PSK:
 		return (0);
 	default:
 		return (DLADM_STATUS_NOTSUP);
@@ -1355,18 +1255,18 @@
 	    MAC_PROP_WL_KEY_TAB, sizeof (wepkey_tab), B_TRUE));
 }
 
-static dladm_status_t
-do_set_essid(dladm_handle_t handle, datalink_id_t linkid,
-    dladm_wlan_essid_t *essid)
+dladm_status_t
+dladm_wlan_set_essid(dladm_handle_t handle, datalink_id_t linkid,
+    const uint8_t *essid, size_t essid_len)
 {
 	wl_essid_t	iessid;
 
-	(void) memset(&iessid, 0, sizeof (essid));
+	(void) memset(&iessid, 0, essid_len);
 
-	if (essid != NULL && essid->we_bytes[0] != '\0') {
-		iessid.wl_essid_length = strlen(essid->we_bytes);
-		(void) strlcpy(iessid.wl_essid_essid, essid->we_bytes,
-		    sizeof (iessid.wl_essid_essid));
+	if (essid != NULL && essid_len != 0) {
+		iessid.wl_essid_length = essid_len;
+		(void) memcpy(iessid.wl_essid_essid, essid,
+		    iessid.wl_essid_length);
 	} else {
 		return (DLADM_STATUS_BADARG);
 	}
@@ -1374,8 +1274,23 @@
 	    sizeof (iessid), B_TRUE));
 }
 
-static dladm_status_t
-do_set_channel(dladm_handle_t handle, datalink_id_t linkid,
+dladm_status_t
+do_set_bssid(dladm_handle_t handle, datalink_id_t linkid,
+    dladm_wlan_bssid_t *bssid)
+{
+	wl_bssid_t	ibssid;
+
+	if (bssid != NULL && bssid->wb_bytes != 0) {
+		(void) memcpy(ibssid, bssid->wb_bytes, DLADM_WLAN_BSSID_LEN);
+	} else {
+		return (DLADM_STATUS_BADARG);
+	}
+	return (i_dladm_wlan_param(handle, linkid, &ibssid, MAC_PROP_WL_BSSID,
+	    sizeof (ibssid), B_TRUE));
+}
+
+dladm_status_t
+dladm_wlan_set_channel(dladm_handle_t handle, datalink_id_t linkid,
     dladm_wlan_channel_t *channel)
 {
 	wl_phy_conf_t phy_conf;
@@ -1390,7 +1305,7 @@
 	    MAC_PROP_WL_PHY_CONFIG, sizeof (phy_conf), B_TRUE));
 }
 
-static dladm_status_t
+dladm_status_t
 do_set_createibss(dladm_handle_t handle, datalink_id_t linkid,
     boolean_t *create_ibss)
 {
@@ -1403,12 +1318,14 @@
 static void
 generate_essid(dladm_wlan_essid_t *essid)
 {
+	char ssid_temp[DLADM_WLAN_MAX_ESSID_LEN];
 	srandom(gethrtime());
-	(void) snprintf(essid->we_bytes, DLADM_WLAN_MAX_ESSID_LEN, "%d",
-	    random());
+	snprintf(ssid_temp, DLADM_WLAN_MAX_ESSID_LEN, "Illumos-%s", random());
+	(void) memcpy(essid->we_bytes,ssid_temp,16);
+	essid->we_length=16;
 }
 
-static dladm_status_t
+dladm_status_t
 do_get_capability(dladm_handle_t handle, datalink_id_t linkid, void *buf,
     int buflen)
 {
@@ -1424,44 +1341,11 @@
 	    B_FALSE));
 }
 
-dladm_status_t
-dladm_wlan_wpa_get_sr(dladm_handle_t handle, datalink_id_t linkid,
-    dladm_wlan_ess_t *sr, uint_t escnt, uint_t *estot)
-{
-	int		i, n;
-	wl_wpa_ess_t	*es;
-	dladm_status_t	status;
-
-	es = malloc(WLDP_BUFSIZE);
-	if (es == NULL)
-		return (DLADM_STATUS_NOMEM);
-
-	status = i_dladm_wlan_param(handle, linkid, es, MAC_PROP_WL_SCANRESULTS,
-	    WLDP_BUFSIZE, B_FALSE);
-
-	if (status == DLADM_STATUS_OK) {
-		n = (es->count > escnt) ? escnt : es->count;
-		for (i = 0; i < n; i ++) {
-			(void) memcpy(sr[i].we_bssid.wb_bytes, es->ess[i].bssid,
-			    DLADM_WLAN_BSSID_LEN);
-			sr[i].we_ssid_len = es->ess[i].ssid_len;
-			(void) memcpy(sr[i].we_ssid.we_bytes, es->ess[i].ssid,
-			    es->ess[i].ssid_len);
-			sr[i].we_wpa_ie_len = es->ess[i].wpa_ie_len;
-			(void) memcpy(sr[i].we_wpa_ie, es->ess[i].wpa_ie,
-			    es->ess[i].wpa_ie_len);
-			sr[i].we_freq = es->ess[i].freq;
-		}
-		*estot = n;
-	}
-
-	free(es);
-	return (status);
-}
+/* WPA support routines */
 
 dladm_status_t
 dladm_wlan_wpa_set_ie(dladm_handle_t handle, datalink_id_t linkid,
-    uint8_t *wpa_ie, uint_t wpa_ie_len)
+    const uint8_t *wpa_ie, size_t wpa_ie_len)
 {
 	wl_wpa_ie_t *ie;
 	uint_t len;
@@ -1560,8 +1444,7 @@
 
 dladm_status_t
 dladm_wlan_wpa_set_mlme(dladm_handle_t handle, datalink_id_t linkid,
-    dladm_wlan_mlme_op_t op, dladm_wlan_reason_t reason,
-    dladm_wlan_bssid_t *bssid)
+    dladm_wlan_mlme_op_t op, dladm_wlan_reason_t reason, const uint8_t *bssid)
 {
 	wl_mlme_t mlme;
 
@@ -1578,402 +1461,275 @@
 	}
 	mlme.im_reason = reason;
 	if (bssid != NULL)
-		(void) memcpy(mlme.im_macaddr, bssid->wb_bytes,
-		    DLADM_WLAN_BSSID_LEN);
+	    memcpy(mlme.im_macaddr, bssid, DLADM_WLAN_BSSID_LEN);
 
 	return (i_dladm_wlan_param(handle, linkid, &mlme, MAC_PROP_WL_MLME,
 	    sizeof (mlme), B_TRUE));
 }
 
-/*
- * routines of create instance
- */
-static scf_propertygroup_t *
-add_property_group_to_instance(scf_handle_t *handle, scf_instance_t *instance,
-    const char *pg_name, const char *pg_type)
-{
-	scf_propertygroup_t *pg;
-
-	pg = scf_pg_create(handle);
-	if (pg == NULL)
-		return (NULL);
-
-	if (scf_instance_add_pg(instance, pg_name, pg_type, 0, pg) != 0) {
-		scf_pg_destroy(pg);
-		return (NULL);
-	}
-
-	return (pg);
-}
-
-static dladm_status_t
-add_new_property(scf_handle_t *handle, const char *prop_name,
-    scf_type_t type, const char *val, scf_transaction_t *tx)
+ /*
+  * This routine is used for opening a control interface to wpa_supplicant
+  * global interface ctrl_path, /var/run/wpa_supplicant-global. This path
+  * is configured in network/wpa_supplicant service manifest.
+  * network/wpa_supplicant service must be running.
+  */
+static int
+wpa_instance_create(char *ifname)
 {
-	scf_value_t *value = NULL;
-	scf_transaction_entry_t *entry = NULL;
-
-	entry = scf_entry_create(handle);
-	if (entry == NULL)
-		goto out;
+	struct wpa_ctrl *ctrl_global;
+	const char *global_path = CTRL_IFACE_GLOBAL;
 
-	value = scf_value_create(handle);
-	if (value == NULL)
-		goto out;
+	/*
+	 * When we'll have a configuration backend that supports know_wlans.conf
+	 * we could add this file direclty in the third parameter
+	 */
+	char *interface_add[] = {"interface_add", ifname, """", "solaris",
+	    CTRL_IFACE_DIR};
 
-	if (scf_transaction_property_new(tx, entry, prop_name, type) != 0)
-		goto out;
+	if (ifname == NULL)
+		return -1;
 
-	if (scf_value_set_from_string(value, type, val) != 0)
-		goto out;
+	ctrl_global = wpa_ctrl_open(global_path);
+	if (ctrl_global == NULL) {
+		return -1;
+	}
 
-	if (scf_entry_add_value(entry, value) != 0)
-		goto out;
+	if (wpa_request(ctrl_global, 5, interface_add))
+		return -1;
 
-	return (DLADM_STATUS_OK);
+	wpa_ctrl_close(ctrl_global);
 
-out:
-	if (value != NULL)
-		scf_value_destroy(value);
-	if (entry != NULL)
-		scf_entry_destroy(entry);
+	/* wpa_s now executes wpa_driver_solaris_init */
 
-	return (DLADM_STATUS_FAILED);
+	return 0;
 }
 
-static dladm_status_t
-add_pg_method(scf_handle_t *handle, scf_instance_t *instance,
-    const char *pg_name, const char *flags)
+static int
+wpa_instance_delete(char *ifname)
 {
-	int			rv, size;
-	dladm_status_t		status = DLADM_STATUS_FAILED;
-	char			*command = NULL;
-	scf_transaction_t	*tran = NULL;
-	scf_propertygroup_t	*pg;
-
-	pg = add_property_group_to_instance(handle, instance,
-	    pg_name, SCF_GROUP_METHOD);
-	if (pg == NULL)
-		goto out;
-
-	tran = scf_transaction_create(handle);
-	if (tran == NULL)
-		goto out;
-
-	size = strlen(SVC_METHOD) + strlen("  ") + strlen(flags) + 1;
-	command = malloc(size);
-	if (command == NULL) {
-		status = DLADM_STATUS_NOMEM;
-		goto out;
-	}
-	(void) snprintf(command, size, "%s %s", SVC_METHOD, flags);
+	/*struct wpa_ctrl *ctrl_conn;*/
+	struct wpa_ctrl *ctrl_global;
 
-	do {
-		if (scf_transaction_start(tran, pg) != 0)
-			goto out;
-
-		if (add_new_property(handle, SCF_PROPERTY_EXEC,
-		    SCF_TYPE_ASTRING, command, tran) != DLADM_STATUS_OK) {
-			goto out;
-		}
-
-		rv = scf_transaction_commit(tran);
-		switch (rv) {
-		case 1:
-			status = DLADM_STATUS_OK;
-			goto out;
-		case 0:
-			scf_transaction_destroy_children(tran);
-			if (scf_pg_update(pg) == -1) {
-				goto out;
-			}
-			break;
-		case -1:
-		default:
-			goto out;
-		}
-	} while (rv == 0);
-
-out:
-	if (tran != NULL) {
-		scf_transaction_destroy_children(tran);
-		scf_transaction_destroy(tran);
-	}
+	const char *global_path = CTRL_IFACE_GLOBAL;
+	/*char *cfile = NULL;*/
+	char *interface_remove[] = {"interface_remove", ifname};
+	/* char *cmd_disconnect[] = {"disconnect"}; */
+	/* int flen, res;*/
 
-	if (pg != NULL)
-		scf_pg_destroy(pg);
+	if (ifname == NULL)
+		return -1;
 
-	if (command != NULL)
-		free(command);
-
-	return (status);
-}
+/*
 
-static dladm_status_t
-do_create_instance(scf_handle_t *handle, scf_service_t *svc,
-    const char *instance_name, const char *command)
-{
-	dladm_status_t status = DLADM_STATUS_FAILED;
-	char *buf;
-	ssize_t max_fmri_len;
-	scf_instance_t *instance;
-
-	instance = scf_instance_create(handle);
-	if (instance == NULL)
-		goto out;
-
-	if (scf_service_add_instance(svc, instance_name, instance) != 0) {
-		if (scf_error() == SCF_ERROR_EXISTS)
-			/* Let the caller deal with the duplicate instance */
-			status = DLADM_STATUS_EXIST;
-		goto out;
-	}
-
-	if (add_pg_method(handle, instance, "start",
-	    command) != DLADM_STATUS_OK) {
-		goto out;
-	}
-
-	/* enabling the instance */
-	max_fmri_len = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH);
-	if ((buf = malloc(max_fmri_len + 1)) == NULL)
-		goto out;
-
-	if (scf_instance_to_fmri(instance, buf, max_fmri_len + 1) > 0) {
-		if ((smf_disable_instance(buf, 0) != 0) ||
-		    (smf_enable_instance(buf, SMF_TEMPORARY) != 0)) {
-			goto out;
+	 * Get the instance name of the existing control interface.
+	 * Control interface will use the link name as the UNIX socket filename
+	 * in CTRL_IFACE_DIR
+
+	if (cfile == NULL) {
+		flen = strlen(CTRL_IFACE_DIR) + strlen(ifname) + 2;
+		cfile = malloc(flen);
+		if (cfile == NULL)
+			return -1;
+		res = snprintf(cfile, flen, "%s/%s", CTRL_IFACE_DIR, ifname);
+		if (res < 0 || res >= flen) {
+			free(cfile);
+			return -1;
 		}
-		status = DLADM_STATUS_OK;
 	}
 
-out:
-	if (instance != NULL)
-		scf_instance_destroy(instance);
-	return (status);
-}
-
-static dladm_status_t
-create_instance(const char *instance_name, const char *command)
-{
-	dladm_status_t status = DLADM_STATUS_FAILED;
-	scf_service_t *svc = NULL;
-	scf_handle_t *handle = NULL;
-
-	handle = scf_handle_create(SCF_VERSION);
-	if (handle == NULL)
-		goto out;
-
-	if (scf_handle_bind(handle) == -1)
-		goto out;
+	ctrl_conn = wpa_ctrl_open(cfile);
 
-	if ((svc = scf_service_create(handle)) == NULL)
-		goto out;
+	free(cfile);
 
-	if (scf_handle_decode_fmri(handle, SERVICE_NAME, NULL, svc,
-	    NULL, NULL, NULL, SCF_DECODE_FMRI_EXACT) != 0)
-		goto out;
+	if (ctrl_conn == NULL)
+		return -1;
 
-	status = do_create_instance(handle, svc, instance_name, command);
+	if (wpa_request(ctrl_conn, 1, cmd_disconnect))
+		return -1;
 
-out:
-	if (svc != NULL)
-		scf_service_destroy(svc);
+	wpa_ctrl_close(ctrl_conn);
+*/
 
-	if (handle != NULL) {
-		(void) scf_handle_unbind(handle);
-		scf_handle_destroy(handle);
+	/* remove interface */
+	ctrl_global = wpa_ctrl_open(global_path);
+	if (ctrl_global == NULL) {
+		return -1;
 	}
 
-	return (status);
-}
+	if (wpa_request(ctrl_global, 2, interface_remove))
+		return -1;
 
-/*
- * routines of delete instance
- */
-#define	DEFAULT_TIMEOUT	60000000
-#define	INIT_WAIT_USECS	50000
+	wpa_ctrl_close(ctrl_global);
 
-static void
-wait_until_disabled(scf_handle_t *handle, char *fmri)
-{
-	char		*state;
-	useconds_t	max;
-	useconds_t	usecs;
-	uint64_t	*cp = NULL;
-	scf_simple_prop_t *sp = NULL;
-
-	max = DEFAULT_TIMEOUT;
-
-	if (((sp = scf_simple_prop_get(handle, fmri, "stop",
-	    SCF_PROPERTY_TIMEOUT)) != NULL) &&
-	    ((cp = scf_simple_prop_next_count(sp)) != NULL) && (*cp != 0))
-		max = (*cp) * 1000000;	/* convert to usecs */
-
-	if (sp != NULL)
-		scf_simple_prop_free(sp);
-
-	for (usecs = INIT_WAIT_USECS; max > 0; max -= usecs) {
-		/* incremental wait */
-		usecs *= 2;
-		usecs = (usecs > max) ? max : usecs;
-
-		(void) usleep(usecs);
-
-		/* Check state after the wait */
-		if ((state = smf_get_state(fmri)) != NULL) {
-			if (strcmp(state, "disabled") == 0)
-				return;
-		}
-	}
+	return 0;
 }
 
-static dladm_status_t
-delete_instance(const char *instance_name)
-{
-	dladm_status_t	status = DLADM_STATUS_FAILED;
-	char		*buf;
-	ssize_t		max_fmri_len;
-	scf_scope_t	*scope = NULL;
-	scf_service_t	*svc = NULL;
-	scf_handle_t	*handle = NULL;
-	scf_instance_t	*instance;
-
-	handle = scf_handle_create(SCF_VERSION);
-	if (handle == NULL)
-		goto out;
-
-	if (scf_handle_bind(handle) == -1)
-		goto out;
-
-	if ((scope = scf_scope_create(handle)) == NULL)
-		goto out;
+#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
+#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
 
-	if ((svc = scf_service_create(handle)) == NULL)
-		goto out;
-
-	if (scf_handle_get_scope(handle, SCF_SCOPE_LOCAL, scope) == -1)
-		goto out;
-
-	if (scf_scope_get_service(scope, SERVICE_NAME, svc) < 0)
-		goto out;
-
-	instance = scf_instance_create(handle);
-	if (instance == NULL)
-		goto out;
-
-	if (scf_service_get_instance(svc, instance_name, instance) != 0) {
-		scf_error_t scf_errnum = scf_error();
+static int wpa_network_config(char *ifname, dladm_wlan_attr_t *attrp,
+	dladm_wlan_key_t *keys, boolean_t *create_ibss, char *identity)
+{
+	struct wpa_ctrl *ctrl_conn;
 
-		if (scf_errnum == SCF_ERROR_NOT_FOUND)
-			status = DLADM_STATUS_OK;
+	char *cfile = NULL;
+	int i, flen, res;
 
-		scf_instance_destroy(instance);
-		goto out;
-	}
+	char *ap_scan[] = {"ap_scan", "1"};
+	char *add_network[] = {"add_network"};
+	char *enable_network[] = {"enable_network", "0"};
+	char *set_network[] = {"set_network", "0", NULL, NULL };
+	char *network_props[] = { "ssid", "key_mgmt", "pairwise", "group",
+	    "auth_alg", "proto"};
+	char *network_vals[6];
+	char *hexascii = NULL;
+	char ap_bssid[DLADM_WLAN_BSSID_LEN*3];
+	char *cmd_bssid[] = { "bssid", "0", ap_bssid };
 
-	max_fmri_len = scf_limit(SCF_LIMIT_MAX_FMRI_LENGTH);
-	if ((buf = malloc(max_fmri_len + 1)) == NULL) {
-		scf_instance_destroy(instance);
-		goto out;
-	}
+	if (ifname == NULL)
+		return -1;
 
-	if (scf_instance_to_fmri(instance, buf, max_fmri_len + 1) > 0) {
-		char *state;
+	for (i=0; i<6; i++)
+		network_vals[1] = NULL;
 
-		state = smf_get_state(buf);
-		if (state && (strcmp(state, SCF_STATE_STRING_ONLINE) == 0 ||
-		    strcmp(state, SCF_STATE_STRING_DEGRADED) == 0)) {
-			if (smf_disable_instance(buf, 0) == 0) {
-				/*
-				 * Wait for some time till timeout to avoid
-				 * a race with scf_instance_delete() below.
-				 */
-				wait_until_disabled(handle, buf);
-			}
+	/*
+	 * Control interface will use the link name as the UNIX socket filename
+	 * in CTRL_IFACE_DIR
+	 */
+	if (cfile == NULL) {
+		flen = strlen(CTRL_IFACE_DIR) + strlen(ifname) + 2;
+		cfile = malloc(flen);
+		if (cfile == NULL)
+			return -1;
+		res = snprintf(cfile, flen, "%s/%s", CTRL_IFACE_DIR, ifname);
+		if (res < 0 || res >= flen) {
+			free(cfile);
+			return -1;
 		}
 	}
 
-	if (scf_instance_delete(instance) != 0) {
-		scf_instance_destroy(instance);
-		goto out;
-	}
+	ctrl_conn = wpa_ctrl_open(cfile);
+	free(cfile);
 
-	scf_instance_destroy(instance);
+	if (ctrl_conn == NULL)
+		return -1;
 
-	status = DLADM_STATUS_OK;
+	/* set ap_scan=2 */
+	if (wpa_request(ctrl_conn, 2, ap_scan))
+		return -1;
+
+	/* add empty wifi network block */
+	(void) wpa_request(ctrl_conn, 1, add_network);
+
+	/* leave bssid out if strict_bssid=false?*/
+	snprintf(ap_bssid, 3 * DLADM_WLAN_BSSID_LEN, MACSTR,
+	    MAC2STR(attrp->wa_bssid.wb_bytes));
+	(void) wpa_request(ctrl_conn, 3, cmd_bssid);
+
+	/* ssid string needs to be quoted */
+	network_vals[0] = malloc(attrp->wa_essid.we_length + 3);
+	snprintf(network_vals[0], attrp->wa_essid.we_length + 3, "\"%s\"",
+	    attrp->wa_essid.we_bytes);
+	/* we will add support for static WEP config. with wpa_s later */
+	network_vals[4] = (char*)dladm_wlan_auth2str(&attrp->wa_auth, malloc(5));
 
-out:
-	if (svc != NULL)
-		scf_service_destroy(svc);
-
-	if (scope != NULL)
-		scf_scope_destroy(scope);
-
-	if (handle != NULL) {
-		(void) scf_handle_unbind(handle);
-		scf_handle_destroy(handle);
-	}
-
-	return (status);
-}
-
-static dladm_status_t
-wpa_instance_create(dladm_handle_t handle, datalink_id_t linkid, void *key)
-{
-	dladm_status_t	status = DLADM_STATUS_FAILED;
-	char		*command = NULL;
-	char		*wk_name = ((dladm_wlan_key_t *)key)->wk_name;
-	int		size;
-	char		instance_name[MAXLINKNAMELEN];
+	/*
+	if (*create_ibss) {
+		network_vals[1]="WPA-NONE";
+		network_vals[2]="NONE";
+		network_vals[3]="TKIP";
+		network_vals[5]="WPA";
+		 * mode=1
+		 * frequency=2412
+		 * psk="secret passphrase"
+		 * ssid="test adhoc"
+	} else {
+		network_vals[1] = wpa_key_mgmt_txt(attrp->wa_ie.key_mgmt);
+		network_vals[2] = wpa_cipher_txt(attrp->wa_ie.pairwise_cipher);
+		network_vals[3] = wpa_cipher_txt(attrp->wa_ie.group_cipher);
+		network_vals[5] = ((attrp->wa_ie.proto == 2) ? "RSN" : "WPA");
+	}
+
+	for (i=0; i<6; i++) {
+		set_network[2] = network_props[i];
+		set_network[3] = network_vals[i];
+		(void) wpa_request(ctrl_conn, 4, set_network);
+	} */
+
+	set_network[2] = network_props[0];
+	set_network[3] = network_vals[0];
+	wpa_request(ctrl_conn, 4, set_network);
+	free(network_vals[0]);
+	free(network_vals[4]);
 
 	/*
-	 * Use the link name as the instance name of the network/wpad service.
+	 * If we use hexascii strings, wpa_s does not require quotation, and
+	 * we would be able to pass it directly to wpa_request.
+	 * Currently getsecobj returns the string value, not hexascii
 	 */
-	status = dladm_datalink_id2info(handle, linkid, NULL, NULL, NULL,
-	    instance_name, sizeof (instance_name));
-	if (status != DLADM_STATUS_OK)
-		goto out;
-
-	size = strlen(instance_name) + strlen(" -i  -k ") + strlen(wk_name) + 1;
-	command = malloc(size);
-	if (command == NULL) {
-		status = DLADM_STATUS_NOMEM;
-		goto out;
-	}
-	(void) snprintf(command, size, "-i %s -k %s", instance_name, wk_name);
+	hexascii = malloc(keys->wk_len + 3);
+	snprintf(hexascii, keys->wk_len + 3, "\"%s\"", keys->wk_val);
 
-	status = create_instance(instance_name, command);
-	if (status == DLADM_STATUS_EXIST) {
-		/*
-		 * Delete the existing instance and create a new instance
-		 * with the supplied arguments.
+	if (keys->wk_class == DLADM_SECOBJ_CLASS_PSK) {
+		set_network[2] = "psk";
+		set_network[3] = hexascii;
+		(void) wpa_request(ctrl_conn, 4, set_network);
+	} else {
+		char *cmd_eap[] = {"set_network", "0", "eap", NULL};
+		set_network[2] = "identity";
+		set_network[3] = identity;
+		(void) wpa_request(ctrl_conn, 4, set_network);
+		set_network[2] = "ca_cert";
+		set_network[3] = "\"/etc/cert/ca.pem\"";
+		(void) wpa_request(ctrl_conn, 4, set_network);
 		 */
-		if ((status = delete_instance(instance_name)) ==
-		    DLADM_STATUS_OK) {
-			status = create_instance(instance_name, command);
+		if (keys->wk_class == DLADM_SECOBJ_CLASS_TLS) {
+			char *tls_props[] = {"engine", "engine_id", "key_id",
+			    "pin", "client_cert"};
+			char *tls_vals[] = {"1", "pkcs11", "TODO", hexascii,
+			    "DEFAULT_PATH"};
+			cmd_eap[3] = "TLS";
+			(void) wpa_request(ctrl_conn, 4, cmd_eap);
+			for (i=0; i<6; i++) {
+				char *cmd_tls[] = {"set_network", "0",
+				    tls_props[i], tls_vals[i]};
+				(void) wpa_request(ctrl_conn, 4, cmd_tls);
+			}
+		} else {
+			set_network[2] = "password";
+		    	set_network[3] = hexascii;
+			(void) wpa_request(ctrl_conn, 4, set_network);
+			if (keys->wk_class == DLADM_SECOBJ_CLASS_TTLS) {
+				cmd_eap[3] = "TTLS";
+				(void) wpa_request(ctrl_conn, 4, cmd_eap);
+				/* optional
+				set_network[2] = "anonymous_identity";
+				set_network[3] = "DEFAULT_ANONYMOUS";
+				(void) wpa_request(ctrl_conn, 4, set_network);*/
+				set_network[2] = "phase2";
+		    		set_network[3] = "\"auth=PAP\"";
+		    		/*
+		    		 * other possible values are: auth=MSCHAPV2 auth=MD5;
+				 * we do not support autheap=TLS for eap-ttls
+				 */
+				(void) wpa_request(ctrl_conn, 4, set_network);
+			} else {
+				cmd_eap[3] = "PEAP";
+				(void) wpa_request(ctrl_conn, 4, cmd_eap);
+				set_network[2] = "phase2";
+		    		set_network[3] = "\"auth=MSCHAPV2\"";
+				(void) wpa_request(ctrl_conn, 4, set_network);
+			}
 		}
 	}
-
-out:
-	if (command != NULL)
-		free(command);
-
-	return (status);
-}
-
-static dladm_status_t
-wpa_instance_delete(dladm_handle_t handle, datalink_id_t linkid)
-{
-	char	instance_name[MAXLINKNAMELEN];
-
+	(void) wpa_request(ctrl_conn, 2, enable_network);
 	/*
-	 * Get the instance name of the network/wpad service (the same as
-	 * the link name).
+	 * the wpa_s driver interface starts interacting with net80211 module
 	 */
-	if (dladm_datalink_id2info(handle, linkid, NULL, NULL, NULL,
-	    instance_name, sizeof (instance_name)) != DLADM_STATUS_OK)
-		return (DLADM_STATUS_FAILED);
 
-	return (delete_instance(instance_name));
+	wpa_ctrl_close(ctrl_conn);
+
+	free(hexascii);
+
+	return 0;
 }
--- old/usr/src/lib/libdladm/common/libdlwlan.h	2012-06-12 19:54:57.953111981 +0200
+++ new/usr/src/lib/libdladm/common/libdlwlan.h	2012-06-12 19:54:57.976140613 +0200
@@ -18,6 +18,7 @@
  *
  * CDDL HEADER END
  */
+
 /*
  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
@@ -32,6 +33,7 @@
  */
 
 #include <sys/types.h>
+#include <sys/un.h>
 #include <libdladm.h>
 
 /*
@@ -45,36 +47,58 @@
 extern "C" {
 #endif
 
-#define	DLADM_WLAN_MAX_ESSID_LEN    (32 + 1)	/* per 802.11 spec */
-						/* max essid length is 32 */
-						/* one more for '\0' */
+#define	DLADM_WLAN_MAX_ESSID_LEN    	32	/* per 802.11 spec */
 #define	DLADM_WLAN_BSSID_LEN		6	/* per 802.11 spec */
 #define	DLADM_WLAN_WPA_KEY_LEN		32	/* per 802.11i spec */
 #define	DLADM_WLAN_MAX_WPA_IE_LEN	40	/* per 802.11i spec */
 
 #define	DLADM_WLAN_CONNECT_TIMEOUT_DEFAULT	10
 #define	DLADM_WLAN_CONNECT_CREATEIBSS		0x00000001
-#define	DLADM_WLAN_CONNECT_NOSCAN		0x00000002
+
+#define	IEEE80211_CAP_ESS			0x0001
+#define	IEEE80211_CAP_IBSS			0x0002
+#define	IEEE80211_CAP_PRIVACY			0x0010
+#define	IEEE80211_CAP_RSN			0x0800
+#define	IEEE80211_RATE				0x7f
+/* device driver capability, not net80211 ones*/
+#define	IEEE80211_C_WPA				0x01800000
+
+#define	IEEE80211_CIPHER_WEP		0
+#define	IEEE80211_CIPHER_TKIP		1
+#define	IEEE80211_CIPHER_AES_OCB	2
+#define	IEEE80211_CIPHER_AES_CCM	3
+#define	IEEE80211_CIPHER_CKIP		4
+#define	IEEE80211_CIPHER_NONE		5	/* pseudo value */
+
+#define	IEEE80211_MLME_ASSOC		1	/* associate station */
+#define	IEEE80211_MLME_DISASSOC		2	/* disassociate station */
+#define	IEEE80211_MLME_DEAUTH		3	/* deauthenticate station */
+#define	IEEE80211_MLME_AUTHORIZE	4	/* authorize station */
+#define	IEEE80211_MLME_UNAUTHORIZE	5	/* unauthorize station */
+
+/* Key Flags */
+#define	IEEE80211_KEY_XMIT		0x01	/* key used for xmit */
+#define	IEEE80211_KEY_RECV		0x02	/* key used for recv */
+#define	IEEE80211_KEY_GROUP		/* key used for WPA group operation */ \
+					0x04
+#define	IEEE80211_KEY_SWCRYPT		0x10	/* host-based encrypt/decrypt */
+#define	IEEE80211_KEY_SWMIC		0x20	/* host-based enmic/demic */
+#define	IEEE80211_KEY_COMMON 		/* common flags passed in by apps */ \
+	(IEEE80211_KEY_XMIT | IEEE80211_KEY_RECV | IEEE80211_KEY_GROUP)
+
+#define	IEEE80211_KEY_DEFAULT		0x80	/* default xmit key */
 
 typedef struct dladm_wlan_essid {
-	char	we_bytes[DLADM_WLAN_MAX_ESSID_LEN];
+	uint32_t we_length;
+	uint8_t we_bytes[DLADM_WLAN_MAX_ESSID_LEN];
 } dladm_wlan_essid_t;
 
 typedef struct dladm_wlan_bssid {
-	uint8_t	wb_bytes[DLADM_WLAN_BSSID_LEN];
+	uint8_t wb_bytes[DLADM_WLAN_BSSID_LEN];
 } dladm_wlan_bssid_t;
 
-typedef struct dladm_wlan_ess {
-	dladm_wlan_bssid_t	we_bssid;
-	dladm_wlan_essid_t	we_ssid;
-	uint_t			we_ssid_len;
-	uint8_t			we_wpa_ie[DLADM_WLAN_MAX_WPA_IE_LEN];
-	uint_t			we_wpa_ie_len;
-	int			we_freq;
-} dladm_wlan_ess_t;
-
 typedef enum {
-	DLADM_WLAN_CIPHER_WEP		= 0,
+	DLADM_WLAN_CIPHER_WEP = 0,
 	DLADM_WLAN_CIPHER_TKIP,
 	DLADM_WLAN_CIPHER_AES_OCB,
 	DLADM_WLAN_CIPHER_AES_CCM,
@@ -83,19 +107,20 @@
 } dladm_wlan_cipher_t;
 
 typedef enum {
-	DLADM_WLAN_MLME_ASSOC		= 1,	/* associate station */
-	DLADM_WLAN_MLME_DISASSOC	= 2	/* disassociate station */
+	DLADM_WLAN_MLME_ASSOC = 1, /* associate station */
+	DLADM_WLAN_MLME_DISASSOC = 2 /* disassociate station */
 } dladm_wlan_mlme_op_t;
 
 typedef enum {
-	DLADM_WLAN_REASON_UNSPECIFIED	= 1,
-	DLADM_WLAN_REASON_DISASSOC_LEAVING	= 5
+	DLADM_WLAN_REASON_UNSPECIFIED = 1,
+	DLADM_WLAN_REASON_DISASSOC_LEAVING = 5
 } dladm_wlan_reason_t;
 
 typedef enum {
 	DLADM_WLAN_SECMODE_NONE = 1,
 	DLADM_WLAN_SECMODE_WEP,
-	DLADM_WLAN_SECMODE_WPA
+	DLADM_WLAN_SECMODE_PSK,
+	DLADM_WLAN_SECMODE_EAP
 } dladm_wlan_secmode_t;
 
 typedef enum {
@@ -115,15 +140,25 @@
 	DLADM_WLAN_MODE_80211AN
 } dladm_wlan_mode_t;
 
+/*
+ * auth_alg: list of allowed IEEE 802.11 authentication algorithms
+ * OPEN = Open System authentication (required for WPA/WPA2)
+ * SHARED = Shared Key authentication (requires extern WEP keys)
+ * an AP could have also no auth_alg. this is the only case where key_mgmt=NONE
+ * in wpa_s configuration should be used.
+ *
+ * when DLADM_WLAN_AUTH_NONE is set, DLADM_WLAN_SECMODE_NONE should be set too
+ */
 typedef enum {
+	DLADM_WLAN_AUTH_NONE,
 	DLADM_WLAN_AUTH_OPEN = 1,
 	DLADM_WLAN_AUTH_SHARED
 } dladm_wlan_auth_t;
 
 typedef enum {
-	DLADM_WLAN_BSSTYPE_BSS = 1,
+	DLADM_WLAN_BSSTYPE_BSS = 0,
 	DLADM_WLAN_BSSTYPE_IBSS,
-	DLADM_WLAN_BSSTYPE_ANY
+	DLADM_WLAN_BSSTYPE_AP
 } dladm_wlan_bsstype_t;
 
 typedef enum {
@@ -132,40 +167,58 @@
 } dladm_wlan_linkstatus_t;
 
 typedef uint32_t dladm_wlan_speed_t;
-typedef	uint32_t dladm_wlan_channel_t;
+typedef uint32_t dladm_wlan_channel_t;
 
+/*
+ * wa_valid is a bitfield used for indicating the validity of each attribute.
+ * wa_valid may have 0 or more of the following bits set:
+ */
 enum {
-	DLADM_WLAN_ATTR_ESSID	= 0x00000001,
-	DLADM_WLAN_ATTR_BSSID	= 0x00000002,
-	DLADM_WLAN_ATTR_SECMODE	= 0x00000004,
+	DLADM_WLAN_ATTR_ESSID = 0x00000001,
+	DLADM_WLAN_ATTR_BSSID = 0x00000002,
+	DLADM_WLAN_ATTR_SECMODE = 0x00000004,
 	DLADM_WLAN_ATTR_STRENGTH = 0x00000008,
-	DLADM_WLAN_ATTR_MODE	= 0x00000010,
-	DLADM_WLAN_ATTR_SPEED	= 0x00000020,
-	DLADM_WLAN_ATTR_AUTH	= 0x00000040,
-	DLADM_WLAN_ATTR_BSSTYPE	= 0x00000080,
-	DLADM_WLAN_ATTR_CHANNEL	= 0x00000100
+	DLADM_WLAN_ATTR_MODE = 0x00000010,
+	DLADM_WLAN_ATTR_SPEED = 0x00000020,
+	DLADM_WLAN_ATTR_AUTH = 0x00000040,
+	DLADM_WLAN_ATTR_BSSTYPE = 0x00000080,
+	DLADM_WLAN_ATTR_CHANNEL = 0x00000100
+};
+
+struct wpa_ie_data {
+	int proto;
+	int pairwise_cipher;
+	int group_cipher;
+	int key_mgmt;
+	int capabilities;
+	size_t num_pmkid;
+	const uint8_t *pmkid;
+	int mgmt_group_cipher;
 };
+
 typedef struct dladm_wlan_attr {
-	uint_t			wa_valid;
-	dladm_wlan_essid_t	wa_essid;
-	dladm_wlan_bssid_t	wa_bssid;
-	dladm_wlan_secmode_t	wa_secmode;
-	dladm_wlan_strength_t	wa_strength;
-	dladm_wlan_mode_t	wa_mode;
-	dladm_wlan_speed_t	wa_speed;
-	dladm_wlan_auth_t	wa_auth;
-	dladm_wlan_bsstype_t	wa_bsstype;
-	dladm_wlan_channel_t	wa_channel;
+	uint_t wa_valid;
+	dladm_wlan_essid_t wa_essid;
+	dladm_wlan_bssid_t wa_bssid;
+	dladm_wlan_secmode_t wa_secmode;
+	dladm_wlan_strength_t wa_strength;
+	dladm_wlan_mode_t wa_mode;
+	dladm_wlan_speed_t wa_speed;
+	dladm_wlan_auth_t wa_auth;
+	dladm_wlan_bsstype_t wa_bsstype;
+	dladm_wlan_channel_t wa_channel;
+	struct wpa_ie_data wa_ie;
 } dladm_wlan_attr_t;
 
 enum {
-	DLADM_WLAN_LINKATTR_STATUS	= 0x00000001,
-	DLADM_WLAN_LINKATTR_WLAN	= 0x00000002
+	DLADM_WLAN_LINKATTR_STATUS = 0x00000001,
+	DLADM_WLAN_LINKATTR_WLAN = 0x00000002
 };
+
 typedef struct dladm_wlan_linkattr {
-	uint_t			la_valid;
-	dladm_wlan_linkstatus_t	la_status;
-	dladm_wlan_attr_t	la_wlan_attr;
+	uint_t la_valid;
+	dladm_wlan_linkstatus_t la_status;
+	dladm_wlan_attr_t la_wlan_attr;
 } dladm_wlan_linkattr_t;
 
 #define	DLADM_WLAN_WEPKEY64_LEN		5 	/* per WEP spec */
@@ -173,67 +226,132 @@
 #define	DLADM_WLAN_MAX_KEY_LEN		64	/* per WEP/WPA spec */
 #define	DLADM_WLAN_MAX_WEPKEYS		4 	/* MAX_NWEPKEYS */
 #define	DLADM_WLAN_MAX_KEYNAME_LEN	64
+
 typedef struct dladm_wlan_key {
-	uint_t		wk_idx;
-	uint_t		wk_len;
-	uint8_t		wk_val[DLADM_WLAN_MAX_KEY_LEN];
-	char		wk_name[DLADM_WLAN_MAX_KEYNAME_LEN];
-	uint_t		wk_class;
+	uint_t wk_idx;
+	uint_t wk_len;
+	uint8_t wk_val[DLADM_WLAN_MAX_KEY_LEN];
+	char wk_name[DLADM_WLAN_MAX_KEYNAME_LEN];
+	dladm_secobj_class_t wk_class;
 } dladm_wlan_key_t;
 
-extern dladm_status_t	dladm_wlan_scan(dladm_handle_t, datalink_id_t, void *,
-			    boolean_t (*)(void *, dladm_wlan_attr_t *));
-extern dladm_status_t	dladm_wlan_connect(dladm_handle_t, datalink_id_t,
-			    dladm_wlan_attr_t *, int, void *, uint_t, uint_t);
-extern dladm_status_t	dladm_wlan_disconnect(dladm_handle_t, datalink_id_t);
-extern dladm_status_t	dladm_wlan_get_linkattr(dladm_handle_t, datalink_id_t,
-			    dladm_wlan_linkattr_t *);
-/* WPA support routines */
-extern dladm_status_t	dladm_wlan_wpa_get_sr(dladm_handle_t, datalink_id_t,
-			    dladm_wlan_ess_t *, uint_t, uint_t *);
-extern dladm_status_t	dladm_wlan_wpa_set_ie(dladm_handle_t, datalink_id_t,
-			    uint8_t *, uint_t);
-extern dladm_status_t	dladm_wlan_wpa_set_wpa(dladm_handle_t, datalink_id_t,
-			    boolean_t);
-extern dladm_status_t	dladm_wlan_wpa_del_key(dladm_handle_t, datalink_id_t,
-			    uint_t, const dladm_wlan_bssid_t *);
-extern dladm_status_t	dladm_wlan_wpa_set_key(dladm_handle_t, datalink_id_t,
-			    dladm_wlan_cipher_t, const dladm_wlan_bssid_t *,
-			    boolean_t, uint64_t, uint_t, uint8_t *, uint_t);
-extern dladm_status_t	dladm_wlan_wpa_set_mlme(dladm_handle_t, datalink_id_t,
-			    dladm_wlan_mlme_op_t,
-			    dladm_wlan_reason_t, dladm_wlan_bssid_t *);
-
-extern const char	*dladm_wlan_essid2str(dladm_wlan_essid_t *, char *);
-extern const char	*dladm_wlan_bssid2str(dladm_wlan_bssid_t *, char *);
-extern const char	*dladm_wlan_secmode2str(dladm_wlan_secmode_t *, char *);
-extern const char	*dladm_wlan_strength2str(dladm_wlan_strength_t *,
-			    char *);
-extern const char	*dladm_wlan_mode2str(dladm_wlan_mode_t *, char *);
-extern const char	*dladm_wlan_speed2str(dladm_wlan_speed_t *, char *);
-extern const char	*dladm_wlan_auth2str(dladm_wlan_auth_t *, char *);
-extern const char	*dladm_wlan_bsstype2str(dladm_wlan_bsstype_t *, char *);
-extern const char	*dladm_wlan_linkstatus2str(dladm_wlan_linkstatus_t *,
-			    char *);
-
-extern dladm_status_t	dladm_wlan_str2essid(const char *,
-			    dladm_wlan_essid_t *);
-extern dladm_status_t	dladm_wlan_str2bssid(const char *,
-			    dladm_wlan_bssid_t *);
-extern dladm_status_t	dladm_wlan_str2secmode(const char *,
-			    dladm_wlan_secmode_t *);
-extern dladm_status_t	dladm_wlan_str2strength(const char *,
-			    dladm_wlan_strength_t *);
-extern dladm_status_t	dladm_wlan_str2mode(const char *,
-			    dladm_wlan_mode_t *);
-extern dladm_status_t	dladm_wlan_str2speed(const char *,
-			    dladm_wlan_speed_t *);
-extern dladm_status_t	dladm_wlan_str2auth(const char *,
-			    dladm_wlan_auth_t *);
-extern dladm_status_t	dladm_wlan_str2bsstype(const char *,
+#define CTRL_IFACE_DIR		"/var/run/wpa_supplicant"
+#define CTRL_IFACE_GLOBAL 	"/var/run/wpa_supplicant-global"
+
+/*
+ * struct wpa_ctrl - Internal structure for control interface library
+ *
+ * This structure is used by the wpa_supplicant/hostapd control interface
+ * library to store internal data. Programs using the library should not touch
+ * this data directly. They can only use the pointer to the data structure as
+ * an identifier for the control interface connection and use this as one of
+ * the arguments for most of the control interface library functions.
+ */
+struct wpa_ctrl {
+	int s;
+	struct sockaddr_un local;
+	struct sockaddr_un dest;
+};
+
+extern dladm_status_t dladm_wlan_scan(dladm_handle_t, datalink_id_t, void *,
+    boolean_t(*)(void *, dladm_wlan_attr_t *));
+extern dladm_status_t dladm_wlan_connect(dladm_handle_t, datalink_id_t,
+    dladm_wlan_attr_t *, int, void *, uint_t, uint_t, char *);
+extern dladm_status_t dladm_wlan_disconnect(dladm_handle_t, datalink_id_t);
+
+/*GET*/
+extern dladm_status_t dladm_wlan_get_linkattr(dladm_handle_t, datalink_id_t, dladm_wlan_linkattr_t *);
+
+extern dladm_status_t dladm_wlan_get_essid(dladm_handle_t, datalink_id_t, void *, int);
+extern dladm_status_t dladm_wlan_get_bssid(dladm_handle_t, datalink_id_t, void *, int);
+extern dladm_status_t dladm_wlan_get_esslist(dladm_handle_t, datalink_id_t, void *, int);
+extern dladm_status_t dladm_wlan_get_capability(dladm_handle_t, datalink_id_t, void *, int);
+
+extern dladm_status_t	dladm_wlan_set_bsstype(dladm_handle_t, datalink_id_t,
 			    dladm_wlan_bsstype_t *);
-extern dladm_status_t	dladm_wlan_str2linkstatus(const char *,
-			    dladm_wlan_linkstatus_t *);
+extern dladm_status_t	dladm_wlan_set_authmode(dladm_handle_t, datalink_id_t,
+			    dladm_wlan_auth_t *);
+extern dladm_status_t	dladm_wlan_set_encryption(dladm_handle_t, datalink_id_t,
+			    dladm_wlan_secmode_t *);
+extern dladm_status_t	dladm_wlan_set_essid(dladm_handle_t, datalink_id_t,
+			    const uint8_t  *, size_t);
+extern dladm_status_t   dladm_wlan_set_bssid(dladm_handle_t, datalink_id_t,
+			    dladm_wlan_bssid_t *);
+extern dladm_status_t	dladm_wlan_set_createibss(dladm_handle_t, datalink_id_t,
+			    boolean_t *);
+extern dladm_status_t	dladm_wlan_set_channel(dladm_handle_t, datalink_id_t,
+			    dladm_wlan_channel_t *);
+extern dladm_status_t dladm_wlan_wpa_set_ie(dladm_handle_t, datalink_id_t,
+    const uint8_t *, size_t);
+extern dladm_status_t dladm_wlan_wpa_set_wpa(dladm_handle_t, datalink_id_t,
+    boolean_t);
+extern dladm_status_t dladm_wlan_wpa_del_key(dladm_handle_t, datalink_id_t,
+    uint_t, const dladm_wlan_bssid_t *);
+extern dladm_status_t dladm_wlan_wpa_set_key(dladm_handle_t, datalink_id_t,
+    dladm_wlan_cipher_t, const dladm_wlan_bssid_t *, boolean_t, uint64_t,
+    uint_t, uint8_t *, uint_t);
+extern dladm_status_t dladm_wlan_wpa_set_mlme(dladm_handle_t, datalink_id_t,
+    dladm_wlan_mlme_op_t, dladm_wlan_reason_t, const uint8_t *);
+
+extern const char *dladm_wlan_essid2str(dladm_wlan_essid_t *, char *);
+extern const char *dladm_wlan_bssid2str(dladm_wlan_bssid_t *, char *);
+extern const char *dladm_wlan_secmode2str(dladm_wlan_secmode_t *, char *);
+extern const char *dladm_wlan_strength2str(dladm_wlan_strength_t *, char *);
+extern const char *dladm_wlan_mode2str(dladm_wlan_mode_t *, char *);
+extern const char *dladm_wlan_speed2str(dladm_wlan_speed_t *, char *);
+extern const char *dladm_wlan_auth2str(dladm_wlan_auth_t *, char *);
+extern const char *dladm_wlan_bsstype2str(dladm_wlan_bsstype_t *, char *);
+extern const char *dladm_wlan_linkstatus2str(dladm_wlan_linkstatus_t *, char *);
+
+extern dladm_status_t dladm_wlan_str2essid(const char *, dladm_wlan_essid_t *);
+extern dladm_status_t dladm_wlan_str2bssid(const char *, dladm_wlan_bssid_t *);
+extern dladm_status_t dladm_wlan_str2secmode(const char *,
+    dladm_wlan_secmode_t *);
+extern dladm_status_t dladm_wlan_str2strength(const char *,
+    dladm_wlan_strength_t *);
+extern dladm_status_t dladm_wlan_str2mode(const char *, dladm_wlan_mode_t *);
+extern dladm_status_t dladm_wlan_str2speed(const char *, dladm_wlan_speed_t *);
+extern dladm_status_t dladm_wlan_str2auth(const char *, dladm_wlan_auth_t *);
+extern dladm_status_t dladm_wlan_str2bsstype(const char *,
+    dladm_wlan_bsstype_t *);
+extern dladm_status_t dladm_wlan_str2linkstatus(const char *,
+    dladm_wlan_linkstatus_t *);
+
+/* wpa_ie parsing support routines */
+
+/*
+ * wpa_parse_wpa_ie - Parse WPA/RSN IE
+ * @wpa_ie: Pointer to WPA or RSN IE
+ * @wpa_ie_len: Length of the WPA/RSN IE
+ * @data: Pointer to data area for parsing results
+ * Returns: 0 on success, -1 on failure
+ *
+ * Parse the contents of WPA or RSN IE and write the parsed data into data.
+ */
+extern int wpa_parse_wpa_ie(const uint8_t *wpa_ie, size_t wpa_ie_len,
+    struct wpa_ie_data *data);
+
+extern char * wpa_cipher_txt(int cipher);
+extern char * wpa_key_mgmt_txt(int key_mgmt);
+
+/* wpa_supplicant control interface client routines */
+
+/*
+ * wpa_ctrl_open - Open a control interface to wpa_supplicant/hostapd
+ * @ctrl_path: Path for UNIX domain sockets;
+ * Returns: Pointer to abstract control interface data or %NULL on failure
+ */
+extern struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path);
+
+/*
+ * wpa_ctrl_close - Close a control interface to wpa_supplicant
+ * @ctrl: Control interface data from wpa_ctrl_open()
+ *
+ * This function is used to close a control interface.
+ */
+extern void wpa_ctrl_close(struct wpa_ctrl *ctrl);
+
+extern int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[]);
 
 #ifdef	__cplusplus
 }
--- old/usr/src/lib/libdladm/common/libdlwlan_impl.h	2012-06-12 19:54:59.115754861 +0200
+++ new/usr/src/lib/libdladm/common/libdlwlan_impl.h	2012-06-12 19:54:59.138739644 +0200
@@ -63,6 +63,18 @@
 	int		wr_cnt;
 } dladm_wlan_rates_t;
 
+/*
+ * not implemented:
+ * powermode: Specifies the power management mode of the WiFi link.
+ * Possible values are:
+ * off (disable power management),
+ * max (maximum power savings), and
+ * fast (performance sensitive power management).
+ * Default is off.
+ *
+ * radio: Specifies whether the radio is on or off; default is on.
+ */
+
 typedef enum {
 	DLADM_WLAN_RADIO_ON = 1,
 	DLADM_WLAN_RADIO_OFF
--- old/usr/src/lib/libdladm/common/linkprop.c	2012-06-12 19:54:59.878808824 +0200
+++ new/usr/src/lib/libdladm/common/linkprop.c	2012-06-12 19:54:59.903242474 +0200
@@ -55,7 +55,6 @@
 #include <inttypes.h>
 #include <sys/ethernet.h>
 #include <inet/iptun.h>
-#include <net/wpa.h>
 #include <sys/sysmacros.h>
 #include <sys/vlan.h>
 #include <libdlbridge.h>
@@ -308,9 +307,6 @@
 
 	{ MAC_PROP_WL_WPA,	sizeof (wl_wpa_t),	"wpa"},
 
-	/*  wl_wpa_ess_t has variable length */
-	{ MAC_PROP_WL_SCANRESULTS, sizeof (wl_wpa_ess_t), "scan_results"},
-
 	{ MAC_PROP_WL_POWER_MODE, sizeof (wl_ps_mode_t), "powermode"},
 
 	{ MAC_PROP_WL_RADIO,	sizeof (dladm_wlan_radio_t), "wl_radio"},
--- old/usr/src/lib/libdladm/common/mapfile-vers	2012-06-12 19:55:03.394114806 +0200
+++ new/usr/src/lib/libdladm/common/mapfile-vers	2012-06-12 19:55:03.417856521 +0200
@@ -90,7 +90,15 @@
 	dladm_wlan_scan;
 	dladm_wlan_connect;
 	dladm_wlan_disconnect;
+	dladm_wlan_get_bssid;
+	dladm_wlan_get_essid;
+	dladm_wlan_get_esslist;
 	dladm_wlan_get_linkattr;
+	dladm_wlan_set_authmode;
+	dladm_wlan_set_bsstype;
+	dladm_wlan_set_channel;
+	dladm_wlan_set_encryption;
+	dladm_wlan_set_essid;
 	dladm_wlan_essid2str;
 	dladm_wlan_bssid2str;
 	dladm_wlan_secmode2str;
@@ -145,7 +153,6 @@
 	dladm_get_conf_field;
 	dladm_set_conf_field;
 	dladm_unset_conf_field;
-	dladm_wlan_wpa_get_sr;
 	dladm_wlan_wpa_set_ie;
 	dladm_wlan_wpa_set_wpa;
 	dladm_wlan_wpa_del_key;
--- old/usr/src/lib/libdladm/common/secobj.c	2012-06-12 19:55:04.243904026 +0200
+++ new/usr/src/lib/libdladm/common/secobj.c	2012-06-12 19:55:04.268103311 +0200
@@ -51,8 +51,11 @@
 } secobj_class_info_t;
 
 static secobj_class_info_t secobj_class_table[] = {
-	{"wep",	DLD_SECOBJ_CLASS_WEP},
-	{"wpa",	DLD_SECOBJ_CLASS_WPA}
+	{"wep",		DLD_SECOBJ_CLASS_WEP},
+	{"psk", 	DLD_SECOBJ_CLASS_PSK},
+	{"eap-tls",	DLD_SECOBJ_CLASS_TLS},
+	{"eap-ttls",	DLD_SECOBJ_CLASS_TTLS},
+	{"peap",	DLD_SECOBJ_CLASS_PEAP}
 };
 
 #define	SECOBJ_MAXBUFSZ	65536
--- /dev/null	2012-06-12 19:55:06.000000000 +0200
+++ new/usr/src/lib/libdladm/common/wpa_ie.c	2012-06-12 19:55:06.053418015 +0200
@@ -0,0 +1,670 @@
+/*
+ * Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+#include <errno.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <libdlwlan.h>
+
+/* IEEE 802.11i */
+#define PMKID_LEN 16
+
+#define WPA_SELECTOR_LEN 4
+#define WPA_VERSION 1
+#define RSN_SELECTOR_LEN 4
+#define RSN_VERSION 1
+
+#define BIT(x) (1 << (x))
+
+/* key_mgmt: */
+#define WPA_KEY_MGMT_IEEE8021X BIT(0)
+#define WPA_KEY_MGMT_PSK BIT(1)
+#define WPA_KEY_MGMT_NONE BIT(2)
+#define WPA_KEY_MGMT_IEEE8021X_NO_WPA BIT(3)
+#define WPA_KEY_MGMT_WPA_NONE BIT(4)
+
+/* proto: */
+#define WPA_PROTO_WPA BIT(0)
+#define WPA_PROTO_RSN BIT(1)
+
+/* pairwise: and group: cyphers */
+#define WPA_CIPHER_NONE BIT(0)
+#define WPA_CIPHER_WEP40 BIT(1)
+#define WPA_CIPHER_WEP104 BIT(2)
+#define WPA_CIPHER_TKIP BIT(3)
+#define WPA_CIPHER_CCMP BIT(4)
+
+/* not supported by net80211*/
+#define WPA_KEY_MGMT_FT_IEEE8021X BIT(5)
+#define WPA_KEY_MGMT_FT_PSK BIT(6)
+#define WPA_KEY_MGMT_IEEE8021X_SHA256 BIT(7)
+#define WPA_KEY_MGMT_PSK_SHA256 BIT(8)
+#define WPA_KEY_MGMT_WPS BIT(9)
+
+/* Information Element IDs */
+#define WLAN_EID_SSID 0
+#define WLAN_EID_RSN 48
+#define WLAN_EID_VENDOR_SPECIFIC 221
+
+#define WPA_GET_LE16(a) ((uint16_t) (((a)[1] << 8) | (a)[0]))
+#define WPA_GET_BE16(a) ((uint16_t) (((a)[0] << 8) | (a)[1]))
+#define WPA_PUT_BE16(a, val)                    \
+        do {                                    \
+                (a)[0] = ((uint16_t) (val)) >> 8;    \
+                (a)[1] = ((uint16_t) (val)) & 0xff;  \
+        } while (0)
+
+
+#define RSN_SELECTOR(a, b, c, d) \
+	((((uint32_t) (a)) << 24) | (((uint32_t) (b)) << 16) | (((uint32_t) (c)) << 8) | \
+	 (uint32_t) (d))
+
+#define WPA_AUTH_KEY_MGMT_NONE RSN_SELECTOR(0x00, 0x50, 0xf2, 0)
+#define WPA_AUTH_KEY_MGMT_UNSPEC_802_1X RSN_SELECTOR(0x00, 0x50, 0xf2, 1)
+#define WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X RSN_SELECTOR(0x00, 0x50, 0xf2, 2)
+#define WPA_CIPHER_SUITE_NONE RSN_SELECTOR(0x00, 0x50, 0xf2, 0)
+#define WPA_CIPHER_SUITE_WEP40 RSN_SELECTOR(0x00, 0x50, 0xf2, 1)
+#define WPA_CIPHER_SUITE_TKIP RSN_SELECTOR(0x00, 0x50, 0xf2, 2)
+#define WPA_CIPHER_SUITE_WRAP RSN_SELECTOR(0x00, 0x50, 0xf2, 3)
+#define WPA_CIPHER_SUITE_CCMP RSN_SELECTOR(0x00, 0x50, 0xf2, 4)
+#define WPA_CIPHER_SUITE_WEP104 RSN_SELECTOR(0x00, 0x50, 0xf2, 5)
+
+
+#define RSN_AUTH_KEY_MGMT_UNSPEC_802_1X RSN_SELECTOR(0x00, 0x0f, 0xac, 1)
+#define RSN_AUTH_KEY_MGMT_PSK_OVER_802_1X RSN_SELECTOR(0x00, 0x0f, 0xac, 2)
+
+#define RSN_AUTH_KEY_MGMT_802_1X_SHA256 RSN_SELECTOR(0x00, 0x0f, 0xac, 5)
+#define RSN_AUTH_KEY_MGMT_PSK_SHA256 RSN_SELECTOR(0x00, 0x0f, 0xac, 6)
+#define RSN_AUTH_KEY_MGMT_TPK_HANDSHAKE RSN_SELECTOR(0x00, 0x0f, 0xac, 7)
+
+#define RSN_CIPHER_SUITE_NONE RSN_SELECTOR(0x00, 0x0f, 0xac, 0)
+#define RSN_CIPHER_SUITE_WEP40 RSN_SELECTOR(0x00, 0x0f, 0xac, 1)
+#define RSN_CIPHER_SUITE_TKIP RSN_SELECTOR(0x00, 0x0f, 0xac, 2)
+#define RSN_CIPHER_SUITE_WRAP RSN_SELECTOR(0x00, 0x0f, 0xac, 3
+#define RSN_CIPHER_SUITE_CCMP RSN_SELECTOR(0x00, 0x0f, 0xac, 4)
+#define RSN_CIPHER_SUITE_WEP104 RSN_SELECTOR(0x00, 0x0f, 0xac, 5)
+#define RSN_CIPHER_SUITE_AES_128_CMAC RSN_SELECTOR(0x00, 0x0f, 0xac, 6)
+
+#define WPA_OUI_TYPE RSN_SELECTOR(0x00, 0x50, 0xf2, 1)
+
+#define RSN_SELECTOR_PUT(a, val) WPA_PUT_BE32((uint8_t *) (a), (val))
+#define RSN_SELECTOR_GET(a) WPA_GET_BE32((const uint8_t *) (a))
+
+#define RSN_NUM_REPLAY_COUNTERS_1 0
+#define RSN_NUM_REPLAY_COUNTERS_2 1
+#define RSN_NUM_REPLAY_COUNTERS_4 2
+#define RSN_NUM_REPLAY_COUNTERS_16 3
+
+/* IEEE 802.11, 7.3.2.25.3 RSN Capabilities */
+#define WPA_CAPABILITY_PREAUTH BIT(0)
+#define WPA_CAPABILITY_NO_PAIRWISE BIT(1)
+
+#define WPA_GET_BE32(a) ((((uint32_t) (a)[0]) << 24) | (((uint32_t) (a)[1]) << 16) | \
+			 (((uint32_t) (a)[2]) << 8) | ((uint32_t) (a)[3]))
+
+/* B14-B15: Reserved */
+
+/* WPA IE version 1
+ * 00-50-f2:1 (OUI:OUI type)
+ * 0x01 0x00 (version; little endian)
+ * (all following fields are optional:)
+ * Group Suite Selector (4 octets) (default: TKIP)
+ * Pairwise Suite Count (2 octets, little endian) (default: 1)
+ * Pairwise Suite List (4 * n octets) (default: TKIP)
+ * Authenticated Key Management Suite Count (2 octets, little endian)
+ *    (default: 1)
+ * Authenticated Key Management Suite List (4 * n octets)
+ *    (default: unspec 802.1X)
+ * WPA Capabilities (2 octets, little endian) (default: 0)
+ */
+
+#pragma pack(1)
+struct wpa_ie_hdr {
+	uint8_t elem_id;
+	uint8_t len;
+	uint8_t oui[4]; /* 24-bit OUI followed by 8-bit OUI type */
+	uint8_t version[2]; /* little endian */
+};
+#pragma pack()
+
+/* 1/4: PMKID
+ * 2/4: RSN IE
+ * 3/4: one or two RSN IEs + GTK IE (encrypted)
+ * 4/4: empty
+ * 1/2: GTK IE (encrypted)
+ * 2/2: empty
+ */
+
+/* RSN IE version 1
+ * 0x01 0x00 (version; little endian)
+ * (all following fields are optional:)
+ * Group Suite Selector (4 octets) (default: CCMP)
+ * Pairwise Suite Count (2 octets, little endian) (default: 1)
+ * Pairwise Suite List (4 * n octets) (default: CCMP)
+ * Authenticated Key Management Suite Count (2 octets, little endian)
+ *    (default: 1)
+ * Authenticated Key Management Suite List (4 * n octets)
+ *    (default: unspec 802.1X)
+ * RSN Capabilities (2 octets, little endian) (default: 0)
+ * PMKID Count (2 octets) (default: 0)
+ * PMKID List (16 * n octets)
+ * Management Group Cipher Suite (4 octets) (default: AES-128-CMAC)
+ */
+
+#pragma pack(1)
+struct rsn_ie_hdr {
+	uint8_t elem_id; /* WLAN_EID_RSN */
+	uint8_t len;
+	uint8_t version[2]; /* little endian */
+};
+#pragma pack()
+
+/* local functions prototypes */
+
+static int wpa_parse_wpa_ie_wpa(const uint8_t *wpa_ie, size_t wpa_ie_len,
+			 struct wpa_ie_data *data);
+static int wpa_parse_wpa_ie_rsn(const uint8_t *rsn_ie, size_t rsn_ie_len,
+			 struct wpa_ie_data *data);
+/**
+ * wpa_cipher_txt - Convert cipher suite to a text string
+ * @cipher: Cipher suite (WPA_CIPHER_* enum)
+ * Returns: Pointer to a text string of the cipher suite name
+ */
+char * wpa_cipher_txt(int cipher)
+{
+	switch (cipher) {
+	case WPA_CIPHER_NONE:
+		return "NONE";
+	case WPA_CIPHER_WEP40:
+		return "WEP-40";
+	case WPA_CIPHER_WEP104:
+		return "WEP-104";
+	case WPA_CIPHER_TKIP:
+		return "TKIP";
+	case WPA_CIPHER_CCMP:
+		return "CCMP";
+	default:
+		return "UNKNOWN";
+	}
+}
+
+/**
+ * wpa_key_mgmt_txt - Convert key management suite to a text string
+ * @key_mgmt: Key management suite (WPA_KEY_MGMT_* enum)
+ * @proto: WPA/WPA2 version (WPA_PROTO_*)
+ * Returns: Pointer to a text string of the key management suite name
+ */
+char * wpa_key_mgmt_txt(int key_mgmt)
+{
+	switch (key_mgmt) {
+	case WPA_KEY_MGMT_IEEE8021X:
+		return "WPA-EAP";
+	case WPA_KEY_MGMT_PSK:
+		return "WPA-PSK";
+	case WPA_KEY_MGMT_NONE:
+		return "NONE";
+	case WPA_KEY_MGMT_IEEE8021X_NO_WPA:
+		return "IEEE8021X";
+	default:
+		return "UNKNOWN";
+	}
+}
+
+static int wpa_cypher_to_bitfield(const uint8_t *s)
+{
+	if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_NONE)
+		return WPA_CIPHER_NONE;
+	if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP40)
+		return WPA_CIPHER_WEP40;
+	if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_TKIP)
+		return WPA_CIPHER_TKIP;
+	if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_CCMP)
+		return WPA_CIPHER_CCMP;
+	if (RSN_SELECTOR_GET(s) == WPA_CIPHER_SUITE_WEP104)
+		return WPA_CIPHER_WEP104;
+	return 0;
+}
+
+static int wpa_key_mgmt_to_bitfield(const uint8_t *s)
+{
+	if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_UNSPEC_802_1X)
+		return WPA_KEY_MGMT_IEEE8021X;
+	if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_PSK_OVER_802_1X)
+		return WPA_KEY_MGMT_PSK;
+	if (RSN_SELECTOR_GET(s) == WPA_AUTH_KEY_MGMT_NONE)
+		return WPA_KEY_MGMT_WPA_NONE;
+	return 0;
+}
+
+static int wpa_parse_wpa_ie_wpa(const uint8_t *wpa_ie, size_t wpa_ie_len,
+			 struct wpa_ie_data *data)
+{
+	const struct wpa_ie_hdr *hdr;
+	const uint8_t *pos;
+	int left;
+	int i, count;
+
+	memset(data, 0, sizeof(*data));
+	data->proto = WPA_PROTO_WPA;
+	data->pairwise_cipher = WPA_CIPHER_TKIP;
+	data->group_cipher = WPA_CIPHER_TKIP;
+	data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
+	data->capabilities = 0;
+	data->pmkid = NULL;
+	data->num_pmkid = 0;
+	data->mgmt_group_cipher = 0;
+
+	if (wpa_ie_len == 0) {
+		/* No WPA IE - fail silently */
+		return -1;
+	}
+
+	if (wpa_ie_len < sizeof(struct wpa_ie_hdr)) {
+		printf("wpa_parse_wpa_ie_wpa: ie len too short %lu",
+			   (unsigned long) wpa_ie_len);
+		return -1;
+	}
+
+	hdr = (const struct wpa_ie_hdr *) wpa_ie;
+
+	if (hdr->elem_id != WLAN_EID_VENDOR_SPECIFIC ||
+	    hdr->len != wpa_ie_len - 2 ||
+	    RSN_SELECTOR_GET(hdr->oui) != WPA_OUI_TYPE ||
+	    WPA_GET_LE16(hdr->version) != WPA_VERSION) {
+		printf("wpa_parse_wpa_ie_wpa: malformed ie or unknown version");
+		return -2;
+	}
+
+	pos = (const uint8_t *) (hdr + 1);
+	left = wpa_ie_len - sizeof(*hdr);
+
+	if (left >= WPA_SELECTOR_LEN) {
+		data->group_cipher = wpa_cypher_to_bitfield(pos);
+		pos += WPA_SELECTOR_LEN;
+		left -= WPA_SELECTOR_LEN;
+	} else if (left > 0) {
+		printf("wpa_parse_wpa_ie_wpa: ie length mismatch, %u too much",
+		    left);
+		return -3;
+	}
+
+	if (left >= 2) {
+		data->pairwise_cipher = 0;
+		count = WPA_GET_LE16(pos);
+		pos += 2;
+		left -= 2;
+		if (count == 0 || left < count * WPA_SELECTOR_LEN) {
+			printf("wpa_parse_wpa_ie_wpa: ie count botch (pairwise)\
+			    , count %u left %u", count, left);
+			return -4;
+		}
+		for (i = 0; i < count; i++) {
+			data->pairwise_cipher |= wpa_cypher_to_bitfield(pos);
+			pos += WPA_SELECTOR_LEN;
+			left -= WPA_SELECTOR_LEN;
+		}
+	} else if (left == 1) {
+		printf("wpa_parse_wpa_ie_wpa: ie too short (for key mgmt)");
+		return -5;
+	}
+
+	if (left >= 2) {
+		data->key_mgmt = 0;
+		count = WPA_GET_LE16(pos);
+		pos += 2;
+		left -= 2;
+		if (count == 0 || left < count * WPA_SELECTOR_LEN) {
+			printf("wpa_parse_wpa_ie_wpa: ie count botch (key mgmt)\
+			    , count %u left %u", count, left);
+			return -6;
+		}
+		for (i = 0; i < count; i++) {
+			data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos);
+			pos += WPA_SELECTOR_LEN;
+			left -= WPA_SELECTOR_LEN;
+		}
+	} else if (left == 1) {
+		printf("wpa_parse_wpa_ie_wpa: ie too short (for capabilities)");
+		return -7;
+	}
+
+	if (left >= 2) {
+		data->capabilities = WPA_GET_LE16(pos);
+		pos += 2;
+		left -= 2;
+	}
+
+	if (left > 0) {
+		printf("wpa_parse_wpa_ie_wpa: ie has %u trailing bytes \
+		    - ignored", left);
+	}
+
+	return 0;
+}
+
+/**
+ * wpa_parse_wpa_ie_rsn - Parse RSN IE
+ * @rsn_ie: Buffer containing RSN IE
+ * @rsn_ie_len: RSN IE buffer length (including IE number and length octets)
+ * @data: Pointer to structure that will be filled in with parsed data
+ * Returns: 0 on success, <0 on failure
+ */
+static int wpa_parse_wpa_ie_rsn(const uint8_t *rsn_ie, size_t rsn_ie_len,
+			 struct wpa_ie_data *data)
+{
+	const struct rsn_ie_hdr *hdr;
+	const uint8_t *pos;
+	int left;
+	int i, count;
+
+	memset(data, 0, sizeof(*data));
+	data->proto = WPA_PROTO_RSN;
+	data->pairwise_cipher = WPA_CIPHER_CCMP;
+	data->group_cipher = WPA_CIPHER_CCMP;
+	data->key_mgmt = WPA_KEY_MGMT_IEEE8021X;
+	data->capabilities = 0;
+	data->pmkid = NULL;
+	data->num_pmkid = 0;
+	data->mgmt_group_cipher = 0;
+
+	if (rsn_ie_len == 0) {
+		/* No RSN IE - fail silently */
+		return -1;
+	}
+
+	if (rsn_ie_len < sizeof(struct rsn_ie_hdr)) {
+		printf("wpa_parse_wpa_ie_rsn: ie len too short %lu",
+		    (unsigned long) rsn_ie_len);
+		return -1;
+	}
+
+	hdr = (const struct rsn_ie_hdr *) rsn_ie;
+
+	if (hdr->elem_id != WLAN_EID_RSN ||
+	    hdr->len != rsn_ie_len - 2 ||
+	    WPA_GET_LE16(hdr->version) != RSN_VERSION) {
+		printf("wpa_parse_wpa_ie_rsn: malformed ie or unknown version");
+		return -2;
+	}
+
+	pos = (const uint8_t *) (hdr + 1);
+	left = rsn_ie_len - sizeof(*hdr);
+
+	if (left >= RSN_SELECTOR_LEN) {
+		data->group_cipher = wpa_cypher_to_bitfield(pos);
+		pos += RSN_SELECTOR_LEN;
+		left -= RSN_SELECTOR_LEN;
+	} else if (left > 0) {
+		printf("wpa_parse_wpa_ie_rsn: ie length mismatch, %u too much",
+		    left);
+		return -3;
+	}
+
+	if (left >= 2) {
+		data->pairwise_cipher = 0;
+		count = WPA_GET_LE16(pos);
+		pos += 2;
+		left -= 2;
+		if (count == 0 || left < count * RSN_SELECTOR_LEN) {
+			printf("wpa_parse_wpa_ie_rsn: ie count botch (pairwise)\
+			, count %u left %u", count, left);
+			return -4;
+		}
+		for (i = 0; i < count; i++) {
+			data->pairwise_cipher |= wpa_cypher_to_bitfield(pos);
+			pos += RSN_SELECTOR_LEN;
+			left -= RSN_SELECTOR_LEN;
+		}
+	} else if (left == 1) {
+		printf("wpa_parse_wpa_ie_rsn: ie too short (for key mgmt)");
+		return -5;
+	}
+
+	if (left >= 2) {
+		data->key_mgmt = 0;
+		count = WPA_GET_LE16(pos);
+		pos += 2;
+		left -= 2;
+		if (count == 0 || left < count * RSN_SELECTOR_LEN) {
+			printf("wpa_parse_wpa_ie_rsn: ie count botch (key mgmt)\
+			, count %u left %u", count, left);
+			return -6;
+		}
+		for (i = 0; i < count; i++) {
+			data->key_mgmt |= wpa_key_mgmt_to_bitfield(pos);
+			pos += RSN_SELECTOR_LEN;
+			left -= RSN_SELECTOR_LEN;
+		}
+	} else if (left == 1) {
+		printf("wpa_parse_wpa_ie_rsn: ie too short (for capabilities)");
+		return -7;
+	}
+
+	if (left >= 2) {
+		data->capabilities = WPA_GET_LE16(pos);
+		pos += 2;
+		left -= 2;
+	}
+
+	if (left >= 2) {
+		data->num_pmkid = WPA_GET_LE16(pos);
+		pos += 2;
+		left -= 2;
+		if (left < (int) data->num_pmkid * PMKID_LEN) {
+			printf("wpa_parse_wpa_ie_rsn: PMKID underflow "
+				   "(num_pmkid=%lu left=%d)",
+				   (unsigned long) data->num_pmkid,
+				   left);
+			data->num_pmkid = 0;
+			return -9;
+		} else {
+			data->pmkid = pos;
+			pos += data->num_pmkid * PMKID_LEN;
+			left -= data->num_pmkid * PMKID_LEN;
+		}
+	}
+
+	if (left > 0)
+		printf("wpa_parse_wpa_ie_rsn: ie has %u trailing bytes \
+		- ignored", left);
+
+	return 0;
+}
+
+int wpa_parse_wpa_ie(const uint8_t *wpa_ie, size_t wpa_ie_len,
+                     struct wpa_ie_data *data)
+{
+        if (wpa_ie_len >= 1 && wpa_ie[0] == WLAN_EID_RSN)
+                return wpa_parse_wpa_ie_rsn(wpa_ie, wpa_ie_len, data);
+        else
+                return wpa_parse_wpa_ie_wpa(wpa_ie, wpa_ie_len, data);
+}
+
+/*
+char * wpa_supplicant_ie_txt(char *pos, char *end, const char *proto,
+				    const uint8_t *ie, size_t ie_len)
+{
+	struct wpa_ie_data data;
+	int first, ret;
+
+	ret = os_snprintf(pos, end - pos, "[%s-", proto);
+	if (ret < 0 || ret >= end - pos)
+		return pos;
+	pos += ret;
+
+	if (wpa_parse_wpa_ie(ie, ie_len, &data) < 0) {
+		ret = os_snprintf(pos, end - pos, "?]");
+		if (ret < 0 || ret >= end - pos)
+			return pos;
+		pos += ret;
+		return pos;
+	}
+
+	first = 1;
+	if (data.key_mgmt & WPA_KEY_MGMT_IEEE8021X) {
+		ret = os_snprintf(pos, end - pos, "%sEAP", first ? "" : "+");
+		if (ret < 0 || ret >= end - pos)
+			return pos;
+		pos += ret;
+		first = 0;
+	}
+	if (data.key_mgmt & WPA_KEY_MGMT_PSK) {
+		ret = os_snprintf(pos, end - pos, "%sPSK", first ? "" : "+");
+		if (ret < 0 || ret >= end - pos)
+			return pos;
+		pos += ret;
+		first = 0;
+	}
+	if (data.key_mgmt & WPA_KEY_MGMT_WPA_NONE) {
+		ret = os_snprintf(pos, end - pos, "%sNone", first ? "" : "+");
+		if (ret < 0 || ret >= end - pos)
+			return pos;
+		pos += ret;
+		first = 0;
+	}
+
+	pos = wpa_supplicant_cipher_txt(pos, end, data.pairwise_cipher);
+
+	if (data.capabilities & WPA_CAPABILITY_PREAUTH) {
+		ret = os_snprintf(pos, end - pos, "-preauth");
+		if (ret < 0 || ret >= end - pos)
+			return pos;
+		pos += ret;
+	}
+
+	ret = os_snprintf(pos, end - pos, "]");
+	if (ret < 0 || ret >= end - pos)
+		return pos;
+	pos += ret;
+
+	return pos;
+}
+
+static const uint8_t * wpa_bss_get_vendor_ie(const struct wpa_bss *bss, uint32_t vendor_type)
+{
+	const uint8_t *end, *pos;
+
+	pos = (const uint8_t *) (bss + 1);
+	end = pos + bss->ie_len;
+
+	while (pos + 1 < end) {
+		if (pos + 2 + pos[1] > end)
+			break;
+		if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
+		    vendor_type == WPA_GET_BE32(&pos[2]))
+			return pos;
+		pos += 2 + pos[1];
+	}
+
+	return NULL;
+}
+
+static const uint8_t * wpa_bss_get_ie(const struct wpa_bss *bss, uint8_t ie)
+{
+	const uint8_t *end, *pos;
+
+	pos = (const uint8_t *) (bss + 1);
+	end = pos + bss->ie_len;
+
+	while (pos + 1 < end) {
+		if (pos + 2 + pos[1] > end)
+			break;
+		if (pos[0] == ie)
+			return pos;
+		pos += 2 + pos[1];
+	}
+
+	return NULL;
+}
+
+Format one result on one text line into a buffer.
+int wpa_supplicant_ctrl_iface_scan_result(
+	struct wpa_supplicant *wpa_s,
+	const struct wpa_bss *bss, char *buf, size_t buflen)
+{
+	char *pos, *end;
+	int ret;
+	const uint8_t *ie, *ie2;
+
+	pos = buf;
+	end = buf + buflen;
+
+	ie = wpa_bss_get_vendor_ie(bss, WPA_IE_VENDOR_TYPE);
+	if (ie)
+		pos = wpa_supplicant_ie_txt(pos, end, "WPA", ie, 2 + ie[1]);
+	ie2 = wpa_bss_get_ie(bss, WLAN_EID_RSN);
+	if (ie2)
+		pos = wpa_supplicant_ie_txt(pos, end, "WPA2", ie2, 2 + ie2[1]);
+	pos = wpa_supplicant_wps_ie_txt(wpa_s, pos, end, bss);
+	if (!ie && !ie2 && bss->caps & IEEE80211_CAP_PRIVACY) {
+		ret = os_snprintf(pos, end - pos, "[WEP]");
+		if (ret < 0 || ret >= end - pos)
+			return -1;
+		pos += ret;
+	}
+	if (bss->caps & IEEE80211_CAP_IBSS) {
+		ret = os_snprintf(pos, end - pos, "[IBSS]");
+		if (ret < 0 || ret >= end - pos)
+			return -1;
+		pos += ret;
+	}
+	if (bss->caps & IEEE80211_CAP_ESS) {
+		ret = os_snprintf(pos, end - pos, "[ESS]");
+		if (ret < 0 || ret >= end - pos)
+			return -1;
+		pos += ret;
+	}
+
+	ret = os_snprintf(pos, end - pos, "\t%s",
+			  wpa_ssid_txt(bss->ssid, bss->ssid_len));
+	if (ret < 0 || ret >= end - pos)
+		return -1;
+	pos += ret;
+
+	ret = os_snprintf(pos, end - pos, "\n");
+	if (ret < 0 || ret >= end - pos)
+		return -1;
+	pos += ret;
+
+	return pos - buf;
+}
+
+
+int wpa_supplicant_ctrl_iface_scan_results(
+	struct wpa_supplicant *wpa_s, char *buf, size_t buflen)
+{
+	char *pos, *end;
+	struct wpa_bss *bss;
+	int ret;
+
+	pos = buf;
+	end = buf + buflen;
+	ret = os_snprintf(pos, end - pos, "bssid / frequency / signal level / "
+			  "flags / ssid\n");
+	if (ret < 0 || ret >= end - pos)
+		return pos - buf;
+	pos += ret;
+
+	dl_list_for_each(bss, &wpa_s->bss_id, struct wpa_bss, list_id) {
+		ret = wpa_supplicant_ctrl_iface_scan_result(wpa_s, bss, pos,
+							    end - pos);
+		if (ret < 0 || ret >= end - pos)
+			return pos - buf;
+		pos += ret;
+	}
+
+	return pos - buf;
+}
+*/
--- /dev/null	2012-06-12 19:55:06.000000000 +0200
+++ new/usr/src/lib/libdladm/common/wpa_if.c	2012-06-12 19:55:06.332444980 +0200
@@ -0,0 +1,821 @@
+/*
+ * Copyright (c) 2002-2012, Jouni Malinen <j@w1.fi>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * Alternatively, this software may be distributed under the terms of BSD
+ * license.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+#include <errno.h>
+#include <ctype.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <libdlwlan.h>
+
+#define WPA_CTRL_RSP "CTRL-RSP-"
+
+enum wpa_cmd_flags {
+	cli_cmd_flag_none	= 0x00,
+	cli_cmd_flag_sensitive	= 0x01
+};
+
+struct wpa_cmd {
+	const char *cmd;
+	int (*handler)(struct wpa_ctrl *ctrl, int argc, char *argv[]);
+	enum wpa_cmd_flags flags;
+	const char *usage;
+};
+
+/**
+ * wpa_ctrl_request - Send a command to wpa_supplicant/hostapd
+ * @ctrl: Control interface data from wpa_ctrl_open()
+ * @cmd: Command; usually, ASCII text, e.g., "PING"
+ * @cmd_len: Length of the cmd in bytes
+ * @reply: Buffer for the response
+ * @reply_len: Reply buffer length
+ * @msg_cb: Callback function for unsolicited messages or %NULL if not used
+ * Returns: 0 on success, -1 on error (send or receive failed), -2 on timeout
+ *
+ * This function is used to send commands to wpa_supplicant/hostapd. Received
+ * response will be written to reply and reply_len is set to the actual length
+ * of the reply. This function will block for up to two seconds while waiting
+ * for the reply. If unsolicited messages are received, the blocking time may
+ * be longer.
+ *
+ * msg_cb can be used to register a callback function that will be called for
+ * unsolicited messages received while waiting for the command response. These
+ * messages may be received if wpa_ctrl_request() is called at the same time as
+ * wpa_supplicant/hostapd is sending such a message. This can happen only if
+ * the program has used wpa_ctrl_attach() to register itself as a monitor for
+ * event messages. Alternatively to msg_cb, programs can register two control
+ * interface connections and use one of them for commands and the other one for
+ * receiving event messages, in other words, call wpa_ctrl_attach() only for
+ * the control interface connection that will be used for event messages.
+ */
+static int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd,
+    size_t cmd_len, char *reply, size_t *reply_len,
+    void (*msg_cb)(char *msg, size_t len));
+
+/* These are temporary UNIX sockets created for receiving requests messages*/
+#define CTRL_IFACE_CLIENT_DIR "/var/run"
+#define CTRL_IFACE_CLIENT_PREFIX "wpa_ctrl_"
+
+struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
+{
+	struct wpa_ctrl *ctrl;
+	static int counter = 0;
+	int ret;
+	size_t res;
+	int tries = 0;
+
+	ctrl = malloc(sizeof(*ctrl));
+	if (ctrl == NULL)
+		return NULL;
+	memset(ctrl, 0, sizeof(*ctrl));
+
+	ctrl->s = socket(PF_UNIX, SOCK_DGRAM, 0);
+	if (ctrl->s < 0) {
+		free(ctrl);
+		return NULL;
+	}
+
+	ctrl->local.sun_family = AF_UNIX;
+	counter++;
+try_again:
+	ret = snprintf(ctrl->local.sun_path, sizeof(ctrl->local.sun_path),
+	    CTRL_IFACE_CLIENT_DIR "/"
+	    CTRL_IFACE_CLIENT_PREFIX "%d-%d", (int) getpid(), counter);
+	if (ret < 0 || (size_t) ret >= sizeof(ctrl->local.sun_path)) {
+		close(ctrl->s);
+		free(ctrl);
+		return NULL;
+	}
+	tries++;
+	if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
+	    sizeof(ctrl->local)) < 0) {
+		if (errno == EADDRINUSE && tries < 2) {
+			/*
+			 * getpid() returns unique identifier for this instance
+			 * of wpa_ctrl, so the existing socket file must have
+			 * been left by unclean termination of an earlier run.
+			 * Remove the file and try again.
+			 */
+			unlink(ctrl->local.sun_path);
+			goto try_again;
+		}
+		close(ctrl->s);
+		free(ctrl);
+		return NULL;
+	}
+
+	ctrl->dest.sun_family = AF_UNIX;
+	res = strlcpy(ctrl->dest.sun_path, ctrl_path,
+			 sizeof(ctrl->dest.sun_path));
+	if (res >= sizeof(ctrl->dest.sun_path)) {
+		close(ctrl->s);
+		free(ctrl);
+		return NULL;
+	}
+	if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
+		    sizeof(ctrl->dest)) < 0) {
+		close(ctrl->s);
+		unlink(ctrl->local.sun_path);
+		free(ctrl);
+		return NULL;
+	}
+
+	return ctrl;
+}
+
+void wpa_ctrl_close(struct wpa_ctrl *ctrl)
+{
+	if (ctrl == NULL)
+		return;
+	unlink(ctrl->local.sun_path);
+	if (ctrl->s >= 0)
+		close(ctrl->s);
+	free(ctrl);
+}
+
+static int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
+		     char *reply, size_t *reply_len,
+		     void (*msg_cb)(char *msg, size_t len))
+{
+	struct timeval tv;
+	int res;
+	fd_set rfds;
+	const char *_cmd;
+	char *cmd_buf = NULL;
+	size_t _cmd_len;
+
+	{
+		_cmd = cmd;
+		_cmd_len = cmd_len;
+	}
+
+	if (send(ctrl->s, _cmd, _cmd_len, 0) < 0) {
+		free(cmd_buf);
+		return -1;
+	}
+	free(cmd_buf);
+
+	for (;;) {
+		tv.tv_sec = 10;
+		tv.tv_usec = 0;
+		FD_ZERO(&rfds);
+		FD_SET(ctrl->s, &rfds);
+		res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
+		if (res < 0)
+			return res;
+		if (FD_ISSET(ctrl->s, &rfds)) {
+			res = recv(ctrl->s, reply, *reply_len, 0);
+			if (res < 0)
+				return res;
+			if (res > 0 && reply[0] == '<') {
+				/* This is an unsolicited message from
+				 * wpa_supplicant, not the reply to the
+				 * request. Use msg_cb to report this to the
+				 * caller. */
+				if (msg_cb) {
+					/* Make sure the message is nul
+					 * terminated. */
+					if ((size_t) res == *reply_len)
+						res = (*reply_len) - 1;
+					reply[res] = '\0';
+					msg_cb(reply, res);
+				}
+				continue;
+			}
+			*reply_len = res;
+			break;
+		} else {
+			return -2;
+		}
+	}
+	return 0;
+}
+
+static void wpa_msg_cb(char *msg, size_t len)
+{
+	snprintf(msg, len, "%s\n");
+}
+
+static int _wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd, int print)
+{
+	char buf[2048];
+	size_t len;
+	int ret;
+
+	len = sizeof(buf) - 1;
+	ret = wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len,
+			       wpa_msg_cb);
+	if (ret == -2) {
+		printf("'%s' command timed out.\n", cmd);
+		return -2;
+	} else if (ret < 0) {
+		printf("'%s' command failed.\n", cmd);
+		return -1;
+	}
+	if (print) {
+		buf[len] = '\0';
+		printf("%s", buf);
+	}
+	return 0;
+}
+
+static int wpa_ctrl_command(struct wpa_ctrl *ctrl, char *cmd)
+{
+	return _wpa_ctrl_command(ctrl, cmd, 1);
+}
+
+/* control interface commands routines */
+
+static int wpa_cmd_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+	char cmd[256];
+	int res;
+
+	if (argc != 1) {
+		printf("Invalid LEVEL command: needs one argument (debug "
+		       "level)\n");
+		return -1;
+	}
+	res = snprintf(cmd, sizeof(cmd), "LEVEL %s", argv[0]);
+	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+		printf("Too long LEVEL command.\n");
+		return -1;
+	}
+	return wpa_ctrl_command(ctrl, cmd);
+}
+
+static int wpa_cmd_reassociate(struct wpa_ctrl *ctrl, int argc,
+				   char *argv[])
+{
+	return wpa_ctrl_command(ctrl, "REASSOCIATE");
+}
+
+static int wpa_cmd_identity(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+	char cmd[256], *pos, *end;
+	int i, ret;
+
+	if (argc < 2) {
+		printf("Invalid IDENTITY command: needs two arguments "
+		       "(network id and identity)\n");
+		return -1;
+	}
+
+	end = cmd + sizeof(cmd);
+	pos = cmd;
+	ret = snprintf(pos, end - pos, WPA_CTRL_RSP "IDENTITY-%s:%s",
+			  argv[0], argv[1]);
+	if (ret < 0 || ret >= end - pos) {
+		printf("Too long IDENTITY command.\n");
+		return -1;
+	}
+	pos += ret;
+	for (i = 2; i < argc; i++) {
+		ret = snprintf(pos, end - pos, " %s", argv[i]);
+		if (ret < 0 || ret >= end - pos) {
+			printf("Too long IDENTITY command.\n");
+			return -1;
+		}
+		pos += ret;
+	}
+
+	return wpa_ctrl_command(ctrl, cmd);
+}
+
+static int wpa_cmd_password(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+	char cmd[256], *pos, *end;
+	int i, ret;
+
+	if (argc < 2) {
+		printf("Invalid PASSWORD command: needs two arguments "
+		       "(network id and password)\n");
+		return -1;
+	}
+
+	end = cmd + sizeof(cmd);
+	pos = cmd;
+	ret = snprintf(pos, end - pos, WPA_CTRL_RSP "PASSWORD-%s:%s",
+			  argv[0], argv[1]);
+	if (ret < 0 || ret >= end - pos) {
+		printf("Too long PASSWORD command.\n");
+		return -1;
+	}
+	pos += ret;
+	for (i = 2; i < argc; i++) {
+		ret = snprintf(pos, end - pos, " %s", argv[i]);
+		if (ret < 0 || ret >= end - pos) {
+			printf("Too long PASSWORD command.\n");
+			return -1;
+		}
+		pos += ret;
+	}
+
+	return wpa_ctrl_command(ctrl, cmd);
+}
+
+static int wpa_cmd_new_password(struct wpa_ctrl *ctrl, int argc,
+				    char *argv[])
+{
+	char cmd[256], *pos, *end;
+	int i, ret;
+
+	if (argc < 2) {
+		printf("Invalid NEW_PASSWORD command: needs two arguments "
+		       "(network id and password)\n");
+		return -1;
+	}
+
+	end = cmd + sizeof(cmd);
+	pos = cmd;
+	ret = snprintf(pos, end - pos, WPA_CTRL_RSP "NEW_PASSWORD-%s:%s",
+			  argv[0], argv[1]);
+	if (ret < 0 || ret >= end - pos) {
+		printf("Too long NEW_PASSWORD command.\n");
+		return -1;
+	}
+	pos += ret;
+	for (i = 2; i < argc; i++) {
+		ret = snprintf(pos, end - pos, " %s", argv[i]);
+		if (ret < 0 || ret >= end - pos) {
+			printf("Too long NEW_PASSWORD command.\n");
+			return -1;
+		}
+		pos += ret;
+	}
+
+	return wpa_ctrl_command(ctrl, cmd);
+}
+
+
+static int wpa_cmd_pin(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+	char cmd[256], *pos, *end;
+	int i, ret;
+
+	if (argc < 2) {
+		printf("Invalid PIN command: needs two arguments "
+		       "(network id and pin)\n");
+		return -1;
+	}
+
+	end = cmd + sizeof(cmd);
+	pos = cmd;
+	ret = snprintf(pos, end - pos, WPA_CTRL_RSP "PIN-%s:%s",
+			  argv[0], argv[1]);
+	if (ret < 0 || ret >= end - pos) {
+		printf("Too long PIN command.\n");
+		return -1;
+	}
+	pos += ret;
+	for (i = 2; i < argc; i++) {
+		ret = snprintf(pos, end - pos, " %s", argv[i]);
+		if (ret < 0 || ret >= end - pos) {
+			printf("Too long PIN command.\n");
+			return -1;
+		}
+		pos += ret;
+	}
+	return wpa_ctrl_command(ctrl, cmd);
+}
+
+static int wpa_cmd_passphrase(struct wpa_ctrl *ctrl, int argc,
+				  char *argv[])
+{
+	char cmd[256], *pos, *end;
+	int i, ret;
+
+	if (argc < 2) {
+		printf("Invalid PASSPHRASE command: needs two arguments "
+		       "(network id and passphrase)\n");
+		return -1;
+	}
+
+	end = cmd + sizeof(cmd);
+	pos = cmd;
+	ret = snprintf(pos, end - pos, WPA_CTRL_RSP "PASSPHRASE-%s:%s",
+			  argv[0], argv[1]);
+	if (ret < 0 || ret >= end - pos) {
+		printf("Too long PASSPHRASE command.\n");
+		return -1;
+	}
+	pos += ret;
+	for (i = 2; i < argc; i++) {
+		ret = snprintf(pos, end - pos, " %s", argv[i]);
+		if (ret < 0 || ret >= end - pos) {
+			printf("Too long PASSPHRASE command.\n");
+			return -1;
+		}
+		pos += ret;
+	}
+
+	return wpa_ctrl_command(ctrl, cmd);
+}
+
+
+static int wpa_cmd_bssid(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+	char cmd[256], *pos, *end;
+	int i, ret;
+
+	if (argc < 2) {
+		printf("Invalid BSSID command: needs two arguments (network "
+		       "id and BSSID)\n");
+		return -1;
+	}
+
+	end = cmd + sizeof(cmd);
+	pos = cmd;
+	ret = snprintf(pos, end - pos, "BSSID");
+	if (ret < 0 || ret >= end - pos) {
+		printf("Too long BSSID command.\n");
+		return -1;
+	}
+	pos += ret;
+	for (i = 0; i < argc; i++) {
+		ret = snprintf(pos, end - pos, " %s", argv[i]);
+		if (ret < 0 || ret >= end - pos) {
+			printf("Too long BSSID command.\n");
+			return -1;
+		}
+		pos += ret;
+	}
+
+	return wpa_ctrl_command(ctrl, cmd);
+}
+
+static int wpa_cmd_log_level(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+	char cmd[256], *pos, *end;
+	int i, ret;
+
+	end = cmd + sizeof(cmd);
+	pos = cmd;
+	ret = snprintf(pos, end - pos, "LOG_LEVEL");
+	if (ret < 0 || ret >= end - pos) {
+		printf("Too long LOG_LEVEL command.\n");
+		return -1;
+	}
+	pos += ret;
+	for (i = 0; i < argc; i++) {
+		ret = snprintf(pos, end - pos, " %s", argv[i]);
+		if (ret < 0 || ret >= end - pos) {
+			printf("Too long LOG_LEVEL command.\n");
+			return -1;
+		}
+		pos += ret;
+	}
+
+	return wpa_ctrl_command(ctrl, cmd);
+}
+
+static int wpa_cmd_select_network(struct wpa_ctrl *ctrl, int argc,
+				      char *argv[])
+{
+	char cmd[32];
+	int res;
+
+	if (argc < 1) {
+		printf("Invalid SELECT_NETWORK command: needs one argument "
+		       "(network id)\n");
+		return -1;
+	}
+
+	res = snprintf(cmd, sizeof(cmd), "SELECT_NETWORK %s", argv[0]);
+	if (res < 0 || (size_t) res >= sizeof(cmd))
+		return -1;
+	cmd[sizeof(cmd) - 1] = '\0';
+
+	return wpa_ctrl_command(ctrl, cmd);
+}
+
+
+static int wpa_cmd_enable_network(struct wpa_ctrl *ctrl, int argc,
+				      char *argv[])
+{
+	char cmd[32];
+	int res;
+
+	if (argc < 1) {
+		printf("Invalid ENABLE_NETWORK command: needs one argument "
+		       "(network id)\n");
+		return -1;
+	}
+
+	res = snprintf(cmd, sizeof(cmd), "ENABLE_NETWORK %s", argv[0]);
+	if (res < 0 || (size_t) res >= sizeof(cmd))
+		return -1;
+	cmd[sizeof(cmd) - 1] = '\0';
+
+	return wpa_ctrl_command(ctrl, cmd);
+}
+
+
+static int wpa_cmd_disable_network(struct wpa_ctrl *ctrl, int argc,
+				       char *argv[])
+{
+	char cmd[32];
+	int res;
+
+	if (argc < 1) {
+		printf("Invalid DISABLE_NETWORK command: needs one argument "
+		       "(network id)\n");
+		return -1;
+	}
+
+	res = snprintf(cmd, sizeof(cmd), "DISABLE_NETWORK %s", argv[0]);
+	if (res < 0 || (size_t) res >= sizeof(cmd))
+		return -1;
+	cmd[sizeof(cmd) - 1] = '\0';
+
+	return wpa_ctrl_command(ctrl, cmd);
+}
+
+
+static int wpa_cmd_add_network(struct wpa_ctrl *ctrl, int argc,
+				   char *argv[])
+{
+	return wpa_ctrl_command(ctrl, "ADD_NETWORK");
+}
+
+
+static int wpa_cmd_remove_network(struct wpa_ctrl *ctrl, int argc,
+				      char *argv[])
+{
+	char cmd[32];
+	int res;
+
+	if (argc < 1) {
+		printf("Invalid REMOVE_NETWORK command: needs one argument "
+		       "(network id)\n");
+		return -1;
+	}
+
+	res = snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %s", argv[0]);
+	if (res < 0 || (size_t) res >= sizeof(cmd))
+		return -1;
+	cmd[sizeof(cmd) - 1] = '\0';
+
+	return wpa_ctrl_command(ctrl, cmd);
+}
+
+static int wpa_cmd_set_network(struct wpa_ctrl *ctrl, int argc,
+				   char *argv[])
+{
+	char cmd[256];
+	int res;
+
+	if (argc != 3) {
+		printf("Invalid SET_NETWORK command: needs three arguments\n"
+		       "(network id, variable name, and value)\n");
+		return -1;
+	}
+
+	res = snprintf(cmd, sizeof(cmd), "SET_NETWORK %s %s %s",
+			  argv[0], argv[1], argv[2]);
+	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+		printf("Too long SET_NETWORK command.\n");
+		return -1;
+	}
+	return wpa_ctrl_command(ctrl, cmd);
+}
+
+static int wpa_cmd_disconnect(struct wpa_ctrl *ctrl, int argc,
+				  char *argv[])
+{
+	return wpa_ctrl_command(ctrl, "DISCONNECT");
+}
+
+static int wpa_cmd_reconnect(struct wpa_ctrl *ctrl, int argc,
+				  char *argv[])
+{
+	return wpa_ctrl_command(ctrl, "RECONNECT");
+}
+
+static int wpa_cmd_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+	return wpa_ctrl_command(ctrl, "SCAN");
+}
+
+
+static int wpa_cmd_scan_results(struct wpa_ctrl *ctrl, int argc,
+				    char *argv[])
+{
+	return wpa_ctrl_command(ctrl, "SCAN_RESULTS");
+}
+
+static int wpa_cmd_terminate(struct wpa_ctrl *ctrl, int argc,
+				 char *argv[])
+{
+	return wpa_ctrl_command(ctrl, "TERMINATE");
+}
+
+static int wpa_cmd_interface_add(struct wpa_ctrl *ctrl, int argc,
+				     char *argv[])
+{
+	char cmd[256];
+	int res;
+
+	if (argc < 1) {
+		printf("Invalid INTERFACE_ADD command: needs at least one "
+		       "argument (interface name)\n"
+		       "All arguments: ifname confname driver ctrl_interface "
+		       "driver_param bridge_name\n");
+		return -1;
+	}
+
+	/*
+	 * INTERFACE_ADD <ifname>TAB<confname>TAB<driver>TAB<ctrl_interface>TAB
+	 * <driver_param>TAB<bridge_name>
+	 */
+	res = snprintf(cmd, sizeof(cmd),
+			  "INTERFACE_ADD %s\t%s\t%s\t%s\t%s\t%s",
+			  argv[0],
+			  argc > 1 ? argv[1] : "", argc > 2 ? argv[2] : "",
+			  argc > 3 ? argv[3] : "", argc > 4 ? argv[4] : "",
+			  argc > 5 ? argv[5] : "");
+	if (res < 0 || (size_t) res >= sizeof(cmd))
+		return -1;
+	cmd[sizeof(cmd) - 1] = '\0';
+	return wpa_ctrl_command(ctrl, cmd);
+}
+
+
+static int wpa_cmd_interface_remove(struct wpa_ctrl *ctrl, int argc,
+					char *argv[])
+{
+	char cmd[128];
+	int res;
+
+	if (argc != 1) {
+		printf("Invalid INTERFACE_REMOVE command: needs one argument "
+		       "(interface name)\n");
+		return -1;
+	}
+
+	res = snprintf(cmd, sizeof(cmd), "INTERFACE_REMOVE %s", argv[0]);
+	if (res < 0 || (size_t) res >= sizeof(cmd))
+		return -1;
+	cmd[sizeof(cmd) - 1] = '\0';
+	return wpa_ctrl_command(ctrl, cmd);
+}
+
+static int wpa_cmd_ap_scan(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+	char cmd[256];
+	int res;
+
+	if (argc != 1) {
+		printf("Invalid AP_SCAN command: needs one argument (ap_scan "
+		       "value)\n");
+		return -1;
+	}
+	res = snprintf(cmd, sizeof(cmd), "AP_SCAN %s", argv[0]);
+	if (res < 0 || (size_t) res >= sizeof(cmd) - 1) {
+		printf("Too long AP_SCAN command.\n");
+		return -1;
+	}
+	return wpa_ctrl_command(ctrl, cmd);
+}
+
+static int wpa_cmd_suspend(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+	return wpa_ctrl_command(ctrl, "SUSPEND");
+}
+
+static struct wpa_cmd wpa_commands[] = {
+	{ "level", wpa_cmd_level,
+	  cli_cmd_flag_none,
+	  "<debug level> = change debug level" },
+	{ "reassociate", wpa_cmd_reassociate,
+	  cli_cmd_flag_none,
+	  "= force reassociation" },
+	{ "identity", wpa_cmd_identity,
+	  cli_cmd_flag_none,
+	  "<network id> <identity> = configure identity for an SSID" },
+	{ "password", wpa_cmd_password,
+	  cli_cmd_flag_sensitive,
+	  "<network id> <password> = configure password for an SSID" },
+	{ "new_password", wpa_cmd_new_password,
+	  cli_cmd_flag_sensitive,
+	  "<network id> <password> = change password for an SSID" },
+	{ "pin", wpa_cmd_pin,
+	  cli_cmd_flag_sensitive,
+	  "<network id> <pin> = configure pin for an SSID" },
+	{ "passphrase", wpa_cmd_passphrase,
+	  cli_cmd_flag_sensitive,
+	  "<network id> <passphrase> = configure private key passphrase\n"
+	  "  for an SSID" },
+	{ "bssid", wpa_cmd_bssid,
+	  cli_cmd_flag_none,
+	  "<network id> <BSSID> = set preferred BSSID for an SSID" },
+	{ "log_level", wpa_cmd_log_level,
+	  cli_cmd_flag_none,
+	  "<level> [<timestamp>] = update the log level/timestamp\n"
+	  "log_level = display the current log level and log options" },
+	{ "select_network", wpa_cmd_select_network,
+	  cli_cmd_flag_none,
+	  "<network id> = select a network (disable others)" },
+	{ "enable_network", wpa_cmd_enable_network,
+	  cli_cmd_flag_none,
+	  "<network id> = enable a network" },
+	{ "disable_network", wpa_cmd_disable_network,
+	  cli_cmd_flag_none,
+	  "<network id> = disable a network" },
+	{ "add_network", wpa_cmd_add_network,
+	  cli_cmd_flag_none,
+	  "= add a network" },
+	{ "remove_network", wpa_cmd_remove_network,
+	  cli_cmd_flag_none,
+	  "<network id> = remove a network" },
+	{ "set_network", wpa_cmd_set_network,
+	  cli_cmd_flag_sensitive,
+	  "<network id> <variable> <value> = set network variables (shows\n"
+	  "  list of variables when run without arguments)" },
+	{ "disconnect", wpa_cmd_disconnect,
+	  cli_cmd_flag_none,
+	  "= disconnect and wait for reassociate/reconnect command before\n"
+	  "  connecting" },
+	{ "reconnect", wpa_cmd_reconnect,
+	  cli_cmd_flag_none,
+	  "= like reassociate, but only takes effect if already disconnected"
+	},
+	{ "scan", wpa_cmd_scan,
+	  cli_cmd_flag_none,
+	  "= request new BSS scan" },
+	{ "scan_results", wpa_cmd_scan_results,
+	  cli_cmd_flag_none,
+	  "= get latest scan results" },
+	{ "terminate", wpa_cmd_terminate,
+	  cli_cmd_flag_none,
+	  "= terminate wpa_supplicant" },
+	{ "interface_add", wpa_cmd_interface_add,
+	  cli_cmd_flag_none,
+	  "<ifname> <confname> <driver> <ctrl_interface> <driver_param>\n"
+	  "  <bridge_name> = adds new interface, all parameters but <ifname>\n"
+	  "  are optional" },
+	{ "interface_remove", wpa_cmd_interface_remove,
+	  cli_cmd_flag_none,
+	  "<ifname> = removes the interface" },
+	{ "ap_scan", wpa_cmd_ap_scan,
+	  cli_cmd_flag_none,
+	  "<value> = set ap_scan parameter" },
+	{ "suspend", wpa_cmd_suspend, cli_cmd_flag_none,
+	  "= notification of suspend/hibernate" },
+	{ NULL, NULL, cli_cmd_flag_none, NULL }
+};
+
+int wpa_request(struct wpa_ctrl *ctrl, int argc, char *argv[])
+{
+	struct wpa_cmd *cmd, *match = NULL;
+	int count;
+	int ret = 0;
+
+	count = 0;
+	cmd = wpa_commands;
+	while (cmd->cmd) {
+		if (strncasecmp(cmd->cmd, argv[0], strlen(argv[0])) == 0)
+		{
+			match = cmd;
+			if (strcasecmp(cmd->cmd, argv[0]) == 0) {
+				/* we have an exact match */
+				count = 1;
+				break;
+			}
+			count++;
+		}
+		cmd++;
+	}
+
+	if (count > 1) {
+		printf("Ambiguous command '%s'; possible commands:", argv[0]);
+		cmd = wpa_commands;
+		while (cmd->cmd) {
+			if (strncasecmp(cmd->cmd, argv[0],
+					   strlen(argv[0])) == 0) {
+				printf(" %s", cmd->cmd);
+			}
+			cmd++;
+		}
+		printf("\n");
+		ret = 1;
+	} else if (count == 0) {
+		printf("Unknown command '%s'\n", argv[0]);
+		ret = 1;
+	} else {
+		ret = match->handler(ctrl, argc - 1, &argv[1]);
+	}
+
+	return ret;
+}
--- old/usr/src/lib/libnwam/common/libnwam_known_wlan.c	2012-06-12 19:55:06.662195821 +0200
+++ new/usr/src/lib/libnwam/common/libnwam_known_wlan.c	2012-06-12 19:55:06.686458927 +0200
@@ -530,7 +530,8 @@
 
 	if (secmode != DLADM_WLAN_SECMODE_NONE &&
 	    secmode != DLADM_WLAN_SECMODE_WEP &&
-	    secmode != DLADM_WLAN_SECMODE_WPA)
+	    secmode != DLADM_WLAN_SECMODE_PSK &&
+	    secmode != DLADM_WLAN_SECMODE_EAP)
 		return (NWAM_ENTITY_INVALID_VALUE);
 
 	return (NWAM_SUCCESS);
--- old/usr/src/lib/libnwam/common/libnwam_values.c	2012-06-12 19:55:07.875221212 +0200
+++ new/usr/src/lib/libnwam/common/libnwam_values.c	2012-06-12 19:55:07.898704255 +0200
@@ -723,7 +723,8 @@
 {
 	{ "none", DLADM_WLAN_SECMODE_NONE },
 	{ "wep", DLADM_WLAN_SECMODE_WEP },
-	{ "wpa", DLADM_WLAN_SECMODE_WPA },
+	{ "wpa-psk", DLADM_WLAN_SECMODE_PSK },
+	{ "wpa-eap", DLADM_WLAN_SECMODE_EAP },
 	{ NULL, 0 }
 };
 
--- old/usr/src/lib/libsecdb/auth_attr.txt	2012-06-12 19:55:09.229324149 +0200
+++ new/usr/src/lib/libsecdb/auth_attr.txt	2012-06-12 19:55:09.252941588 +0200
@@ -91,8 +91,6 @@
 solaris.network.ilb.enable:::Network ILB Enable Configuration::help=NetworkILBenable.html
 solaris.network.interface.config:::Network Interface Configuration::help=NetworkInterfaceConfig.html
 solaris.network.link.security:::Link Security::help=LinkSecurity.html
-solaris.network.wifi.config:::Wifi Config::help=WifiConfig.html
-solaris.network.wifi.wep:::Wifi Wep::help=WifiWep.html
 solaris.network.vrrp:::Administer VRRP::help=NetworkVRRP.html
 #
 solaris.print.:::Printer Management::help=PrintHeader.html
--- old/usr/src/lib/libsecdb/help/auths/Makefile	2012-06-12 19:55:10.229711926 +0200
+++ new/usr/src/lib/libsecdb/help/auths/Makefile	2012-06-12 19:55:10.253523527 +0200
@@ -132,8 +132,6 @@
 	NetworkHeader.html \
 	NetworkVRRP.html \
 	NetworkInterfaceConfig.html \
-	WifiConfig.html \
-	WifiWep.html \
 	LinkSecurity.html \
 	IdmapRules.html \
 	SmfIdmapStates.html \
--- old/usr/src/pkg/manifests/SUNWcs.mf	2012-06-12 19:55:11.649250719 +0200
+++ new/usr/src/pkg/manifests/SUNWcs.mf	2012-06-12 19:55:11.680453973 +0200
@@ -1125,8 +1125,6 @@
 file path=usr/lib/help/auths/locale/C/SysShutdown.html
 file path=usr/lib/help/auths/locale/C/SysSyseventRead.html
 file path=usr/lib/help/auths/locale/C/SysSyseventWrite.html
-file path=usr/lib/help/auths/locale/C/WifiConfig.html
-file path=usr/lib/help/auths/locale/C/WifiWep.html
 file path=usr/lib/help/auths/locale/C/ZoneCloneFrom.html
 file path=usr/lib/help/auths/locale/C/ZoneHeader.html
 file path=usr/lib/help/auths/locale/C/ZoneLogin.html
--- old/usr/src/pkg/manifests/consolidation-osnet-osnet-message-files.mf	2012-06-12 19:55:13.759803100 +0200
+++ new/usr/src/pkg/manifests/consolidation-osnet-osnet-message-files.mf	2012-06-12 19:55:13.784044219 +0200
@@ -210,8 +210,6 @@
 file path=usr/lib/help/auths/locale/TNDaemon.html
 file path=usr/lib/help/auths/locale/TNctl.html
 file path=usr/lib/help/auths/locale/ValueTND.html
-file path=usr/lib/help/auths/locale/WifiConfig.html
-file path=usr/lib/help/auths/locale/WifiWep.html
 file path=usr/lib/help/auths/locale/ZoneCloneFrom.html
 file path=usr/lib/help/auths/locale/ZoneHeader.html
 file path=usr/lib/help/auths/locale/ZoneLogin.html
--- /dev/null	2012-06-12 19:55:14.000000000 +0200
+++ new/usr/src/pkg/manifests/service-network-wpa_supplicant.mf	2012-06-12 19:55:14.876707387 +0200
@@ -0,0 +1,58 @@
+#
+# 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 (c) 2010, Oracle and/or its affiliates. All rights reserved.
+#
+
+set name=pkg.fmri value=pkg:/service/network/wpa_supplicant@$(PKGVERS)
+set name=pkg.description \
+    value="The service implements the IEEE802.11i (WPA/WPA2) specification."
+set name=pkg.summary value="Wireless WPA Supplicant"
+set name=info.classification \
+    value=org.opensolaris.category.2008:System/Hardware
+set name=variant.arch value=$(ARCH)
+dir path=lib
+dir path=lib/svc
+dir path=lib/svc/manifest group=sys
+dir path=lib/svc/manifest/network group=sys
+dir path=usr group=sys
+dir path=usr/lib
+dir path=usr/lib/inet
+dir path=usr/share/man/man1m
+file path=lib/svc/manifest/network/wpa_supplicant.xml group=sys mode=0444
+file path=usr/lib/inet/wpa_supplicant mode=0555
+file path=usr/share/man/man1m/wpa_supplicant.1m
+legacy pkg=SUNWwpar \
+    desc="The service implements the IEEE802.11i (WPA/WPA2) specification." \
+    name="Wireless WPA Supplicant, (Root)"
+legacy pkg=SUNWwpau \
+    desc="The service implements the IEEE802.11i (WPA/WPA2) specification." \
+    name="Wireless WPA Supplicant, (Usr)"
+license cr_Sun license=cr_Sun
+license lic_CDDL license=lic_CDDL
+license usr/src/cmd/cmd-inet/usr.lib/wpa_supplicant/THIRDPARTYLICENSE \
+    license=usr/src/cmd/cmd-inet/usr.lib/wpa_supplicant/THIRDPARTYLICENSE
+depend fmri=SUNWcs type=require
+depend fmri=SUNWcsd type=require
+depend fmri=system/library type=require
+depend fmri=system/library/platform type=require
+depend fmri=system/library/processor type=require
--- old/usr/src/uts/common/inet/wifi_ioctl.h	2012-06-12 19:55:15.138277698 +0200
+++ new/usr/src/uts/common/inet/wifi_ioctl.h	2012-06-12 19:55:15.162065841 +0200
@@ -25,6 +25,7 @@
 
 /*
  * Macro and date structures defined for 802.11 wifi config tool.
+ * (no more used, we should remove them)
  */
 
 #ifndef	__WIFI_IOCTL_H
@@ -37,8 +38,6 @@
 #endif
 
 #define	MAX_KEY_LENGTH 26
-#define	MAX_ESSID_LENGTH (32 + 1)	/* max essid length is 32 */
-					/* one more for '\0' */
 #define	MAX_CHANNEL_NUM	99
 #define	MAX_RSSI 15
 #define	MAX_NWEPKEYS 4
@@ -49,6 +48,7 @@
 /*
  * ioctls
  */
+
 #define	WLAN_IOCTL_BASE 0x1000
 #define	WLAN_GET_VERSION (WLAN_IOCTL_BASE + 0x0)
 #define	WLAN_SET_PARAM (WLAN_IOCTL_BASE + 0x2)
@@ -58,6 +58,7 @@
 /*
  * parameters
  */
+
 #define	WL_PARAMETERS_BASE 0x2000
 #define	WL_BSSID (WL_PARAMETERS_BASE + 0x0)
 #define	WL_ESSID (WL_PARAMETERS_BASE + 0x1)
@@ -97,6 +98,7 @@
 #define	WL_RADIO (WL_PARAMETERS_BASE + 0x23)
 #define	WL_LINKSTATUS (WL_PARAMETERS_BASE + 0x24)
 #define	WL_DEV_DEPEND (WL_PARAMETERS_BASE + 0x25)
+
 /*
  * commands
  */
@@ -109,6 +111,7 @@
 
 /*
  * domains
+ * outdated?
  */
 /* --USA */
 #define	WL_DOMAIN_BASE 0x4000
@@ -126,6 +129,7 @@
 
 /*
  * power mode
+ * not implemented
  */
 
 #define	WL_PM_AM 0x0
@@ -163,6 +167,7 @@
 #define	WL_NOENCRYPTION 0x0
 #define	WL_ENC_WEP 0x1
 #define	WL_ENC_WPA 0x2
+
 #define	WL_OPENSYSTEM 0x1
 #define	WL_SHAREDKEY 0x2
 
@@ -208,9 +213,10 @@
 #define	WL_HRDS (WL_OTHER_BASE + 0x4)
 #define	WL_ERP (WL_OTHER_BASE + 0x5)
 
-#define	WL_BSS_BSS 1
-#define	WL_BSS_IBSS 3
-#define	WL_BSS_ANY 2
+/* aligned with wpa_s values */
+#define	WL_BSS_BSS 0
+#define	WL_BSS_IBSS 1
+#define	WL_BSS_AP 2
 /*
  * field_offset
  */
@@ -220,16 +226,17 @@
  * type definationes
  */
 typedef boolean_t wl_create_ibss_t;
-typedef char wl_bssid_t[6];
+typedef uint8_t wl_bssid_t[6];
 
 typedef struct wl_essid {
 	uint32_t wl_essid_length;
-	char wl_essid_essid[34];
-}wl_essid_t;
+	uint8_t wl_essid_essid[32];
+} wl_essid_t;
 
+/* there are no consumers for wl_nodename prop */
 typedef struct wl_nodename {
 	uint32_t wl_nodename_length;
-	char wl_nodename_name[34];
+	char wl_nodename_name[32];
 } wl_nodename_t;
 
 typedef struct wl_phy_supported {
@@ -302,14 +309,16 @@
 typedef uint32_t wl_rssi_t;
 typedef uint32_t wl_rssi_threshold_t;
 typedef uint32_t wl_bss_type_t;
-typedef uint32_t wl_authmode_t;
+typedef uint8_t wl_authmode_t;
 typedef uint32_t wl_encryption_t;
 typedef uint32_t wl_wep_key_id_t;
 typedef boolean_t wl_radio_t;
 typedef uint32_t wl_rts_threshold_t;
 typedef uint32_t wl_short_retry_t;
 typedef uint32_t wl_long_retry_t;
-typedef uint32_t wl_beacon_period_t;
+typedef uint16_t wl_beacon_period_t;
+typedef uint32_t wl_beacon_age_t;
+typedef uint64_t wl_beacon_tsf_t;
 typedef uint32_t wl_tx_lifetime_t;
 typedef uint32_t wl_rx_lifetime_t;
 typedef uint32_t wl_frag_threshold_t;
@@ -324,23 +333,93 @@
 	char wl_rates_rates[1];
 } wl_rates_t;
 
+/*
+ * Macro and data structures defined for 802.11i.
+ */
+
+typedef struct wl_wpa_ie {
+	uint32_t	wpa_ie_len;
+	uint8_t		wpa_ie[1];	/* it's the head of wpa_ie */
+} wl_wpa_ie_t;
+
+typedef struct wl_wpa {
+	uint32_t	wpa_flag;
+} wl_wpa_t;
+
+typedef struct wl_capability {
+	uint32_t	caps;
+} wl_capability_t;
+
+typedef uint16_t wl_ess_caps;
+
+/*
+ * WPA/RSN get/set key request.
+ * ik_type  : wep/tkip/aes
+ * ik_keyix : should be between 0 and 3, 0 will be used as default key.
+ * ik_keylen: key length in bytes.
+ * ik_keydata and ik_keylen include the DATA key and MIC key.
+ * ik_keyrsc/ik_keytsc: rx/tx seq number.
+ */
+#pragma pack(1)
+typedef struct wl_key {
+	uint8_t		ik_type;
+	uint8_t		ik_pad;
+
+	uint16_t	ik_keyix;
+	uint8_t		ik_keylen;
+	uint8_t		ik_flags;
+
+	uint8_t		ik_macaddr[6];
+	uint64_t	ik_keyrsc;
+	uint64_t	ik_keytsc;
+
+	/* [IEEE80211_KEYBUF_SIZE+IEEE80211_MICBUF_SIZE] */
+	uint8_t		ik_keydata[32];
+} wl_key_t;
+#pragma pack()
+
+typedef struct wl_del_key {
+	uint8_t		idk_keyix;
+	uint8_t		idk_macaddr[6];
+} wl_del_key_t;
+
+/*
+ * structure for WL_MLME state manipulation request.
+ * im_op: operations include auth/deauth/assoc/disassoc,
+ * im_reason: 802.11 reason code
+ */
+typedef struct wl_mlme {
+	uint8_t		im_op;
+	uint16_t	im_reason;
+	uint8_t		im_macaddr[6];
+} wl_mlme_t;
+
+/*
+ * beacon, probe response
+ */
+
+#pragma pack(1)
 typedef struct wl_ess_conf {
-	uint32_t wl_ess_conf_length;
-	wl_essid_t wl_ess_conf_essid;
-	wl_bssid_t wl_ess_conf_bssid;
-	char wl_ess_conf_reserved[2];
-	wl_bss_type_t wl_ess_conf_bsstype;
-	wl_authmode_t wl_ess_conf_authmode;
-	boolean_t wl_ess_conf_wepenabled;
-	wl_rssi_t wl_ess_conf_sl;
+	uint32_t 		wl_ess_conf_length;
+	wl_essid_t 		wl_ess_conf_essid;
+	wl_bssid_t 		wl_ess_conf_bssid;
+	wl_beacon_period_t	wl_ess_conf_beacon_period;
+	wl_beacon_tsf_t		wl_ess_conf_beacon_tsf;
+	wl_beacon_age_t		wl_ess_conf_beacon_age;
+	wl_rssi_t 		wl_ess_conf_sl;
+	char 			wl_supported_rates[MAX_SCAN_SUPPORT_RATES];
 	union {
-		wl_fhss_t wl_phy_fhss_conf;
-		wl_dsss_t wl_phy_dsss_conf;
-		wl_ofdm_t wl_phy_ofdm_conf;
-		wl_erp_t wl_phy_erp_conf;
+		wl_fhss_t 	wl_phy_fhss_conf;
+		wl_dsss_t 	wl_phy_dsss_conf;
+		wl_ofdm_t 	wl_phy_ofdm_conf;
+		wl_erp_t 	wl_phy_erp_conf;
 	} wl_phy_conf;
-	char wl_supported_rates[MAX_SCAN_SUPPORT_RATES];
+	/* ieee80211_node capinfo != ieee80211com caps */
+	wl_ess_caps 		wl_ess_conf_caps;
+	uint32_t		wl_ess_conf_wpa_ie_len;
+	uint8_t			wl_ess_conf_wpa_ie[40];
 } wl_ess_conf_t;
+#pragma pack()
 
 typedef struct wl_ess_list {
 	uint32_t wl_ess_list_num;
--- old/usr/src/uts/common/io/dld/dld_drv.c	2012-06-12 19:55:16.547117754 +0200
+++ new/usr/src/uts/common/io/dld/dld_drv.c	2012-06-12 19:55:16.570308918 +0200
@@ -1167,8 +1167,7 @@
 
 	sobjp = &ssp->ss_obj;
 
-	if (sobjp->so_class != DLD_SECOBJ_CLASS_WEP &&
-	    sobjp->so_class != DLD_SECOBJ_CLASS_WPA)
+	if (sobjp->so_class == DLD_SECOBJ_CLASS_TLS)
 		return (EINVAL);
 
 	if (sobjp->so_name[DLD_SECOBJ_NAME_MAX - 1] != '\0' ||
--- old/usr/src/uts/common/io/mac/mac.c	2012-06-12 19:55:18.062680297 +0200
+++ new/usr/src/uts/common/io/mac/mac.c	2012-06-12 19:55:18.090776511 +0200
@@ -311,7 +311,6 @@
 #include <sys/pool_pset.h>
 #include <sys/cpupart.h>
 #include <inet/wifi_ioctl.h>
-#include <net/wpa.h>
 
 #define	IMPL_HASHSZ	67	/* prime */
 
@@ -2959,9 +2958,6 @@
 	case MAC_PROP_WL_WPA:
 		minsize = sizeof (wl_wpa_t);
 		break;
-	case MAC_PROP_WL_SCANRESULTS:
-		minsize = sizeof (wl_wpa_ess_t);
-		break;
 	case MAC_PROP_WL_POWER_MODE:
 		minsize = sizeof (wl_ps_mode_t);
 		break;
--- old/usr/src/uts/common/io/net80211/net80211.c	2012-06-12 19:55:23.530885546 +0200
+++ new/usr/src/uts/common/io/net80211/net80211.c	2012-06-12 19:55:23.555024148 +0200
@@ -191,9 +191,6 @@
 void
 ieee80211_notify(ieee80211com_t *ic, wpa_event_type event)
 {
-	if ((ic->ic_flags & IEEE80211_F_WPA) == 0)
-		return;		/* Not running on WPA mode */
-
 	ic->ic_eventq[ic->ic_evq_tail] = event;
 	ic->ic_evq_tail ++;
 	if (ic->ic_evq_tail >= MAX_EVENT) ic->ic_evq_tail = 0;
--- old/usr/src/uts/common/io/net80211/net80211_ioctl.c	2012-06-12 19:55:24.724730847 +0200
+++ new/usr/src/uts/common/io/net80211/net80211_ioctl.c	2012-06-12 19:55:24.748710244 +0200
@@ -64,7 +64,6 @@
 static void wl_get_capability(struct ieee80211com *, void *);
 static int wl_set_wpa(struct ieee80211com *, const void *);
 static void wl_get_wpa(struct ieee80211com *, void *);
-static void wl_get_scanresults(struct ieee80211com *, void *);
 static void wl_get_esslist(struct ieee80211com *, void *);
 static int wl_set_wepkey(struct ieee80211com *, const void *);
 static int wl_set_optie(struct ieee80211com *, const void *);
@@ -732,14 +731,23 @@
 	bcopy(in->in_essid, conf->wl_ess_conf_essid.wl_essid_essid,
 	    in->in_esslen);
 	bcopy(in->in_bssid, conf->wl_ess_conf_bssid, IEEE80211_ADDR_LEN);
-	conf->wl_ess_conf_wepenabled =
-	    (in->in_capinfo & IEEE80211_CAPINFO_PRIVACY ?
-	    WL_ENC_WEP : WL_NOENCRYPTION);
-	conf->wl_ess_conf_bsstype =
-	    (in->in_capinfo & IEEE80211_CAPINFO_ESS ?
-	    WL_BSS_BSS : WL_BSS_IBSS);
+
+	conf->wl_ess_conf_beacon_period = in->in_intval;
+	conf->wl_ess_conf_beacon_tsf = in->in_tstamp.tsf;
+	conf->wl_ess_conf_beacon_age = in->in_rstamp;
+
 	conf->wl_ess_conf_sl = wifi_getrssi(in);
-	conf->wl_ess_conf_reserved[0] = (in->in_wpa_ie == NULL? 0 : 1);
+
+	conf->wl_ess_conf_caps = in->in_capinfo;
+	/* authmode is set to IEEE80211_AUTH_OPEN = 1 by default */
+
+	if (in->in_wpa_ie == NULL) {
+		conf->wl_ess_conf_wpa_ie_len = 0;
+	} else {
+		conf->wl_ess_conf_wpa_ie_len = in->in_wpa_ie[1] + 2;
+		bcopy(in->in_wpa_ie, conf->wl_ess_conf_wpa_ie,
+		    conf->wl_ess_conf_wpa_ie_len);
+	}
 
 	/* physical (FH, DS, ERP) parameters */
 	if (IEEE80211_IS_CHAN_A(chan) || IEEE80211_IS_CHAN_T(chan)) {
@@ -1129,78 +1137,6 @@
 }
 
 /*
- * To be compatible with drivers/tools of OpenSolaris.org,
- * we use a different ID to filter out those APs of WPA mode.
- */
-static int
-wifi_cfg_scanresults(struct ieee80211com *ic, uint32_t cmd, mblk_t **mp)
-{
-	mblk_t *omp;
-	wldp_t *outp;
-	wl_wpa_ess_t *sr;
-	ieee80211_node_t *in;
-	ieee80211_node_table_t *nt;
-	int len, ap_num = 0;
-	int err = 0;
-
-	if ((omp = wifi_getoutmsg(*mp, cmd, MAX_BUF_LEN - WIFI_BUF_OFFSET)) ==
-	    NULL) {
-		return (ENOMEM);
-	}
-	outp = (wldp_t *)omp->b_rptr;
-	sr = (wl_wpa_ess_t *)outp->wldp_buf;
-	sr->count = 0;
-
-	switch (cmd) {
-	case WLAN_GET_PARAM:
-		ieee80211_dbg(IEEE80211_MSG_WPA, "wifi_cfg_scanresults\n");
-		nt = &ic->ic_scan;
-		IEEE80211_NODE_LOCK(nt);
-		in = list_head(&nt->nt_node);
-		while (in != NULL) {
-			/* filter out non-WPA APs */
-			if (in->in_wpa_ie == NULL) {
-				in = list_next(&nt->nt_node, in);
-				continue;
-			}
-			bcopy(in->in_bssid, sr->ess[ap_num].bssid,
-			    IEEE80211_ADDR_LEN);
-			sr->ess[ap_num].ssid_len = in->in_esslen;
-			bcopy(in->in_essid, sr->ess[ap_num].ssid,
-			    in->in_esslen);
-			sr->ess[ap_num].freq = in->in_chan->ich_freq;
-
-			len = in->in_wpa_ie[1] + 2;
-			bcopy(in->in_wpa_ie, sr->ess[ap_num].wpa_ie, len);
-			sr->ess[ap_num].wpa_ie_len = len;
-
-			ap_num ++;
-			in = list_next(&nt->nt_node, in);
-		}
-		IEEE80211_NODE_UNLOCK(nt);
-		sr->count = ap_num;
-		outp->wldp_length = WIFI_BUF_OFFSET +
-		    offsetof(wl_wpa_ess_t, ess) +
-		    sr->count * sizeof (struct wpa_ess);
-		omp->b_wptr = omp->b_rptr + outp->wldp_length;
-		break;
-	case WLAN_SET_PARAM:
-		outp->wldp_result = WL_READONLY;
-		err = EINVAL;
-		break;
-	default:
-		ieee80211_err("wifi_cfg_scanresults: unknown cmmand %x\n", cmd);
-		outp->wldp_result = WL_NOTSUPPORTED;
-		err = EINVAL;
-		break;
-	}
-
-	freemsg(*mp);
-	*mp = omp;
-	return (err);
-}
-
-/*
  * Manually control the state of AUTH | DEAUTH | DEASSOC | ASSOC
  */
 static int
@@ -1308,30 +1244,6 @@
 	case WL_RSSI:
 		err = wifi_cfg_rssi(ic, cmd, mp);
 		break;
-	/*
-	 * WPA IOCTLs
-	 */
-	case WL_CAPABILITY:
-		err = wifi_cfg_caps(ic, cmd, mp);
-		break;
-	case WL_WPA:
-		err = wifi_cfg_wpa(ic, cmd, mp);
-		break;
-	case WL_KEY:
-		err = wifi_cfg_wpakey(ic, cmd, mp);
-		break;
-	case WL_DELKEY:
-		err = wifi_cfg_delkey(ic, cmd, mp);
-		break;
-	case WL_SETOPTIE:
-		err = wifi_cfg_setoptie(ic, cmd, mp);
-		break;
-	case WL_SCANRESULTS:
-		err = wifi_cfg_scanresults(ic, cmd, mp);
-		break;
-	case WL_MLME:
-		err = wifi_cfg_setmlme(ic, cmd, mp);
-		break;
 	default:
 		wifi_setupoutmsg(mp1, 0);
 		wp->wldp_result = WL_LACK_FEATURE;
@@ -1485,7 +1397,6 @@
 	bcopy(essid, ow_essid.wl_essid_essid,
 	    ow_essid.wl_essid_length);
 	bcopy(&ow_essid, wldp_buf, sizeof (wl_essid_t));
-
 }
 
 /*
@@ -1567,7 +1478,7 @@
 		ow_opmode = WL_BSS_IBSS;
 		break;
 	default:
-		ow_opmode = WL_BSS_ANY;
+		ow_opmode = WL_BSS_BSS;
 		break;
 	}
 
@@ -1949,54 +1860,6 @@
 }
 
 /*
- * MAC_PROP_WL_SCANRESULTS
- */
-
-static void
-wl_get_scanresults(struct ieee80211com *ic, void *wldp_buf)
-{
-	wl_wpa_ess_t *sr;
-	ieee80211_node_t *in;
-	ieee80211_node_table_t *nt;
-	int ap_num;
-	int len;
-
-	sr = (wl_wpa_ess_t *)wldp_buf;
-	sr->count = 0;
-	ap_num = 0;
-
-	ieee80211_dbg(IEEE80211_MSG_WPA, "wl_get_scanrelults\n");
-
-	nt = &ic->ic_scan;
-	IEEE80211_NODE_LOCK(nt);
-	in = list_head(&nt->nt_node);
-
-	while (in != NULL) {
-		/* filter out non-wpa APs */
-		if (in->in_wpa_ie == NULL) {
-			in = list_next(&nt->nt_node, in);
-			continue;
-		}
-		bcopy(in->in_bssid, sr->ess[ap_num].bssid,
-		    IEEE80211_ADDR_LEN);
-		sr->ess[ap_num].ssid_len = in->in_esslen;
-		bcopy(in->in_essid, sr->ess[ap_num].ssid,
-		    in->in_esslen);
-		sr->ess[ap_num].freq = in->in_chan->ich_freq;
-
-		len = in->in_wpa_ie[1] + 2;
-		bcopy(in->in_wpa_ie, sr->ess[ap_num].wpa_ie, len);
-		sr->ess[ap_num].wpa_ie_len = len;
-
-		ap_num++;
-		in = list_next(&nt->nt_node, in);
-	}
-	IEEE80211_NODE_UNLOCK(nt);
-	sr->count = ap_num;
-
-}
-
-/*
  * MAC_PROP_WL_ESS_LIST
  */
 static void
@@ -2096,7 +1959,7 @@
 	(void) memcpy(ie, ie_in->wpa_ie, ie_in->wpa_ie_len);
 	if (ic->ic_opt_ie != NULL) {
 		ieee80211_dbg(IEEE80211_MSG_BRUSSELS,
-		    "wl_set_optie:ic_opt_ie!=NULL\n");
+		    "wl_set_optie: ic_opt_ie != NULL\n");
 		ieee80211_free(ic->ic_opt_ie);
 	}
 	ic->ic_opt_ie = ie;
@@ -2146,8 +2009,8 @@
 	ieee80211_node_t *in;
 	wl_mlme_t *mlme = (wl_mlme_t *)wldp_buf;
 
-	ieee80211_dbg(IEEE80211_MSG_WPA, "wl_set_mlme: "
-	    "op=%d\n", mlme->im_op);
+	ieee80211_dbg(IEEE80211_MSG_WPA, "wl_set_mlme: op=%d <%s> \n",
+	    mlme->im_op, ieee80211_macaddr_sprintf(mlme->im_macaddr));
 
 	switch (mlme->im_op) {
 	case IEEE80211_MLME_DISASSOC:
@@ -2174,7 +2037,10 @@
 			err = EINVAL;
 			break;
 		}
-		if (ic->ic_des_esslen != 0) {
+		if (ic->ic_flags & IEEE80211_F_DESBSSID) {
+			in = ieee80211_find_node(&ic->ic_scan,
+			    ic->ic_des_bssid);
+		} else if (ic->ic_des_esslen != 0) {
 		/*
 		 * Desired ssid specified; must match both bssid and
 		 * ssid to distinguish ap advertising multiple ssid's.
@@ -2379,6 +2245,13 @@
  * 		When acknowledge a M_IOCTL message, this error
  * 		is ignored
  */
+
+/*
+ * Not implemented:
+ * MAC_PROP_WL_POWER_MODE
+ * MAC_PROP_WL_RADIO,
+ */
+
 /* ARGSUSED */
 int
 ieee80211_setprop(void *ic_arg, const char *pr_name, mac_prop_id_t wldp_pr_num,
@@ -2439,10 +2312,6 @@
 	case MAC_PROP_WL_SUPPORTED_RATES:
 	case MAC_PROP_WL_RSSI:
 	case MAC_PROP_WL_CAPABILITY:
-	case MAC_PROP_WL_SCANRESULTS:
-		ieee80211_err("ieee80211_setprop: opmode err\n");
-		err = EINVAL;
-		break;
 	default:
 		ieee80211_err("ieee80211_setprop: opmode not support\n");
 		err = ENOTSUP;
@@ -2506,9 +2375,6 @@
 	case MAC_PROP_WL_WPA:
 		wl_get_wpa(ic, wldp_buf);
 		break;
-	case MAC_PROP_WL_SCANRESULTS:
-		wl_get_scanresults(ic, wldp_buf);
-		break;
 	case MAC_PROP_WL_CREATE_IBSS:
 		wl_get_createibss(ic, wldp_buf);
 		break;
@@ -2547,7 +2413,6 @@
 	case MAC_PROP_WL_SUPPORTED_RATES:
 	case MAC_PROP_WL_RSSI:
 	case MAC_PROP_WL_CAPABILITY:
-	case MAC_PROP_WL_SCANRESULTS:
 	case MAC_PROP_WL_CREATE_IBSS:
 		mac_prop_info_set_perm(prh, MAC_PROP_PERM_READ);
 	}
--- old/usr/src/uts/common/net/Makefile	2012-06-12 19:55:27.236348175 +0200
+++ new/usr/src/uts/common/net/Makefile	2012-06-12 19:55:27.259741349 +0200
@@ -28,7 +28,7 @@
 
 HDRS=	af.h if.h if_arp.h if_dl.h if_types.h route.h pfkeyv2.h pfpolicy.h \
 	ppp-comp.h ppp_defs.h pppio.h vjcompress.h sppptun.h pppoe.h radix.h \
-	wpa.h simnet.h bridge.h bridge_impl.h trill.h
+	simnet.h bridge.h bridge_impl.h trill.h
 
 ROOTDIRS= $(ROOT)/usr/include/net
 
--- old/usr/src/uts/common/sys/dld.h	2012-06-12 19:55:28.000929069 +0200
+++ new/usr/src/uts/common/sys/dld.h	2012-06-12 19:55:28.023913024 +0200
@@ -119,10 +119,17 @@
 
 /*
  * Secure objects ioctls
+ * 1.WEP Static key in 64 hex-digits
+ * 2.WPA 256-bit preshared key in 64 hex-digits
+ * 3.User password string for EAP methods (except EAP-TLS) in 64 hex-digits
+ * 4.Client Private key PKCS#11 keystore PIN
  */
 typedef enum {
-	DLD_SECOBJ_CLASS_WEP = 1,
-	DLD_SECOBJ_CLASS_WPA
+	DLD_SECOBJ_CLASS_WEP = 0,
+	DLD_SECOBJ_CLASS_PSK,
+	DLD_SECOBJ_CLASS_TLS,
+	DLD_SECOBJ_CLASS_TTLS,
+	DLD_SECOBJ_CLASS_PEAP
 } dld_secobj_class_t;
 
 #define	DLD_SECOBJ_OPT_CREATE	0x00000001
--- old/usr/src/uts/common/sys/mac.h	2012-06-12 19:55:28.955046757 +0200
+++ new/usr/src/uts/common/sys/mac.h	2012-06-12 19:55:28.978320506 +0200
@@ -180,7 +180,6 @@
 	MAC_PROP_WL_PHY_CONFIG,
 	MAC_PROP_WL_CAPABILITY,
 	MAC_PROP_WL_WPA,
-	MAC_PROP_WL_SCANRESULTS,
 	MAC_PROP_WL_POWER_MODE,
 	MAC_PROP_WL_RADIO,
 	MAC_PROP_WL_ESS_LIST,
--- old/usr/src/uts/common/sys/net80211.h	2012-06-12 19:55:30.043619071 +0200
+++ new/usr/src/uts/common/sys/net80211.h	2012-06-12 19:55:30.067007526 +0200
@@ -44,7 +44,6 @@
 #include <sys/net80211_proto.h>
 #include <sys/net80211_crypto.h>
 #include <sys/net80211_ht.h>
-#include <net/wpa.h>
 
 /*
  * IEEE802.11 kernel support module
@@ -229,6 +228,9 @@
 #define	MAX_EVENT		16
 #define	MAX_IEEE80211STR	256
 
+/* required for 'arn' driver */
+#define	MAX_RSSI 		15
+
 /* For IEEE80211_RADIOTAP_FLAGS */
 #define	IEEE80211_RADIOTAP_F_CFP	0x01
 					/* sent/received during CFP */
@@ -250,6 +252,9 @@
 
 /*
  * Authentication mode.
+ * auth_algs should be only OPEN/SHARED/LEAP
+ * see IEEE80211_AUTH_ALG_* in net80211_proto.h
+ * NONE/8021X/AUTO/WPA refer to key_mgmt protocols!
  */
 enum ieee80211_authmode {
 	IEEE80211_AUTH_NONE	= 0,
@@ -257,7 +262,7 @@
 	IEEE80211_AUTH_SHARED	= 2,	/* shared-key */
 	IEEE80211_AUTH_8021X	= 3,	/* 802.1x */
 	IEEE80211_AUTH_AUTO	= 4,	/* auto-select/accept */
-	/* NB: these are used only for ioctls */
+	/* actually, this is never used */
 	IEEE80211_AUTH_WPA	= 5	/* WPA/RSN w/ 802.1x/PSK */
 };
 
@@ -268,8 +273,25 @@
 	IEEE80211_S_ASSOC	= 3,	/* try to assoc */
 	IEEE80211_S_RUN		= 4	/* associated */
 };
+
 #define	IEEE80211_S_MAX	(IEEE80211_S_RUN+1)
 
+#define	WPA_DOOR 	"/var/run/wpa_door"
+
+/*
+ * WPA State machine events
+ */
+typedef enum {
+	EVENT_ASSOC,
+	EVENT_DISASSOC,
+	EVENT_SCAN_RESULTS = 3
+} wpa_event_type;
+
+typedef struct  wl_events {
+	wpa_event_type	event;
+} wl_events_t;
+
+
 /*
  * 802.11 rate set.
  */
--- old/usr/src/uts/common/sys/net80211_proto.h	2012-06-12 19:55:31.595710113 +0200
+++ new/usr/src/uts/common/sys/net80211_proto.h	2012-06-12 19:55:31.619960110 +0200
@@ -789,7 +789,7 @@
 
 #define	WPA_OUI			0xf25000
 #define	WPA_OUI_TYPE		0x01
-#define	WPA_VERSION		1		/* current supported version */
+//#define	WPA_VERSION		1		/* current supported version */
 
 #define	IEEE80211_CHALLENGE_LEN			128
 
