/* * Copyright 2000, International Business Machines Corporation and others. * All Rights Reserved. * * This software has been released under the terms of the IBM Public * License. For details, see the LICENSE file in the top-level source * directory or online at http://www.openafs.org/dl/license10.html */ #include #include #include #ifdef AFS_NT40_ENV #include #else #include #include #include #include #include #endif #include #include #include #include #include "rx_user.h" #include "rx_clock.h" #include "rx_queue.h" #include "rx.h" #include "rx_globals.h" #define TIMEOUT 20 extern struct hostent *hostutil_GetHostByName(); static short PortNumber(aport) register char *aport; { register int tc; register short total; total = 0; while (tc = *aport++) { if (tc < '0' || tc > '9') return -1; /* bad port number */ total *= 10; total += tc - (int) '0'; } return htons(total); } static short PortName(aname) register char *aname; { register struct servent *ts; ts = getservbyname(aname, (char *) 0); if (!ts) return -1; return ts->s_port; /* returns it in network byte order */ } MainCommand(as, arock) char *arock; struct cmd_syndesc *as; { register int i; int s; int j; struct sockaddr_in taddr; afs_int32 host; struct in_addr hostAddr; short port; struct hostent *th; register afs_int32 code; int nodally; int allconns; int rxstats; int onlyClient, onlyServer; afs_int32 onlyHost; short onlyPort; int onlyAuth; int flag; int dallyCounter; int withSecStats; int withAllConn; int withRxStats; int withWaiters; int withIdleThreads; int withPeers; struct rx_debugStats tstats; char *portName, *hostName; struct rx_debugConn tconn; short noConns; short showPeers; int version_flag; char version[64]; afs_int32 length=64; afs_uint32 supportedDebugValues = 0; afs_uint32 supportedStatValues = 0; afs_uint32 supportedConnValues = 0; afs_uint32 supportedPeerValues = 0; afs_int32 nextconn = 0; afs_int32 nextpeer = 0; nodally = (as->parms[2].items ? 1 : 0); allconns = (as->parms[3].items ? 1 : 0); rxstats = (as->parms[4].items ? 1 : 0); onlyServer = (as->parms[5].items ? 1 : 0); onlyClient = (as->parms[6].items ? 1 : 0); version_flag=(as->parms[10].items ? 1 : 0); noConns = (as->parms[11].items ? 1 : 0); showPeers = (as->parms[12].items ? 1 : 0); if (as->parms[0].items) hostName = as->parms[0].items->data; else hostName = (char *) 0; if (as->parms[1].items) portName = as->parms[1].items->data; else portName = (char *) 0; if (as->parms[7].items) { char *name = as->parms[7].items->data; if ((onlyPort = PortNumber(name)) == -1) onlyPort = PortName(name); if (onlyPort == -1) { printf("rxdebug: can't resolve port name %s\n", name); exit(1); } } else onlyPort = -1; if (as->parms[8].items) { char *name = as->parms[8].items->data; struct hostent *th; th = hostutil_GetHostByName(name); if (!th) { printf("rxdebug: host %s not found in host table\n", name); exit(1); } bcopy(th->h_addr, &onlyHost, sizeof(afs_int32)); } else onlyHost = -1; if (as->parms[9].items) { char *name = as->parms[9].items->data; if (strcmp (name, "clear") == 0) onlyAuth = 0; else if (strcmp (name, "auth") == 0) onlyAuth = 1; else if (strcmp (name, "crypt") == 0) onlyAuth = 2; else if ((strcmp (name, "null") == 0) || (strcmp (name, "none") == 0) || (strncmp (name, "noauth", 6) == 0) || (strncmp (name, "unauth", 6) == 0)) onlyAuth = -1; else { fprintf (stderr, "Unknown authentication level: %s\n", name); exit (1); } } else onlyAuth = 999; /* lookup host */ if (hostName) { th = hostutil_GetHostByName(hostName); if (!th) { printf("rxdebug: host %s not found in host table\n", hostName); exit(1); } bcopy(th->h_addr, &host, sizeof(afs_int32)); } else host = htonl(0x7f000001); /* IP localhost */ if (!portName) port = htons(7000); /* default is fileserver */ else { if ((port = PortNumber(portName)) == -1) port = PortName(portName); if (port == -1) { printf("rxdebug: can't resolve port name %s\n", portName); exit(1); } } dallyCounter = 0; hostAddr.s_addr = host; printf("Trying %s (port %d):\n", inet_ntoa(hostAddr), ntohs(port)); s = socket(AF_INET, SOCK_DGRAM, 0); taddr.sin_family = AF_INET; taddr.sin_port = 0; taddr.sin_addr.s_addr = 0; code = bind(s, (struct sockaddr *) &taddr, sizeof(struct sockaddr_in)); if (code) { perror("bind"); exit(1); } if(version_flag) { code = rx_GetServerVersion(s, host, port, length, version); if (code < 0) { printf("get version call failed with code %d, errno %d\n", code,errno); exit(1); } printf("AFS version: %s\n",version);fflush(stdout); exit(0); } code = rx_GetServerDebug(s, host, port, &tstats, &supportedDebugValues); if (code < 0) { printf("getstats call failed with code %d\n", code); exit(1); } withSecStats = (supportedDebugValues & RX_SERVER_DEBUG_SEC_STATS); withAllConn = (supportedDebugValues & RX_SERVER_DEBUG_ALL_CONN); withRxStats = (supportedDebugValues & RX_SERVER_DEBUG_RX_STATS); withWaiters = (supportedDebugValues & RX_SERVER_DEBUG_WAITER_CNT); withIdleThreads = (supportedDebugValues & RX_SERVER_DEBUG_IDLE_THREADS); withPeers = (supportedDebugValues & RX_SERVER_DEBUG_ALL_PEER); printf("Free packets: %d, packet reclaims: %d, calls: %d, used FDs: %d\n", tstats.nFreePackets, tstats.packetReclaims, tstats.callsExecuted, tstats.usedFDs); if (!tstats.waitingForPackets) printf("not "); printf("waiting for packets.\n"); if (withWaiters) printf("%d calls waiting for a thread\n",tstats.nWaiting); if ( withIdleThreads ) printf("%d threads are idle\n", tstats.idleThreads); if (rxstats) { if (!withRxStats) { noRxStats: withRxStats = 0; fprintf (stderr, "WARNING: Server doesn't support retrieval of Rx statistics\n"); } else { struct rx_stats rxstats; /* should gracefully handle the case where rx_stats grows */ code = rx_GetServerStats(s, host, port, &rxstats, &supportedStatValues); if (code < 0) { printf("rxstats call failed with code %d\n", code); exit(1); } if (code != sizeof(rxstats)) { if ((((struct rx_debugIn *)(&rxstats))->type == RX_DEBUGI_BADTYPE)) goto noRxStats; printf ("WARNING: returned Rx statistics of unexpected size (got %d)\n", code); /* handle other versions?... */ } rx_PrintTheseStats (stdout, &rxstats, sizeof(rxstats), tstats.nFreePackets, tstats.version); } } if (!noConns) { if (allconns) { if (!withAllConn) fprintf (stderr, "WARNING: Server doesn't support retrieval of all connections,\n getting only interesting instead.\n"); } if (onlyServer) printf ("Showing only server connections\n"); if (onlyClient) printf ("Showing only client connections\n"); if (onlyAuth != 999) { static char *name[] = {"unauthenticated", "rxkad_clear", "rxkad_auth", "rxkad_crypt"}; printf ("Showing only %s connections\n", name[onlyAuth+1]); } if (onlyHost != -1) { hostAddr.s_addr = onlyHost; printf ("Showing only connections from host %s\n", inet_ntoa(hostAddr)); } if (onlyPort != -1) printf ("Showing only connections on port %u\n", ntohs(onlyPort)); for(i=0;;i++) { code = rx_GetServerConnections(s, host, port, &nextconn, allconns, supportedDebugValues, &tconn, &supportedConnValues); if (code < 0) { printf("getconn call failed with code %d\n", code); break; } if (tconn.cid == 0xffffffff) { printf("Done.\n"); break; } /* see if we're in nodally mode and all calls are dallying */ if (nodally) { flag = 0; for(j=0;j (double) from working, * this code produces negative lifetimes when run on the * RT. */ printf (", expires in %.1f hours", ((afs_uint32)tconn.secStats.expires - time(0)) / 3600.0); if (!(flags & 1)) { printf ("\n Received %d bytes in %d packets\n", tconn.secStats.bytesReceived, tconn.secStats.packetsReceived); printf (" Sent %d bytes in %d packets\n", tconn.secStats.bytesSent, tconn.secStats.packetsSent); } else printf ("\n"); break; } default: printf(" unknown\n"); } } for(j=0;j"); cmd_AddParm(ts, "-onlyhost", CMD_SINGLE, CMD_OPTIONAL, "show only "); cmd_AddParm(ts, "-onlyauth", CMD_SINGLE, CMD_OPTIONAL, "show only "); cmd_AddParm(ts,"-version",CMD_FLAG,CMD_OPTIONAL,"show AFS version id"); cmd_AddParm(ts,"-noconns",CMD_FLAG,CMD_OPTIONAL,"show no connections"); cmd_AddParm(ts,"-peers",CMD_FLAG,CMD_OPTIONAL,"show peers"); cmd_Dispatch(argc, argv); exit(0); }