# -*- Mode: Makefile;  -*-

###############################################################################
#                                                                             #
#   Copyright 2005 University of Cambridge Computer Laboratory.               #
#                                                                             #
#   This file is part of Nprobe.                                              #
#                                                                             #
#   Nprobe is free software; you can redistribute it and/or modify            #
#   it under the terms of the GNU General Public License as published by      #
#   the Free Software Foundation; either version 2 of the License, or         #
#   (at your option) any later version.                                       #
#                                                                             #
#   Nprobe 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 Nprobe; if not, write to the Free Software                     #
#   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA #
#                                                                             #
###############################################################################

#
# Where to find various stuff
#

# Archive root
NPROBE_ROOT = ..

# Import all relative paths defined at top level
include $(NPROBE_ROOT)/Makefile.paths

###############################################################################
##############################################################################

#
# Make switches
#

# Profiling switch (use "make profile=1" to build for profiling)
profile=
#

###############################################################################
##############################################################################

#
# A whole bunch of probe configuration stuff handled here and in 
#  modules/config.h 
# 
# ** FIX ME - gather all probe configuration into one central place ** 
#


# Configure switch (default is for bluebird, use "ntl=1" for thrust)
ntl=

ifeq ($(ntl),)
  CONFIG_DEF = -DCAM_CONFIG
else
 CONFIG_DEF = -DNTL_CONFIG
endif

###############################################################################


# Single hosts switch - switches size of host/host and port/port flow hash tables when observing generated workloads
singlehosts=

ifeq ($(singlehosts),)
  SH_DEF =
else
  SH_DEF = -DSINGLE_HOSTS
endif

##############################################################################


#
# Perform checksum calculations
#
DO_CKSUM = -DCKSUM 
#DO_CKSUM =

###############################################################################

#
# Perform flow filtering
#
#DO_FFILT = -DFLOW_FILT 
DO_FFILT =

###############################################################################

#
# Time major fn calls in pkt processing stack
#
TIME_CALLS = -DNO_TIME_CALLS
#TIME_CALLS = -DTIME_CALLS_RUSAGE
#TIME_CALLS = -DTIME_CALLS_TIMES

###############################################################################

#ATM_DEFS =              #Thrust
#ATM_DEFS = -DATM_LANE  #Bluebird

###############################################################################
#
# Use NIC generated packet arrival time stamps
#
#TIME_STAMPS = -DNIC_STAMP -DACENIC
TIME_STAMPS = -DNIC_STAMP -DSK98
#TIME_STAMPS = 
#

###############################################################################
##############################################################################


PLATFORM=$(OS)
#DEPENDENCYFILE=./dependencies.$(OS)
DEPENDENCY_FILE=nprobe.d

###############################################################################

#MATHS_LIBS =
MATHS_LIBS = -lm

###############################################################################

ifeq ($(profile),)
  CC = gcc -g -Wall
  PROFILING=
else
  CC = gcc -g -Wall -pg -static -lc_p
  PROFILING=-DPROFILING
endif

###############################################################################

#
# Build defines
#

# Defines for console output and fed from tcpdump output file 
#DEFINES = -DCPRINTF -DTCPDUMP_FED -DPRINT_OUT -DREPORT

# Defines for file output and fed from tcpdump output file 
#DEFINES = -DCPRINTF -DTCPDUMP_FED  -DREPORT

# Defines for file output via mmap and fed from tcpdump output file 
#DEFINES = -DCPRINTF -DTCPDUMP_FED -DREPORT -DMMAP_REPORT

# Defines for binary file fed from tcpdump output file 
OFFLINE_DEFINES = -DOWAN $(CONFIG_DEF) -DCPRINTF -DTCPDUMP_FED -DBIN_REPORT -DDUMP_DEBUG -DCPRINTF $(LZO_DEFS) $(PROFILING) \
 -DNO_TIME_CALLS $(DO_CKSUM) #-DWRITE_OBJECTS -DTCP_TEST

