// Display all processes and relevant network traffic using show function void do_refresh() { refreshconninode(); refreshcount++; ProcList * curproc = processes; ProcList * previousproc = NULL; int nproc = processes->size(); /* initialise to null pointers */ Line * lines [nproc]; int n = 0; #ifndef NDEBUG // initialise to null pointers for (int i = 0; i < nproc; i++) lines[i] = NULL; #endif while (curproc != NULL) { // walk though its connections, summing up their data, and // throwing away connections that haven't received a package // in the last PROCESSTIMEOUT seconds. assert (curproc != NULL); assert (curproc->getVal() != NULL); assert (nproc == processes->size()); /* remove timed-out processes (unless it's one of the the unknown process) */ if ((curproc->getVal()->getLastPacket() + PROCESSTIMEOUT <= curtime.tv_sec) && (curproc->getVal() != unknowntcp) && (curproc->getVal() != unknownudp) && (curproc->getVal() != unknownip)) { if (DEBUG) std::cout << "PROC: Deleting process\n"; ProcList * todelete = curproc; Process * p_todelete = curproc->getVal(); if (previousproc) { previousproc->next = curproc->next; curproc = curproc->next; } else { processes = curproc->getNext(); curproc = processes; } delete todelete; delete p_todelete; nproc--; //continue; } else { // add a non-timed-out process to the list of stuff to show float value_sent = 0, value_recv = 0; if (viewMode == VIEWMODE_KBPS) { //std::cout << "kbps viemode" << std::endl; getkbps (curproc->getVal(), &value_recv, &value_sent); } else if (viewMode == VIEWMODE_TOTAL_KB) { //std::cout << "total viemode" << std::endl; gettotalkb(curproc->getVal(), &value_recv, &value_sent); } else if (viewMode == VIEWMODE_TOTAL_MB) { //std::cout << "total viemode" << std::endl; gettotalmb(curproc->getVal(), &value_recv, &value_sent); } else if (viewMode == VIEWMODE_TOTAL_B) { //std::cout << "total viemode" << std::endl; gettotalb(curproc->getVal(), &value_recv, &value_sent); } else { forceExit(false, "Invalid viewMode: %d", viewMode); } uid_t uid = curproc->getVal()->getUid(); #ifndef NDEBUG struct passwd * pwuid = getpwuid(uid); assert (pwuid != NULL); // value returned by pwuid should not be freed, according to // Petr Uzel. //free (pwuid); #endif assert (curproc->getVal()->pid >= 0); assert (n < nproc); lines[n] = new Line (curproc->getVal()->name, value_recv, value_sent, curproc->getVal()->pid, uid, curproc->getVal()->devicename); previousproc = curproc; curproc = curproc->next; n++; #ifndef NDEBUG assert (nproc == processes->size()); if (curproc == NULL) assert (n-1 < nproc); else assert (n < nproc); #endif } } /* sort the accumulated lines */ qsort (lines, nproc, sizeof(Line *), GreatestFirst); if (tracemode || DEBUG) show_trace(lines, nproc); else show_ncurses(lines, nproc); if (refreshlimit != 0 && refreshcount >= refreshlimit) quit_cb(0); }
// Display all processes and relevant network traffic using show function void do_refresh() { int rows; // number of terminal rows int cols; // number of terminal columns unsigned int proglen; // max length of the "PROGRAM" column getmaxyx(stdscr, rows, cols); /* find the boundaries of the screeen */ if (cols < 60) { clear(); mvprintw(0,0, "The terminal is too narrow! Please make it wider.\nI'll wait..."); return; } if (cols > PROGNAME_WIDTH) cols = PROGNAME_WIDTH; proglen = cols - 53; refreshconninode(); if (DEBUG || tracemode) { std::cout << "\nRefreshing:\n"; } else { clear(); mvprintw (0, 0, "%s", caption->c_str()); attron(A_REVERSE); mvprintw (2, 0, " PID USER %-*.*s DEV SENT RECEIVED ", proglen, proglen, "PROGRAM"); attroff(A_REVERSE); } ProcList * curproc = processes; ProcList * previousproc = NULL; int nproc = processes->size(); /* initialise to null pointers */ Line * lines [nproc]; int n = 0, i = 0; double sent_global = 0; double recv_global = 0; #ifndef NDEBUG // initialise to null pointers for (int i = 0; i < nproc; i++) lines[i] = NULL; #endif while (curproc != NULL) { // walk though its connections, summing up their data, and // throwing away connections that haven't received a package // in the last PROCESSTIMEOUT seconds. assert (curproc != NULL); assert (curproc->getVal() != NULL); assert (nproc == processes->size()); /* remove timed-out processes (unless it's one of the the unknown process) */ if ((curproc->getVal()->getLastPacket() + PROCESSTIMEOUT <= curtime.tv_sec) && (curproc->getVal() != unknowntcp) && (curproc->getVal() != unknownudp) && (curproc->getVal() != unknownip)) { if (DEBUG) std::cout << "PROC: Deleting process\n"; ProcList * todelete = curproc; Process * p_todelete = curproc->getVal(); if (previousproc) { previousproc->next = curproc->next; curproc = curproc->next; } else { processes = curproc->getNext(); curproc = processes; } delete todelete; delete p_todelete; nproc--; //continue; } else { // add a non-timed-out process to the list of stuff to show float value_sent = 0, value_recv = 0; if (viewMode == VIEWMODE_KBPS) { //std::cout << "kbps viemode" << std::endl; getkbps (curproc->getVal(), &value_recv, &value_sent); } else if (viewMode == VIEWMODE_TOTAL_KB) { //std::cout << "total viemode" << std::endl; gettotalkb(curproc->getVal(), &value_recv, &value_sent); } else if (viewMode == VIEWMODE_TOTAL_MB) { //std::cout << "total viemode" << std::endl; gettotalmb(curproc->getVal(), &value_recv, &value_sent); } else if (viewMode == VIEWMODE_TOTAL_B) { //std::cout << "total viemode" << std::endl; gettotalb(curproc->getVal(), &value_recv, &value_sent); } else { forceExit(false, "Invalid viewMode: %d", viewMode); } uid_t uid = curproc->getVal()->getUid(); #ifndef NDEBUG struct passwd * pwuid = getpwuid(uid); assert (pwuid != NULL); // value returned by pwuid should not be freed, according to // Petr Uzel. //free (pwuid); #endif assert (curproc->getVal()->pid >= 0); assert (n < nproc); lines[n] = new Line (curproc->getVal()->name, value_recv, value_sent, curproc->getVal()->pid, uid, curproc->getVal()->devicename); previousproc = curproc; curproc = curproc->next; n++; #ifndef NDEBUG assert (nproc == processes->size()); if (curproc == NULL) assert (n-1 < nproc); else assert (n < nproc); #endif } } /* sort the accumulated lines */ qsort (lines, nproc, sizeof(Line *), GreatestFirst); /* print them */ for (i=0; i<nproc; i++) { if (i+3 < rows) lines[i]->show(i+3, proglen); recv_global += lines[i]->recv_value; sent_global += lines[i]->sent_value; delete lines[i]; } if (tracemode || DEBUG) { /* print the 'unknown' connections, for debugging */ ConnList * curr_unknownconn = unknowntcp->connections; while (curr_unknownconn != NULL) { std::cout << "Unknown connection: " << curr_unknownconn->getVal()->refpacket->gethashstring() << std::endl; curr_unknownconn = curr_unknownconn->getNext(); } } if ((!tracemode) && (!DEBUG)){ attron(A_REVERSE); int totalrow = std::min(rows-1, 3+1+i); mvprintw (totalrow, 0, " TOTAL %-*.*s %10.3f %10.3f ", proglen, proglen, " ", sent_global, recv_global); if (viewMode == VIEWMODE_KBPS) { mvprintw (3+1+i, cols - 7, "KB/sec "); } else if (viewMode == VIEWMODE_TOTAL_B) { mvprintw (3+1+i, cols - 7, "B "); } else if (viewMode == VIEWMODE_TOTAL_KB) { mvprintw (3+1+i, cols - 7, "KB "); } else if (viewMode == VIEWMODE_TOTAL_MB) { mvprintw (3+1+i, cols - 7, "MB "); } attroff(A_REVERSE); mvprintw (totalrow+1, 0, ""); refresh(); } }
static void nethogsmonitor_handle_update(NethogsMonitorCallback cb) { refreshconninode(); refreshcount++; ProcList *curproc = processes; ProcList *previousproc = NULL; int nproc = processes->size(); while (curproc != NULL) { // walk though its connections, summing up their data, and // throwing away connections that haven't received a package // in the last PROCESSTIMEOUT seconds. assert(curproc != NULL); assert(curproc->getVal() != NULL); assert(nproc == processes->size()); /* remove timed-out processes (unless it's one of the unknown process) */ if ((curproc->getVal()->getLastPacket() + PROCESSTIMEOUT <= curtime.tv_sec) && (curproc->getVal() != unknowntcp) && (curproc->getVal() != unknownudp) && (curproc->getVal() != unknownip)) { if (DEBUG) std::cout << "PROC: Deleting process\n"; NethogsRecordMap::iterator it = monitor_record_map.find(curproc); if (it != monitor_record_map.end()) { NethogsMonitorRecord &data = it->second; (*cb)(NETHOGS_APP_ACTION_REMOVE, &data); monitor_record_map.erase(curproc); } ProcList *todelete = curproc; Process *p_todelete = curproc->getVal(); if (previousproc) { previousproc->next = curproc->next; curproc = curproc->next; } else { processes = curproc->getNext(); curproc = processes; } delete todelete; delete p_todelete; nproc--; // continue; } else { const u_int32_t uid = curproc->getVal()->getUid(); u_int32_t sent_bytes; u_int32_t recv_bytes; float sent_kbs; float recv_kbs; curproc->getVal()->getkbps(&recv_kbs, &sent_kbs); curproc->getVal()->gettotal(&recv_bytes, &sent_bytes); // notify update bool const new_data = (monitor_record_map.find(curproc) == monitor_record_map.end()); NethogsMonitorRecord &data = monitor_record_map[curproc]; bool data_change = false; if (new_data) { data_change = true; static int record_id = 0; ++record_id; memset(&data, 0, sizeof(data)); data.record_id = record_id; data.name = curproc->getVal()->name; data.pid = curproc->getVal()->pid; } data.device_name = curproc->getVal()->devicename; #define NHM_UPDATE_ONE_FIELD(TO, FROM) \ if ((TO) != (FROM)) { \ TO = FROM; \ data_change = true; \ } NHM_UPDATE_ONE_FIELD(data.uid, uid) NHM_UPDATE_ONE_FIELD(data.sent_bytes, sent_bytes) NHM_UPDATE_ONE_FIELD(data.recv_bytes, recv_bytes) NHM_UPDATE_ONE_FIELD(data.sent_kbs, sent_kbs) NHM_UPDATE_ONE_FIELD(data.recv_kbs, recv_kbs) #undef NHM_UPDATE_ONE_FIELD if (data_change) { (*cb)(NETHOGS_APP_ACTION_SET, &data); } // next previousproc = curproc; curproc = curproc->next; } } }