Пример #1
0
/*
 * Request a port number from the port mapper.
 * Returns the port in host order.
 */
int
rpc_getport(struct iodesc *d, n_long prog, n_long vers)
{
	struct args {
		n_long	prog;		/* call program */
		n_long	vers;		/* call version */
		n_long	proto;		/* call protocol */
		n_long	port;		/* call port (unused) */
	} *args;
	struct res {
		n_long port;
	} *res;
	struct {
		n_long	h[RPC_HEADER_WORDS];
		struct args d;
	} sdata;
	struct {
		n_long	h[RPC_HEADER_WORDS];
		struct res d;
		n_long  pad;
	} rdata;
	ssize_t cc;
	int port;

#ifdef RPC_DEBUG
	if (debug)
		printf("getport: prog=0x%x vers=%d\n", prog, vers);
#endif

	/* This one is fixed forever. */
	if (prog == PMAPPROG)
		return (PMAPPORT);

	/* Try for cached answer first */
	port = rpc_pmap_getcache(d->destip, prog, vers);
	if (port != -1)
		return (port);

	args = &sdata.d;
	args->prog = htonl(prog);
	args->vers = htonl(vers);
	args->proto = htonl(IPPROTO_UDP);
	args->port = 0;
	res = &rdata.d;

	cc = rpc_call(d, PMAPPROG, PMAPVERS, PMAPPROC_GETPORT,
		args, sizeof(*args), res, sizeof(*res));
	if (cc < 0 || (size_t)cc < sizeof(*res)) {
		printf("getport: %s", strerror(errno));
		errno = EBADRPC;
		return (-1);
	}
	port = (int)ntohl(res->port);

	rpc_pmap_putcache(d->destip, prog, vers, port);

	return (port);
}
Пример #2
0
/*
 * RPC: bootparam/whoami
 * Given client IP address, get:
 *	client name	(hostname)
 *	domain name (domainname)
 *	gateway address
 *
 * The hostname and domainname are set here for convenience.
 *
 * Note - bpsin is initialized to the broadcast address,
 * and will be replaced with the bootparam server address
 * after this call is complete.  Have to use PMAP_PROC_CALL
 * to make sure we get responses only from a servers that
 * know about us (don't want to broadcast a getport call).
 */
int
bp_whoami(int sockfd)
{
	/* RPC structures for PMAPPROC_CALLIT */
	struct args {
		u_int32_t prog;
		u_int32_t vers;
		u_int32_t proc;
		u_int32_t arglen;
		struct xdr_inaddr xina;
	} *args;
	struct repl {
		u_int16_t _pad;
		u_int16_t port;
		u_int32_t encap_len;
		/* encapsulated data here */
		n_long  capsule[64];
	} *repl;
	struct {
		n_long	h[RPC_HEADER_WORDS];
		struct args d;
	} sdata;
	struct {
		n_long	h[RPC_HEADER_WORDS];
		struct repl d;
	} rdata;
	char *send_tail, *recv_head;
	struct iodesc *d;
	int len, x;

	RPC_PRINTF(("bp_whoami: myip=%s\n", inet_ntoa(myip)));

	if (!(d = socktodesc(sockfd))) {
		RPC_PRINTF(("bp_whoami: bad socket. %d\n", sockfd));
		return (-1);
	}
	args = &sdata.d;
	repl = &rdata.d;

	/*
	 * Build request args for PMAPPROC_CALLIT.
	 */
	args->prog = htonl(BOOTPARAM_PROG);
	args->vers = htonl(BOOTPARAM_VERS);
	args->proc = htonl(BOOTPARAM_WHOAMI);
	args->arglen = htonl(sizeof(struct xdr_inaddr));
	send_tail = (char *)&args->xina;

	/*
	 * append encapsulated data (client IP address)
	 */
	if (xdr_inaddr_encode(&send_tail, myip))
		return (-1);

	/* RPC: portmap/callit */
	d->myport = htons(--rpc_port);
	d->destip.s_addr = INADDR_BROADCAST;	/* XXX: subnet bcast? */
	/* rpc_call will set d->destport */

	len = rpc_call(d, PMAPPROG, PMAPVERS, PMAPPROC_CALLIT,
	    args, send_tail - (char *)args,
	    repl, sizeof(*repl));
	if (len < 8) {
		printf("bootparamd: 'whoami' call failed\n");
		return (-1);
	}

	/* Save bootparam server address (from IP header). */
	rpc_fromaddr(repl, &bp_server_addr, &bp_server_port);

	/*
	 * Note that bp_server_port is now 111 due to the
	 * indirect call (using PMAPPROC_CALLIT), so get the
	 * actual port number from the reply data.
	 */
	bp_server_port = repl->port;

	RPC_PRINTF(("bp_whoami: server at %s:%d\n",
	    inet_ntoa(bp_server_addr), ntohs(bp_server_port)));

	/* We have just done a portmap call, so cache the portnum. */
	rpc_pmap_putcache(bp_server_addr, BOOTPARAM_PROG, BOOTPARAM_VERS,
	    (int)ntohs(bp_server_port));

	/*
	 * Parse the encapsulated results from bootparam/whoami
	 */
	x = ntohl(repl->encap_len);
	if (len < x) {
		printf("bp_whoami: short reply, %d < %d\n", len, x);
		return (-1);
	}
	recv_head = (char *)repl->capsule;

	/* client name */
	hostnamelen = MAXHOSTNAMELEN-1;
	if (xdr_string_decode(&recv_head, hostname, &hostnamelen)) {
		RPC_PRINTF(("bp_whoami: bad hostname\n"));
		return (-1);
	}

	/* domain name */
	domainnamelen = MAXHOSTNAMELEN-1;
	if (xdr_string_decode(&recv_head, domainname, &domainnamelen)) {
		RPC_PRINTF(("bp_whoami: bad domainname\n"));
		return (-1);
	}

	/* gateway address */
	if (xdr_inaddr_decode(&recv_head, &gateip)) {
		RPC_PRINTF(("bp_whoami: bad gateway\n"));
		return (-1);
	}

	/* success */
	return(0);
}