# Defines for binary file output via mmap and fed from tprobe
ONLINE_DEFINES = $(CONFIG_DEF) -DCPRINTF -DPROBE_FED -DBIN_REPORT  -DMMAP_REPORT  -DDUMP_DEBUG -DCPRINTF $(LZO_DUMP_DEFS) $(LZO_REP_DEFS) \
 $(PROFILING) $(DO_CKSUM) \
$(SH_DEF) $(DO_FFILT) $(TIME_CALLS) $(TIME_STAMPS) #-DWRITE_OBJECTS

###############################################################################
 
CCOPT =

INCLUDES = -I. -I$(COMMON_HDR_DIR) -I$(NPROBE_MODULE_DIR)
LIBS = $(ATM_LIBS) $(MATHS_LIBS)

# Standard CFLAGS - ***USED FOR WAN ***
CFLAGS = $(CCOPT) $(ONLINE_DEFINES) $(INCLUDES)

# CFLAGS FOR OWAN
O_CFLAGS = $(CCOPT) $(OFFLINE_DEFINES) $(INCLUDES)

# CFLAGS FOR WREAD
R_CFLAGS = $(CCOPT) $(ONLINE_DEFINES) -DWREAD -DUSE_HOSTNAMES $(INCLUDES)

#CC = gcc -g -Wall
#CC = cc -g 

AS = as
MAKE = make

OS_LINUX = ix86_linux
LINUX_CKSUM_OBJ = i386-csum.o

ifeq ($(OS),$(OS_LINUX))
  I_CKSUM_OBJ = $(LINUX_CKSUM_OBJ)
else
  I_CKSUM_OBJ =
endif

###############################################################################

# 
# Where to find source not in this directory
#
vpath %.c $(COMMON_SRC_DIR)
vpath %.h $(COMMON_HDR_DIR)

###############################################################################

#
# Common C src and headers
#

WAN_COMMON_CSRC = counters.c \
	print_util.c print_type.c errstring.c \
	cprintf.c print_type.c

WREAD_COMMON_CSRC =  wread_util.c  http_util.c report.c  counters.c \
	print_util.c  print_type.c errstring.c cprintf.c  malloc_rec.c

INSERT_COMMON_CSRC = print_util.c print_type.c

WAN_NPROBE_CSRC = $(addprefix $(COMMON_SRC_DIR)/, $(WAN_COMMON_CSRC))

WREAD_NPROBE_CSRC = $(addprefix $(COMMON_SRC_DIR)/, $(WREAD_COMMON_CSRC))

INSERT_NPROBE_CSRC = $(addprefix $(COMMON_SRC_DIR)/, $(INSERT_COMMON_CSRC))

NPROBE_HDRS = http_errdefs.h basic_defs.h \
	counters.h np_file.h tcp.h \
	http.h flows.h \
	http_util.h udp.h \
	sundry_records.h udp_ns.h \
	icmp.h malloc_rec.h

WAN_NPROBE_HDRS = $(addprefix $(COMMON_HDR_DIR)/, $(NPROBE_HDRS))

###############################################################################

#
# C src and hdrs specific to Nprobe runtime
#

WAN_SPEC_CSRC =  main.c tcpdump_patch.c interface.c pkt.c http.c \
	seq.c flows.c tcp.c http_req.c http_rep.c  \
	performance_timer.c error.c tcp_seq.c output.c \
	pool.c probe_main.c fingerprint.c if_nprobe.c arr_his.c writer.c \
	 tcp_ftp.c tcp_rtsp.c tcp_other.c csum.c sundry_records.c timeouts.c \
	udp.c udp_ns.c udp_other.c content_t.c parse_object.c ffilter.c \
	procstat.c ace_clk.c sk98_clk.c if_stats.c tcp_bgp.c service.c \
	probe_config.c parse_http_fields.c


WREAD_SPEC_CSRC = wread.c servers.c

