📄 rpcinfo.c
字号:
/* @(#)rpcinfo.c 2.2 88/08/11 4.0 RPCSRC */#ifndef lintstatic char sccsid[] = "@(#)rpcinfo.c 1.22 87/08/12 SMI";#endif/* * Copyright (C) 1986, Sun Microsystems, Inc. *//* * rpcinfo: ping a particular rpc program * or dump the portmapper *//* * Sun RPC is a product of Sun Microsystems, Inc. and is provided for * unrestricted use provided that this legend is included on all tape * media and as a part of the software program in whole or part. Users * may copy or modify Sun RPC without charge, but are not authorized * to license or distribute it to anyone else except as part of a product or * program developed by the user. * * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. * * Sun RPC is provided with no support and without any obligation on the * part of Sun Microsystems, Inc. to assist in its use, correction, * modification or enhancement. * * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC * OR ANY PART THEREOF. * * In no event will Sun Microsystems, Inc. be liable for any lost revenue * or profits or other special, indirect and consequential damages, even if * Sun has been advised of the possibility of such damages. * * Sun Microsystems, Inc. * 2550 Garcia Avenue * Mountain View, California 94043 */#include <rpc/rpc.h>#include <stdio.h>#include <sys/socket.h>#include <netdb.h>#include <rpc/pmap_prot.h>#include <rpc/pmap_clnt.h>#include <signal.h>#include <ctype.h>#define MAXHOSTLEN 256#define MIN_VERS ((u_long) 0)#define MAX_VERS ((u_long) 4294967295L)static void udpping(/*u_short portflag, int argc, char **argv*/);static void tcpping(/*u_short portflag, int argc, char **argv*/);static int pstatus(/*CLIENT *client, u_long prognum, u_long vers*/);static void pmapdump(/*int argc, char **argv*/);static bool_t reply_proc(/*void *res, struct sockaddr_in *who*/);static void brdcst(/*int argc, char **argv*/);static void deletereg(/* int argc, char **argv */) ;static void usage(/*void*/);static u_long getprognum(/*char *arg*/);static u_long getvers(/*char *arg*/);static void get_inet_address(/*struct sockaddr_in *addr, char *host*/);extern u_long inet_addr(); /* in 4.2BSD, arpa/inet.h called that a in_addr */extern char *inet_ntoa();/* * Functions to be performed. */#define NONE 0 /* no function */#define PMAPDUMP 1 /* dump portmapper registrations */#define TCPPING 2 /* ping TCP service */#define UDPPING 3 /* ping UDP service */#define BRDCST 4 /* ping broadcast UDP service */#define DELETES 5 /* delete registration for the service */intmain(argc, argv) int argc; char **argv;{ register int c; extern char *optarg; extern int optind; int errflg; int function; u_short portnum; function = NONE; portnum = 0; errflg = 0; while ((c = getopt(argc, argv, "ptubdn:")) != EOF) { switch (c) { case 'p': if (function != NONE) errflg = 1; else function = PMAPDUMP; break; case 't': if (function != NONE) errflg = 1; else function = TCPPING; break; case 'u': if (function != NONE) errflg = 1; else function = UDPPING; break; case 'b': if (function != NONE) errflg = 1; else function = BRDCST; break; case 'n': portnum = (u_short) atoi(optarg); /* hope we don't get bogus # */ break; case 'd': if (function != NONE) errflg = 1; else function = DELETES; break; case '?': errflg = 1; } } if (errflg || function == NONE) { usage(); return (1); } switch (function) { case PMAPDUMP: if (portnum != 0) { usage(); return (1); } pmapdump(argc - optind, argv + optind); break; case UDPPING: udpping(portnum, argc - optind, argv + optind); break; case TCPPING: tcpping(portnum, argc - optind, argv + optind); break; case BRDCST: if (portnum != 0) { usage(); return (1); } brdcst(argc - optind, argv + optind); break; case DELETES: deletereg(argc - optind, argv + optind); break; } return (0);} static voidudpping(portnum, argc, argv) u_short portnum; int argc; char **argv;{ struct timeval to; struct sockaddr_in addr; enum clnt_stat rpc_stat; CLIENT *client; u_long prognum, vers, minvers, maxvers; int sock = RPC_ANYSOCK; struct rpc_err rpcerr; int failure; if (argc < 2 || argc > 3) { usage(); exit(1); } prognum = getprognum(argv[1]); get_inet_address(&addr, argv[0]); /* Open the socket here so it will survive calls to clnt_destroy */ sock = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP); if (sock < 0) { perror("rpcinfo: socket"); exit(1); } failure = 0; if (argc == 2) { /* * A call to version 0 should fail with a program/version * mismatch, and give us the range of versions supported. */ addr.sin_port = htons(portnum); to.tv_sec = 5; to.tv_usec = 0; if ((client = clntudp_create(&addr, prognum, (u_long)0, to, &sock)) == NULL) { clnt_pcreateerror("rpcinfo"); printf("program %lu is not available\n", prognum); exit(1); } to.tv_sec = 10; to.tv_usec = 0; rpc_stat = clnt_call(client, NULLPROC, xdr_void, (char *)NULL, xdr_void, (char *)NULL, to); if (rpc_stat == RPC_PROGVERSMISMATCH) { clnt_geterr(client, &rpcerr); minvers = rpcerr.re_vers.low; maxvers = rpcerr.re_vers.high; } else if (rpc_stat == RPC_SUCCESS) { /* * Oh dear, it DOES support version 0. * Let's try version MAX_VERS. */ addr.sin_port = htons(portnum); to.tv_sec = 5; to.tv_usec = 0; if ((client = clntudp_create(&addr, prognum, MAX_VERS, to, &sock)) == NULL) { clnt_pcreateerror("rpcinfo"); printf("program %lu version %lu is not available\n", prognum, MAX_VERS); exit(1); } to.tv_sec = 10; to.tv_usec = 0; rpc_stat = clnt_call(client, NULLPROC, xdr_void, (char *)NULL, xdr_void, (char *)NULL, to); if (rpc_stat == RPC_PROGVERSMISMATCH) { clnt_geterr(client, &rpcerr); minvers = rpcerr.re_vers.low; maxvers = rpcerr.re_vers.high; } else if (rpc_stat == RPC_SUCCESS) { /* * It also supports version MAX_VERS. * Looks like we have a wise guy. * OK, we give them information on all * 4 billion versions they support... */ minvers = 0; maxvers = MAX_VERS; } else { (void) pstatus(client, prognum, MAX_VERS); exit(1); } } else { (void) pstatus(client, prognum, (u_long)0); exit(1); } clnt_destroy(client); for (vers = minvers; vers <= maxvers; vers++) { addr.sin_port = htons(portnum); to.tv_sec = 5; to.tv_usec = 0; if ((client = clntudp_create(&addr, prognum, vers, to, &sock)) == NULL) { clnt_pcreateerror("rpcinfo"); printf("program %lu version %lu is not available\n", prognum, vers); exit(1); } to.tv_sec = 10; to.tv_usec = 0; rpc_stat = clnt_call(client, NULLPROC, xdr_void, (char *)NULL, xdr_void, (char *)NULL, to); if (pstatus(client, prognum, vers) < 0) failure = 1; clnt_destroy(client); } } else { vers = getvers(argv[2]); addr.sin_port = htons(portnum); to.tv_sec = 5; to.tv_usec = 0; if ((client = clntudp_create(&addr, prognum, vers, to, &sock)) == NULL) { clnt_pcreateerror("rpcinfo"); printf("program %lu version %lu is not available\n", prognum, vers); exit(1); } to.tv_sec = 10; to.tv_usec = 0; rpc_stat = clnt_call(client, 0, xdr_void, (char *)NULL, xdr_void, (char *)NULL, to); if (pstatus(client, prognum, vers) < 0) failure = 1; } (void) close(sock); /* Close it up again */ if (failure) exit(1);}static voidtcpping(portnum, argc, argv) u_short portnum; int argc; char **argv;{ struct timeval to; struct sockaddr_in addr; enum clnt_stat rpc_stat; CLIENT *client; u_long prognum, vers, minvers, maxvers; int sock = RPC_ANYSOCK; struct rpc_err rpcerr; int failure;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -