DLLEXPORT libtrace_icmp_t *trace_get_icmp_from_ip(libtrace_ip_t *ip, uint32_t *remaining) { libtrace_icmp_t *icmpptr = 0; if (ip->ip_p == TRACE_IPPROTO_ICMP) { icmpptr = (libtrace_icmp_t *)trace_get_payload_from_ip(ip, NULL, remaining); } return icmpptr; }
DLLEXPORT libtrace_udp_t *trace_get_udp_from_ip(libtrace_ip_t *ip, uint32_t *remaining) { libtrace_udp_t *udpptr = 0; if (ip->ip_p == TRACE_IPPROTO_UDP) { udpptr = (libtrace_udp_t *) trace_get_payload_from_ip(ip, NULL, remaining); } return udpptr; }
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); } }
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; }
/** 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; }