1b2845e83SBill Paul /* 2*df57947fSPedro F. Giffuni * SPDX-License-Identifier: BSD-4-Clause 3*df57947fSPedro F. Giffuni * 4b2845e83SBill Paul * Copyright (c) 1996, 1997 5b2845e83SBill Paul * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 6b2845e83SBill Paul * 7b2845e83SBill Paul * Redistribution and use in source and binary forms, with or without 8b2845e83SBill Paul * modification, are permitted provided that the following conditions 9b2845e83SBill Paul * are met: 10b2845e83SBill Paul * 1. Redistributions of source code must retain the above copyright 11b2845e83SBill Paul * notice, this list of conditions and the following disclaimer. 12b2845e83SBill Paul * 2. Redistributions in binary form must reproduce the above copyright 13b2845e83SBill Paul * notice, this list of conditions and the following disclaimer in the 14b2845e83SBill Paul * documentation and/or other materials provided with the distribution. 15b2845e83SBill Paul * 3. All advertising materials mentioning features or use of this software 16b2845e83SBill Paul * must display the following acknowledgement: 17b2845e83SBill Paul * This product includes software developed by Bill Paul. 18b2845e83SBill Paul * 4. Neither the name of the author nor the names of any co-contributors 19b2845e83SBill Paul * may be used to endorse or promote products derived from this software 20b2845e83SBill Paul * without specific prior written permission. 21b2845e83SBill Paul * 22b2845e83SBill Paul * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND 23b2845e83SBill Paul * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24b2845e83SBill Paul * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25b2845e83SBill Paul * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR CONTRIBUTORS BE LIABLE 26b2845e83SBill Paul * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27b2845e83SBill Paul * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28b2845e83SBill Paul * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29b2845e83SBill Paul * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30b2845e83SBill Paul * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31b2845e83SBill Paul * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32b2845e83SBill Paul * SUCH DAMAGE. 33b2845e83SBill Paul */ 34b2845e83SBill Paul 356a67774fSHiroki Sato /*- 366a67774fSHiroki Sato * Copyright (c) 2009, Sun Microsystems, Inc. 376a67774fSHiroki Sato * All rights reserved. 38b2845e83SBill Paul * 396a67774fSHiroki Sato * Redistribution and use in source and binary forms, with or without 406a67774fSHiroki Sato * modification, are permitted provided that the following conditions are met: 416a67774fSHiroki Sato * - Redistributions of source code must retain the above copyright notice, 426a67774fSHiroki Sato * this list of conditions and the following disclaimer. 436a67774fSHiroki Sato * - Redistributions in binary form must reproduce the above copyright notice, 446a67774fSHiroki Sato * this list of conditions and the following disclaimer in the documentation 456a67774fSHiroki Sato * and/or other materials provided with the distribution. 466a67774fSHiroki Sato * - Neither the name of Sun Microsystems, Inc. nor the names of its 476a67774fSHiroki Sato * contributors may be used to endorse or promote products derived 486a67774fSHiroki Sato * from this software without specific prior written permission. 49b2845e83SBill Paul * 506a67774fSHiroki Sato * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 516a67774fSHiroki Sato * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 526a67774fSHiroki Sato * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 536a67774fSHiroki Sato * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 546a67774fSHiroki Sato * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 556a67774fSHiroki Sato * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 566a67774fSHiroki Sato * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 576a67774fSHiroki Sato * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 586a67774fSHiroki Sato * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 596a67774fSHiroki Sato * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 606a67774fSHiroki Sato * POSSIBILITY OF SUCH DAMAGE. 61b2845e83SBill Paul */ 6277cbf0b3SPhilippe Charnier #if 0 63b728350eSDavid E. O'Brien #ifndef lint 6477cbf0b3SPhilippe Charnier static char *sccsid = "@(#)from: clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro"; 6577cbf0b3SPhilippe Charnier static char *sccsid = "@(#)from: clnt_udp.c 2.2 88/08/01 4.0 RPCSRC"; 6677cbf0b3SPhilippe Charnier #endif 67b2845e83SBill Paul #endif 68b728350eSDavid E. O'Brien #include <sys/cdefs.h> 69b728350eSDavid E. O'Brien __FBSDID("$FreeBSD$"); 70b2845e83SBill Paul 71b2845e83SBill Paul /* 72b2845e83SBill Paul * clnt_udp.c, Implements a UDP/IP based, client side RPC. 73b2845e83SBill Paul * 74b2845e83SBill Paul * Copyright (C) 1984, Sun Microsystems, Inc. 75b2845e83SBill Paul */ 76b2845e83SBill Paul 7777cbf0b3SPhilippe Charnier #include <errno.h> 7877cbf0b3SPhilippe Charnier #include <netdb.h> 79b2845e83SBill Paul #include <stdio.h> 80b2845e83SBill Paul #include <stdlib.h> 81b2845e83SBill Paul #include <string.h> 8277cbf0b3SPhilippe Charnier #include <unistd.h> 838de34b25SBill Paul #include <pthread.h> 84b2845e83SBill Paul #include <rpc/rpc.h> 85b2845e83SBill Paul #include <rpc/pmap_clnt.h> 86b2845e83SBill Paul #include <rpc/pmap_prot.h> 87b2845e83SBill Paul #include <rpcsvc/yp.h> 888de34b25SBill Paul #include <sys/types.h> 898de34b25SBill Paul #include <sys/poll.h> 9077cbf0b3SPhilippe Charnier #include <sys/socket.h> 918de34b25SBill Paul #include <sys/signal.h> 9277cbf0b3SPhilippe Charnier #include <sys/ioctl.h> 93fd8e4ebcSMike Barcroft #include <arpa/inet.h> 9477cbf0b3SPhilippe Charnier #include <net/if.h> 958de34b25SBill Paul 96b2845e83SBill Paul #include "yp_ping.h" 97b2845e83SBill Paul 98b2845e83SBill Paul /* 99b2845e83SBill Paul * pmap_getport.c 100b2845e83SBill Paul * Client interface to pmap rpc service. 101b2845e83SBill Paul * 102b2845e83SBill Paul * Copyright (C) 1984, Sun Microsystems, Inc. 103b2845e83SBill Paul */ 104b2845e83SBill Paul 105b2845e83SBill Paul 106b2845e83SBill Paul static struct timeval timeout = { 1, 0 }; 107b2845e83SBill Paul static struct timeval tottimeout = { 1, 0 }; 108b2845e83SBill Paul 109b2845e83SBill Paul /* 110b2845e83SBill Paul * Find the mapped port for program,version. 111b2845e83SBill Paul * Calls the pmap service remotely to do the lookup. 112b2845e83SBill Paul * Returns 0 if no map exists. 113b2845e83SBill Paul */ 114b2845e83SBill Paul static u_short 115dc584ddbSDag-Erling Smørgrav __pmap_getport(struct sockaddr_in *address, u_long program, u_long version, 116dc584ddbSDag-Erling Smørgrav u_int protocol) 117b2845e83SBill Paul { 118b2845e83SBill Paul u_short port = 0; 119b2845e83SBill Paul int sock = -1; 120b2845e83SBill Paul register CLIENT *client; 121b2845e83SBill Paul struct pmap parms; 122b2845e83SBill Paul 123b2845e83SBill Paul address->sin_port = htons(PMAPPORT); 124b2845e83SBill Paul 125b2845e83SBill Paul client = clntudp_bufcreate(address, PMAPPROG, 126b2845e83SBill Paul PMAPVERS, timeout, &sock, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); 127b2845e83SBill Paul if (client != (CLIENT *)NULL) { 128b2845e83SBill Paul parms.pm_prog = program; 129b2845e83SBill Paul parms.pm_vers = version; 130b2845e83SBill Paul parms.pm_prot = protocol; 131b2845e83SBill Paul parms.pm_port = 0; /* not needed or used */ 132f249dbccSDag-Erling Smørgrav if (CLNT_CALL(client, PMAPPROC_GETPORT, 133f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_pmap, &parms, 134f249dbccSDag-Erling Smørgrav (xdrproc_t)xdr_u_short, &port, 135f249dbccSDag-Erling Smørgrav tottimeout) != RPC_SUCCESS){ 136b2845e83SBill Paul rpc_createerr.cf_stat = RPC_PMAPFAILURE; 137b2845e83SBill Paul clnt_geterr(client, &rpc_createerr.cf_error); 138b2845e83SBill Paul } else if (port == 0) { 139b2845e83SBill Paul rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; 140b2845e83SBill Paul } 141b2845e83SBill Paul CLNT_DESTROY(client); 142b2845e83SBill Paul } 143b2845e83SBill Paul if (sock != -1) 144b2845e83SBill Paul (void)close(sock); 145b2845e83SBill Paul address->sin_port = 0; 146b2845e83SBill Paul return (port); 147b2845e83SBill Paul } 148b2845e83SBill Paul 149b2845e83SBill Paul /* 150b2845e83SBill Paul * Transmit to YPPROC_DOMAIN_NONACK, return immediately. 151b2845e83SBill Paul */ 152b2845e83SBill Paul static bool_t * 153b2845e83SBill Paul ypproc_domain_nonack_2_send(domainname *argp, CLIENT *clnt) 154b2845e83SBill Paul { 155b2845e83SBill Paul static bool_t clnt_res; 156b2845e83SBill Paul struct timeval TIMEOUT = { 0, 0 }; 157b2845e83SBill Paul 158b2845e83SBill Paul memset((char *)&clnt_res, 0, sizeof (clnt_res)); 159b2845e83SBill Paul if (clnt_call(clnt, YPPROC_DOMAIN_NONACK, 160b2845e83SBill Paul (xdrproc_t) xdr_domainname, (caddr_t) argp, 161b2845e83SBill Paul (xdrproc_t) xdr_bool, (caddr_t) &clnt_res, 162b2845e83SBill Paul TIMEOUT) != RPC_SUCCESS) { 163b2845e83SBill Paul return (NULL); 164b2845e83SBill Paul } 165b2845e83SBill Paul return (&clnt_res); 166b2845e83SBill Paul } 167b2845e83SBill Paul 168b2845e83SBill Paul /* 169b2845e83SBill Paul * Receive response from YPPROC_DOMAIN_NONACK asynchronously. 170b2845e83SBill Paul */ 171b2845e83SBill Paul static bool_t * 172b2845e83SBill Paul ypproc_domain_nonack_2_recv(domainname *argp, CLIENT *clnt) 173b2845e83SBill Paul { 174b2845e83SBill Paul static bool_t clnt_res; 175b2845e83SBill Paul struct timeval TIMEOUT = { 0, 0 }; 176b2845e83SBill Paul 177b2845e83SBill Paul memset((char *)&clnt_res, 0, sizeof (clnt_res)); 178b2845e83SBill Paul if (clnt_call(clnt, YPPROC_DOMAIN_NONACK, 179b2845e83SBill Paul (xdrproc_t) NULL, (caddr_t) argp, 180b2845e83SBill Paul (xdrproc_t) xdr_bool, (caddr_t) &clnt_res, 181b2845e83SBill Paul TIMEOUT) != RPC_SUCCESS) { 182b2845e83SBill Paul return (NULL); 183b2845e83SBill Paul } 184b2845e83SBill Paul return (&clnt_res); 185b2845e83SBill Paul } 186b2845e83SBill Paul 187b2845e83SBill Paul /* 188b2845e83SBill Paul * "We have the machine that goes 'ping!'" -- Monty Python 189b2845e83SBill Paul * 190b2845e83SBill Paul * This function blasts packets at the YPPROC_DOMAIN_NONACK procedures 191b2845e83SBill Paul * of the NIS servers listed in restricted_addrs structure. 192b2845e83SBill Paul * Whoever replies the fastest becomes our chosen server. 193b2845e83SBill Paul * 194b2845e83SBill Paul * Note: THIS IS NOT A BROADCAST OPERATION! We could use clnt_broadcast() 195b2845e83SBill Paul * for this, but that has the following problems: 196b2845e83SBill Paul * - We only get the address of the machine that replied in the 197b2845e83SBill Paul * 'eachresult' callback, and on multi-homed machines this can 198b2845e83SBill Paul * lead to confusion. 199b2845e83SBill Paul * - clnt_broadcast() only transmits to local networks, whereas with 200b2845e83SBill Paul * NIS+ you can have a perfectly good server located anywhere on or 201b2845e83SBill Paul * off the local network. 202b2845e83SBill Paul * - clnt_broadcast() blocks for an arbitrary amount of time which the 203b2845e83SBill Paul * caller can't control -- we want to avoid that. 204b2845e83SBill Paul * 205b2845e83SBill Paul * Also note that this has nothing to do with the NIS_PING procedure used 206b2845e83SBill Paul * for replica updates. 207b2845e83SBill Paul */ 208b2845e83SBill Paul 209b2845e83SBill Paul struct ping_req { 210b2845e83SBill Paul struct sockaddr_in sin; 211bfe95cccSBill Fenner u_int32_t xid; 212b2845e83SBill Paul }; 213b2845e83SBill Paul 214dc584ddbSDag-Erling Smørgrav int 215dc584ddbSDag-Erling Smørgrav __yp_ping(struct in_addr *restricted_addrs, int cnt, char *dom, short *port) 216b2845e83SBill Paul { 217b2845e83SBill Paul struct timeval tv = { 5, 0 }; 218b2845e83SBill Paul struct ping_req **reqs; 219b2845e83SBill Paul unsigned long i; 2208de34b25SBill Paul int async; 221844812c4SBill Paul struct sockaddr_in sin, *any = NULL; 2220be84ce8SDoug Rabson struct netbuf addr; 223b2845e83SBill Paul int winner = -1; 224bfe95cccSBill Fenner u_int32_t xid_seed, xid_lookup; 225b2845e83SBill Paul int sock, dontblock = 1; 226b2845e83SBill Paul CLIENT *clnt; 227b2845e83SBill Paul char *foo = dom; 228bfb109dfSBill Paul int validsrvs = 0; 229b2845e83SBill Paul 230b2845e83SBill Paul /* Set up handles. */ 23185f10495SPedro F. Giffuni reqs = calloc(cnt, sizeof(struct ping_req *)); 232b2845e83SBill Paul xid_seed = time(NULL) ^ getpid(); 233b2845e83SBill Paul 234b2845e83SBill Paul for (i = 0; i < cnt; i++) { 235b2845e83SBill Paul bzero((char *)&sin, sizeof(sin)); 236b2845e83SBill Paul sin.sin_family = AF_INET; 237b2845e83SBill Paul bcopy((char *)&restricted_addrs[i], 238b2845e83SBill Paul (char *)&sin.sin_addr, sizeof(struct in_addr)); 239b2845e83SBill Paul sin.sin_port = htons(__pmap_getport(&sin, YPPROG, 240b2845e83SBill Paul YPVERS, IPPROTO_UDP)); 241b2845e83SBill Paul if (sin.sin_port == 0) 242b2845e83SBill Paul continue; 243b2845e83SBill Paul reqs[i] = calloc(1, sizeof(struct ping_req)); 244b2845e83SBill Paul bcopy((char *)&sin, (char *)&reqs[i]->sin, sizeof(sin)); 245b2845e83SBill Paul any = &reqs[i]->sin; 246b2845e83SBill Paul reqs[i]->xid = xid_seed; 247b2845e83SBill Paul xid_seed++; 248bfb109dfSBill Paul validsrvs++; 249b2845e83SBill Paul } 250b2845e83SBill Paul 251b2845e83SBill Paul /* Make sure at least one server was assigned */ 252bfb109dfSBill Paul if (!validsrvs) { 253b2845e83SBill Paul free(reqs); 254b2845e83SBill Paul return(-1); 255b2845e83SBill Paul } 256b2845e83SBill Paul 257b2845e83SBill Paul /* Create RPC handle */ 258b2845e83SBill Paul sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); 259b2845e83SBill Paul clnt = clntudp_create(any, YPPROG, YPVERS, tv, &sock); 260b2845e83SBill Paul if (clnt == NULL) { 261b2845e83SBill Paul close(sock); 262b2845e83SBill Paul for (i = 0; i < cnt; i++) 263b2845e83SBill Paul if (reqs[i] != NULL) 264b2845e83SBill Paul free(reqs[i]); 265b2845e83SBill Paul free(reqs); 266b2845e83SBill Paul return(-1); 267b2845e83SBill Paul } 268b2845e83SBill Paul clnt->cl_auth = authunix_create_default(); 269b2845e83SBill Paul tv.tv_sec = 0; 2708de34b25SBill Paul 2718360efbdSAlfred Perlstein clnt_control(clnt, CLSET_TIMEOUT, (char *)&tv); 2728de34b25SBill Paul async = TRUE; 2738de34b25SBill Paul clnt_control(clnt, CLSET_ASYNC, (char *)&async); 274b2845e83SBill Paul ioctl(sock, FIONBIO, &dontblock); 275b2845e83SBill Paul 276b2845e83SBill Paul /* Transmit */ 277b2845e83SBill Paul for (i = 0; i < cnt; i++) { 278b2845e83SBill Paul if (reqs[i] != NULL) { 2798de34b25SBill Paul clnt_control(clnt, CLSET_XID, (char *)&reqs[i]->xid); 2800be84ce8SDoug Rabson addr.len = sizeof(reqs[i]->sin); 2810be84ce8SDoug Rabson addr.buf = (char *) &reqs[i]->sin; 2820be84ce8SDoug Rabson clnt_control(clnt, CLSET_SVC_ADDR, &addr); 283b2845e83SBill Paul ypproc_domain_nonack_2_send(&foo, clnt); 284b2845e83SBill Paul } 285b2845e83SBill Paul } 286b2845e83SBill Paul 287b2845e83SBill Paul /* Receive reply */ 288b2845e83SBill Paul ypproc_domain_nonack_2_recv(&foo, clnt); 289b2845e83SBill Paul 290b2845e83SBill Paul /* Got a winner -- look him up. */ 2918de34b25SBill Paul clnt_control(clnt, CLGET_XID, (char *)&xid_lookup); 292b2845e83SBill Paul for (i = 0; i < cnt; i++) { 293b2845e83SBill Paul if (reqs[i] != NULL && reqs[i]->xid == xid_lookup) { 294b2845e83SBill Paul winner = i; 295b2845e83SBill Paul *port = reqs[i]->sin.sin_port; 296b2845e83SBill Paul } 297b2845e83SBill Paul } 298b2845e83SBill Paul 299b2845e83SBill Paul /* Shut everything down */ 300b2845e83SBill Paul auth_destroy(clnt->cl_auth); 301b2845e83SBill Paul clnt_destroy(clnt); 302b2845e83SBill Paul close(sock); 303b2845e83SBill Paul 304b2845e83SBill Paul for (i = 0; i < cnt; i++) 305b2845e83SBill Paul if (reqs[i] != NULL) 306b2845e83SBill Paul free(reqs[i]); 307b2845e83SBill Paul free(reqs); 308b2845e83SBill Paul 309b2845e83SBill Paul return(winner); 310b2845e83SBill Paul } 311