#
# Copyright (C) 2013-2021 by the University of Southern California
# $Id$
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License,
# version 2, as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.

CC = gcc
CPP= g++
LD = g++
CFLAGS = -g -Wall
CXXFLAGS = -g -Wall -std=c++11
#CFLAGS = -g -O1 -Wall -std=c++11
# need to switch to static libtrace to avoid package dependency during binary install
# LIBTRACE=-ltrace
STATIC_LIBTRACE=/usr/lib64/libtrace.a /usr/lib64/libwandio.a -lpthread -llzma -lbz2 -lpcap -lz -llzo2
DYNAMIC_LIBTRACE=-ltrace
OTHER_LIBS=-lssl -lcrypto -lldns -lpcap -lcryptopANT -llz4

.PHONY: clean all

DESTDIR=
PREFIX=/usr
BINDIR=$(PREFIX)/bin
MAN1DIR=$(PREFIX)/share/man/man1
PROGRAM=dnsanon

ALL_FLAGS=-D DNSANON_BUILD=1
ALL_CXXFLAGS=$(ALL_FLAGS)
DSC_OBJ = dsc/src/pcap.o dsc/src/hashtbl.o dsc/src/xmalloc.o dsc/src/inX_addr.o dsc/src/compat.o
DSC_CFLAGS = $(ALL_FLAGS) -I dsc/src
all: dnsanon anon_names

