void per_packet(libtrace_packet_t *packet) { struct timeval ts; /* Get the timestamp for the current packet */ ts = trace_get_timeval(packet); /* If next_report is zero, then this is the first packet from the * trace so we need to determine the time at which the first report * must occur, i.e. 10 seconds from now. */ if (next_report == 0) { next_report = ts.tv_sec + 10; /* This is also a good opportunity to print column headings */ printf("Time\t\tWire Length\tCapture Length\n"); } /* Check whether we need to report average packet sizes or not. * * If the timestamp for the current packet is beyond the time when the * next report was due then we have to output our current stats and * reset it to zero. * * Note that I use a while loop here to ensure that we correctly deal * with periods in which no packets are observed. */ while (ts.tv_sec > next_report) { /* Print the timestamp for the report */ printf("%u\t", next_report); /* Calculate and print the average wire length */ printf("%.2f\t\t", ((double)wire_count) / packet_count); /* Calculate and print the average capture length */ printf("%.2f\n", ((double)capture_count) / packet_count); /* Reset the counters */ packet_count = 0; wire_count = 0; capture_count = 0; /* Determine when the next report is due */ next_report += 10; } /* Increment our counters */ /* Packet count is easy to keep track of */ packet_count += 1; /* Use trace_get_wire_length() to increment our wire length counter */ wire_count += trace_get_wire_length(packet); /* trace_get_capture_length() will tell us the capture length of the * packet */ capture_count += trace_get_capture_length(packet); }
/* Reads the next available packet from a DAG card, in a BLOCKING fashion * * If DUCK reporting is enabled, the packet returned may be a DUCK update */ static int dag_read_packet(libtrace_t *libtrace, libtrace_packet_t *packet) { int numbytes; int size = 0; uint32_t flags = 0; struct timeval tv; dag_record_t *erfptr = NULL; /* Check if we're due for a DUCK report */ if (DUCK.last_pkt - DUCK.last_duck > DUCK.duck_freq && DUCK.duck_freq != 0) { size = dag_get_duckinfo(libtrace, packet); DUCK.last_duck = DUCK.last_pkt; if (size != 0) { return size; } /* No DUCK support, so don't waste our time anymore */ DUCK.duck_freq = 0; } /* Don't let anyone try to free our DAG memory hole */ flags |= TRACE_PREP_DO_NOT_OWN_BUFFER; /* If the packet buffer is currently owned by libtrace, free it so * that we can set the packet to point into the DAG memory hole */ if (packet->buf_control == TRACE_CTRL_PACKET) { packet->buf_control = TRACE_CTRL_EXTERNAL; free(packet->buffer); packet->buffer = 0; } /* Grab a full ERF record */ do { numbytes = dag_available(libtrace); if (numbytes < 0) return numbytes; if (numbytes == 0) continue; erfptr = dag_get_record(libtrace); } while (erfptr == NULL); /* Prepare the libtrace packet */ if (dag_prepare_packet(libtrace, packet, erfptr, TRACE_RT_DATA_ERF, flags)) return -1; /* Update the DUCK timer */ tv = trace_get_timeval(packet); DUCK.last_pkt = tv.tv_sec; return packet->payload ? htons(erfptr->rlen) : erf_get_framing_length(packet); }
int main(int argc, char *argv[]) { char *uri = lookup_uri(argv[1]); int psize = 0; int error = 0; int count = 0; libtrace_packet_t *packet; trace = trace_create(uri); iferr(trace); trace_start(trace); iferr(trace); packet=trace_create_packet(); for (;;) { double ts; double tsdiff; struct timeval tv; if ((psize = trace_read_packet(trace, packet)) <0) { error = 1; break; } if (psize == 0) { error = 0; break; } count ++; tv=trace_get_timeval(packet); ts=trace_get_seconds(packet); tsdiff = (tv.tv_sec+tv.tv_usec/1000000.0)-ts; assert(tsdiff > -0.001 && tsdiff < 0.001); } trace_destroy_packet(packet); if (error == 0) { if (count == 100) { printf("success: 100 packets read\n"); } else { printf("failure: 100 packets expected, %d seen\n",count); error = 1; } } else { iferr(trace); } trace_destroy(trace); return error; }
static gboolean qfTraceHandlePacket(qfTraceSource_t *lts, yfPBuf_t *pbuf, qfContext_t *ctx) { yfIPFragInfo_t fraginfo_buf, *fraginfo = ctx->fragtab ? &fraginfo_buf : NULL; libtrace_linktype_t linktype; uint8_t *pkt; uint32_t caplen; struct timeval tv; /* extract data from libtrace */ tv = trace_get_timeval(lts->packet); pkt = trace_get_packet_buffer(lts->packet, &linktype, &caplen); /* Decode packet into packet buffer */ if (!yfDecodeToPBuf(ctx->dectx, linktype, yfDecodeTimeval(&tv), trace_get_capture_length(lts->packet), pkt, fraginfo, pbuf)) { /* Couldn't decode packet; counted in dectx. Skip. */ return FALSE; } #if QOF_ENABLE_DETUNE /* Signal drop if detune says so */ if (ctx->ictx.detune) { if (!qfDetunePacket(ctx->ictx.detune, &pbuf->ptime, pbuf->iplen)) { return FALSE; } } #endif /* Handle fragmentation if necessary */ if (fraginfo && fraginfo->frag) { yfDefragPBuf(ctx->fragtab, fraginfo, pbuf, pkt, caplen); } /* signal packet processed */ return TRUE; }
/** Implements the process_packet function of the plugin API */ int corsaro_dos_process_packet(corsaro_t *corsaro, corsaro_packet_t *packet) { libtrace_packet_t *ltpacket = LT_PKT(packet); void *temp = NULL; uint8_t proto; uint32_t remaining; libtrace_ip_t *ip_hdr = NULL; libtrace_icmp_t *icmp_hdr = NULL; libtrace_ip_t *inner_ip_hdr = NULL; /* borrowed from libtrace's protocols.h (used by trace_get_*_port) */ struct ports_t { uint16_t src; /**< Source port */ uint16_t dst; /**< Destination port */ }; uint16_t attacker_port = 0; uint16_t target_port = 0; attack_vector_t findme; int khret; khiter_t khiter; attack_vector_t *vector = NULL; uint8_t *pkt_buf = NULL; libtrace_linktype_t linktype; struct timeval tv; if((packet->state.flags & CORSARO_PACKET_STATE_FLAG_BACKSCATTER) == 0) { /* not a backscatter packet */ return 0; } /* backscatter packet, lets find the flow */ /* check for ipv4 */ /* 10/19/12 ak replaced much more verbose code to get header with this */ if((ip_hdr = trace_get_ip(ltpacket)) == NULL) { /* non-ipv4 packet */ return 0; } /* get the transport header */ if((temp = trace_get_transport(ltpacket, &proto, &remaining)) == NULL) { /* not enough payload */ return 0; } findme.target_ip = 0; if(ip_hdr->ip_p == TRACE_IPPROTO_ICMP && remaining >= 2) { icmp_hdr = (libtrace_icmp_t *)temp; if((icmp_hdr->type == 3 || icmp_hdr->type == 4 || icmp_hdr->type == 5 || icmp_hdr->type == 11 || icmp_hdr->type == 12) && ((temp = trace_get_payload_from_icmp(icmp_hdr, &remaining)) != NULL && remaining >= 20 && (inner_ip_hdr = (libtrace_ip_t *)temp) && inner_ip_hdr->ip_v == 4)) { /* icmp error message */ if(inner_ip_hdr->ip_src.s_addr != ip_hdr->ip_dst.s_addr) { STATE(corsaro)->number_mismatched_packets++; } findme.target_ip = ntohl(inner_ip_hdr->ip_dst.s_addr); /* just extract the first four bytes of payload as ports */ if((temp = trace_get_payload_from_ip(inner_ip_hdr, NULL, &remaining)) != NULL && remaining >= 4) { attacker_port = ntohs(((struct ports_t *)temp)->src); target_port = ntohs(((struct ports_t *)temp)->dst); } } else { findme.target_ip = ntohl(ip_hdr->ip_src.s_addr); attacker_port = ntohs(icmp_hdr->code); target_port = ntohs(icmp_hdr->type); } } else if((ip_hdr->ip_p == TRACE_IPPROTO_TCP || ip_hdr->ip_p == TRACE_IPPROTO_UDP) && remaining >= 4) { findme.target_ip = ntohl(ip_hdr->ip_src.s_addr); attacker_port = trace_get_destination_port(ltpacket); target_port = trace_get_source_port(ltpacket); } if(findme.target_ip == 0) { /* the packet is none of ICMP, TCP or UDP */ return 0; } tv = trace_get_timeval(ltpacket); /* is this vector in the hash? */ assert(STATE(corsaro)->attack_hash != NULL); if((khiter = kh_get(av, STATE(corsaro)->attack_hash, &findme)) != kh_end(STATE(corsaro)->attack_hash)) { /* the vector is in the hash */ vector = kh_key(STATE(corsaro)->attack_hash, khiter); if(attack_vector_is_expired(vector, tv.tv_sec) != 0) { kh_del(av, STATE(corsaro)->attack_hash, khiter); attack_vector_free(vector); vector = NULL; } } if(vector == NULL) { /* create a new vector and fill it */ if((vector = attack_vector_init(corsaro)) == NULL) { corsaro_log(__func__, corsaro, "failed to create new attack vector"); return -1; } /* i think this may be buggy. do it the safe way for now vector->initial_packet = corsaro_mincopy_packet(packet); */ vector->initial_packet_len = trace_get_capture_length(ltpacket); if((vector->initial_packet = malloc(vector->initial_packet_len)) == NULL) { corsaro_log(__func__, corsaro, "could not malloc initial packet"); return -1; } if((pkt_buf = trace_get_packet_buffer(ltpacket, &linktype, NULL)) == NULL) { corsaro_log(__func__, corsaro, "could not get packet buffer"); return -1; } memcpy(vector->initial_packet, pkt_buf, vector->initial_packet_len); vector->attacker_ip = ntohl(ip_hdr->ip_dst.s_addr); vector->responder_ip = ntohl(ip_hdr->ip_src.s_addr); vector->target_ip = findme.target_ip; vector->start_time = tv; vector->ppm_window.window_start = tv.tv_sec; /* add to the hash */ khiter = kh_put(av, STATE(corsaro)->attack_hash, vector, &khret); } assert(vector != NULL); vector->packet_cnt++; vector->interval_packet_cnt++; vector->byte_cnt += ntohs(ip_hdr->ip_len); vector->interval_byte_cnt += ntohs(ip_hdr->ip_len); vector->latest_time = tv; /* update the pps window */ attack_vector_update_ppm_window(vector, tv); /* add the attacker ip to the hash */ kh_put(32xx, vector->attack_ip_hash, ntohl(ip_hdr->ip_dst.s_addr), &khret); /* add the ports to the hashes */ kh_put(32xx, vector->attack_port_hash, attacker_port, &khret); kh_put(32xx, vector->target_port_hash, target_port, &khret); return 0; }
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); }*/ }
static int pcap_write_packet(libtrace_out_t *libtrace, libtrace_packet_t *packet) { struct pcap_pkthdr pcap_pkt_hdr; void *link; libtrace_linktype_t linktype; uint32_t remaining; link = trace_get_packet_buffer(packet,&linktype,&remaining); /* We may have to convert this packet into a suitable PCAP packet */ /* If this packet cannot be converted to a pcap linktype then * pop off the top header until it can be converted */ while (libtrace_to_pcap_linktype(linktype)==TRACE_DLT_ERROR) { if (!demote_packet(packet)) { trace_set_err_out(libtrace, TRACE_ERR_NO_CONVERSION, "pcap does not support this format"); return -1; } link = trace_get_packet_buffer(packet,&linktype,&remaining); } if (!OUTPUT.trace.pcap) { int linktype=libtrace_to_pcap_dlt(trace_get_link_type(packet)); OUTPUT.trace.pcap = pcap_open_dead(linktype,65536); if (!OUTPUT.trace.pcap) { trace_set_err_out(libtrace,TRACE_ERR_INIT_FAILED, "Failed to open dead trace: %s\n", pcap_geterr(OUTPUT.trace.pcap)); } OUTPUT.trace.dump = pcap_dump_open(OUTPUT.trace.pcap, libtrace->uridata); if (!OUTPUT.trace.dump) { char *errmsg = pcap_geterr(OUTPUT.trace.pcap); trace_set_err_out(libtrace,TRACE_ERR_INIT_FAILED,"Failed to open output file: %s\n", errmsg ? errmsg : "Unknown error"); return -1; } } /* Corrupt packet, or other "non data" packet, so skip it */ if (link == NULL) { /* Return "success", but nothing written */ return 0; } /* Check if the packet was captured using one of the PCAP formats */ if (packet->trace->format == &pcap || packet->trace->format == &pcapint) { /* Yes - this means we can write it straight out */ pcap_dump((u_char*)OUTPUT.trace.dump, (struct pcap_pkthdr *)packet->header, packet->payload); } else { /* No - need to fill in a PCAP header with the appropriate * values */ /* Leave the manual copy as it is, as it gets around * some OS's having different structures in pcap_pkt_hdr */ struct timeval ts = trace_get_timeval(packet); pcap_pkt_hdr.ts.tv_sec = ts.tv_sec; pcap_pkt_hdr.ts.tv_usec = ts.tv_usec; pcap_pkt_hdr.caplen = remaining; /* trace_get_wire_length includes FCS, while pcap doesn't */ if (trace_get_link_type(packet)==TRACE_TYPE_ETH) if (trace_get_wire_length(packet) >= 4) { pcap_pkt_hdr.len = trace_get_wire_length(packet)-4; } else { pcap_pkt_hdr.len = 0; } else pcap_pkt_hdr.len = trace_get_wire_length(packet); assert(pcap_pkt_hdr.caplen<65536); assert(pcap_pkt_hdr.len<65536); pcap_dump((u_char*)OUTPUT.trace.dump, &pcap_pkt_hdr, packet->payload); } return 0; }