TCP_INSERT_SPEC_CSRC = tcp_insert.c


###############################################################################

#
# All the C src and hdrs
#

WAN_CSRC = $(WAN_NPROBE_CSRC) $(WAN_SPEC_CSRC)

WREAD_CSRC = $(WREAD_NPROBE_CSRC) $(WREAD_SPEC_CSRC)

TCP_INSERT_CSRC = $(INSERT_NPROBE_CSRC) $(TCP_INSERT_SPEC_CSRC)

###############################################################################


SSRC = i386-csum.S

CSRC =	$(WAN_CSRC) $(TRYHASH_CSRC) $(WREAD_SRC) $(TCP_INSERT_CSRC) sizes.c

###############################################################################

WAN_OWAN_COMMON_OBJ =  cprintf.o $(I_CKSUM_OBJ) csum.o timeouts.o ffilter.o tcp_bgp.o service.o print_type.o

WAN_SPEC_OBJ = main.o tcpdump_patch.o interface.o pkt.o  print_util.o http.o \
	seq.o flows.o tcp.o http_req.o http_rep.o counters.o     \
	performance_timer.o error.o tcp_seq.o output.o \
	errstring.o pool.o probe_main.o fingerprint.o \
	if_nprobe.o arr_his.o writer.o tcp_ftp.o tcp_rtsp.o\
	tcp_other.o  sundry_records.o udp.o udp_ns.o udp_other.o\
	 parse_object.o procstat.o ace_clk.o \
	sk98_clk.o if_stats.o probe_config.o  content_t.o parse_http_fields.o

WAN_OBJ = $(WAN_OWAN_COMMON_OBJ) $(WAN_SPEC_OBJ)

OWAN_SPEC_OBJ = o_main.o o_tcpdump_patch.o o_interface.o o_pkt.o  \
	o_print_util.o o_http.o o_counters.o     \
	o_seq.o o_flows.o o_tcp.o o_http_req.o o_http_rep.o \
	o_performance_timer.o o_error.o o_tcp_seq.o o_output.o \
	o_errstring.o o_pool.o o_probe_main.o o_fingerprint.o \
	o_if_nprobe.o o_writer.o  o_tcp_ftp.o o_tcp_rtsp.o\
	o_tcp_other.o o_tcp_test.o o_udp.o o_udp_ns.o o_udp_other.o\
	o_parse_object.o arr_his.o o_probe_config.o  o_content_t.o o_parse_http_fields.o

OWAN_OBJ = $(WAN_OWAN_COMMON_OBJ) $(OWAN_SPEC_OBJ)

WREAD_COMMON_OBJ = http_util.o errstring.o cprintf.o malloc_rec.o\
	print_type.o

WREAD_SPEC_OBJ =  wr_wread.o wr_wread_util.o wr_report.o \
	wr_counters.o wr_print_util.o

WREAD_OBJ = $(WREAD_COMMON_OBJ) $(WREAD_SPEC_OBJ)

TCP_INSERT_OBJ = tcp_insert.o print_util.o print_type.o cprintf.o

###############################################################################

BINARIES =  wan owan wread sizes ckstr insert

###############################################################################




# Explicit dependency rule for *.o where *.c resides in other dir
%.o : %.c
	rm -f $@;
	$(CC) $(CFLAGS) -c $< -o $@

# rule for making owan objects (same as wan objects but prefixed o_)
o_%.o : %.c
	rm -f $@;
	$(CC) $(O_CFLAGS) -c $< -o $@

# rule for making wread objects (prefixed wr_)
wr_%.o : %.c
	rm -f $@;
	$(CC) $(R_CFLAGS) -c $< -o $@

.s.o:
	rm -f $@;
	 $(AS) $(CFLAGS) -o $*.o $*.s



all: $(BINARIES) install

wan: $(WAN_OBJ) Makefile
	$(CC) $(CFLAGS) -o $@ $(WAN_OBJ) $(LIBS)
	touch $@

