/* * Create an rpc client attached to the mount daemon. */ CLIENT * get_mount_client(char *host, struct sockaddr_in *unused_sin, struct timeval *tv, int *sock, u_long mnt_version) { CLIENT *client; struct netbuf nb; struct netconfig *nc = NULL; struct sockaddr_in sin; nb.maxlen = sizeof(sin); nb.buf = (char *) &sin; /* * First try a TCP handler */ /* * Find mountd address on TCP */ if ((nc = getnetconfigent(NC_TCP)) == NULL) { plog(XLOG_ERROR, "getnetconfig for tcp failed: %s", nc_sperror()); goto tryudp; } if (!rpcb_getaddr(MOUNTPROG, mnt_version, nc, &nb, host)) { /* * don't print error messages here, since mountd might legitimately * serve udp only */ goto tryudp; } /* * Create privileged TCP socket */ *sock = t_open(nc->nc_device, O_RDWR, 0); if (*sock < 0) { plog(XLOG_ERROR, "t_open %s: %m", nc->nc_device); goto tryudp; } if (bind_resv_port(*sock, (u_short *) NULL) < 0) plog(XLOG_ERROR, "couldn't bind mountd socket to privileged port"); if ((client = clnt_vc_create(*sock, &nb, MOUNTPROG, mnt_version, 0, 0)) == (CLIENT *) NULL) { plog(XLOG_ERROR, "clnt_vc_create failed"); t_close(*sock); goto tryudp; } /* tcp succeeded */ dlog("get_mount_client: using tcp, port %d", sin.sin_port); if (nc) freenetconfigent(nc); return client; tryudp: /* first free possibly previously allocated netconfig entry */ if (nc) freenetconfigent(nc); /* * TCP failed so try UDP */ /* * Find mountd address on UDP */ if ((nc = getnetconfigent(NC_UDP)) == NULL) { plog(XLOG_ERROR, "getnetconfig for udp failed: %s", nc_sperror()); goto badout; } if (!rpcb_getaddr(MOUNTPROG, mnt_version, nc, &nb, host)) { plog(XLOG_ERROR, "%s", clnt_spcreateerror("couldn't get mountd address on udp")); goto badout; } /* * Create privileged UDP socket */ *sock = t_open(nc->nc_device, O_RDWR, 0); if (*sock < 0) { plog(XLOG_ERROR, "t_open %s: %m", nc->nc_device); goto badout; /* neither tcp not udp succeeded */ } if (bind_resv_port(*sock, (u_short *) NULL) < 0) plog(XLOG_ERROR, "couldn't bind mountd socket to privileged port"); if ((client = clnt_dg_create(*sock, &nb, MOUNTPROG, mnt_version, 0, 0)) == (CLIENT *) NULL) { plog(XLOG_ERROR, "clnt_dg_create failed"); t_close(*sock); goto badout; /* neither tcp not udp succeeded */ } if (clnt_control(client, CLSET_RETRY_TIMEOUT, (char *) tv) == FALSE) { plog(XLOG_ERROR, "clnt_control CLSET_RETRY_TIMEOUT for udp failed"); clnt_destroy(client); goto badout; /* neither tcp not udp succeeded */ } /* udp succeeded */ dlog("get_mount_client: using udp, port %d", sin.sin_port); return client; badout: /* failed */ if (nc) freenetconfigent(nc); return NULL; }
int rpcclt_initialize(rpcclt_t * client, const char *host, unsigned long prog, unsigned long vers, unsigned int sendsz, unsigned int recvsz, uint32_t port_num, struct timeval timeout) { int status = -1; struct sockaddr_in server; struct hostent *hp; int one = 1; int port = 0; DEBUG_FUNCTION; if (client->sock >= 0) { /* ** socket reference should be set to -1 at initialization or when released ** if rpcclt_initialize is called with socket not set to -1 we may be loosing ** a socket */ warning("rpcclt_initialize - dest %s:%d - prg 0x%8.8x - socket %d may be lost", host,port_num,(unsigned int)prog,client->sock); } client->client = 0; client->sock = -1; server.sin_family = AF_INET; if ((hp = gethostbyname(host)) == 0) { severe("gethostbyname failed for host : %s, %s", host, strerror(errno)); goto out; } bcopy((char *) hp->h_addr, (char *) &server.sin_addr, hp->h_length); if (port_num == 0) { if ((port = pmap_getport(&server, prog, vers, IPPROTO_TCP)) == 0) { warning("pmap_getport failed%s", clnt_spcreateerror("")); errno = EPROTO; goto out; } server.sin_port = htons(port); } else { server.sin_port = htons(port_num); } if ((client->sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { goto out; } // Allows other sockets to bind() to this port, unless there is an active // listening socket bound to the port already. if (setsockopt (client->sock, SOL_SOCKET, SO_REUSEADDR, (char *) &one, sizeof (int)) < 0) { goto out; } // Set a timeout value for output operations if (setsockopt (client->sock, SOL_SOCKET, SO_SNDTIMEO, (char *) &timeout, sizeof (timeout)) < 0) { goto out; } // This option specifies what should happen when the socket // of a type that promises reliable delivery still has untransmitted // messages when it is closed struct linger linger; linger.l_onoff = 1; //0 = off (l_linger ignored), nonzero = on linger.l_linger = 0; //0 = discard data, nonzero = wait for data sent if (setsockopt (client->sock, SOL_SOCKET, SO_LINGER, &linger, sizeof (linger)) < 0) { goto out; } // If set, disable the Nagle algorithm. This means that segments are always // sent as soon as possible, even if there is only a small amount of data. if (setsockopt (client->sock, SOL_TCP, TCP_NODELAY, (char *) &one, sizeof (int)) < 0) { goto out; } if ((client->sock < 0) || (connect(client->sock, (struct sockaddr *) &server, sizeof (server)) < 0)) { status = -1; goto out; } if ((client->client = clnttcp_create(&server, prog, vers, &client->sock, sendsz, recvsz)) == NULL) { errno = EPROTO; goto out; } // Set TIMEOUT for this connection clnt_control(client->client, CLSET_TIMEOUT, (char *) &timeout); status = 0; out: if (status != 0) rpcclt_release(client); return status; }
static int yppasswd_remote(ypclnt_t *ypclnt, const struct passwd *pwd, const char *passwd) { struct yppasswd yppwd; struct rpc_err rpcerr; CLIENT *clnt = NULL; int ret, *result; /* fill the yppasswd structure */ memset(&yppwd, 0, sizeof yppwd); yppwd.newpw.pw_uid = pwd->pw_uid; yppwd.newpw.pw_gid = pwd->pw_gid; if ((yppwd.newpw.pw_name = strdup(pwd->pw_name)) == NULL || (yppwd.newpw.pw_passwd = strdup(pwd->pw_passwd)) == NULL || (yppwd.newpw.pw_gecos = strdup(pwd->pw_gecos)) == NULL || (yppwd.newpw.pw_dir = strdup(pwd->pw_dir)) == NULL || (yppwd.newpw.pw_shell = strdup(pwd->pw_shell)) == NULL || (yppwd.oldpass = strdup(passwd ? passwd : "")) == NULL) { ypclnt_error(ypclnt, __func__, "%s", strerror(errno)); ret = -1; goto done; } /* connect to rpc.yppasswdd */ clnt = clnt_create(ypclnt->server, YPPASSWDPROG, YPPASSWDVERS, "udp"); if (clnt == NULL) { ypclnt_error(ypclnt, __func__, "failed to connect to rpc.yppasswdd: %s", clnt_spcreateerror(ypclnt->server)); ret = -1; goto done; } clnt->cl_auth = authunix_create_default(); /* request the update */ result = yppasswdproc_update_1(&yppwd, clnt); /* check for RPC errors */ clnt_geterr(clnt, &rpcerr); if (rpcerr.re_status != RPC_SUCCESS) { ypclnt_error(ypclnt, __func__, "NIS password update failed: %s", clnt_sperror(clnt, ypclnt->server)); ret = -1; goto done; } /* check the result of the update */ if (result == NULL || *result != 0) { ypclnt_error(ypclnt, __func__, "NIS password update failed"); /* XXX how do we get more details? */ ret = -1; goto done; } ypclnt_error(ypclnt, NULL, NULL); ret = 0; done: if (clnt != NULL) { auth_destroy(clnt->cl_auth); clnt_destroy(clnt); } free(yppwd.newpw.pw_name); if (yppwd.newpw.pw_passwd != NULL) { memset(yppwd.newpw.pw_passwd, 0, strlen(yppwd.newpw.pw_passwd)); free(yppwd.newpw.pw_passwd); } free(yppwd.newpw.pw_gecos); free(yppwd.newpw.pw_dir); free(yppwd.newpw.pw_shell); if (yppwd.oldpass != NULL) { memset(yppwd.oldpass, 0, strlen(yppwd.oldpass)); free(yppwd.oldpass); } return (ret); }
void clnt_pcreateerror(char *s) { (void) fprintf(stderr,"%s",clnt_spcreateerror(s)); }
int main (int argc, char *argv[]) { int err; nfs_fh3 fh; size_t length; char *fh_v; char *svraddr = NULL; CLIENT *p_clntp = NULL; char *fpath =NULL; struct hsfs_inode root; struct hsfs_super super; struct statvfs stbuf; root.sb = &super; char *cliname = basename (argv[0]); if (argc <3){ err = EINVAL; fprintf(stderr, "%s $svraddr $fpath.\n", cliname); goto exit; } svraddr = argv[1]; fpath = argv[2]; p_clntp = clnt_create(svraddr, NFS_PROGRAM, NFS_V3,"udp"); if (NULL == p_clntp){ fprintf(stderr, "%s: Create handle to RPC server"\ "(%s, %u, %u) failed: (%s).\n",cliname, svraddr, NFSPROC3_FSSTAT, NFS_V3,clnt_spcreateerror(cliname)); err = ENXIO; goto exit; } err = map_path_to_nfs3fh (svraddr, fpath, &length, &fh_v); if (err!= 0){ printf("map_path_to_nfs3fh failed! err:%d\n",err); goto exit; } memset (&fh,0,sizeof(fh)); fh.data.data_len=length; fh.data.data_val=fh_v; root.fh = fh; super.clntp = p_clntp; err = hsi_nfs3_statfs(&root); if (err){ printf("hsi_nfs3_statfs failed! err:%d\n",err); goto exit; } printf ("\ttbytes=%u\n\tfbytes=%u\n\tabytes=%u\n\ttfiles=%u\n\tffiles=%u\n\tafiles=%u\n", root.sb->tbytes,root.sb->fbytes,root.sb->abytes,root.sb->tfiles,root.sb->ffiles,root.sb->afiles); err = hsi_super2statvfs (root.sb, &stbuf); if (err){ goto exit; } printf ("\tf_bsize=%u\n\tf_frsize=%u\n\tf_blocks=%u\n\tf_bfree=%u\n\tf_bavail=%u\n\tf_files=%u\n", stbuf.f_bsize,stbuf.f_frsize,stbuf.f_blocks,stbuf.f_bfree,stbuf.f_bavail,stbuf.f_files); printf ("\tf_ffree=%u\n\tf_favail=%u\n\tf_fsid=%u\n\tf_flag=%u\n\tf_namemax=%u\n", stbuf.f_ffree,stbuf.f_favail,stbuf.f_fsid,stbuf.f_flag,stbuf.f_namemax); exit: exit (err); }
static int yppasswd_local(ypclnt_t *ypclnt, const struct passwd *pwd) { struct master_yppasswd yppwd; struct rpc_err rpcerr; struct netconfig *nc = NULL; void *localhandle = NULL; CLIENT *clnt = NULL; int ret, *result; /* fill the master_yppasswd structure */ memset(&yppwd, 0, sizeof yppwd); yppwd.newpw.pw_uid = pwd->pw_uid; yppwd.newpw.pw_gid = pwd->pw_gid; yppwd.newpw.pw_change = pwd->pw_change; yppwd.newpw.pw_expire = pwd->pw_expire; yppwd.newpw.pw_fields = pwd->pw_fields; yppwd.oldpass = strdup(""); yppwd.domain = strdup(ypclnt->domain); if ((yppwd.newpw.pw_name = strdup(pwd->pw_name)) == NULL || (yppwd.newpw.pw_passwd = strdup(pwd->pw_passwd)) == NULL || (yppwd.newpw.pw_class = strdup(pwd->pw_class)) == NULL || (yppwd.newpw.pw_gecos = strdup(pwd->pw_gecos)) == NULL || (yppwd.newpw.pw_dir = strdup(pwd->pw_dir)) == NULL || (yppwd.newpw.pw_shell = strdup(pwd->pw_shell)) == NULL) { ypclnt_error(ypclnt, __func__, "%s", strerror(errno)); ret = -1; goto done; } /* connect to rpc.yppasswdd */ localhandle = setnetconfig(); while ((nc = getnetconfig(localhandle)) != NULL) { if (nc->nc_protofmly != NULL && strcmp(nc->nc_protofmly, NC_LOOPBACK) == 0) break; } if (nc == NULL) { ypclnt_error(ypclnt, __func__, "getnetconfig: %s", nc_sperror()); ret = -1; goto done; } if ((clnt = clnt_tp_create(NULL, MASTER_YPPASSWDPROG, MASTER_YPPASSWDVERS, nc)) == NULL) { ypclnt_error(ypclnt, __func__, "failed to connect to rpc.yppasswdd: %s", clnt_spcreateerror(ypclnt->server)); ret = -1; goto done; } clnt->cl_auth = authunix_create_default(); /* request the update */ result = yppasswdproc_update_master_1(&yppwd, clnt); /* check for RPC errors */ clnt_geterr(clnt, &rpcerr); if (rpcerr.re_status != RPC_SUCCESS) { ypclnt_error(ypclnt, __func__, "NIS password update failed: %s", clnt_sperror(clnt, ypclnt->server)); ret = -1; goto done; } /* check the result of the update */ if (result == NULL || *result != 0) { ypclnt_error(ypclnt, __func__, "NIS password update failed"); /* XXX how do we get more details? */ ret = -1; goto done; } ypclnt_error(ypclnt, NULL, NULL); ret = 0; done: if (clnt != NULL) { auth_destroy(clnt->cl_auth); clnt_destroy(clnt); } endnetconfig(localhandle); free(yppwd.newpw.pw_name); if (yppwd.newpw.pw_passwd != NULL) { memset(yppwd.newpw.pw_passwd, 0, strlen(yppwd.newpw.pw_passwd)); free(yppwd.newpw.pw_passwd); } free(yppwd.newpw.pw_class); free(yppwd.newpw.pw_gecos); free(yppwd.newpw.pw_dir); free(yppwd.newpw.pw_shell); if (yppwd.oldpass != NULL) { memset(yppwd.oldpass, 0, strlen(yppwd.oldpass)); free(yppwd.oldpass); } return (ret); }
/* * Create an RPC connection and establish an authenticated * gss context with a server. */ static int create_auth_rpc_client(struct clnt_info *clp, char *tgtname, CLIENT **clnt_return, AUTH **auth_return, uid_t uid, int authtype, gss_cred_id_t cred) { CLIENT *rpc_clnt = NULL; struct rpc_gss_sec sec; AUTH *auth = NULL; int retval = -1; OM_uint32 min_stat; char rpc_errmsg[1024]; int protocol; struct timeval timeout; struct sockaddr *addr = (struct sockaddr *) &clp->addr; socklen_t salen; sec.qop = GSS_C_QOP_DEFAULT; sec.svc = RPCSEC_GSS_SVC_NONE; sec.cred = cred; sec.req_flags = 0; if (authtype == AUTHTYPE_KRB5) { sec.mech = (gss_OID)&krb5oid; sec.req_flags = GSS_C_MUTUAL_FLAG; } else { printerr(0, "ERROR: Invalid authentication type (%d) " "in create_auth_rpc_client\n", authtype); goto out_fail; } if (authtype == AUTHTYPE_KRB5) { #ifdef HAVE_SET_ALLOWABLE_ENCTYPES /* * Do this before creating rpc connection since we won't need * rpc connection if it fails! */ if (limit_krb5_enctypes(&sec)) { printerr(1, "WARNING: Failed while limiting krb5 " "encryption types for user with uid %d\n", uid); goto out_fail; } #endif } /* create an rpc connection to the nfs server */ printerr(2, "creating %s client for server %s\n", clp->protocol, clp->servername); protocol = IPPROTO_TCP; if ((strcmp(clp->protocol, "udp")) == 0) protocol = IPPROTO_UDP; switch (addr->sa_family) { case AF_INET: salen = sizeof(struct sockaddr_in); break; #ifdef IPV6_SUPPORTED case AF_INET6: salen = sizeof(struct sockaddr_in6); break; #endif /* IPV6_SUPPORTED */ default: printerr(1, "ERROR: Unknown address family %d\n", addr->sa_family); goto out_fail; } if (!populate_port(addr, salen, clp->prog, clp->vers, protocol)) goto out_fail; /* set the timeout according to the requested valued */ timeout.tv_sec = (long) rpc_timeout; timeout.tv_usec = (long) 0; rpc_clnt = nfs_get_rpcclient(addr, salen, protocol, clp->prog, clp->vers, &timeout); if (!rpc_clnt) { snprintf(rpc_errmsg, sizeof(rpc_errmsg), "WARNING: can't create %s rpc_clnt to server %s for " "user with uid %d", protocol == IPPROTO_TCP ? "tcp" : "udp", clp->servername, uid); printerr(0, "%s\n", clnt_spcreateerror(rpc_errmsg)); goto out_fail; } if (!tgtname) tgtname = clp->servicename; printerr(2, "creating context with server %s\n", tgtname); auth = authgss_create_default(rpc_clnt, tgtname, &sec); if (!auth) { /* Our caller should print appropriate message */ printerr(1, "WARNING: Failed to create krb5 context for " "user with uid %d for server %s\n", uid, tgtname); goto out_fail; } /* Success !!! */ rpc_clnt->cl_auth = auth; *clnt_return = rpc_clnt; *auth_return = auth; retval = 0; out: if (sec.cred != GSS_C_NO_CREDENTIAL) gss_release_cred(&min_stat, &sec.cred); return retval; out_fail: /* Only destroy here if failure. Otherwise, caller is responsible */ if (rpc_clnt) clnt_destroy(rpc_clnt); goto out; }
/* * NFS stuff and unmount(2) call */ int umountfs(struct statfs *sfs) { char fsidbuf[64]; enum clnt_stat clnt_stat; struct timeval try; struct addrinfo *ai, hints; int do_rpc; CLIENT *clp; char *nfsdirname, *orignfsdirname; char *hostp, *delimp; ai = NULL; do_rpc = 0; hostp = NULL; nfsdirname = delimp = orignfsdirname = NULL; memset(&hints, 0, sizeof hints); if (strcmp(sfs->f_fstypename, "nfs") == 0) { if ((nfsdirname = strdup(sfs->f_mntfromname)) == NULL) err(1, "strdup"); orignfsdirname = nfsdirname; if (*nfsdirname == '[' && (delimp = strchr(nfsdirname + 1, ']')) != NULL && *(delimp + 1) == ':') { hostp = nfsdirname + 1; nfsdirname = delimp + 2; } else if ((delimp = strrchr(nfsdirname, ':')) != NULL) { hostp = nfsdirname; nfsdirname = delimp + 1; } if (hostp != NULL) { *delimp = '\0'; getaddrinfo(hostp, NULL, &hints, &ai); if (ai == NULL) { warnx("can't get net id for host"); } } /* * Check if we have to start the rpc-call later. * If there are still identical nfs-names mounted, * we skip the rpc-call. Obviously this has to * happen before unmount(2), but it should happen * after the previous namecheck. * A non-NULL return means that this is the last * mount from mntfromname that is still mounted. */ if (getmntentry(sfs->f_mntfromname, NULL, NULL, CHECKUNIQUE) != NULL) do_rpc = 1; } if (!namematch(ai)) { free(orignfsdirname); return (1); } /* First try to unmount using the file system ID. */ snprintf(fsidbuf, sizeof(fsidbuf), "FSID:%d:%d", sfs->f_fsid.val[0], sfs->f_fsid.val[1]); if (unmount(fsidbuf, fflag | MNT_BYFSID) != 0) { /* XXX, non-root users get a zero fsid, so don't warn. */ if (errno != ENOENT || sfs->f_fsid.val[0] != 0 || sfs->f_fsid.val[1] != 0) warn("unmount of %s failed", sfs->f_mntonname); if (errno != ENOENT) { free(orignfsdirname); return (1); } /* Compatibility for old kernels. */ if (sfs->f_fsid.val[0] != 0 || sfs->f_fsid.val[1] != 0) warnx("retrying using path instead of file system ID"); if (unmount(sfs->f_mntonname, fflag) != 0) { warn("unmount of %s failed", sfs->f_mntonname); free(orignfsdirname); return (1); } } /* Mark this this file system as unmounted. */ getmntentry(NULL, NULL, &sfs->f_fsid, REMOVE); if (vflag) (void)printf("%s: unmount from %s\n", sfs->f_mntfromname, sfs->f_mntonname); /* * Report to mountd-server which nfsname * has been unmounted. */ if (ai != NULL && !(fflag & MNT_FORCE) && do_rpc) { clp = clnt_create(hostp, MOUNTPROG, MOUNTVERS3, "udp"); if (clp == NULL) { warnx("%s: %s", hostp, clnt_spcreateerror("MOUNTPROG")); free(orignfsdirname); return (1); } clp->cl_auth = authsys_create_default(); try.tv_sec = 20; try.tv_usec = 0; clnt_stat = clnt_call(clp, MOUNTPROC_UMNT, (xdrproc_t)xdr_dir, nfsdirname, (xdrproc_t)xdr_void, (caddr_t)0, try); if (clnt_stat != RPC_SUCCESS) { warnx("%s: %s", hostp, clnt_sperror(clp, "RPCMNT_UMOUNT")); free(orignfsdirname); return (1); } /* * Remove the unmounted entry from /var/db/mounttab. */ if (read_mtab()) { clean_mtab(hostp, nfsdirname, vflag); if(!write_mtab(vflag)) warnx("cannot remove mounttab entry %s:%s", hostp, nfsdirname); free_mtab(); } auth_destroy(clp->cl_auth); clnt_destroy(clp); }
int main(int argc, char *argv[]) { spraycumul host_stats; sprayarr host_array; CLIENT *cl; int c; u_int i; u_int count = 0; int delay = 0; int length = 0; double xmit_time; /* time to receive data */ while ((c = getopt(argc, argv, "c:d:l:")) != -1) { switch (c) { case 'c': count = atoi(optarg); break; case 'd': delay = atoi(optarg); break; case 'l': length = atoi(optarg); break; default: usage(); /* NOTREACHED */ } } argc -= optind; argv += optind; if (argc != 1) { usage(); /* NOTREACHED */ } /* Correct packet length. */ if (length > SPRAYMAX) { length = SPRAYMAX; } else if (length < SPRAYOVERHEAD) { length = SPRAYOVERHEAD; } else { /* The RPC portion of the packet is a multiple of 32 bits. */ length -= SPRAYOVERHEAD - 3; length &= ~3; length += SPRAYOVERHEAD; } /* * The default value of count is the number of packets required * to make the total stream size 100000 bytes. */ if (!count) { count = 100000 / length; } /* Initialize spray argument */ host_array.sprayarr_len = length - SPRAYOVERHEAD; host_array.sprayarr_val = spray_buffer; /* create connection with server */ cl = clnt_create(*argv, SPRAYPROG, SPRAYVERS, "udp"); if (cl == NULL) errx(1, "%s", clnt_spcreateerror("")); /* * For some strange reason, RPC 4.0 sets the default timeout, * thus timeouts specified in clnt_call() are always ignored. * * The following (undocumented) hack resets the internal state * of the client handle. */ clnt_control(cl, CLSET_TIMEOUT, &NO_DEFAULT); /* Clear server statistics */ if (clnt_call(cl, SPRAYPROC_CLEAR, (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_void, NULL, TIMEOUT) != RPC_SUCCESS) errx(1, "%s", clnt_sperror(cl, "")); /* Spray server with packets */ printf ("sending %u packets of lnth %d to %s ...", count, length, *argv); fflush (stdout); for (i = 0; i < count; i++) { clnt_call(cl, SPRAYPROC_SPRAY, (xdrproc_t)xdr_sprayarr, &host_array, (xdrproc_t)xdr_void, NULL, ONE_WAY); if (delay) { usleep(delay); } } /* Collect statistics from server */ if (clnt_call(cl, SPRAYPROC_GET, (xdrproc_t)xdr_void, NULL, (xdrproc_t)xdr_spraycumul, &host_stats, TIMEOUT) != RPC_SUCCESS) errx(1, "%s", clnt_sperror(cl, "")); xmit_time = host_stats.clock.sec + (host_stats.clock.usec / 1000000.0); printf ("\n\tin %.2f seconds elapsed time\n", xmit_time); /* report dropped packets */ if (host_stats.counter != count) { int packets_dropped = count - host_stats.counter; printf("\t%d packets (%.2f%%) dropped\n", packets_dropped, 100.0 * packets_dropped / count ); } else { printf("\tno packets dropped\n"); } printf("Sent:"); print_xferstats(count, length, xmit_time); printf("Rcvd:"); print_xferstats(host_stats.counter, length, xmit_time); exit (0); }
CLIENT * Creer_RPCClient( unsigned int adresse, unsigned int programme, unsigned int version, unsigned short port, int sockfd ) { struct sockaddr_in adresse_rpc ; int sock = 0 ; CLIENT * client ; struct timeval intervalle ; int rc ; struct netconfig * nconf ; struct netbuf netbuf ; memset( &adresse_rpc, 0, (size_t)sizeof( adresse_rpc ) ) ; adresse_rpc.sin_port = port ; adresse_rpc.sin_family = AF_INET ; adresse_rpc.sin_addr.s_addr = adresse ; sock = sockfd ; intervalle.tv_sec = TIMEOUT_SEC ; intervalle.tv_usec = 0 ; if( sock > 0 ) { if( port > 0 ) { /* En tcp, il faut que la socket soit connectee sur le service en face si on n'utilise pas RPC_ANYSOCK * ATTENTION, ceci est une feature non documentee des RPC clientes (j'ai vu ca dans les sources) */ if( connect( sock, (struct sockaddr *)&adresse_rpc, sizeof( adresse_rpc ) ) < 0 ) fprintf( stderr, "connect impossible sur le serveur RPC\n" ) ; } else { /* Dans ce cas, on ne connait pas le port en face, donc connect impossible, on prend RPC_ANYSOCK * mais uniquement apres avoir ferme la socket 'sock' qui ne sert a rien ici */ close( sock ) ; sock = RPC_ANYSOCK ; } } /* initialisation des structures de TI-RPC */ if( ( nconf = (struct netconfig *)getnetconfigent( "tcp" ) ) == NULL ) { fprintf( stderr, "Erreur de getnetconfigent\n" ) ; exit( 1 ) ; } netbuf.maxlen = sizeof( adresse_rpc ); netbuf.len = sizeof( adresse_rpc ); netbuf.buf = &adresse_rpc; /* Creation et allocation du client */ if( ( client = clnt_tli_create( sock, nconf, &netbuf, programme, version, SEND_SIZE, RECV_SIZE ) ) == NULL ) { char erreur[100] ; char entete[100] ; sprintf( entete, "Creation RPC %d|%d|0x%x:%d|%d", programme, version, adresse, port, sock ) ; strcpy( erreur, clnt_spcreateerror( entete ) ) ; fprintf( stderr, "%s", erreur ) ; return NULL ; } return client ; } /* Creer_RPCClient */
main( int argc, char * argv[] ) { struct timeval intervalle = { TIMEOUT_SEC, 0 }; CLIENT * client ; int c ; struct rpcent * etc_rpc ; /* pour consulter /etc/rpc ou rpc.bynumber */ unsigned int adresse_serveur ; /* Au format NET */ struct hostent * hp ; char nom_exec[MAXPATHLEN] ; char machine_locale[256] ; char * tempo_nom_exec = NULL ; unsigned int rpc_service_num = DEFAULT_RPC_SERVICE ; unsigned int rpc_version = V1 ; unsigned int rpcproc = PROC_PLUS1 ; unsigned short port = ntohs( DEFAULT_PORT ) ; int val = 2 ; int rc ; char gss_service[1024] ; /* On recupere le nom de l'executable */ if( ( tempo_nom_exec = strrchr( argv[0], '/' ) ) != NULL ) strcpy( (char *)nom_exec, tempo_nom_exec + 1 ) ; while( ( c = getopt( argc, argv, options ) ) != EOF ) { switch( c ) { case 'd': /* Cette option permet de recuperer un nom pour la machine distante */ if( isalpha( *optarg ) ) { /* Recuperation de l'adresse de la machine serveur */ if( ( hp = gethostbyname( optarg ) ) == NULL ) { fprintf( stderr, "error gethostbyname errono=%u|%s\n", errno, strerror( errno ) ) ; exit( 1 ) ; } memcpy( &adresse_serveur, hp->h_addr, hp->h_length ) ; } else { adresse_serveur = inet_addr( optarg ) ; } break; case 's': /* Un nom ou un numero de service a ete indique */ if( isalpha( (int)*optarg ) ) { /* Ca commence pas par un chiffre donc c'est un nom service */ if( ( etc_rpc = getrpcbyname( optarg ) ) == NULL ) { fprintf( stderr, "Impossible de resoudre le service %s\n", optarg ) ; } else { rpc_service_num = etc_rpc->r_number ; } } else { /* C'est un numero de service qui est indique */ rpc_service_num = atoi( optarg ) ; } break ; case 'v': /* numero de version */ rpc_version = atoi( optarg ) ; break ; case 'p': rpcproc = atoi( optarg ) ; break ; case 'h': case '?': default: /* Affichage de l'aide en ligne */ fprintf( stderr, utilisation, nom_exec ) ; exit( 0 ) ; break ; } } if( ( client = Creer_RPCClient( adresse_serveur, rpc_service_num, rpc_version, port , RPC_ANYSOCK ) ) == NULL ) { char erreur[100] ; strcpy( erreur, clnt_spcreateerror( "Creation RPC" ) ) ; fprintf( stderr, "Creation RPC: %s\n", erreur ) ; exit( 1 ) ; } client->cl_auth = authunix_create_default(); val = 2 ; fprintf( stderr, "J'envoie la valeur %d\n", val ) ; if( ( rc = clnt_call( client, rpcproc, (xdrproc_t)xdr_int, (caddr_t)&val, (xdrproc_t)xdr_int, (caddr_t)&val, intervalle ) ) != RPC_SUCCESS ) { clnt_perror( client, "appel a FIXE_RET\n" ) ; exit ( 1 ) ; } fprintf( stderr, "Je recois la valeur %d\n", val ) ; auth_destroy( client->cl_auth ) ; clnt_destroy( client ) ; }