Пример #1
0
// #include <sys/prctl.h>
void start_netflow_collection(process_packet_pointer func_ptr) {
    logger << log4cpp::Priority::INFO << "netflow plugin started";

#ifdef ENABLE_LUA_HOOKS
    if (lua_hooks_enabled) {
        netflow_lua_state = init_lua_jit(lua_hooks_path);

        if (netflow_lua_state == NULL) {
            lua_hooks_enabled = false;
        }
    }
#endif

    // prctl(PR_SET_NAME,"fastnetmon_netflow", 0, 0, 0);

    netflow_process_func_ptr = func_ptr;
    // By default we listen on IPv4
    std::string netflow_host = "0.0.0.0";
    std::string netflow_ports = "";

    if (configuration_map.count("netflow_port") != 0) {
        netflow_ports = configuration_map["netflow_port"];
    }

    if (configuration_map.count("netflow_host") != 0) {
        netflow_host = configuration_map["netflow_host"];
    }

    if (configuration_map.count("netflow_sampling_ratio") != 0) {
        sampling_rate = convert_string_to_integer(configuration_map["netflow_sampling_ratio"]);

        logger << log4cpp::Priority::INFO << "Using custom sampling ratio for netflow: " << sampling_rate;
    }

    if (configuration_map.count("netflow_divide_counters_on_interval_length") != 0) {
        netflow_divide_counters_on_interval_length =
            configuration_map["netflow_divide_counters_on_interval_length"] == "on" ? true : false;
    }

#ifdef ENABLE_LUA_HOOKS
    if (configuration_map.count("netflow_lua_hooks_path") != 0) {
        lua_hooks_path = configuration_map["netflow_lua_hooks_path"];
        lua_hooks_enabled = true;
    }
#endif

    boost::thread_group netflow_collector_threads;
    
    std::vector<std::string> ports_for_listen;
    boost::split(ports_for_listen, netflow_ports, boost::is_any_of(","), boost::token_compress_on);

    logger << log4cpp::Priority::INFO << netflow_plugin_log_prefix << "We will listen on " << ports_for_listen.size() << " ports";

    for (std::vector<std::string>::iterator port = ports_for_listen.begin(); port != ports_for_listen.end(); ++port) {
        unsigned int netflow_port = convert_string_to_integer(*port);
        
        if (netflow_port == 0) {
            netflow_port = 2055;
        }

        netflow_collector_threads.add_thread( new boost::thread(start_netflow_collector,
            netflow_host,
            convert_string_to_integer(*port)
        ));
    }

    netflow_collector_threads.join_all(); 
}
Пример #2
0
// #include <sys/prctl.h>
void start_netflow_collection(process_packet_pointer func_ptr) {
    logger << log4cpp::Priority::INFO << "netflow plugin started";

#ifdef ENABLE_LUA_HOOKS
    init_lua_jit();
#endif

    // prctl(PR_SET_NAME,"fastnetmon_netflow", 0, 0, 0);

    netflow_process_func_ptr = func_ptr;

    // By default we listen on IPv4
    std::string netflow_host = "0.0.0.0";

    if (configuration_map.count("netflow_port") != 0) {
        netflow_port = convert_string_to_integer(configuration_map["netflow_port"]);
    }

    if (configuration_map.count("netflow_host") != 0) {
        netflow_host = configuration_map["netflow_host"];
    }

    if (configuration_map.count("netflow_sampling_ratio") != 0) {
        sampling_rate = convert_string_to_integer(configuration_map["netflow_sampling_ratio"]);

        logger << log4cpp::Priority::INFO << "We use custom sampling ratio for netflow: " << sampling_rate;
    }

    if (configuration_map.count("netflow_divide_counters_on_interval_length") != 0) {
        netflow_divide_counters_on_interval_length =
            configuration_map["netflow_divide_counters_on_interval_length"] == "on" ? true : false;
    }

#ifdef ENABLE_LUA_HOOKS
    if (configuration_map.count("netflow_lua_hooks_path") != 0) {
        lua_hooks_path = configuration_map["netflow_lua_hooks_path"];
    }
#endif

    logger << log4cpp::Priority::INFO << "netflow plugin will listen on " << netflow_host << ":"
           << netflow_port << " udp port";

    unsigned int udp_buffer_size = 65536;
    char udp_buffer[udp_buffer_size];

    struct addrinfo hints;
    memset(&hints, 0, sizeof hints);

    // Could be AF_INET6 or AF_INET
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_DGRAM;
    // This flag will generate wildcard IP address if we not specified certain IP address for
    // binding
    hints.ai_flags = AI_PASSIVE | AI_NUMERICHOST;

    struct addrinfo* servinfo = NULL;

    const char* address_for_binding = NULL;

    if (!netflow_host.empty()) {
        address_for_binding = netflow_host.c_str();
    }

    char port_as_string[16];
    sprintf(port_as_string, "%d", netflow_port);

    int getaddrinfo_result = getaddrinfo(address_for_binding, port_as_string, &hints, &servinfo);

    if (getaddrinfo_result != 0) {
        logger << log4cpp::Priority::ERROR << "Netflow getaddrinfo function failed with code: " << getaddrinfo_result
               << " please check netflow_host";
        exit(1);
    }

    int sockfd = socket(servinfo->ai_family, servinfo->ai_socktype, servinfo->ai_protocol);

    int bind_result = bind(sockfd, servinfo->ai_addr, servinfo->ai_addrlen);

    if (bind_result) {
        logger << log4cpp::Priority::ERROR << "Can't listen port: " << netflow_port << " on host "
               << netflow_host << " errno:" << errno << " error: " << strerror(errno);
        return;
    }

    struct sockaddr_in6 peer;
    memset(&peer, 0, sizeof(peer));

    /* We should specify timeout there for correct toolkit shutdown */
    /* Because otherwise recvfrom will stay in blocked mode forever */
    struct timeval tv;
    tv.tv_sec  = 5;  /* X Secs Timeout */
    tv.tv_usec = 0;  // Not init'ing this can cause strange errors

    setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(struct timeval));

    while (true) {
        // This approach provide ability to store both IPv4 and IPv6 client's addresses
        struct sockaddr_storage client_address;
        // It's MUST
        memset(&client_address, 0, sizeof(struct sockaddr_storage));
        socklen_t address_len = sizeof(struct sockaddr_storage);

        int received_bytes =
        recvfrom(sockfd, udp_buffer, udp_buffer_size, 0, (struct sockaddr*)&client_address, &address_len);

        if (received_bytes > 0) {
            // Pass host and port as numbers without any conversion
            int getnameinfo_flags = NI_NUMERICSERV | NI_NUMERICHOST;
            char host[NI_MAXHOST];
            char service[NI_MAXSERV];
            int result = getnameinfo((struct sockaddr*)&client_address, address_len, host,
                                     NI_MAXHOST, service, NI_MAXSERV, getnameinfo_flags);

            // We sill store client's IP address as string for allowing IPv4 and IPv6 processing in
            // same time
            std::string client_addres_in_string_format = std::string(host);
            // logger<< log4cpp::Priority::INFO<<"We receive packet from IP:
            // "<<client_addres_in_string_format;

            // printf("We receive %d\n", received_bytes);
            process_netflow_packet((u_int8_t*)udp_buffer, received_bytes, client_addres_in_string_format);
        } else {

            if (received_bytes == -1) {
                if (errno == EAGAIN) {
                    // We got timeout, it's OK!
                } else {
                    logger << log4cpp::Priority::ERROR << "netflow data receive failed";
                }
            }
        }

        // Add interruption point for correct application shutdown
        boost::this_thread::interruption_point();
    }

    freeaddrinfo(servinfo);
}