static int gencode_check_ports(thash *ports, bool outbound, struct sock_filter *filter, int loc_drop, int loc_accept) { int i = 0, j; struct port *sp; unsigned long port; if (thash_count(ports) == 0) { /* no ports - just drop */ for (j = 0; j < 3; j++) { memcpy(filter+i, &check_ports[2], sizeof *check_ports); filter[i].k = loc_drop - i - 1; i++; } return i; } /* check local ports -> source port */ memcpy(filter+i, &check_ports[0], sizeof *check_ports); filter[i].k += 0; /* in UDP/TCP src port is @ offset 0 */ i++; thash_reset(ports); while ((sp = thash_uint_iter(ports, &port))) { if (sp->local != outbound) continue; memcpy(filter+i, &check_ports[1], sizeof *check_ports); filter[i].k = port; filter[i].jt = loc_accept - i - 1; i++; } /* check remote ports -> destination port */ memcpy(filter+i, &check_ports[0], sizeof *check_ports); filter[i].k += 2; /* in UDP/TCP dst port is @ offset 2 */ i++; thash_reset(ports); while ((sp = thash_uint_iter(ports, &port))) { if (sp->local == outbound) continue; memcpy(filter+i, &check_ports[1], sizeof *check_ports); filter[i].k = port; filter[i].jt = loc_accept - i - 1; i++; } /* if nothing matched, drop */ memcpy(filter+i, &check_ports[2], sizeof *check_ports); filter[i].k = loc_drop - i - 1; i++; return i; }
void pid_detach_all(struct tracedump *td) { struct pid *sp; thash_reset(td->pids); while ((sp = thash_uint_iter(td->pids, NULL))) { ptrace_detach(sp, 0); pid_del(td, sp->pid); } }
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; }