/* dsgetstat.c - NWDSGetNDSStatistics() Copyright (C) 2000 Petr Vandrovec This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Revision history: 1.00 2000, February 2 Petr Vandrovec Initial version, copied from nwdsgethost demo. 1.01 2000, April 26 Petr Vandrovec Turned from example into real API 1.02 2000, May 1 Petr Vandrovec Added NWDSResetNDSStatistics. */ #include #include "nwnet_i.h" #include static NWDSCCODE __NWDSGetNDSStatistics( NWCONN_HANDLE conn, nuint32 requestMask, size_t statsInfoLen, NDSStatsInfo_T* statsInfo ) { nuint8 rqbuffer[5]; nuint32 rpbuffer[32]; NW_FRAGMENT rp; NWDSCCODE dserr; BSET(rqbuffer, 0, DS_NCP_GET_DS_STATISTICS); DSET_LH(rqbuffer, 1, requestMask | 0x00000001); rp.fragAddr.rw = rpbuffer; rp.fragSize = sizeof(rpbuffer); dserr = NWRequestSimple(conn, DS_NCP_VERB, rqbuffer, 5, &rp); if (!dserr) { size_t rplen; rplen = rp.fragSize; if (rplen < 4) { dserr = NWE_INVALID_NCP_PACKET_LENGTH; } else { size_t pos; int i; nuint32 flags; flags = DVAL_LH(rpbuffer, 0); statsInfo->statsVersion = flags; pos = 4; for (i = 1; i < 32; i++) { nuint32 val; if (flags & (1 << i)) { if (pos + 4 > rplen) { dserr = NWE_INVALID_NCP_PACKET_LENGTH; break; } val = DVAL_LH(rpbuffer, pos); pos += 4; } else val = 0; switch (i) { #define endof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER + sizeof(((TYPE *)0)->MEMBER)) #define ISI(v,x) case v: if (endof(NDSStatsInfo_T, x) <= statsInfoLen) statsInfo->x = val; break ISI(1, noSuchEntry); ISI(2, localEntry); ISI(3, typeReferral); ISI(4, aliasReferral); ISI(5, requestCount); ISI(6, requestDataSize); ISI(7, replyDataSize); ISI(8, resetTime); ISI(9, transportReferral); ISI(10, upReferral); ISI(11, downReferral); /* 12..31 are reserved */ #undef ISI } } } } return dserr; } NWDSCCODE NWDSGetNDSStatistics( NWDSContextHandle ctx, const NWDSChar* serverName, size_t statsInfoLen, NDSStatsInfo_T* statsInfo) { NWCONN_HANDLE conn; NWDSCCODE dserr; dserr = NWDSOpenConnToNDSServer(ctx, serverName, &conn); if (dserr) return dserr; dserr = __NWDSGetNDSStatistics(conn, 0x01FFFFFF, statsInfoLen, statsInfo); NWCCCloseConn(conn); return dserr; } static NWDSCCODE __NWDSResetNDSStatistics( NWCONN_HANDLE conn ) { static const nuint8 rqbuffer[1] = { DS_NCP_RESET_DS_COUNTERS }; return NWRequestSimple(conn, DS_NCP_VERB, rqbuffer, 1, NULL); } NWDSCCODE NWDSResetNDSStatistics( NWDSContextHandle ctx, const NWDSChar* serverName ) { NWCONN_HANDLE conn; NWDSCCODE dserr; dserr = NWDSOpenConnToNDSServer(ctx, serverName, &conn); if (dserr) return dserr; dserr = __NWDSResetNDSStatistics(conn); NWCCCloseConn(conn); return dserr; } static NWDSCCODE __NWDSGetDSVerInfo( NWCONN_HANDLE conn, nuint32 version, nuint32 requestMask, Buf_T* reply ) { nuint8 rqbuffer[9]; NW_FRAGMENT rp; NWDSCCODE dserr; void* rpptr; size_t maxl; if (!reply) return ERR_NULL_POINTER; BSET(rqbuffer, 0, DS_NCP_PING); DSET_LH(rqbuffer, 1, version); DSET_LH(rqbuffer, 5, requestMask); NWDSBufStartPut(reply, 0); rpptr = NWDSBufRetrievePtrAndLen(reply, &maxl); rp.fragAddr.rw = rpptr; rp.fragSize = maxl; dserr = NWRequestSimple(conn, DS_NCP_VERB, rqbuffer, 9, &rp); if (dserr) return dserr; if (rp.fragSize > maxl) return NWE_BUFFER_OVERFLOW; NWDSBufPutSkip(reply, rp.fragSize); NWDSBufFinishPut(reply); #if 0 { nuint8* p; for (p = reply->curPos; p < reply->dataend; p++) printf("%02X ", *p); printf("\n"); } #endif return 0; } NWDSCCODE NWDSGetDSVerInfo( NWCONN_HANDLE conn, nuint32* dsVersion, nuint32* rootMostEntryDepth, char* sapName, nuint32* flags, wchar_t* treeName ) { NWDSCCODE dserr; nuint8 buffer[1024]; Buf_T buf; nuint32 rqflags = 0; nuint32 tmp; nuint32 version; if (rootMostEntryDepth) rqflags |= DSPING_DEPTH; else rootMostEntryDepth = &tmp; if (dsVersion) rqflags |= DSPING_BUILD_NUMBER; else dsVersion = &tmp; if (flags) rqflags |= DSPING_FLAGS; else flags = &tmp; if (sapName) rqflags |= DSPING_SAP_NAME; if (treeName) rqflags |= DSPING_TREE_NAME; version = 0; if (rqflags & ~(DSPING_SUPPORTED_FIELDS | DSPING_DEPTH | DSPING_BUILD_NUMBER | DSPING_FLAGS | DSPING_SAP_NAME | DSPING_TREE_NAME)) { version = 1; } NWDSSetupBuf(&buf, buffer, sizeof(buffer)); dserr = __NWDSGetDSVerInfo(conn, version, rqflags, &buf); if (dserr) return dserr; dserr = NWDSBufGetLE32(&buf, &version); if (dserr) return dserr; switch (version) { case 0x00000009: { unsigned char asciiName[MAX_TREE_NAME_CHARS + 1]; nuint32 asciiNameLen; dserr = NWDSBufGetLE32(&buf, &asciiNameLen); if (dserr) return dserr; if (asciiNameLen > sizeof(asciiName)) return NWE_BUFFER_OVERFLOW; if (asciiNameLen) { dserr = NWDSBufGet(&buf, asciiName, asciiNameLen); if (dserr) return dserr; if (asciiName[asciiNameLen-1]) return ERR_INVALID_SERVER_RESPONSE; while (asciiNameLen > 1 && asciiName[asciiNameLen - 2] == '_') asciiNameLen--; } else { asciiNameLen = 1; } asciiName[asciiNameLen - 1] = 0; dserr = NWDSBufGetLE32(&buf, rootMostEntryDepth); if (dserr) return dserr; dserr = NWDSBufGetLE32(&buf, dsVersion); if (dserr) return dserr; dserr = NWDSBufGetLE32(&buf, flags); if (dserr) return dserr; if (sapName) memcpy(sapName, asciiName, asciiNameLen); if (treeName) { unsigned char* src = asciiName; do { *treeName++ = *src++; } while (--asciiNameLen); } } return 0; case 0x0000000A: if (rqflags & DSPING_SUPPORTED_FIELDS) { dserr = NWDSBufGetLE32(&buf, &rqflags); if (dserr) return dserr; } if (rqflags & DSPING_DEPTH) { dserr = NWDSBufGetLE32(&buf, rootMostEntryDepth); if (dserr) return dserr; } if (rqflags & DSPING_BUILD_NUMBER) { dserr = NWDSBufGetLE32(&buf, dsVersion); if (dserr) return dserr; } if (rqflags & DSPING_FLAGS) { dserr = NWDSBufGetLE32(&buf, flags); if (dserr) return dserr; } if (rqflags & DSPING_SAP_NAME) { dserr = NWDSBufGetLE32(&buf, &tmp); if (dserr) return dserr; if (tmp > MAX_TREE_NAME_CHARS + 1) return NWE_BUFFER_OVERFLOW; if (tmp) { dserr = NWDSBufGet(&buf, sapName, tmp); if (dserr) return dserr; if (sapName[tmp-1]) return ERR_INVALID_SERVER_RESPONSE; } else { sapName[0] = 0; } } if (rqflags & DSPING_TREE_NAME) { dserr = NWDSBufDN(&buf, treeName, (MAX_TREE_NAME_CHARS + 1) * sizeof(wchar_t)); if (dserr) return dserr; } break; default: return ERR_INVALID_API_VERSION; } return 0; }