17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 23*740638c8Sbw * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate #include <stdio.h> 307c478bd9Sstevel@tonic-gate #include <stdlib.h> 317c478bd9Sstevel@tonic-gate #include <unistd.h> 327c478bd9Sstevel@tonic-gate #include <string.h> 337c478bd9Sstevel@tonic-gate #include <locale.h> 347c478bd9Sstevel@tonic-gate #include <sys/utsname.h> 357c478bd9Sstevel@tonic-gate #include <sys/systeminfo.h> 367c478bd9Sstevel@tonic-gate #include <netdb.h> 377c478bd9Sstevel@tonic-gate #include <sys/types.h> 387c478bd9Sstevel@tonic-gate #include <sys/param.h> 397c478bd9Sstevel@tonic-gate #include <sys/errno.h> 407c478bd9Sstevel@tonic-gate #include <sys/file.h> 417c478bd9Sstevel@tonic-gate #include <sys/ioctl.h> 427c478bd9Sstevel@tonic-gate #include <sys/signal.h> 437c478bd9Sstevel@tonic-gate #include <sys/wait.h> 447c478bd9Sstevel@tonic-gate #include <sys/time.h> 457c478bd9Sstevel@tonic-gate #include <sys/socket.h> 467c478bd9Sstevel@tonic-gate #include <sys/stropts.h> 477c478bd9Sstevel@tonic-gate #include <sys/resource.h> 487c478bd9Sstevel@tonic-gate #include <net/if.h> 497c478bd9Sstevel@tonic-gate #include <net/if_arp.h> 507c478bd9Sstevel@tonic-gate #include <sys/stream.h> 517c478bd9Sstevel@tonic-gate #include <net/route.h> 527c478bd9Sstevel@tonic-gate #include <netinet/in.h> 537c478bd9Sstevel@tonic-gate #include <arpa/inet.h> 547c478bd9Sstevel@tonic-gate #include <netinet/if_ether.h> 557c478bd9Sstevel@tonic-gate #include <netinet/ip_var.h> 567c478bd9Sstevel@tonic-gate #include <netinet/udp.h> 577c478bd9Sstevel@tonic-gate #include <netinet/udp_var.h> 587c478bd9Sstevel@tonic-gate #include <rpc/rpc.h> 597c478bd9Sstevel@tonic-gate #include <rpcsvc/bootparam_prot.h> 607c478bd9Sstevel@tonic-gate 617c478bd9Sstevel@tonic-gate #define MAXIFS 256 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate /* command line flags */ 647c478bd9Sstevel@tonic-gate int debug = 0; /* do debug printfs */ 657c478bd9Sstevel@tonic-gate int echo_host = 0; /* just echo hostname, don't set it */ 667c478bd9Sstevel@tonic-gate int verbose = 0; /* do verbose printfs */ 677c478bd9Sstevel@tonic-gate int safe = 0; /* don't change anything */ 687c478bd9Sstevel@tonic-gate int multiple = 0; /* take multiple replies */ 697c478bd9Sstevel@tonic-gate 707c478bd9Sstevel@tonic-gate static ulong_t if_netmask; 717c478bd9Sstevel@tonic-gate 727c478bd9Sstevel@tonic-gate void notsupported(), usage(), bp_whoami(); 737c478bd9Sstevel@tonic-gate int get_ifdata(); /* get IP addr, subnet mask from IF */ 747c478bd9Sstevel@tonic-gate extern char *inet_ntoa(); 757c478bd9Sstevel@tonic-gate extern int getopt(), setdomainname(); 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate struct prototab { 787c478bd9Sstevel@tonic-gate char *name; 797c478bd9Sstevel@tonic-gate void (*func)(); 807c478bd9Sstevel@tonic-gate } prototab[] = { 817c478bd9Sstevel@tonic-gate { "bootparams", bp_whoami }, 827c478bd9Sstevel@tonic-gate { "bootp", notsupported }, 837c478bd9Sstevel@tonic-gate { 0, 0 } 847c478bd9Sstevel@tonic-gate }; 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate 877c478bd9Sstevel@tonic-gate 887c478bd9Sstevel@tonic-gate /* 897c478bd9Sstevel@tonic-gate * usage: hostconfig [-p <protocol>] [-v] [-n] [-h] [<ifname>] [-f <hostname>] 907c478bd9Sstevel@tonic-gate * 917c478bd9Sstevel@tonic-gate * options: 927c478bd9Sstevel@tonic-gate * -d Debug mode. 937c478bd9Sstevel@tonic-gate * -v Verbose mode. 947c478bd9Sstevel@tonic-gate * -n Don't change anything. 957c478bd9Sstevel@tonic-gate * -h Don't set hostname, just echo to standard out. 967c478bd9Sstevel@tonic-gate * -m Wait for multiple answers (best used with the "-n" 977c478bd9Sstevel@tonic-gate * and "-v" flags). 987c478bd9Sstevel@tonic-gate * -f <hostname> Fake mode - get bootparams for <hostname> (also 997c478bd9Sstevel@tonic-gate * best used with the "-n" and "-v" flags). 1007c478bd9Sstevel@tonic-gate * <ifname> Use IP address of <interface> in whoami request. 1017c478bd9Sstevel@tonic-gate * 1027c478bd9Sstevel@tonic-gate * If no interface name is specified, bp_whoami will cycle through the 1037c478bd9Sstevel@tonic-gate * interfaces, using the IP address of each in turn until an answer is 1047c478bd9Sstevel@tonic-gate * received. Note that rpc_broadcast() broadcasts the RPC call on all 1057c478bd9Sstevel@tonic-gate * interfaces, so the <ifname> argument doesn't restrict the request 1067c478bd9Sstevel@tonic-gate * to that interface, it just uses that interface to determine the IP 1077c478bd9Sstevel@tonic-gate * address to put into the request. If "-f <hostname>" is specified, 1087c478bd9Sstevel@tonic-gate * we put the IP address of <hostname> in the whoami request. Otherwise, 1097c478bd9Sstevel@tonic-gate * we put the IP address of the interface in the whoami request. 1107c478bd9Sstevel@tonic-gate * 1117c478bd9Sstevel@tonic-gate */ 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate 114*740638c8Sbw int 1157c478bd9Sstevel@tonic-gate main(argc, argv) 1167c478bd9Sstevel@tonic-gate int argc; 1177c478bd9Sstevel@tonic-gate char **argv; 1187c478bd9Sstevel@tonic-gate { 1197c478bd9Sstevel@tonic-gate struct ifreq *reqbuf; 1207c478bd9Sstevel@tonic-gate struct ifreq *ifr; 1217c478bd9Sstevel@tonic-gate struct ifconf ifc; 1227c478bd9Sstevel@tonic-gate struct in_addr targetaddr; 1237c478bd9Sstevel@tonic-gate struct hostent *hp; 1247c478bd9Sstevel@tonic-gate char *targethost = NULL; 1257c478bd9Sstevel@tonic-gate char *cmdname; 1267c478bd9Sstevel@tonic-gate int c; 1277c478bd9Sstevel@tonic-gate int n; 1287c478bd9Sstevel@tonic-gate struct prototab *ptp; 1297c478bd9Sstevel@tonic-gate void (*protofunc)() = NULL; 1307c478bd9Sstevel@tonic-gate int numifs; 1317c478bd9Sstevel@tonic-gate unsigned bufsize; 1327c478bd9Sstevel@tonic-gate 1337c478bd9Sstevel@tonic-gate extern char *optarg; 1347c478bd9Sstevel@tonic-gate extern int optind; 1357c478bd9Sstevel@tonic-gate 1367c478bd9Sstevel@tonic-gate cmdname = argv[0]; 1377c478bd9Sstevel@tonic-gate 1387c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "dhvnmf:p:")) != -1) { 1397c478bd9Sstevel@tonic-gate 1407c478bd9Sstevel@tonic-gate switch ((char)c) { 1417c478bd9Sstevel@tonic-gate case 'd': 1427c478bd9Sstevel@tonic-gate debug++; 1437c478bd9Sstevel@tonic-gate break; 1447c478bd9Sstevel@tonic-gate 1457c478bd9Sstevel@tonic-gate case 'h': 1467c478bd9Sstevel@tonic-gate echo_host++; 1477c478bd9Sstevel@tonic-gate break; 1487c478bd9Sstevel@tonic-gate case 'v': 1497c478bd9Sstevel@tonic-gate verbose++; 1507c478bd9Sstevel@tonic-gate break; 1517c478bd9Sstevel@tonic-gate 1527c478bd9Sstevel@tonic-gate case 'm': 1537c478bd9Sstevel@tonic-gate multiple++; 1547c478bd9Sstevel@tonic-gate break; 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate case 'n': 1577c478bd9Sstevel@tonic-gate safe++; 1587c478bd9Sstevel@tonic-gate break; 1597c478bd9Sstevel@tonic-gate 1607c478bd9Sstevel@tonic-gate case 'f': 1617c478bd9Sstevel@tonic-gate targethost = optarg; 1627c478bd9Sstevel@tonic-gate break; 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate case 'p': 1657c478bd9Sstevel@tonic-gate protofunc = NULL; 1667c478bd9Sstevel@tonic-gate for (ptp = &prototab[0]; ptp->func; ptp++) 1677c478bd9Sstevel@tonic-gate if (strcmp(optarg, ptp->name) == 0) { 1687c478bd9Sstevel@tonic-gate protofunc = ptp->func; 1697c478bd9Sstevel@tonic-gate break; 1707c478bd9Sstevel@tonic-gate } 1717c478bd9Sstevel@tonic-gate if (protofunc == NULL) 1727c478bd9Sstevel@tonic-gate usage(cmdname); 1737c478bd9Sstevel@tonic-gate break; 1747c478bd9Sstevel@tonic-gate 1757c478bd9Sstevel@tonic-gate case '?': 1767c478bd9Sstevel@tonic-gate usage(cmdname); 1777c478bd9Sstevel@tonic-gate } 1787c478bd9Sstevel@tonic-gate } 1797c478bd9Sstevel@tonic-gate 1807c478bd9Sstevel@tonic-gate if (protofunc == NULL) 1817c478bd9Sstevel@tonic-gate usage(cmdname); 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate if (targethost) { 1847c478bd9Sstevel@tonic-gate /* we are faking it */ 1857c478bd9Sstevel@tonic-gate if (debug) 1867c478bd9Sstevel@tonic-gate fprintf(stdout, "targethost = %s\n", targethost); 1877c478bd9Sstevel@tonic-gate 1887c478bd9Sstevel@tonic-gate if ((hp = gethostbyname(targethost)) == NULL) { 1897c478bd9Sstevel@tonic-gate if ((targetaddr.s_addr = inet_addr(targethost)) == 1907c478bd9Sstevel@tonic-gate (ulong_t)(-1)) { 1917c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1927c478bd9Sstevel@tonic-gate "%s: cannot get IP address for %s\n", 1937c478bd9Sstevel@tonic-gate cmdname, targethost); 1947c478bd9Sstevel@tonic-gate return (1); 1957c478bd9Sstevel@tonic-gate } 1967c478bd9Sstevel@tonic-gate } else { 1977c478bd9Sstevel@tonic-gate if (hp->h_length != sizeof (targetaddr)) { 1987c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1997c478bd9Sstevel@tonic-gate "%s: cannot find host entry for %s\n", 2007c478bd9Sstevel@tonic-gate cmdname, targethost); 2017c478bd9Sstevel@tonic-gate return (1); 2027c478bd9Sstevel@tonic-gate } else 2037c478bd9Sstevel@tonic-gate (void) memcpy(&targetaddr.s_addr, hp->h_addr, 2047c478bd9Sstevel@tonic-gate sizeof (targetaddr)); 2057c478bd9Sstevel@tonic-gate } 2067c478bd9Sstevel@tonic-gate } else 2077c478bd9Sstevel@tonic-gate targetaddr.s_addr = 0; 2087c478bd9Sstevel@tonic-gate 2097c478bd9Sstevel@tonic-gate if (optind < argc) { 2107c478bd9Sstevel@tonic-gate /* interface names were specified */ 2117c478bd9Sstevel@tonic-gate for (; optind < argc; optind++) { 2127c478bd9Sstevel@tonic-gate if (debug) 2137c478bd9Sstevel@tonic-gate fprintf(stdout, "Trying arg %s\n", 2147c478bd9Sstevel@tonic-gate argv[optind]); 2157c478bd9Sstevel@tonic-gate (*protofunc)(argv[optind], targetaddr); 2167c478bd9Sstevel@tonic-gate } 2177c478bd9Sstevel@tonic-gate } else { 2187c478bd9Sstevel@tonic-gate /* no interface names specified - try them all */ 2197c478bd9Sstevel@tonic-gate int ifcount = 0; /* count of useable interfaces */ 2207c478bd9Sstevel@tonic-gate int s; 2217c478bd9Sstevel@tonic-gate 2227c478bd9Sstevel@tonic-gate if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 2237c478bd9Sstevel@tonic-gate perror("socket"); 2247c478bd9Sstevel@tonic-gate return (1); 2257c478bd9Sstevel@tonic-gate } 2267c478bd9Sstevel@tonic-gate #ifdef SIOCGIFNUM 2277c478bd9Sstevel@tonic-gate if (ioctl(s, SIOCGIFNUM, (char *)&numifs) < 0) { 2287c478bd9Sstevel@tonic-gate numifs = MAXIFS; 2297c478bd9Sstevel@tonic-gate } 2307c478bd9Sstevel@tonic-gate #else 2317c478bd9Sstevel@tonic-gate numifs = MAXIFS; 2327c478bd9Sstevel@tonic-gate #endif 2337c478bd9Sstevel@tonic-gate bufsize = numifs * sizeof (struct ifreq); 2347c478bd9Sstevel@tonic-gate reqbuf = (struct ifreq *)malloc(bufsize); 2357c478bd9Sstevel@tonic-gate if (reqbuf == NULL) { 2367c478bd9Sstevel@tonic-gate fprintf(stderr, "out of memory\n"); 2377c478bd9Sstevel@tonic-gate return (1); 2387c478bd9Sstevel@tonic-gate } 2397c478bd9Sstevel@tonic-gate ifc.ifc_buf = (caddr_t)&reqbuf[0]; 2407c478bd9Sstevel@tonic-gate ifc.ifc_len = bufsize; 2417c478bd9Sstevel@tonic-gate if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) { 2427c478bd9Sstevel@tonic-gate perror("ioctl(SIOCGIFCONF)"); 2437c478bd9Sstevel@tonic-gate return (1); 2447c478bd9Sstevel@tonic-gate } 2457c478bd9Sstevel@tonic-gate ifr = ifc.ifc_req; 2467c478bd9Sstevel@tonic-gate n = ifc.ifc_len/sizeof (struct ifreq); 2477c478bd9Sstevel@tonic-gate for (; n > 0; n--, ifr++) { 2487c478bd9Sstevel@tonic-gate if (ioctl(s, SIOCGIFFLAGS, (char *)ifr) < 0) { 2497c478bd9Sstevel@tonic-gate perror("ioctl(SIOCGIFFLAGS)"); 2507c478bd9Sstevel@tonic-gate return (1); 2517c478bd9Sstevel@tonic-gate } 2527c478bd9Sstevel@tonic-gate if ((ifr->ifr_flags & IFF_LOOPBACK) || 2537c478bd9Sstevel@tonic-gate !(ifr->ifr_flags & IFF_BROADCAST) || 2547c478bd9Sstevel@tonic-gate !(ifr->ifr_flags & IFF_UP) || 2557c478bd9Sstevel@tonic-gate (ifr->ifr_flags & IFF_NOARP) || 2567c478bd9Sstevel@tonic-gate (ifr->ifr_flags & IFF_POINTOPOINT)) { 2577c478bd9Sstevel@tonic-gate if (debug) 2587c478bd9Sstevel@tonic-gate fprintf(stdout, "If %s not suitable\n", 2597c478bd9Sstevel@tonic-gate ifr->ifr_name); 2607c478bd9Sstevel@tonic-gate continue; 2617c478bd9Sstevel@tonic-gate } else { 2627c478bd9Sstevel@tonic-gate if (debug) 2637c478bd9Sstevel@tonic-gate fprintf(stdout, "Trying device %s\n", 2647c478bd9Sstevel@tonic-gate ifr->ifr_name); 2657c478bd9Sstevel@tonic-gate (*protofunc)(ifr->ifr_name, targetaddr); 2667c478bd9Sstevel@tonic-gate ifcount++; 2677c478bd9Sstevel@tonic-gate } 2687c478bd9Sstevel@tonic-gate } 2697c478bd9Sstevel@tonic-gate if (verbose && ifcount == 0) { 2707c478bd9Sstevel@tonic-gate fprintf(stderr, "No useable interfaces found.\n"); 2717c478bd9Sstevel@tonic-gate return (1); 2727c478bd9Sstevel@tonic-gate } 2737c478bd9Sstevel@tonic-gate (void) close(s); 2747c478bd9Sstevel@tonic-gate (void) free((char *)reqbuf); 2757c478bd9Sstevel@tonic-gate } 2767c478bd9Sstevel@tonic-gate return (0); 2777c478bd9Sstevel@tonic-gate } 2787c478bd9Sstevel@tonic-gate 2797c478bd9Sstevel@tonic-gate 2807c478bd9Sstevel@tonic-gate void 2817c478bd9Sstevel@tonic-gate add_default_route(router_addr) 2827c478bd9Sstevel@tonic-gate struct in_addr router_addr; 2837c478bd9Sstevel@tonic-gate { 2847c478bd9Sstevel@tonic-gate struct rtentry route; 2857c478bd9Sstevel@tonic-gate struct sockaddr_in *sin; 2867c478bd9Sstevel@tonic-gate int s; 2877c478bd9Sstevel@tonic-gate 2887c478bd9Sstevel@tonic-gate (void) memset(&route, 0, sizeof (route)); 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate /* route destination is "default" - zero */ 2917c478bd9Sstevel@tonic-gate /* LINTED - alignment OK (32bit) */ 2927c478bd9Sstevel@tonic-gate sin = (struct sockaddr_in *)&route.rt_dst; 2937c478bd9Sstevel@tonic-gate sin->sin_family = AF_INET; 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate /* LINTED - alignment OK (32bit) */ 2967c478bd9Sstevel@tonic-gate sin = (struct sockaddr_in *)&route.rt_gateway; 2977c478bd9Sstevel@tonic-gate sin->sin_family = AF_INET; 2987c478bd9Sstevel@tonic-gate sin->sin_addr.s_addr = router_addr.s_addr; 2997c478bd9Sstevel@tonic-gate 3007c478bd9Sstevel@tonic-gate route.rt_flags = RTF_GATEWAY | RTF_UP; 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 3037c478bd9Sstevel@tonic-gate perror("socket"); 3047c478bd9Sstevel@tonic-gate return; 3057c478bd9Sstevel@tonic-gate } 3067c478bd9Sstevel@tonic-gate if (ioctl(s, SIOCADDRT, (char *)&route) == -1) { 3077c478bd9Sstevel@tonic-gate perror("add default route"); 3087c478bd9Sstevel@tonic-gate return; 3097c478bd9Sstevel@tonic-gate } 3107c478bd9Sstevel@tonic-gate (void) close(s); 3117c478bd9Sstevel@tonic-gate } 3127c478bd9Sstevel@tonic-gate 3137c478bd9Sstevel@tonic-gate 3147c478bd9Sstevel@tonic-gate int 3157c478bd9Sstevel@tonic-gate bpanswer(res, nb) 3167c478bd9Sstevel@tonic-gate struct bp_whoami_res *res; 3177c478bd9Sstevel@tonic-gate struct netbuf *nb; 3187c478bd9Sstevel@tonic-gate { 3197c478bd9Sstevel@tonic-gate struct in_addr router_addr; 3207c478bd9Sstevel@tonic-gate static int set; 3217c478bd9Sstevel@tonic-gate int len; 3227c478bd9Sstevel@tonic-gate char errbuf[MAX_MACHINE_NAME + 28]; 3237c478bd9Sstevel@tonic-gate /* MAX_MACHINE_NAME + strlen ("sysinfo(SI_SET_HOSTNAME)()") + null */ 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate (void) memcpy(&router_addr, &res->router_address.bp_address_u.ip_addr, 3267c478bd9Sstevel@tonic-gate sizeof (router_addr)); 3277c478bd9Sstevel@tonic-gate 3287c478bd9Sstevel@tonic-gate if (verbose) { 3297c478bd9Sstevel@tonic-gate struct sockaddr_in *addr; 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate if (nb) { 3327c478bd9Sstevel@tonic-gate /* LINTED - alignment (32bit) OK */ 3337c478bd9Sstevel@tonic-gate addr = (struct sockaddr_in *)nb->buf; 3347c478bd9Sstevel@tonic-gate fprintf(stdout, "From [%s]: ", 3357c478bd9Sstevel@tonic-gate inet_ntoa(addr->sin_addr)); 3367c478bd9Sstevel@tonic-gate } else { 3377c478bd9Sstevel@tonic-gate fprintf(stdout, "Reply:\\t\\t"); 3387c478bd9Sstevel@tonic-gate } 3397c478bd9Sstevel@tonic-gate fprintf(stdout, "hostname = %s\n", res->client_name); 3407c478bd9Sstevel@tonic-gate fprintf(stdout, "\t\typdomain = %s\n", res->domain_name); 3417c478bd9Sstevel@tonic-gate fprintf(stdout, "\t\trouter = %s\n", inet_ntoa(router_addr)); 3427c478bd9Sstevel@tonic-gate } 3437c478bd9Sstevel@tonic-gate 3447c478bd9Sstevel@tonic-gate if (!safe && !set) { 3457c478bd9Sstevel@tonic-gate /* 3467c478bd9Sstevel@tonic-gate * Stuff the values from the RPC reply into the kernel. 3477c478bd9Sstevel@tonic-gate * Only allow one pass through this code; There's no reason 3487c478bd9Sstevel@tonic-gate * why all replies should tweak the kernel. 3497c478bd9Sstevel@tonic-gate */ 3507c478bd9Sstevel@tonic-gate set++; 3517c478bd9Sstevel@tonic-gate 3527c478bd9Sstevel@tonic-gate len = strlen(res->client_name); 3537c478bd9Sstevel@tonic-gate if (len != 0) { 3547c478bd9Sstevel@tonic-gate if (!echo_host) { 3557c478bd9Sstevel@tonic-gate if (sysinfo(SI_SET_HOSTNAME, res->client_name, 3567c478bd9Sstevel@tonic-gate len) < 0) { 3577c478bd9Sstevel@tonic-gate (void) snprintf(errbuf, sizeof (errbuf), 3587c478bd9Sstevel@tonic-gate "sysinfo(SI_SET_HOSTNAME)(%s)", 3597c478bd9Sstevel@tonic-gate res->client_name); 3607c478bd9Sstevel@tonic-gate perror(errbuf); 3617c478bd9Sstevel@tonic-gate } 3627c478bd9Sstevel@tonic-gate } else 3637c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "%s\n", 3647c478bd9Sstevel@tonic-gate res->client_name); 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate len = strlen(res->domain_name); 3687c478bd9Sstevel@tonic-gate if (len != 0) { 3697c478bd9Sstevel@tonic-gate if (setdomainname(res->domain_name, len) == -1) { 3707c478bd9Sstevel@tonic-gate (void) snprintf(errbuf, sizeof (errbuf), 3717c478bd9Sstevel@tonic-gate "setdomainname(%s)", res->domain_name); 3727c478bd9Sstevel@tonic-gate perror(errbuf); 3737c478bd9Sstevel@tonic-gate } 3747c478bd9Sstevel@tonic-gate } 3757c478bd9Sstevel@tonic-gate 3767c478bd9Sstevel@tonic-gate /* we really should validate this router value */ 3777c478bd9Sstevel@tonic-gate if (router_addr.s_addr != 0) 3787c478bd9Sstevel@tonic-gate add_default_route(router_addr); 3797c478bd9Sstevel@tonic-gate } 3807c478bd9Sstevel@tonic-gate 3817c478bd9Sstevel@tonic-gate if (multiple) 3827c478bd9Sstevel@tonic-gate return (NULL); 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate /* our job is done */ 3857c478bd9Sstevel@tonic-gate exit(0); 3867c478bd9Sstevel@tonic-gate /* NOTREACHED */ 3877c478bd9Sstevel@tonic-gate } 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate void 3907c478bd9Sstevel@tonic-gate bp_whoami(device, addr) 3917c478bd9Sstevel@tonic-gate char *device; 3927c478bd9Sstevel@tonic-gate struct in_addr addr; 3937c478bd9Sstevel@tonic-gate { 3947c478bd9Sstevel@tonic-gate struct bp_whoami_arg req; 3957c478bd9Sstevel@tonic-gate struct bp_whoami_res res; 3967c478bd9Sstevel@tonic-gate struct in_addr lookupaddr; 3977c478bd9Sstevel@tonic-gate enum clnt_stat stat; 3987c478bd9Sstevel@tonic-gate int val = 1; 3997c478bd9Sstevel@tonic-gate 4007c478bd9Sstevel@tonic-gate if (debug) 4017c478bd9Sstevel@tonic-gate fprintf(stdout, "bp_whoami on interface %s addr %s\n", device, 4027c478bd9Sstevel@tonic-gate inet_ntoa(addr)); 4037c478bd9Sstevel@tonic-gate 4047c478bd9Sstevel@tonic-gate if (addr.s_addr == 0) { 4057c478bd9Sstevel@tonic-gate if (get_ifdata(device, &lookupaddr, &if_netmask) == -1) 4067c478bd9Sstevel@tonic-gate exit(1); 4077c478bd9Sstevel@tonic-gate } else 4087c478bd9Sstevel@tonic-gate (void) memcpy(&lookupaddr, &addr, sizeof (addr)); 4097c478bd9Sstevel@tonic-gate 4107c478bd9Sstevel@tonic-gate lookupaddr.s_addr = ntohl(lookupaddr.s_addr); 4117c478bd9Sstevel@tonic-gate 4127c478bd9Sstevel@tonic-gate if (debug) 4137c478bd9Sstevel@tonic-gate fprintf(stdout, "lookup address is %s\n", 4147c478bd9Sstevel@tonic-gate inet_ntoa(lookupaddr)); 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate (void) memset(&req, 0, sizeof (req)); 4177c478bd9Sstevel@tonic-gate (void) memset(&res, 0, sizeof (res)); 4187c478bd9Sstevel@tonic-gate 4197c478bd9Sstevel@tonic-gate req.client_address.address_type = IP_ADDR_TYPE; 4207c478bd9Sstevel@tonic-gate (void) memcpy(&req.client_address.bp_address_u.ip_addr, &lookupaddr, 4217c478bd9Sstevel@tonic-gate sizeof (lookupaddr)); 4227c478bd9Sstevel@tonic-gate 4237c478bd9Sstevel@tonic-gate /* 4247c478bd9Sstevel@tonic-gate * Broadcast using portmap version number 2 ONLY to 4257c478bd9Sstevel@tonic-gate * prevent broadcast storm 4267c478bd9Sstevel@tonic-gate */ 4277c478bd9Sstevel@tonic-gate 4287c478bd9Sstevel@tonic-gate (void) __rpc_control(CLCR_SET_LOWVERS, &val); 4297c478bd9Sstevel@tonic-gate 4307c478bd9Sstevel@tonic-gate stat = rpc_broadcast(BOOTPARAMPROG, BOOTPARAMVERS, BOOTPARAMPROC_WHOAMI, 4317c478bd9Sstevel@tonic-gate xdr_bp_whoami_arg, (caddr_t)&req, xdr_bp_whoami_res, (caddr_t)&res, 4327c478bd9Sstevel@tonic-gate (resultproc_t)bpanswer, "udp"); 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate /* Now try version 3 as well */ 4357c478bd9Sstevel@tonic-gate 4367c478bd9Sstevel@tonic-gate val = 0; 4377c478bd9Sstevel@tonic-gate (void) __rpc_control(CLCR_SET_LOWVERS, &val); 4387c478bd9Sstevel@tonic-gate 4397c478bd9Sstevel@tonic-gate stat = rpc_broadcast(BOOTPARAMPROG, BOOTPARAMVERS, 4407c478bd9Sstevel@tonic-gate BOOTPARAMPROC_WHOAMI, xdr_bp_whoami_arg, (caddr_t)&req, 4417c478bd9Sstevel@tonic-gate xdr_bp_whoami_res, (caddr_t)&res, (resultproc_t)bpanswer, "udp"); 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate if (stat != RPC_SUCCESS) { 4447c478bd9Sstevel@tonic-gate clnt_perrno(stat); 4457c478bd9Sstevel@tonic-gate exit(1); 4467c478bd9Sstevel@tonic-gate } 4477c478bd9Sstevel@tonic-gate } 4487c478bd9Sstevel@tonic-gate 4497c478bd9Sstevel@tonic-gate 4507c478bd9Sstevel@tonic-gate /* 4517c478bd9Sstevel@tonic-gate * Get IP address of an interface. As long as we are looking, get the 4527c478bd9Sstevel@tonic-gate * netmask as well. 4537c478bd9Sstevel@tonic-gate */ 4547c478bd9Sstevel@tonic-gate int 4557c478bd9Sstevel@tonic-gate get_ifdata(dev, ipp, maskp) 4567c478bd9Sstevel@tonic-gate char *dev; 4577c478bd9Sstevel@tonic-gate ulong_t *ipp, *maskp; 4587c478bd9Sstevel@tonic-gate { 4597c478bd9Sstevel@tonic-gate struct ifreq ifr; 4607c478bd9Sstevel@tonic-gate /* LINTED - alignment OK (32bit) */ 4617c478bd9Sstevel@tonic-gate struct sockaddr_in *sin = (struct sockaddr_in *)&ifr.ifr_addr; 4627c478bd9Sstevel@tonic-gate int s; 4637c478bd9Sstevel@tonic-gate 4647c478bd9Sstevel@tonic-gate if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { 4657c478bd9Sstevel@tonic-gate perror("socket"); 4667c478bd9Sstevel@tonic-gate return (-1); 4677c478bd9Sstevel@tonic-gate } 4687c478bd9Sstevel@tonic-gate 4697c478bd9Sstevel@tonic-gate if (strlcpy(ifr.ifr_name, dev, sizeof (ifr.ifr_name)) >= 4707c478bd9Sstevel@tonic-gate sizeof (ifr.ifr_name)) { 4717c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Device name too long %s\n", 4727c478bd9Sstevel@tonic-gate dev); 4737c478bd9Sstevel@tonic-gate return (-1); 4747c478bd9Sstevel@tonic-gate } 4757c478bd9Sstevel@tonic-gate 4767c478bd9Sstevel@tonic-gate if (ipp) { 4777c478bd9Sstevel@tonic-gate if (ioctl(s, SIOCGIFADDR, (caddr_t)&ifr) < 0) { 4787c478bd9Sstevel@tonic-gate perror("ioctl(SIOCGIFADDR)"); 4797c478bd9Sstevel@tonic-gate return (-1); 4807c478bd9Sstevel@tonic-gate } 4817c478bd9Sstevel@tonic-gate *ipp = ntohl(sin->sin_addr.s_addr); 4827c478bd9Sstevel@tonic-gate 4837c478bd9Sstevel@tonic-gate if (debug) 4847c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "Interface '%s' address %s\n", 4857c478bd9Sstevel@tonic-gate dev, inet_ntoa(sin->sin_addr)); 4867c478bd9Sstevel@tonic-gate } 4877c478bd9Sstevel@tonic-gate 4887c478bd9Sstevel@tonic-gate if (maskp) { 4897c478bd9Sstevel@tonic-gate if (ioctl(s, SIOCGIFNETMASK, (caddr_t)&ifr) < 0) { 4907c478bd9Sstevel@tonic-gate perror("SIOCGIFNETMASK"); 4917c478bd9Sstevel@tonic-gate return (-1); 4927c478bd9Sstevel@tonic-gate } 4937c478bd9Sstevel@tonic-gate *maskp = ntohl(sin->sin_addr.s_addr); 4947c478bd9Sstevel@tonic-gate 4957c478bd9Sstevel@tonic-gate if (debug) 4967c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 4977c478bd9Sstevel@tonic-gate "Interface '%s' subnet mask %s\n", dev, 4987c478bd9Sstevel@tonic-gate inet_ntoa(sin->sin_addr)); 4997c478bd9Sstevel@tonic-gate } 5007c478bd9Sstevel@tonic-gate 5017c478bd9Sstevel@tonic-gate (void) close(s); 5027c478bd9Sstevel@tonic-gate return (0); 5037c478bd9Sstevel@tonic-gate } 5047c478bd9Sstevel@tonic-gate 5057c478bd9Sstevel@tonic-gate void 5067c478bd9Sstevel@tonic-gate notsupported() 5077c478bd9Sstevel@tonic-gate { 5087c478bd9Sstevel@tonic-gate fprintf(stderr, "requested protocol is not supported\n"); 5097c478bd9Sstevel@tonic-gate exit(1); 5107c478bd9Sstevel@tonic-gate } 5117c478bd9Sstevel@tonic-gate 5127c478bd9Sstevel@tonic-gate void 5137c478bd9Sstevel@tonic-gate usage(cmdname) 5147c478bd9Sstevel@tonic-gate char *cmdname; 5157c478bd9Sstevel@tonic-gate { 5167c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "usage: %s [-v] [-n] [-m] [-h] [<ifname>] " 5177c478bd9Sstevel@tonic-gate "[-f <hostname>] -p bootparams|bootp\n", cmdname); 5187c478bd9Sstevel@tonic-gate (void) fflush(stderr); 5197c478bd9Sstevel@tonic-gate exit(1); 5207c478bd9Sstevel@tonic-gate } 521