void pcap_init(struct tracedump *td) { int i; struct sockaddr_ll ll; struct pcap_file_hdr ph; /* initialize */ td->pc = mmatic_zalloc(td->mm, sizeof(struct pcap)); /* open the sniffing socket */ memset(&ll, 0, sizeof ll); ll.sll_family = AF_PACKET; td->pc->fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL)); if (td->pc->fd == -1) { dbg(1, "Could not connect to the sniffing socket - insufficient privileges?\n"); die_errno("socket"); } /* open the resultant file */ if (streq(td->opts.outfile, "-")) { td->pc->fp = stdout; setvbuf(stdout, 0, _IOLBF, 0); } else { td->pc->fp = fopen(td->opts.outfile, "w"); if (!td->pc->fp) { dbg(1, "Could not open the output file: %s\n", td->opts.outfile); die_errno("fopen"); } dbg(1, "Writing packets to %s\n", td->opts.outfile); } /* write the global header */ ph.magic_number = PCAP_MAGIC_NUMBER; ph.version_major = 2; ph.version_minor = 4; ph.thiszone = 0; ph.sigfigs = 0; ph.snaplen = td->opts.snaplen; ph.network = LINKTYPE_LINUX_SLL; fwrite(&ph, sizeof ph, 1, td->pc->fp); /* start the reader thread */ i = pthread_create(&td->pc->reader, NULL, sniffer_thread, td); if (i != 0) die("pthread_create(sniffer_thread) failed with error %d\n", i); /* update the filter */ pcap_update(td); }
static void *gc_thread(void *arg) { struct tracedump *td; sigset_t ss; uint8_t *tcp = NULL, *udp = NULL; unsigned int port; struct port *sp; int count = 0; struct timeval now; td = (struct tracedump *) arg; sigaddset(&ss, SIGTERM); sigaddset(&ss, SIGINT); pthread_sigmask(SIG_SETMASK, &ss, NULL); while (1) { sleep(60); /* read list of active tcp/udp ports */ tcp = port_list(td, true); udp = port_list(td, false); if (!tcp || !udp) { dbg(1, "gc: reading tcp/udp ports failed\n"); goto next; } /* * iterate through all monitored TCP/UDP ports and delete those * that are not needed anymore */ pthread_mutex_lock(&td->mutex_ports); gettimeofday(&now, NULL); /* TCP */ thash_reset(td->tcp_ports); while ((sp = thash_uint_iter(td->tcp_ports, &port))) { /* skip ports "younger" than 60 secs * workaround that autobound TCP ports are not visible in procfs - Linux bug? */ if (pjf_timediff(&now, &sp->since)/1000000 < 60) continue; if (!PORT_ISSET(tcp, port)) { count++; thash_uint_set(td->tcp_ports, port, NULL); dbg(3, "port TCP/%d deleted\n", port); } } /* UDP */ thash_reset(td->udp_ports); while ((sp = thash_uint_iter(td->udp_ports, &port))) { if (!PORT_ISSET(udp, port)) { count++; thash_uint_set(td->udp_ports, port, NULL); dbg(3, "port UDP/%d deleted\n", port); } } pthread_mutex_unlock(&td->mutex_ports); /* if any changes were made, run the BPF filter update */ if (count > 0) pcap_update(td); next: if (tcp) mmatic_free(tcp); if (udp) mmatic_free(udp); } return NULL; }