示例#1
0
/*
 * Get a copy of the current port maps.
 * Calls the pmap service remotely to do get the maps.
 */
struct pmaplist *
pmap_getmaps(struct sockaddr_in *address)
{
	struct pmaplist *head = NULL;
	int socket = -1;
	struct timeval minutetimeout;
	CLIENT *client;

	minutetimeout.tv_sec = 60;
	minutetimeout.tv_usec = 0;
	address->sin_port = htons(PMAPPORT);
	client = clnttcp_create(address, PMAPPROG,
	    PMAPVERS, &socket, 50, 500);
	if (client != NULL) {
		if (CLNT_CALL(client, (rpcproc_t)PMAPPROC_DUMP, 
		    (xdrproc_t)xdr_void, NULL,
		    (xdrproc_t)xdr_pmaplist, &head, minutetimeout) !=
		    RPC_SUCCESS) {
			clnt_perror(client, "pmap_getmaps rpc problem");
		}
		CLNT_DESTROY(client);
	}
	if (socket != -1)
		(void)_RPC_close(socket);
	address->sin_port = 0;
	return (head);
}
示例#2
0
static void
clnttcp_destroy(
	CLIENT *h)
{
	struct ct_data *ct =
	    (struct ct_data *) h->cl_private;

	if (ct->ct_closeit) {
		(void)_RPC_close(ct->ct_sock);
	}
	XDR_DESTROY(&(ct->ct_xdrs));
	mem_free(ct, sizeof(struct ct_data));
	mem_free(h, sizeof(CLIENT));
}
示例#3
0
/*
 * Find the mapped port for program,version.
 * Calls the pmap service remotely to do the lookup.
 * Returns 0 if no map exists.
 */
u_short
pmap_getport(
	struct sockaddr_in *address,
	u_long program,
	u_long version,
	u_int protocol )
{
	u_short port = 0;
	int socket = -1;
	CLIENT *client;
	struct pmap parms;

	address->sin_port = htons(PMAPPORT);
	client = clntudp_bufcreate(address, PMAPPROG,
	    PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE);
	if (client != NULL) {
		parms.pm_prog = program;
		parms.pm_vers = version;
		parms.pm_prot = protocol;
		parms.pm_port = 0;  /* not needed or used */
		if (CLNT_CALL(client, (rpcproc_t)PMAPPROC_GETPORT,
		    (xdrproc_t)xdr_pmap,
		    &parms, (xdrproc_t)xdr_u_short, &port, tottimeout) !=
		    RPC_SUCCESS){
			rpc_createerr.cf_stat = RPC_PMAPFAILURE;
			clnt_geterr(client, &rpc_createerr.cf_error);
		} else if (port == 0) {
			rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
		}
		CLNT_DESTROY(client);
	}
	if (socket != -1)
		(void)_RPC_close(socket);
	address->sin_port = 0;
	return (port);
}
示例#4
0
/*
 * Create a client handle for a tcp/ip connection.
 * If *sockp<0, *sockp is set to a newly created TCP socket and it is
 * connected to raddr.  If *sockp non-negative then
 * raddr is ignored.  The rpc/tcp package does buffering
 * similar to stdio, so the client must pick send and receive buffer sizes,];
 * 0 => use the default.
 * If raddr->sin_port is 0, then a binder on the remote machine is
 * consulted for the right port number.
 * NB: *sockp is copied into a private area.
 * NB: It is the clients responsibility to close *sockp.
 * NB: The rpch->cl_auth is set null authentication.  Caller may wish to set this
 * something more useful.
 */
