void packet_size_breakdown(struct OPTIONS *options, char *ifname, int facilitytime, struct filterstate *ofilter) { WINDOW *win; PANEL *panel; WINDOW *borderwin; PANEL *borderpanel; struct ifstat_brackets brackets[20]; unsigned int interval; int ch; int fd; char buf[MAX_PACKET_SIZE]; int br; char *ipacket; char iface[10]; unsigned int mtu; struct sockaddr_ll fromaddr; unsigned short linktype; int pkt_result; struct timeval tv; unsigned long starttime, startlog, timeint; unsigned long now; unsigned long long unow; unsigned long updtime = 0; unsigned long long updtime_usec = 0; int logging = options->logging; FILE *logfile = NULL; struct promisc_states *promisc_list; char msgstring[80]; if (!facility_active(PKTSIZEIDFILE, ifname)) mark_facility(PKTSIZEIDFILE, "Packet size breakdown", ifname); else { snprintf(msgstring, 80, "Packet sizes already being monitored on %s", ifname); write_error(msgstring, daemonized); return; } if (!iface_supported(ifname)) { err_iface_unsupported(); unmark_facility(PKTSIZEIDFILE, ifname); return; } if (!iface_up(ifname)) { err_iface_down(); unmark_facility(PKTSIZEIDFILE, ifname); return; } borderwin = newwin(LINES - 2, COLS, 1, 0); borderpanel = new_panel(borderwin); wattrset(borderwin, BOXATTR); tx_box(borderwin, ACS_VLINE, ACS_HLINE); mvwprintw(borderwin, 0, 1, " Packet Distribution by Size "); win = newwin(LINES - 4, COLS - 2, 2, 1); panel = new_panel(win); tx_stdwinset(win); wtimeout(win, -1); wattrset(win, STDATTR); tx_colorwin(win); move(LINES - 1, 1); stdexitkeyhelp(); initialize_brackets(ifname, brackets, &interval, &mtu, win); mvwprintw(win, 1, 1, "Packet size brackets for interface %s", ifname); wattrset(win, BOXATTR); mvwprintw(win, 4, 1, "Packet Size (bytes)"); mvwprintw(win, 4, 26, "Count"); mvwprintw(win, 4, 36, "Packet Size (bytes)"); mvwprintw(win, 4, 60, "Count"); wattrset(win, HIGHATTR); if (logging) { if (strcmp(current_logfile, "") == 0) { snprintf(current_logfile, 80, "%s-%s.log", PKTSIZELOG, ifname); if (!daemonized) input_logfile(current_logfile, &logging); } } if (logging) { opentlog(&logfile, current_logfile); if (logfile == NULL) logging = 0; } if (logging) signal(SIGUSR1, rotate_size_log); writelog(logging, logfile, "******** Packet size distribution facility started ********"); exitloop = 0; gettimeofday(&tv, NULL); starttime = startlog = timeint = tv.tv_sec; open_socket(&fd); if (fd < 0) { unmark_facility(PKTSIZEIDFILE, ifname); return; } 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); active_facility_countfile[0] = '\0'; do { gettimeofday(&tv, NULL); now = tv.tv_sec; unow = tv.tv_sec * 1e+6 + tv.tv_usec; 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 (now - timeint >= 5) { printelapsedtime(starttime, now, LINES - 3, 1, borderwin); timeint = now; } if ((now - startlog >= options->logspan) && (logging)) { write_size_log(brackets, now - starttime, ifname, mtu, logfile); startlog = now; } check_rotate_flag(&logfile, logging); if ((facilitytime != 0) && (((now - starttime) / 60) >= facilitytime)) exitloop = 1; getpacket(fd, buf, &fromaddr, &ch, &br, iface, win); if (ch != ERR) { switch (ch) { case 12: case 'l': case 'L': tx_refresh_screen(); break; case 'x': case 'X': case 'q': case 'Q': case 27: case 24: exitloop = 1; } } if (br > 0) { pkt_result = processpacket(buf, &ipacket, &br, NULL, NULL, NULL, &fromaddr, &linktype, ofilter, MATCH_OPPOSITE_USECONFIG, iface, ifname); if (pkt_result != PACKET_OK) continue; update_size_distrib(br, brackets, interval, win); } } while (!exitloop); if (logging) { signal(SIGUSR1, SIG_DFL); write_size_log(brackets, now - starttime, ifname, mtu, logfile); writelog(logging, logfile, "******** Packet size distribution facility stopped ********"); fclose(logfile); } close(fd); 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(panel); delwin(win); del_panel(borderpanel); delwin(borderwin); unmark_facility(PKTSIZEIDFILE, ifname); strcpy(current_logfile, ""); }
void hostmon(const struct OPTIONS *options, time_t facilitytime, char *ifptr, struct filterstate *ofilter) { int logging = options->logging; struct ethtab table; struct ethtabent *entry; char scratch_saddr[ETH_ALEN]; char scratch_daddr[ETH_ALEN]; unsigned int idx = 1; int is_ip; int ch; char *ifname = ifptr; struct timeval tv; time_t starttime; time_t now = 0; unsigned long long unow = 0; time_t statbegin = 0; time_t startlog = 0; time_t updtime = 0; unsigned long long updtime_usec = 0; struct eth_desc *list = NULL; FILE *logfile = NULL; int pkt_result; WINDOW *sortwin; PANEL *sortpanel; int keymode = 0; int instance_id; int fd; struct promisc_states *promisc_list; if (!facility_active(LANMONIDFILE, ifptr)) mark_facility(LANMONIDFILE, "LAN monitor", ifptr); else { write_error("LAN station monitor already running on %s", gen_iface_msg(ifptr)); return; } if (ifptr != NULL) { if (!dev_up(ifptr)) { err_iface_down(); unmark_facility(LANMONIDFILE, ifptr); return; } } 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); instance_id = adjust_instance_count(LANMONCOUNTFILE, 1); hostmonhelp(); initethtab(&table, options->actmode); /* Ethernet description list */ struct eth_desc *elist = load_eth_desc(ARPHRD_ETHER); /* FDDI description list */ struct eth_desc *flist = load_eth_desc(ARPHRD_FDDI); if (logging) { if (strcmp(current_logfile, "") == 0) { strncpy(current_logfile, gen_instance_logname(LANLOG, instance_id), 80); if (!daemonized) input_logfile(current_logfile, &logging); } } if (logging) { opentlog(&logfile, current_logfile); if (logfile == NULL) logging = 0; } if (logging) { signal(SIGUSR1, rotate_lanlog); rotate_flag = 0; writelog(logging, logfile, "******** LAN traffic monitor started ********"); } leaveok(table.tabwin, TRUE); fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if(fd == -1) { write_error("Unable to obtain monitoring socket"); goto err; } if(ifptr && dev_bind_ifname(fd, ifptr) == -1) { write_error("Unable to bind interface on the socket"); goto err_close; } exitloop = 0; gettimeofday(&tv, NULL); starttime = statbegin = startlog = tv.tv_sec; PACKET_INIT(pkt); do { gettimeofday(&tv, NULL); now = tv.tv_sec; unow = tv.tv_sec * 1000000ULL + tv.tv_usec; if ((now - starttime) >= 5) { printelapsedtime(statbegin, now, LINES - 3, 15, table.borderwin); updateethrates(&table, options->actmode, starttime, now, idx); starttime = now; } if (logging) { check_rotate_flag(&logfile); if ((now - startlog) >= options->logspan) { writeethlog(table.head, options->actmode, now - 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.tabwin) == -1) { write_error("Packet receive failed"); exitloop = 1; break; } if (ch != ERR) { if (keymode == 0) { switch (ch) { case KEY_UP: scrollethwin(&table, SCROLLDOWN, &idx); break; case KEY_DOWN: scrollethwin(&table, SCROLLUP, &idx); break; case KEY_PPAGE: case '-': pageethwin(&table, SCROLLDOWN, &idx); break; case KEY_NPAGE: case ' ': pageethwin(&table, SCROLLUP, &idx); break; case 12: case 'l': case 'L': tx_refresh_screen(); break; case 's': case 'S': show_hostsort_keywin(&sortwin, &sortpanel); keymode = 1; break; case 'q': case 'Q': case 'x': case 'X': case 27: case 24: exitloop = 1; } } else if (keymode == 1) { del_panel(sortpanel); delwin(sortwin); sort_hosttab(&table, &idx, ch); keymode = 0; } } if (pkt.pkt_len > 0) { char ifnamebuf[IFNAMSIZ]; pkt_result = packet_process(&pkt, NULL, NULL, NULL, ofilter, MATCH_OPPOSITE_USECONFIG, 0); if (pkt_result != PACKET_OK) continue; if (!ifptr) { /* we're capturing on "All interfaces", */ /* so get the name of the interface */ /* of this packet */ int r = dev_get_ifname(pkt.pkt_ifindex, ifnamebuf); if (r != 0) { write_error("Unable to get interface name"); break; /* can't get interface name, get out! */ } ifname = ifnamebuf; } /* get HW addresses */ switch (pkt.pkt_hatype) { case ARPHRD_ETHER: { struct ethhdr *hdr_eth = (struct ethhdr *)pkt.pkt_buf; memcpy(scratch_saddr, hdr_eth->h_source, ETH_ALEN); memcpy(scratch_daddr, hdr_eth->h_dest, ETH_ALEN); list = elist; break; } case ARPHRD_FDDI: { struct fddihdr *hdr_fddi = (struct fddihdr *)pkt.pkt_buf; memcpy(scratch_saddr, hdr_fddi->saddr, FDDI_K_ALEN); memcpy(scratch_daddr, hdr_fddi->daddr, FDDI_K_ALEN); list = flist; break; } case ARPHRD_IEEE802: case ARPHRD_IEEE802_TR: { struct trh_hdr *hdr_trh = (struct trh_hdr *)pkt.pkt_buf; memcpy(scratch_saddr, hdr_trh->saddr, TR_ALEN); memcpy(scratch_daddr, hdr_trh->daddr, TR_ALEN); list = flist; break; } default: /* unknown link protocol */ continue; } switch(pkt.pkt_protocol) { case ETH_P_IP: case ETH_P_IPV6: is_ip = 1; break; default: is_ip = 0; break; } /* Check source address entry */ entry = in_ethtable(&table, pkt.pkt_hatype, scratch_saddr); if (!entry) entry = addethentry(&table, pkt.pkt_hatype, ifname, scratch_saddr, list); if (entry != NULL) { updateethent(entry, pkt.pkt_len, is_ip, 1); if (!entry->prev_entry->un.desc.printed) printethent(&table, entry->prev_entry, idx); printethent(&table, entry, idx); } /* Check destination address entry */ entry = in_ethtable(&table, pkt.pkt_hatype, scratch_daddr); if (!entry) entry = addethentry(&table, pkt.pkt_hatype, ifname, scratch_daddr, list); if (entry != NULL) { updateethent(entry, pkt.pkt_len, is_ip, 0); if (!entry->prev_entry->un.desc.printed) printethent(&table, entry->prev_entry, idx); printethent(&table, entry, idx); } } } while (!exitloop); err_close: 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); adjust_instance_count(LANMONCOUNTFILE, -1); if (logging) { signal(SIGUSR1, SIG_DFL); writeethlog(table.head, options->actmode, time(NULL) - statbegin, logfile); writelog(logging, logfile, "******** LAN traffic monitor stopped ********"); fclose(logfile); } del_panel(table.tabpanel); delwin(table.tabwin); del_panel(table.borderpanel); delwin(table.borderwin); update_panels(); doupdate(); destroyethtab(&table); free_eth_desc(elist); free_eth_desc(flist); unmark_facility(LANMONIDFILE, ifptr); strcpy(current_logfile, ""); }
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, ""); }