void AbstractRPM::pollPings() { #ifdef USE_PING pingobj_t *pingContext = ping_construct(); std::map<Wt::WString, Wt::WString> ipToComputer; double timeout = 0.1; if (ping_setopt(pingContext, PING_OPT_TIMEOUT, (void *)&timeout)) std::cerr << "ping_setopt failed: " << ping_get_error(pingContext) << std::endl; for (size_t i = 0; i < _computers.size(); i++) { if (_computers[i].ipAddress != Wt::WString()) { if (ping_host_add(pingContext, _computers[i].ipAddress.toUTF8().c_str())) std::cerr << "ping_host_add failed: " << ping_get_error(pingContext) << std::endl; ipToComputer[_computers[i].ipAddress] = _computers[i].name; } } while (1) { { boost::lock_guard<boost::mutex> lock(pollingThreadsExitLock); if (shouldExit) break; } if (ping_send(pingContext) < 0) std::cerr << "ping_send failed: " << ping_get_error(pingContext) << std::endl; pingobj_iter_t *iter; for (iter = ping_iterator_get(pingContext); iter != NULL; iter = ping_iterator_next(iter)) { double ping; size_t size = sizeof(double); if (ping_iterator_get_info(iter, PING_INFO_LATENCY, (void*)&ping, &size)) std::cerr << "ping_iterator_get_info/latency failed" << std::endl; char hostname[101]; size_t hostname_len = sizeof(hostname); if (ping_iterator_get_info(iter, PING_INFO_USERNAME, (void*)hostname, &hostname_len)) std::cerr << "ping_iterator_get_info/hostname failed" << std::endl; setPingDelay(ipToComputer[hostname], ping); } sleep(1); } ping_destroy(pingContext); #endif }
int main (int argc, char **argv) { /* Local Vars */ int rv; pingobj_t *oping; pingobj_iter_t *iter; uint32_t dropped=0, num=0; int ttl=0; double rt, rta=0; char haddr[40]; size_t data_len, buf_len; /* Set signal handling and alarm */ if (signal(SIGALRM, timeout_alarm_handler) == SIG_ERR) critical("Setup SIGALRM trap failed!"); /* Process check arguments */ if (process_arguments(argc, argv) != OK) unknown("Parsing arguments failed!"); /* Start plugin timeout */ alarm(mp_timeout); /* Init liboping */ oping = ping_construct(); if (oping == NULL) unknown("Can't initialize liboping"); rv = ping_setopt(oping, PING_OPT_AF, &ipv); if (rv != 0) unknown("liboping setup Error: %s", ping_get_error(oping)); rv = ping_setopt(oping, PING_OPT_DATA, "monitoringplug/check_oping based on liboping. "); if (rv != 0) unknown("liboping setup Error: %s", ping_get_error(oping)); if (interface) { rv = ping_setopt(oping, PING_OPT_DEVICE, (char *)interface); if (rv != 0) unknown("liboping setup Error: %s", ping_get_error(oping)); } if (ttl) { rv = ping_setopt(oping, PING_OPT_TTL, &ttl); if (rv != 0) unknown("liboping setup Error: %s", ping_get_error(oping)); } rv = ping_host_add(oping, hostname); if (rv != 0) unknown("liboping setup Error: %s", ping_get_error(oping)); for (; packets > 0; packets--) { rv = ping_send(oping); if (rv < 0) critical("Send Error: %s", ping_get_error(oping)); for (iter = ping_iterator_get(oping); iter != NULL; iter = ping_iterator_next(iter)) { buf_len = sizeof(dropped); rv = ping_iterator_get_info(iter, PING_INFO_DROPPED, &dropped, &buf_len); if (rv != 0) unknown("liboping ping_iterator_get_info failed!"); buf_len = sizeof(rt); rv = ping_iterator_get_info(iter, PING_INFO_LATENCY, &rt, &buf_len); if (rv != 0) unknown("liboping ping_iterator_get_info failed!"); rta += rt; buf_len = sizeof(num); rv = ping_iterator_get_info(iter, PING_INFO_SEQUENCE, &num, &buf_len); if (rv != 0) unknown("liboping ping_iterator_get_info failed!"); data_len = 0; rv = ping_iterator_get_info(iter, PING_INFO_DATA, NULL, &data_len); if (rv != 0) unknown("liboping ping_iterator_get_info failed!"); buf_len = sizeof(haddr); rv = ping_iterator_get_info(iter, PING_INFO_ADDRESS, haddr, &buf_len); if (rv != 0) unknown("liboping ping_iterator_get_info failed!"); buf_len = sizeof(ttl); rv = ping_iterator_get_info(iter, PING_INFO_RECV_TTL, &ttl, &buf_len); if (rv != 0) unknown("liboping ping_iterator_get_info failed!"); if (mp_verbose > 0 && ttl > 0) printf("%zu bytes from %s (%s): icmp_seq=%u ttl=%i time=%.2f ms\n", data_len, hostname, haddr, num, ttl, rt); } if (quick && num > 0 && get_status((float)(rta/num), rta_thresholds) == STATE_OK && get_status((dropped*100)/num, lost_thresholds) == STATE_OK) { break; } else if (packets > 1) { if (interval.tv_sec || interval.tv_nsec) nanosleep(&interval, NULL); else sleep(1); } } if (num == 0) critical("PING_INFO_SEQUENCE is 0"); mp_perfdata_float("rta", (float)(rta/num), "s", rta_thresholds); mp_perfdata_int("pl", (int)(dropped*100)/num, "%", lost_thresholds); int result1, result2; result1 = get_status((float)(rta/num), rta_thresholds); result2 = get_status((dropped*100)/num, lost_thresholds); result1 = result1 > result2 ? result1 : result2; free_threshold(rta_thresholds); free_threshold(lost_thresholds); switch(result1) { case STATE_OK: ok("Packet loss = %d%, RTA = %.2f ms", (int)(dropped*100)/num, (float)(rta/num)); break; case STATE_WARNING: warning("Packet loss = %d%, RTA = %.2f ms", (int)(dropped*100)/num, (float)(rta/num)); break; case STATE_CRITICAL: critical("Packet loss = %d%, RTA = %.2f ms", (int)(dropped*100)/num, (float)(rta/num)); break; } critical("You should never reach this point."); }
static void *ping_thread (void *arg) /* {{{ */ { static pingobj_t *pingobj = NULL; struct timeval tv_begin; struct timeval tv_end; struct timespec ts_wait; struct timespec ts_int; hostlist_t *hl; int count; c_complain_t complaint = C_COMPLAIN_INIT_STATIC; pthread_mutex_lock (&ping_lock); pingobj = ping_construct (); if (pingobj == NULL) { ERROR ("ping plugin: ping_construct failed."); ping_thread_error = 1; pthread_mutex_unlock (&ping_lock); return ((void *) -1); } if (ping_source != NULL) if (ping_setopt (pingobj, PING_OPT_SOURCE, (void *) ping_source) != 0) ERROR ("ping plugin: Failed to set source address: %s", ping_get_error (pingobj)); #ifdef HAVE_OPING_1_3 if (ping_device != NULL) if (ping_setopt (pingobj, PING_OPT_DEVICE, (void *) ping_device) != 0) ERROR ("ping plugin: Failed to set device: %s", ping_get_error (pingobj)); #endif ping_setopt (pingobj, PING_OPT_TIMEOUT, (void *) &ping_timeout); ping_setopt (pingobj, PING_OPT_TTL, (void *) &ping_ttl); if (ping_data != NULL) ping_setopt (pingobj, PING_OPT_DATA, (void *) ping_data); /* Add all the hosts to the ping object. */ count = 0; for (hl = hostlist_head; hl != NULL; hl = hl->next) { int tmp_status; tmp_status = ping_host_add (pingobj, hl->host); if (tmp_status != 0) WARNING ("ping plugin: ping_host_add (%s) failed: %s", hl->host, ping_get_error (pingobj)); else count++; } if (count == 0) { ERROR ("ping plugin: No host could be added to ping object. Giving up."); ping_thread_error = 1; pthread_mutex_unlock (&ping_lock); return ((void *) -1); } /* Set up `ts_int' */ { double temp_sec; double temp_nsec; temp_nsec = modf (ping_interval, &temp_sec); ts_int.tv_sec = (time_t) temp_sec; ts_int.tv_nsec = (long) (temp_nsec * 1000000000L); } while (ping_thread_loop > 0) { int status; _Bool send_successful = 0; if (gettimeofday (&tv_begin, NULL) < 0) { char errbuf[1024]; ERROR ("ping plugin: gettimeofday failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); ping_thread_error = 1; break; } pthread_mutex_unlock (&ping_lock); status = ping_send (pingobj); if (status < 0) { c_complain (LOG_ERR, &complaint, "ping plugin: ping_send failed: %s", ping_get_error (pingobj)); } else { c_release (LOG_NOTICE, &complaint, "ping plugin: ping_send succeeded."); send_successful = 1; } pthread_mutex_lock (&ping_lock); if (ping_thread_loop <= 0) break; if (send_successful) (void) ping_dispatch_all (pingobj); if (gettimeofday (&tv_end, NULL) < 0) { char errbuf[1024]; ERROR ("ping plugin: gettimeofday failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); ping_thread_error = 1; break; } /* Calculate the absolute time until which to wait and store it in * `ts_wait'. */ time_calc (&ts_wait, &ts_int, &tv_begin, &tv_end); pthread_cond_timedwait (&ping_cond, &ping_lock, &ts_wait); if (ping_thread_loop <= 0) break; } /* while (ping_thread_loop > 0) */ pthread_mutex_unlock (&ping_lock); ping_destroy (pingobj); return ((void *) 0); } /* }}} void *ping_thread */
static int ping_dispatch_all (pingobj_t *pingobj) /* {{{ */ { pingobj_iter_t *iter; hostlist_t *hl; int status; for (iter = ping_iterator_get (pingobj); iter != NULL; iter = ping_iterator_next (iter)) { /* {{{ */ char userhost[NI_MAXHOST]; double latency; size_t param_size; param_size = sizeof (userhost); status = ping_iterator_get_info (iter, #ifdef PING_INFO_USERNAME PING_INFO_USERNAME, #else PING_INFO_HOSTNAME, #endif userhost, ¶m_size); if (status != 0) { WARNING ("ping plugin: ping_iterator_get_info failed: %s", ping_get_error (pingobj)); continue; } for (hl = hostlist_head; hl != NULL; hl = hl->next) if (strcmp (userhost, hl->host) == 0) break; if (hl == NULL) { WARNING ("ping plugin: Cannot find host %s.", userhost); continue; } param_size = sizeof (latency); status = ping_iterator_get_info (iter, PING_INFO_LATENCY, (void *) &latency, ¶m_size); if (status != 0) { WARNING ("ping plugin: ping_iterator_get_info failed: %s", ping_get_error (pingobj)); continue; } hl->pkg_sent++; if (latency >= 0.0) { hl->pkg_recv++; hl->latency_total += latency; hl->latency_squared += (latency * latency); /* reset missed packages counter */ hl->pkg_missed = 0; } else hl->pkg_missed++; /* if the host did not answer our last N packages, trigger a resolv. */ if ((ping_max_missed >= 0) && (hl->pkg_missed >= ((uint32_t) ping_max_missed))) { /* {{{ */ /* we reset the missed package counter here, since we only want to * trigger a resolv every N packages and not every package _AFTER_ N * missed packages */ hl->pkg_missed = 0; WARNING ("ping plugin: host %s has not answered %d PING requests," " triggering resolve", hl->host, ping_max_missed); /* we trigger the resolv simply be removeing and adding the host to our * ping object */ status = ping_host_remove (pingobj, hl->host); if (status != 0) { WARNING ("ping plugin: ping_host_remove (%s) failed.", hl->host); } else { status = ping_host_add (pingobj, hl->host); if (status != 0) ERROR ("ping plugin: ping_host_add (%s) failed.", hl->host); } } /* }}} ping_max_missed */ } /* }}} for (iter) */ return (0); } /* }}} int ping_dispatch_all */