#include <sys/param.h>
#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void usage __P((void));
#include <netdb.h>
#include <signal.h>
#include <mach/boolean.h>
#include <sys/types.h>
#include <sys/file.h>
#include <sys/fcntl.h>
#include <sys/ioctl_compat.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <net/if.h>
#include <ifaddrs.h>
#include <rpc/rpc.h>
#include <arpa/inet.h>
#include "bootparam_prot.h"
struct in_addr ip_address;
struct in_addr net_mask;
static __inline__
u_long iptohl(struct in_addr ip)
{
return (ntohl(ip.s_addr));
}
static __inline__ boolean_t
in_subnet(struct in_addr netaddr, struct in_addr netmask, struct in_addr ip)
{
if ((iptohl(ip) & iptohl(netmask))
!= (iptohl(netaddr) & iptohl(netmask))) {
return (FALSE);
}
return (TRUE);
}
bool_t
each_whoresult(result, from)
bp_whoami_res *result;
struct sockaddr_in *from;
{
if (result) {
struct hostent * host;
struct in_addr * router;
router = (struct in_addr *)
&result->router_address.bp_address_u.ip_addr;
if (in_subnet(*router, net_mask, ip_address)) {
if (result->client_name && result->client_name[0])
printf("host_name=%s\n", result->client_name);
if (result->domain_name && result->domain_name[0])
printf("nis_domain=%s\n", result->domain_name);
printf("router=%s\n", inet_ntoa(*router));
host = gethostbyaddr((char *) &from->sin_addr,
sizeof (from->sin_addr), AF_INET);
if (host) {
printf("server_name=%s\n", host->h_name);
}
printf("server_ip_address=%s\n", inet_ntoa(from->sin_addr));
return(TRUE);
}
}
return(FALSE);
}
static boolean_t
getFirstInterface(struct sockaddr_in *ret_p)
{
struct ifaddrs *ifap;
struct ifaddrs *ifcurrent;
getifaddrs(&ifap);
for (ifcurrent = ifap; ifcurrent; ifcurrent = ifcurrent->ifa_next) {
if (ifcurrent->ifa_addr->sa_family == AF_INET) {
if ((ifcurrent->ifa_flags & IFF_LOOPBACK)
|| !(ifcurrent->ifa_flags & IFF_UP))
continue;
net_mask = ((struct sockaddr_in*)(ifcurrent->ifa_netmask))->sin_addr;
*ret_p = *((struct sockaddr_in*)(ifcurrent->ifa_addr));
freeifaddrs(ifap);
return (TRUE);
}
}
if (ifap)
freeifaddrs(ifap);
return (FALSE);
}
int
bp_whoami()
{
extern enum clnt_stat clnt_broadcast();
struct sockaddr_in sockin;
enum clnt_stat stat;
struct bp_whoami_arg who_arg;
struct bp_whoami_res who_res;
if (getFirstInterface(&sockin) == FALSE)
return (2);
ip_address = sockin.sin_addr;
who_arg.client_address.bp_address_u.ip_addr =
*((ip_addr_t *)&sockin.sin_addr);
who_arg.client_address.address_type = IP_ADDR_TYPE;
bzero(&who_res, sizeof (who_res));
stat = clnt_broadcast(BOOTPARAMPROG, BOOTPARAMVERS,
BOOTPARAMPROC_WHOAMI, xdr_bp_whoami_arg,
&who_arg, xdr_bp_whoami_res, &who_res,
each_whoresult);
if (stat == RPC_SUCCESS) {
return (0);
}
if (stat == RPC_TIMEDOUT)
return (1);
fprintf(stderr, "bpwhoami: ");
clnt_perrno(stat);
return (2);
}
int
main(argc,argv)
int argc;
char *argv[];
{
exit(bp_whoami());
}