00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "mon_constants.h"
00040 #include "utils.h"
00041 #include "ApMon.h"
00042 #include "proc_utils.h"
00043
00044 #ifndef WIN32
00045 #include <dirent.h>
00046 #endif
00047
00048 using namespace apmon_utils;
00049
00050 void ProcUtils::getCPUUsage(ApMon& apm, double& cpuUsage,
00051 double& cpuUsr, double& cpuSys,
00052 double& cpuNice, double& cpuIdle, int numCPUs)
00053 throw (runtime_error, procutils_error) {
00054 #ifndef WIN32
00055 FILE *fp1;
00056 char line[MAX_STRING_LEN];
00057 char s1[20]; double usrTime, sysTime, niceTime, idleTime, totalTime;
00058 int indU, indS, indN, indI;
00059
00060 time_t crtTime = time(NULL);
00061 fp1 = fopen("/proc/stat", "r");
00062 if (fp1 == NULL)
00063 throw procutils_error((char*)"[ getCPUUsage() ] Could not open /proc/stat");
00064
00065 while (fgets(line, MAX_STRING_LEN, fp1)) {
00066 if (strstr(line, "cpu") == line)
00067 break;
00068 }
00069
00070 if (line == NULL) {
00071 fclose(fp1);
00072 throw procutils_error((char*)"[ getCPUUsage() ] Could not obtain CPU usage info from /proc/stat");
00073 }
00074 fclose(fp1);
00075
00076 sscanf(line, "%s %lf %lf %lf %lf", s1, &usrTime, &niceTime, &sysTime,
00077 &idleTime);
00078
00079 indU = getVectIndex( (char*)"cpu_usr", apm.sysMonitorParams, apm.nSysMonitorParams);
00080 indS = getVectIndex((char*)"cpu_sys", apm.sysMonitorParams, apm.nSysMonitorParams);
00081 indN = getVectIndex((char*)"cpu_nice", apm.sysMonitorParams, apm.nSysMonitorParams);
00082 indI = getVectIndex((char*)"cpu_idle", apm.sysMonitorParams, apm.nSysMonitorParams);
00083 if (idleTime < apm.lastSysVals[indI]) {
00084 apm.lastSysVals[indU] = usrTime;
00085 apm.lastSysVals[indS] = sysTime;
00086 apm.lastSysVals[indN] = niceTime;
00087 apm.lastSysVals[indI] = idleTime;
00088 throw runtime_error("[ getCPUUsage() ] CPU usage counter reset");
00089 }
00090
00091 if (numCPUs == 0)
00092 throw procutils_error((char*)"[ getCPUUsage() ] Number of CPUs was not initialized");
00093
00094
00095 if (crtTime <= apm.lastSysInfoSend)
00096 throw runtime_error("[ getCPUUsage() ] Current time <= time of the previous sysInfoSend");
00097
00098 totalTime = (usrTime - apm.lastSysVals[indU]) +
00099 (sysTime -apm.lastSysVals[indS]) +
00100 (niceTime - apm.lastSysVals[indN]) +
00101 (idleTime - apm.lastSysVals[indI]);
00102
00103 cpuUsr = 100 * (usrTime - apm.lastSysVals[indU]) / totalTime;
00104 cpuSys = 100 * (sysTime - apm.lastSysVals[indS]) / totalTime;
00105 cpuNice = 100 * (niceTime - apm.lastSysVals[indN]) / totalTime;
00106 cpuIdle = 100 * (idleTime - apm.lastSysVals[indI]) / totalTime;
00107 cpuUsage = 100 * (totalTime - (idleTime - apm.lastSysVals[indI])) / totalTime;
00108
00109 apm.lastSysVals[indU] = usrTime;
00110 apm.lastSysVals[indN] = niceTime;
00111 apm.lastSysVals[indI] = idleTime;
00112 apm.lastSysVals[indS] = sysTime;
00113 #endif
00114 }
00115
00116 void ProcUtils::getSwapPages(ApMon& apm, double& pagesIn,
00117 double& pagesOut, double& swapIn,
00118 double& swapOut)
00119 throw (runtime_error, procutils_error) {
00120 #ifndef WIN32
00121 FILE *fp1;
00122 char line[MAX_STRING_LEN];
00123 char s1[20];
00124 bool foundPages, foundSwap;
00125 double p_in, p_out, s_in, s_out;
00126 int ind1, ind2;
00127
00128 time_t crtTime = time(NULL);
00129 fp1 = fopen("/proc/stat", "r");
00130 if (fp1 == NULL)
00131 throw procutils_error((char*)"[ getSwapPages() ] Could not open /proc/stat");
00132 if (crtTime <= apm.lastSysInfoSend)
00133 throw runtime_error("[ getSwapPages() ] Current time <= time of the previous sysInfoSend");
00134
00135 foundPages = foundSwap = false;
00136 while (fgets(line, MAX_STRING_LEN, fp1)) {
00137 if (strstr(line, "page") == line) {
00138 foundPages = true;
00139 sscanf(line, "%s %lf %lf ", s1, &p_in, &p_out);
00140
00141 ind1 = getVectIndex((char*)"pages_in", apm.sysMonitorParams, apm.nSysMonitorParams);
00142 ind2 = getVectIndex((char*)"pages_out", apm.sysMonitorParams, apm.nSysMonitorParams);
00143 if (p_in < apm.lastSysVals[ind1] || p_out < apm.lastSysVals[ind2]) {
00144 apm.lastSysVals[ind1] = p_in;
00145 apm.lastSysVals[ind2] = p_out;
00146 throw runtime_error("[ getSwapPages() ] Pages in/out counter reset");
00147 }
00148 pagesIn = (p_in - apm.lastSysVals[ind1]) / (crtTime - apm.lastSysInfoSend);
00149 pagesOut = (p_out - apm.lastSysVals[ind2]) / (crtTime - apm.lastSysInfoSend);
00150 apm.lastSysVals[ind1] = p_in;
00151 apm.lastSysVals[ind2] = p_out;
00152
00153 }
00154
00155 if (strstr(line, "swap") == line) {
00156 foundSwap = true;
00157 sscanf(line, "%s %lf %lf ", s1, &s_in, &s_out);
00158
00159 ind1 = getVectIndex((char*)"swap_in", apm.sysMonitorParams, apm.nSysMonitorParams);
00160 ind2 = getVectIndex((char*)"swap_out", apm.sysMonitorParams, apm.nSysMonitorParams);
00161 if (s_in < apm.lastSysVals[ind1] || s_out < apm.lastSysVals[ind2]) {
00162 apm.lastSysVals[ind1] = s_in;
00163 apm.lastSysVals[ind2] = s_out;
00164 throw runtime_error("[ getSwapPages() ] Swap in/out counter reset");
00165 }
00166 swapIn = (s_in - apm.lastSysVals[ind1]) / (crtTime - apm.lastSysInfoSend);
00167 swapOut = (s_out - apm.lastSysVals[ind2]) / (crtTime - apm.lastSysInfoSend);
00168 apm.lastSysVals[ind1] = s_in;
00169 apm.lastSysVals[ind2] = s_out;
00170
00171 }
00172 }
00173
00174 fclose(fp1);
00175
00176 if (!foundPages || !foundSwap) {
00177 throw procutils_error((char*)"[ getSwapPages() ] Could not obtain swap/pages in/out from /proc/stat");
00178 }
00179 #endif
00180 }
00181
00182 void ProcUtils::getLoad(double &load1, double &load5,
00183 double &load15, double &processes)
00184 throw(procutils_error) {
00185 #ifndef WIN32
00186 double v1, v5, v15, activeProcs, totalProcs;
00187 FILE *fp1;
00188
00189 fp1 = fopen("/proc/loadavg", "r");
00190 if (fp1 == NULL)
00191 throw procutils_error((char*)"[ getLoad() ] Could not open /proc/loadavg");
00192
00193 fscanf(fp1, "%lf %lf %lf", &v1, &v5, &v15);
00194 load1 = v1;
00195 load5 = v5;
00196 load15 = v15;
00197
00198 fscanf(fp1, "%lf/%lf", &activeProcs, &totalProcs);
00199 processes = totalProcs;
00200 fclose(fp1);
00201 #endif
00202 }
00203
00204 void ProcUtils::getProcesses(double& processes, double states[])
00205 throw(runtime_error) {
00206 #ifndef WIN32
00207 char *argv[4];
00208 char psstat_f[40];
00209 pid_t mypid = getpid();
00210 pid_t cpid;
00211 int status;
00212 char ch, buf[100];
00213 FILE *pf;
00214
00215 sprintf(psstat_f, "/tmp/apmon_psstat%d", mypid);
00216
00217 switch (cpid = fork()) {
00218 case -1:
00219 throw runtime_error("[ getProcesses() ] Unable to fork()");
00220 case 0:
00221 argv[0] = (char *)"/bin/sh"; argv[1] = (char *)"-c";
00222 sprintf(buf, "ps -A -o state > %s",
00223 psstat_f);
00224 argv[2] = buf;
00225 argv[3] = 0;
00226 execv("/bin/sh", argv);
00227 exit(RET_ERROR);
00228 default:
00229 if (waitpid(cpid, &status, 0) == -1) {
00230 sprintf(buf, "[ getProcesses() ] The number of processes could not be determined");
00231 throw runtime_error(buf);
00232 }
00233 }
00234
00235 pf = fopen(psstat_f, "rt");
00236 if (pf == NULL) {
00237 unlink(psstat_f);
00238 sprintf(buf, "[ getProcesses() ] The number of processes could not be determined");
00239 throw runtime_error(buf);
00240 }
00241
00242 processes = 0;
00243
00244
00245 for (int i = 0; i < NLETTERS; i++)
00246 states[i] = 0.0;
00247 while (fgets(buf, 10, pf) > 0) {
00248 ch = buf[0];
00249 states[ch - 65]++;
00250 processes++;
00251 }
00252
00253 fclose(pf);
00254 unlink(psstat_f);
00255 #endif
00256 }
00257
00258 void ProcUtils::getSysMem(double &totalMem, double &totalSwap)
00259 throw(procutils_error) {
00260 #ifndef WIN32
00261 char s1[20], line[MAX_STRING_LEN];
00262 bool memFound = false, swapFound = false;
00263 double valMem, valSwap;
00264 FILE *fp1;
00265
00266 fp1 = fopen("/proc/meminfo", "r");
00267 if (fp1 == NULL)
00268 throw procutils_error((char*)"[ getSysMem() ] Could not open /proc/meminfo");
00269
00270 while (fgets(line, MAX_STRING_LEN, fp1)) {
00271 if (strstr(line, "MemTotal:") == line) {
00272 sscanf(line, "%s %lf", s1, &valMem);
00273 memFound = true;
00274 continue;
00275 }
00276
00277 if (strstr(line, "SwapTotal:") == line) {
00278 sscanf(line, "%s %lf", s1, &valSwap);
00279 swapFound = true;
00280 continue;
00281 }
00282
00283 }
00284 fclose(fp1);
00285
00286 if (!memFound || !swapFound)
00287 throw procutils_error((char*)"[ getSysMem() ] Could not obtain memory info from /proc/meminfo");
00288 totalMem = valMem;
00289 totalSwap = valSwap;
00290 #endif
00291 }
00292
00293 void ProcUtils::getMemUsed(double &usedMem, double& freeMem,
00294 double &usedSwap, double& freeSwap)
00295 throw(procutils_error) {
00296 #ifndef WIN32
00297 double mFree = 0, mTotal = 0, sFree = 0, sTotal = 0;
00298 char s1[20], line[MAX_STRING_LEN];
00299 bool mFreeFound = false, mTotalFound = false;
00300 bool sFreeFound = false, sTotalFound = false;
00301 FILE *fp1;
00302
00303 fp1 = fopen("/proc/meminfo", "r");
00304 if (fp1 == NULL)
00305 throw procutils_error((char*)"[ getMemUsed() ] Could not open /proc/meminfo");
00306
00307 while (fgets(line, MAX_STRING_LEN, fp1)) {
00308 if (strstr(line, "MemTotal:") == line) {
00309 sscanf(line, "%s %lf", s1, &mTotal);
00310 mTotalFound = true;
00311 continue;
00312 }
00313
00314 if (strstr(line, "MemFree:") == line) {
00315 sscanf(line, "%s %lf", s1, &mFree);
00316 mFreeFound = true;
00317 continue;
00318 }
00319
00320 if (strstr(line, "SwapTotal:") == line) {
00321 sscanf(line, "%s %lf", s1, &sTotal);
00322 sTotalFound = true;
00323 continue;
00324 }
00325
00326 if (strstr(line, "SwapFree:") == line) {
00327 sscanf(line, "%s %lf", s1, &sFree);
00328 sFreeFound = true;
00329 continue;
00330 }
00331
00332 }
00333 fclose(fp1);
00334
00335 if (!mFreeFound || !mTotalFound || !sFreeFound || !sTotalFound)
00336 throw procutils_error((char*)"[ getMemUsed() ] Could not obtain memory info from /proc/meminfo");
00337
00338 usedMem = (mTotal - mFree) / 1024;
00339 freeMem = mFree / 1024;
00340 usedSwap = (sTotal - sFree) / 1024;
00341 freeSwap = sFree / 1024;
00342 #endif
00343 }
00344
00345 void ProcUtils::getNetworkInterfaces(int &nInterfaces,
00346 char names[][20]) throw(procutils_error) {
00347 #ifndef WIN32
00348 char line[MAX_STRING_LEN], *tmp;
00349
00350
00351 FILE *fp1;
00352
00353 nInterfaces = 0;
00354
00355 fp1 = fopen("/proc/net/dev", "r");
00356 if (fp1 == NULL)
00357 throw procutils_error((char*)"[ getMemUsed() ] Could not open /proc/net/dev");
00358 while (fgets(line, MAX_STRING_LEN, fp1)) {
00359 if (strchr(line, ':') == NULL)
00360 continue;
00361
00362 tmp = strtok(line, " :");
00363
00364 if (strcmp(tmp, "lo") == 0)
00365 continue;
00366
00367 strcpy(names[nInterfaces], tmp);
00368 nInterfaces++;
00369 }
00370
00371 fclose(fp1);
00372 #endif
00373 }
00374
00375 void ProcUtils::getNetInfo(ApMon& apm, double **vNetIn,
00376 double **vNetOut, double **vNetErrs)
00377 throw(runtime_error, procutils_error) {
00378 #ifndef WIN32
00379 double *netIn, *netOut, *netErrs, bytesReceived, bytesSent;
00380 int errs;
00381 char line[MAX_STRING_LEN], msg[MAX_STRING_LEN];
00382
00383
00384 char *tmp, *tok;
00385 double bootTime = 0;
00386 FILE *fp1;
00387 time_t crtTime = time(NULL);
00388 int ind, i;
00389
00390 if (apm.lastSysInfoSend == 0) {
00391 try {
00392 bootTime = getBootTime();
00393 } catch (procutils_error& ) {
00394 logger(WARNING, "[ getNetInfo() ] Error obtaining boot time. The first system monitoring datagram will contain incorrect data.");
00395 bootTime = 0;
00396 }
00397 }
00398
00399 if (crtTime <= apm.lastSysInfoSend)
00400 throw runtime_error("[ getNetInfo() ] Current time <= time of the previous sysInfoSend");
00401
00402 fp1 = fopen("/proc/net/dev", "r");
00403 if (fp1 == NULL)
00404 throw procutils_error((char*)"[ getNetInfo() ] Could not open /proc/net/dev");
00405
00406 netIn = (double *)malloc(apm.nInterfaces * sizeof(double));
00407 netOut = (double *)malloc(apm.nInterfaces * sizeof(double));
00408 netErrs = (double *)malloc(apm.nInterfaces * sizeof(double));
00409
00410 while (fgets(line, MAX_STRING_LEN, fp1)) {
00411 if (strchr(line, ':') == NULL)
00412 continue;
00413 tmp = strtok(line, " :");
00414
00415
00416 if (strcmp(tmp, "lo") == 0)
00417 continue;
00418
00419
00420 ind = -1;
00421 for (i = 0; i < apm.nInterfaces; i++)
00422 if (strcmp(apm.interfaceNames[i], tmp) == 0) {
00423 ind = i;
00424 break;
00425 }
00426
00427 if (ind < 0) {
00428 fclose(fp1);
00429 free(netIn); free(netOut); free(netErrs);
00430 sprintf(msg, "[ getNetInfo() ] Could not find interface %s in /proc/net/dev",
00431 tmp);
00432 throw runtime_error(msg);
00433 }
00434
00435
00436 tok = strtok(NULL, " ");
00437 bytesReceived = atof(tok);
00438 tok = strtok(NULL, " ");
00439 tok = strtok(NULL, " ");
00440 errs = atoi(tok);
00441
00442 for (i = 1; i <= 5; i++)
00443 tok = strtok(NULL, " ");
00444
00445 tok = strtok(NULL, " ");
00446 bytesSent = atof(tok);
00447 tok = strtok(NULL, " ");
00448 tok = strtok(NULL, " ");
00449 errs += atoi(tok);
00450
00451
00452
00453 if (bytesReceived < apm.lastBytesReceived[ind] || bytesSent <
00454 apm.lastBytesSent[ind] || errs < apm.lastNetErrs[ind]) {
00455 apm.lastBytesReceived[ind] = bytesReceived;
00456 apm.lastBytesSent[ind] = bytesSent;
00457 apm.lastNetErrs[ind] = errs;
00458 fclose(fp1);
00459 free(netIn); free(netOut); free(netErrs);
00460 throw runtime_error("[ getNetInfo() ] Network interface(s) restarted.");
00461 }
00462
00463 if (apm.lastSysInfoSend == 0) {
00464 netIn[ind] = bytesReceived/(crtTime - bootTime);
00465 netOut[ind] = bytesSent/(crtTime - bootTime);
00466 netErrs[ind] = errs;
00467 }
00468 else {
00469 netIn[ind] = (bytesReceived - apm.lastBytesReceived[ind]) / (crtTime -
00470 apm.lastSysInfoSend);
00471 netIn[ind] /= 1024;
00472 netOut[ind] = (bytesSent - apm.lastBytesSent[ind]) / (crtTime -
00473 apm.lastSysInfoSend);
00474 netOut[ind] /= 1024;
00475
00476 netErrs[ind] = errs;
00477 }
00478
00479 apm.lastBytesReceived[ind] = bytesReceived;
00480 apm.lastBytesSent[ind] = bytesSent;
00481 apm.lastNetErrs[ind] = errs;
00482 }
00483
00484 fclose(fp1);
00485 *vNetIn = netIn;
00486 *vNetOut = netOut;
00487 *vNetErrs = netErrs;
00488 #endif
00489 }
00490
00491 int ProcUtils::getNumCPUs() throw(procutils_error) {
00492 #ifdef WIN32
00493 return 0;
00494 #else
00495 int numCPUs = 0;
00496 char line[MAX_STRING_LEN];
00497
00498 FILE *fp = fopen("/proc/stat", "r");
00499
00500 if (fp == NULL)
00501 throw procutils_error((char*)"[ getNumCPUs() ] Could not open /proc/stat.");
00502
00503 while(fgets(line, MAX_STRING_LEN, fp)) {
00504 if (strstr(line, "cpu") == line && isdigit(line[3]))
00505 numCPUs++;
00506 }
00507
00508 fclose(fp);
00509 return numCPUs;
00510 #endif
00511 }
00512
00513 void ProcUtils::getCPUInfo(ApMon& apm) throw(procutils_error) {
00514 #ifndef WIN32
00515 double freq = 0;
00516 char line[MAX_STRING_LEN], s1[100], s2[100], s3[100];
00517
00518
00519 char *tmp, *tmp_trim;
00520 bool freqFound = false, bogomipsFound = false;
00521
00522 FILE *fp = fopen("/proc/cpuinfo", "r");
00523 if (fp == NULL)
00524 throw procutils_error((char*)"[ getCPUInfo() ] Could not open /proc/cpuinfo");
00525
00526 while (fgets(line, MAX_STRING_LEN, fp)) {
00527 if (strstr(line, "cpu MHz") == line) {
00528 sscanf(line, "%s %s %s %lf", s1, s2, s3, &freq);
00529 apm.currentGenVals[GEN_CPU_MHZ] = freq;
00530 freqFound = true;
00531 continue;
00532 }
00533
00534 if (strstr(line, "bogomips") == line) {
00535 sscanf(line, "%s %s %lf", s1, s2, &(apm.currentGenVals[GEN_BOGOMIPS]));
00536 bogomipsFound = true;
00537 continue;
00538 }
00539
00540 if (strstr(line, "vendor_id") == line) {
00541 tmp = strtok(line, ":");
00542
00543 tmp = strtok(NULL, ":");
00544 tmp_trim = trimString(tmp);
00545 strcpy(apm.cpuVendor, tmp_trim);
00546 free(tmp_trim);
00547 continue;
00548 }
00549
00550 if (strstr(line, "cpu family") == line) {
00551 tmp = strtok(line, ":");
00552 tmp = strtok(NULL, ":");
00553 tmp_trim = trimString(tmp);
00554 strcpy(apm.cpuFamily, tmp_trim);
00555 free(tmp_trim);
00556 continue;
00557 }
00558
00559 if (strstr(line, "model") == line && strstr(line, "model name") != line) {
00560 tmp = strtok(line, ":");
00561 tmp = strtok(NULL, ":");
00562 tmp_trim = trimString(tmp);
00563 strcpy(apm.cpuModel, tmp_trim);
00564 free(tmp_trim);
00565 continue;
00566 }
00567
00568 if (strstr(line, "model name") == line) {
00569 tmp = strtok(line, ":");
00570
00571 tmp = strtok(NULL, ":");
00572 tmp_trim = trimString(tmp);
00573 strcpy(apm.cpuModelName, tmp_trim);
00574 free(tmp_trim);
00575 continue;
00576 }
00577 }
00578
00579 fclose(fp);
00580 if (!freqFound || !bogomipsFound)
00581 throw procutils_error((char*)"[ getCPUInfo() ] Could not find frequency or bogomips in /proc/cpuinfo");
00582 #endif
00583 }
00584
00588 long ProcUtils::getBootTime() throw (procutils_error) {
00589 #ifdef WIN32
00590 return 0;
00591 #else
00592 char line[MAX_STRING_LEN], s[MAX_STRING_LEN];
00593 long btime = 0;
00594 FILE *fp = fopen("/proc/stat", "rt");
00595 if (fp == NULL)
00596 throw procutils_error((char*)"[ getBootTime() ] Could not open /proc/stat");
00597
00598 while (fgets(line, MAX_STRING_LEN, fp)) {
00599 if (strstr(line, "btime") == line) {
00600 sscanf(line, "%s %ld", s, &btime);
00601 break;
00602 }
00603 }
00604 fclose(fp);
00605 if (btime == 0)
00606 throw procutils_error((char*)"[ getBootTime() ] Could not find boot time in /proc/stat");
00607 return btime;
00608 #endif
00609 }
00610
00611
00612 double ProcUtils::getUpTime() throw(procutils_error) {
00613 #ifdef WIN32
00614 return 0;
00615 #else
00616 double uptime = 0;
00617 FILE *fp = fopen("/proc/uptime", "rt");
00618 if (fp == NULL) {
00619 throw procutils_error((char*)"[ getUpTime() ] Could not open /proc/uptime");
00620 }
00621
00622 fscanf(fp, "%lf", &uptime);
00623 fclose(fp);
00624
00625 if (uptime <= 0) {
00626 throw procutils_error((char*)"[ getUpTime() ] Could not find uptime in /proc/uptime");
00627 }
00628 return uptime / (24 * 3600);
00629 #endif
00630 }
00631
00632 int ProcUtils::countOpenFiles(long pid) throw(procutils_error) {
00633 #ifdef WIN32
00634 return 0;
00635 #else
00636 char dirname[50];
00637 char msg[MAX_STRING_LEN];
00638 DIR *dir;
00639 int cnt = 0;
00640
00641
00642 sprintf(dirname, "/proc/%ld/fd", pid);
00643 dir = opendir(dirname);
00644 if (dir == NULL) {
00645 sprintf(msg, "[ countOpenFiles() ] Could not open %s", dirname);
00646 throw procutils_error(msg);
00647 }
00648
00649
00650 while (readdir(dir) != NULL) {
00651 cnt++;
00652 }
00653
00654 closedir(dir);
00655
00656
00657 cnt -= 2;
00658 if (cnt < 0) {
00659 sprintf(msg, "[ countOpenFiles() ] Directory %s has less than 2 entries",
00660 dirname);
00661 logger(FINE, msg);
00662 cnt = 0;
00663 }
00664
00665 return cnt;
00666 #endif
00667 }
00668
00669 void ProcUtils::getNetstatInfo(ApMon& apm, double nsockets[],
00670 double tcp_states[])
00671 throw(runtime_error) {
00672
00673
00674
00675 int i;
00676 for (i = 0; i < 4; i++)
00677 nsockets[i] = 0.0;
00678 for (i = 0; i < N_TCP_STATES; i++)
00679 tcp_states[i] = 0.0;
00680
00681 #ifndef WIN32
00682 char *argv[4];
00683 char netstat_f[40];
00684 pid_t mypid = getpid();
00685 pid_t cpid;
00686 int status, idx;
00687 char buf[100], msg[100];
00688 char *pbuf = buf, *tmp, *tmp2;
00689 FILE *pf;
00690
00691 sprintf(netstat_f, "/tmp/apmon_netstat%d", mypid);
00692
00693 switch (cpid = fork()) {
00694 case -1:
00695 throw runtime_error("[ getNetstatInfo() ] Unable to fork()");
00696 case 0:
00697 argv[0] = (char *)"/bin/sh"; argv[1] = (char *)"-c";
00698 sprintf(buf, "netstat -an > %s",
00699 netstat_f);
00700 argv[2] = buf;
00701 argv[3] = 0;
00702 execv("/bin/sh", argv);
00703 exit(RET_ERROR);
00704 default:
00705 if (waitpid(cpid, &status, 0) == -1) {
00706 sprintf(msg, "[ getNetstatInfo() ] The netstat information could not be collected");
00707 throw runtime_error(msg);
00708 }
00709 }
00710
00711 pf = fopen(netstat_f, "rt");
00712 if (pf == NULL) {
00713 unlink(netstat_f);
00714 sprintf(msg, "[ getNetstatInfo() ] The netstat information could not be collected");
00715 throw runtime_error(msg);
00716 }
00717
00718 while (fgets(buf, 200, pf) > 0) {
00719 tmp = strtok_r(buf, " \t\n", &pbuf);
00720 if (strstr(tmp, "tcp") == tmp) {
00721 nsockets[SOCK_TCP]++;
00722
00723
00724 for (i = 1; i <= 5; i++)
00725 tmp2 = strtok_r(NULL, " \t\n", &pbuf);
00726
00727 idx = getVectIndex(tmp2, apm.socketStatesMapTCP, N_TCP_STATES);
00728 if (idx >= 0) {
00729 tcp_states[idx]++;
00730 } else {
00731 sprintf(msg, "[ getNestatInfo() ] Invalid socket state: %s q", tmp2);
00732 logger(WARNING, msg);
00733 }
00734 } else {
00735 if (strstr(tmp, "udp") == tmp) {
00736 nsockets[SOCK_UDP]++;
00737 } else {
00738 if (strstr(tmp, "unix") == tmp)
00739 nsockets[SOCK_UNIX]++;
00740 else if (strstr(tmp, "icm") == tmp)
00741 nsockets[SOCK_ICM]++;
00742 }
00743 }
00744 }
00745
00746 fclose(pf);
00747 unlink(netstat_f);
00748 #endif
00749 }