setup.c revision 5c0b7edee9bd9fad49038456b16972ff28fa4187
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (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 2004 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* file: setup.c
*
* This file contains the routines used to create data
* structures, such as Mobile Nodes, Visitor Entries,
* interfaces and security association.
*/
#include <stdio.h>
#include <syslog.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <limits.h>
#include <errno.h>
#include "agent.h"
#include "mip.h"
#include "setup.h"
#include "agentKernelIntfce.h"
/* ----------------- Common to all mobility agents ------------------- */
extern struct hash_table maAdvConfigHash;
/*
* This table stores all of the Security Associations
*/
extern HashTable mipSecAssocHash;
/*
* This table has one entry for each known Mobility Agent
*/
extern HashTable mipAgentHash;
/*
* This table has one entry for each pool defined in the config file
*/
extern HashTable mipPoolHash;
/*
* This table has one entry for each active tunnel number
*/
extern HashTable mipTunlHash;
/* Home Agent specific data structures. */
extern struct hash_table haMobileNodeHash;
/* Other external declarations */
extern int logVerbosity;
/* MipTunlEntryLookup function defined in agentKernelIntfce.c */
/*
* Given that we are acting as an SNMP Sub-Agent, we will need
* to register our address with the SNMP Master Agent. The
* subagent_addr variable is used for this purpose.
*/
ipaddr_t subagent_addr = 0;
#define VNI "vni"
#define VNISTRLEN 3
/*
* Function: CreateMobileNodeEntry
*
* Arguments: mnEntryType - Whether the entry is dynamic or
* static
* homeAddr - The Mobile Node's Home Address
* mnNAI - The Mobile Node's NAI
* mnNAILen - The length of the NAI
* homeAgentAddr - The Mobile Node's Home Agent
* SPI - The Mobile Node's SPI
* state - A RADIUS thing. not needed for now
* poolIdentifier - The Pool Identifier
*
* Description: This function is used to create a Mobile Node
* entry, which is added to the hash table. The
* SPI provided MUST have been previously defined
* as is the pool (if a non-zero value was provided
* as the pool id).
*
* If a Home Address was provided, we will add the
* node to the hash table based on the Home Address
* otherwise the NAI will be used.
*
* The Mobile Node entry will be locked upon return.
* The caller is responsible for unlocking the
* node when it is finished with it.
*
* Returns: upon successful return, this function will
* return the Mobile Node Entry pointer, otherwise
* NULL.
*
*/
/* ARGSUSED */
{
#ifdef RADIUS_ENABLED
#endif /* RADIUS_ENABLED */
return (NULL);
}
/*
* First, let's make sure that we already have
* this SPI defined.
*/
return (NULL);
}
/*
* Let's see if we already have this pool.
*/
if (poolIdentifier) {
return (NULL);
}
}
/*
* If an NAI is provided, make sure that it is legal
*/
if (mnNAI) {
if (mnNaiLen > MAX_NAI_LENGTH) {
return (NULL);
}
}
if (!entry) {
return (NULL);
}
/* Now add our values */
if (homeAgentAddr == 0) {
} else {
}
entry->haMnBindingCnt = 0;
#ifdef RADIUS_ENABLED
#endif /* RADIUS_ENABLED */
if (mnNAI) {
}
return (NULL);
}
if (poolIdentifier && mnNaiLen) {
/* Add the entry to the NAI hash */
entry, LOCK_WRITE)) {
"hash table");
return (NULL);
}
} else {
entry, LOCK_WRITE)) {
"hash table");
return (NULL);
}
}
return (entry);
}
/*
* Function: CreateMobilityAgentEntry
*
* Arguments: maEntryType - Whether the entry is dynamic or
* static
* address - The Mobility Agent's IP Address
* SPI - The Mobility Agent's SPI
* lifetime - The lifetime of the entry (for
* dynamic entries only)
*
* Description: This function will create the Mobility Agent
* Entry, and will add it to the Hash table.
* The SPI provided MUST have been previously
* defined, otherwise an error will occur.
*
* If the node is created as a dynamic entry,
* we will setup the entry's expiration time.
*
* The entry will be locked upon return.
* The caller is responsible for unlocking the
* node when it is finished with it.
*
* Returns: upon successful return, this function will
* return the Mobility Agent Entry pointer,
* otherwise NULL.
*/
{
/*
* First, let's make sure that we do not already have
* this SPI defined.
*/
return (NULL);
}
if (!entry) {
return (NULL);
}
/* Now add our values */
if (isDynamic) {
/*
* Setup when the key expires...
*/
} else {
}
return (NULL);
}
LOCK_WRITE)) {
"table");
return (NULL);
}
return (entry);
}
/*
* Function: CreateSecAssocEntry
*
* Arguments: SPI - Security Parameter Index
* SaType - Whether the entry is dynamic or
* static
* ReplayProtection - The replay protection
* type
* AlgorithmType - The authentication algorithm
* type
* AlgorithmMode - The mode used for the
* algorithm.
* keyLength - The length of the key
* key - A pointer to the key
* lifetime - The lifetime of the entry (for
* dynamic entries only)
*
* Description: This function will create a Security Association
* entry, and will add it to the hash table. If the
* SPI already exists, we will return an error.
*
* If the node is created as a dynamic entry,
* we will setup the entry's expiration time.
*
* Also, if the SA is dynamic and a duplicate SA
* is received, it is updated, and no error is
* returned. (if the SA is *not* dynamic, an
* error *is* returned.)
*
* The entry will be locked upon return.
* The caller is responsible for unlocking the
* node when it is finished with it.
*
* Returns: upon successful return, this function will
* return the Security Association Entry
* pointer, otherwise NULL.
*/
int lifetime)
{
/*
* First, let's make sure that we do not already have
* this SPI defined.
*/
SPI);
return (NULL);
} else {
}
}
/* Entry is set if dynamic and already found */
if (!entry) {
sizeof (MipSecAssocEntry));
if (!entry) {
"FATAL: Unable to allocate Sec Assoc Entry");
return (NULL);
}
}
if (isDynamic) {
/*
* Setup when the key expires...
*/
} else {
}
/* If it is already in table, we already own it with the RWLOCK set */
if (!alreadyInserted) {
return (NULL);
}
entry, LOCK_WRITE)) {
"Assoc. entry to hash tabl");
return (NULL);
}
}
return (entry);
}
/*
* Function: CreateInterfaceEntry
*
* Arguments: dev - A pointer to the device name
* regLifetime - The maximum registration lifetime that
* are willing to accept.
* advertiseOnBcast - Whether we will advertise on the
* broadcast address.
* minInterval - The minimum interval between adv.
* maxInterval - The maximum interval between adv.
* advLifetime - The maximum advertisement lifetime
* lifetime that we will advertise on this
* interface.
* advSeqNum - The sequence number that we will
* initially advertise.
* servicesFlags - The flags that we will advertise
* on the interface.
* prefixFlags - determines whether we will advertise
* the prefix length extension.
* reverseTunnelAllowed - are we going to allow MN's to
* request the reverse tunnel, and thereby send
* FA_REVERSE_TUNNEL_UNAVAILABLE errors to MN's
* requesting a reverse tunnel? Note, this is set to
* RT_NONE, RT_FA, RT_HA, or RT_BOTH depending on which
* of our agents is allowing the reverse tunnel.
* reverseTunnelRequired - are we going to require MN's to
* request the reverse tunnel, and thereby send
* FA_REVERSE_TUNNEL_REQUIRED errors to MN's not
* requesting a reverse tunnel? Note, this is set to
* RT_NONE, RT_FA, RT_HA, or RT_BOTH depending on which
* of our agents is requiring the reverse tunnel.
* advInterval - Advertisement interval for this interface
*
* Description: This function will create an interface entry,
* and will add it to the hash table. We will
* directly retrieve the interface's IP address and
* MAC address.
*
* Returns: int, 0 if successful.
*
* Comment: This function takes too many arguments. If this function
* ever needs a major change, passing a structure with all
* arguments should be considered.
*
*/
int
{
char *cp;
/* If a virtual network interface is specified, warn the user */
" virtual interface that does not transmit"
" or receive packets. See vni(7D)", dev);
}
}
/* Let's check for dynamic interface entry */
sizeof (MaAdvConfigEntry));
"AdvConfigEntry");
return (-2);
}
} else {
int len;
/*
* Since devicename contains '*', it must be an entry
* for dynamic interface.For dynamic interface entry
* in the config file, we do not create entry in the
* MaAdvConfigEntry[], rather we keep a linked list
* of dynamic interface types. For each type of dynamic
* interface entry, the attributes will be common and
* saved in DynamicIfaceTypeEntry data structure.
* When mipagent detects one new interface that matches
* with the same type and that is not an exisisting one
* that went through down-up cycle, then it creates a new
* entry and attaches to the MaAdvConfigEntry list
*/
"Invalid dynamic interface %s in mipagent.conf",
dev);
return (-1);
}
/* Replace '*' with null character */
mipverbose(("CreateInterfaceEntry: dynamic device %s\n",
dev));
if (dynamicIfaceHead == NULL) {
sizeof (DynamicIfaceTypeEntry));
} else {
/* search if this type exists already */
== 0) {
mipverbose(("CreateInterfaceEntry:"
" Dynamic Entry already exists"
" %s\n", dev));
return (0);
}
}
sizeof (DynamicIfaceTypeEntry));
/* Link to the dynamicEntry list */
}
}
/* Fill in the structure with the parameter values */
/* Set the global variable DynamicInterface */
return (0);
} /* else dynamic entry */
/* Now add our interface values */
/*
* Simplify the configuration effort, read IP address, netmask
* and hardware address directly from the interface.
*/
return (-1);
}
/*
* Save the first address usable for registering with the
* SNMP master.
*/
if (subagent_addr != 0)
/*
* Don't attempt to get the hardware address if it's a point-to-point
* interface.
*/
mipverbose(("Unable to get interface address "
return (-1);
}
}
/*
* TODO: Under Solaris, pkts for LINK_BCAST_ADDR seem to
* be sent on all of a host's interfaces. Don't know if this
* can be controlled using some options similar to
* IP_MULTICAST_IF.
*/
if (advertiseOnBcast == 1) {
} else {
}
if (advLimitUnsolicited == _B_FALSE)
else
/* Set maNextAdvTime in getAndDispatchNetwork */
/* The follwoing is always set false in this routine */
return (NULL);
}
/*
* Ok, this is just a temp hack, but we need to save the
* local address of the interface. Otherwise we will need to
* configure the home agent for each Mobile Node, which is
* just too much config for everybody. Given that we really
* only work with one interface, this is not a big deal, but
* this DOES need to be cleaned up.
*/
/*
* We do not request that the node be locked in this case since
* we do not need the pointer to be returned. We are just calling
* and ensuring that a pointer was in fact returned.
*/
LOCK_NONE)) {
return (-1);
}
return (0);
}
/*
* Function: CreateTunlEntry
*
* Arguments: tnum - Tunnel number
* target - target address
* tunsrc - Tunnel source endpoint address
* muxfd - file desc of the stream that is
* associated with the tunnel.
*
* Description: This function will create a Tunnel
* entry, and will add it to the hash table.
*
* Returns: upon successful return, this function will
* return the Tunnel Entry pointer, otherwise NULL.
*/
{
/*
* First, let's make sure that we do not already have
* this target defined.
*/
return (NULL);
}
if (!entry) {
return (NULL);
}
return (NULL);
}
return (NULL);
}
return (entry);
}