174462Salfred/* $NetBSD: check_bound.c,v 1.2 2000/06/22 08:09:26 fvdl Exp $ */ 274462Salfred/* $FreeBSD$ */ 374462Salfred 474462Salfred/* 574462Salfred * Sun RPC is a product of Sun Microsystems, Inc. and is provided for 674462Salfred * unrestricted use provided that this legend is included on all tape 774462Salfred * media and as a part of the software program in whole or part. Users 874462Salfred * may copy or modify Sun RPC without charge, but are not authorized 974462Salfred * to license or distribute it to anyone else except as part of a product or 1074462Salfred * program developed by the user. 1174462Salfred * 1274462Salfred * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE 1374462Salfred * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR 1474462Salfred * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. 1574462Salfred * 1674462Salfred * Sun RPC is provided with no support and without any obligation on the 1774462Salfred * part of Sun Microsystems, Inc. to assist in its use, correction, 1874462Salfred * modification or enhancement. 1974462Salfred * 2074462Salfred * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE 2174462Salfred * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC 2274462Salfred * OR ANY PART THEREOF. 2374462Salfred * 2474462Salfred * In no event will Sun Microsystems, Inc. be liable for any lost revenue 2574462Salfred * or profits or other special, indirect and consequential damages, even if 2674462Salfred * Sun has been advised of the possibility of such damages. 2774462Salfred * 2874462Salfred * Sun Microsystems, Inc. 2974462Salfred * 2550 Garcia Avenue 3074462Salfred * Mountain View, California 94043 3174462Salfred */ 3274462Salfred/* 3374462Salfred * Copyright (c) 1986 - 1991 by Sun Microsystems, Inc. 3474462Salfred */ 3574462Salfred 3674462Salfred/* #ident "@(#)check_bound.c 1.15 93/07/05 SMI" */ 3774462Salfred 3874462Salfred#if 0 3974462Salfred#ifndef lint 4074462Salfredstatic char sccsid[] = "@(#)check_bound.c 1.11 89/04/21 Copyr 1989 Sun Micro"; 4174462Salfred#endif 4274462Salfred#endif 4374462Salfred 4474462Salfred/* 4574462Salfred * check_bound.c 4674462Salfred * Checks to see whether the program is still bound to the 47228990Suqs * claimed address and returns the universal merged address 4874462Salfred * 4974462Salfred */ 5074462Salfred 5174462Salfred#include <sys/types.h> 5274462Salfred#include <sys/socket.h> 5374462Salfred#include <rpc/rpc.h> 54296994Sasomers#include <rpc/svc_dg.h> 5574462Salfred#include <stdio.h> 5674462Salfred#include <netconfig.h> 5774462Salfred#include <syslog.h> 5874462Salfred#include <string.h> 5974462Salfred#include <unistd.h> 6074462Salfred#include <stdlib.h> 6174462Salfred 6274462Salfred#include "rpcbind.h" 6374462Salfred 6474462Salfredstruct fdlist { 6574462Salfred int fd; 6674462Salfred struct netconfig *nconf; 6774462Salfred struct fdlist *next; 6874462Salfred int check_binding; 6974462Salfred}; 7074462Salfred 7174462Salfredstatic struct fdlist *fdhead; /* Link list of the check fd's */ 7274462Salfredstatic struct fdlist *fdtail; 7374462Salfredstatic char *nullstring = ""; 7474462Salfred 75173412Skevlostatic bool_t check_bound(struct fdlist *, char *uaddr); 7674462Salfred 7774462Salfred/* 7874462Salfred * Returns 1 if the given address is bound for the given addr & transport 7974462Salfred * For all error cases, we assume that the address is bound 8074462Salfred * Returns 0 for success. 8174462Salfred */ 8274462Salfredstatic bool_t 8374462Salfredcheck_bound(struct fdlist *fdl, char *uaddr) 8474462Salfred{ 8574462Salfred int fd; 8674462Salfred struct netbuf *na; 8774462Salfred int ans; 8874462Salfred 8974462Salfred if (fdl->check_binding == FALSE) 9074462Salfred return (TRUE); 9174462Salfred 9274462Salfred na = uaddr2taddr(fdl->nconf, uaddr); 9374462Salfred if (!na) 9474462Salfred return (TRUE); /* punt, should never happen */ 9574462Salfred 9674462Salfred fd = __rpc_nconf2fd(fdl->nconf); 9774462Salfred if (fd < 0) { 9879722Siedowse free(na->buf); 9974462Salfred free(na); 10074462Salfred return (TRUE); 10174462Salfred } 10274462Salfred 10374462Salfred ans = bind(fd, (struct sockaddr *)na->buf, na->len); 10474462Salfred 10574462Salfred close(fd); 10679722Siedowse free(na->buf); 10774462Salfred free(na); 10874462Salfred 10974462Salfred return (ans == 0 ? FALSE : TRUE); 11074462Salfred} 11174462Salfred 11274462Salfredint 113104592Salfredadd_bndlist(struct netconfig *nconf, struct netbuf *baddr __unused) 11474462Salfred{ 11574462Salfred struct fdlist *fdl; 11674462Salfred struct netconfig *newnconf; 11774462Salfred 11874462Salfred newnconf = getnetconfigent(nconf->nc_netid); 11974462Salfred if (newnconf == NULL) 12074462Salfred return (-1); 12196788Sjmallett fdl = malloc(sizeof (struct fdlist)); 12274462Salfred if (fdl == NULL) { 12374462Salfred freenetconfigent(newnconf); 12474462Salfred syslog(LOG_ERR, "no memory!"); 12574462Salfred return (-1); 12674462Salfred } 12774462Salfred fdl->nconf = newnconf; 12874462Salfred fdl->next = NULL; 12974462Salfred if (fdhead == NULL) { 13074462Salfred fdhead = fdl; 13174462Salfred fdtail = fdl; 13274462Salfred } else { 13374462Salfred fdtail->next = fdl; 13474462Salfred fdtail = fdl; 13574462Salfred } 13674462Salfred /* XXX no bound checking for now */ 13774462Salfred fdl->check_binding = FALSE; 13874462Salfred 13974462Salfred return 0; 14074462Salfred} 14174462Salfred 14274462Salfredbool_t 14374462Salfredis_bound(char *netid, char *uaddr) 14474462Salfred{ 14574462Salfred struct fdlist *fdl; 14674462Salfred 14774462Salfred for (fdl = fdhead; fdl; fdl = fdl->next) 14874462Salfred if (strcmp(fdl->nconf->nc_netid, netid) == 0) 14974462Salfred break; 15074462Salfred if (fdl == NULL) 15174462Salfred return (TRUE); 15274462Salfred return (check_bound(fdl, uaddr)); 15374462Salfred} 15474462Salfred 15574462Salfred/* 15674462Salfred * Returns NULL if there was some system error. 15774462Salfred * Returns "" if the address was not bound, i.e the server crashed. 15874462Salfred * Returns the merged address otherwise. 15974462Salfred */ 16074462Salfredchar * 16174462Salfredmergeaddr(SVCXPRT *xprt, char *netid, char *uaddr, char *saddr) 16274462Salfred{ 16374462Salfred struct fdlist *fdl; 164296994Sasomers struct svc_dg_data *dg_data; 16574462Salfred char *c_uaddr, *s_uaddr, *m_uaddr, *allocated_uaddr = NULL; 16674462Salfred 16774462Salfred for (fdl = fdhead; fdl; fdl = fdl->next) 16874462Salfred if (strcmp(fdl->nconf->nc_netid, netid) == 0) 16974462Salfred break; 17074462Salfred if (fdl == NULL) 17174462Salfred return (NULL); 17274462Salfred if (check_bound(fdl, uaddr) == FALSE) 17374462Salfred /* that server died */ 17474462Salfred return (nullstring); 17574462Salfred /* 176296994Sasomers * Try to determine the local address on which the client contacted us, 177296994Sasomers * so we can send a reply from the same address. If it's unknown, then 178296994Sasomers * try to determine which address the client used, and pick a nearby 179296994Sasomers * local address. 180296994Sasomers * 18174462Salfred * If saddr is not NULL, the remote client may have included the 18274462Salfred * address by which it contacted us. Use that for the "client" uaddr, 18374462Salfred * otherwise use the info from the SVCXPRT. 18474462Salfred */ 185296994Sasomers dg_data = (struct svc_dg_data*)xprt->xp_p2; 186296994Sasomers if (dg_data != NULL && dg_data->su_srcaddr.buf != NULL) { 187296994Sasomers c_uaddr = taddr2uaddr(fdl->nconf, &dg_data->su_srcaddr); 188296994Sasomers allocated_uaddr = c_uaddr; 189296994Sasomers } 190296994Sasomers else if (saddr != NULL) { 19174462Salfred c_uaddr = saddr; 19274462Salfred } else { 19374462Salfred c_uaddr = taddr2uaddr(fdl->nconf, svc_getrpccaller(xprt)); 19474462Salfred allocated_uaddr = c_uaddr; 19574462Salfred } 196296994Sasomers if (c_uaddr == NULL) { 197296994Sasomers syslog(LOG_ERR, "taddr2uaddr failed for %s", 198296994Sasomers fdl->nconf->nc_netid); 199296994Sasomers return (NULL); 200296994Sasomers } 20174462Salfred 20274462Salfred#ifdef ND_DEBUG 20374462Salfred if (debugging) { 20474462Salfred if (saddr == NULL) { 20574462Salfred fprintf(stderr, "mergeaddr: client uaddr = %s\n", 20674462Salfred c_uaddr); 20774462Salfred } else { 20874462Salfred fprintf(stderr, "mergeaddr: contact uaddr = %s\n", 20974462Salfred c_uaddr); 21074462Salfred } 21174462Salfred } 21274462Salfred#endif 21374462Salfred s_uaddr = uaddr; 21474462Salfred /* 21574462Salfred * This is all we should need for IP 4 and 6 21674462Salfred */ 21774462Salfred m_uaddr = addrmerge(svc_getrpccaller(xprt), s_uaddr, c_uaddr, netid); 21874462Salfred#ifdef ND_DEBUG 21974462Salfred if (debugging) 22074462Salfred fprintf(stderr, "mergeaddr: uaddr = %s, merged uaddr = %s\n", 22174462Salfred uaddr, m_uaddr); 22274462Salfred#endif 223301644Sngie free(allocated_uaddr); 22474462Salfred return (m_uaddr); 22574462Salfred} 22674462Salfred 22774462Salfred/* 22874462Salfred * Returns a netconf structure from its internal list. This 22974462Salfred * structure should not be freed. 23074462Salfred */ 23174462Salfredstruct netconfig * 232296994Sasomersrpcbind_get_conf(const char *netid) 23374462Salfred{ 23474462Salfred struct fdlist *fdl; 23574462Salfred 23674462Salfred for (fdl = fdhead; fdl; fdl = fdl->next) 23774462Salfred if (strcmp(fdl->nconf->nc_netid, netid) == 0) 23874462Salfred break; 23974462Salfred if (fdl == NULL) 24074462Salfred return (NULL); 24174462Salfred return (fdl->nconf); 24274462Salfred} 243