예제 #1
0
void analyze(flow * flowrec) {

	if (flowrec->datapkts==pktlimit) {
		if (action==ACTION_LABEL) {
			if (!flowrec->isSSL) {
				flowrec->label=labeling(assign(flowrec->pkt_sizes,threshold),flowrec->dport);
			} else {
				flowrec->label=SSL_labeling(assign(flowrec->pkt_sizes,threshold),flowrec->dport);
			}
		} else {
			flowrec->label=LABEL_PARSED;
		}
		
		if (sslparsing && flowrec->label>0 && flowrec->label<=model.nbapplis && model.SSLapplis[flowrec->label-1]) {
		//If connection is SSL we continue the parsing
			flowrec->isSSL=1;
			flowrec->SSLdata=0;
			flowrec->datapkts=0;
			bzero(flowrec->pkt_sizes,pktlimit*sizeof(int16_t));
			flowrec->labelSSL=flowrec->label;
			flowrec->label=LABEL_NONE;
			return;
		}

		if (memory>=OPT_NOSTORE) {
			//If we want to minimize memory usage, we print information about the connection and remove it from the hashtable
			print_flow(flowrec);
			clear_hash_entry(flow_hash,flowrec);
		}
	}
}
예제 #2
0
static void dump_flows(flow * list) {
	flow * flowrec;
	for (flowrec = list; flowrec; flowrec = flowrec->next) {
		print_flow(flowrec);
		clear_hash_entry(flow_hash,flowrec);
	}
}
예제 #3
0
static void clean_flows(flow * list, uint32_t ts) {
	flow * flowrec;
	flow * savflow;
	int i=0;
	
	flowrec=list;
	while (flowrec && ts-flowrec->ts_latest>EXP_TIME) {
		i++;
		savflow=flowrec;
		print_flow(flowrec);
		clear_hash_entry(flow_hash,flowrec);
		flowrec=savflow->next;
	}
}
예제 #4
0
/*ARGSUSED*/
static int
show_flow(dladm_handle_t handle, dladm_flow_attr_t *attr, void *arg)
{
	show_flow_state_t	*statep = arg;
	dladm_status_t		status;
	flow_fields_buf_t	fbuf;

	/*
	 * first get all the flow attributes into fbuf;
	 */
	bzero(&fbuf, sizeof (fbuf));
	status = print_flow(statep, attr, &fbuf);

	if (status != DLADM_STATUS_OK)
		goto done;

	ofmt_print(statep->fs_ofmt, (void *)&fbuf);

done:
	statep->fs_status = status;
	return (DLADM_WALK_CONTINUE);
}
예제 #5
0
파일: pcap_parse.c 프로젝트: necoma/aguri2
static void
dump_reader(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
{
	/* clear aguri_flow to be filled in parsers */
	memset(&aguri_flow, 0, sizeof(aguri_flow));

	(*net_reader)(user, h, p);

	if (aguri_flow.agflow_fs.fs_ipver == 0)
		/* not a IP packet */
		return;

	aguri_flow.agflow_packets = htonl(1);
	aguri_flow.agflow_bytes = htonl(h->len);
	aguri_flow.agflow_first = aguri_flow.agflow_last = 
		htonl((u_int32_t)h->ts.tv_sec);
	
	if (debug == 0) {
		if (fwrite(&aguri_flow, sizeof(aguri_flow), 1, stdout) != 1)
			err(1, "fwrite failed!");
	} else
		print_flow(&aguri_flow);
}
예제 #6
0
static int
app_pipeline_fa_flow_ls(struct app_params *app,
		uint32_t pipeline_id)
{
	struct app_pipeline_fa *p;
	uint32_t i;

	/* Check input arguments */
	if (app == NULL)
		return -1;

	p = app_pipeline_data_fe(app, pipeline_id,
		&pipeline_flow_actions);
	if (p == NULL)
		return -1;

	for (i = 0; i < p->params.n_flows; i++) {
		struct app_pipeline_fa_flow *flow = &p->flows[i];

		print_flow(p, i, flow);
	}

	return 0;
}
예제 #7
0
int
parse_sflow5(const char **p)
{
	u_int32_t format, len;
	u_int32_t seqno, src_id, srate, total, drops, input, output, nrecords;
	u_int32_t record_type, record_len;
	u_int32_t protocol, framelen, stripped;
	int snaplen, i;

	format	= buffer_read_4(p) & 0xfff;
	len	= buffer_read_4(p);
	if (verbose > 1)
		fprintf(stderr, "sflow5: format:%u, len:%u\n",
				format, len);
	switch (format) {
	case 1: /* flow sample */
		seqno 	= buffer_read_4(p);
		src_id 	= buffer_read_4(p);
		srate 	= buffer_read_4(p);
		total 	= buffer_read_4(p);
		drops 	= buffer_read_4(p);
		input 	= buffer_read_4(p);
		output 	= buffer_read_4(p);
		nrecords	= buffer_read_4(p);

		sampling_rate = srate;

		if (verbose > 1)
			fprintf(stderr, "flow sample: srate:%u, nrecords:%u\n",
				srate, nrecords);

		for (i = 0; i < nrecords; i++) {
			record_type	= buffer_read_4(p);
			record_len	= buffer_read_4(p);

			/* clear aguri_flow to be filled in parsers */
			memset(&aguri_flow, 0, sizeof(aguri_flow));

			switch (record_type) {
			case 1: /* raw packet header */
				protocol = buffer_read_4(p);
				framelen = buffer_read_4(p);
				stripped = buffer_read_4(p);
				record_len -= 12;
				if (verbose > 1)
					fprintf(stderr, "record type: raw header: proto:%u, rlen:%u flen:%u, stripped:%u\n",
				    		protocol, record_len, framelen, stripped);
				switch (protocol) {
				case 1: /* ethernet */
					/* read the first 4 bytes for snaplen */
					snaplen = ntohl(*((u_int32_t *)*p));
					snapend = *p + 4 + snaplen;
					/* frame_length holds ethernet frame
					 * length; we remove 4 bytes of FCS to
					 * be consistent with pcap
					 */
					frame_length = framelen - 4;
					etherhdr_parse(*p + 4, snaplen);
					break;
				default:
					break;
				}
				buffer_skip(p, record_len);
				break;
			default:
				if (verbose > 1)
					fprintf(stderr, "record type:%u, len:%u\n",
				    		record_type, record_len);
				buffer_skip(p, record_len);
				break;
			} /* switch */

			if (aguri_flow.agflow_fs.fs_ipver != 0) {
				/* flow info was filled by the parser:
				 * for frame_length, we remove 4 bytes of FCS
				 * to be consistent with pcap
				 */
				aguri_flow.agflow_packets = htonl(1 * srate);
				aguri_flow.agflow_bytes = htonl((framelen - 4) * srate);
				aguri_flow.agflow_first = aguri_flow.agflow_last = htonl((u_int32_t)timestamp);

				if (debug == 0) {
					if (fwrite(&aguri_flow, sizeof(aguri_flow), 1, stdout) != 1)
						err(1, "fwrite failed!");
				} else
					print_flow(&aguri_flow);
			}

		}  /* nrecords in sample */
		break;
	case 2: /* counter sample */
		buffer_skip(p, len);
		break;
	case 3: /* expanded flow sample */
		buffer_skip(p, len);
		break;
	case 4: /* expanded counter sample */
		buffer_skip(p, len);
		break;
	default:
		buffer_skip(p, len);
		break;
	}

	return (0);
}
예제 #8
0
int
parse_sflow4_sample(const char **p)
{
	u_int32_t sample_type, packetdata_type;
	u_int32_t seqno, src_id, srate, total, drops, input, output;
	u_int32_t protocol, framelen, snaplen;
	u_int32_t interval, counters_version;
	u_int32_t nextended, extended_type, addr_type;
	u_int32_t aspath_len, asn_len, community_len, str_len;
	int i;

	sample_type	= buffer_read_4(p);
	if (verbose > 1)
		fprintf(stderr, "sflow4: sample_type:%u\n", sample_type);
	switch (sample_type) {
	case 1: /* flow sample */
		seqno 	= buffer_read_4(p);
		src_id 	= buffer_read_4(p);
		srate 	= buffer_read_4(p);
		total 	= buffer_read_4(p);
		drops 	= buffer_read_4(p);
		input 	= buffer_read_4(p);
		output 	= buffer_read_4(p);

		sampling_rate = srate;
		
		packetdata_type	= buffer_read_4(p);
		if (verbose > 1)
			fprintf(stderr, "flow_sample: packetdata_type:%u, srate:%u\n",
				packetdata_type, srate);

		switch (packetdata_type) {
		case 1: /* header */
			protocol = buffer_read_4(p);
			framelen = buffer_read_4(p);
			snaplen  = buffer_read_4(p);

			if (verbose > 0)
				fprintf(stderr, "header: framelen:%u, snaplen:%u, proto:%u\n",
			    		framelen, snaplen, protocol);

			/* clear aguri_flow to be filled in parsers */
			memset(&aguri_flow, 0, sizeof(aguri_flow));

			switch (protocol) {
			case 1: /* ethernet */
				snapend = *p + snaplen;
				etherhdr_parse(*p, snaplen);
				break;
			default:
				if (verbose > 0)
					fprintf(stderr, "unknown proto:%u\n",
			    			protocol);
				break;
			}

			buffer_skip(p, snaplen);

			if (aguri_flow.agflow_fs.fs_ipver != 0) {
				/* flow info was filled by the parser:
				 * for frame_length, we remove 4 bytes of FCS
				 * to be consistent with pcap
				 */
				aguri_flow.agflow_packets = htonl(1 * srate);
				aguri_flow.agflow_bytes = htonl((framelen - 4) * srate);
				aguri_flow.agflow_first = aguri_flow.agflow_last = htonl((u_int32_t)timestamp);

				if (debug == 0) {
					if (fwrite(&aguri_flow, sizeof(aguri_flow), 1, stdout) != 1)
						err(1, "fwrite failed!");
				} else
					print_flow(&aguri_flow);
			}
			
			break;
		case 2: /* IPv4 */
			buffer_skip(p, 8*4);
			if (verbose > 0)
				fprintf(stderr, "packetdata IPv4 not supported\n");
			break;
		case 3: /* IPv6 */
			buffer_skip(p, 14*4);
			if (verbose > 0)
				fprintf(stderr, "packetdata IPv6 not supported\n");
			break;
		default:
			if (verbose > 0)
				fprintf(stderr, "unknown packetdata_type:%u\n", packetdata_type);
			return (-1);
		}

		/* extended data */
		nextended = buffer_read_4(p);
		if (verbose > 0)
			fprintf(stderr, "extended data:%u\n", nextended);
		for (i = 0; i < nextended; i++) {
			extended_type = buffer_read_4(p);
			switch (extended_type) {
			case 1: /* switch */
				buffer_skip(p, 4*4);
				break;
			case 2: /* router */
				addr_type = buffer_read_4(p);
				switch (addr_type) {
				case 1: /* IPv4 */
					buffer_skip(p, 4);
					break;
				case 2: /* IPv6 */
					buffer_skip(p, 16);
					break;
				default:
					return (-1);
				}
				buffer_skip(p, 2*4);
				break;
			case 3: /* gateway */
				buffer_skip(p, 3*4);
				aspath_len = buffer_read_4(p);
				while (aspath_len-- > 0) {
					buffer_skip(p, 4);
					if (sflow_version >= 4) {
						asn_len = buffer_read_4(p);
						while (asn_len-- > 0)
							buffer_skip(p, 4);
					}
				}
				community_len = buffer_read_4(p);
				buffer_skip(p, community_len * 4);
				buffer_skip(p, 4);
				break;
			case 4: /* user */
				str_len = buffer_read_4(p);
				buffer_skip(p, str_len);
				str_len = buffer_read_4(p);
				buffer_skip(p, str_len);
				break;
			case 5: /* url */
				buffer_skip(p, 4);
				str_len = buffer_read_4(p);
				buffer_skip(p, str_len);
				break;
			default:
				return (-1);
			}
		}
		break;
	case 2: /* counter sample */
		seqno 	= buffer_read_4(p);
		src_id 	= buffer_read_4(p);
		interval = buffer_read_4(p);
		counters_version = buffer_read_4(p);
		if (verbose > 0)
			fprintf(stderr, "counter sample: type:%u\n", counters_version);
		switch (counters_version) {
		case 1: /* generic */
			buffer_skip(p, 22*4);
			break;
		case 2: /* ethernet */
			buffer_skip(p, 22*4);
			buffer_skip(p, 13*4);
			break;
		case 3: /* tokenring */
			buffer_skip(p, 22*4);
			buffer_skip(p, 18*4);
			break;
		case 4: /* fddi */
			buffer_skip(p, 22*4);
			break;
		case 5: /* 100basevg */
			buffer_skip(p, 22*4);
			buffer_skip(p, 20*4);
			break;
		case 6: /* wan */
			buffer_skip(p, 22*4);
			break;
		case 7: /* vlan */
			buffer_skip(p, 7*4);
			break;
		default:
			if (verbose > 0)
				fprintf(stderr, "counter sample %d not supported\n",
				    counters_version);
			return (-1);
		}
		break;
	default:
		if (verbose > 0)
			fprintf(stderr, "unknown sample_type %u\n", sample_type);
		return (-1);
	}
	
	return (0);
}
예제 #9
0
void count_flow (const struct ip * ip,uint16_t iplen,uint32_t tspkt) {
	flow tmp, tmp_peer;
	flow * flowrec=NULL;

	uint16_t hsize,psize,sslsize;
	uint32_t seq;
	struct tcphdr *t;
	int direction=0;

	t=(struct tcphdr *)(((uint8_t*)ip) + ip->ip_hl*4);


	hsize=ip->ip_hl*4+t->doff*4;
	psize=ntohs(ip->ip_len)-hsize;

	seq=ntohl(t->seq);


	if (psize>0) {
	//	If this packet is a data packet, we look for its connection in the hashtable
		/* Set the key to the source/destination address pair. */
		tmp.src.s_addr = ip->ip_src.s_addr;
		tmp.dst.s_addr = ip->ip_dst.s_addr;
		tmp.sport = ntohs (t->source);
		tmp.dport = ntohs (t->dest);

		// Peer
		tmp_peer.src.s_addr = tmp.dst.s_addr;
		tmp_peer.dst.s_addr = tmp.src.s_addr;
		tmp_peer.sport = tmp.dport;
		tmp_peer.dport = tmp.sport;

		direction=0;
		if (flowrec = (flow *) find_hash_entry (flow_hash, &tmp)) {
			direction=1;
		} else if (flowrec = (flow *) find_hash_entry (flow_hash, &tmp_peer)) {
			direction=2;
		}
		

		if (direction>0 && flowrec->label==LABEL_NONE) {
		//	Connection exists, is classifiable (SYN seen) and in sequence
			
			//First we reorder the list of connection (connections with most recent packets at the end of the list)
			if (flowrec->next) {
				//Else connection is already the last in the last so no modification
				//Connection cannot be the first we have a special empty pointer for the head of the list (first_flow)
				flowrec->prev->next=flowrec->next;
				flowrec->next->prev=flowrec->prev;
				active_flows->next=flowrec;
				flowrec->prev=active_flows;
				flowrec->next=NULL;
				active_flows=flowrec;
			}
			flowrec->ts_latest=tspkt;

			if (direction==1) {
				if (flowrec->data1==0) {
					//First packet with data
					flowrec->data1=1;
					flowrec->nextseq=seq+psize;
				} else if (flowrec->nextseq!=seq) {
					//Out of sequence packet, we remove the entry for this connection
					flowrec->label=LABEL_OUTOFSEQ;
					if (memory>=OPT_NOSTORE) {
						print_flow(flowrec);
						clear_hash_entry(flow_hash,flowrec);
						return ;
					}
				} else {
					flowrec->nextseq+=psize;
				}
			}
			if (direction==2) {
				if (flowrec->data2==0) {
					//First packet in reverse direction, initialize sequence number
					flowrec->data2=1;
					flowrec->nextseqpeer=seq+psize;
				} else if (flowrec->nextseqpeer!=seq) {
					flowrec->label=LABEL_OUTOFSEQ;
					if (memory>=OPT_NOSTORE) {
						print_flow(flowrec);
						clear_hash_entry(flow_hash,flowrec);
						return ;
					}
				} else {
					flowrec->nextseqpeer+=psize;
				}
			}
	
			if (!flowrec->isSSL) {
				assert(flowrec->datapkts<pktlimit);
				flowrec->pkt_sizes[flowrec->datapkts]=(direction==1) ? psize : -psize;
				flowrec->datapkts+=1;
				analyze(flowrec);
			}
			
			//If packet is SSL we parse it
			if (flowrec->isSSL) {
				sslsize=0;
				if (!flowrec->SSLdata) {
					sslsize=sslpayload(((uint8_t*)t)+t->doff*4,psize,iplen-hsize);
					if (sslsize>0) flowrec->SSLdata=1;
				} else sslsize=psize-5; 	//5: length of SSL header

				if (flowrec->SSLdata) {
					assert(flowrec->datapkts<pktlimit);
					flowrec->pkt_sizes[flowrec->datapkts]=(direction==1) ? clearsize(sslsize) : -clearsize(sslsize);
					flowrec->datapkts+=1;
					analyze(flowrec);
				}
			}
		}
		// Else: Connection is not classifiable: ignored
	} else if (t->syn==1 && t->ack==0) {
		// We are only intersted in SYN packets when there is no data

		flowrec = (flow *) malloc (sizeof (flow));
		if (flowrec == NULL) {
			fprintf (stderr, "Can't malloc new connection\n");
			abort ();
		}

		flowrec->pkt_sizes=(int16_t *)malloc(pktlimit*sizeof(int16_t));
		if (flowrec->pkt_sizes == NULL) {
			fprintf (stderr, "Can't malloc new connection\n");
			abort ();
		}
		flowrec->label=LABEL_NONE;

		bzero(flowrec->pkt_sizes,pktlimit*sizeof(int16_t));
		
		flowrec->src.s_addr=ip->ip_src.s_addr;
		flowrec->dst.s_addr=ip->ip_dst.s_addr;
		flowrec->sport=ntohs (t->source);
		flowrec->dport=ntohs (t->dest);

		flowrec->nextseq=0;
		flowrec->nextseqpeer=0;
		flowrec->data1=0;
		flowrec->data2=0;

		flowrec->isSSL=0;
		flowrec->SSLdata=0;

		flowrec->datapkts=0; 
		flowrec->ts_latest=tspkt;

		flowrec->prev = active_flows;
		flowrec->next = NULL;

		active_flows->next = flowrec;
      		active_flows = flowrec;

      		nbflows++;

      		add_hash_entry (flow_hash, flowrec);
	} else if (memory>=OPT_GARBAGE && (t->rst || t->fin)) {
	// We remove connections in which we see RST or FIN

		/* Set the key to the source/destination address pair. */
		tmp.src.s_addr = ip->ip_src.s_addr;
		tmp.dst.s_addr = ip->ip_dst.s_addr;
		tmp.sport = ntohs (t->source);
		tmp.dport = ntohs (t->dest);

		// Peer
		tmp_peer.src.s_addr = tmp.dst.s_addr;
		tmp_peer.dst.s_addr = tmp.src.s_addr;
		tmp_peer.sport = tmp.dport;
		tmp_peer.dport = tmp.sport;
		
		flowrec = (flow *) find_hash_entry (flow_hash, &tmp);
		if (!flowrec) flowrec = (flow *) find_hash_entry (flow_hash, &tmp_peer);
		if (flowrec) {
			print_flow(flowrec);
			clear_hash_entry(flow_hash,flowrec);
			return ;
		}
	}
	flowrec;
}