void pkt(struct lfc *lfc, void *mydata, struct lfc_flow *flow, void *flowdata, double ts, bool up, bool is_new, libtrace_packet_t *pkt) { struct flowdata *fd = flowdata; if (up) { if (fd->ups > 0) return; } else { if (fd->downs > 0) return; } /* * get the payload */ uint8_t proto; uint16_t ethertype; uint32_t rem; void *ptr; uint8_t *v; ptr = trace_get_layer3(pkt, ðertype, &rem); if (!ptr || ethertype != TRACE_ETHERTYPE_IP) return; ptr = trace_get_payload_from_ip(ptr, &proto, &rem); if (!ptr) return; if (proto == TRACE_IPPROTO_TCP) v = trace_get_payload_from_tcp(ptr, &rem); else if (proto == TRACE_IPPROTO_UDP) v = trace_get_payload_from_udp(ptr, &rem); else v = NULL; if (!v || rem == 0) return; /* * copy */ if (up) { fd->ups = MIN(LEN, rem); memcpy(fd->up, v, fd->ups); } else { fd->downs = MIN(LEN, rem); memcpy(fd->down, v, fd->downs); } }
void pkt(struct lfc *lfc, void *pdata, struct lfc_flow *lf, void *data, double ts, bool up, bool is_new, libtrace_packet_t *pkt) { struct ndpi *nd = pdata; struct flow *f = data; struct ipoque_id_struct *srcid, *dstid; uint8_t *iph; uint16_t et; uint32_t rem; uint64_t time; if (!f->ipq_flow) f->ipq_flow = mmatic_zalloc(nd->mm, ipoque_detection_get_sizeof_ipoque_flow_struct()); iph = trace_get_layer3(pkt, &et, &rem); time = ts * 1000; srcid = getid(nd, &lf->src); dstid = getid(nd, &lf->dst); f->proto = ipoque_detection_process_packet( nd->ipq, f->ipq_flow, iph, rem, time, srcid, dstid); }
/* Get the size of the payload as it was in the original packet, i.e. prior * to any truncation. * * Basically, wire length minus the packet headers. * * Currently only supports IP (v4 and v6) and TCP, UDP and ICMP. Will return * 0 if an unsupported protocol header is encountered, or if one of the * headers is truncated. */ DLLEXPORT size_t trace_get_payload_length(const libtrace_packet_t *packet) { void *layer; uint16_t ethertype; uint8_t proto; uint32_t rem; libtrace_ip_t *ip; libtrace_ip6_t *ip6; libtrace_tcp_t *tcp; size_t len = 0; /* Just use the cached length if we can */ if (packet->payload_length != -1) return packet->payload_length; /* Set to zero so that we can return early without having to * worry about forgetting to update the cached value */ ((libtrace_packet_t *)packet)->payload_length = 0; layer = trace_get_layer3(packet, ðertype, &rem); if (!layer) return 0; switch (ethertype) { case TRACE_ETHERTYPE_IP: ip = (libtrace_ip_t *)layer; if (rem < sizeof(libtrace_ip_t)) return 0; len = ntohs(ip->ip_len) - (4 * ip->ip_hl); /* Deal with v6 within v4 */ if (ip->ip_p == TRACE_IPPROTO_IPV6) len -= sizeof(libtrace_ip6_t); break; case TRACE_ETHERTYPE_IPV6: ip6 = (libtrace_ip6_t *)layer; if (rem < sizeof(libtrace_ip6_t)) return 0; len = ntohs(ip6->plen); break; default: return 0; } layer = trace_get_transport(packet, &proto, &rem); if (!layer) return 0; switch(proto) { case TRACE_IPPROTO_TCP: if (rem < sizeof(libtrace_tcp_t)) return 0; tcp = (libtrace_tcp_t *)layer; if (len < (size_t)(4 * tcp->doff)) return 0; len -= (4 * tcp->doff); break; case TRACE_IPPROTO_UDP: if (rem < sizeof(libtrace_udp_t)) return 0; if (len < sizeof(libtrace_udp_t)) return 0; len -= sizeof(libtrace_udp_t); break; case TRACE_IPPROTO_ICMP: if (rem < sizeof(libtrace_icmp_t)) return 0; if (len < sizeof(libtrace_icmp_t)) return 0; len -= sizeof(libtrace_icmp_t); break; case TRACE_IPPROTO_ICMPV6: if (rem < sizeof(libtrace_icmp6_t)) return 0; if (len < sizeof(libtrace_icmp6_t)) return 0; len -= sizeof(libtrace_icmp6_t); break; default: return 0; } ((libtrace_packet_t *)packet)->payload_length = len; return len; }
DLLEXPORT uint16_t *trace_checksum_transport(libtrace_packet_t *packet, uint16_t *csum) { void *header = NULL; uint16_t ethertype; uint32_t remaining; uint32_t sum = 0; uint8_t proto = 0; uint16_t *csum_ptr = NULL; int plen = 0; uint8_t safety[65536]; uint8_t *ptr = safety; header = trace_get_layer3(packet, ðertype, &remaining); if (header == NULL) return NULL; if (ethertype == TRACE_ETHERTYPE_IP) { libtrace_ip_t *ip = (libtrace_ip_t *)header; if (remaining < sizeof(libtrace_ip_t)) return NULL; sum = ipv4_pseudo_checksum(ip); } else if (ethertype == TRACE_ETHERTYPE_IPV6) { libtrace_ip6_t *ip = (libtrace_ip6_t *)header; if (remaining < sizeof(libtrace_ip6_t)) return 0; sum = ipv6_pseudo_checksum(ip); } header = trace_get_transport(packet, &proto, &remaining); if (proto == TRACE_IPPROTO_TCP) { libtrace_tcp_t *tcp = (libtrace_tcp_t *)header; header = trace_get_payload_from_tcp(tcp, &remaining); csum_ptr = &tcp->check; memcpy(ptr, tcp, tcp->doff * 4); tcp = (libtrace_tcp_t *)ptr; tcp->check = 0; ptr += (tcp->doff * 4); } else if (proto == TRACE_IPPROTO_UDP) { libtrace_udp_t *udp = (libtrace_udp_t *)header; header = trace_get_payload_from_udp(udp, &remaining); csum_ptr = &udp->check; memcpy(ptr, udp, sizeof(libtrace_udp_t)); udp = (libtrace_udp_t *)ptr; udp->check = 0; ptr += sizeof(libtrace_udp_t); } else if (proto == TRACE_IPPROTO_ICMP) { /* ICMP doesn't use the pseudo header */ sum = 0; libtrace_icmp_t *icmp = (libtrace_icmp_t *)header; header = trace_get_payload_from_icmp(icmp, &remaining); csum_ptr = &icmp->checksum; memcpy(ptr, icmp, sizeof(libtrace_icmp_t)); icmp = (libtrace_icmp_t *)ptr; icmp->checksum = 0; ptr += sizeof(libtrace_icmp_t); } else { return NULL; } sum += add_checksum(safety, (uint16_t)(ptr - safety)); plen = trace_get_payload_length(packet); if (plen < 0) return NULL; if (remaining < (uint32_t)plen) return NULL; if (header == NULL) return NULL; sum += add_checksum(header, (uint16_t)plen); *csum = ntohs(finish_checksum(sum)); //assert(0); return csum_ptr; }
DLLEXPORT void *trace_get_transport(const libtrace_packet_t *packet, uint8_t *proto, uint32_t *remaining ) { uint8_t dummy_proto; uint16_t ethertype; uint32_t dummy_remaining; void *transport; if (!proto) proto=&dummy_proto; if (!remaining) remaining=&dummy_remaining; if (packet->l4_header) { /* void *link; libtrace_linktype_t linktype; link = trace_get_packet_buffer(packet, &linktype, remaining); if (!link) return NULL; */ *proto = packet->transport_proto; /* *remaining -= (packet->l4_header - link); */ *remaining = packet->l4_remaining; return packet->l4_header; } transport = trace_get_layer3(packet,ðertype,remaining); if (!transport || *remaining == 0) return NULL; switch (ethertype) { case TRACE_ETHERTYPE_IP: /* IPv4 */ transport=trace_get_payload_from_ip( (libtrace_ip_t*)transport, proto, remaining); /* IPv6 */ if (transport && *proto == TRACE_IPPROTO_IPV6) { transport=trace_get_payload_from_ip6( (libtrace_ip6_t*)transport, proto,remaining); } break; case TRACE_ETHERTYPE_IPV6: /* IPv6 */ transport = trace_get_payload_from_ip6( (libtrace_ip6_t*)transport, proto, remaining); break; default: *proto = 0; transport = NULL; break; } ((libtrace_packet_t *)packet)->transport_proto = *proto; ((libtrace_packet_t *)packet)->l4_header = transport; ((libtrace_packet_t *)packet)->l4_remaining = *remaining; return transport; }
static void per_packet(libtrace_packet_t *packet) { /* Packet data */ uint32_t remaining; /* L3 data */ void *l3; uint16_t ethertype; /* Transport data */ void *transport; uint8_t proto; /* Payload data */ void *payload; if (lastts < 1) lastts = trace_get_seconds(packet); if (lastts+1.0 < trace_get_seconds(packet)) { ++lastts; printf("%.03f,",lastts); printf("%"PRIu64",%"PRIu64",",v4,v6); printf("%"PRIu64",%"PRIu64",%"PRIu64,icmp,tcp,udp); printf("\n"); v4=v6=0; icmp=tcp=udp=0; } l3 = trace_get_layer3(packet,ðertype,&remaining); if (!l3) /* Probable ARP or something */ return; /* Get the UDP/TCP/ICMP header from the IPv4/IPv6 packet */ switch (ethertype) { case 0x0800: transport = trace_get_payload_from_ip( (libtrace_ip_t*)l3, &proto, &remaining); if (!transport) return; ++v4; break; case 0x86DD: transport = trace_get_payload_from_ip6( (libtrace_ip6_t*)l3, &proto, &remaining); if (!transport) return; ++v6; break; default: return; } /* Parse the udp/tcp/icmp payload */ switch(proto) { case 1: ++icmp; return; case 6: payload = trace_get_payload_from_tcp( (libtrace_tcp_t*)transport, &remaining); if (!payload) return; ++tcp; break; case 17: payload = trace_get_payload_from_udp( (libtrace_udp_t*)transport, &remaining); if (!payload) return; ++udp; break; default: return; } ++ok; }
static int per_packet(libtrace_packet_t * pkt, FILE * fp_write, struct time_adjust_record * time_adjust_flow) { // Create a new packet which is a copy of the old packet. //libtrace_packet_t *copy_pkt = trace_copy_packet(pkt); libtrace_ip_t *ip = trace_get_ip(pkt); libtrace_ip6_t *ip6 = trace_get_ip6(pkt); struct sockaddr_storage src_addr; struct sockaddr_storage dest_addr; struct sockaddr *src_addr_ptr; struct sockaddr *dest_addr_ptr; /* L3 data */ void *l3; uint16_t ethertype; /* Transport data */ void *transport; uint8_t proto; /* Payload data */ uint32_t remaining; struct timeval ts; //printf("In per_packet line:%d\n", __LINE__); l3 = trace_get_layer3(pkt,ðertype,&remaining); if (!l3) { /* Probable ARP or something */ return; } /* Get the UDP/TCP/ICMP header from the IPv4/IPv6 packet */ /*switch (ethertype) { case 0x0800: transport = trace_get_payload_from_ip( (libtrace_ip_t*)l3, &proto, &remaining); if (!transport) return; //++v4; break; case 0x86DD: transport = trace_get_payload_from_ip6( (libtrace_ip6_t*)l3, &proto, &remaining); if (!transport) return; //++v6; break; default: return; }*/ // Get packet information //get port numbers int src_port = trace_get_source_port(pkt); int dest_port = trace_get_destination_port(pkt); src_addr_ptr = trace_get_source_address(pkt, (struct sockaddr *) &src_addr); dest_addr_ptr = trace_get_destination_address(pkt, (struct sockaddr *) &dest_addr); if( (NULL == src_addr_ptr) || (NULL == dest_addr_ptr) ) { //printf("In per_packet line:%d\n", __LINE__); return; } //get source ip address char src_ip[100]; if (src_addr_ptr->sa_family == AF_INET) { struct sockaddr_in *src_v4 = (struct sockaddr_in *) src_addr_ptr; inet_ntop(AF_INET, &(src_v4->sin_addr), src_ip, 100); } //get destination ip address char dest_ip[100]; if (dest_addr_ptr->sa_family == AF_INET) { struct sockaddr_in *dest_v4 = (struct sockaddr_in *) dest_addr_ptr; inet_ntop(AF_INET, &(dest_v4->sin_addr), dest_ip, 100); } ts = trace_get_timeval(pkt); struct timeval ts_adjust; ts_adjust.tv_sec = 0; ts_adjust.tv_usec = 0; //printf("1 %s %d %s %d\n", time_adjust_flow->src_ip, time_adjust_flow->src_port, time_adjust_flow->dest_ip, time_adjust_flow->dest_port); //printf("2 %s %d %s %d\n", src_ip, src_port, dest_ip, dest_port); if( (src_port == time_adjust_flow->src_port) && (strcmp(src_ip, time_adjust_flow->src_ip) == 0) && (dest_port == time_adjust_flow->dest_port) && (strcmp(dest_ip, time_adjust_flow->dest_ip) == 0) ) { //printf("CASE1: in per_packet line:%d\n", __LINE__); if(time_adjust_flow->last_direction == -1) { time_adjust_flow->last_direction = 0; ts_adjust.tv_sec = time_adjust_flow->first_pkt_sec; ts_adjust.tv_usec = time_adjust_flow->first_pkt_usec; } else if(time_adjust_flow->last_direction == 0) //update rtt { //add client inter arrival time if(time_adjust_flow->client_inter_usec + time_adjust_flow->last_tv_usec >= 1000000) { ts_adjust.tv_usec = time_adjust_flow->client_inter_usec + time_adjust_flow->last_tv_usec - 1000000; ts_adjust.tv_sec = time_adjust_flow->client_inter_sec + time_adjust_flow->last_tv_sec + 1; } else { ts_adjust.tv_sec = time_adjust_flow->client_inter_sec + time_adjust_flow->last_tv_sec; ts_adjust.tv_usec = time_adjust_flow->client_inter_usec + time_adjust_flow->last_tv_usec; } } else if(time_adjust_flow->last_direction == 1) { //add reaction time if(time_adjust_flow->reaction_usec + time_adjust_flow->last_tv_usec >= 1000000) { ts_adjust.tv_usec = time_adjust_flow->reaction_usec + time_adjust_flow->last_tv_usec - 1000000; ts_adjust.tv_sec = time_adjust_flow->reaction_sec + time_adjust_flow->last_tv_sec + 1; } else { ts_adjust.tv_usec = time_adjust_flow->reaction_usec + time_adjust_flow->last_tv_usec; ts_adjust.tv_sec = time_adjust_flow->reaction_sec + time_adjust_flow->last_tv_sec; } time_adjust_flow->last_direction = 0; } time_adjust_flow->last_tv_sec = ts_adjust.tv_sec; time_adjust_flow->last_tv_usec = ts_adjust.tv_usec; fprintf(fp_write, "%d, %d\n", time_adjust_flow->last_tv_sec, time_adjust_flow->last_tv_usec); //printf("%d, %d\n", time_adjust_flow->last_tv_sec, time_adjust_flow->last_tv_usec); } if( (src_port == time_adjust_flow->dest_port) && (strcmp(src_ip, time_adjust_flow->dest_ip) == 0) && (dest_port == time_adjust_flow->src_port) && (strcmp(dest_ip, time_adjust_flow->src_ip) == 0) ) { //printf("CASE2 in per_packet line:%d\n", __LINE__); if(time_adjust_flow->last_direction == -1) { time_adjust_flow->last_direction = 1; ts_adjust.tv_sec = time_adjust_flow->first_pkt_sec; ts_adjust.tv_usec = time_adjust_flow->first_pkt_usec; } else if(time_adjust_flow->last_direction == 1) //update rtt { //add server inter arrival time if(time_adjust_flow->server_inter_usec + time_adjust_flow->last_tv_usec >= 1000000) { ts_adjust.tv_usec = time_adjust_flow->server_inter_usec + time_adjust_flow->last_tv_usec - 1000000; ts_adjust.tv_sec = time_adjust_flow->server_inter_sec + time_adjust_flow->last_tv_sec + 1; } else { ts_adjust.tv_usec = time_adjust_flow->server_inter_usec + time_adjust_flow->last_tv_usec; ts_adjust.tv_sec = time_adjust_flow->server_inter_sec + time_adjust_flow->last_tv_sec; } //printf("Pkt: %d, last_tv_sec: %d last_tv_usec: %d, ts.tv_sec: %u, ts.tv_usec: %u, rtt_avg_direct0: %f\n", flow_stats.pkt_count, flow_stats.last_tv_sec, flow_stats.last_tv_usec, ts.tv_sec, ts.tv_usec, flow_stats.rtt_avg_direct1); } else if(time_adjust_flow->last_direction == 0) { // add client RTT if(time_adjust_flow->rtt_usec + time_adjust_flow->last_tv_usec >= 1000000) { ts_adjust.tv_usec = time_adjust_flow->rtt_usec + time_adjust_flow->last_tv_usec - 1000000; ts_adjust.tv_sec = time_adjust_flow->rtt_sec + time_adjust_flow->last_tv_sec + 1; } else { ts_adjust.tv_sec = time_adjust_flow->rtt_sec + time_adjust_flow->last_tv_sec; ts_adjust.tv_usec = time_adjust_flow->rtt_usec + time_adjust_flow->last_tv_usec; } time_adjust_flow->last_direction = 1; } time_adjust_flow->last_tv_sec = ts_adjust.tv_sec; time_adjust_flow->last_tv_usec = ts_adjust.tv_usec; fprintf(fp_write, "%d, %d\n", time_adjust_flow->last_tv_sec, time_adjust_flow->last_tv_usec); //printf("%d, %d\n", time_adjust_flow->last_tv_sec, time_adjust_flow->last_tv_usec); } //trace_destroy_packet(copy_pkt); return 0; /*if ( (strcmp(src_ip, "")) || (strcmp(dest_ip, "")) ) { sprintf(OutputBuffer, "sec: %u, usec: %u, src_ip: %s, src_port: %d, dest_ip: %s, dest_port: %d, pkt_size: %d, remaining: %d", ts.tv_sec, ts.tv_usec, src_ip, src_port, dest_ip, dest_port, pkt_size, remaining); }*/ }