libtrace_vxlan_t *trace_get_vxlan_from_udp(libtrace_udp_t *udp, uint32_t *remaining) { if (udp->dest != htons(4789)) { /* UDP port number for vxlan */ return NULL; /* Not a vxlan packet. */ } return trace_get_payload_from_udp(udp, remaining); }
static void per_packet(libtrace_packet_t *packet) { assert(packet); uint32_t remaining; uint8_t proto; void *transport = trace_get_transport(packet, &proto, &remaining); if (!transport || proto != TRACE_IPPROTO_UDP) return; void *radius = trace_get_payload_from_udp(transport, &remaining); if (!radius) return; process_radius(radius, remaining); }
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 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, ðertype, &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; }
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; }