Пример #1
0
struct spi_ep *ep_new_pkt(struct spi_source *source, spi_epaddr_t epa,
	const struct timeval *ts, void *data, uint32_t size)
{
	struct spi *spi = source->spi;
	struct spi_ep *ep;
	char *key;
	struct spi_pkt *pkt;
	mmatic *mm;

	key = _k(source, epa);
	ep = thash_get(spi->eps, key);
	if (!ep) {
		mm = mmatic_create();
		ep = mmatic_zalloc(mm, sizeof *ep);
		ep->mm = mm;
		ep->source = source;
		ep->epa = epa;
		thash_set(spi->eps, key, ep);

		source->eps++;

		dbg(8, "new ep %s\n", spi_epa2a(epa));
	}

	/* make packet */
	pkt = mmatic_zalloc(ep->mm, sizeof *pkt);
	pkt->size = size;
	pkt->payload = mmatic_zalloc(ep->mm, spi->options.N);
	memcpy(pkt->payload, data, spi->options.N);
	memcpy(&pkt->ts, ts, sizeof(struct timeval));

	/* update last packet time */
	memcpy(&ep->last, ts, sizeof(struct timeval));

	/* store packet */
	if (!ep->pkts)
		ep->pkts = tlist_create(mmatic_free, ep->mm);

	tlist_push(ep->pkts, pkt);

	/* generate event if pkts big enough */
	if (ep->gclock1 == 0 && tlist_count(ep->pkts) >= spi->options.C) {
		ep->gclock1++;
		spi_announce(spi, "endpointPacketsReady", 0, ep, false);
		dbg(7, "ep %s ready\n", spi_epa2a(epa));
	}

	return ep;
}
Пример #2
0
int cmd_packet_init(struct line *line, const char *text)
{
	struct mg *mg = line->mg;
	struct cmd_packet *cp;
	struct mgp_line *pl;
	char *errmsg;

	pl = mgp_parse_line(mg->mm, text, 0, NULL, &errmsg,
		"size", "rep", "T", "burst", NULL);
	if (!pl) {
		dbg(0, "%s: line %d: packet: parse error: %s\n",
			mg->options.traf_file, line->line_num, errmsg);
		return 1;
	}

	/* rewrite into struct cmd_packet */
	cp = mmatic_zalloc(mg->mm, sizeof(struct cmd_packet));
	line->prv = cp;

	cp->len   = mgp_prepare_int(pl, "size", 100);
	cp->num   = mgp_int(mgp_prepare_int(pl, "rep", 1));
	cp->T     = mgp_prepare_int(pl, "T", 1000);
	cp->burst = mgp_prepare_int(pl, "burst", 1);

	return 0;
}
Пример #3
0
struct client *create_client(mmatic *mm)
{
	struct client *client;
	client = mmatic_zalloc(mm, sizeof *client);
	client->servers = thash_create_intkey(mmatic_free, mm);
	return client;
}
Пример #4
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);
}
Пример #5
0
int main(int argc, char *argv[])
{
	mmatic *mm;
	struct flowcalc *fc;
	void *h;
	struct module *mod;
	char *name, *s;
	tlist *ls;
	void *pdata;

	/*
	 * initialization
	 */
	mm = mmatic_create();
	fc = mmatic_zalloc(mm, sizeof *fc);
	fc->mm = mm;
	fc->modules = tlist_create(NULL, mm);

	/* read options */
	if (parse_argv(fc, argc, argv))
		return 1;

	/* enable all modules found in given directory */
	if (tlist_count(fc->modules) == 0) {
		ls = pjf_ls(fc->dir, mm);
		tlist_iter_loop(ls, name) {
			s = strrchr(name, '.');
			if (s && streq(s, ".so")) {
				*s = 0;
				tlist_push(fc->modules, name);
			}
		}
Пример #6
0
bool init(struct lfc *lfc, void **pdata)
{
    mmatic *mm;
    struct ndpi *ndpi;
    IPOQUE_PROTOCOL_BITMASK all;

    mm = mmatic_create();
    ndpi = mmatic_zalloc(mm, sizeof *ndpi);
    ndpi->mm = mm;
    ndpi->ids = thash_create_intkey(NULL, mm); // TODO: null ffn?

    ndpi->ipq = ipoque_init_detection_module(1000, ma, db); // TODO: 1000?
    if (!ndpi->ipq) {
        dbg(0, "ipoque_init_detection_module() failed\n");
        return false;
    }

    IPOQUE_BITMASK_SET_ALL(all);
    ipoque_set_protocol_detection_bitmask2(ndpi->ipq, &all);

    *pdata = ndpi;

    printf("%%%% ndpi 0.1 - nDPI\n");
    printf("@attribute ndpi_proto string\n");

    return true;
}
Пример #7
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;
}
Пример #8
0
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);
}
Пример #9
0
int main(int argc, char *argv[])
{
	mmatic *mm;

	/*
	 * initialization
	 */
	mm = mmatic_create();
	fd = mmatic_zalloc(mm, sizeof *fd);
	fd->mm = mm;
	fd->cache = thash_create_intkey(mmatic_free, mm);
	fd->out_files = thash_create_strkey(trace_destroy_output, mm);

	/* catch SIGINT */
	signal(SIGINT, sigint);

	/* read options */
	if (parse_argv(argc, argv))
		return 1;

	/* file-system init */
	{
		if (streq(fd->arff_file, "-")) {
			fd->afh = stdin;
		} else {
			fd->afh = fopen(fd->arff_file, "r");
			if (!fd->afh) {
				cleanup();
				die("Reading input ARFF file '%s' failed: %s\n", fd->arff_file, strerror(errno));
			}
		}

		if (pjf_mkdir(fd->dir) != 0) {
			cleanup();
			die("Creating output directory '%s' failed\n", fd->dir);
		}
	}

	fd->lfc = lfc_init();
	lfc_register(fd->lfc, "flowdump", sizeof(struct flow), pkt, NULL, fd);

	if (!lfc_run(fd->lfc, fd->pcap_file, fd->filter)) {
		cleanup();
		die("Reading file '%s' failed\n", fd->pcap_file);
	}

	cleanup();
	return 0;
}
Пример #10
0
int flow_count(struct spi_source *source, spi_epaddr_t src, spi_epaddr_t dst, const struct timeval *ts)
{
	struct spi *spi = source->spi;
	struct spi_flow *flow;

	flow = _get_flow(source, src, dst);
	if (!flow) {
		flow = mmatic_zalloc(spi, sizeof *flow);
		flow->source = source;
		flow->epa1 = MIN(src, dst);
		flow->epa2 = MAX(src, dst);
		_set_flow(source, src, dst, flow);
	}

	memcpy(&flow->last, ts, sizeof(struct timeval));
	return ++flow->counter;
}
Пример #11
0
void verdict_init(struct spi *spi)
{
	struct verdict *v;

	spi_subscribe(spi, "endpointClassification", _verdict_new_classification, false);
	spi_subscribe_after(spi, "endpointVerdictChanged", _verdict_eaten, false);

	v = mmatic_zalloc(spi->mm, sizeof *v);
	spi->vdata = v;

	if (spi->options.verdict_simple) {
		v->type = SPI_VERDICT_SIMPLE;
	} else if (spi->options.verdict_best) {
		v->type = SPI_VERDICT_BEST;
	} else {
		v->type = SPI_VERDICT_EWMA;
		v->ewma.N = spi->options.verdict_ewma_len ? spi->options.verdict_ewma_len : 5;
	}
}
Пример #12
0
void *port_list(struct tracedump *td, bool tcp)
{
	char *path;
	char buf[BUFSIZ], *ptr1, *ptr2;
	FILE *fp;
	uint8_t *list;
	unsigned long port;

	path = tcp ? "/proc/net/tcp" : "/proc/net/udp";

	fp = fopen(path, "r");
	if (!fp) {
		dbg(1, "fopen(%s): %s\n", path, strerror(errno));
		return NULL;
	}

	/* a bitmask 1: active, 0: inactive */
	list = mmatic_zalloc(td->mm, UINT16_MAX / sizeof(uint8_t));

	while (fgets(buf, sizeof buf, fp)) {
		/* first : */
		ptr1 = strchr(buf, ':');
		if (!ptr1) continue;
		ptr1++;

		/* second : */
		ptr1 = strchr(ptr1, ':');
		if (!ptr1) continue;
		ptr1++;

		/* space */
		ptr2 = strchr(ptr1, ' ');
		if (!ptr2) continue;
		ptr2[0]  = '\0';

		/* translate */
		port = strtol(ptr1, NULL, 16);
		PORT_SET(list, port);
	}

	fclose(fp);
	return list;
}
Пример #13
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;
}
Пример #14
0
static void _ewma_verdict(struct spi *spi, struct spi_classresult *cr)
{
	struct verdict *v = spi->vdata;
	struct ewma_verdict *ev = cr->ep->vdata;
	int i;
	double m1 = 0.0, m2 = 0.0;
	spi_label_t max_label = 0;

	/* special case if its first verdict request */
	if (!ev) {
		ev = mmatic_zalloc(cr->ep->mm, sizeof *ev);
		cr->ep->vdata = ev;

		/* init EWMA with class. result */
		memcpy(ev->cprob, cr->cprob, sizeof(spi_cprob_t));

		/* fall-back on simple verdict */
		_simple_verdict(spi, cr);
	} else {
		/* update EWMA */
		for (i = 1; i <= SPI_LABEL_MAX; i++) {
			ev->cprob[i] = EWMA(ev->cprob[i], cr->cprob[i], v->ewma.N);

			/* collect info as _cprob_dist() */
			if (ev->cprob[i] > m2) {
				if (ev->cprob[i] > m1) {
					max_label = i;
					m2 = m1;
					m1 = ev->cprob[i];
				} else {
					m2 = ev->cprob[i];
				}
			}
		}

		if (m1 - m2 > cr->ep->verdict_prob) {
			cr->ep->verdict = max_label;
			cr->ep->verdict_prob = (m1 - m2);
		}
	}
}
Пример #15
0
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 ndpi *nd = pdata;
    struct flow *f = data;
    struct ipoque_id_struct *srcid, *dstid;
    uint8_t *iph;
    uint16_t et;
    uint32_t rem;
    uint64_t time;

    if (!f->ipq_flow)
        f->ipq_flow = mmatic_zalloc(nd->mm, ipoque_detection_get_sizeof_ipoque_flow_struct());

    iph = trace_get_layer3(pkt, &et, &rem);
    time = ts * 1000;

    srcid = getid(nd, &lf->src);
    dstid = getid(nd, &lf->dst);

    f->proto = ipoque_detection_process_packet(
                   nd->ipq, f->ipq_flow, iph, rem, time, srcid, dstid);
}
Пример #16
0
int32_t inject_socketcall(struct tracedump *td, struct pid *sp, uint32_t sc_code, ...)
{
	/* int 0x80, int3 */
	unsigned char code[4] = { 0xcd, 0x80, 0xcc, 0 };
	char backup[4];
	struct user_regs_struct regs, regs2;
	int ss_vals, ss_mem, ss;
	va_list vl;
	enum arg_type type;
	uint32_t sv;
	void *ptr;
	uint8_t *stack, *stack_mem;
	uint32_t *stack32;
	int i, j;

	/*
	 * get the required amount of stack space
	 */
	ss_vals = 0;
	ss_mem = 0;
	va_start(vl, sc_code);
	do {
		type = va_arg(vl, enum arg_type);
		if (type == AT_LAST) break;
		sv  = va_arg(vl, uint32_t);

		/* each socketcall argument takes 4 bytes */
		ss_vals += 4;

		/* if its memory, it takes additional sv bytes */
		if (type == AT_MEM_IN || type == AT_MEM_INOUT) {
			ss_mem += sv;
			ptr = va_arg(vl, void *);
		}
	} while (true);
	va_end(vl);
	ss = ss_vals + ss_mem;

	/*
	 * backup
	 */
	ptrace_getregs(sp, &regs);
	memcpy(&regs2, &regs, sizeof regs);
	ptrace_read(sp, regs.eip, backup, sizeof backup);

	/*
	 * write the stack
	 */
	stack = mmatic_zalloc(td->mm, ss);
	stack32 = (uint32_t *) stack;
	stack_mem = stack + ss_vals;

	va_start(vl, sc_code);
	i = 0; j = 0;
	do {
		type = va_arg(vl, enum arg_type);
		if (type == AT_LAST) break;

		sv  = va_arg(vl, uint32_t);

		if (type == AT_VALUE) {
			stack32[i++] = sv;
		} else { /* i.e. its a memory arg */
			stack32[i++] = regs.esp - ss_mem + j;

			/* copy the memory */
			ptr = va_arg(vl, void *);
			memcpy(stack_mem + j, ptr, sv);
			j += sv;
		}
	} while (true);
	va_end(vl);

	ptrace_write(sp, regs.esp - ss, stack, ss);

	/*
	 * write the code and run
	 */
	regs2.eax = 102; // socketcall
	regs2.ebx = sc_code;
	regs2.ecx = regs.esp - ss;

	ptrace_write(sp, regs.eip, code, sizeof code);
	ptrace_setregs(sp, &regs2);
	ptrace_cont(sp, 0, true);

	/*
	 * read back
	 */
	ptrace_getregs(sp, &regs2);
	ptrace_read(sp, regs.esp - ss_mem, stack_mem, ss_mem);

	va_start(vl, sc_code);
	do {
		type = va_arg(vl, enum arg_type);
		if (type == AT_LAST) break;

		sv = va_arg(vl, uint32_t);
		if (type == AT_VALUE) continue;

		ptr = va_arg(vl, void *);
		if (type == AT_MEM_IN) continue;

		memcpy(ptr, stack_mem, sv);
		stack_mem += sv;
	} while (true);
	va_end(vl);

	/* restore */
	ptrace_write(sp, regs.eip, backup, sizeof backup);
	ptrace_setregs(sp, &regs);

	mmatic_free(stack);

	return regs2.eax;
}
Пример #17
0
int main(int argc, char *argv[])
{
	mmatic *mm = mmatic_create();
	mmatic *mmtmp = mmatic_create();
	struct mg *mg;
	int i;

	/*
	 * initialize and parse config
	 */

	mg = mmatic_zalloc(mm, sizeof(struct mg));
	mg->mm = mm;
	mg->mmtmp = mmtmp;
	apply_defaults(mg);

	/* get my id number from hostname */
	fetch_myid(mg);

	/* parse command line options */
	if (parse_argv(mg, argc, argv))
		return 1;

	/* parse configuration file options */
	if (mg->options.conf_file) {
		if (parse_config(mg))
			return 4;
	}

	/*
	 * config syntax looks OK, see if it is feasible
	 */

	/* initialize random number generator */
	srand48(mg->options.myid);

	/* init libevent */
	mg->evb = event_init();
	event_set_log_callback(libevent_log);

	/* init stats structures so mgstats_aggregator_add() used somewhere below works */
	mgstats_init(mg);

	/* attach to raw interfaces */
	if (mgi_init(mg, handle_packet) <= 0) {
		dbg(0, "no available interfaces found\n");
		return 2;
	}

	/* parse traffic file */
	if (parse_traffic(mg))
		return 3;

	/*
	 * all OK, prepare to start
	 */

	/* synchronize time reference point on all nodes */
	mgc_sync(mg);

	/* schedule stats writing */
	mgstats_start(mg);

	/* attach global stats */
	_stats_init(mg);

	/* schedule heartbeat and disk sync signals */
	heartbeat_init(mg);
	sync_init(mg);

	/* schedule the real work of this node: line generators */
	for (i = 1; i < TRAFFIC_LINE_MAX; i++) {
		if (!(mg->lines[i] && mg->lines[i]->my))
			continue;

		/* this will schedule first execution */
		mgs_sleep(mg->lines[i], NULL);
		mg->running++;
	}

	/* suppose last frame was received now */
	gettimeofday(&mg->last, NULL);

	/*
	 * start!
	 */

	dbg(0, "Starting\n");
	event_base_dispatch(mg->evb);

	/*******************************/

	/*
	 * cleanup after end of libevent loop
	 */

	event_base_free(mg->evb);
	mmatic_free(mg->mm);
	mmatic_free(mg->mmtmp);

	fflush(NULL);
	sync();

	return 0;
}
Пример #18
0
/** Parse traffic file
 * @retval 0 success
 * @retval 1 syntax error
 * @retval 2 logic error
 */
