コード例 #1
0
void
setup_io(void) {
	nmsg_output_t output_cb;
	nmsg_res res;

	io = nmsg_io_init();
	assert(io != NULL);

	output_cb = nmsg_output_open_callback(nmsg_callback, NULL);
	if (output_cb == NULL)
		errx(EXIT_FAILURE, "nmsg_output_open_callback() failed");
	res = nmsg_io_add_output(io, output_cb, NULL);
	if (res != nmsg_res_success)
		errx(EXIT_FAILURE, "nmsg_io_add_output() failed: %s", nmsg_res_lookup(res));
}
コード例 #2
0
ファイル: output.c プロジェクト: farsightsec/axa
void
out_flush(void)
{
	nmsg_res res;
	ssize_t wlen;

	if (time_out_flush.tv_sec == 0)
		return;

	if (out_buf_len != 0) {
		wlen = write(out_fd, &out_buf[out_buf_base],
			     out_buf_len - out_buf_base);
		if (wlen < 0) {
			if (errno != EAGAIN && errno != EWOULDBLOCK
			    && errno != EINTR) {
				error_msg("write(%s): %s",
					  out_addr, strerror(errno));
				out_close(true);
			}
		} else {
			out_buf_base += wlen;
			if (out_buf_base >= out_buf_len)
				out_buf_base = out_buf_len = 0;
		}
	}

	if (out_nmsg_output != NULL) {
		res = nmsg_output_flush(out_nmsg_output);
		if (res != nmsg_res_success
		    &&  (out_sock_type != SOCK_DGRAM
			 || res != nmsg_res_errno
			 || !AXA_IGNORED_UDP_ERRNO(errno))) {
			error_msg("nmsg_output_flush(forward): %s",
				  nmsg_res_lookup(res));
			out_close(true);
		}
	}

	time_out_flush.tv_sec = 0;
}
コード例 #3
0
ファイル: whit2nmsg.c プロジェクト: synthesizerpatel/axa
axa_w2n_res_t
axa_whit2nmsg(axa_emsg_t *emsg, nmsg_input_t nmsg_input,
	      nmsg_message_t *msgp, axa_p_whit_t *whit, size_t whit_len)
{
	size_t msg_len;
	nmsg_message_t *msgs;
	size_t n_msgs;
	struct timespec ts;
	nmsg_res res;

	*msgp = NULL;

	msg_len = whit_len - sizeof(whit->nmsg.hdr);
	if (msg_len <= 0) {
		axa_pemsg(emsg, "truncated nmsg");
		return (AXA_W2N_RES_FAIL);
	}
	ts.tv_sec = AXA_P2H32(whit->nmsg.hdr.ts.tv_sec);
	ts.tv_nsec = AXA_P2H32(whit->nmsg.hdr.ts.tv_nsec);
	res = nmsg_input_read_null(nmsg_input, whit->nmsg.b, msg_len,
				   &ts, &msgs, &n_msgs);
	if (res != nmsg_res_success) {
		axa_pemsg(emsg, "nmsg_input_read_null(): %s",
			  nmsg_res_lookup(res));
		return (AXA_W2N_RES_FAIL);
	}
	/* if res == nmsg_res_success && n_msgs == 0, we have an NMSG fragment */
	if (n_msgs < 1 || n_msgs > 1) {
		while (n_msgs > 0)
			nmsg_message_destroy(&msgs[--n_msgs]);
		free(msgs);
		return (AXA_W2N_RES_FRAGMENT);
	}

	*msgp = msgs[0];
	free(msgs);
	return (AXA_W2N_RES_SUCCESS);
}
コード例 #4
0
ファイル: main.c プロジェクト: farsightsec/axa
int
main(int argc, char **argv)
{
	const char *fields_file = "";
	const char *config_file = "";
#if LIBEDIT_IS_UNICODE
	wchar_t wc;
#endif
	char cmd_buf[500];
	const char *cmd;
	int cmd_len;
	bool version = false;
	const char *cfile = NULL;
	size_t n;
	nmsg_res res;
	char *p;
	int i;

	axa_set_me(argv[0]);
	AXA_ASSERT(axa_parse_log_opt(NULL, "trace,off,stderr"));
	AXA_ASSERT(axa_parse_log_opt(NULL, "error,off,stderr"));
	axa_syslog_init();
	axa_set_core();
	axa_client_init(&client);

	if (strcmp(axa_prog_name, "radtool") == 0)
		mode = RAD;

	if (isatty(STDIN_FILENO))
		el_e = el_init(axa_prog_name, stdin, stdout, stderr);
	if (el_e != NULL) {
		int flag;

		if (0 > el_get(el_e, EL_EDITMODE, &flag) || !flag) {
			el_end(el_e);
			el_e = NULL;
		}
	}
	if (el_e != NULL) {
		/* prefer emacs mode but let the user choose in .editrc */
		el_set(el_e, EL_EDITOR, "emacs");
		/* bind emacs search to ^R */
		el_set(el_e, EL_BIND, "\022", "em-inc-search-prev", NULL);
		el_source(el_e, NULL);
		el_history = history_init();
		history(el_history, &el_event, H_SETSIZE, 800);
		history_get_savefile();
		history(el_history, &el_event, H_LOAD, history_savefile);
		el_set(el_e, EL_HIST, history, el_history);
		el_set(el_e, EL_PROMPT, el_prompt);
		el_set(el_e, EL_SIGNAL, 1);
		el_set(el_e, EL_GETCFN, getcfn);
	}

	while ((i = getopt(argc, argv, "hVdNF:E:S:c:n:")) != -1) {
		switch (i) {
		case 'n':
			config_file = optarg;
			break;
		case 'V':
			version = true;
			break;

		case 'h':
			usage();
			break;
		case 'd':
			++axa_debug;
			break;

		case 'N':
			no_prompt = true;
			break;

		case 'F':
			fields_file = optarg;
			break;

		case 'E':
			if (axa_tls_cipher_list(&emsg, optarg) == NULL)
				error_msg("%s", emsg.c);
			break;

		case 'S':
			if (!axa_tls_certs_dir(&emsg, optarg))
				error_msg("%s", emsg.c);
			break;

		case 'c':
			if (cfile != NULL)
				error_msg("only one -c allowed;"
					  " ignoring all but the last");
			cfile = optarg;
			break;

		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	if (version) {
		version_cmd(AXA_TAG_NONE, "", NULL);
		if (argc == 0)
			stop(EX_OK);
	}

	signal(SIGPIPE, SIG_IGN);
	if (el_e != NULL) {
		signal(SIGINT, sigint);
		signal(SIGTERM, sigterm);
		signal(SIGHUP, sigterm);
	}

	AXA_DEBUG_TO_NMSG(axa_debug);
	res = nmsg_init();
	if (res != nmsg_res_success) {
		error_msg("nmsg_init(): %s", nmsg_res_lookup(res));
		exit(EX_SOFTWARE);
	}
	nmsg_input = nmsg_input_open_null();
	AXA_ASSERT(nmsg_input != NULL);
	nmsg_pres = nmsg_output_open_pres(STDOUT_FILENO);

	axa_load_fields(fields_file);
	if (!axa_load_client_config(&emsg, config_file)) {
			axa_error_msg("can't load config file: %s", emsg.c);
			exit(EXIT_FAILURE);
	}

	/* Answer commands from the control file. */
	if (cfile != NULL) {
		axa_asprintf(&p, "source %s", cfile);
		if (el_e != NULL)
			history(el_history, &el_event, H_ENTER, p);
		if (!do_cmds(p))
			error_msg(" initial \"-c %s\" failed", cfile);
		free(p);
	}

	/* Answer commands from the command line. */
	while (argc != 0) {
		if (el_e != NULL)
			history(el_history, &el_event, H_ENTER, *argv);
		if (!do_cmds(*argv)) {
			error_msg(" initial command \"%s\" failed", *argv);
			break;
		}

		++argv;
		--argc;
	}

	for (;;) {
		cmd_input.tv_sec = 0;
		fflush(stderr);
		fflush(stdout);

		if (in_file_cur > 0) {
			/* Get a command from a "sourced" file. */
			if (interrupted) {
				close_in_files();
				continue;
			}
			cmd = axa_fgetln(in_files[in_file_cur].f,
					 in_files[in_file_cur].name,
					 &in_files[in_file_cur].lineno,
					 &in_files[in_file_cur].buf,
					 &in_files[in_file_cur].buf_size);
			if (cmd == NULL) {
				close_in_file_cur();
				continue;
			}
			if (axa_debug != 0) {
				printf("< %s\n", cmd);
				fflush(stdout);
			}

		} else if (el_e != NULL) {
			/* Get a command from the terminal via editline(3). */
			cmd = el_gets(el_e, &cmd_len);
			prompt_len = 0;
			if (!interrupted) {
				if (cmd == NULL) {
					fputc('\n', stdout);
					if (cmd_len == -1)
					    error_msg("el_gets(): %s",
						      strerror(errno));
					stop(EX_OK);
				}

				/* Save nontrivial command lines. */
				if (*(cmd+strspn(cmd, AXA_WHITESPACE)) != '\0')
					history(el_history, &el_event,
						H_ENTER, cmd);
			}

		} else if (!interrupted) {
			/* Get a command from stdin. */
			n = 0;
			for (;;) {
#if LIBEDIT_IS_UNICODE
				getcfn(NULL, &wc);
				cmd_buf[n] = wctob(wc);
#else
				getcfn(NULL, &cmd_buf[n]);
#endif
				if (cmd_buf[n++] == '\n'
				    || n >= sizeof(cmd_buf)-1)
					break;
			}
			cmd_buf[n] = '\0';
			cmd = cmd_buf;
		}

		if (interrupted) {
			interrupted = false;
			if (el_e != NULL) {
				el_set(el_e, EL_UNBUFFERED, 0);
				el_reset(el_e);
				if (prompt_cleared.tv_sec != 0) {
					packet_counting = true;
					packet_count = 0;
					packet_count_total = 0;
				}
			}
			close_in_files();
			fputs(" (int)\n", stdout);
			continue;
		}

		if (!do_cmds(cmd)) {
			fputs(" ?\n", stderr);
			fflush(stdout);
			close_in_files();
		}
	}
}
コード例 #5
0
ファイル: output.c プロジェクト: farsightsec/axa
/* forward watch hits as NMSG messages */
bool
out_whit_nmsg(axa_p_whit_t *whit, size_t whit_len)
{
	nmsg_message_t msg;
	struct timespec ts;
	static const union {
		uint    e;
		uint8_t	c[0];
	} pkt_enum = { .e = NMSG__BASE__PACKET_TYPE__IP };
	size_t len;
	struct timeval now;
	nmsg_res res;
	bool result;

	switch ((axa_p_whit_enum_t)whit->hdr.type) {
	case AXA_P_WHIT_NMSG:
		/* pass NMSG messages along */
		if (whit2nmsg(&msg, whit, whit_len) == AXA_W2N_RES_FRAGMENT) {
			if (axa_debug != 0)
				printf("ignoring NMSG fragment from "
						AXA_OP_CH_PREFIX"%d",
						AXA_P2H_CH(whit->hdr.ch));
			return (false);
		}
		if (msg == NULL)
			return (false);
		break;

	case AXA_P_WHIT_IP:
		/* Convert raw IP packets to nmsg BASE_PACKET */
		len = whit_len - sizeof(whit->ip.hdr);
		if (AXA_P2H32(whit->ip.hdr.ip_len) != len)
			return (false);	/* Ignore incomplete packets. */

		if (!out_nmsg_mod_checked) {
			out_nmsg_mod_checked = true;
			out_nmsg_mod = nmsg_msgmod_lookup(NMSG_VENDOR_BASE_ID,
						NMSG_VENDOR_BASE_PACKET_ID);
			if (out_nmsg_mod == NULL) {
				out_error("cannot get BASE_PACKET module");
				return (false);
			}
			res = nmsg_msgmod_init(out_nmsg_mod, &out_nmsg_clos);
			if (res != nmsg_res_success) {
				out_error("cannot init BASE_PACKET module");
				out_nmsg_mod = NULL;
				return (false);
			}
		}
		if (out_nmsg_mod == NULL) {
			out_error("cannot forward IP as NMSG messages"
				  " without PACKET nmsg_msgmod");
			return (false);
		}

		msg = nmsg_message_init(out_nmsg_mod);
		AXA_ASSERT(msg != NULL);
		res = nmsg_message_set_field(msg, "payload_type", 0,
					     pkt_enum.c, sizeof(pkt_enum));
		AXA_ASSERT(res == nmsg_res_success);
		res = nmsg_message_set_field(msg, "payload", 0,
					     whit->ip.b, len);
		AXA_ASSERT(res == nmsg_res_success);
		ts.tv_sec = AXA_P2H32(whit->ip.hdr.tv.tv_sec);
		ts.tv_nsec = AXA_P2H32(whit->ip.hdr.tv.tv_usec) * 1000;
		nmsg_message_set_time(msg, &ts);
		break;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunreachable-code"
	default:
		out_error("cannot forward SRA #%d messages as NMSG messages",
			  whit->hdr.type);
		return (false);
#pragma clang diagnostic pop
	}

	res = nmsg_output_write(out_nmsg_output, msg);
	if (res == nmsg_res_success) {
		result = true;
	} else {
		result = false;

		gettimeofday(&now, NULL);
		if (out_sock_type != SOCK_DGRAM
		    || res != nmsg_res_errno
		    || !AXA_IGNORED_UDP_ERRNO(errno)) {
			/* Stop on non-UDP errors. */
			clear_prompt();
			error_msg("nmsg_output_write(): %s",
				  nmsg_res_lookup(res));
			out_close(false);
			disconnect(true);
		} else if (output_errno != errno
			   || 60*1000 <= axa_elapsed_ms(&now,
							&output_errno_time)
			   || axa_debug >= AXA_DEBUG_TRACE) {
			/* Report occasional identical UDP errors. */
			output_errno = errno;
			gettimeofday(&output_errno_time, NULL);
			clear_prompt();
			error_msg("nmsg_output_write(): %s",
				  strerror(output_errno));
		}
	}

	nmsg_message_destroy(&msg);
	if (time_out_flush.tv_sec == 0)
		gettimeofday(&time_out_flush, NULL);

	return (result);
}
コード例 #6
0
ファイル: axa_tsindextool.c プロジェクト: farsightsec/axa
int
main(int argc, char *argv[])
{
	int n, c, rc, ec = EXIT_FAILURE, fd_in = -1, fd_out = -1, verbosity = 0;
	uint32_t ts_start = 0, ts_end = 0, count = 0, nmsg_cnt = 0;
	MDB_env *env = NULL;
	MDB_txn *txn = NULL;
	MDB_dbi dbi;
	MDB_val key, data;
	MDB_cursor *cursor = NULL;
	struct timespec ts, msg_ts;
	off_t *offset;
	nmsg_input_t nmsg_in = NULL;
	nmsg_output_t nmsg_out = NULL;
	nmsg_res res;
	nmsg_message_t msg;
	char *json;
	bool input_json = false, input_nmsg = false, is_counting = false, need_exact = false;
	const char *lmdb_filename = NULL, *nmsg_filename_in = NULL;
	char nmsg_filename_out[BUFSIZ] = {0};

	while ((c = getopt(argc, argv, "c:e:f:j:r:s:hvx")) != EOF) {
		switch (c) {
			case 'c':
				count = atoi(optarg);
				is_counting = true;
				break;
			case 'e':
				ts_end = atoi(optarg);
				break;
			case 'f':
				lmdb_filename = optarg;
				break;
			case 'j':
				nmsg_filename_in = optarg;
				input_json = true;
				break;
			case 'r':
				nmsg_filename_in = optarg;
				input_nmsg = true;
				break;
			case 's':
				ts_start = atoi(optarg);
				break;
			case 'v':
				verbosity++;
				break;
			case 'x':
				need_exact = true;
				break;
			case 'h':
			default:
				usage(argv[0], NULL);
				goto done;
		}
	}

	if (ts_start == 0) {
		usage(argv[0], "Need a starting timestamp (-s).");
		goto done;
	}
	if (lmdb_filename == NULL) {
		usage(argv[0], "Need a tsindex file (-f).");
		goto done;
		return (EXIT_FAILURE);
	}
	if ((input_json == false && input_nmsg == false) ||
			(input_json && input_nmsg)) {
		usage(argv[0], "Need either an nmsg json file (-j) or binary nmsg file (-r).");
		goto done;
		return (EXIT_FAILURE);
	}
	if ((ts_end == 0 && count == 0) ||
			(ts_end != 0 && count != 0)) {
		usage(argv[0], "Need either an ending timestamp (-e) or a count (-c).");
		goto done;
		return (EXIT_FAILURE);
	}

	res = nmsg_init();
	if (res != nmsg_res_success) {
		fprintf(stderr, "Error initializing NMSG library: %s\n",
				nmsg_res_lookup(res));
		goto done;
		return (EXIT_FAILURE);
	}

	fd_in = open(nmsg_filename_in, O_RDONLY);
	if (fd_in < 0) {
		fprintf(stderr, "Can't open nmsg input file \"%s\": %s\n",
				nmsg_filename_in, strerror(errno));
		goto done;
		return (EXIT_FAILURE);
	}
	n = strlcpy(nmsg_filename_out, nmsg_filename_in,
			sizeof (nmsg_filename_out));
	snprintf(nmsg_filename_out + n, sizeof (nmsg_filename_out) - n,
			"-tsindex.%u.%s", getpid(),
			input_json ? "json" : "nmsg");

	fd_out = open(nmsg_filename_out, O_CREAT | O_WRONLY, 0644);
	if (fd_out < 0) {
		fprintf(stderr, "Can't open nmsg output file \"%s\": %s\n",
				nmsg_filename_out, strerror(errno));
		goto done;
		return (EXIT_FAILURE);
	}

	if (input_json) {
		nmsg_in = nmsg_input_open_json(fd_in);
		if (nmsg_in == NULL) {
			fprintf(stderr, "nmsg_input_open_json() failed\n");
			goto done;
		}
		nmsg_out = nmsg_output_open_json(fd_out);
		if (nmsg_out == NULL) {
			fprintf(stderr, "nmsg_ouput_open_json() failed\n");
			goto done;
		}
	}
	else if (input_nmsg) {
		nmsg_in = nmsg_input_open_file(fd_in);
		if (nmsg_in == NULL) {
			fprintf(stderr, "nmsg_input_open_file() failed\n");
			goto done;
		}
		nmsg_out = nmsg_output_open_file(fd_out, NMSG_WBUFSZ_MAX);
		if (nmsg_out == NULL) {
			fprintf(stderr, "nmsg_ouput_open_file() failed\n");
			goto done;
		}
	}

	rc = mdb_env_create(&env);
	if (rc != 0) {
		fprintf(stderr, "mdb_create() failed: %s\n", mdb_strerror(rc));
		goto done;
	}

	rc = mdb_env_open(env, lmdb_filename, MDB_NOSUBDIR | MDB_RDONLY, 0664);
	if (rc != 0) {
		fprintf(stderr, "mdb_env_open failed(): %s\n",
				mdb_strerror(rc));
		goto done;
	}

	rc = mdb_txn_begin(env, NULL, MDB_RDONLY, &txn);
	if (rc != 0) {
		fprintf(stderr, "mdb_txn_begin failed(): %s\n",
				mdb_strerror(rc));
		goto done;
	}

	rc = mdb_open(txn, NULL, MDB_INTEGERKEY, &dbi);
	if (rc) {
		fprintf(stderr, "mdb_open(): %s\n", mdb_strerror(rc));
		goto done;
	}

	rc = mdb_set_compare(txn, dbi, axa_tsi_mdb_cmp);
	if (rc) {
		fprintf(stderr, "mdb_set_compare(): %s\n", mdb_strerror(rc));
		goto done;
	}

	ts.tv_sec = ts_start;
	ts.tv_nsec = 0;

	key.mv_size = sizeof (ts);
	key.mv_data = &ts;

	rc = mdb_cursor_open(txn, dbi, &cursor);
	if (rc) {
		fprintf(stderr, "mdb_cursor_open(): %s\n", mdb_strerror(rc));
		goto done;
	}

	rc = mdb_cursor_get(cursor, &key, &data,
			need_exact ? MDB_SET : MDB_SET_RANGE);
	if (rc == MDB_NOTFOUND) {
		printf("Did not find starting timestamp %u in %s.\n",
				ts_start, lmdb_filename);
		goto done;
	}
	if (rc) {
		fprintf(stderr, "mdb_cursor_get(): %s\n", mdb_strerror(rc));
		goto done;
	}

	(void) mdb_cursor_close(cursor);

	offset = (off_t *)data.mv_data;
	if (verbosity > 0)
		printf("Found %u at offset 0x%"PRIu64".\n", ts_start, *offset);

	if (lseek(fd_in, *offset, SEEK_SET) == sizeof (off_t) - 1) {
		fprintf(stderr, "lseek(): %s\n", strerror(errno));
		goto done;
	}

	while (1) {
		if (is_counting) {
			if (count-- <= 0)
				break;
		}
		res = nmsg_input_read(nmsg_in, &msg);
		if (res == nmsg_res_eof) {
			if (verbosity > 0)
				printf("End of file reached.\n");
			break;
		}
		if (res != nmsg_res_success) {
			fprintf(stderr, "nmsg_input_read(): %s\n", nmsg_res_lookup(res));
			goto done;
		}

		if (is_counting == false) {
			nmsg_message_get_time(msg, &msg_ts);
			if (msg_ts.tv_sec >= ts_end) {
				nmsg_message_destroy(&msg);
				break;
			}
		}

		res = nmsg_output_write(nmsg_out, msg);
		if (res != nmsg_res_success) {
			fprintf(stderr, "nmsg_output_write(): %s\n", nmsg_res_lookup(res));
			nmsg_message_destroy(&msg);
			goto done;
		}

		if (verbosity > 1) {
			res = nmsg_message_to_json(msg, &json);
			if (res != nmsg_res_success) {
				fprintf(stderr, "nmsg_message_to_pres(): %s\n", nmsg_res_lookup(res));
				nmsg_message_destroy(&msg);
				goto done;
			}

			printf("%s\n", json);
			free(json);
		}
		nmsg_cnt++;
		nmsg_message_destroy(&msg);
	}

	ec = EXIT_SUCCESS;
	printf("Wrote %u nmsgs to %s.\n", nmsg_cnt, nmsg_filename_out);
done:
	if (fd_in != -1)
		close(fd_in);
	if (fd_out != -1)
		close(fd_out);
	if (nmsg_in != NULL)
		nmsg_input_close(&nmsg_in);
	if (nmsg_out != NULL)
		nmsg_output_close(&nmsg_out);
	if (txn != NULL)
		mdb_txn_abort(txn);
	if (env != NULL)
		mdb_env_close(env);

	return (ec);
}