Beispiel #1
0
void port_add(struct sock *ss, bool local)
{
	struct port *sp;
	thash *ports;

	pthread_mutex_lock(&ss->td->mutex_ports);

	if (ss->type == SOCK_DGRAM)
		ports = ss->td->udp_ports;
	else if (ss->type == SOCK_STREAM)
		ports = ss->td->tcp_ports;
	else
		die("invalid ss->type\n");

	sp = thash_uint_get(ports, ss->port);
	if (!sp) {
		sp = mmatic_zalloc(ss->td->mm, sizeof *sp);
		thash_uint_set(ports, ss->port, sp);

		dbg(3, "port %d/%s added\n", ss->port,
			ss->type == SOCK_STREAM ? "TCP" : "UDP");
	}

	gettimeofday(&sp->since, NULL);
	sp->local = local;
	sp->socknum = ss->socknum;

	pthread_mutex_unlock(&ss->td->mutex_ports);
}
Beispiel #2
0
static void cache_update()
{
	char buf[BUFSIZ], *ptr, *cm;
	int i;
	unsigned int id;

	if (!fd->afh)
		return;

	if (thash_count(fd->cache) > 50000000)
		return;

	while (thash_count(fd->cache) < 10000000 && fgets(buf, sizeof buf, fd->afh)) {
		if (!isdigit(buf[0]))
			continue;

		ptr = buf;
		cm = strchr(ptr, ',');
		if (!cm)
			continue;
		else
			*cm = '\0';

		/* get flow id */
		id = atoi(ptr);

		/* get flow target */
		for (i = 1; i < fd->colnum; i++) {
			ptr = cm + 1;
			cm = strchr(ptr, ',');
			if (!cm) {
				cm = strchr(ptr, '\n');
				break;
			}
		}

		if (cm)
			*cm = '\0';

		for (i = 0; ptr[i]; i++) {
			if (!isalnum(ptr[i]))
				ptr[i] = '_';
		}

		thash_uint_set(fd->cache, id, mmatic_strdup(fd->mm, ptr));
	}

	if (feof(fd->afh)) {
		fclose(fd->afh);
		fd->afh = NULL;
	}
}
Beispiel #3
0
/* NOTE: it might be necessary to time-out nd->ids entries in order to decrease memory consumption */
static struct ipoque_id_struct *getid(struct ndpi *nd, struct lfc_flow_addr *lfa)
{
    struct ipoque_id_struct *id;

    id = thash_uint_get(nd->ids, (uint32_t) lfa->addr.ip4.s_addr);

    if (!id) {
        id = mmatic_zalloc(nd->mm, ipoque_detection_get_sizeof_ipoque_id_struct());
        thash_uint_set(nd->ids, (uint32_t) lfa->addr.ip4.s_addr, id);
    }

    return id;
}
Beispiel #4
0
struct pid *pid_get(struct tracedump *td, pid_t pid)
{
	struct pid *sp;

	/* speed-up cache */
	if (td->sp && td->sp->pid == pid)
		return td->sp;

	sp = thash_uint_get(td->pids, pid);
	if (!sp) {
		dbg(7, "new pid %d\n", pid);
		sp = mmatic_zalloc(td->mm, sizeof *sp);
		sp->td = td;
		sp->pid = pid;
		thash_uint_set(td->pids, pid, sp);
	}

	return sp;
}
Beispiel #5
0
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;
}
Beispiel #6
0
static void pkt(struct lfc *lfc, void *pdata,
	struct lfc_flow *lf, void *data,
	double ts, bool up, bool is_new, libtrace_packet_t *pkt)
{
	struct flow *f = data;
	char *name, *uri;
	libtrace_out_t *out;

	if (f->ignore)
		return;

	if (is_new) {
		/* find the flow by its id in the ARFF file, get output file name */
		name = thash_uint_get(fd->cache, lf->id);
		if (!name) {
			cache_update();
			name = thash_uint_get(fd->cache, lf->id);
			if (!name) {
				f->ignore = true;
				thash_uint_set(fd->cache, lf->id, NULL);
				return;
			}
		}

		/* ignore flows with column values we are not interested in */
		if (fd->value && !streq(fd->value, name)) {
			f->ignore = true;
			thash_uint_set(fd->cache, lf->id, NULL);
			return;
		}

		/* get libtrace output file */
		out = thash_get(fd->out_files, name);
		if (!out) {
			uri = mmatic_sprintf(fd->mm, "pcap:%s/%s.pcap", fd->dir, name);

			out = trace_create_output(uri);
			if (!out) {
				cleanup();
				die("trace_create_output(%s) failed\n", uri);
			}

			if (trace_is_err_output(out)) {
				trace_perror_output(out, "Opening output trace file");
				cleanup();
				die("trace_create_output(%s) failed\n", uri);
			}

			if (trace_start_output(out) == -1) {
				trace_perror_output(out, "Starting output trace");
				cleanup();
				die("trace_start_output(%s) failed\n", uri);
			}

			thash_set(fd->out_files, name, out);
		}

		f->out = out;

		/* remove id from cache */
		thash_uint_set(fd->cache, lf->id, NULL);
	}

	trace_write_packet(f->out, pkt);
	if (trace_is_err_output(f->out)) {
		trace_perror_output(f->out, "Writing packet to output trace file");
		cleanup();
		die("trace_write_packet() failed\n");
	}
}
Beispiel #7
0
void pid_del(struct tracedump *td, pid_t pid)
{
	dbg(7, "deleting pid %d\n", pid);
	thash_uint_set(td->pids, pid, NULL);
}