Esempio n. 1
0
void firehose_packet(const char *pciaddr, char *data, int length) {
    // Garbadge collection code
    double current_timestamp = (double)rte_rdtsc() / system_tsc_resolution_hz;

    if (current_timestamp - last_timestamp > gc_call_timeout) {
        std::vector<conntrack_hash_struct_for_simple_packet_t> keys_to_remove; 
    
        for (auto& itr : my_connection_tracking_storage) {
            // Remove all records who older than X seconds
            if (current_timestamp - itr.second.last_timestamp > gc_clean_how_old_records) {
                keys_to_remove.push_back(itr.first);
            }   
        }   

        //if (!keys_to_remove.empty()) {
        //    std::cout << "We will remove " << keys_to_remove.size() << " keys" << std::endl; 
        //}  

        for (auto key_to_remove : keys_to_remove)  {
            my_connection_tracking_storage.erase(key_to_remove);
        }

        last_timestamp = current_timestamp;
    }  
    // GC code ends
    
    __sync_fetch_and_add(&received_packets, 1);
    __sync_fetch_and_add(&received_bytes, length);
 
    struct pfring_pkthdr packet_header;

    memset(&packet_header, 0, sizeof(packet_header));
    packet_header.len = length;
    packet_header.caplen = length;

    // We do not calculate timestamps because timestamping is very CPU intensive operation:
    // https://github.com/ntop/PF_RING/issues/9
    u_int8_t timestamp = 0;
    u_int8_t add_hash = 0;
    fastnetmon_parse_pkt((u_char*)data, &packet_header, 4, timestamp, add_hash);

    simple_packet current_packet;
    parse_raw_packet_to_simple_packet((u_char*)data, length, current_packet); 
    
    conntrack_hash_struct_for_simple_packet_t conntrack_structure;
    convert_simple_packet_toconntrack_hash_struct(current_packet, conntrack_structure);



    ndpi_tracking_flow_t& dpi_tracking_structure = my_connection_tracking_storage[ conntrack_structure ];

    // Protocol already detected
    /*
    if (dpi_tracking_structure.protocol_detected && dpi_tracking_structure.detected_protocol.protocol == NDPI_PROTOCOL_IRC) {
        char print_buffer[512];
        fastnetmon_print_parsed_pkt(print_buffer, 512, (u_char*)data, &packet_header);
        printf("packet: %s\n", print_buffer);

        for (unsigned int index = packet_header.extended_hdr.parsed_pkt.offset.payload_offset; index < packet_header.len; index++) {
            printf("%c", data[index]); 
        }   
    
        printf("\n");

        return;
    }
    */

    dpi_tracking_structure.update_timestamp();

    uint32_t current_tickt = 0 ;
    uint8_t* iph = (uint8_t*)(&data[packet_header.extended_hdr.parsed_pkt.offset.l3_offset]);

    // printf("vlan: %d\n", packet_header.extended_hdr.parsed_pkt.vlan_id);

    struct ndpi_iphdr* ndpi_ip_header = (struct ndpi_iphdr*)iph;

    unsigned int ipsize = packet_header.len; 
 
    ndpi_protocol detected_protocol = ndpi_detection_process_packet(my_ndpi_struct, dpi_tracking_structure.flow, iph, ipsize, current_tickt, dpi_tracking_structure.src, dpi_tracking_structure.dst);

    if (detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN && detected_protocol.master_protocol == NDPI_PROTOCOL_UNKNOWN) {
        // printf("Can't detect protocol\n");
    } else {
        dpi_tracking_structure.detected_protocol = detected_protocol;
        dpi_tracking_structure.protocol_detected = true;

        //printf("Master protocol: %d protocol: %d\n", detected_protocol.master_protocol, detected_protocol.protocol);
        char* protocol_name = ndpi_get_proto_name(my_ndpi_struct, detected_protocol.protocol);
        char* master_protocol_name = ndpi_get_proto_name(my_ndpi_struct, detected_protocol.master_protocol);        

        if (detected_protocol.protocol == NDPI_PROTOCOL_HTTP) {
            std::string host_name = std::string((const char*)dpi_tracking_structure.flow->host_server_name);

            //printf("server name: %s\n", dpi_tracking_structure.flow->host_server_name); 
           
            if (redis_context != NULL) { 
                known_http_hosts_t::iterator itr = known_http_hosts.find(host_name);

                if (itr == known_http_hosts.end()) {
                    // Not defined in internal cache
                    // Add in local cache:
                    known_http_hosts[ host_name ] = 1;
                
                    // Add to Redis
                    store_data_in_redis(host_name, "1");
                } else {
                    // Already stored
                }

            }
        }

        //printf("Protocol: %s master protocol: %s\n", protocol_name, master_protocol_name);

        bool its_bad_protocol = false;
        //if(ndpi_is_proto(detected_protocol, NDPI_PROTOCOL_TOR)) { 
        //    its_bad_protocol = true;
        //}
   
        if (detected_protocol.protocol == NDPI_PROTOCOL_IRC or detected_protocol.master_protocol == NDPI_PROTOCOL_IRC) { 
            its_bad_protocol = true;
        }

        if (its_bad_protocol) {
            printf("Bad protocol %s master protocol %s found\n", protocol_name, master_protocol_name);
            char print_buffer[512];
            fastnetmon_print_parsed_pkt(print_buffer, 512, (u_char*)data, &packet_header);
            printf("packet: %s\n", print_buffer);

            for (unsigned int index = packet_header.extended_hdr.parsed_pkt.offset.payload_offset; index < packet_header.len; index++) {
                printf("%c", data[index]); 
            }
            
            printf("\n");
        }
    }
}
Esempio n. 2
0
void pcap_parse_packet(char* buffer, uint32_t len) {
    struct pfring_pkthdr packet_header;

    memset(&packet_header, 0, sizeof(packet_header));
    packet_header.len = len;
    packet_header.caplen = len;

    // We do not calculate timestamps because timestamping is very CPU intensive operation:
    // https://github.com/ntop/PF_RING/issues/9
    u_int8_t timestamp = 0;
    u_int8_t add_hash = 0;
    fastnetmon_parse_pkt((u_char*)buffer, &packet_header, 4, timestamp, add_hash);

    struct ndpi_id_struct *src = NULL;
    struct ndpi_id_struct *dst = NULL;
    struct ndpi_flow_struct *flow = NULL;

    // So, we will init nDPI flow here
    if (flow == NULL) {
        src = (struct ndpi_id_struct*)malloc(size_id_struct);
        memset(src, 0, size_id_struct);

        dst = (struct ndpi_id_struct*)malloc(size_id_struct);
        memset(dst, 0, size_id_struct);

        flow = (struct ndpi_flow_struct *)malloc(size_flow_struct); 
        memset(flow, 0, size_flow_struct);

        /*

        struct ndpi_flow *newflow = (struct ndpi_flow*)malloc(sizeof(struct ndpi_flow)); 
        memset(newflow, 0, sizeof(struct ndpi_flow));

        newflow->protocol = packet_header.extended_hdr.parsed_pkt.l3_proto;
        newflow->vlan_id = packet_header.extended_hdr.parsed_pkt.vlan_id;

        uint32_t ip_src = packet_header.extended_hdr.parsed_pkt.ip_src.v4;
        uint32_t ip_dst = packet_header.extended_hdr.parsed_pkt.ip_dst.v4;

        uint16_t src_port = packet_header.extended_hdr.parsed_pkt.l4_src_port; 
        uint16_t dst_port = packet_header.extended_hdr.parsed_pkt.l4_dst_port;

        if (ip_src < ip_dst) {
            newflow->lower_ip = ip_src 
            newflow->upper_ip = ip_dst;

            newflow->lower_port = src_port; 
            newflow->upper_port = dst_port;
        } else {
            newflow->lower_ip = ip_dst;
            newflow->upper_ip = ip_src;

            newflow->lower_port = dst_port;
            newflow->upper_port = src_port;
        }

        newflow->src_id = malloc(size_id_struct);
        memset(newflow->src_id, 0, size_id_struct);

        newflow->dst_id = malloc(size_id_struct);
        memset(newflow->dst_id, 0, size_id_struct);
           
        *src = newflow->src_id, *dst = newflow->dst_id; 

        flow = newflow;

        */
    } else {
        //printf("We process only single packet\n");
        //exit(0);
        return;
    }

    uint32_t current_tickt = 0 ;
  
    uint8_t* iph = (uint8_t*)(&buffer[packet_header.extended_hdr.parsed_pkt.offset.l3_offset]);

    struct ndpi_iphdr* ndpi_ip_header = (struct ndpi_iphdr*)iph;

    unsigned int ipsize = packet_header.len; 
 
    ndpi_protocol detected_protocol = ndpi_detection_process_packet(my_ndpi_struct, flow, iph, ipsize, current_tickt, src, dst);

    if (detected_protocol.protocol == NDPI_PROTOCOL_UNKNOWN && 
        detected_protocol.master_protocol == NDPI_PROTOCOL_UNKNOWN) {
        printf("Can't detect protocol\n");
    } else {
        //printf("Master protocol: %d protocol: %d\n", detected_protocol.master_protocol, detected_protocol.protocol);
        char* protocol_name = ndpi_get_proto_name(my_ndpi_struct, detected_protocol.protocol);
        char* master_protocol_name = ndpi_get_proto_name(my_ndpi_struct, detected_protocol.master_protocol);        

        printf("Protocol: %s master protocol: %s\n", protocol_name, master_protocol_name);

        // It's DNS request or answer
        if (detected_protocol.protocol == NDPI_PROTOCOL_DNS) {
            
        }

        
        if (strstr(master_protocol_name, "Tor") == master_protocol_name or strstr(protocol_name, "IRC") != NULL)  {
            printf("Bad protocol %s master protocol %s found\n", protocol_name, master_protocol_name);
            char print_buffer[512];
            fastnetmon_print_parsed_pkt(print_buffer, 512, (u_char*)buffer, &packet_header);
            printf("packet: %s\n", print_buffer);
        }
       
    }

    // We need use custom function because standard free could not free all memory here
    ndpi_free_flow(flow);

    free(dst);
    free(src);

    flow = NULL;
    dst = NULL;
    src = NULL;
}