owan: $(OWAN_OBJ) Makefile
	$(CC) $(O_CFLAGS) -o $@ $(OWAN_OBJ) $(LIBS)
	touch $@

wread: $(WREAD_OBJ)
	$(CC) $(WR_CFLAGS) -o $@ $(WREAD_OBJ) #$(LIBS)
	touch $@

sizes: sizes.c
	$(CC) $(CFLAGS) -o $@ sizes.c

ckstr: ckstr.c
	$(CC) $(CFLAGS) -o $@ ckstr.c

insert: $(TCP_INSERT_OBJ)
	$(CC) $(CFLAGS) -o $@ $(TCP_INSERT_OBJ)

# produce command to set up nprobe runtime path to build dir
paths_raw: Makefile
	@echo
	@echo '***************************************************************'
	@echo To set up Nprobe runtime using archive tree execute: \
	\". $(PATHS_SETUP)/ 0 1 0 $(subst $(NPROBE_ROOT), \
	$(ABS_ROOT_PATH), $(NPROBE_DIR))\"
	@echo '***************************************************************'
	@echo

# produce command to set up run_time paths etc. for installed version
paths: Makefile
	@echo
	@echo '***************************************************************'
	@echo To set up Nprobe runtime using installed versions execute: \
	\". $(PATHS_SETUP) 0 1 0 $(INSTALL_BIN_DIR)\"
	@echo '***************************************************************'
	@echo

setup: all install paths

setup_raw: all paths_raw

# copy everything useful to install/bin directory, or update as necessary
install update_install: install_dirs $(BINARIES)
	@cp -uvf  $(BINARIES)  $(INSTALL_BIN_DIR)

install_owan: install_dirs owan
	@cp -uvf  owan  $(INSTALL_BIN_DIR)

install_wread: install_dirs wread
	@cp -uvf  wread  $(INSTALL_BIN_DIR)

# Create install dirs if necessary
install_dirs: 
	@if [ ! -d $(INSTALL_LIB_DIR) ]; \
		then \
			mkdir -p $(INSTALL_LIB_DIR); \
			echo Created $(INSTALL_LIB_DIR); \
	fi
	@if [ ! -d $(INSTALL_BIN_DIR) ]; \
		then \
			mkdir -p $(INSTALL_BIN_DIR); \
			echo Created $(INSTALL_BIN_DIR); \
	fi

owan_test: install_owan
	@echo '** Testing owan **'	
	if [ ! -f $(DUMP_TEST_DATA) ];\
		then \
			echo 'Unzipping data file'; \
			gunzip -c $(DUMP_TEST_DATA).gz \
				> $(DUMP_TEST_DATA); \
	else \
		sleep 2; \
	fi
	@$(INSTALL_BIN_DIR)/owan $(DUMP_TEST_DATA) 

wread_test: install_wread
	@if [ ! -f  $(WREAD_TEST_DATA) ]; \
		then \
			echo '** Running Owan to generate rep file **'; \
			sleep 3; \
			$(MAKE) owan_test; \
	fi
	@echo '** Testing wread and piping through less **'
	@sleep 5
	@$(INSTALL_BIN_DIR)/wread $(WREAD_TEST_DATA)	| less -r
		| less -r

config_probe:
	$(PROBE_CONFIG_GEN) probe_config.tmpl probe_config

probe_config:
	echo

probe_config.c probe_config.h: probe_config.tmpl probe_config $(PROBE_CONFIG_GEN)
	$(PROBE_CONFIG_GEN) probe_config.tmpl probe_config

o_probe_config.o: probe_config.c

content_t:
	$(CONTENT_T_GEN) content_types content_t.tmpl $(COMMON_SRC_DIR)/print_type.c $(COMMON_HDR_DIR)/content_t.h content_t.c

content_t_save:
	$(CONTENT_T_GEN) -s content_types content_t.tmpl $(COMMON_SRC_DIR)/print_type.c $(COMMON_HDR_DIR)/content_t.h content_t.c