static int parse_traffic(struct mg *mg)
{
	FILE *fp;
	const char *file;
	char buf[BUFSIZ];
	uint32_t line_num = 0;
	struct line *line;
	int i, rc;
	char *rest, *errmsg;
	struct mgp_line *pl;

	file = mg->options.traf_file;
	fp = fopen(file, "r");
	if (!fp) {
		dbg(0, "could not open traffic file: %s: %s\n", file, strerror(errno));
		return 1;
	}

	while (fgets(buf, sizeof buf, fp)) {
		line_num++;
		if (line_num >= N(mg->lines))
			die("Too many lines in the traffic file");

		/* skip comments */
		if (buf[0] == '#' || buf[0] == '\r' || buf[0] == '\n')
			continue;

		/* parse line */
		pl = mgp_parse_line(mg->mm, buf, 8, &rest, &errmsg,
			"s", "ms", "iface", "src", "dst", "rate", "noack", "cmd", NULL);
		if (!pl) {
			dbg(0, "%s: line %d: parse error: %s\n", file, line_num, errmsg);
			return 1;
		}

		/* ...and rewrite into struct line */
		line = mmatic_zalloc(mg->mm, sizeof *line);
		mg->lines[line_num] = line;

		line->mg = mg;
		line->line_num = line_num;
		line->contents = mmatic_strdup(mg->mm, buf);
		line->stats = stats_create(mg->mm);

		/* time */
		line->tv.tv_sec = mgp_get_int(pl, "s", 0);
		line->tv.tv_usec = mgp_get_int(pl, "ms", 0) * 1000;

		/* interface */
		i = mgp_get_int(pl, "iface", 0);
		if (i >= IFINDEX_MAX) {
			dbg(0, "%s: line %d: too big interface number: %d\n", file, line_num, i);
			return 1;
		}
		line->interface = &mg->interface[i];
		if (line->interface->fd <= 0) {
			dbg(0, "%s: line %d: interface not opened: %d\n", file, line_num, i);
			return 2;
		}

		/* src/dst */
		line->srcid = mgp_get_int(pl, "src", 1);
		line->dstid = mgp_get_int(pl, "dst", 1);
		line->my    = (line->srcid == mg->options.myid);

		/* rate/noack */
		line->rate = mgp_get_float(pl, "rate", 0) * 2.0;  /* driver uses "half-rates"; NB: "auto" => 0 */
		line->noack = mgp_get_int(pl, "noack", 0);

		/*
		 * command
		 */
		line->cmd = mgp_get_string(pl, "cmd", "");
		if (!line->cmd) {
			dbg(0, "%s: line %d: no line command\n", file, line_num);
			return 2;
		}

		/* find command handlers */
		if (!find_line_cmd(line)) {
			dbg(0, "%s: line %d: invalid command: %s\n", file, line_num, line->cmd);
			return 2;
		}

		/* initialize scheduler of outgoing frames */
		mgs_setup(&line->schedule, mg, line->cmd_timeout, line);

		/* call command initializer */
		rc = line->cmd_init(line, rest);
		if (rc != 0)
			return rc;
	}

	fclose(fp);
	return 0;
}
Пример #19
0
int32_t inject_socketcall(struct tracedump *td, struct pid *sp, uint32_t sc_code, ...)
{
	struct user_regs_struct regs, regs2;
	int ss_vals, ss_mem, ss;
	va_list vl;
	enum arg_type type;
	uint32_t sv;
	void *ptr;
	uint8_t *stack, *stack_mem;
	uint32_t *stack32;
	int i, j;

	/*
	 * get the required amount of stack space
	 */
	ss_vals = 0;  // stack space for immediate values
	ss_mem = 0;   // stack space for pointer values
	va_start(vl, sc_code);
	do {
		type = va_arg(vl, enum arg_type);
		if (type == AT_LAST) break;
		sv  = va_arg(vl, uint32_t);

		/* each socketcall argument takes 4 bytes */
		ss_vals += 4;

		/* if its memory, it takes additional sv bytes */
		if (type == AT_MEM_IN || type == AT_MEM_INOUT) {
			ss_mem += sv;
			ptr = va_arg(vl, void *);
		}
	} while (true);
	va_end(vl);
	ss = ss_vals + ss_mem;

	/*
	 * backup
	 */
	ptrace_getregs(sp, &regs);
	memcpy(&regs2, &regs, sizeof regs);

	/*
	 * write the stack
	 */
	stack = mmatic_zalloc(td->mm, ss); // stack area for immediate values
	stack32 = (uint32_t *) stack;
	stack_mem = stack + ss_vals;       // stack area for pointer values

	va_start(vl, sc_code);
	i = 0; j = 0;
	do {
		type = va_arg(vl, enum arg_type);
		if (type == AT_LAST) break;

		sv  = va_arg(vl, uint32_t);

		if (type == AT_VALUE) {
			stack32[i++] = sv;
		} else { /* i.e. its a memory arg */
			stack32[i++] = regs.esp - ss_mem + j;

			/* copy the memory */
			ptr = va_arg(vl, void *);
			memcpy(stack_mem + j, ptr, sv);
			j += sv;
		}
	} while (true);
	va_end(vl);

	ptrace_write(sp, regs.esp - ss, stack, ss);

	/*
	 * write the code and run
	 */
	_prepare(sp);

	regs2.eax = 102;            // socketcall
	regs2.ebx = sc_code;
	regs2.ecx = regs.esp - ss;
	regs2.eip = sp->vdso_addr;  // gateway to int3

	ptrace_setregs(sp, &regs2);
	ptrace_cont_syscall(sp, 0, true);   // enter...
	ptrace_cont_syscall(sp, 0, true);   // ...and exit

	/*
	 * read back
	 */
	ptrace_getregs(sp, &regs2);
	ptrace_read(sp, regs.esp - ss_mem, stack_mem, ss_mem);

	va_start(vl, sc_code);
	do {
		type = va_arg(vl, enum arg_type);
		if (type == AT_LAST) break;

		sv = va_arg(vl, uint32_t);
		if (type == AT_VALUE) continue;

		ptr = va_arg(vl, void *);
		if (type == AT_MEM_IN) continue;

		memcpy(ptr, stack_mem, sv);
		stack_mem += sv;
	} while (true);
	va_end(vl);

	/* restore */
	ptrace_setregs(sp, &regs);
	mmatic_free(stack);

	return regs2.eax;
}
Пример #20
0
static struct sock_fprog *gencode_alloc(struct tracedump *td)
{
	struct sock_fprog *fp;
	int i, j;

