// Copy and paste from netmap module inline bool parse_raw_packet_to_simple_packet(u_char* buffer, int len, simple_packet& packet) { 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); // char print_buffer[512]; // fastnetmon_print_parsed_pkt(print_buffer, 512, (u_char*)buffer, &packet_header); // logger.info("%s", print_buffer); if (packet_header.extended_hdr.parsed_pkt.ip_version != 4 && packet_header.extended_hdr.parsed_pkt.ip_version != 6) { return false; } // We need this for deep packet inspection packet.packet_payload_length = len; packet.packet_payload_pointer = (void*)buffer; packet.ip_protocol_version = packet_header.extended_hdr.parsed_pkt.ip_version; if (packet.ip_protocol_version == 4) { // IPv4 /* PF_RING stores data in host byte order but we use network byte order */ packet.src_ip = htonl(packet_header.extended_hdr.parsed_pkt.ip_src.v4); packet.dst_ip = htonl(packet_header.extended_hdr.parsed_pkt.ip_dst.v4); } else { // IPv6 memcpy(packet.src_ipv6.s6_addr, packet_header.extended_hdr.parsed_pkt.ip_src.v6.s6_addr, 16); memcpy(packet.dst_ipv6.s6_addr, packet_header.extended_hdr.parsed_pkt.ip_dst.v6.s6_addr, 16); } packet.source_port = packet_header.extended_hdr.parsed_pkt.l4_src_port; packet.destination_port = packet_header.extended_hdr.parsed_pkt.l4_dst_port; packet.length = packet_header.len; packet.protocol = packet_header.extended_hdr.parsed_pkt.l3_proto; packet.ts = packet_header.ts; packet.ip_fragmented = packet_header.extended_hdr.parsed_pkt.ip_fragmented; packet.ttl = packet_header.extended_hdr.parsed_pkt.ip_ttl; // Copy flags from PF_RING header to our pseudo header if (packet.protocol == IPPROTO_TCP) { packet.flags = packet_header.extended_hdr.parsed_pkt.tcp.flags; } else { packet.flags = 0; } return true; }
void consume_pkt(u_char* buffer, int len) { //static char packet_data[2000]; //printf("Got packet with length: %d\n", len); //memcpy(packet_data, buffer, len); struct pfring_pkthdr l2tp_header; memset(&l2tp_header, 0, sizeof(l2tp_header)); l2tp_header.len = len; l2tp_header.caplen = len; fastnetmon_parse_pkt((u_char*)buffer, &l2tp_header, 4, 1, 0); //char print_buffer[512]; //fastnetmon_print_parsed_pkt(print_buffer, 512, (u_char*)buffer, &l2tp_header); //printf("%s\n", print_buffer); __sync_fetch_and_add(&number_of_packets, 1); }
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"); } } }
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; }