1
0

Source code upload

This commit is contained in:
calmsacibis995
2022-09-29 17:59:04 +03:00
parent 72fa9da3d7
commit 8fc8fa8089
33399 changed files with 11964078 additions and 0 deletions

872
eoe/cmd/rpcbind/rpcbind.c Normal file
View File

@@ -0,0 +1,872 @@
/* Copyright (c) 1990, 1991 UNIX System Laboratories, Inc. */
/* Copyright (c) 1984, 1986, 1987, 1988, 1989, 1990 AT&T */
/* All Rights Reserved */
/* THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF */
/* UNIX System Laboratories, Inc. */
/* The copyright notice above does not evidence any */
/* actual or intended publication of such source code. */
#ident "@(#)rpcbind:rpcbind.c 1.14.9.2"
/*+++++++++++++++++++++++++++++++++++++++++++++++++++++++++
* PROPRIETARY NOTICE (Combined)
*
* This source code is unpublished proprietary information
* constituting, or derived under license from AT&T's UNIX(r) System V.
* In addition, portions of such source code were derived from Berkeley
* 4.3 BSD under license from the Regents of the University of
* California.
*
*
*
* Copyright Notice
*
* Notice of copyright on this source code product does not indicate
* publication.
*
* (c) 1986,1987,1988,1989,1990 Sun Microsystems, Inc
* (c) 1983,1984,1985,1986,1987,1988,1989,1990 AT&T.
* (c) 1990,1991 UNIX System Laboratories, Inc.
* All rights reserved.
*/
/*
* rpcbind.c
* Implements the program, version to address mapping for rpc.
*
*/
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <rpc/rpc.h>
#include <rpc/rpcb_prot.h>
#include <netconfig.h>
#include <netdir.h>
#include <sys/wait.h>
#include <signal.h>
#include <fmtmsg.h>
#ifdef PORTMAP
#include <netinet/in.h>
#include <rpc/pmap_prot.h>
#endif
#include "rpcbind.h"
#include <sys/termios.h>
#ifdef SYSLOG
#include <sys/syslog.h>
#else
#define LOG_DAEMON (3<<3)
#define LOG_CONS 0x02
#define LOG_ERR 3
#endif /* SYSLOG */
#ifdef sgi
#include <string.h>
/* #include <sys/stream.h> #include <sys/tihdr.h> #include <sys/stropts.h> */
#include <tiuser.h>
#endif
extern void *malloc();
extern char *strdup();
#ifdef PORTMAP
extern void pmap_service();
#endif
extern int rpcb_service();
#ifdef WAIT3
void reap();
#endif
static void terminate();
static void detachfromtty();
static void parseargs();
static int init_transport();
extern void read_warmstart();
extern void write_warmstart();
/* Global variables */
int debugging = 0; /* Tell me what's going on */
#ifdef sgi
int verbose = 0; /* report errors */
int do_mcast = 0; /* register for UDP multicasts */
SVCXPRT *m_xprt;
int max_forks = 10; /* maximum number of callits at once */
#endif
RPCBLIST *list_rbl; /* A list of version 3 rpcbind services */
char *loopback_dg; /* Datagram loopback transport, for set and unset */
char *loopback_vc; /* COTS loopback transport, for set and unset */
char *loopback_vc_ord; /* COTS_ORD loopback transport, for set and unset */
int Secure = 1;
/* Local Variable */
static int warmstart = 0; /* Grab a old copy of registrations */
#ifdef PORTMAP
PMAPLIST *list_pml; /* A list of version 2 rpcbind services */
char *udptrans = ""; /* Name of UDP transport */
char *tcptrans = ""; /* Name of TCP transport */
char *udp_uaddr; /* Universal UDP address */
char *tcp_uaddr; /* Universal TCP address */
SVCXPRT *ludp_xprt = NULL; /* loopback udp transport */
SVCXPRT *ltcp_xprt = NULL; /* loopback tcp transport */
#endif
static char servname[] = "rpcbind";
static char superuser[] = "superuser";
extern int t_errno;
extern char *t_errlist[];
#ifdef sgi
/*
* Simple access control to restrict any request for useful information
* to a limited set of addresses. The first match in the array of
* mask-match pairs allows the request to be processed. Any address
* for this host is always allowed.
*/
#define MAX_OKNETS 50
struct oknet oknets[MAX_OKNETS];
int num_oknets;
int Aflag;
int bflag;
#endif
main(argc, argv)
int argc;
char *argv[];
{
struct netconfig *nconf;
void *nc_handle; /* Net config handle */
openlog("rpcbind", LOG_CONS, LOG_DAEMON);
parseargs(argc, argv);
if (geteuid()) { /* This command allowed only to root */
(void) fprintf(stderr, "must be root to run %s\n", argv[0]);
exit(1);
}
#ifdef sgi
if (!Secure)
(void) fmtmsg(MM_CONSOLE, "rpcbind", MM_WARNING, "The -C option provides backward compatibility for broken applications. It also exposes a widely known security problem.", NULL, NULL);
#endif
nc_handle = setnetconfig(); /* open netconfig file */
if (nc_handle == NULL) {
syslog(LOG_ERR, "could not read /etc/netconfig");
exit(1);
}
loopback_dg = "";
loopback_vc = "";
loopback_vc_ord = "";
{ struct rlimit rl;
rl.rlim_cur = 1024;
rl.rlim_max = 1024;
(void) setrlimit(RLIMIT_NOFILE, &rl); /* SCA */
}
while (nconf = getnetconfig(nc_handle)) {
init_transport(nconf);
}
endnetconfig(nc_handle);
if ((loopback_dg[0] == NULL) && (loopback_vc[0] == NULL) &&
(loopback_vc_ord[0] == NULL)) {
syslog(LOG_ERR, "could not find loopback transports");
exit(1);
}
(void) signal(SIGCHLD, SIG_IGN); /* XXX see reap below */
(void) signal(SIGINT, terminate);
if (warmstart) {
read_warmstart();
}
if (debugging) {
printf("rpcbind debugging enabled -- will abort on errors!\n");
} else {
detachfromtty();
}
my_svc_run();
syslog(LOG_ERR, "svc_run returned unexpectedly");
rpcbind_abort();
/* NOTREACHED */
}
#ifdef sgi
int
rpcb_setsockopt(
int fd,
int level,
int optname,
void *optval,
int optlen)
{
int retval;
struct t_optmgmt reqt;
struct {
struct opthdr hdr;
char optbytes[1000];
} buf;
buf.hdr.level = level;
buf.hdr.name = optname;
buf.hdr.len = optlen;
(void)memcpy(buf.optbytes, optval, optlen);
reqt.opt.maxlen = reqt.opt.len = sizeof buf.hdr + optlen;
reqt.opt.buf = (char *)&buf;
reqt.flags = T_NEGOTIATE;
retval = t_optmgmt(fd, &reqt, &reqt);
return retval;
}
void
add_mcast( int fd )
{
struct ip_mreq mreq;
mreq.imr_multiaddr.s_addr = htonl(PMAP_MULTICAST_INADDR);
mreq.imr_interface.s_addr = htonl(INADDR_ANY);
if (rpcb_setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
&mreq, sizeof mreq)) {
fprintf(stderr, "cannot enable multicast reception: %s\n",
t_errlist[t_errno]);
}
}
#endif
/*
* Adds the entry into the rpcbind database.
* If PORTMAP, then for UDP and TCP, it adds the entries for version 2 also
* Returns 0 if succeeds, else fails
*/
static int
init_transport(nconf)
struct netconfig *nconf; /* Transport provider info */
{
int fd;
struct t_bind *taddr, *baddr;
RPCBLIST *rbl;
SVCXPRT *my_xprt, *l_xprt;
struct nd_addrlist *nas;
struct nd_hostserv hs;
int status; /* bound checking ? */
if ((nconf->nc_semantics != NC_TPI_CLTS) &&
(nconf->nc_semantics != NC_TPI_COTS) &&
(nconf->nc_semantics != NC_TPI_COTS_ORD))
return (1); /* not my type */
if (verbose) {
int i;
char **s;
(void) fprintf(stderr, "%s: %d lookup routines :\n",
nconf->nc_netid, nconf->nc_nlookups);
for (i = 0, s = nconf->nc_lookups; i < nconf->nc_nlookups; i++, s++)
fprintf(stderr, "[%d] - %s\n", i, *s);
}
if ((fd = t_open(nconf->nc_device, O_RDWR, NULL)) < 0) {
syslog(LOG_ERR, "%s: cannot open connection: %s",
nconf->nc_netid, t_errlist[t_errno]);
return (1);
}
taddr = (struct t_bind *)t_alloc(fd, T_BIND, T_ADDR);
baddr = (struct t_bind *)t_alloc(fd, T_BIND, T_ADDR);
if ((baddr == NULL) || (taddr == NULL)) {
syslog(LOG_ERR, "%s: cannot allocate netbuf: %s",
nconf->nc_netid, t_errlist[t_errno]);
exit(1);
}
/* Get rpcbind's address on this transport */
hs.h_host = HOST_SELF;
hs.h_serv = servname;
if (0 != (status = netdir_getbyname(nconf, &hs, &nas))) {
if (verbose)
(void)fprintf(stderr,
"rpcbind : netdir_getbyname returned %d\n", status);
goto error;
}
/* Copy the address */
taddr->addr.len = nas->n_addrs->len;
memcpy(taddr->addr.buf, nas->n_addrs->buf, (int)nas->n_addrs->len);
if (verbose) {
/* for debugging print out our universal address */
char *uaddr;
uaddr = taddr2uaddr(nconf, nas->n_addrs);
(void) fprintf(stderr, "rpcbind : my address is %s\n", uaddr);
(void) free(uaddr);
}
netdir_free((char *)nas, ND_ADDRLIST);
if (nconf->nc_semantics == NC_TPI_CLTS)
taddr->qlen = 0;
else
taddr->qlen = 8; /* should be enough */
if (t_bind(fd, taddr, baddr) != 0) {
syslog(LOG_ERR, "%s: cannot bind: %s",
nconf->nc_netid, t_errlist[t_errno]);
goto error;
}
if (memcmp(taddr->addr.buf, baddr->addr.buf, (int)baddr->addr.len)) {
syslog(LOG_ERR, "%s: address in use", nconf->nc_netid);
goto error;
}
my_xprt = (SVCXPRT *)svc_tli_create(fd, nconf, baddr, 0, 0);
if (my_xprt == (SVCXPRT *)NULL) {
syslog(LOG_ERR, "%s: could not create service",
nconf->nc_netid);
goto error;
}
#ifdef PORTMAP
/*
* Register both the versions for tcp/ip and udp/ip
*/
if ((strcmp(nconf->nc_protofmly, NC_INET) == 0) &&
((strcmp(nconf->nc_proto, NC_TCP) == 0) ||
(strcmp(nconf->nc_proto, NC_UDP) == 0))) {
PMAPLIST *pml;
int lfd, on = 1, tcp = (strcmp(nconf->nc_proto, NC_TCP) == 0);
char laddr[32];
struct t_bind *ltaddr, *lbaddr;
struct netbuf *nb;
struct in_addr la = { htonl(INADDR_LOOPBACK) };
if (!svc_register(my_xprt, PMAPPROG, PMAPVERS,
pmap_service, NULL)) {
syslog(LOG_ERR, "could not register on %s",
nconf->nc_netid);
goto error;
}
pml = (PMAPLIST *)malloc((u_int)sizeof (PMAPLIST));
if (pml == (PMAPLIST *)NULL) {
syslog(LOG_ERR, "no memory!");
exit(1);
}
pml->pml_map.pm_prog = PMAPPROG;
pml->pml_map.pm_vers = PMAPVERS;
pml->pml_map.pm_port = PMAPPORT;
if (tcp) {
if (tcptrans[0]) {
syslog(LOG_ERR,
"cannot have more than one TCP transport");
goto error;
}
tcptrans = strdup(nconf->nc_netid);
pml->pml_map.pm_prot = IPPROTO_TCP;
/* Let's snarf the universal address */
/* "h1.h2.h3.h4.p1.p2" */
tcp_uaddr = taddr2uaddr(nconf, &baddr->addr);
} else {
if (udptrans[0]) {
syslog(LOG_ERR,
"cannot have more than one UDP transport");
goto error;
}
udptrans = strdup(nconf->nc_netid);
pml->pml_map.pm_prot = IPPROTO_UDP;
/* Let's snarf the universal address */
/* "h1.h2.h3.h4.p1.p2" */
udp_uaddr = taddr2uaddr(nconf, &baddr->addr);
#ifdef sgi
/*
* Listen to multicast.
*/
if (do_mcast) {
int mfd;
char maddr[15+8+1];
struct t_bind *mtaddr, *mbaddr;
struct in_addr ma = {PMAP_MULTICAST_INADDR};
if ((mfd = t_open(nconf->nc_device,
O_RDWR, NULL)) < 0) {
syslog(LOG_ERR,
"%s: cannot open multicast"
" connection: %s",
nconf->nc_netid,
t_errlist[t_errno]);
goto mcast_out;
}
mtaddr = (struct t_bind *)t_alloc(mfd, T_BIND,
T_ADDR);
mbaddr = (struct t_bind *)t_alloc(mfd, T_BIND,
T_ADDR);
sprintf(maddr, "%s.%u.%u", inet_ntoa(ma),
PMAPPORT>>8, PMAPPORT&0xff);
nb = uaddr2taddr(nconf, maddr);
memcpy(mtaddr->addr.buf, nb->buf,
mtaddr->addr.len = nb->len);
free(nb);
(void)rpcb_setsockopt(mfd,SOL_SOCKET,
SO_REUSEADDR,
&on, sizeof(on));
add_mcast(mfd);
if (t_bind(mfd, mtaddr, mbaddr) != 0) {
syslog(LOG_ERR,
"%s: cannot multicast bind: %s",
nconf->nc_netid,
t_errlist[t_errno]);
goto mcast_out;
}
m_xprt = (SVCXPRT *)svc_tli_create(mfd, nconf,
mbaddr,0,0);
if (m_xprt == 0) {
syslog(LOG_ERR, "%s: could not create"
" mulicast service",
nconf->nc_netid);
goto mcast_out;
}
if (!svc_register(m_xprt,PMAPPROG,PMAPVERS,
pmap_service, NULL)) {
syslog(LOG_ERR,
"could not register on %s",
nconf->nc_netid);
goto mcast_out;
}
/* version 3 registration */
if (!svc_reg(m_xprt, RPCBPROG, RPCBVERS,
rpcb_service, NULL)) {
syslog(LOG_ERR, "could not multicast"
" register %s version 3",
nconf->nc_netid);
goto mcast_out;
}
svc_versquiet(m_xprt);
mcast_out:
(void) t_free((char *)mtaddr, T_BIND);
(void) t_free((char *)mbaddr, T_BIND);
}
#endif
}
pml->pml_next = list_pml;
list_pml = pml;
/* Add version 3 information */
pml = (PMAPLIST *)malloc((u_int)sizeof (PMAPLIST));
if (pml == (PMAPLIST *)NULL) {
syslog(LOG_ERR, "no memory!");
exit(1);
}
pml->pml_map = list_pml->pml_map;
pml->pml_map.pm_vers = RPCBVERS;
pml->pml_next = list_pml;
list_pml = pml;
/* Also add version 2 stuff to rpcbind list */
rbl = (RPCBLIST *)malloc((u_int)sizeof (RPCBLIST));
if (rbl == (RPCBLIST *)NULL) {
syslog(LOG_ERR, "no memory!");
exit(1);
}
rbl->rpcb_map.r_prog = PMAPPROG;
rbl->rpcb_map.r_vers = PMAPVERS; /* Version 2 */
rbl->rpcb_map.r_netid = strdup(nconf->nc_netid);
rbl->rpcb_map.r_addr = taddr2uaddr(nconf, &baddr->addr);
rbl->rpcb_map.r_owner = superuser;
rbl->rpcb_next = list_rbl; /* Attach to global list */
list_rbl = rbl;
if ( Secure ) {
/* Create the udp/tcp loopback service port so we
identify connections that actually used the loopback
interface to connect vs those spoofing the loopback
source address. We exit on any failures because
we will not be able to set/unset portmap services
in pmap_service without these service ports defined */
if ((lfd = t_open(nconf->nc_device,O_RDWR,NULL)) <0) {
syslog(LOG_ERR,
"%s: cannot open loopback connection: %s",
nconf->nc_netid, t_errlist[t_errno]);
exit(1);
}
ltaddr = (struct t_bind *)t_alloc(lfd, T_BIND, T_ADDR);
lbaddr = (struct t_bind *)t_alloc(lfd, T_BIND, T_ADDR);
if (ltaddr == NULL || lbaddr == NULL) {
syslog(LOG_ERR,
"%s: cannot allocate local netbuf: %s",
nconf->nc_netid, t_errlist[t_errno]);
exit(1);
}
sprintf(laddr, "%s.%u.%u", inet_ntoa(la),
PMAPPORT>>8, PMAPPORT&0xff);
nb = uaddr2taddr(nconf, laddr);
memcpy(ltaddr->addr.buf, nb->buf,
ltaddr->addr.len = nb->len);
free(nb);
(void)rpcb_setsockopt(lfd, SOL_SOCKET, SO_REUSEADDR,
&on, sizeof(on));
if (t_bind(lfd, ltaddr, lbaddr) != 0) {
syslog(LOG_ERR, "%s: cannot loopback bind: %s",
nconf->nc_netid, t_errlist[t_errno]);
exit(1);
}
l_xprt = (SVCXPRT *)svc_tli_create(lfd, nconf, lbaddr,
0,0);
if (l_xprt == 0) {
syslog(LOG_ERR, "%s: could not create"
" loopback service", nconf->nc_netid);
exit(1);
}
if (!svc_register(l_xprt, PMAPPROG, PMAPVERS,
pmap_service, NULL)) {
syslog(LOG_ERR, "could not register loopback"
" pmap_service %s", nconf->nc_netid);
exit(1);
}
svc_versquiet(l_xprt);
if (tcp)
ltcp_xprt = l_xprt;
else
ludp_xprt = l_xprt;
(void) t_free((char *)ltaddr, T_BIND);
(void) t_free((char *)lbaddr, T_BIND);
}
}
#endif
/* version 3 registration */
if (!svc_reg(my_xprt, RPCBPROG, RPCBVERS, rpcb_service, NULL)) {
syslog(LOG_ERR, "could not register %s version 3",
nconf->nc_netid);
goto error;
}
rbl = (RPCBLIST *)malloc((u_int)sizeof (RPCBLIST));
if (rbl == (RPCBLIST *)NULL) {
syslog(LOG_ERR, "no memory!");
exit(1);
}
rbl->rpcb_map.r_prog = RPCBPROG;
rbl->rpcb_map.r_vers = RPCBVERS; /* The new version number */
rbl->rpcb_map.r_netid = strdup(nconf->nc_netid);
rbl->rpcb_map.r_addr = taddr2uaddr(nconf, &baddr->addr);
rbl->rpcb_map.r_owner = superuser;
rbl->rpcb_next = list_rbl; /* Attach to global list */
list_rbl = rbl;
/*
* Tell RPC library to shut up about version mismatches so that new
* revs of broadcast protocols don't cause all the old servers to
* say: "wrong version".
*/
svc_versquiet(my_xprt);
/*
* In case of loopback transports, negotiate for
* returning of the uid of the caller.
*/
if (strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) {
if (nconf->nc_semantics == NC_TPI_CLTS)
loopback_dg = strdup(nconf->nc_netid);
else if (nconf->nc_semantics == NC_TPI_COTS)
loopback_vc = strdup(nconf->nc_netid);
else if (nconf->nc_semantics == NC_TPI_COTS_ORD)
loopback_vc_ord = strdup(nconf->nc_netid);
if (_rpc_negotiate_uid(fd)) {
syslog(LOG_ERR,
"could not negotiate with loopback tranport %s",
nconf->nc_netid);
}
}
/* decide if bound checking works for this transport */
status = add_bndlist(nconf, taddr, baddr);
#ifdef BIND_DEBUG
if (status < 0) {
fprintf(stderr, "Error in finding bind status for %s\n",
nconf->nc_netid);
} else if (status == 0) {
fprintf(stderr, "check binding for %s\n",
nconf->nc_netid);
} else if (status > 0) {
fprintf(stderr, "No check binding for %s\n",
nconf->nc_netid);
}
#endif
(void) t_free((char *)taddr, T_BIND);
(void) t_free((char *)baddr, T_BIND);
return (0);
error:
(void) t_free((char *)taddr, T_BIND);
(void) t_free((char *)baddr, T_BIND);
(void) t_close(fd);
return (1);
}
/*
* XXX this should be fixed to reap our children rather than ignoring the
* signal like we do for now ...
*/
#ifdef WAIT3
static void
reap()
{
while (wait3(NULL, WNOHANG, NULL) > 0);
}
#endif
/*
* Catch the signal and die
*/
static void
terminate()
{
syslog(LOG_ERR, "terminating on signal");
write_warmstart(); /* Dump yourself */
exit(2);
}
void
rpcbind_abort()
{
write_warmstart(); /* Dump yourself */
abort();
}
/*
* detach from tty
*/
static void
detachfromtty()
{
close(0);
close(1);
close(2);
switch (fork()) {
case (pid_t)-1:
perror("fork");
break;
case 0:
break;
default:
exit(0);
}
setsid();
(void)open("/dev/null", O_RDWR, 0);
dup(0);
dup(0);
}
/* get command line options */
static void
parseargs(argc, argv)
int argc;
char *argv[];
#ifndef sgi
{
int c;
while ((c = getopt(argc, argv, "dwC")) != EOF) {
switch (c) {
case 'd':
debugging = 1;
break;
case 'w':
warmstart = 1;
break;
case 'C':
Secure = 0;
break;
default: /* error */
fprintf(stderr, "usage: rpcbind -[dwC]\n");
exit (1);
}
}
}
#else
{
int t;
int argerr = 0;
extern int optind, opterr;
extern char *optarg;
opterr = 0;
while ((t = getopt(argc, argv, "a:Abdf:mvwC")) != EOF) {
switch (t) {
case 'a': {
char *cp;
struct oknet n;
/*
* Option formats: "mask,match" or "network", where
* mask, match and network are valid IP address/network
* numbers. "network" is a shorthand for specifying the
* default mask and match appropriate for the
* network's address class.
*/
if (cp = strchr(optarg, ',')) {
*cp++ = '\0';
if (!inet_isaddr(optarg, &n.mask.s_addr)) {
fprintf(stderr,
"%s: illegal IP address for mask\n",
optarg);
argerr = 1;
break;
}
if (!inet_isaddr(cp, &n.match.s_addr)) {
fprintf(stderr,
"%s: illegal IP address for match\n",
cp);
argerr = 1;
break;
}
} else {
/*
* Treat arg as a network address,
* host part of address is ignored.
*/
if (!inet_isaddr(optarg, &n.match.s_addr)) {
fprintf(stderr,
"%s: illegal network address\n",
optarg);
argerr = 1;
break;
}
if (IN_CLASSA(n.match.s_addr))
n.mask.s_addr = IN_CLASSA_NET;
else if (IN_CLASSB(n.match.s_addr))
n.mask.s_addr = IN_CLASSB_NET;
else if (IN_CLASSC(n.match.s_addr))
n.mask.s_addr = IN_CLASSC_NET;
else {
fprintf(stderr,
"%s: illegal network address class\n",
optarg);
argerr = 1;
break;
}
n.match.s_addr &= n.mask.s_addr;
}
if (num_oknets < MAX_OKNETS)
oknets[num_oknets++] = n;
else
fprintf(stderr,
"too many nets, extra ignored\n");
break;
}
case 'A':
/*
* Trust all directly connected networks.
*/
Aflag = 1;
break;
case 'b':
/*
* Trust non-multicast including broadcast sources
* because we are behind a firewall.
*/
bflag = 1;
break;
/*
* NB: rpcbind doesn't presently fork for PMAPPROC_CALLIT
* so this option is ignored. It is parsed for command
* line compatibility with portmap.
*/
case 'f': {
int max = atoi(optarg);
if (max < 1) {
fprintf(stderr,
"%s: illegal value for fork limit, ignored\n",
optarg);
argerr = 1;
} else
max_forks = max;
break;
}
case 'm':
do_mcast = 1;
break;
case 'd':
debugging = 1;
/* fall thru */
case 'v':
verbose = 1;
break;
case 'w':
warmstart = 1;
break;
case 'C':
Secure = 0;
break;
default:
case '?':
fprintf(stderr,"unknown option: %s\n", argv[optind -1]);
argerr = 1;
break;
}
}
if (argerr) {
/* -d option just for testing, don't show it */
/* do not mention -f since it is not supported */
fprintf(stderr,
"usage: rpcbind [-vmAbwC] [-a mask,match | -a match]\n");
exit(1);
}
}
/*
* Return 1 if the address is accepted, 0 otherwise.
*/
int
chknet(struct in_addr addr)
{
register struct oknet *n;
register int i;
for (n = oknets, i = 0; i < num_oknets; n++, i++) {
if ((addr.s_addr & n->mask.s_addr) == n->match.s_addr)
return 1;
}
/*
* If it was not in the explicit list and if allowed, check
* the implicit list.
*/
if (Aflag) {
getlocal();
for (i = num_local, n = &addrs->a[0]; i != 0; i--, n++) {
if (0 == ((addr.s_addr ^ n->mask.s_addr)
& n->match.s_addr))
return 1;
}
}
return 0;
}
#endif /* sgi */