/*
* 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 2005 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 <unistd.h>
#include <string.h>
#include <locale.h>
#include <sys/systeminfo.h>
#include <netdb.h>
#include <sys/resource.h>
#include <netinet/if_ether.h>
#include <rpcsvc/bootparam_prot.h>
/* command line flags */
int get_ifdata(); /* get IP addr, subnet mask from IF */
extern char *inet_ntoa();
extern int getopt(), setdomainname();
struct prototab {
char *name;
void (*func)();
} prototab[] = {
{ "bootparams", bp_whoami },
{ "bootp", notsupported },
{ 0, 0 }
};
/*
* usage: hostconfig [-p <protocol>] [-v] [-n] [-h] [<ifname>] [-f <hostname>]
*
* options:
* -d Debug mode.
* -v Verbose mode.
* -n Don't change anything.
* -h Don't set hostname, just echo to standard out.
* -m Wait for multiple answers (best used with the "-n"
* and "-v" flags).
* -f <hostname> Fake mode - get bootparams for <hostname> (also
* best used with the "-n" and "-v" flags).
* <ifname> Use IP address of <interface> in whoami request.
*
* If no interface name is specified, bp_whoami will cycle through the
* interfaces, using the IP address of each in turn until an answer is
* received. Note that rpc_broadcast() broadcasts the RPC call on all
* interfaces, so the <ifname> argument doesn't restrict the request
* to that interface, it just uses that interface to determine the IP
* address to put into the request. If "-f <hostname>" is specified,
* we put the IP address of <hostname> in the whoami request. Otherwise,
* we put the IP address of the interface in the whoami request.
*
*/
int
int argc;
char **argv;
{
char *cmdname;
int c;
int n;
int numifs;
unsigned bufsize;
extern char *optarg;
extern int optind;
switch ((char)c) {
case 'd':
debug++;
break;
case 'h':
echo_host++;
break;
case 'v':
verbose++;
break;
case 'm':
multiple++;
break;
case 'n':
safe++;
break;
case 'f':
targethost = optarg;
break;
case 'p':
break;
}
break;
case '?':
}
}
if (targethost) {
/* we are faking it */
if (debug)
(ulong_t)(-1)) {
"%s: cannot get IP address for %s\n",
return (1);
}
} else {
"%s: cannot find host entry for %s\n",
return (1);
} else
sizeof (targetaddr));
}
} else
targetaddr.s_addr = 0;
/* interface names were specified */
if (debug)
}
} else {
/* no interface names specified - try them all */
int s;
perror("socket");
return (1);
}
#ifdef SIOCGIFNUM
}
#else
#endif
return (1);
}
perror("ioctl(SIOCGIFCONF)");
return (1);
}
for (; n > 0; n--, ifr++) {
perror("ioctl(SIOCGIFFLAGS)");
return (1);
}
if (debug)
continue;
} else {
if (debug)
ifcount++;
}
}
return (1);
}
(void) close(s);
}
return (0);
}
void
struct in_addr router_addr;
{
int s;
/* route destination is "default" - zero */
/* LINTED - alignment OK (32bit) */
/* LINTED - alignment OK (32bit) */
perror("socket");
return;
}
perror("add default route");
return;
}
(void) close(s);
}
int
struct bp_whoami_res *res;
{
static int set;
int len;
/* MAX_MACHINE_NAME + strlen ("sysinfo(SI_SET_HOSTNAME)()") + null */
sizeof (router_addr));
if (verbose) {
if (nb) {
/* LINTED - alignment (32bit) OK */
} else {
}
}
/*
* Stuff the values from the RPC reply into the kernel.
* Only allow one pass through this code; There's no reason
* why all replies should tweak the kernel.
*/
set++;
if (len != 0) {
if (!echo_host) {
len) < 0) {
"sysinfo(SI_SET_HOSTNAME)(%s)",
res->client_name);
}
} else
res->client_name);
}
if (len != 0) {
}
}
/* we really should validate this router value */
if (router_addr.s_addr != 0)
}
if (multiple)
return (NULL);
/* our job is done */
exit(0);
/* NOTREACHED */
}
void
char *device;
{
if (debug)
exit(1);
} else
if (debug)
sizeof (lookupaddr));
/*
* Broadcast using portmap version number 2 ONLY to
* prevent broadcast storm
*/
/* Now try version 3 as well */
val = 0;
if (stat != RPC_SUCCESS) {
exit(1);
}
}
/*
* Get IP address of an interface. As long as we are looking, get the
* netmask as well.
*/
int
char *dev;
{
/* LINTED - alignment OK (32bit) */
int s;
perror("socket");
return (-1);
}
dev);
return (-1);
}
if (ipp) {
perror("ioctl(SIOCGIFADDR)");
return (-1);
}
if (debug)
}
if (maskp) {
perror("SIOCGIFNETMASK");
return (-1);
}
if (debug)
"Interface '%s' subnet mask %s\n", dev,
}
(void) close(s);
return (0);
}
void
{
exit(1);
}
void
char *cmdname;
{
"[-f <hostname>] -p bootparams|bootp\n", cmdname);
exit(1);
}