예제 #1
0
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);
}
예제 #2
0
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" );
	}
}
예제 #3
0
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;
	    }
	  }
	}
      }
예제 #4
0
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!");
  }
}