	/* code locations */
	int
	loc_1      = 0,
	loc_2      = loc_1 + N(check_ip),
	loc_3      = loc_2 + N(check_type_outbound),
	loc_4      = loc_3 + N(check_ports) + thash_count(td->udp_ports),
	loc_5      = loc_4 + N(check_ports) + thash_count(td->tcp_ports),
	loc_6      = loc_5 + N(check_type_inbound),
	loc_7      = loc_6 + N(check_ports) + thash_count(td->udp_ports),
	loc_accept = loc_7 + N(check_ports) + thash_count(td->tcp_ports),
	loc_drop   = loc_accept + 1;

	/* allocate memory */
	fp = mmatic_zalloc(td->mm, sizeof(struct sock_fprog));
	fp->len = loc_drop + 1;
	fp->filter = mmatic_zalloc(td->mm, sizeof(struct sock_filter) * fp->len);

/*printf("loc_1=%d, loc_2=%d, loc_3=%d, loc_4=%d, loc_5=%d, loc_6=%d, loc_7=%d, loc_drop=%d, loc_accept=%d\n",
loc_1, loc_2, loc_3, loc_4, loc_5,
loc_6, loc_7, loc_drop, loc_accept);*/

	/*
	 * Fill
	 */
	i = 0;

#define SUBST_JMP(from, to)                    \
	if (fp->filter[i+j].jt == (from))          \
		fp->filter[i+j].jt = (to) - i - j - 1; \
	if (fp->filter[i+j].jf == (from))          \
		fp->filter[i+j].jf = (to) - i - j - 1;

