11ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn/*
21ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn * BPF program compilation tool
31ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn *
41ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn * Generates decimal output, similar to `tcpdump -ddd ...`.
51ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn * Unlike tcpdump, will generate for any given link layer type.
61ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn *
71ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn * Written by Willem de Bruijn (willemb@google.com)
81ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn * Copyright Google, Inc. 2013
91ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn * Licensed under the GNU General Public License version 2 (GPLv2)
101ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn*/
111ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn
121ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn#include <pcap.h>
131ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn#include <stdio.h>
141ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn
151ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijnint main(int argc, char **argv)
161ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn{
171ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn	struct bpf_program program;
181ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn	struct bpf_insn *ins;
191ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn	int i, dlt = DLT_RAW;
201ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn
211ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn	if (argc < 2 || argc > 3) {
221ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn		fprintf(stderr, "Usage:    %s [link] '<program>'\n\n"
231ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn				"          link is a pcap linklayer type:\n"
241ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn				"          one of EN10MB, RAW, SLIP, ...\n\n"
251ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn				"Examples: %s RAW 'tcp and greater 100'\n"
261ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn				"          %s EN10MB 'ip proto 47'\n'",
271ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn				argv[0], argv[0], argv[0]);
281ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn		return 1;
291ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn	}
301ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn
311ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn	if (argc == 3) {
321ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn		dlt = pcap_datalink_name_to_val(argv[1]);
331ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn		if (dlt == -1) {
341ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn			fprintf(stderr, "Unknown datalinktype: %s\n", argv[1]);
351ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn			return 1;
361ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn		}
371ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn	}
381ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn
391ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn	if (pcap_compile_nopcap(65535, dlt, &program, argv[argc - 1], 1,
401ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn				PCAP_NETMASK_UNKNOWN)) {
411ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn		fprintf(stderr, "Compilation error\n");
421ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn		return 1;
431ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn	}
441ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn
451ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn	printf("%d,", program.bf_len);
461ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn	ins = program.bf_insns;
471ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn	for (i = 0; i < program.bf_len-1; ++ins, ++i)
481ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn		printf("%u %u %u %u,", ins->code, ins->jt, ins->jf, ins->k);
491ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn
501ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn	printf("%u %u %u %u\n", ins->code, ins->jt, ins->jf, ins->k);
511ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn
521ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn	pcap_freecode(&program);
531ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn	return 0;
541ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn}
551ac30c97c339957b6e3c5cf571de7bc38c827730Willem de Bruijn
56