int main (int argc, char** argv) { if (argc < 2) { std::cout << "Please, enter a filename" << std::endl; exit(-1); } local_addrs = new local_addr (/*TODO*/1, NULL); needrefresh = false; process_init(); tracemode = 1; if ((!tracemode) && (!DEBUG)){ init_ui(); } char errbuf[DP_ERRBUF_SIZE]; //dp_handle * newhandle = dp_open_live(current_dev->name, BUFSIZ, promisc, 100, errbuf); dp_handle * newhandle = dp_open_offline(argv[1], errbuf); dp_addcb (newhandle, dp_packet_ip, process_ip); dp_addcb (newhandle, dp_packet_ip6, process_ip6); dp_addcb (newhandle, dp_packet_tcp, process_tcp); dp_addcb (newhandle, dp_packet_udp, process_udp); signal (SIGALRM, &alarm_cb); signal (SIGINT, &quit_cb); //alarm (refreshdelay); //fprintf(stderr, "Waiting for first packet to arrive (see sourceforge.net bug 1019381)\n"); struct dpargs * userdata = (dpargs *) malloc (sizeof (struct dpargs)); userdata->sa_family = AF_UNSPEC; int ret = dp_dispatch (newhandle, -1, (u_char *)userdata, sizeof (struct dpargs)); free (userdata); if (ret == -1) { std::cout << "Error dispatching: " << dp_geterr(newhandle); } std::cout << "Done dispatching. " << dp_geterr(newhandle); do_refresh(); }
static int nethogsmonitor_init() { process_init(); device *devices = get_default_devices(); if (devices == NULL) { std::cerr << "No devices to monitor" << std::endl; return NETHOGS_STATUS_NO_DEVICE; } device *current_dev = devices; bool promiscuous = false; int nb_devices = 0; int nb_failed_devices = 0; while (current_dev != NULL) { ++nb_devices; if (!getLocal(current_dev->name, false)) { std::cerr << "getifaddrs failed while establishing local IP." << std::endl; ++nb_failed_devices; continue; } char errbuf[PCAP_ERRBUF_SIZE]; dp_handle *newhandle = dp_open_live(current_dev->name, BUFSIZ, promiscuous, 100, errbuf); if (newhandle != NULL) { dp_addcb(newhandle, dp_packet_ip, process_ip); dp_addcb(newhandle, dp_packet_ip6, process_ip6); dp_addcb(newhandle, dp_packet_tcp, process_tcp); dp_addcb(newhandle, dp_packet_udp, process_udp); /* The following code solves sf.net bug 1019381, but is only available * in newer versions (from 0.8 it seems) of libpcap * * update: version 0.7.2, which is in debian stable now, should be ok * also. */ if (dp_setnonblock(newhandle, 1, errbuf) == -1) { fprintf(stderr, "Error putting libpcap in nonblocking mode\n"); } handles = new handle(newhandle, current_dev->name, handles); if (pc_loop_use_select) { // some devices may not support pcap_get_selectable_fd int const fd = pcap_get_selectable_fd(newhandle->pcap_handle); if (fd != -1) { pc_loop_fd_list.push_back(fd); } else { pc_loop_use_select = false; pc_loop_fd_list.clear(); fprintf(stderr, "failed to get selectable_fd for %s\n", current_dev->name); } } } else { fprintf(stderr, "ERROR: opening handler for device %s: %s\n", current_dev->name, strerror(errno)); ++nb_failed_devices; } current_dev = current_dev->next; } if (nb_devices == nb_failed_devices) { return NETHOGS_STATUS_FAILURE; } // use the Self-Pipe trick to interrupt the select() in the main loop if (pc_loop_use_select) { self_pipe = create_self_pipe(); if (self_pipe.first == -1 || self_pipe.second == -1) { std::cerr << "Error creating pipe file descriptors\n"; pc_loop_use_select = false; } else { pc_loop_fd_list.push_back(self_pipe.first); } } return NETHOGS_STATUS_OK; }
int main (int argc, char** argv) { process_init(); device * devices = NULL; //dp_link_type linktype = dp_link_ethernet; int promisc = 0; int opt; while ((opt = getopt(argc, argv, "Vhbtpd:v:c:s")) != -1) { switch(opt) { case 'V': versiondisplay(); exit(0); case 'h': help(false); exit(0); case 'b': bughuntmode = true; tracemode = true; break; case 't': tracemode = true; break; case 'p': promisc = 1; break; case 's': sortRecv = false; break; case 'd': refreshdelay = atoi(optarg); break; case 'v': viewMode = atoi(optarg) % VIEWMODE_COUNT; break; case 'c': refreshlimit = atoi(optarg); break; /* case 'f': argv++; if (strcmp (optarg, "ppp") == 0) linktype = dp_link_ppp; else if (strcmp (optarg, "eth") == 0) linktype = dp_link_ethernet; } break; */ default: help(true); exit(EXIT_FAILURE); } } while (optind < argc) { devices = new device (strdup(argv[optind++]), devices); } if (devices == NULL) { devices = get_default_devices(); if ( devices == NULL ) { std::cerr << "Not devices to monitor" << std::endl; return 0; } } if ((!tracemode) && (!DEBUG)){ init_ui(); } if (NEEDROOT && (geteuid() != 0)) forceExit(false, "You need to be root to run NetHogs!"); //use the Self-Pipe trick to interrupt the select() in the main loop self_pipe = create_self_pipe(); if( self_pipe.first == -1 || self_pipe.second == -1 ) { forceExit(false, "Error creating pipe file descriptors\n"); } else { //add the self-pipe to allow interrupting select() pc_loop_fd_list.push_back(self_pipe.first); } char errbuf[PCAP_ERRBUF_SIZE]; handle * handles = NULL; device * current_dev = devices; while (current_dev != NULL) { getLocal(current_dev->name, tracemode); dp_handle * newhandle = dp_open_live(current_dev->name, BUFSIZ, promisc, 100, errbuf); if (newhandle != NULL) { dp_addcb (newhandle, dp_packet_ip, process_ip); dp_addcb (newhandle, dp_packet_ip6, process_ip6); dp_addcb (newhandle, dp_packet_tcp, process_tcp); dp_addcb (newhandle, dp_packet_udp, process_udp); /* The following code solves sf.net bug 1019381, but is only available * in newer versions (from 0.8 it seems) of libpcap * * update: version 0.7.2, which is in debian stable now, should be ok * also. */ if (dp_setnonblock (newhandle, 1, errbuf) == -1) { fprintf(stderr, "Error putting libpcap in nonblocking mode\n"); } handles = new handle (newhandle, current_dev->name, handles); if( pc_loop_use_select ) { //some devices may not support pcap_get_selectable_fd int const fd = pcap_get_selectable_fd(newhandle->pcap_handle); if( fd != -1 ) { pc_loop_fd_list.push_back(fd); } else { pc_loop_use_select = false; pc_loop_fd_list.clear(); fprintf(stderr, "failed to get selectable_fd for %s\n", current_dev->name); } } } else { fprintf(stderr, "Error opening handler for device %s\n", current_dev->name); } current_dev = current_dev->next; } signal (SIGINT, &quit_cb); fprintf(stderr, "Waiting for first packet to arrive (see sourceforge.net bug 1019381)\n"); struct dpargs * userdata = (dpargs *) malloc (sizeof (struct dpargs)); // Main loop: // // Walks though the 'handles' list, which contains handles opened in non-blocking mode. // This causes the CPU utilisation to go up to 100%. This is tricky: while (1) { bool packets_read = false; handle * current_handle = handles; while (current_handle != NULL) { userdata->device = current_handle->devicename; userdata->sa_family = AF_UNSPEC; int retval = dp_dispatch (current_handle->content, -1, (u_char *)userdata, sizeof (struct dpargs)); if (retval < 0) { std::cerr << "Error dispatching: " << retval << std::endl; } else if (retval != 0) { packets_read = true; } current_handle = current_handle->next; } time_t const now = ::time(NULL); if( last_refresh_time + refreshdelay <= now ) { last_refresh_time = now; if ((!DEBUG)&&(!tracemode)) { // handle user input ui_tick(); } do_refresh(); } //if not packets, do a select() until next packet if (!packets_read) { if( !wait_for_next_trigger() ) { //Exit the loop break; } } } //clean up clean_up(); }