	/* 1. check_ip */
	memcpy(fp->filter + i, check_ip, sizeof check_ip);
	for (j = 0; j < N(check_ip); j++) {
		SUBST_JMP(__DROP, loc_drop);
	}
	i += j;

	/* 2. check_type_outbound */
	memcpy(fp->filter + i, check_type_outbound, sizeof check_type_outbound);
	for (j = 0; j < N(check_type_outbound); j++) {
		SUBST_JMP(__RET1, loc_5);
		SUBST_JMP(__RET2, loc_4);
		SUBST_JMP(__DROP, loc_drop);
	}
	i += j;

	/* 3. OUTBOUND: check_ports: td->udp_ports */
	i += gencode_check_ports(td->udp_ports, true, fp->filter+i, loc_drop-i, loc_accept-i);

	/* 4. OUTBOUND: check_ports: td->tcp_ports */
	i += gencode_check_ports(td->tcp_ports, true, fp->filter+i, loc_drop-i, loc_accept-i);

	/* 5. check_type_inbound */
	memcpy(fp->filter + i, check_type_inbound, sizeof check_type_inbound);
	for (j = 0; j < N(check_type_inbound); j++) {
		SUBST_JMP(__RET1, loc_7);
		SUBST_JMP(__DROP, loc_drop);
	}
	i += j;

	/* 6. INBOUND: check_ports: td->udp_ports */
	i += gencode_check_ports(td->udp_ports, false, fp->filter+i, loc_drop-i, loc_accept-i);

	/* 7. INBOUND: check_ports: td->tcp_ports */
	i += gencode_check_ports(td->tcp_ports, false, fp->filter+i, loc_drop-i, loc_accept-i);

	/* 8. end */
	memcpy(fp->filter + i, end, sizeof end);
	i += N(end);

	return fp;
}