homebrew-core/Formula/libtrace.rb

258 lines
7.6 KiB
Ruby

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.19.tar.bz2"
sha256 "d1a2d756d744c4ffad480f6d4b0bdaca05a9966c87e491992c42007a22317e5a"
license "GPL-3.0-or-later"
livecheck do
url :homepage
regex(/href=.*?libtrace[._-]v?(\d+(?:\.\d+)+)\.t/i)
end
bottle do
sha256 cellar: :any, arm64_monterey: "f9edccc796e56af2f95bbbcffa1e791f7a17192e010ca4034b45ffa2427a0ae1"
sha256 cellar: :any, arm64_big_sur: "1726bfafd1b98709f408d17495827e1884f5e0bdc3a1933c80da04116dfd9bca"
sha256 cellar: :any, monterey: "a7a4f93a72e61b050f64ba94ca1074c4e0da466914755abe87c9d66894ec9fcb"
sha256 cellar: :any, big_sur: "beba5d290b00bd42eafec29d80b05460da03da8f00e1c4e1ef58c47e602c1312"
sha256 cellar: :any, catalina: "9aa10a0c52d0f1e3929cd8c4fffd0a1c65f12c4527d95d8854c1139cffb1dcc4"
sha256 cellar: :any_skip_relocation, x86_64_linux: "3dde6596eb8e6501379c201dd115de9e1f106dbc39e5705a56f07055249ed8c2"
end
depends_on "openssl@1.1"
depends_on "wandio"
uses_from_macos "flex" => :build
uses_from_macos "libpcap"
resource "homebrew-8021x.pcap" do
url "https://github.com/LibtraceTeam/libtrace/raw/9e82eabc39bc491c74cc4215d7eda5f07b85a8f5/test/traces/8021x.pcap"
sha256 "aa036e997d7bec2fa3d387e3ad669eba461036b9a89b79dcf63017a2c4dac725"
end
# Fix -flat_namespace being used on Big Sur and later.
patch do
url "https://raw.githubusercontent.com/Homebrew/formula-patches/03cf8088210822aa2c1ab544ed58ea04c897d9c4/libtool/configure-big_sur.diff"
sha256 "35acd6aebc19843f1a2b3a63e880baceb0f5278ab1ace661e57a502d9d78c93c"
end
def install
system "./configure", *std_configure_args
system "make", "install"
end
test do
(testpath/"test.c").write <<~EOS
#include <libtrace.h>
#include <inttypes.h>
#include <stdio.h>
#include <getopt.h>
#include <stdlib.h>
#include <string.h>
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,&ethertype,&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 (optind<argc) {
trace = trace_create(argv[optind]);
++optind;
if (trace_is_err(trace)) {
trace_perror(trace,"Opening trace file");
return 1;
}
if (snaplen>0)
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("homebrew-8021x.pcap").stage testpath
system "./test", testpath/"8021x.pcap"
end
end