void error_per_packet(struct libtrace_packet_t *packet) { struct libtrace_ip *ip = trace_get_ip(packet); struct libtrace_tcp *tcp = trace_get_tcp(packet); void *link = trace_get_packet_buffer(packet,NULL,NULL); if (!link) { ++rx_errors; } /* This isn't quite as simple as it seems. * * If the packets were captured via wdcap's anonymisation module, * the checksum is set to 0 when it is correct and 1 if incorrect. * * If a different capture method is used, there's a good chance the * checksum has not been altered */ if (ip) { if (ntohs(ip->ip_sum)!=0) ++ip_errors; } if (tcp) { if (ntohs(tcp->check)!=0) ++tcp_errors; } }
void test(libtrace_packet_t** packets, int len) { int i = 0; while (i < len) { libtrace_tcp_t* tcp = trace_get_tcp(packets[i++]); uint32_t rem; void* data = trace_get_payload_from_tcp(tcp, &rem); } }
int main(int argc, char* argv[]) { if(argc != 2) { fprintf(stderr, "Missing *.pcap file path as argument"); exit(1); } char* filepath = argv[1]; setvbuf(stdout, NULL, _IOLBF, 0); printf("Starting...\n"); long int total_ns; struct timespec start_time; struct timespec end_time; int exit_code = 0; int i, psize = 0; libtrace_packet_t **packets = malloc(100 * sizeof(libtrace_packet_t*)); i = 0; char* trace_string = malloc(5 + strlen(filepath) + 1); strcpy(trace_string, "pcap:"); strcat(trace_string, filepath); libtrace_t* trace = trace_create(trace_string); iferr(trace); trace_start(trace); libtrace_packet_t* packet = trace_create_packet(); while ((psize = trace_read_packet(trace, packet)) > 0){ libtrace_tcp_t* tcp = trace_get_tcp(packet); if(tcp != NULL){ packets[i++] = packet; packet = trace_create_packet(); } } int len = i; for (i = 0; i < 1000; i++) { clock_gettime(CLOCK_MONOTONIC, &start_time); test(packets, len); clock_gettime(CLOCK_MONOTONIC, &end_time); total_ns += (end_time.tv_sec - start_time.tv_sec) * 1000000000 + (end_time.tv_nsec - start_time.tv_nsec); } int runs = i; for (i = 0; i < len; i++){ trace_destroy_packet(packets[i]); } free(packets); printf("Took %ld nanoseconds.\n", total_ns/runs); }
void per_packet(libtrace_packet_t *packet) { libtrace_tcp_t *tcp; /* Get the TCP header using trace_get_tcp() */ tcp = trace_get_tcp(packet); /* If the packet does not have a TCP header, skip it */ if (tcp == NULL) return; /* Check if either port in the TCP header is 80. Note that we * have to byteswap the port numbers because we are reading directly * out of the zero-copied packet */ if ((ntohs(tcp->source) == 80) || (ntohs(tcp->dest) == 80)) count += 1; }
void synopt_per_packet(struct libtrace_packet_t *packet) { struct libtrace_tcp *tcp = trace_get_tcp(packet); unsigned char *opt_ptr; libtrace_direction_t dir = trace_get_direction(packet); int len; unsigned char type, optlen, *data; struct tcp_opts opts_seen = {false, false, false, false, false, false}; if(!tcp) return; if (!tcp->syn) return; if (dir != TRACE_DIR_INCOMING && dir != TRACE_DIR_OUTGOING) dir = TRACE_DIR_OTHER; len = tcp->doff * 4 - sizeof(libtrace_tcp_t); if(len == 0) return; opt_ptr = (unsigned char *)tcp + sizeof (libtrace_tcp_t); while(trace_get_next_option(&opt_ptr,&len,&type,&optlen,&data)){ /* I don't think we need to count NO-OPs */ if (type == 1) continue; switch(type) { case 2: opts_seen.mss = true; break; case 3: opts_seen.winscale = true; break; case 4: opts_seen.sack = true; break; case 5: opts_seen.sack = true; break; case 8: opts_seen.ts = true; break; case 11: case 12: case 13: opts_seen.ttcp = true; break; default: opts_seen.other = true; } } if (tcp->ack) { total_synacks ++; classify_packet(opts_seen, &synack_counts); } else { total_syns ++; classify_packet(opts_seen, &syn_counts); } }
/* * Updates the RTT estimates given a new packet belonging to the flow. */ void rtt_handshake_update (void *data, struct libtrace_packet_t *packet) { struct rtt_handshake_record_t *record = (struct rtt_handshake_record_t *) data; struct libtrace_tcp *tcp; double time; int direction; // If a session has been established then skip all calculations. if (!record->established) { if ((tcp = trace_get_tcp (packet)) == NULL) return; time = trace_get_seconds (packet); direction = trace_get_direction (packet); // Check that the direction is ok if(!(direction==0 || direction==1)) return; // Check if the packet is a SYN, a SYN/ACK or an ACK if (tcp->syn) { if (tcp->ack) { // If the SYN/ACK is a retransmit, then we must not // update the rtt to the origin of the SYN/ACK but // only to the destination. if (direction == 0) { //outbound, so incoming syn if(record->rtt_in < 0.0) { // Do not update if rtt already set record->rtt_in += time; } record->rtt_out = -time; } else { if(record->rtt_out < 0.0) { record->rtt_out += time; } record->rtt_in = -time; } } else { if(direction == 0) { record->rtt_out = -time; } else { record->rtt_in = -time; } } } else if (tcp->ack) { // ack - syn_ack gives the time for the other direction if (direction == 0) { //outbound, so incoming syn_ack record->rtt_in += time; } else { record->rtt_out += time; } record->established = 1; } } }