clean:
	rm -f *.o *.fsdb *~ dnsanon dnsanon.spec *.bz2 *.d anon_names dsc/src/*.o dsc/src/*.d

parse.cc.o: parse.cc parse.hh
main.cc.o: main.cc global_var.h
anon.cc.o: anon.cc anon.hh
aes_util.cc.o: aes_util.cc aes_util.hh
utility.cc.o: utility.cc utility.hh
anon_names.o: anon_names.cc
base64_util.o: base64_util.cc base64_util.hh
table.o: table.cc table.hh

anon_names: anon_names.o base64_util.o anon.o aes_util.o utility.o
	$(LD) -o anon_names $^ -lssl -lcrypto -lcryptopANT

dnsanon: main.o parse.o anon.o aes_util.o base64_util.o table.o utility.o \
		 dsc_glue.o $(DSC_OBJ)
	$(LD) -o dnsanon $^ $(DYNAMIC_LIBTRACE) $(OTHER_LIBS)

dnsanon_static: main.o parse.o anon.o aes_util.o base64_util.o table.o utility.o \
				dsc_glue.o $(DSC_OBJ)
	$(LD) -o dnsanon $^ $(STATIC_LIBTRACE) $(OTHER_LIBS)

.c.o:
	$(CC) $(CFLAGS) $(DSC_CFLAGS) -MT $@ -MD -MP -c -o $@ $<
.cc.o:
	$(CXX) $(CXXFLAGS) $(ALL_CXXFLAGS) -MT $@ -MD -MP -c -o $@ $< -lssl -lcrypto

dnsanon.1: dnsanon.md
	pandoc -f markdown -t man -o dnsanon.1 dnsanon.md -s

install_dnsanon_dynamic: dnsanon
	cp dnsanon $(DESTDIR)$(BINDIR)/$(PROGRAM)
	chmod u=rwx,go=rx $(DESTDIR)$(BINDIR)/$(PROGRAM)

install_dnsanon_static: dnsanon_static
	cp dnsanon $(DESTDIR)$(BINDIR)/$(PROGRAM)
	chmod u=rwx,go=rx $(DESTDIR)$(BINDIR)/$(PROGRAM)

install_man: dnsanon.1
	-mkdir -p $(DESTDIR)$(MAN1DIR)
	-gzip < dnsanon.1 >$(DESTDIR)$(MAN1DIR)/dnsanon.1.gz

install:
	-mkdir -p $(DESTDIR)$(BINDIR)
	make install_dnsanon_dynamic
	make install_man

install_static:
	-mkdir -p $(DESTDIR)$(BINDIR)
	make install_dnsanon_static
	make install_man

VERSION=$(shell grep VERSION version.h | sed -e 's/^[^"]*"//' -e 's/"[^"]*$$//')
RELEASE=$(shell grep RELEASE version.h | sed -e 's/^[^"]*"//' -e 's/"[^"]*$$//')
VERSION_RELEASE=$(VERSION)-$(RELEASE)

######################################################################
#
# testing
#

test_enc:
	cat domain_names |./anon_names -k keyfile
test_dec:
	cat domain_names |./anon_names -k keyfile | ./anon_names -k keyfile -r
test_validate:
	cat domain_names |./anon_names -k keyfile | ./anon_names -k keyfile -r  | diff - domain_names

test_samples: ./dnsanon
	( cd sample_data && make test )

DATA_DIR=sample_data
TEST_DIR=.dnsanon_test
test: dnsanon
	rm -rf $(TEST_DIR) && mkdir -pv $(TEST_DIR)
	dn=(output_151226_Q output_151226_Qm output_151226_mqr);\
	for d in "$${dn[@]}"; do\
		OUT_DIR=$(TEST_DIR)/$$d;\
		mkdir -p $$OUT_DIR;\
		OPT=`echo $$d | cut -d _ -f 3`;\
		./dnsanon -i $(DATA_DIR)/input_151226.pcap -o $$OUT_DIR -p $$OPT -c none;\
		diff -I ^# $$OUT_DIR $(DATA_DIR)/$$d || exit 1; \
	done
	dn=(output_151226_QR_T output_151226_mqr_T);\
	for d in "$${dn[@]}"; do\
		OUT_DIR=$(TEST_DIR)/$$d;\
		mkdir -p $$OUT_DIR;\
		OPT=`echo $$d | cut -d _ -f 3`;\
		./dnsanon -i $(DATA_DIR)/input_151226.pcap -o $$OUT_DIR -p $$OPT -c none -T;\
		diff -I ^# $$OUT_DIR $(DATA_DIR)/$$d || exit 1; \
	done
	./dnsanon -i  $(DATA_DIR)/input2.pcap -o - -p Q | \
	diff -I ^# - $(DATA_DIR)/output_2_Q/1351804728.090728.message_question.fsdb || exit 1
	OUT_DIR=$(TEST_DIR)/anon_output_151226_mqr;\
	mkdir -p $$OUT_DIR;\
	./dnsanon -i $(DATA_DIR)/input_151226.pcap -o $$OUT_DIR -p mqr -c none -a all -k keyfile --pass4 16 --pass6 64;\
	diff -I ^# $$OUT_DIR $(DATA_DIR)/anon_output_151226_mqr || exit 1;\
	./dnsanon --ip-ttl --rtt -i  $(DATA_DIR)/input2.pcap -o - -p Q | \
	diff -I ^# - $(DATA_DIR)/output_2_Q_ttl_rtt/1351804728.090728.message_question.fsdb || exit 1
	OUT_DIR=$(TEST_DIR)/anon_output_151226_mqr;\
	echo "[info] test is successful";\
	rm -rf $(TEST_DIR)

update_test: dnsanon
	dn=(output_151226_Q output_151226_Qm output_151226_mqr);\
	for d in "$${dn[@]}"; do\
		OUT_DIR=$(DATA_DIR)/$$d;\
		mkdir -p $$OUT_DIR;\
		OPT=`echo $$d | cut -d _ -f 3`;\
		./dnsanon -i $(DATA_DIR)/input_151226.pcap -o $$OUT_DIR -p $$OPT -c none;\
	done
	dn=(output_2_Q output_2_Qm output_2_mqr);\
	for d in "$${dn[@]}"; do\
		OUT_DIR=$(DATA_DIR)/$$d;\
		mkdir -p $$OUT_DIR;\
		OPT=`echo $$d | cut -d _ -f 3`;\
		./dnsanon -i $(DATA_DIR)/input2.pcap -o $$OUT_DIR -p $$OPT -c none;\
	done

update_test_2: dnsanon
	dn=(output_151226_QR output_151226_mqr);\
	for d in "$${dn[@]}"; do\
		OUT_DIR=$(DATA_DIR)/$${d}_T;\
		mkdir -p $$OUT_DIR;\
		OPT=`echo $$d | cut -d _ -f 3`;\
		./dnsanon -i $(DATA_DIR)/input_151226.pcap -o $$OUT_DIR -p $$OPT -c none -T;\
	done

update_onequery: dnsanon
	dn=(output_onequery_Q output_onequery_Qm output_onequery_mqr);\
	for d in "$${dn[@]}"; do\
		OUT_DIR=$(DATA_DIR)/$$d;\
		mkdir -p $$OUT_DIR;\
		OPT=`echo $$d | cut -d _ -f 3`;\
		./dnsanon -i $(DATA_DIR)/input_onequery.pcap -o $$OUT_DIR -p $$OPT -c none;\
	done

######################################################################
#
# packaging
#

# generic

# TODO expand the curly braces or set SHELL=/bin/bash explicitly at the top of
# this Makefile as curly braces expansion is not POSIX-compliant (and will fail
# on Debian/Ubuntu).
TARBALL = dnsanon-$(VERSION_RELEASE).tar.gz
tar.gz: dnsanon.spec dnsanon.1
	ln -s . dnsanon-$(VERSION_RELEASE)
	tar -chvzf $(TARBALL) \
		--exclude='*.d' \
		--exclude='*.o' \
		dnsanon-$(VERSION_RELEASE)/README \
		dnsanon-$(VERSION_RELEASE)/COPYING \
		dnsanon-$(VERSION_RELEASE)/Makefile \
		dnsanon-$(VERSION_RELEASE)/*.{cc,hh,c,h} \
		dnsanon-$(VERSION_RELEASE)/dnsanon.{1,md} \
		dnsanon-$(VERSION_RELEASE)/dnsanon.spec{,.in} \
		dnsanon-$(VERSION_RELEASE)/dsc \
		dnsanon-$(VERSION_RELEASE)/sample_data
	rm dnsanon-$(VERSION_RELEASE)

# fedora
dnsanon.spec:  dnsanon.spec.in version.h
	<dnsanon.spec.in sed 's/@VERSION@/'$(VERSION)'/g; s/@RELEASE@/'$(RELEASE)'/g' >$@

rpms: dnsanon.spec tar.gz
	cp $(TARBALL) $$HOME/rpmbuild/SOURCES
	cp dnsanon.spec $$HOME/rpmbuild/SPECS
	( cd $$HOME/rpmbuild; rpmbuild -ba SPECS/dnsanon.spec; )
	( cd $$HOME/rpmbuild; rpmsign --addsign  $$HOME/rpmbuild/RPMS/x86_64/dnsanon-$(VERSION)*.x86_64.rpm; )
	cp $$HOME/rpmbuild/RPMS/x86_64/dnsanon-$(VERSION)*.x86_64.rpm .
	cp $$HOME/rpmbuild/SRPMS/dnsanon-$(VERSION)*.src.rpm .

rpmlint:
	rpmlint dnsanon-$(VERSION)*.src.rpm

# release
INTERNAL_WEBSITE=../../../../ANT/WWW/ant_2015/software/dnsanon
release:
	@echo "You should edit version.h to remove -dev, then do: \"make tar.gz; make rpms; make rpmlint\""
	cp dnsanon-$(VERSION_RELEASE).tar.gz dnsanon-$(VERSION)*.src.rpm $(INTERNAL_WEBSITE)
	( cd $(INTERNAL_WEBSITE); git add dnsanon-$(VERSION_RELEASE).tar.gz dnsanon-$(VERSION)*.src.rpm; )
	@echo "now (edit _data/software.yaml); git tag -s -u 0x4c6cd6f2 -m 'dnsanon-$(VERSION_RELEASE) release' dnsanon-$(VERSION_RELEASE); cd $(INTERNAL_WEBSITE); git commit -m 'release $(VERSION_RELEASE)'; git push;"
