/*
* 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 <libdladm.h>
#include <libdllink.h>
#include <libdlwlan.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <libnwam.h>
#include "conditions.h"
#include "ncu.h"
#include "objects.h"
#include "util.h"
/*
* conditions.c - contains routines which check state to see if activation
* conditions for NWAM objects are satisfied and rates activation conditions to
* help determine which is most specific.
*
* If the activation-mode is CONDITIONAL_ANY or CONDITIONAL_ALL, the conditions
* property is set to a string made up of conditional expressions. Each
* expression is made up of a condition that can be assigned a boolean value,
* e.g. "system-domain is sun.com" or "ncu ip:bge0 is-not active". If the
* activation-mode is CONDITIONAL_ANY, the condition will be satisfied if any
* one of the conditions is true; if the activation-mode is CONDITIONAL_ALL,
* the condition is satisfied only if all of the conditions are true.
*/
extern int getdomainname(char *, int);
/* NCP, NCU, ENM and location conditions */
const char *ncp_name);
const char *ncu_name);
const char *enm_name);
const char *loc_name);
/* IP address conditions */
const char *ip_address);
/* domainname conditions */
const char *domainname);
const char *domainname);
/* WLAN conditions */
const char *essid);
const char *essid);
struct nwamd_condition_map {
} condition_map[] =
{
};
/*
* This function takes which kind of conditions (is or is not) we are testing
* the object against and an object and applies the conditon to the object.
*/
static boolean_t
{
return (B_FALSE);
switch (condition) {
case NWAM_CONDITION_IS:
return (state == NWAM_STATE_ONLINE);
case NWAM_CONDITION_IS_NOT:
return (state != NWAM_STATE_ONLINE);
default:
return (B_FALSE);
}
}
static boolean_t
{
(void) pthread_mutex_lock(&active_ncp_mutex);
(void) pthread_mutex_unlock(&active_ncp_mutex);
switch (condition) {
case NWAM_CONDITION_IS:
return (active);
case NWAM_CONDITION_IS_NOT:
default:
return (B_FALSE);
}
}
static boolean_t
{
/* names are case-insensitive, so get real name from libnwam */
== NWAM_SUCCESS) {
&ncuh) == NWAM_SUCCESS) {
} else {
return (B_FALSE);
}
return (B_FALSE);
}
/*
* Name may be either unqualified or qualified by NCU type
* (interface:/link:). Need to translate unqualified names
* to qualified, specifying interface:name if an interface
* NCU is present, otherwise link:ncu.
*/
!= NWAM_SUCCESS) {
return (B_FALSE);
}
ncu_name);
return (rv);
}
static boolean_t
{
char *real_name;
/* names are case-insensitive, so get real name from libnwam */
return (B_FALSE);
return (B_FALSE);
}
return (rv);
}
static boolean_t
{
char *real_name;
/* names are case-insensitive, so get real name from libnwam */
return (B_FALSE);
return (B_FALSE);
}
return (rv);
}
static boolean_t
const char *found_domain)
{
/* convert target_domain and found_domain to lowercase for strstr() */
for (i = 0; i < len_t; i++)
for (i = 0; i < len_f; i++)
switch (condition) {
case NWAM_CONDITION_IS:
case NWAM_CONDITION_IS_NOT:
case NWAM_CONDITION_CONTAINS:
default:
return (B_FALSE);
}
}
struct ncu_adv_domains {
char *dns_domain;
char *nis_domain;
};
static int
{
return (0);
return (1);
}
return (0);
}
static boolean_t
{
return (B_FALSE);
}
static boolean_t
{
&adv_domains);
/*
* Walk the advertised domain list. Our test function tests one
* single domain, but we're dealing with a list: if our condition
* is positive ('is' or 'contains'), the test function for each
* domain results are or'd together; if our condition is negative
* ('is-not' or 'does-not-contain'), the test function results must
* be and'd. Thus our short-circuit exit value depends on our
* condition: if the test function returns TRUE it implies immediate
* success for a positive condition; if it returns FALSE it implies
* immediate failure for a negative condition.
*/
adp = adv_domains;
break;
}
}
/*
* We did not short-circuit; we therefore failed if our
* condition was positive, and succeeded if our condition
* was negative.
*/
}
/* now free the domain list */
adp = adv_domains;
}
return (rtn);
}
/*
* Returns true if prefixlen bits of addr1 match prefixlen bits of addr2.
*/
static boolean_t
{
int i, j = 0;
if (prefixlen == 0)
return (B_TRUE);
while (prefixlen > 0) {
if (prefixlen >= 8) {
mask[j++] = 0xFF;
prefixlen -= 8;
} else {
prefixlen--;
}
}
/* Ensure at least one byte is tested */
if (j == 0) j++;
for (i = 0; i < j; i++) {
return (B_FALSE);
}
return (B_TRUE);
}
/*
* Given a string representation of an IPv4 or IPv6 address returns the
* sockaddr representation. Note that 'sockaddr' should point at the correct
* sockaddr structure for the address family (sockaddr_in for AF_INET or
* sockaddr_in6 for AF_INET6) or alternatively at a sockaddr_storage
* structure.
*/
static struct sockaddr_storage *
struct sockaddr_storage *addr)
{
int err;
} else {
return (NULL);
}
}
struct nwamd_ipaddr_condition_walk_arg {
int prefixlen;
};
static int
{
} else {
}
case NWAM_CONDITION_IS:
if (match)
return (1);
return (0);
case NWAM_CONDITION_IS_NOT:
return (0);
default:
return (0);
}
}
static boolean_t
const char *ip_address_string)
{
return (B_FALSE);
return (B_FALSE);
}
!= NULL) {
} else {
"nwamd_str2sockaddr failed for %s: %s", ip_address,
return (B_FALSE);
}
if (prefixlen_string != NULL)
switch (condition) {
case NWAM_CONDITION_IS:
break;
case NWAM_CONDITION_IS_NOT:
break;
default:
return (B_FALSE);
}
}
continue;
break;
}
}
struct nwamd_wlan_condition_walk_arg {
const char *exp_essid;
const char *exp_bssid;
};
static int
{
NULL)) != DLADM_STATUS_OK) {
"failed: %s", linkname,
return (DLADM_WALK_CONTINUE);
}
if (status != DLADM_STATUS_OK) {
"failed: %s", linkname,
return (DLADM_WALK_CONTINUE);
}
return (DLADM_WALK_TERMINATE);
wa->num_connected++;
/* Is the NIC associated with the expected access point? */
case NWAM_CONDITION_IS:
return (DLADM_WALK_TERMINATE);
break;
case NWAM_CONDITION_IS_NOT:
return (DLADM_WALK_TERMINATE);
break;
case NWAM_CONDITION_CONTAINS:
return (DLADM_WALK_TERMINATE);
break;
return (DLADM_WALK_TERMINATE);
break;
default:
return (DLADM_WALK_TERMINATE);
}
return (DLADM_WALK_CONTINUE);
}
/* Is the NIC associated with the expected access point? */
case NWAM_CONDITION_IS:
return (DLADM_WALK_TERMINATE);
break;
case NWAM_CONDITION_IS_NOT:
return (DLADM_WALK_TERMINATE);
break;
default:
return (DLADM_WALK_TERMINATE);
}
return (DLADM_WALK_CONTINUE);
}
/*
* Neither an ESSID or BSSID match is required - being connected to a
* WLAN is enough.
*/
case NWAM_CONDITION_IS:
return (DLADM_WALK_TERMINATE);
default:
return (DLADM_WALK_TERMINATE);
}
/*NOTREACHED*/
return (DLADM_WALK_CONTINUE);
}
static boolean_t
const char *essid)
{
wa.num_connected = 0;
}
static boolean_t
const char *bssid)
{
wa.num_connected = 0;
}
/*
* This function takes an activation mode and a string representation of a
* condition and evaluates it.
*/
{
char *object_name;
int i, j;
for (i = 0; i < num_conditions; i++) {
condition_strings[i]);
return (B_FALSE);
}
for (j = 0; j < (sizeof (condition_map) /
sizeof (struct nwamd_condition_map)); j++) {
}
ret) {
return (B_TRUE);
}
!ret) {
return (B_FALSE);
}
}
return (B_TRUE);
return (B_TRUE);
return (B_FALSE);
}
/*
* In rating activation conditions, we take the best-rated CONDITIONAL_ANY
* condition, or sum all the CONDITIONAL_ALL condition ratings. This allows
* us to compare between location activation conditions to pick the best.
*/
{
char *object_name;
int i;
for (i = 0; i < num_conditions; i++) {
object_name = NULL;
!= NWAM_SUCCESS) {
"condition");
return (0);
}
if (rating > total_rating)
} else if (activation_mode ==
total_rating += rating;
}
}
return (total_rating);
}
/*
* Different from nwamd_triggered_check_all_conditions() in that this
* function enqueues a timed check event.
*/
void
{
0, NULL);
if (check_event != NULL) {
/* Add another timed event to recheck conditions */
}
}
/*
* Does not enqueue another check event.
*/
void
{
}
void
{
0, NULL);
if (check_event != NULL)
}
void
{
NWAM_OBJECT_TYPE_UNKNOWN, 0, NULL);
if (check_event != NULL)
}
}