static struct ndpi_flow *get_ndpi_flow6(const struct ndpi_ip6_hdr *iph6, u_int16_t ip_offset, struct ndpi_id_struct **src, struct ndpi_id_struct **dst, u_int8_t *proto) { struct ndpi_iphdr iph; memset(&iph, 0, sizeof(iph)); iph.version = 4; iph.saddr = iph6->ip6_src.__u6_addr.__u6_addr32[2] + iph6->ip6_src.__u6_addr.__u6_addr32[3]; iph.daddr = iph6->ip6_dst.__u6_addr.__u6_addr32[2] + iph6->ip6_dst.__u6_addr.__u6_addr32[3]; iph.protocol = iph6->ip6_ctlun.ip6_un1.ip6_un1_nxt; return(get_ndpi_flow(6, &iph, ip_offset, sizeof(struct ndpi_ip6_hdr), ntohs(iph6->ip6_ctlun.ip6_un1.ip6_un1_plen), src, dst, proto)); }
static unsigned int packet_processing(const u_int64_t time, const struct ndpi_iphdr *iph, struct ndpi_ip6_hdr *iph6, u_int16_t ip_offset, u_int16_t ipsize, u_int16_t rawsize) { struct ndpi_id_struct *src, *dst; struct ndpi_flow *flow; struct ndpi_flow_struct *ndpi_flow = NULL; u_int32_t protocol = 0; u_int8_t proto; if(iph) flow = get_ndpi_flow(4, iph, ip_offset, ipsize, ntohs(iph->tot_len) - (iph->ihl * 4), &src, &dst, &proto); else flow = get_ndpi_flow6(iph6, ip_offset, &src, &dst, &proto); if(flow != NULL) { ndpi_flow = flow->ndpi_flow; flow->packets++, flow->bytes += rawsize; } else return(0); ip_packet_count++; total_bytes += rawsize + 24 /* CRC etc */; if(flow->detection_completed) return(0); protocol = (const u_int32_t)ndpi_detection_process_packet(ndpi_struct, ndpi_flow, iph ? (uint8_t *)iph : (uint8_t *)iph6, ipsize, time, src, dst); flow->detected_protocol = protocol; if((flow->detected_protocol != NDPI_PROTOCOL_UNKNOWN) || (proto == IPPROTO_UDP) || ((proto == IPPROTO_TCP) && (flow->packets > 10))) { flow->detection_completed = 1; #if 0 if(flow->ndpi_flow->l4.tcp.host_server_name[0] != '\0') printf("%s\n", flow->ndpi_flow->l4.tcp.host_server_name); #endif if(verbose > 1) { char buf1[32], buf2[32]; printf("%s %s:%u > %s:%u [proto: %u/%s][%s]\n", ipProto2Name(flow->protocol), intoaV4(ntohl(flow->lower_ip), buf1, sizeof(buf1)), ntohs(flow->lower_port), intoaV4(ntohl(flow->upper_ip), buf2, sizeof(buf2)), ntohs(flow->upper_port), protocol, ndpi_get_proto_name(ndpi_struct, protocol), flow->ndpi_flow->host_server_name); } snprintf(flow->host_server_name, sizeof(flow->host_server_name), "%s", flow->ndpi_flow->host_server_name); free_ndpi_flow(flow); } #if 0 if(ndpi_flow->l4.tcp.host_server_name[0] != '\0') printf("%s\n", ndpi_flow->l4.tcp.host_server_name); #endif return 0; }
int doingDetection() { int status; struct nlmsghdr *nlh; struct ndpi_ethher *ethernet; struct ndpi_iphdr *iph; ipq_packet_msg_t *ipq_packet; int ip_len; struct ndpi_id_struct *src, *dst; struct ndpi_flow *flow; struct ndpi_flow_struct *ndpi_flow = NULL; u_int32_t protocol = 0; u_int8_t proto; u_int64_t time; static u_int64_t lasttime=0; unsigned char payload[1024*1024]; while(1) { status = ipq_read(h, buf, sizeof(buf),0); if(status==0||status==-1)continue; memset(payload, 0x00, sizeof(payload)); if(status > sizeof(struct nlmsghdr)) { nlh = (struct nlmsghdr *)buf;//测试是否和ndpi_ethher一致。 ipq_packet = ipq_get_packet(buf); ip_len=ipq_packet->data_len; time = ((uint64_t) ipq_packet->timestamp_sec) * detection_tick_resolution +ipq_packet->timestamp_usec / (1000000 / detection_tick_resolution); memcpy(payload + ETH_HDRLEN, ipq_packet->payload, ip_len); // printf("2\n"); if(lasttime > time) { time = lasttime; } lasttime = time; iph = (struct ndpi_iphdr *)(&(ipq_packet->payload[0]));//需要测试是否和pcap来的一致 if(iph) { // printf("before get_ndpi_flow\n"); flow = get_ndpi_flow(iph, ip_len,&src, &dst, &proto); // printf("after get_ndpi_flow\n"); } if(flow != NULL) { ndpi_flow = flow->ndpi_flow; flow->packets++, flow->bytes += ip_len; } else continue; // printf("3\n"); ip_packet_count++; total_bytes+=ip_len+24; if(flow->detection_completed) { /*ipq_set_verdict(h, ipq_packet->packet_id, NF_ACCEPT,ipq_packet->data_len,payload + ETH_HDRLEN);*/ ipq_set_mark(h,ipq_packet->packet_id,1); continue; } protocol = (const u_int32_t)ndpi_detection_process_packet(ndpi_struct, ndpi_flow,(char *)iph,ip_len, time, src, dst); // printf("4\n"); if((flow->detected_protocol != NDPI_PROTOCOL_UNKNOWN) || ((proto == IPPROTO_UDP) && (flow->packets > 8)) || ((proto == IPPROTO_TCP) && (flow->packets > 10))) { if(flow->detected_protocol==NDPI_PROTOCOL_UNKNOWN) flow->detected_protocol = ndpi_guess_undetected_protocol(ndpi_struct, flow->protocol, ntohl(flow->lower_ip), ntohs(flow->lower_port), ntohl(flow->upper_ip), ntohs(flow->upper_port)); flow->detection_completed = 1; protocol_counter[flow->detected_protocol]+=flow->packets; protocol_flows[flow->detected_protocol]++; protocol_counter_bytes[flow->detected_protocol]+=flow->bytes; snprintf(flow->host_server_name, sizeof(flow->host_server_name), "%s", flow->ndpi_flow->host_server_name); } ipq_set_verdict(h, ipq_packet->packet_id, NF_ACCEPT,ipq_packet->data_len,payload + ETH_HDRLEN); snprintf(flow->host_server_name, sizeof(flow->host_server_name), "%s", flow->ndpi_flow->host_server_name); } } }
static unsigned int packet_processing(const u_int64_t time, const struct pcap_pkthdr *header, const struct ndpi_iphdr *iph, u_int16_t ipsize, u_int16_t rawsize) { struct ndpi_id_struct *src, *dst; struct ndpi_flow *flow; struct ndpi_flow_struct *ndpi_flow = NULL; u_int16_t protocol = 0; u_int16_t frag_off = ntohs(iph->frag_off); flow = get_ndpi_flow(header, iph, ipsize); if (flow != NULL) { ndpi_flow = flow->ndpi_flow; flow->packets++, flow->bytes += rawsize; src = flow->src_id, dst = flow->dst_id; } else return; ip_packet_count++; total_bytes += rawsize; if(flow->detection_completed) return; // only handle unfragmented packets if ((frag_off & 0x3FFF) == 0) { // here the actual detection is performed ndpi_protocol detected = ndpi_detection_process_packet(ndpi_struct, ndpi_flow, (uint8_t *) iph, ipsize, time, src, dst); protocol = detected.master_protocol; } else { static u_int8_t frag_warning_used = 0; if (frag_warning_used == 0) { printf("\n\nWARNING: fragmented ip packets are not supported and will be skipped \n\n"); frag_warning_used = 1; } return 0; } #if 0 if(verbose && (protocol == 0)) { char buf1[32], buf2[32]; printf("%s %s:%u > %s:%u [proto: %u/%s]\n", ipProto2Name(flow->protocol), intoaV4(ntohl(flow->lower_ip), buf1, sizeof(buf1)), ntohs(flow->lower_port), intoaV4(ntohl(flow->upper_ip), buf2, sizeof(buf2)), ntohs(flow->upper_port), protocol, ndpi_get_proto_name(ndpi_struct, protocol)); } #endif flow->detected_protocol = protocol; if((flow->detected_protocol != NDPI_PROTOCOL_UNKNOWN) || (iph->protocol == IPPROTO_UDP) || ((iph->protocol == IPPROTO_TCP) && (flow->packets > 10))) { flow->detection_completed = 1; #if 0 if(flow->ndpi_flow->l4.tcp.host_server_name[0] != '\0') printf("%s\n", flow->ndpi_flow->l4.tcp.host_server_name); #endif free_ndpi_flow(flow); } #if 0 if(ndpi_flow->l4.tcp.host_server_name[0] != '\0') printf("%s\n", ndpi_flow->l4.tcp.host_server_name); #endif return 0; }