CLIENT *
clnttcp_create(
	struct sockaddr_in *raddr,
	u_long prog,		/* program number */
	u_long vers,		/* version number */
	int *sockp,
	u_int sendsz,
	u_int recvsz)
{
	CLIENT *h;
	struct ct_data *ct = NULL;	/* client handle */
	struct timeval now;
	struct rpc_msg call_msg;
	static uintptr_t disrupt;

	if (disrupt == 0)
		disrupt = (uintptr_t)raddr;

	h  = (CLIENT *)mem_alloc(sizeof(*h));
	if (h == NULL) {
		(void)fprintf(stderr, "clnttcp_create: out of memory\n");
		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
		rpc_createerr.cf_error.re_errno = errno;
		goto fooy;
	}
	ct = (struct ct_data *)mem_alloc(sizeof (*ct));
	if (ct == NULL) {
		(void)fprintf(stderr, "clnttcp_create: out of memory\n");
		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
		rpc_createerr.cf_error.re_errno = errno;
		goto fooy;
	}

	/*
	 * If no port number given ask the pmap for one
	 */
	if (raddr->sin_port == 0) {
		u_short port;
		if ((port = pmap_getport(raddr, prog, vers, IPPROTO_TCP)) == 0) {
			mem_free((caddr_t)ct, sizeof(struct ct_data));
			mem_free((caddr_t)h, sizeof(CLIENT));
			return ((CLIENT *)NULL);
		}
		raddr->sin_port = htons(port);
	}

	/*
	 * If no socket given, open one
	 */
	if (*sockp < 0) {
		*sockp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
		(void)bindresvport(*sockp, (struct sockaddr_in *)0);
		if ((*sockp < 0)
		    || (connect(*sockp, (struct sockaddr *)raddr,
		    sizeof(*raddr)) < 0)) {
			rpc_createerr.cf_stat = RPC_SYSTEMERROR;
			rpc_createerr.cf_error.re_errno = errno;
			if (*sockp != -1)
				(void)_RPC_close(*sockp);
			goto fooy;
		}
		ct->ct_closeit = TRUE;
	} else {
		ct->ct_closeit = FALSE;
	}

	/*
	 * Set up private data struct
	 */
	ct->ct_sock = *sockp;
	ct->ct_wait.tv_usec = 0;
	ct->ct_waitset = FALSE;
	ct->ct_addr = *raddr;

	/*
	 * Initialize call message
	 */
	(void)gettimeofday(&now, (struct timezone *)0);
	call_msg.rm_xid = (++disrupt) ^ getpid() ^ now.tv_sec ^ now.tv_usec;
	call_msg.rm_direction = CALL;
	call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION;
	call_msg.rm_call.cb_prog = prog;
	call_msg.rm_call.cb_vers = vers;

	/*
	 * pre-serialize the static part of the call msg and stash it away
	 */
	xdrmem_create(&(ct->ct_xdrs), ct->ct_u.ct_mcallc, MCALL_MSG_SIZE,
	    XDR_ENCODE);
	if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) {
		if (ct->ct_closeit) {
			(void)_RPC_close(*sockp);
		}
		goto fooy;
	}
	ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs));
	XDR_DESTROY(&(ct->ct_xdrs));

	/*
	 * Create a client handle which uses xdrrec for serialization
	 * and authnone for authentication.
	 */
	xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz,
	    (caddr_t)ct, readtcp, writetcp);
	h->cl_ops = &tcp_ops;
	h->cl_private = (caddr_t) ct;
	h->cl_auth = authnone_create();
	return (h);

fooy:
	/*
	 * Something goofed, free stuff and barf
	 */
	if (ct)
		mem_free((caddr_t)ct, sizeof(struct ct_data));
	if (h)
		mem_free((caddr_t)h, sizeof(CLIENT));
	return ((CLIENT *)NULL);
}
示例#5
0
/*
 * don't use gethostbyname, which would invoke yellow pages
 *
 * Avoid loopback interfaces.  We return information from a loopback
 * interface only if there are no other possible interfaces.
 */
int
get_myaddress(
	struct sockaddr_in *addr)
{
	int s;
	struct ifconf ifc;
	struct ifreq ifreq, *ifr;
	int loopback = 0, gotit = 0;

	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		return(-1);
	}
