door.c revision b00044a2eb43864b8718585d21949611a2ee59ef
/*
* 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
* 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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* This file contains the library interface for the nwamd libdoor(3LIB)
* service. This library is intended for use by an external GUI utility to
* provide status information to users and allow control over nwam behavior in
* certain situations.
*/
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <door.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <libdladm.h>
#include <libnwam.h>
/* Special include files; data structures shared with nwamd */
#include <defines.h>
#include <structures.h>
static int door_fd = -1;
/*
* This lock protects the library against descriptor leaks caused by multiple
* threads attempting to race at opening the door. It also protects the door
* users by preventing reinit while busy.
*/
static uint_t door_users;
#define BUFFER_SIZE 256
/* ARGSUSED */
static void
door_cancel_handler(void *arg)
{
(void) pthread_mutex_lock(&door_lock);
door_users--;
(void) pthread_mutex_unlock(&door_lock);
}
/*
* This wraps around door_call(3C), and makes sure that interrupts and error
* cases are handled in a reasonable way and that we always have an accurate
* door user count.
*/
static int
{
int retv;
/*
* In order to avoid blocking and starving out the init routine, we
* check here for a descriptor before attempting to take a lock.
*/
if (door_fd == -1) {
return (-1);
}
return (-1);
}
door_users++;
(void) pthread_mutex_unlock(&door_lock);
/* The door_call function doesn't restart, so take care of that */
do {
errno = 0;
break;
/* No legitimate door call on our server returns without data */
retv = -1;
}
return (retv);
}
/*
* This is a common clean-up function for the door-calling routines. It checks
* for the daemon's standard error return mechanism (single integer with an
* errno) and for the special case of an oversized return buffer.
*/
static int
{
retv = -1;
return (retv);
}
/*
* Convert the internal libdladm representation of WLAN attributes into a text
* representation that we can send to the client. The passed-in 'strbuf'
* parameter points to a buffer that's known to be large enough to hold all of
* the strings.
*/
static char *
{
static const struct {
char *(*cvt)(void *, char *);
} cvtable[] = {
{
(char *(*)(void *, char *))dladm_wlan_essid2str,
},
{
(char *(*)(void *, char *))dladm_wlan_bssid2str,
},
{
(char *(*)(void *, char *))dladm_wlan_secmode2str,
},
{
(char *(*)(void *, char *))dladm_wlan_strength2str,
},
{
(char *(*)(void *, char *))dladm_wlan_mode2str,
},
{
(char *(*)(void *, char *))dladm_wlan_speed2str,
},
{
(char *(*)(void *, char *))dladm_wlan_auth2str,
},
{
(char *(*)(void *, char *))dladm_wlan_bsstype2str,
},
{ 0, NULL, 0 }
};
int i;
char **cptr;
/* LINTED: pointer alignment */
strbuf);
} else {
*cptr = "";
}
}
/* This one element is a simple integer, not a string */
return (strbuf);
}
/*
* Wait for an event from the daemon and return it to the caller in allocated
* storage.
*/
libnwam_wait_event(void)
{
int retv;
char *str;
}
nde->nde_interface);
if (has_wlan_attrs)
}
}
return (led);
}
/* Free an allocated event */
void
{
}
/*
* Get a list of Lower-Layer Profiles (interfaces) in a single allocated array.
*/
{
int retv;
const nwam_llp_data_t *nld;
char *sbuf;
*numllp = 0;
return (NULL);
}
/* Figure room needed to return strings to caller */
strsize = 0;
llp++;
}
/* Convert internal to external structures */
nllp->llp_primary =
nllp->llp_locked =
nllp++;
llp++;
}
}
return (nllpret);
}
/* Free an LLP list */
void
{
}
/* Set the priority for a single LLP */
int
{
int retv;
}
/* Lock a single LLP as selected */
int
libnwam_lock_llp(const char *ifname)
{
int retv;
sizeof (cmd.ndc_interface));
} else {
}
}
/* Get an array listing the scanned WLANs (Access Points) and attributes */
{
int retv;
char *sbuf;
*numwlans = 0;
return (NULL);
}
/* Figure amount of storage needed for strings */
strsize = 0;
wllp++;
}
WLA_NUM_STRS) + strsize);
/* Convert internal to external structures */
sbuf);
wllp++;
wlan++;
}
} else {
count = 0;
}
return (wlanret);
}
/* Free array of WLANs */
void
{
}
/* Get the non-volatile list of known user-specified Access Points */
{
int retv;
char *sbuf;
*numkas = 0;
return (NULL);
}
/*
* Buffer returned from daemon has string offsets in place of
* pointers; convert back to pointers for user.
*/
break;
break;
kabuf++;
kap++;
}
} else {
count = 0;
}
return (kapret);
}
/* Free a Known AP list */
void
{
}
/*
* Add a new AP to the "known" list so that we'll automatically connect.
* BSSID is optional.
*/
int
{
int retv;
}
/*
* Delete an AP from the "known" list so that we won't connect to it
* automatically. BSSID is optional.
*/
int
{
int retv;
}
/*
* Select a particular Access Point (WLAN) for use on a given interface. This
* may disconnect from the current AP if the link is already connected.
*/
int
{
int retv;
}
/*
* Set the encryption key needed for a given AP. The key string is cleartext.
*/
int
const char *key)
{
int retv;
}
/* Initiate wireless scan on the indicated interface */
int
libnwam_start_rescan(const char *ifname)
{
int retv;
}
/* Shut down the library. */
int
libnwam_fini(void)
{
int retv;
return (-1);
}
if (door_fd != -1) {
door_fd = -1;
}
(void) pthread_mutex_unlock(&door_lock);
return (retv);
}
/*
* Initialize the library for use. Waittime is the number of seconds
* (approximate) to wait for the daemon to become available if it isn't ready
* immediately. This may be -1 to wait forever, or 0 to open the connection to
* the daemon without waiting (i.e., fail if not ready now).
*/
int
libnwam_init(int waittime)
{
int newfd;
int retv;
for (;;) {
break;
}
if (door_users != 0) {
(void) pthread_mutex_unlock(&door_lock);
break;
}
if (door_fd != -1) {
door_fd = -1;
}
if (newfd != -1) {
/* Make a dummy call to make sure daemon is running */
if (retv == 0) {
/* Call worked; we're done. */
(void) pthread_mutex_unlock(
&door_lock);
return (0);
} else {
}
} else {
}
/*
* Zero data means daemon terminated.
* Otherwise, this is a permanent error. No
* point in waiting around and retrying for a
* permanent problem.
*/
(void) pthread_mutex_unlock(&door_lock);
break;
}
}
}
(void) pthread_mutex_unlock(&door_lock);
if (waittime == 0)
break;
if (waittime > 0)
waittime--;
/*
* We could do something smarter here, but decline to for now.
* This is "good enough" for NWAM Phase 0.5.
*/
(void) sleep(1);
}
return (-1);
}