known_wlans.c revision c1976b8365310f23085adaa53cf00b14039014c8
/*
* 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
*/
/*
*/
#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libdladm.h>
#include <libdllink.h>
#include <libdlwlan.h>
#include <libgen.h>
#include <libnwam.h>
#include "events.h"
#include "known_wlans.h"
#include "ncu.h"
#include "objects.h"
#include "util.h"
/*
* known_wlans.c - contains routines which handle the known WLAN abstraction.
*/
#define KNOWN_WIFI_NETS_FILE "/etc/nwam/known_wifi_nets"
/* enum for parsing each line of /etc/nwam/known_wifi_nets */
typedef enum {
ESSID = 0,
/* Structure for one BSSID */
typedef struct bssid {
struct qelem bssid_links;
char *bssid;
} bssid_t;
/* Structure for an ESSID and its BSSIDs */
typedef struct kw {
char kw_essid[NWAM_MAX_NAME_LEN];
} kw_t;
/* Holds the linked-list of ESSIDs to make Known WLANs out of */
/* Used in walking secobjs looking for an ESSID prefix match. */
struct nwamd_secobj_arg {
};
static void
kw_list_init(void)
{
}
static void
kw_list_free(void)
{
bssid_t *b;
/* free kw_bssids */
remque(&b->bssid_links);
free(b);
}
}
}
/* Returns the entry in kw_list for the given ESSID. NULL if non-existent */
static kw_t *
{
return (NULL);
return (kw);
}
return (NULL);
}
static boolean_t
{
bssid_t *b;
return (B_FALSE);
}
free(b);
return (B_FALSE);
}
return (B_TRUE);
}
/*
* Add the BSSID to the given kw. Since /etc/nwam/known_wifi_nets is
* populated such that the wifi networks visited later are towards the end
* of the file, remove the give kw from its current position and append it
* to the end of kw_list. This ensures that kw_list is in the reverse
* order of visited wifi networks. Returns B_TRUE on success.
*/
static boolean_t
{
bssid_t *b;
return (B_FALSE);
}
kw->kw_num_bssids++;
/* remove kw from current position */
/* and insert at end */
return (B_TRUE);
}
/*
* Parses /etc/nwam/known_wifi_nets and populates kw_list, with the oldest
* wifi networks first in the list. Returns the number of unique entries
* in kw_list (to use for priority values).
*/
static int
parse_known_wifi_nets(void)
{
kw_list_init();
/*
* The file format is:
* essid\tbssid (essid followed by tab followed by bssid)
*/
return (0);
cp++;
continue;
continue;
}
"%s:%d: cannot add entry (%s,%s) to list",
} else {
num_kw++;
}
} else {
"%s:%d:cannot update entry (%s,%s) to list",
}
}
/* next line ... */
}
return (num_kw);
}
/*
* Walk security objects looking for one that matches the essid prefix.
* Store the key and keyname if a match is found - we use the last match
* as the key for the known WLAN, since it is the most recently updated.
*/
/* ARGSUSED0 */
static boolean_t
const char *secobjname)
{
"found secobj with prefix %s : %s\n",
/* Free last key found (if any) */
/* Retrive key so we can get security mode */
sizeof (nsa->nsa_keyname));
case DLADM_SECOBJ_CLASS_WEP:
break;
case DLADM_SECOBJ_CLASS_WPA:
break;
default:
/* shouldn't happen */
"key class for key %s was invalid",
nsa->nsa_keyname);
break;
}
}
return (B_TRUE);
}
/* Upgrade /etc/nwam/known_wifi_nets file to new libnwam-based config model */
void
{
bssid_t *b;
char **bssids;
int i, num_kw;
struct nwamd_secobj_arg nsa;
/* Parse /etc/nwam/known_wifi_nets */
/* Create Known WLANs for each unique ESSID */
!= NWAM_SUCCESS) {
nwam_strerror(err));
continue;
}
/* priority of this ESSID */
!= NWAM_SUCCESS) {
nwam_strerror(err));
continue;
}
if (err != NWAM_SUCCESS) {
nwam_strerror(err));
continue;
}
/* loop through kw->kw_bssids and create an array of bssids */
continue;
}
}
/* BSSIDs for this ESSID */
nwam_strerror(err));
for (i = 0; i < kw->kw_num_bssids; i++)
continue;
}
for (i = 0; i < kw->kw_num_bssids; i++)
if (err != NWAM_SUCCESS) {
nwam_strerror(err));
continue;
}
/*
* Retrieve last key matching ESSID prefix if any, and set
* the retrieved key name and security mode.
*/
sizeof (nsa.nsa_essid_prefix));
&keynameval)) == NWAM_SUCCESS) {
(void) nwam_known_wlan_set_prop_value(kwh,
}
}
&secmodeval)) != NWAM_SUCCESS ||
!= NWAM_SUCCESS) {
"could not set security mode: %s",
continue;
}
/* commit, no collision checking by libnwam */
if (err != NWAM_SUCCESS) {
nwam_strerror(err));
}
/* next ... */
}
kw_list_free();
}
{
char *keyname;
return (err);
== NWAM_SUCCESS) {
}
if (keynameval != NULL)
return (err);
}
/* Performs a scan on a wifi link NCU */
/* ARGSUSED */
static int
{
return (0);
/* network selection will be done only if possible */
return (0);
}
/* Handle known WLAN initialization/refresh event */
/* ARGSUSED */
void
{
/*
* Since the Known WLAN list has changed, do a rescan so that the
* best network is selected.
*/
}
void
{
nwe_action) {
case NWAM_ACTION_ADD:
case NWAM_ACTION_REFRESH:
break;
case NWAM_ACTION_DESTROY:
/* Nothing needs to be done for destroy */
break;
/* all other events are invalid for known WLANs */
case NWAM_ACTION_ENABLE:
case NWAM_ACTION_DISABLE:
default:
"unexpected action");
break;
}
}
int
{
if (known_wlan_event == NULL)
return (1);
return (0);
}