void ifstats(const struct OPTIONS *options, struct filterstate *ofilter, time_t facilitytime) { int logging = options->logging; struct iftab table; int pkt_result = 0; struct iflist *ptmp = NULL; unsigned int idx = 1; FILE *logfile = NULL; int ch; int fd; struct timeval tv; time_t starttime = 0; time_t statbegin = 0; time_t now = 0; struct timeval start_tv; unsigned long long unow = 0; time_t startlog = 0; time_t updtime = 0; unsigned long long updtime_usec = 0; struct promisc_states *promisc_list; if (!facility_active(GSTATIDFILE, "")) mark_facility(GSTATIDFILE, "general interface statistics", ""); else { write_error("General interface stats already active in another process"); return; } initiflist(&(table.head)); if (table.head == NULL) { no_ifaces_error(); unmark_facility(GSTATIDFILE, ""); return; } initiftab(&table); if ((first_active_facility()) && (options->promisc)) { init_promisc_list(&promisc_list); save_promisc_list(promisc_list); srpromisc(1, promisc_list); destroy_promisc_list(&promisc_list); } adjust_instance_count(PROCCOUNTFILE, 1); if (logging) { if (strcmp(current_logfile, "") == 0) { strcpy(current_logfile, GSTATLOG); if (!daemonized) input_logfile(current_logfile, &logging); } } if (logging) { opentlog(&logfile, GSTATLOG); if (logfile == NULL) logging = 0; } if (logging) { signal(SIGUSR1, rotate_gstat_log); rotate_flag = 0; writelog(logging, logfile, "******** General interface statistics started ********"); } preparescreen(&table); update_panels(); doupdate(); fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if(fd == -1) { write_error("Unable to obtain monitoring socket"); goto err; } //isdnfd = -1; exitloop = 0; gettimeofday(&tv, NULL); start_tv = tv; starttime = startlog = statbegin = tv.tv_sec; PACKET_INIT(pkt); while (!exitloop) { gettimeofday(&tv, NULL); now = tv.tv_sec; unow = tv.tv_sec * 1000000ULL + tv.tv_usec; if ((now - starttime) >= 1) { unsigned long msecs; msecs = timeval_diff_msec(&tv, &start_tv); updaterates(&table, options->actmode, msecs, idx); printelapsedtime(statbegin, now, LINES - 3, 1, table.borderwin); starttime = now; start_tv = tv; } if (logging) { check_rotate_flag(&logfile); if ((now - startlog) >= options->logspan) { writegstatlog(&table, options->actmode, time(NULL) - statbegin, logfile); startlog = now; } } if (((options->updrate != 0) && (now - updtime >= options->updrate)) || ((options->updrate == 0) && (unow - updtime_usec >= DEFAULT_UPDATE_DELAY))) { update_panels(); doupdate(); updtime = now; updtime_usec = unow; } if ((facilitytime != 0) && (((now - statbegin) / 60) >= facilitytime)) exitloop = 1; if (packet_get(fd, &pkt, &ch, table.statwin) == -1) { write_error("Packet receive failed"); exitloop = 1; break; } switch (ch) { case ERR: /* no key ready, do nothing */ break; case KEY_UP: scrollgstatwin(&table, SCROLLDOWN, &idx); break; case KEY_DOWN: scrollgstatwin(&table, SCROLLUP, &idx); break; case KEY_PPAGE: case '-': pagegstatwin(&table, SCROLLDOWN, &idx); break; case KEY_NPAGE: case ' ': pagegstatwin(&table, SCROLLUP, &idx); break; case 12: case 'l': case 'L': tx_refresh_screen(); break; case 'Q': case 'q': case 'X': case 'x': case 27: case 24: exitloop = 1; break; } if (pkt.pkt_len <= 0) continue; pkt_result = packet_process(&pkt, NULL, NULL, NULL, ofilter, MATCH_OPPOSITE_USECONFIG, options->v6inv4asv6); if (pkt_result != PACKET_OK && pkt_result != MORE_FRAGMENTS) continue; ptmp = positionptr(table.head, pkt.pkt_ifindex); if (!ptmp) continue; ptmp->total++; ptmp->spanbr += pkt.pkt_len; ptmp->br += pkt.pkt_len; if (pkt.pkt_protocol == ETH_P_IP) { ptmp->iptotal++; if (pkt_result == CHECKSUM_ERROR) { (ptmp->badtotal)++; continue; } } else if (pkt.pkt_protocol == ETH_P_IPV6) { ptmp->ip6total++; } else { (ptmp->noniptotal)++; } printifentry(ptmp, table.statwin, idx); } close(fd); err: if ((options->promisc) && (is_last_instance())) { load_promisc_list(&promisc_list); srpromisc(0, promisc_list); destroy_promisc_list(&promisc_list); } adjust_instance_count(PROCCOUNTFILE, -1); del_panel(table.statpanel); delwin(table.statwin); del_panel(table.borderpanel); delwin(table.borderwin); update_panels(); doupdate(); if (logging) { signal(SIGUSR1, SIG_DFL); writegstatlog(&table, options->actmode, time(NULL) - statbegin, logfile); writelog(logging, logfile, "******** General interface statistics stopped ********"); fclose(logfile); } destroyiflist(table.head); pkt_cleanup(); unmark_facility(GSTATIDFILE, ""); strcpy(current_logfile, ""); }
} } void cleanupserver() { if(serverhost) enet_host_destroy(serverhost); serverhost = NULL; if(pongsock != ENET_SOCKET_NULL) enet_socket_destroy(pongsock); if(lansock != ENET_SOCKET_NULL) enet_socket_destroy(lansock); pongsock = lansock = ENET_SOCKET_NULL; } void updaterates(); VARF(serveruprate, 0, 0, INT_MAX, updaterates()); VARF(serverdownrate, 0, 0, INT_MAX, updaterates()); SVAR(serverip, ""); VARF(serverport, 0, server::serverport(), 0xFFFF, { if(!serverport) serverport = server::serverport(); }); void updaterates() { if(serverhost) enet_host_bandwidth_limit(serverhost, serverdownrate, serveruprate); } VARF(maxclients, 0, DEFAULTCLIENTS, MAXCLIENTS, { if(!maxclients) maxclients = DEFAULTCLIENTS; }); VARF(maxdupclients, 0, 0, MAXCLIENTS, { if(serverhost) serverhost->duplicatePeers = maxdupclients ? maxdupclients : MAXCLIENTS; }); VAR(maxslots, 0, 0, MAXCLIENTS);