inetcfg.c revision d62bc4badc1c1f1549c961cfb8b420e650e1272b
/*
* 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.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <fcntl.h>
#include <unistd.h>
#include <stropts.h>
#include <libintl.h>
#include <libdlpi.h>
#include <inetcfg.h>
#define ICFG_TUNNEL_PROTOCOL(protocol) \
#define ICFG_SOCKADDR_LEN(protocol) \
(socklen_t)sizeof (struct sockaddr_in) : \
(socklen_t)sizeof (struct sockaddr_in6)
#define ICFG_LOGICAL_SEP ':'
/*
* Maximum amount of time (in milliseconds) to wait for Duplicate Address
* Detection to complete in the kernel.
*/
#define DAD_WAIT_TIME 5000
/*
* Note: must be kept in sync with error codes in <inetcfg.h>
*/
/* 0 ICFG_SUCCESS */ "Success",
/* 1 ICFG_FAILURE */ "Failure",
/* 2 ICFG_NOT_TUNNEL */ "Tunnel operation attempted on non-tunnel",
/* 3 ICFG_NOT_SET */ "Could not return non-existent value",
/* 4 ICFG_BAD_ADDR */ "Invalid Address",
/* 5 ICFG_BAD_PROT */ "Wrong protocol family for operation",
/* 6 ICFG_DAD_FAILED */ "Duplicate address detection failure",
/* 7 ICFG_DAD_FOUND */ "Duplicate address detected"
};
/*
* Convert a prefix length to a netmask. Note that the mask array
* should zero'ed by the caller.
*
* Returns: ICFG_SUCCESS or ICFG_FAILURE.
*/
static int
{
return (ICFG_FAILURE);
}
while (prefixlen > 0) {
if (prefixlen >= 8) {
*mask++ = 0xFF;
prefixlen -= 8;
continue;
}
prefixlen--;
}
return (ICFG_SUCCESS);
}
/*
* Copies an an IPv4 or IPv6 address from a sockaddr_storage
* structure into the appropriate sockaddr structure for the
* address family (sockaddr_in for AF_INET or sockaddr_in6 for
* AF_INET6) and verifies that the structure size is large enough
* for the copy.
*
* Returns: ICFG_SUCCESS or ICFG_FAILURE.
*/
static int
{
return (ICFG_FAILURE);
}
return (ICFG_SUCCESS);
}
/*
* Copies an an IPv4 or IPv6 address frrom its sockaddr structure
* into a sockaddr_storage structure and does a simple size of
* structure verification.
*
* Returns: ICFG_SUCCESS or ICFG_FAILURE.
*/
static int
{
return (ICFG_FAILURE);
}
return (ICFG_SUCCESS);
}
/*
* Ensures that the tunnel parameter data for the tunnel associated with
* the handle is cached. If the 'force_update' argument is TRUE, then the
* cache should be updated.
*
* Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL or ICFG_FAILURE.
*/
static int
{
return (ICFG_SUCCESS);
}
return (ICFG_NOT_TUNNEL);
}
return (ICFG_FAILURE);
}
sizeof (params->ifta_lifr_name));
return (ICFG_NOT_TUNNEL);
}
return (ICFG_FAILURE);
}
/*
* We assert that the iftun_req version is the right one
* and that the lower and upper protocols are set to either
* IPv4 or IPv6. Otherwise, some of our APIs are buggy.
*/
}
return (ICFG_SUCCESS);
}
/*
* Sets a tunnel destination or source address (depending upon 'type') on
* a tunnel interface.
*
* Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL or ICFG_FAILURE.
*/
static int
{
struct sockaddr_storage laddr;
int ret;
return (ret);
}
} else {
}
if (ret != ICFG_SUCCESS) {
return (ret);
}
} else {
}
sizeof (params->ifta_lifr_name));
return (ICFG_FAILURE);
}
return (ICFG_SUCCESS);
}
/*
* Return the appropriate error message for a given ICFG error.
*/
const char *
icfg_errmsg(int errcode)
{
}
/*
* Opens the an interface as defined by the interface argument and returns
* a handle to the interface via the 'handle' argument. The caller is
* responsible for freeing resources allocated by this API by calling the
* icfg_close() API.
*
* Returns: ICFG_SUCCESS or ICFG_FAILURE.
*/
int
{
int sock;
int syserr;
/*
* Make sure that a valid protocol family was specified.
*/
return (ICFG_FAILURE);
}
return (ICFG_FAILURE);
}
return (ICFG_FAILURE);
}
*handle = loc_handle;
return (ICFG_SUCCESS);
}
/*
* Closes the interface opened by icfg_open() and releases all resources
* associated with the handle.
*/
void
{
}
}
/*
* Refreshes the tunnel parameter data cache associated with the interface
* represented by the handle. Tunnel parameter data is cached by the
* libinetcfg library by the first call to to any of the tunnel related APIs.
* Since there is no synchronization between consumers of the library and
* non-users of this library, the cache may contain stale data. Users may
* wish to use this API to refresh the cache before subsequent calls to the
* other tunnel related APIs.
*
* Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL or ICFG_FAILURE.
*/
int
{
}
/*
* Sets the destination address for the tunnel interface represented
* by 'handle'.
*
* The 'addr' argument points to either a sockaddr_in structure
* (for IPv4) or a sockaddr_in6 structure (for IPv6) that holds
* the IP address. The 'addrlen' argument gives the length of the
* 'addr' structure.
*
* This API will always result in an update of the tunnel parameter
* data cache.
*
* Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL or ICFG_FAILURE.
*/
int
{
}
/*
* Sets the source address for the tunnel interface represented
* by 'handle'.
*
* The 'addr' argument points to either a sockaddr_in structure
* (for IPv4) or a sockaddr_in6 structure (for IPv6) that holds
* the IP address. The 'addrlen' argument gives the length of the
* 'addr' structure.
*
* This API will always result in an update of the tunnel parameter
* data cache.
*
* Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL or ICFG_FAILURE.
*/
int
{
}
/*
* Sets the hop limit for the tunnel interface represented by
* the handle to the value contained in the 'limit' argument.
*
* This API will always result in an update of the tunnel parameter data cache.
*
* Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL or ICFG_FAILURE.
*/
int
{
int ret;
return (ret);
}
sizeof (params->ifta_lifr_name));
return (ICFG_FAILURE);
}
return (ICFG_SUCCESS);
}
/*
* Sets the encapsulation limit for the tunnel interface represented by
* the handle to the value contained in the 'limit' argument. If the
* value of the limit is negative, then the encapsulation limit is disabled.
*
* This API will always result in an update of the tunnel parameter data cache.
*
* Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL or ICFG_FAILURE.
*/
int
{
int ret;
return (ret);
}
sizeof (params->ifta_lifr_name));
return (ICFG_FAILURE);
}
return (ICFG_SUCCESS);
}
/*
* Returns the source address for the tunnel interface represented
* by 'handle'.
*
* The 'addr' argument is a result parameter that is filled in with
* the requested address. The format of the 'addr' parameter is
* determined by the address family of the interface.
*
* The 'addrlen' argument is a value-result parameter. Initially,
* it contains the amount of space pointed to by 'addr'; on return
* it contains the length in bytes of the address returned.
*
* Note that if 'addrlen' is not large enough for the returned
* address value, then ICFG_FAILURE will be returned and errno
* will be set to ENOSPC.
*
* This API will retrieve the tunnel source value from the tunnel
* parameter data cache and will only update the cache if no data has
* yet been cached for this tunnel.
*
* Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL, ICFG_NOT_SET or
* ICFG_FAILURE.
*/
int
{
int ret;
return (ret);
}
return (ICFG_NOT_SET);
}
} else {
}
¶ms->ifta_saddr));
}
/*
* Returns the destination address for the tunnel interface
* represented by 'handle'.
*
* The 'addr' argument is a result parameter that is filled in
* with the requested address. The format of the 'addr' parameter
* is determined by the address family of the interface.
*
* The 'addrlen' argument is a value-result parameter. Initially, it
* contains the amount of space pointed to by 'addr'; on return it
* contains the length in bytes of the address returned.
*
* Note that if 'addrlen' is not large enough for the returned address
* value, then ICFG_FAILURE will be returned and errno will be set
* to ENOSPC.
*
* This API will retrieve the tunnel destination value from the tunnel
* parameter data cache and will only update the cache if no data has yet
* been cached for this tunnel.
*
* Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL, ICFG_NOT_SET or
* ICFG_FAILURE.
*/
int
{
int ret;
return (ret);
}
return (ICFG_NOT_SET);
}
}
¶ms->ifta_daddr));
}
/*
* Returns the tunnel hop limit (if any). The value of the limit
* will be copied into the buffer supplied by the 'limit' argument.
*
* This API will retrieve the hoplimit value from the tunnel parameter data
* cache and will only update the cache if no data has yet been cached for
* this tunnel.
*
* Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL, ICFG_NOT_SET or
* ICFG_FAILURE.
*/
int
{
int ret;
return (ret);
}
return (ICFG_NOT_SET);
}
return (ICFG_SUCCESS);
}
/*
* Returns the tunnel encapsulation limit (if any). The value of the limit
* will be copied into the buffer supplied by the 'limit' argument.
*
* This API will retrieve the encapsulation limit value from the tunnel
* parameter data cache and will only update the cache if no data has yet
* been cached for this tunnel.
*
* Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL, ICFG_NOT_SET or
* ICFG_FAILURE.
*/
int
{
int ret;
return (ret);
}
return (ICFG_NOT_SET);
}
return (ICFG_SUCCESS);
}
/*
* Returns the protocol family (AF_INET or AF_INET6) of the protocol
* actually being used to tunnel the data. The value of the protocol family
* will be copied into the buffer supplied by the 'protocol' argument.
*
* This API will retrieve the protocol value from the tunnel parameter data
* cache and will only update the cache if no data has yet been cached for
* this tunnel.
*
* Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL or ICFG_FAILURE.
*/
int
{
int ret;
return (ret);
}
return (ICFG_SUCCESS);
}
/*
* Returns the protocol family (AF_INET or AF_INET6) of the protocol
* actually being tunneled. The value of the protocol family will be copied
* into the buffer supplied by the 'protocol' argument.
*
* This API will retrieve the protocolvalue from the tunnel parameter data
* cache and will only update the cache if no data has yet been cached for
* this tunnel.
*
* Returns: ICFG_SUCCESS, ICFG_NOT_TUNNEL or ICFG_FAILURE.
*/
int
{
int ret;
return (ret);
}
return (ICFG_SUCCESS);
}
/*
* Any time that flags are changed on an interface where either the new or the
* existing flags have IFF_UP set, we'll get at least one RTM_IFINFO message to
* announce the flag status. Typically, there are two such messages: one
* saying that the interface is going down, and another saying that it's coming
* back up.
*
* We wait here for that second message, which can take one of two forms:
* either IFF_UP or IFF_DUPLICATE. If something's amiss with the kernel,
* though, we don't wait forever. (Note that IFF_DUPLICATE is a high-order
* bit, and we can't see it in the routing socket messages.)
*/
static int
{
union {
char buf[1024];
} msg;
int index;
int retv;
return (retv);
for (;;) {
if (now >= DAD_WAIT_TIME)
break;
break;
break;
continue;
/* Note that ifm_index is just 16 bits */
return (ICFG_SUCCESS);
return (retv);
if (flags & IFF_DUPLICATE)
return (ICFG_DAD_FOUND);
}
return (ICFG_DAD_FAILED);
}
/*
* Sets the flags for the interface represented by the 'handle'
* argument to the value contained in the 'flags' argument.
*
* If the new flags value will transition the interface from "down" to "up,"
* then duplicate address detection is performed by the kernel. This routine
* waits to get the outcome of that test.
*
* Returns: ICFG_SUCCESS, ICFG_DAD_FOUND, ICFG_DAD_FAILED or ICFG_FAILURE.
*/
int
{
int ret;
int rtsock;
return (ret);
return (ICFG_SUCCESS);
/*
* Any time flags are changed on an interface that has IFF_UP set,
* you'll get a routing socket message. We care about the status,
* though, only when the new flags are marked "up."
*/
if (rtsock != -1)
return (ICFG_FAILURE);
}
if (rtsock == -1) {
return (ICFG_SUCCESS);
} else {
return (ret);
}
}
/*
* Sets the metric value for the interface represented by the
* 'handle' argument to the value contained in the 'metric'
* argument.
*
* Returns: ICFG_SUCCESS or ICFG_FAILURE.
*/
int
{
return (ICFG_FAILURE);
}
return (ICFG_SUCCESS);
}
/*
* Sets the mtu value for the interface represented by the
* 'handle' argument to the value contained in the 'mtu'
* argument.
*
* Returns: ICFG_SUCCESS or ICFG_FAILURE.
*/
int
{
return (ICFG_FAILURE);
}
return (ICFG_SUCCESS);
}
/*
* Sets the index value for the interface represented by the
* 'handle' argument to the value contained in the 'index'
* argument.
*
* Returns: ICFG_SUCCESS or ICFG_FAILURE.
*/
int
{
return (ICFG_FAILURE);
}
return (ICFG_SUCCESS);
}
/*
* Sets the netmask address for the interface represented by
* 'handle'.
*
* The handle must represent an IPv4 interface.
*
* The address will be set to the value pointed to by 'addr'.
*
* Returns: ICFG_SUCCESS, ICFG_BAD_PROT or ICFG_FAILURE.
*/
int
{
int ret;
return (ICFG_BAD_PROT);
}
return (ret);
}
return (ICFG_FAILURE);
}
return (ICFG_SUCCESS);
}
/*
* Sets the broadcast address for the interface represented by
* 'handle'.
*
* The handle must represent an IPv4 interface.
*
* The address will be set to the value pointed to by 'addr'.
*
* Returns: ICFG_SUCCESS, ICFG_BAD_PROT or ICFG_FAILURE.
*/
int
{
int ret;
return (ICFG_BAD_PROT);
}
return (ret);
}
return (ICFG_FAILURE);
}
return (ICFG_SUCCESS);
}
/*
* Sets the prefixlen value for the interface represented by the handle
* argument to the value contained in the 'prefixlen' argument. The
* prefixlen is actually stored internally as a netmask value and the API
* will convert the value contained in 'prefixlen' into the correct netmask
* value according to the protocol family of the interface.
*
* Returns: ICFG_SUCCESS or ICFG_FAILURE.
*/
int
{
struct sockaddr_in6 *sin6;
int ret;
return (ret);
}
} else {
struct sockaddr_in *sin;
int ret;
return (ret);
}
}
return (ICFG_FAILURE);
}
return (ICFG_SUCCESS);
}
/*
* Sets the address for the interface represented by 'handle'.
*
* The 'addr' argument points to either a sockaddr_in structure
* (for IPv4) or a sockaddr_in6 structure (for IPv6) that holds
* the IP address. The 'addrlen' argument gives the length of the
* 'addr' structure.
*
* If the interface is an IPv6 interface and the interface is
* already in the "up" state, then duplicate address detection
* is performed before the address is set and is set only if no
* duplicate address is detected.
*
* Returns: ICFG_SUCCESS, ICFG_FAILURE, ICFG_DAD_FOUND, ICFG_DAD_FAILED
* or ICFG_FAILURE.
*/
int
{
int ret;
int rtsock;
return (ret);
}
/*
* Need to do check on duplicate address detection results if the
* interface is up.
*/
return (ret);
}
if (rtsock != -1)
return (ICFG_FAILURE);
}
if (rtsock == -1) {
return (ICFG_SUCCESS);
} else {
return (ret);
}
}
/*
* Sets the token for the interface represented by 'handle'.
*
* The handle must represent an IPv6 interface.
*
* The token will be set to the value contained in 'addr' and
* its associated prefixlen will be set to 'prefixlen'.
*
* Returns: ICFG_SUCCESS, ICFG_BAD_PROT or ICFG_FAILURE.
*/
int
int prefixlen)
{
int ret;
return (ICFG_BAD_PROT);
}
return (ret);
}
return (ICFG_FAILURE);
}
return (ICFG_SUCCESS);
}
/*
* Sets the subnet address for the interface represented by 'handle'.
*
* The 'addr' argument points to either a sockaddr_in structure
* (for IPv4) or a sockaddr_in6 structure (for IPv6) that holds
* the IP address. The 'addrlen' argument gives the length of the
* 'addr' structure.
*
* The prefixlen of the subnet address will be set to 'prefixlen'.
*
* Returns: ICFG_SUCCESS or ICFG_FAILURE.
*/
int
{
int ret;
return (ret);
}
return (ICFG_FAILURE);
}
return (ICFG_SUCCESS);
}
/*
* Sets the destination address for the interface represented by
* 'handle'.
*
* The 'addr' argument points to either a sockaddr_in structure
* (for IPv4) or a sockaddr_in6 structure (for IPv6) that holds
* the IP address. The 'addrlen' argument gives the length of the
* 'addr' structure.
*
* Returns: ICFG_SUCCESS or ICFG_FAILURE.
*/
int
{
int ret;
return (ret);
}
return (ICFG_FAILURE);
}
return (ICFG_SUCCESS);
}
/*
* Returns the address and prefixlen of the interface represented
* by 'handle'.
*
* The 'addr' argument is a result parameter that is filled in with
* the requested address. The format of the 'addr' parameter is
* determined by the address family of the interface.
*
* The 'addrlen' argument is a value-result parameter. Initially, it
* contains the amount of space pointed to by 'addr'; on return it
* contains the length in bytes of the address returned.
*
* Note that if 'addrlen' is not large enough for the returned address
* value, then ICFG_FAILURE will be returned and errno will be set to ENOSPC.
*
* If the 'force' argument is set to B_TRUE, then non-critical errors in
* obtaining the address will be ignored and the address will be set to
* all 0's. Non-critical errors consist of EADDRNOTAVAIL, EAFNOSUPPORT,
* and ENXIO.
*
* Returns: ICFG_SUCCESS or ICFG_FAILURE.
*/
int
{
int ret;
} else {
return (ICFG_FAILURE);
}
}
return (ret);
}
return (ICFG_SUCCESS);
}
/*
* Returns the token address and the token prefixlen of the
* interface represented by 'handle'.
*
* The 'addr' argument is a result parameter that is filled in
* with the requested address.
*
* The 'prefixlen' argument is a result paramter that is filled
* in with the token prefixlen.
*
* If the 'force' argument is set to B_TRUE, then non-critical errors in
* obtaining the token address will be ignored and the address will be set
* to all 0's. Non-critical errors consist of EADDRNOTAVAIL and EINVAL.
*
* Returns: ICFG_SUCCESS, ICFG_BAD_PROT or ICFG_FAILURE.
*/
int
{
return (ICFG_BAD_PROT);
}
} else {
return (ICFG_FAILURE);
}
}
}
/*
* Returns the subnet address and the subnet prefixlen of the interface
* represented by 'handle'.
*
* The 'addr' argument is a result parameter that is filled in with
* the requested address. The format of the 'addr' parameter is
* determined by the address family of the interface.
*
* The 'addrlen' argument is a value-result parameter. Initially, it
* contains the amount of space pointed to by 'addr'; on return it
* contains the length in bytes of the address returned.
*
* Note that if 'addrlen' is not large enough for the returned address
* value, then ICFG_FAILURE will be returned and errno will be set to ENOSPC.
*
* If the 'force' argument is set to B_TRUE, then non-critical errors in
* obtaining the address will be ignored and the address will be set to all
* 0's. Non-critical errors consist of EADDRNOTAVAIL, EAFNOSUPPORT,and ENXIO.
*
* Returns: ICFG_SUCCESS or ICFG_FAILURE.
*/
int
{
int ret;
} else {
return (ICFG_FAILURE);
}
}
return (ret);
}
return (ICFG_SUCCESS);
}
/*
* Returns the netmask address of the interface represented by 'handle'.
*
* The handle must represent an IPv4 interface.
*
* The 'addr' argument is a result parameter that is filled in with
* the requested address.
*
* If no netmask address has been set for the interface, an address of
* all 0's will be returned.
*
* Returns: ICFG_SUCCESS, ICFG_BAD_PROT or ICFG_FAILURE.
*/
int
{
return (ICFG_BAD_PROT);
}
if (errno != EADDRNOTAVAIL) {
return (ICFG_FAILURE);
}
}
}
/*
* Returns the broadcast address of the interface represented by 'handle'.
*
* The handle must represent an IPv4 interface.
*
* The 'addr' argument is a result parameter that is filled in with
* the requested address.
*
* If no broadcast address has been set for the interface, an address
* of all 0's will be returned.
*
* Returns: ICFG_SUCCESS, ICFG_BAD_PROT or ICFG_FAILURE.
*/
int
{
return (ICFG_BAD_PROT);
}
if (errno != EADDRNOTAVAIL) {
return (ICFG_FAILURE);
}
}
}
/*
* Returns the destination address of the interface represented
* by 'handle'.
*
* The 'addr' argument is a result parameter that is filled in with
* the requested address. The format of the 'addr' parameter is
* determined by the address family of the interface.
*
* The 'addrlen' argument is a value-result parameter. Initially, it
* contains the amount of space pointed to by 'addr'; on return it
* contains the length in bytes of the address returned.
*
* Note that if 'addrlen' is not large enough for the returned address
* value, then ICFG_FAILURE will be returned and errno will be set to
* ENOSPC.
*
* If no destination address has been set for the interface, an address
* of all 0's will be returned.
*
* Returns: ICFG_SUCCESS or ICFG_FAILURE.
*/
int
{
if (errno != EADDRNOTAVAIL) {
return (ICFG_FAILURE);
}
/* No destination address set yet */
sizeof (lifr.lifr_dstaddr));
}
}
/*
* Returns the groupname, if any, of the interface represented by the handle
* argument into the buffer pointed to by the 'groupname' argument. The size
* of the groupname buffer is expected to be of 'len' bytes in length and
* should be large enough to receive the groupname of the interface
* (i.e., LIFNAMSIZ).
*
* Returns: ICFG_SUCCESS, ICFG_NOT_SET or ICFG_FAILURE.
*/
int
{
return (ICFG_FAILURE);
}
} else {
return (ICFG_NOT_SET);
}
return (ICFG_SUCCESS);
}
/*
* Returns the link info of the interface represented by the handle
* argument into the buffer pointed to by the 'info' argument.
*
* Returns: ICFG_SUCCESS or ICFG_FAILURE.
*/
int
{
char *cp;
*cp = '\0';
}
return (ICFG_FAILURE);
}
return (ICFG_SUCCESS);
}
/*
* Returns the flags value of the interface represented by the handle
* argument into the buffer pointed to by the 'flags' argument.
*
* Returns: ICFG_SUCCESS or ICFG_FAILURE.
*/
int
{
return (ICFG_FAILURE);
}
return (ICFG_SUCCESS);
}
/*
* Returns the metric value of the interface represented by the handle
* argument into the buffer pointed to by the 'metric' argument.
*
* Returns: ICFG_SUCCESS or ICFG_FAILURE.
*/
int
{
return (ICFG_FAILURE);
}
return (ICFG_SUCCESS);
}
/*
* Returns the mtu value of the interface represented by the handle
* argument into the buffer pointed to by the 'mtu' argument.
*
* Returns: ICFG_SUCCESS or ICFG_FAILURE.
*/
int
{
return (ICFG_FAILURE);
}
return (ICFG_SUCCESS);
}
/*
* Returns the index value of the interface represented by the handle
* argument into the buffer pointed to by the 'index' argument.
*
* Returns: ICFG_SUCCESS or ICFG_FAILURE.
*/
int
{
return (ICFG_FAILURE);
}
return (ICFG_SUCCESS);
}
/*
* Walks a list of interfaces and for each interface found, the
* caller-supplied function 'callback()' is invoked. The iteration will be
* interrupted if the caller-supplied function does not return ICFG_SUCCESS.
*
* The 'proto' argument is used by the caller to define which interfaces are
* to be walked by the API. The possible values for 'proto' are AF_INET,
* AF_INET6, and AF_UNSPEC.
*
* The 'arg' argument is a pointer to caller-specific data.
*
* Returns: ICFG_SUCCESS, ICFG_FAILURE or error code returned by callback().
*/
int
{
int len;
int i;
int ret;
if (ret != ICFG_SUCCESS) {
return (ret);
}
for (i = 0; i < len; i++) {
break;
}
}
return (ret);
}
/*
* Returns a list of currently plumbed interfaces. The list of interfaces is
* returned as an array of icfg_if_t structures. The number of interfaces in
* the array will be returned via the 'numif' argument. Since the array of
* interfaces is allocated by this API, the caller is responsible for freeing
* the memory associated with this array by calling icfg_free_list().
*
* The 'proto' argument is used by the caller to define which interfaces are
* to be listed by the API. The possible values for proto are AF_INET,
* AF_INET6, and AF_UNSPEC.
*
* Returns: ICFG_SUCCESS or ICFG_FAILURE.
*/
static int
int sock;
char *buf;
unsigned bufsize;
int num;
int lifc_flags = LIFC_NOXMIT;
int syserr;
int i;
/*
* Validate the protocol family.
*/
return (ICFG_FAILURE);
}
lifc_family = proto;
/*
* Open a socket. Note that the AF_INET domain seems to
* support both IPv4 and IPv6.
*/
return (ICFG_FAILURE);
}
/*
* Get the number of interfaces and allocate a buffer
* large enough to allow the interfaces to be enumerated.
*/
return (ICFG_FAILURE);
}
return (ICFG_FAILURE);
}
/*
* Obtain a list of the interfaces.
*/
return (ICFG_FAILURE);
}
return (ICFG_FAILURE);
}
} else {
}
}
return (ICFG_SUCCESS);
}
typedef struct linklist {
char ll_name[DLPI_LINKNAME_MAX];
} linklist_t;
typedef struct linkwalk {
int lw_num;
int lw_err;
} linkwalk_t;
static boolean_t
{
return (B_TRUE);
}
else
return (B_FALSE);
}
/*
* Returns a list of data links that can be plumbed. The list of interfaces is
* returned as an array of icfg_if_t structures. The number of interfaces in
* the array will be returned via the 'numif' argument.
*
* Returns: ICFG_SUCCESS or ICFG_FAILURE.
*/
static int
int save_errno = 0;
int ret = ICFG_FAILURE;
goto done;
}
goto done;
list++;
}
ret = ICFG_SUCCESS;
done:
save_errno = errno;
}
errno = save_errno;
return (ret);
}
/*
* Returns a list of network interfaces. The list of
* interfaces is returned as an array of icfg_if_t structures.
* The number of interfaces in the array will be returned via
* the 'numif' argument. Since the array of interfaces is
* allocated by this API, the caller is responsible for freeing
* the memory associated with this array by calling
* icfg_free_list().
*
* The 'proto' argument is used by the caller to define which
* interfaces are to be listed by the API. The possible values
* for 'proto' are AF_INET, AF_INET6, and AF_UNSPEC.
*
* The 'type' argument is used by the caller specify whether
* to enumerate installed network interfaces or plumbed
* network interfaces. The value for 'type' can be ICFG_PLUMBED
* or ICFG_INSTALLED.
*/
int
{
*numif = 0;
if (type == ICFG_PLUMBED) {
} else if (type == ICFG_INSTALLED) {
} else {
return (ICFG_FAILURE);
}
}
/*
* Frees the memory allocated by icfg_get_list().
*/
void
{
}
/*
* Determines whether or not an interface name represents
* a logical interface or not.
*
* Returns: B_TRUE if logical, B_FALSE if not.
*
* Note: this API can be vastly improved once interface naming
* is resolved in the future. This will do for now.
*/
{
!= NULL);
}
/*
* Given a sockaddr representation of an IPv4 or IPv6 address returns the
* string 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.
*
* Returns: ICFG_SUCCESS or ICFG_FAILURE.
*/
int
{
struct sockaddr_in *sin;
struct sockaddr_in6 *sin6;
const char *str;
int ret = ICFG_FAILURE;
len);
} else {
return (ICFG_FAILURE);
}
ret = ICFG_SUCCESS;
}
return (ret);
}
/*
* 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.
*
* Returns: ICFG_SUCCESS, ICFG_BAD_ADDR or ICFG_FAILURE.
*/
int
{
struct sockaddr_in *sin;
struct sockaddr_in6 *sin6;
int ret;
int err;
return (ICFG_FAILURE);
}
return (ICFG_FAILURE);
}
} else {
return (ICFG_FAILURE);
}
if (err == 0) {
ret = ICFG_BAD_ADDR;
} else if (err == 1) {
ret = ICFG_SUCCESS;
} else {
ret = ICFG_FAILURE;
}
return (ret);
}