📄 hostmon.c
字号:
tx_printkeyhelp("O", " - IP packets out", *win, DLGHIGHATTR, DLGTEXTATTR); wmove(*win, 9, 2); tx_printkeyhelp("Y", " - total bytes out", *win, DLGHIGHATTR, DLGTEXTATTR); wmove(*win, 10, 2); tx_printkeyhelp("Any other key", " - cancel sort", *win, DLGHIGHATTR, DLGTEXTATTR); update_panels(); doupdate();}/* * Swap two host table entries. */void swaphostents(struct ethtab *list, struct ethtabent *p1, struct ethtabent *p2){ register unsigned int tmp; struct ethtabent *p1prevsaved; struct ethtabent *p2nextsaved; if (p1 == p2) return; tmp = p1->index; p1->index = p2->index; p2->index = tmp; p1->next_entry->index = p1->index + 1; p2->next_entry->index = p2->index + 1; if (p1->prev_entry != NULL) p1->prev_entry->next_entry = p2; else list->head = p2; if (p2->next_entry->next_entry != NULL) p2->next_entry->next_entry->prev_entry = p1->next_entry; else list->tail = p1->next_entry; p2nextsaved = p2->next_entry->next_entry; p1prevsaved = p1->prev_entry; if (p1->next_entry->next_entry == p2) { p2->next_entry->next_entry = p1; p1->prev_entry = p2->next_entry; } else { p2->next_entry->next_entry = p1->next_entry->next_entry; p1->prev_entry = p2->prev_entry; p2->prev_entry->next_entry = p1; p1->next_entry->next_entry->prev_entry = p2->next_entry; } p2->prev_entry = p1prevsaved; p1->next_entry->next_entry = p2nextsaved;}unsigned long long ql_getkey(struct ethtabent *entry, int ch){ unsigned long long result = 0; switch (ch) { case 'P': result = entry->next_entry->un.figs.inpcount; break; case 'I': result = entry->next_entry->un.figs.inippcount; break; case 'B': result = entry->next_entry->un.figs.inbcount; break; case 'K': result = entry->next_entry->un.figs.outpcount; break; case 'O': result = entry->next_entry->un.figs.outippcount; break; case 'Y': result = entry->next_entry->un.figs.outbcount; break; } return result;}struct ethtabent *ql_partition(struct ethtab *table, struct ethtabent **low, struct ethtabent **high, int ch){ struct ethtabent *pivot = *low; struct ethtabent *left = *low; struct ethtabent *right = *high; struct ethtabent *ptmp; unsigned long long pivot_value; pivot_value = ql_getkey(pivot, ch); while (left->index < right->index) { while ((ql_getkey(left, ch) >= pivot_value) && (left->next_entry->next_entry != NULL)) left = left->next_entry->next_entry; while (ql_getkey(right, ch) < pivot_value) right = right->prev_entry->prev_entry; if (left->index < right->index) { swaphostents(table, left, right); if (*low == left) *low = right; if (*high == right) *high = left; ptmp = left; left = right; right = ptmp; } } swaphostents(table, pivot, right); if (*low == pivot) *low = right; if (*high == right) *high = pivot; return pivot;}/* * Quicksort routine for the LAN station monitor */void quicksort_lan_entries(struct ethtab *table, struct ethtabent *low, struct ethtabent *high, int ch){ struct ethtabent *pivot; if ((high == NULL) || (low == NULL)) return; if (high->index > low->index) { pivot = ql_partition(table, &low, &high, ch); if (pivot->prev_entry != NULL) quicksort_lan_entries(table, low, pivot->prev_entry->prev_entry, ch); quicksort_lan_entries(table, pivot->next_entry->next_entry, high, ch); }}void sort_hosttab(struct ethtab *list, int *idx, int command){ struct ethtabent *ptemp1; unsigned int idxtmp; if (!list->head) return; command = toupper(command); if ((command != 'P') && (command != 'I') && (command != 'B') && (command != 'K') && (command != 'O') && (command != 'Y')) return; quicksort_lan_entries(list, list->head, list->tail->prev_entry, command); ptemp1 = list->firstvisible = list->head; *idx = 1; idxtmp = 0; tx_colorwin(list->tabwin); while ((ptemp1) && (idxtmp <= LINES - 4)) { printethent(list, ptemp1, *idx); idxtmp++; if (idxtmp <= LINES - 4) list->lastvisible = ptemp1; ptemp1 = ptemp1->next_entry; }}/* * The LAN station monitor */void hostmon(const struct OPTIONS *options, int facilitytime, char *ifptr, struct filterstate *ofilter){ int logging = options->logging; int fd; struct ethtab table; struct ethtabent *entry; struct sockaddr_ll fromaddr; unsigned short linktype; int br; char buf[MAX_PACKET_SIZE]; char scratch_saddr[6]; char scratch_daddr[6]; unsigned int idx = 1; int is_ip; int ch; char ifname[10]; struct timeval tv; unsigned long starttime; unsigned long now = 0; unsigned long long unow = 0; unsigned long statbegin = 0, startlog = 0; unsigned long updtime = 0; unsigned long long updtime_usec = 0; struct desclist elist; /* Ethernet description list */ struct desclist flist; /* FDDI description list */ struct desclist *list = NULL; FILE *logfile = NULL; int pkt_result; char *ipacket; int nomem = 0; WINDOW *sortwin; PANEL *sortpanel; int keymode = 0; int instance_id; char msgstring[80]; struct promisc_states *promisc_list; if (!facility_active(LANMONIDFILE, ifptr)) mark_facility(LANMONIDFILE, "LAN monitor", ifptr); else { snprintf(msgstring, 80, "LAN station monitor already running on %s", gen_iface_msg(ifptr)); write_error(msgstring, daemonized); return; } if (ifptr != NULL) { if (!iface_supported(ifptr)) { err_iface_unsupported(); unmark_facility(LANMONIDFILE, ifptr); return; } if (!iface_up(ifptr)) { err_iface_down(); unmark_facility(LANMONIDFILE, ifptr); return; } } open_socket(&fd); if (fd < 0) { 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); strncpy(active_facility_countfile, LANMONCOUNTFILE, 64); hostmonhelp(); initethtab(&table, options->actmode); loaddesclist(&elist, LINK_ETHERNET, WITHETCETHERS); loaddesclist(&flist, LINK_FDDI, WITHETCETHERS); 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); exitloop = 0; gettimeofday(&tv, NULL); starttime = statbegin = startlog = tv.tv_sec; do { gettimeofday(&tv, NULL); now = tv.tv_sec; unow = tv.tv_sec * 1e+6 + 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 (((now - startlog) >= options->logspan) && (logging)) { writeethlog(table.head, options->actmode, now - statbegin, logfile); startlog = now; } if (((options->updrate != 0) && (now - updtime >= options->updrate)) || ((options->updrate == 0) && (unow - updtime_usec >= HOSTMON_UPDATE_DELAY))) { update_panels(); doupdate(); updtime = now; updtime_usec = unow; } check_rotate_flag(&logfile, logging); if ((facilitytime != 0) && (((now - statbegin) / 60) >= facilitytime)) exitloop = 1; getpacket(fd, buf, &fromaddr, &ch, &br, ifname, table.tabwin); 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 (br > 0) { pkt_result = processpacket(buf, &ipacket, &br, NULL, NULL, NULL, &fromaddr, &linktype, ofilter, MATCH_OPPOSITE_USECONFIG, ifname, ifptr); if (pkt_result != PACKET_OK) continue; if ((linktype == LINK_ETHERNET) || (linktype == LINK_FDDI) || (linktype == LINK_PLIP) || (linktype == LINK_TR) || (linktype == LINK_VLAN)) { if (fromaddr.sll_protocol == htons(ETH_P_IP)) is_ip = 1; else is_ip = 0; /* * Check source address entry */ if ((linktype == LINK_ETHERNET) || (linktype == LINK_PLIP) || (linktype == LINK_VLAN)) { memcpy(scratch_saddr, ((struct ethhdr *) buf)->h_source, ETH_ALEN); memcpy(scratch_daddr, ((struct ethhdr *) buf)->h_dest, ETH_ALEN); list = &elist; } else if (linktype == LINK_FDDI) { memcpy(scratch_saddr, ((struct fddihdr *) buf)->saddr, FDDI_K_ALEN); memcpy(scratch_daddr, ((struct fddihdr *) buf)->daddr, FDDI_K_ALEN); list = &flist; } else if (linktype == LINK_TR) { memcpy(scratch_saddr, ((struct trh_hdr *) buf)->saddr, TR_ALEN); memcpy(scratch_daddr, ((struct trh_hdr *) buf)->daddr, TR_ALEN); list = &flist; } entry = in_ethtable(&table, linktype, scratch_saddr); if ((entry == NULL) && (!nomem)) entry = addethentry(&table, linktype, ifname, scratch_saddr, &nomem, list); if (entry != NULL) { updateethent(entry, br, 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, linktype, scratch_daddr); if ((entry == NULL) && (!nomem)) entry = addethentry(&table, linktype, ifname, scratch_daddr, &nomem, list); if (entry != NULL) { updateethent(entry, br, is_ip, 0); if (!entry->prev_entry->un.desc.printed) printethent(&table, entry->prev_entry, idx); printethent(&table, entry, idx); } } } } while (!exitloop); 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); adjust_instance_count(LANMONCOUNTFILE, -1); if (logging) { signal(SIGUSR1, SIG_DFL); writeethlog(table.head, options->actmode, time((time_t *) 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); destroydesclist(&elist); destroydesclist(&flist); unmark_facility(LANMONIDFILE, ifptr); strcpy(current_logfile, "");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -