void NetworkInterface::flow_processing(ZMQ_Flow *zflow) { bool src2dst_direction; Flow *flow; if((time_t)zflow->last_switched > (time_t)last_pkt_rcvd) last_pkt_rcvd = zflow->last_switched; /* Updating Flow */ flow = getFlow(zflow->src_mac, zflow->dst_mac, zflow->vlan_id, &zflow->src_ip, &zflow->dst_ip, zflow->src_port, zflow->dst_port, zflow->l4_proto, &src2dst_direction, zflow->first_switched, zflow->last_switched); if(flow == NULL) return; if(zflow->l4_proto == IPPROTO_TCP) flow->updateTcpFlags(zflow->tcp_flags); flow->addFlowStats(src2dst_direction, zflow->pkt_sampling_rate*zflow->in_pkts, zflow->pkt_sampling_rate*zflow->in_bytes, zflow->pkt_sampling_rate*zflow->out_pkts, zflow->pkt_sampling_rate*zflow->out_bytes, zflow->last_switched); flow->setDetectedProtocol(zflow->l7_proto); flow->setJSONInfo(json_object_to_json_string(zflow->additional_fields)); flow->updateActivities(); incStats(zflow->src_ip.isIPv4() ? ETHERTYPE_IP : ETHERTYPE_IPV6, flow->get_detected_protocol(), zflow->pkt_sampling_rate*(zflow->in_bytes + zflow->out_bytes), zflow->pkt_sampling_rate*(zflow->in_pkts + zflow->out_pkts), 24 /* 8 Preamble + 4 CRC + 12 IFG */ + 14 /* Ethernet header */); purgeIdle(zflow->last_switched); }
void Report::DoIncludes() { DoSectionTitle( "Includes", "includes" ); size_t numLibsOutput = 0; // build per-library stats const LibraryStats * const * end = m_LibraryStats.End(); for ( LibraryStats ** it = m_LibraryStats.Begin(); it != end; ++it ) { if ( ( *it )->objectCount_OutOfDate == 0 ) { continue; } // get all the includes for this library const Node * library = ( *it )->library; IncludeStatsMap incStatsMap; GetIncludeFilesRecurse( incStatsMap, library ); // flatten and sort by usage Array< const IncludeStats * > incStats( 10 * 1024, true ); incStatsMap.Flatten( incStats ); incStats.SortDeref(); Write( "<h3>%s</h3>\n", library->GetName().Get() ); numLibsOutput++; if ( incStats.GetSize() == 0 ) { Write( "No inludes.\n" ); continue; } DoTableStart(); Write( "<tr><th style=\"width:80px;\">Objects</th><th style=\"width:80px;\">Included</td><th style=\"width:60px;\">PCH</th><th>Name</th></tr>\n" ); const uint32_t numObjects = ( *it )->objectCount; // output const size_t numIncludes = incStats.GetSize(); size_t numOutput = 0; for ( size_t i=0; i<numIncludes; ++i ) { const IncludeStats & s = *incStats[ i ]; const char * fileName = s.node->GetName().Get(); const uint32_t included = s.count; const bool inPCH = s.inPCH; // start collapsable section if ( numOutput == 10 ) { DoToggleSection( numIncludes - 10 ); } Write( ( numOutput == 10 ) ? "<tr></tr><tr><td style=\"width:80px;\">%u</td><td style=\"width:80px;\">%u</td><td style=\"width:60px;\">%s</td><td>%s</td></tr>\n" : "<tr><td>%u</td><td>%u</td><td>%s</td><td>%s</td></tr>\n", numObjects, included, inPCH ? "YES" : "no", fileName ); numOutput++; } DoTableStop(); // end collpsable section if ( numOutput > 10 ) { Write( "</details>\n" ); } } DoTableStop(); if ( numLibsOutput == 0 ) { Write( "No libraries built.\n" ); } }
void NetworkInterface::packet_dissector(const struct pcap_pkthdr *h, const u_char *packet) { struct ndpi_ethhdr *ethernet, dummy_ethernet; struct ndpi_iphdr *iph; u_int64_t time; static u_int64_t lasttime = 0; u_int16_t eth_type, ip_offset, vlan_id = 0; u_int32_t res = ntop->getGlobals()->get_detection_tick_resolution(), null_type; int pcap_datalink_type = get_datalink(); setTimeLastPktRcvd(h->ts.tv_sec); time = ((uint64_t) h->ts.tv_sec) * res + h->ts.tv_usec / (1000000 / res); if(lasttime > time) time = lasttime; lasttime = time; if(pcap_datalink_type == DLT_NULL) { memcpy(&null_type, packet, sizeof(u_int32_t)); switch(null_type) { case BSD_AF_INET: eth_type = ETHERTYPE_IP; break; case BSD_AF_INET6_BSD: case BSD_AF_INET6_FREEBSD: case BSD_AF_INET6_DARWIN: eth_type = ETHERTYPE_IPV6; break; default: incStats(0, NDPI_PROTOCOL_UNKNOWN, h->len, 1, 24 /* 8 Preamble + 4 CRC + 12 IFG */); return; /* Any other non IP protocol */ } memset(&dummy_ethernet, 0, sizeof(dummy_ethernet)); ethernet = (struct ndpi_ethhdr *)&dummy_ethernet; ip_offset = 4; } else if(pcap_datalink_type == DLT_EN10MB) { ethernet = (struct ndpi_ethhdr *) packet; ip_offset = sizeof(struct ndpi_ethhdr); eth_type = ntohs(ethernet->h_proto); } else if(pcap_datalink_type == 113 /* Linux Cooked Capture */) { memset(&dummy_ethernet, 0, sizeof(dummy_ethernet)); ethernet = (struct ndpi_ethhdr *)&dummy_ethernet; eth_type = (packet[14] << 8) + packet[15]; ip_offset = 16; incStats(0, NDPI_PROTOCOL_UNKNOWN, h->len, 1, 24 /* 8 Preamble + 4 CRC + 12 IFG */); } else { incStats(0, NDPI_PROTOCOL_UNKNOWN, h->len, 1, 24 /* 8 Preamble + 4 CRC + 12 IFG */); return; } if(eth_type == 0x8100 /* VLAN */) { Ether80211q *qType = (Ether80211q*)&packet[ip_offset]; vlan_id = ntohs(qType->vlanId) & 0xFFF; eth_type = (packet[ip_offset+2] << 8) + packet[ip_offset+3]; ip_offset += 4; } // just work on Ethernet packets that contain IPv4 switch(eth_type) { case ETHERTYPE_IP: if(h->caplen >= ip_offset) { u_int16_t frag_off; iph = (struct ndpi_iphdr *) &packet[ip_offset]; if(iph->version != 4) { /* This is not IPv4 */ return; } else frag_off = ntohs(iph->frag_off); if(ntop->getGlobals()->decode_tunnels() && (iph->protocol == IPPROTO_UDP) && ((frag_off & 0x3FFF /* IP_MF | IP_OFFSET */ ) == 0)) { u_short ip_len = ((u_short)iph->ihl * 4); struct ndpi_udphdr *udp = (struct ndpi_udphdr *)&packet[ip_offset+ip_len]; u_int16_t sport = ntohs(udp->source), dport = ntohs(udp->dest); if((sport == GTP_U_V1_PORT) || (dport == GTP_U_V1_PORT)) { /* Check if it's GTPv1 */ u_int offset = (u_int)(ip_offset+ip_len+sizeof(struct ndpi_udphdr)); u_int8_t flags = packet[offset]; u_int8_t message_type = packet[offset+1]; if((((flags & 0xE0) >> 5) == 1 /* GTPv1 */) && (message_type == 0xFF /* T-PDU */)) { ip_offset = ip_offset+ip_len+sizeof(struct ndpi_udphdr)+8 /* GTPv1 header len */; if(flags & 0x04) ip_offset += 1; /* next_ext_header is present */ if(flags & 0x02) ip_offset += 4; /* sequence_number is present (it also includes next_ext_header and pdu_number) */ if(flags & 0x01) ip_offset += 1; /* pdu_number is present */ iph = (struct ndpi_iphdr *) &packet[ip_offset]; if(iph->version != 4) { /* FIX - Add IPv6 support */ return; } } } }
void NetworkInterface::packet_processing(const u_int32_t when, const u_int64_t time, struct ndpi_ethhdr *eth, u_int16_t vlan_id, struct ndpi_iphdr *iph, struct ndpi_ip6_hdr *ip6, u_int16_t ipsize, u_int16_t rawsize) { bool src2dst_direction; u_int8_t l4_proto; Flow *flow; u_int8_t *eth_src = eth->h_source, *eth_dst = eth->h_dest; IpAddress src_ip, dst_ip; u_int16_t src_port, dst_port; struct ndpi_tcphdr *tcph = NULL; struct ndpi_udphdr *udph = NULL; u_int16_t l4_packet_len; u_int8_t *l4, tcp_flags = 0; u_int8_t *ip; bool is_fragment = false; if(iph != NULL) { /* IPv4 */ if(ipsize < 20) { incStats(ETHERTYPE_IP, NDPI_PROTOCOL_UNKNOWN, rawsize, 1, 24 /* 8 Preamble + 4 CRC + 12 IFG */); return; } if((iph->ihl * 4) > ipsize || ipsize < ntohs(iph->tot_len) || (iph->frag_off & htons(0x1FFF /* IP_OFFSET */)) != 0) { is_fragment = true; } l4_packet_len = ntohs(iph->tot_len) - (iph->ihl * 4); l4_proto = iph->protocol; l4 = ((u_int8_t *) iph + iph->ihl * 4); ip = (u_int8_t*)iph; } else { /* IPv6 */ if(ipsize < sizeof(const struct ndpi_ip6_hdr)) { incStats(ETHERTYPE_IPV6, NDPI_PROTOCOL_UNKNOWN, rawsize, 1, 24 /* 8 Preamble + 4 CRC + 12 IFG */); return; } l4_packet_len = ntohs(ip6->ip6_ctlun.ip6_un1.ip6_un1_plen)-sizeof(const struct ndpi_ip6_hdr); l4_proto = ip6->ip6_ctlun.ip6_un1.ip6_un1_nxt; l4 = (u_int8_t*)ip6 + sizeof(const struct ndpi_ip6_hdr); ip = (u_int8_t*)ip6; } if((l4_proto == IPPROTO_TCP) && (l4_packet_len >= 20)) { /* tcp */ tcph = (struct ndpi_tcphdr *)l4; src_port = tcph->source, dst_port = tcph->dest; tcp_flags = l4[13]; } else if((l4_proto == IPPROTO_UDP) && (l4_packet_len >= 8)) { /* udp */ udph = (struct ndpi_udphdr *)l4; src_port = udph->source, dst_port = udph->dest; } else { /* non tcp/udp protocols */ src_port = dst_port = 0; } if(iph != NULL) { src_ip.set_ipv4(iph->saddr); dst_ip.set_ipv4(iph->daddr); } else { src_ip.set_ipv6(&ip6->ip6_src); dst_ip.set_ipv6(&ip6->ip6_dst); } #if defined(WIN32) && defined(DEMO_WIN32) if(this->ethStats.getNumPackets() > MAX_NUM_PACKETS) { static bool showMsg = false; if(!showMsg) { ntop->getTrace()->traceEvent(TRACE_NORMAL, "-----------------------------------------------------------"); ntop->getTrace()->traceEvent(TRACE_NORMAL, "WARNING: this demo application is a limited ntopng version able to"); ntop->getTrace()->traceEvent(TRACE_NORMAL, "capture up to %d packets. If you are interested", MAX_NUM_PACKETS); ntop->getTrace()->traceEvent(TRACE_NORMAL, "in the full version please have a look at the ntop"); ntop->getTrace()->traceEvent(TRACE_NORMAL, "home page http://www.ntop.org/."); ntop->getTrace()->traceEvent(TRACE_NORMAL, "-----------------------------------------------------------"); ntop->getTrace()->traceEvent(TRACE_NORMAL, ""); showMsg = true; } return; } #endif /* Updating Flow */ flow = getFlow(eth_src, eth_dst, vlan_id, &src_ip, &dst_ip, src_port, dst_port, l4_proto, &src2dst_direction, last_pkt_rcvd, last_pkt_rcvd); if(flow == NULL) { incStats(iph ? ETHERTYPE_IP : ETHERTYPE_IPV6, NDPI_PROTOCOL_UNKNOWN, rawsize, 1, 24 /* 8 Preamble + 4 CRC + 12 IFG */); return; } else { flow->incStats(src2dst_direction, rawsize); if(l4_proto == IPPROTO_TCP) flow->updateTcpFlags(tcp_flags); } /* Protocol Detection */ flow->updateActivities(); if(flow->isDetectionCompleted()) { /* Handle aggregations here */ switch(flow->get_detected_protocol()) { case NDPI_PROTOCOL_DNS: struct ndpi_flow_struct *ndpi_flow = flow->get_ndpi_flow(); struct ndpi_id_struct *cli = (struct ndpi_id_struct*)flow->get_cli_id(); struct ndpi_id_struct *srv = (struct ndpi_id_struct*)flow->get_srv_id(); if(ndpi_flow) { memset(&ndpi_flow->detected_protocol_stack, 0, sizeof(ndpi_flow->detected_protocol_stack)); ndpi_detection_process_packet(ndpi_struct, ndpi_flow, ip, ipsize, (u_int32_t)time, cli, srv); if(ndpi_flow->protos.dns.ret_code != 0) { /* This is a negative reply thus we notify the system that this aggregation must not be tracked */ flow->aggregateInfo((char*)ndpi_flow->host_server_name, l4_proto, NDPI_PROTOCOL_DNS, false); } } break; } flow->processDetectedProtocol(); flow->deleteFlowMemory(); incStats(iph ? ETHERTYPE_IP : ETHERTYPE_IPV6, flow->get_detected_protocol(), rawsize, 1, 24 /* 8 Preamble + 4 CRC + 12 IFG */); return; } else incStats(iph ? ETHERTYPE_IP : ETHERTYPE_IPV6, flow->get_detected_protocol(), rawsize, 1, 24 /* 8 Preamble + 4 CRC + 12 IFG */); if(!is_fragment) { struct ndpi_flow_struct *ndpi_flow = flow->get_ndpi_flow(); struct ndpi_id_struct *cli = (struct ndpi_id_struct*)flow->get_cli_id(); struct ndpi_id_struct *srv = (struct ndpi_id_struct*)flow->get_srv_id(); flow->setDetectedProtocol(ndpi_detection_process_packet(ndpi_struct, ndpi_flow, ip, ipsize, (u_int32_t)time, cli, srv)); } else { // FIX - only handle unfragmented packets // ntop->getTrace()->traceEvent(TRACE_WARNING, "IP fragments are not handled yet!"); } }