241 lines
6.7 KiB
Ruby
241 lines
6.7 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.11.tar.bz2"
|
|
sha256 "75a2a8bc1c3cb32a6a5e1ef41d5e3740505880d94cc97df94cf33f7a8f65750e"
|
|
|
|
bottle do
|
|
cellar :any
|
|
sha256 "e79359353b5aa4c7177bb015be328a7d9d25e17729de6103a1dafec79d8edb28" => :catalina
|
|
sha256 "c82d9d3ef55ac52c4b7ac2640c758ad8997e77869de5558d68384a456f4ab74f" => :mojave
|
|
sha256 "764cf9c54d186d1dca1b5d5e27bdaaca48764bce7f8abe32b77f2f3274acd827" => :high_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 <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,ð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 (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("8021x.pcap").stage testpath
|
|
system "./test", testpath/"8021x.pcap"
|
|
end
|
|
end
|