/*
* 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 1991-2003 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 <unistd.h>
#include <errno.h>
#include <netinet/igmp_var.h>
#include <netinet/ip_mroute.h>
#include <netdb.h>
#include <nss_dbdefs.h>
#include <fcntl.h>
#include <stropts.h>
#include "bootparam_private.h"
typedef struct mib_item_s {
long group;
long mib_id;
long length;
char *valp;
} mib_item_t;
static void free_itemlist(mib_item_t *);
static mib_item_t *
{
int flags;
int i, j, getcode;
flags = 0;
perror("mibget: putmsg(ctl) failed");
goto error_exit;
}
/*
* each reply consists of a ctl part for one fixed structure
* or table, as defined in mib2.h. The format is a T_OPTMGMT_ACK,
* len is the size of the data part of the message.
*/
for (j = 1; ; j++) {
flags = 0;
if (getcode == -1) {
perror("mibget getmsg(ctl) failed");
if (debug) {
msgout("# level name len");
i = 0;
msgout("%d %4ld %5ld %ld", ++i,
}
goto error_exit;
}
if ((getcode == 0) &&
if (debug)
msgout("mibget getmsg() %d returned EOD "
"(level %lu, name %lu)",
return (first_item); /* this is EOD msg */
}
msgout("mibget %d gives T_ERROR_ACK: "
"TLI_error = 0x%lx, UNIX_error = 0x%lx",
goto error_exit;
}
msgout("mibget getmsg(ctl) %d returned %d, "
"ctlbuf.len = %d, PRIM_type = %ld",
msgout("T_OPTMGMT_ACK: MGMT_flags = 0x%lx, "
"req->len = %lu",
goto error_exit;
}
if (!temp) {
perror("mibget malloc failed");
goto error_exit;
}
if (last_item)
else
first_item = temp;
if (debug)
"msg %d: group = %4ld mib_id = %5ld length = %ld",
flags = 0;
if (getcode == -1) {
perror("mibget getmsg(data) failed");
goto error_exit;
} else if (getcode != 0) {
msgout("xmibget getmsg(data) returned %d, "
"databuf.maxlen = %d, databuf.len = %d",
goto error_exit;
}
}
return (NULL);
}
static void
{
while (item_list) {
}
}
/*
* If we are a router, return address of interface closest to client.
* If we are not a router, look through our routing table and return
* address of "best" router that is on same net as client.
*
* We expect the router flag to show up first, followed by interface
* addr group, followed by the routing table.
*/
{
int sd;
/* mask of interface used to route to client and best_router */
/* address of interface used to route to client and best_router */
/* address of "best router"; i.e. the answer */
interface_mask.s_addr = 0L;
interface_addr.s_addr = 0L;
best_router.s_addr = 0L;
/* open a stream to IP */
if (sd == -1) {
perror("ip open");
msgout("can't open mib stream");
return (0);
}
/* send down a request and suck up all the mib info from IP */
msgout("mibget() failed");
return (0);
}
/*
* We make three passes through the list of collected IP mib
* information. First we figure out if we are a router. Next,
* we find which of our interfaces is on the same subnet as
* the client. Third, we paw through our own routing table
* looking for a useful router address.
*/
/*
* The general IP group.
*/
/* are we an IP router? */
break;
}
}
/*
* The interface group.
*/
/*
* Try to find out which interface is up, configured,
* not loopback, and on the same subnet as the client.
* Save its address and netmask.
*/
int ifflags;
break;
}
map++;
}
}
}
/*
* If this exercise found no interface on the same subnet as
* the client, then we can't suggest any router address to
* use.
*/
if (interface_addr.s_addr == 0) {
if (debug)
msgout("get_ip_route: no interface on same net "
"as client");
return (0);
}
/*
* If we are a router, we return to client the address of our
* interface on the same net as the client.
*/
if (ip_forwarding == 1) {
if (debug)
msgout("get_ip_route: returning local addr %s",
return (interface_addr.s_addr);
}
if (debug) {
}
/*
* The routing table group.
*/
if (debug)
msgout("%lu records for ipRouteEntryTable",
sizeof (mib2_ipRouteEntry_t));
rp++) {
if (debug >= 2)
msgout("ire_type = %d, next_hop = 0x%x",
rp->ipRouteNextHop);
/*
* We are only interested in real
* gateway routes.
*/
IRE_DEFAULT) &&
IRE_PREFIX) &&
IRE_HOST) &&
continue;
/*
* We are only interested in routes with
* a next hop on the same subnet as
* the client.
*/
if ((rp->ipRouteNextHop &
interface_mask.s_addr) !=
continue;
/*
* We have a valid route. Give preference
* to default routes.
*/
if ((rp->ipRouteDest == 0) ||
(best_router.s_addr == 0))
}
}
}
msgout("get_ip_route: no route found for client");
return (best_router.s_addr);
}
/*
* Return address of server interface closest to client.
*
* If the server has only a single IP address return it. Otherwise check
* if the server has an interface on the same subnet as the client and
* return the address of that interface.
*/
{
int err;
int sd;
return (server_addr);
return (server_addr);
/* open a stream to IP */
if (sd == -1) {
perror("ip open");
msgout("can't open mib stream");
return (server_addr);
}
/* send down a request and suck up all the mib info from IP */
msgout("mibget() failed");
return (server_addr);
}
/*
* Search through the list for our interface which is on the same
* subnet as the client and get the netmask.
*/
/*
* Try to find out which interface is up, configured,
* not loopback, and on the same subnet as the client.
* Save its address and netmask.
*/
int ifflags;
addr != INADDR_ANY &&
client_net = net;
client_mask = mask;
break;
}
map++;
}
}
}
/*
* If we found the interface check which is the best IP address.
*/
if (found_client_int) {
server_addr = addr;
break;
}
addr_list++;
}
}
if (debug && server_addr == 0)
msgout("No usable interface for returning reply");
return (server_addr);
}