Example #1
0
int
receive_fd(int sock)
{
#if defined(HAVE_RECVMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR))
	struct msghdr msg;
	struct iovec vec;
	ssize_t n;
	char ch;
	int fd;
#ifndef HAVE_ACCRIGHTS_IN_MSGHDR
	char tmp[CMSG_SPACE(sizeof(int))];
	struct cmsghdr *cmsg;
#endif

	memset(&msg, 0, sizeof(msg));
	vec.iov_base = &ch;
	vec.iov_len = 1;
	msg.msg_iov = &vec;
	msg.msg_iovlen = 1;
#ifdef HAVE_ACCRIGHTS_IN_MSGHDR
	msg.msg_accrights = (caddr_t)&fd;
	msg.msg_accrightslen = sizeof(fd);
#else
	msg.msg_control = tmp;
	msg.msg_controllen = sizeof(tmp);
#endif

	if ((n = recvmsg(sock, &msg, 0)) == -1)
		logerr("%s: recvmsg", __func__);
	if (n != 1)
		logerrx("%s: recvmsg: expected received 1 got %ld", __func__,
		    (long)n);

#ifdef HAVE_ACCRIGHTS_IN_MSGHDR
	if (msg.msg_accrightslen != sizeof(fd))
		logerrx("%s: no fd", __func__);
#else
	cmsg = CMSG_FIRSTHDR(&msg);
	if (cmsg == NULL)
		logerrx("%s: no message header", __func__);
#ifndef BROKEN_CMSG_TYPE
	if (cmsg->cmsg_type != SCM_RIGHTS)
		logerrx("%s: expected type %d got %d", __func__,
		    SCM_RIGHTS, cmsg->cmsg_type);
#endif
	fd = (*(int *)CMSG_DATA(cmsg));
#endif
	return (fd);
#else
# error No supported FD passing primitives found
#endif
}
static int
start_socket(int monitor_fd)
{
	int fd;

	if ((fd = client_open_socket(monitor_fd)) == -1)
		logerrx("Logsock open failed, exiting");
	return (fd);
}
static int
start_log(int monitor_fd)
{
	int fd;
	off_t r;
	char ebuf[512];

	if ((fd = client_open_log(monitor_fd)) == -1)
		logerrx("Logfile open failed, exiting");

	/* Don't try to write a v.3 log on the end of a v.2 one */

	r = lseek(fd, 0, SEEK_END);

	/*
	 * If there isn't a full legacy header in the file or an error occurs
	 * (r == -1, e.g. on a FIFO) then don't bother checking for an old 
	 * log header.
	 */
	if (r < sizeof(struct store_v2_header))
		return (fd);

	if ((r = lseek(fd, 0, SEEK_SET)) == -1)
		logerr("%s: lseek", __func__);

	switch (store_v2_check_header(fd, ebuf, sizeof(ebuf))) {
	case STORE_ERR_OK:
		/* Uh oh - an old flow log is in the way, don't try to write */
		logerrx("Error: Cannot append to legacy (version 2) flow log, "
		    "please move it out of the way and restart flowd");
	case STORE_ERR_BAD_MAGIC:
	case STORE_ERR_UNSUP_VERSION:
		/* Good - the existing flow log is a probably a new one */
		if ((r = lseek(fd, 0, SEEK_END)) == -1)
			logerr("%s: lseek", __func__);
		return (fd);
	default:
		logerrx("%s: %s", __func__, ebuf);
	}

	/* NOTREACHED */
	return (-1);
}
/* Enqueue a flow for output, return 0 on success, -1 on queue full */
static int
output_flow_enqueue(u_int8_t *f, size_t len, int verbose)
{
	/* Force flush on overflow */
	if (output_queue_offset + len > OUTPUT_MAX_QLEN) {
		logit(LOG_DEBUG, "%s: output queue full", __func__);
		return (-1);
	}

	if (output_queue == NULL) {
		output_queue_alloc = OUTPUT_INITIAL_QLEN;
		if ((output_queue = malloc(output_queue_alloc)) == NULL) {
			logerrx("Output queue allocation (%u bytes) failed",
			    output_queue_alloc);
		}
		if (verbose) {
			logit(LOG_DEBUG, "%s: initial allocation %u", __func__,
			    output_queue_alloc);
		}
	}
	
	while (output_queue_offset + len > output_queue_alloc) {
		u_int8_t *tmp_q;
		size_t tmp_len = output_queue_alloc << 1;

		/* This should never happen if max = initial * 2^x */
		if (tmp_len > OUTPUT_MAX_QLEN) {
			logit(LOG_DEBUG, "%s: oops, tmp_len (%u) > "
			    "OUTPUT_MAX_QLEN (%u)", __func__, tmp_len,
			    OUTPUT_MAX_QLEN);
			return (-1);
		}
		if ((tmp_q = realloc(output_queue, tmp_len)) == NULL) {
			logit(LOG_DEBUG, "%s: realloc of %u fail", __func__,
			    tmp_len);
			return (-1);
		}
		if (verbose) {
			logit(LOG_DEBUG, "%s: increased output queue "
			    "from %uKB to %uKB", __func__,
			    output_queue_alloc >> 10, tmp_len >> 10);
		}
		output_queue = tmp_q;
		output_queue_alloc = tmp_len;
	}
	memcpy(output_queue + output_queue_offset, f, len);
	output_queue_offset += len;
	if (verbose) {
		logit(LOG_DEBUG, "%s: offset %u alloc %u", __func__,
		    output_queue_offset, output_queue_alloc);
	}
	
	return (0);
}
Example #5
0
int
send_fd(int sock, int fd)
{
#if defined(HAVE_SENDMSG) && (defined(HAVE_ACCRIGHTS_IN_MSGHDR) || defined(HAVE_CONTROL_IN_MSGHDR))
	struct msghdr msg;
	struct iovec vec;
	char ch = '\0';
	ssize_t n;
#ifndef HAVE_ACCRIGHTS_IN_MSGHDR
	char tmp[CMSG_SPACE(sizeof(int))];
	struct cmsghdr *cmsg;
#endif

	memset(&msg, 0, sizeof(msg));
#ifdef HAVE_ACCRIGHTS_IN_MSGHDR
	msg.msg_accrights = (caddr_t)&fd;
	msg.msg_accrightslen = sizeof(fd);
#else
	msg.msg_control = (caddr_t)tmp;
	msg.msg_controllen = CMSG_LEN(sizeof(int));
	cmsg = CMSG_FIRSTHDR(&msg);
	cmsg->cmsg_len = CMSG_LEN(sizeof(int));
	cmsg->cmsg_level = SOL_SOCKET;
	cmsg->cmsg_type = SCM_RIGHTS;
	*(int *)CMSG_DATA(cmsg) = fd;
#endif

	vec.iov_base = &ch;
	vec.iov_len = 1;
	msg.msg_iov = &vec;
	msg.msg_iovlen = 1;

	if ((n = sendmsg(sock, &msg, 0)) == -1)
		logerr("%s: sendmsg(%d)", __func__, fd);
	if (n != 1)
		logerrx("%s: sendmsg: expected sent 1 got %ld", __func__,
		    (long)n);

	return (0);
#else
# error No supported FD passing primitives found
#endif
}
static void
output_flow_flush(int log_fd, int verbose)
{
	char ebuf[512];

	if (log_fd == -1)
		return;

	if (verbose) {
		logit(LOG_DEBUG, "%s: flushing output queue len %u", __func__,
		    output_queue_offset);
	}

	if (output_queue_offset == 0)
		return;
	
	if (store_put_buf(log_fd, output_queue, output_queue_offset, ebuf,
	    sizeof(ebuf)) != STORE_ERR_OK)
		logerrx("%s: exiting on %s", __func__, ebuf);

	output_queue_offset = 0;
}
static void
process_flow(struct store_flow_complete *flow, struct flowd_config *conf,
    int log_fd, int log_socket)
{
	char ebuf[512], fbuf[1024];
	int flen;
	u_int filtres;

	/* Another sanity check */
	if (flow->src_addr.af != flow->dst_addr.af) {
		logit(LOG_WARNING, "%s: flow src(%d)/dst(%d) AF mismatch",
		    __func__, flow->src_addr.af, flow->dst_addr.af);
		return;
	}

	/* Prepare for writing */
	flow->hdr.fields = htonl(flow->hdr.fields);
	flow->recv_time.recv_sec = htonl(flow->recv_time.recv_sec);
	flow->recv_time.recv_usec = htonl(flow->recv_time.recv_usec);

	filtres = filter_flow(flow, &conf->filter_list);
	if (conf->opts & FLOWD_OPT_VERBOSE) {
		char fmtbuf[1024];
		u_int64_t pp = 0;
		struct flot_node fl;

		store_format_flow(flow, &fl, fmtbuf, sizeof(fmtbuf), 0,
		    STORE_DISPLAY_ALL, 0);
		logit(LOG_DEBUG, "%s: %s flow %s", __func__,
		    filtres == FF_ACTION_DISCARD ? "DISCARD" : "ACCEPT", fmtbuf);
///////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////	IMED
sem_wait (&semFlows);

Add_flow(&fl); 

//logit(LOG_WARNING, "Remplissage de||||||||  flot_flow_packets ######### %llu   ###################################", flot.flow_packets); 
//logit(LOG_WARNING, "Remplissage de||||||||  l'adresse source ######### %s   ########estimation_flow_list ########################", flot.src_addr);

/*logit(LOG_WARNING, "packets ###### %llu   ####### \n", estimation_flow_list->flow_packets);
logit(LOG_WARNING, "SRC_ADDR #### %s   #### \n", estimation_flow_list->src_addr);
logit(LOG_WARNING, "DST_ADDR #### %s   ##### \n", estimation_flow_list->dst_addr);
logit(LOG_WARNING, "GATEWAY ##### %s   ##### \n", estimation_flow_list->gateway_addr);
logit(LOG_WARNING, "SRC_PORT #### %d   ###### \n", estimation_flow_list->src_port);
logit(LOG_WARNING, "DST_PORT #### %d   ####### \n", estimation_flow_list->dst_port);
logit(LOG_WARNING, "OCKTETS ##### %llu   ###### \n", estimation_flow_list->flow_octets);*/


sem_post (&semFlows);
// sleep(1);
/////////////////////////////////////////////////////////////////////////////////////////////////////
	}

	if (filtres == FF_ACTION_DISCARD)
		return;

	if (store_flow_serialise_masked(flow, conf->store_mask, fbuf,
	    sizeof(fbuf), &flen, ebuf, sizeof(ebuf)) != STORE_ERR_OK)
		logerrx("%s: exiting on %s", __func__, ebuf);

	if (log_fd != -1 && output_flow_enqueue(fbuf, flen,
	    conf->opts & FLOWD_OPT_VERBOSE) == -1) {
		output_flow_flush(log_fd, conf->opts & FLOWD_OPT_VERBOSE);
		/* Must not fail after flush */
		if (output_flow_enqueue(fbuf, flen,
		    conf->opts & FLOWD_OPT_VERBOSE) == -1)
			logerrx("%s: enqueue failed after flush", __func__);
	}

	/* Track failures to send on log socket so we can reopen it */
	if (log_socket != -1 && send(log_socket, fbuf, flen, 0) == -1) {
		if (logsock_num_errors > 0 &&
		    (logsock_num_errors % 10) == 0) {
			logit(LOG_WARNING, "log socket send: %s "
			    "(num errors %d)", strerror(errno),
			    logsock_num_errors);
		}
		if (errno != ENOBUFS) {
			if (logsock_first_error == 0)
				logsock_first_error = time(NULL);
			logsock_num_errors++;
		}
	} else {
		/* Start to disregard errors after success */
		if (logsock_num_errors > 0)
			logsock_num_errors--;
		if (logsock_num_errors == 0)
			logsock_first_error = 0;
	}

	/* XXX reopen log file on one failure, exit on multiple */
}
Example #8
0
int
main(int argc, char **argv)
{
    int ch, i, fd, utc, r, verbose, debug, csv;
    extern char *optarg;
    extern int optind;
    struct store_flow_complete flow;
    struct store_v2_flow_complete flow_v2;
    char buf[2048], ebuf[512];
    const char *ffile, *ofile;
    FILE *ffilef;
    int ofd, read_legacy, head, nflows;
    u_int32_t disp_mask;
    struct flowd_config filter_config;
    struct store_v2_header hdr_v2;

    utc = verbose = debug = read_legacy = csv = 0;
    ofile = ffile = NULL;
    ofd = -1;
    ffilef = NULL;
    head = 0;

    bzero(&filter_config, sizeof(filter_config));

    while ((ch = getopt(argc, argv, "H:LUdf:ho:qvc")) != -1) {
        switch (ch) {
        case 'h':
            usage();
            return (0);
        case 'H':
            if ((head = atoi(optarg)) <= 0) {
                fprintf(stderr, "Invalid -H value.\n");
                usage();
                exit(1);
            }
            break;
        case 'L':
            read_legacy = 1;
            break;
        case 'U':
            utc = 1;
            break;
        case 'd':
            debug = 1;
            filter_config.opts |= FLOWD_OPT_VERBOSE;
            break;
        case 'f':
            ffile = optarg;
            break;
        case 'o':
            ofile = optarg;
            break;
        case 'q':
            verbose = -1;
            break;
        case 'v':
            verbose = 1;
            break;
        case 'c':
            csv = 1;
            break;
        default:
            usage();
            exit(1);
        }
    }
    loginit(PROGNAME, 1, debug);

    if (argc - optind < 1) {
        fprintf(stderr, "No logfile specified\n");
        usage();
        exit(1);
    }

    if (ffile != NULL) {
        if ((ffilef = fopen(ffile, "r")) == NULL)
            logerr("fopen(%s)", ffile);
        if (parse_config(ffile, ffilef, &filter_config, 1) != 0)
            exit(1);
        fclose(ffilef);
    }

    if (ofile != NULL) {
        if (strcmp(ofile, "-") == 0) {
            if (!debug)
                verbose = -1;
            ofile = NULL;
            if (isatty(STDOUT_FILENO))
                logerrx("Refusing to write binary flow data to "
                        "standard output.");
        }
        ofd = open_start_log(ofile, debug);
    }

    if (filter_config.store_mask == 0)
        filter_config.store_mask = STORE_FIELD_ALL;

    disp_mask = (verbose > 0) ? STORE_DISPLAY_ALL: STORE_DISPLAY_BRIEF;
    disp_mask &= filter_config.store_mask;

    for (i = optind; i < argc; i++) {
        if (strcmp(argv[i], "-") == 0)
            fd = STDIN_FILENO;
        else if ((fd = open(argv[i], O_RDONLY)) == -1)
            logerr("open(%s)", argv[i]);

        if (read_legacy && store_v2_get_header(fd, &hdr_v2, ebuf,
                                               sizeof(ebuf)) != STORE_ERR_OK)
            logerrx("%s", ebuf);

        if (verbose >= 1) {
            printf("LOGFILE %s", argv[i]);
            if (read_legacy)
                printf(" started at %s",
                       iso_time(ntohl(hdr_v2.start_time), utc));
            printf("\n");
            fflush(stdout);
        }

        if (csv == 1) {
            csv++;
            printf("#:unix_secs,unix_nsecs,sysuptime,exaddr,"
                   "dpkts,doctets,first,last,engine_type,engine_id,"
                   "srcaddr,dstaddr,nexthop,input,output,srcport,"
                   "dstport,prot,tos,tcp_flags,src_mask,dst_mask,"
                   "src_as,dst_as\n");
        }

        for (nflows = 0; head == 0 || nflows < head; nflows++) {
            bzero(&flow, sizeof(flow));

            if (read_legacy)
                r = store_v2_get_flow(fd, &flow_v2, ebuf,
                                      sizeof(ebuf));
            else
                r = store_get_flow(fd, &flow, ebuf,
                                   sizeof(ebuf));

            if (r == STORE_ERR_EOF)
                break;
            else if (r != STORE_ERR_OK)
                logerrx("%s", ebuf);

            if (read_legacy &&
                    store_v2_flow_convert(&flow_v2, &flow) == -1)
                logerrx("legacy flow conversion failed");

            if (ffile != NULL && filter_flow(&flow,
                                             &filter_config.filter_list) == FF_ACTION_DISCARD)
                continue;
            if (csv) {
                store_format_flow_flowtools_csv(&flow, buf,
                                                sizeof(buf), utc, disp_mask, 0);
                printf("%s\n", buf);
            }
            else if (verbose >= 0) {
                store_format_flow(&flow, buf, sizeof(buf),
                                  utc, disp_mask, 0);
                printf("%s\n", buf);
                fflush(stdout);
            }
            if (ofd != -1 && store_put_flow(ofd, &flow,
                                            filter_config.store_mask, ebuf,
                                            sizeof(ebuf)) == -1)
                logerrx("%s", ebuf);
        }
        if (fd != STDIN_FILENO)
            close(fd);
    }
    if (ofd != -1)
        close(ofd);

    if (ffile != NULL && debug)
        dump_config(&filter_config, "final", 1);

    return (0);
}