again:
	ifc.ifc_len = sizeof ( struct ifreq ) * 8u;
	ifc.ifc_buf = malloc ( ifc.ifc_len );
  if ( ! ifc.ifc_buf ) {
		_RPC_close(s);
    return -1;
  }
	if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) {
		_RPC_close(s);
    free ( ifc.ifc_buf );
		return(-1);
	}
	ifr = ifc.ifc_req;

	while ( ifc.ifc_len >= ifreqSize ( ifr ) ) {
    ifreq = *ifr;
		if (ioctl(s, SIOCGIFFLAGS, (char *) &ifreq ) < 0) {
			_RPC_close(s);
      free ( ifc.ifc_buf );
			return(-1);
		}
		if (((ifreq.ifr_flags & IFF_UP) &&
		    ifr->ifr_addr.sa_family == AF_INET &&
			!(ifreq.ifr_flags & IFF_LOOPBACK)) ||
		    (loopback == 1 && (ifreq.ifr_flags & IFF_LOOPBACK)
			&& (ifr->ifr_addr.sa_family == AF_INET)
			&& (ifreq.ifr_flags &  IFF_UP))) {
			*addr = *((struct sockaddr_in *)&ifr->ifr_addr);
			addr->sin_port = htons(PMAPPORT);
			gotit = 1;
			break;
		}

    const size_t len = ifreqSize ( ifr );
    ifc.ifc_len -= len;
    /* 
     * RTEMS seems to require copy up to properly aligned 
     * boundary at the beginning of the buffer?
     */
    memmove ( ifr, len + (char *) ifr, ifc.ifc_len );
	}
	if (gotit == 0 && loopback == 0) {
    free ( ifc.ifc_buf );
		loopback = 1;
		goto again;
	}
	(void)_RPC_close(s);
  free ( ifc.ifc_buf );
	return (gotit ? 0 : -1);
}
示例#6
0
int
callrpc(
	char *host,
	int prognum, int versnum, int procnum,
	xdrproc_t inproc, char *in,
	xdrproc_t outproc, char *out )
{
	register struct call_rpc_private *crp = callrpc_private;
	struct sockaddr_in server_addr;
	enum clnt_stat clnt_stat;
	struct hostent *hp;
	struct timeval timeout, tottimeout;

	if (crp == 0) {
		crp = (struct call_rpc_private *)calloc(1, sizeof (*crp));
		if (crp == 0)
			return (0);
		callrpc_private = crp;
	}
	if (crp->oldhost == NULL) {
		crp->oldhost = malloc(MAXHOSTNAMELEN);
		crp->oldhost[0] = 0;
		crp->socket = RPC_ANYSOCK;
	}
	if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum
		&& strcmp(crp->oldhost, host) == 0) {
		/* reuse old client */
	} else {
		crp->valid = 0;
		if (crp->socket != -1)
			(void)_RPC_close(crp->socket);
		crp->socket = RPC_ANYSOCK;
		if (crp->client) {
			clnt_destroy(crp->client);
			crp->client = NULL;
		}
		if ((hp = gethostbyname(host)) == NULL)
			return ((int) RPC_UNKNOWNHOST);
		timeout.tv_usec = 0;
		timeout.tv_sec = 5;
		memset(&server_addr, 0, sizeof(server_addr));
		memcpy((char *)&server_addr.sin_addr, hp->h_addr, hp->h_length);
		server_addr.sin_len = sizeof(struct sockaddr_in);
		server_addr.sin_family = AF_INET;
		server_addr.sin_port =  0;
		if ((crp->client = clntudp_create(&server_addr, (u_long)prognum,
		    (u_long)versnum, timeout, &crp->socket)) == NULL)
			return ((int) rpc_createerr.cf_stat);
		crp->valid = 1;
		crp->oldprognum = prognum;
		crp->oldversnum = versnum;
		(void) strcpy(crp->oldhost, host);
	}
	tottimeout.tv_sec = 25;
	tottimeout.tv_usec = 0;
	clnt_stat = clnt_call(crp->client, procnum, inproc, in,
	    outproc, out, tottimeout);
	/*
	 * if call failed, empty cache
	 */
	if (clnt_stat != RPC_SUCCESS)
		crp->valid = 0;
	return ((int) clnt_stat);
}