/*
* 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
*/
/*
*/
/*
* This file contains the functions that are required for communicating
* with in.ndpd while creating autoconfigured addresses.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <assert.h>
#include <poll.h>
#include <ipadm_ndpd.h>
#include "libipadm_impl.h"
static void i_ipadm_make_linklocal(struct sockaddr_in6 *,
const struct in6_addr *);
static ipadm_status_t i_ipadm_send_ndpd_cmd(const char *,
const struct ipadm_addrobj_s *, int);
/*
* Sends message to in.ndpd asking not to do autoconf for the given interface,
* until IPADM_CREATE_ADDRS or IPADM_ENABLE_AUTOCONF is sent.
*/
{
}
/*
* Sends message to in.ndpd to enable autoconf for the given interface,
* until another IPADM_DISABLE_AUTOCONF is sent.
*/
{
}
{
/*
* Create the link local based on the given token. If the same intfid
* was already used with a different address object, this step will
* fail.
*/
if (status != IPADM_SUCCESS)
return (status);
/*
* Request in.ndpd to start the autoconfiguration.
* If autoconfiguration was already started by another means (e.g.
* "ifconfig" ), in.ndpd will return EEXIST.
*/
if (status != IPADM_SUCCESS &&
status != IPADM_NDPD_NOT_RUNNING) {
return (status);
}
}
/* Persist the intfid. */
if (status != IPADM_SUCCESS) {
}
return (status);
}
{
/*
* Send a msg to in.ndpd to remove the autoconfigured addresses,
* and delete the link local that was created.
*/
if (status == IPADM_NDPD_NOT_RUNNING)
if (status == IPADM_SUCCESS)
return (status);
}
static ipadm_status_t
{
int err;
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
/*
* Create a logical interface if needed.
*/
if (status != IPADM_SUCCESS)
return (status);
if (status == IPADM_ADDROBJ_EXISTS)
goto retry;
if (status != IPADM_SUCCESS)
return (status);
}
/* Create the link-local address */
goto fail;
if (addr->ipadm_intfidlen == 0) {
/*
* If we have to use the default interface id,
* we just need to set the prefix to the link-local prefix.
* SIOCSLIFPREFIX sets the address with the given prefix
* and the default interface id.
*/
if (err < 0)
goto fail;
} else {
/* Make a linklocal address in sin6 and set it */
if (err < 0)
goto fail;
}
goto fail;
goto fail;
return (IPADM_SUCCESS);
fail:
else
/* Remove the linklocal that was created. */
if (addif) {
} else {
}
return (status);
}
/*
* Make a linklocal address based on the given intfid and copy it into
* the output parameter `sin6'.
*/
static void
{
int i;
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
for (i = 0; i < 4; i++) {
}
}
/*
* Function that forms an ndpd msg and sends it to the in.ndpd daemon's loopback
* listener socket.
*/
static ipadm_status_t
int cmd)
{
int fd;
int flags;
int retval;
return (IPADM_INVALID_ARG);
}
if (fd == -1)
return (IPADM_FAILURE);
/* Put the socket in non-blocking mode */
if (flags != -1)
/* Connect to in.ndpd */
goto fail;
if (cmd == IPADM_CREATE_ADDRS) {
sizeof (msg.inm_aobjname));
}
}
goto fail;
goto fail;
return (IPADM_ADDRCONF_EXISTS);
return (ipadm_errno2status(retval));
fail:
return (IPADM_NDPD_NOT_RUNNING);
}
/*
* Attempt to read `buflen' worth of bytes from `fd' into the buffer pointed
* to by `buf'.
*/
int
{
int retval;
/*
* Wait for data to come in or for the timeout to fire.
*/
if (retval <= 0) {
if (retval == 0)
break;
}
/*
* Descriptor is ready; have at it.
*/
if (prbytes <= 0) {
continue;
break;
}
}
}
/*
* Write `buflen' bytes from `buffer' to open file `fd'. Returns 0
* if all requested bytes were written, or an error code if not.
*/
int
{
if (nbytes == -1)
return (-1);
if (nbytes == 0) {
return (-1);
}
}
return (0);
}