class Libtrace < Formula desc "Library for trace processing supporting multiple inputs" homepage "https://research.wand.net.nz/software/libtrace.php" url "https://research.wand.net.nz/software/libtrace/libtrace-4.0.9.tar.bz2" sha256 "90f7e317aaa1b93f8b9f17e82ca3b0c7da99d066dbf770ae8de384a402a2218e" revision 1 bottle do cellar :any sha256 "22c334623bab9cbaaf0b8a8e35018fd152d9bede0d97eafcef51a7f5f16819b6" => :catalina sha256 "1f8b78a136537fb62a151869db571242e96d95e33f662d82b18b819e783fea8f" => :mojave sha256 "fd30916693a3c73b3893370af52f02a71c67d23efaf72ead13b279d7b6583be6" => :high_sierra sha256 "e4d5b43970e5ac9d444410fdd18265246f590051c946cf5f6a14f99b2c96f108" => :sierra end depends_on "openssl@1.1" depends_on "wandio" resource "8021x.pcap" do url "https://github.com/LibtraceTeam/libtrace/raw/9e82eabc39bc491c74cc4215d7eda5f07b85a8f5/test/traces/8021x.pcap" sha256 "aa036e997d7bec2fa3d387e3ad669eba461036b9a89b79dcf63017a2c4dac725" end def install system "./configure", "--disable-dependency-tracking", "--prefix=#{prefix}" system "make", "install" end test do (testpath/"test.c").write <<~EOS #include #include #include #include #include #include double lastts = 0.0; uint64_t v4_packets=0; uint64_t v6_packets=0; uint64_t udp_packets=0; uint64_t tcp_packets=0; uint64_t icmp_packets=0; uint64_t ok_packets=0; 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_packets,v6_packets); printf("%"PRIu64",%"PRIu64",%"PRIu64,icmp_packets,tcp_packets,udp_packets); printf("\\n"); v4_packets=v6_packets=0; icmp_packets=tcp_packets=udp_packets=0; } l3 = trace_get_layer3(packet,ðertype,&remaining); if (!l3) /* Probable ARP or something */ return; /* Get the UDP/TCP/ICMP header from the IPv4_packets/IPv6_packets packet */ switch (ethertype) { case 0x0800: transport = trace_get_payload_from_ip( (libtrace_ip_t*)l3, &proto, &remaining); if (!transport) return; ++v4_packets; break; case 0x86DD: transport = trace_get_payload_from_ip6( (libtrace_ip6_t*)l3, &proto, &remaining); if (!transport) return; ++v6_packets; break; default: return; } /* Parse the udp_packets/tcp_packets/icmp_packets payload */ switch(proto) { case 1: ++icmp_packets; return; case 6: payload = trace_get_payload_from_tcp( (libtrace_tcp_t*)transport, &remaining); if (!payload) return; ++tcp_packets; break; case 17: payload = trace_get_payload_from_udp( (libtrace_udp_t*)transport, &remaining); if (!payload) return; ++udp_packets; break; default: return; } ++ok_packets; } static void usage(char *argv0) { fprintf(stderr,"usage: %s [ --filter | -f bpfexp ] [ --snaplen | -s snap ]\\n\\t\\t[ --promisc | -p flag] [ --help | -h ] [ --libtrace-help | -H ] libtraceuri...\\n",argv0); } int main(int argc, char *argv[]) { libtrace_t *trace; libtrace_packet_t *packet; libtrace_filter_t *filter=NULL; int snaplen=-1; int promisc=-1; while(1) { int option_index; struct option long_options[] = { { "filter", 1, 0, 'f' }, { "snaplen", 1, 0, 's' }, { "promisc", 1, 0, 'p' }, { "help", 0, 0, 'h' }, { "libtrace-help", 0, 0, 'H' }, { NULL, 0, 0, 0 } }; int c= getopt_long(argc, argv, "f:s:p:hH", long_options, &option_index); if (c==-1) break; switch (c) { case 'f': filter=trace_create_filter(optarg); break; case 's': snaplen=atoi(optarg); break; case 'p': promisc=atoi(optarg); break; case 'H': trace_help(); return 1; default: fprintf(stderr,"Unknown option: %c\\n",c); /* FALL THRU */ case 'h': usage(argv[0]); return 1; } } if (optind>=argc) { fprintf(stderr,"Missing input uri\\n"); usage(argv[0]); return 1; } while (optind0) if (trace_config(trace,TRACE_OPTION_SNAPLEN,&snaplen)) { trace_perror(trace,"ignoring: "); } if (filter) if (trace_config(trace,TRACE_OPTION_FILTER,filter)) { trace_perror(trace,"ignoring: "); } if (promisc!=-1) { if (trace_config(trace,TRACE_OPTION_PROMISC,&promisc)) { trace_perror(trace,"ignoring: "); } } if (trace_start(trace)) { trace_perror(trace,"Starting trace"); trace_destroy(trace); return 1; } packet = trace_create_packet(); while (trace_read_packet(trace,packet)>0) { per_packet(packet); } trace_destroy_packet(packet); if (trace_is_err(trace)) { trace_perror(trace,"Reading packets"); } trace_destroy(trace); } if (filter) { trace_destroy_filter(filter); } return 0; } EOS system ENV.cc, "test.c", "-I#{include}", "-L#{lib}", "-ltrace", "-o", "test" resource("8021x.pcap").stage testpath system "./test", testpath/"8021x.pcap" end end