/*
* 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 <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <libnwam.h>
#include "events.h"
#include "ncp.h"
#include "ncu.h"
#include "util.h"
/*
* routing_events.c - this file contains routines to retrieve routing socket
* events and package them for high level processing.
*/
(RTAX_MAX * sizeof (struct sockaddr_storage))
static void printaddrs(int, void *);
static char *printaddr(void **);
static void *getaddr(int, int, void *);
union rtm_buf
{
/* Routing information. */
struct
{
} r;
/* Interface information. */
struct
{
} im;
/* Interface address information. */
struct
{
} ia;
};
static int seq = 0;
static const char *
{
switch (type) {
case RTM_NEWADDR:
return ("NEWADDR");
case RTM_DELADDR:
return ("DELADDR");
case RTM_CHGADDR:
return ("CHGADDR");
case RTM_FREEADDR:
return ("FREEADDR");
default:
return (typestr);
}
}
/* ARGSUSED0 */
static void *
{
int n;
for (;;) {
continue;
} else if (n == -1) {
"%d: %m", v4_sock);
/* Low likelihood. What's recovery path? */
continue;
}
if (rtm->rtm_msglen < n) {
"routing socket but message claims to be "
continue;
}
continue;
}
if (rtm->rtm_msglen != n) {
n, v4_sock);
}
case RTM_NEWADDR:
case RTM_DELADDR:
case RTM_CHGADDR:
case RTM_FREEADDR:
break;
/* Ignore routing socket messages for 0.0.0.0 */
/*LINTED*/
== INADDR_ANY) {
"tossing message for 0.0.0.0");
break;
}
break;
break;
/*
* We don't use the lladdr in this structure so we can
* run over it.
*/
if (ifa->ifam_index == 0) {
break;
}
"routing_events_v4: unhandled type %d",
break;
}
/* Create and enqueue IF_STATE event */
break;
}
}
/* NOTREACHED */
return (NULL);
}
/* ARGSUSED0 */
static void *
{
int n;
for (;;) {
continue;
} else if (n == -1) {
"%d: %m", v6_sock);
/* Low likelihood. What's recovery path? */
continue;
}
if (rtm->rtm_msglen < n) {
"routing socket but message claims to be "
continue;
}
continue;
}
if (rtm->rtm_msglen != n) {
n, v6_sock);
}
case RTM_NEWADDR:
case RTM_DELADDR:
case RTM_CHGADDR:
case RTM_FREEADDR:
break;
/* Ignore routing socket messages for :: & linklocal */
/*LINTED*/
"tossing message for ::");
break;
}
/*LINTED*/
"tossing message for link local address");
break;
}
if ((netmask =
break;
break;
/*
* We don't use the lladdr in this structure so we can
* run over it.
*/
if (ifa->ifam_index == 0) {
break;
}
"routing_events_v6: unhandled type %d",
break;
}
/* Create and enqueue IF_STATE event */
break;
}
}
/* NOTREACHED */
return (NULL);
}
void
{
/*
* Initialize routing sockets here so that we know the routing threads
* (and any requests to add a route) will be working with a valid socket
* by the time we start handling events.
*/
if (v4_sock == -1)
pfail("failed to open v4 routing socket: %m");
if (v6_sock == -1)
pfail("failed to open v6 routing socket: %m");
(void) pthread_attr_init(&attr);
pfail("routing thread creation failed");
(void) pthread_attr_destroy(&attr);
}
void
{
(void) pthread_cancel(v4_routing);
(void) pthread_cancel(v6_routing);
}
void
{
/* LINTED E_BAD_PTR_CAST_ALIGN */
int af;
/* retrieve the index value for the interface */
ifname);
return;
}
"only wrote %d bytes of %d to routing socket\n",
}
}
static char *
{
switch (family) {
case AF_UNSPEC:
sizeof (buffer));
break;
case AF_INET:
sizeof (buffer));
break;
case AF_INET6:
sizeof (buffer));
break;
case AF_LINK:
break;
default:
/*
* We can't reliably update the size of this thing
* because we don't know what its type is. So bump
* it by a sockaddr_in and see what happens. The
* caller should really make sure this never happens.
*/
"unknown address family %d", family);
break;
}
return (buffer);
}
static void
{
if (mask == 0)
return;
if (mask & RTA_GATEWAY)
if (mask & RTA_NETMASK)
if (mask & RTA_GENMASK)
if (mask & RTA_AUTHOR)
}
static void
{
switch (family) {
case AF_UNSPEC:
case AF_INET:
break;
case AF_INET6:
break;
case AF_LINK:
break;
default:
break;
}
}
static void *
{
int i;
void *p = addresses;
return (NULL);
if (i & mask)
nextaddr(&p);
}
return (p);
}
static void
{
case AF_INET:
break;
case AF_INET6:
break;
case AF_LINK:
break;
default:
break;
}
}