content_t.c content_t.h $(COMMON_SRC_DIR)/print_type.c: content_t.tmpl content_types $(CONTENT_T_GEN)
	$(CONTENT_T_GEN) content_types content_t.tmpl $(COMMON_SRC_DIR)/print_type.c $(COMMON_HDR_DIR)/content_t.h content_t.c

o_content_t.o: content_t.c 

parse_http_fields:
	$(PARSE_HTTP_FIELDS_GEN) http_fields parse_http_fields.tmpl parse_http_fields.c

parse_http_fields.c: http_fields parse_http_fields.tmpl $(PARSE_HTTP_FIELDS_GEN)
	$(PARSE_HTTP_FIELDS_GEN) http_fields parse_http_fields.tmpl parse_http_fields.c

generate: config_probe content_t parse_http_fields


tidy:
	rm -f *.o

clean: tidy
	rm -f $(BINARIES)

test_clean:
	if [ -f $(DUMP_TEST_DATA).gz ];\
		then \
			rm -vf $(DUMP_TEST_DATA); \
	fi      
	rm -vf $(DUMP_TEST_DATA).A*

very_clean: clean test_clean
	rm -vf $(DEPENDENCY_FILE) probe_config.c probe_config.h \
	probe_config*bak $(COMMON_SRC_DIR)/print_type.c* \
	$(COMMON_HDR_DIR)/content_t.h* content_t.c parse_http_fields.c \
	*.bak

clobber: very_clean
	@rm -vf $(addprefix $(INSTALL_BIN_DIR)/, $(BINARIES))

$(DEPENDENCY_FILE) :
	if [ ! -f $(DEPENDENCY_FILE) ]; then touch $(DEPENDENCY_FILE); fi 

depend: $(DEPENDENCY_FILE) probe_config.c content_t.c parse_http_fields.c
#depend: $(DEPENDENCY_FILE) generate
	makedepend -f- -- $(DEFINES) -- $(INCLUDES) $(CSRC) $(SSRC) $(HDR) \
	  | sed -e 's/$(subst /,\/,$(COMMON_SRC_DIR))\///' \
	  > $(DEPENDENCY_FILE)
	makedepend -f- -- $(DEFINES) -- $(INCLUDES) \
	  $(addprefix $(COMMON_SRC_DIR)/, $(filter $(WAN_COMMON_CSRC), \
	    $(subst o_, , $(addsuffix .c, $(basename $(OWAN_SPEC_OBJ)))))) \
	  | sed -e 's/$(subst /,\/,$(COMMON_SRC_DIR))\//o_/' \
	  >> $(DEPENDENCY_FILE)
	makedepend -f- -- $(DEFINES) -- $(INCLUDES) \
	  $(addprefix ./, $(filter-out $(WAN_COMMON_CSRC), \
	    $(subst o_, , $(addsuffix .c, $(basename $(OWAN_SPEC_OBJ)))))) \
	  | sed -e 's/.\//o_/' \
	  >> $(DEPENDENCY_FILE)
	makedepend -f- -- $(DEFINES) -- $(INCLUDES) \
	  $(addprefix $(COMMON_SRC_DIR)/, $(filter $(WREAD_COMMON_CSRC), \
	    $(subst wr_, , $(addsuffix .c, $(basename $(WREAD_SPEC_OBJ)))))) \
	  | sed -e 's/$(subst /,\/,$(COMMON_SRC_DIR))\//wr_/' \
	  >> $(DEPENDENCY_FILE)
	makedepend -f- -- $(DEFINES) -- $(INCLUDES) \
	  $(addprefix ./, $(filter-out $(WREAD_COMMON_CSRC), \
	    $(subst wr_, , $(addsuffix .c, $(basename $(WREAD_SPEC_OBJ)))))) \
	  | sed -e 's/.\//wr_/' \
	  >> $(DEPENDENCY_FILE)


include $(DEPENDENCY_FILE)
