Ejemplo n.º 1
0
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, &ethertype, &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);
	}
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
/* 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, &ethertype, &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;

}
Ejemplo n.º 4
0
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, &ethertype, &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;
}
Ejemplo n.º 5
0
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,&ethertype,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;
}
Ejemplo n.º 6
0
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,&ethertype,&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,&ethertype,&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);
  }*/

}