summaryrefslogtreecommitdiff
path: root/Makefile
blob: 25c96b5c9d6b815e3b014d48abb498d634b11367 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
# netsniff-ng build system
# Copyright 2012 - 2013 Daniel Borkmann <borkmann@gnumaniacs.org>
# Subject to the GNU GPL, version 2.

VERSION = 0
PATCHLEVEL = 5
SUBLEVEL = 8
EXTRAVERSION = -rc0
NAME = Ziggomatic

TOOLS ?= netsniff-ng trafgen astraceroute flowtop ifpps bpfc curvetun mausezahn

# For packaging purposes, prefix can define a different path.
PREFIX ?=

# Disable if you don't want it
CCACHE ?= ccache

# Location of installation paths.
SBINDIR = $(PREFIX)/usr/sbin
INCDIR = $(PREFIX)/usr/include
ETCDIR = $(PREFIX)/etc
ETCDIRE = $(ETCDIR)/netsniff-ng

# Shut up make, helper warnings, parallel compilation!
MAKEFLAGS += --no-print-directory
MAKEFLAGS += -rR
MAKEFLAGS += --warn-undefined-variables
MAKEFLAGS += --jobs=$(shell grep "^processor" /proc/cpuinfo | wc -l)

# Debugging option
ifeq ("$(origin DEBUG)", "command line")
  DEBUG := 1
else
  DEBUG := 0
endif

# For packaging purposes, you might want to call your own:
#   make CFLAGS="<flags>"
CFLAGS_DEF = -fstack-protector
ifeq ($(DEBUG), 1)
  CFLAGS_DEF += -g
  CFLAGS_DEF += -O2
else
  CFLAGS_DEF += -march=native
  CFLAGS_DEF += -mtune=native
  CFLAGS_DEF += -O3
  CFLAGS_DEF += -fpie
  CFLAGS_DEF += -pipe
  CFLAGS_DEF += -fomit-frame-pointer
endif
CFLAGS_DEF += --param=ssp-buffer-size=4
CFLAGS_DEF += -fno-strict-aliasing
CFLAGS_DEF += -fexceptions
CFLAGS_DEF += -fasynchronous-unwind-tables
CFLAGS_DEF += -fno-delete-null-pointer-checks
CFLAGS_DEF += -D_FORTIFY_SOURCE=2
CFLAGS_DEF += -D_REENTRANT
CFLAGS_DEF += -D_FILE_OFFSET_BITS=64
CFLAGS_DEF += -D_LARGEFILE_SOURCE
CFLAGS_DEF += -D_LARGEFILE64_SOURCE
CFLAGS_DEF += -std=gnu99

WFLAGS_DEF  = -Wall
WFLAGS_DEF += -Wformat=2
WFLAGS_DEF += -Wmissing-prototypes
WFLAGS_DEF += -Wdeclaration-after-statement
WFLAGS_DEF += -Werror-implicit-function-declaration
WFLAGS_DEF += -Wstrict-prototypes
WFLAGS_DEF += -Wundef
WFLAGS_DEF += -Wimplicit-int

WFLAGS_EXTRA  = -Wno-unused-result
WFLAGS_EXTRA += -Wmissing-parameter-type
WFLAGS_EXTRA += -Wtype-limits
WFLAGS_EXTRA += -Wclobbered
WFLAGS_EXTRA += -Wmissing-field-initializers
WFLAGS_EXTRA += -Woverride-init
WFLAGS_EXTRA += -Wold-style-declaration
WFLAGS_EXTRA += -Wignored-qualifiers
WFLAGS_EXTRA += -Wempty-body
WFLAGS_EXTRA += -Wuninitialized

WFLAGS_DEF += $(WFLAGS_EXTRA)
CFLAGS_DEF += $(WFLAGS_DEF)

CFLAGS ?= $(CFLAGS_DEF)
CPPFLAGS =
ifeq ("$(origin CROSS_LD_LIBRARY_PATH)", "command line")
  LDFLAGS = -L$(CROSS_LD_LIBRARY_PATH)
else
  LDFLAGS =
endif

ALL_CFLAGS = $(CFLAGS) -I.
ALL_CFLAGS += -DVERSION_STRING=\"$(VERSION_STRING)\"
ALL_CFLAGS += -DPREFIX_STRING=\"$(PREFIX)\"
ifneq ($(wildcard /usr/include/linux/net_tstamp.h),)
  ALL_CFLAGS += -D__WITH_HARDWARE_TIMESTAMPING
endif
ALL_LDFLAGS = $(LDFLAGS)
LEX_FLAGS =
YAAC_FLAGS =

# Be quite and do not echo the cmd
Q = @

# Some command definitions
LD = $(Q)echo -e "  LD\t$@" && $(CCACHE) $(CROSS_COMPILE)gcc
CCNQ = $(CCACHE) $(CROSS_COMPILE)gcc
CC = $(Q)echo -e "  CC\t$<" && $(CCNQ)
MKDIR = $(Q)echo -e "  MKDIR\t$@" && mkdir
ifeq ($(DEBUG), 1)
  STRIP = $(Q)true
else
  STRIP = $(Q)echo -e "  STRIP\t$@" && $(CROSS_COMPILE)strip
endif
LEX = $(Q)echo -e "  LEX\t$<" && flex
YAAC = $(Q)echo -e "  YAAC\t$<" && bison
INST = echo -e "  INST\t$(1)" && install -d $(2) && \
	install --mode=644 -DC $(1) $(2)/$(shell basename $(1))
ifeq ("$(origin PREFIX)", "command line")
  INSTX = echo -e "  INST\t$(1)" && install -d $(2) && \
	install -C $(1) $(2)/$(shell basename $(1))
else
  INSTX = echo -e "  INST\t$(1)" && install -C $(1) $(2)/$(shell basename $(1))
endif
RM = echo -e "  RM\t$(1)" && rm -rf $(1)
RMDIR = echo -e "  RM\t$(1)" && rmdir --ignore-fail-on-non-empty $(1) 2> /dev/null || true
GIT_ARCHIVE = git archive --prefix=netsniff-ng-$(VERSION_STRING)/ $(VERSION_STRING) | \
	      $(1) > ../netsniff-ng-$(VERSION_STRING).tar.$(2)
GIT_TAG = git tag -a $(VERSION_STRING) -s -m "tools: $(VERSION_STRING) release"
GIT_LOG = git shortlog -n --not $(shell git describe --abbrev=0 --tags)
GIT_REM = git ls-files -o | xargs rm -rf
GIT_PEOPLE = git log --no-merges $(VERSION_STRING)..HEAD | grep Author: | cut -d: -f2 | \
	     cut -d\< -f1 | sort | uniq -c | sort -nr

export VERSION PATCHLEVEL SUBLEVEL EXTRAVERSION
export CROSS_COMPILE

VERSION_STRING = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
VERSION_SHORT = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)

bold = $(shell tput bold)
normal = $(shell tput sgr0)

ifndef NACL_LIB_DIR
ifndef NACL_INC_DIR
   $(info $(bold)NACL_LIB_DIR/NACL_INC_DIR is undefined, build libnacl first for curvetun!$(normal))
endif
endif

ifeq ("$(origin CROSS_COMPILE)", "command line")
  WHAT := Cross compiling
else
  WHAT := Building
endif

build_showinfo:
	$(Q)echo "$(bold)$(WHAT) netsniff-ng toolkit ($(VERSION_STRING)) for" \
	      $(shell $(CCNQ) -dumpmachine)":$(normal)"
clean_showinfo:
	$(Q)echo "$(bold)Cleaning netsniff-ng toolkit ($(VERSION_STRING)):$(normal)"

%.yy.o: %.l
	$(LEX) -P $(shell perl -wlne 'print $$1 if /lex-func-prefix:\s([a-z]+)/' $<) \
	       -o $(BUILD_DIR)/$(shell basename $< .l).yy.c $(LEX_FLAGS) $<
%.tab.o: %.y
	$(YAAC) -p $(shell perl -wlne 'print $$1 if /yaac-func-prefix:\s([a-z]+)/' $<) \
		-o $(BUILD_DIR)/$(shell basename $< .y).tab.c $(YAAC_FLAGS) -d $<

.PHONY: all toolkit $(TOOLS) clean %_prehook %_distclean %_clean %_install tag tags cscope
.FORCE:
.DEFAULT_GOAL := all
.DEFAULT:
.IGNORE: %_clean_custom %_install_custom
.NOTPARALLEL: $(TOOLS)

NCONF_FILES = ether.conf tcp.conf udp.conf oui.conf geoip.conf

all: build_showinfo toolkit
allbutcurvetun: $(filter-out curvetun,$(TOOLS))
allbutmausezahn: $(filter-out mausezahn,$(TOOLS))
toolkit: $(TOOLS)
install: install_all
install_all: $(foreach tool,$(TOOLS),$(tool)_install)
install_allbutcurvetun: $(foreach tool,$(filter-out curvetun,$(TOOLS)),$(tool)_install)
install_allbutmausezahn: $(foreach tool,$(filter-out mausezahn,$(TOOLS)),$(tool)_install)
clean mostlyclean: $(foreach tool,$(TOOLS),$(tool)_clean)
realclean distclean clobber: $(foreach tool,$(TOOLS),$(tool)_distclean)
	$(Q)$(call RMDIR,$(ETCDIRE))
mrproper: clean distclean
	$(Q)$(GIT_REM)

define TOOL_templ
  include $(1)/Makefile
  $(1) $(1)%: BUILD_DIR := $(1)
  $(1)_prehook:
	$(Q)echo "$(bold)$(WHAT) $(1):$(normal)"
  $(1): $(1)_prehook $$($(1)-lex) $$($(1)-yaac) $$(patsubst %.o,$(1)/%.o,$$($(1)-objs))
  $(1)_clean: $(1)_clean_custom
	$(Q)$$(call RM,$(1)/*.o $(1)/$(1))
  $(1)_install: $(1)_install_custom
	$(Q)$$(call INSTX,$(1)/$(1),$$(SBINDIR))
  $(1)_distclean: $(1)_distclean_custom
	$(Q)$$(call RM,$$(SBINDIR)/$(1))
  $(1)/%.yy.o: $(1)/%.yy.c
	$$(CC) $$(ALL_CFLAGS) -o $$@ -c $$<
  $(1)/%.tab.o: $(1)/%.tab.c
	$$(CC) $$(ALL_CFLAGS) -o $$@ -c $$<
  $(1)/%.o: %.c
	$$(CC) $$(ALL_CFLAGS) -o $(1)/$$(shell basename $$@) -c $$<
endef

$(foreach tool,$(TOOLS),$(eval $(call TOOL_templ,$(tool))))

%:: ;

netsniff-ng: ALL_CFLAGS += $(shell pkg-config --cflags libnl-3.0) $(shell pkg-config --cflags libnl-genl-3.0) -D__WITH_PROTOS -D__WITH_TCPDUMP_LIKE_FILTER
trafgen: ALL_CFLAGS += -I.. $(shell pkg-config --cflags libnl-3.0) $(shell pkg-config --cflags libnl-genl-3.0) -D__WITH_PROTOS
ifpps: ALL_CFLAGS += $(shell pkg-config --cflags ncurses)
flowtop: ALL_CFLAGS += $(shell pkg-config --cflags ncurses)
bpfc: ALL_CFLAGS += -I..
curvetun: ALL_CFLAGS += -I ${NACL_INC_DIR}
curvetun: ALL_LDFLAGS += -L ${NACL_LIB_DIR}
# This gets some extra treatment here until the code looks properly
mausezahn: ALL_CFLAGS = -O2 -I. -I.. -DVERSION_STRING=\"$(VERSION_STRING)\" -DPREFIX_STRING=\"$(PREFIX)\"

bpfc_clean_custom:
	$(Q)$(call RM,$(BUILD_DIR)/*.h $(BUILD_DIR)/*.c)
trafgen_clean_custom:
	$(Q)$(call RM,$(BUILD_DIR)/*.h $(BUILD_DIR)/*.c)
netsniff-ng_distclean_custom flowtop_distclean_custom:
	$(Q)$(foreach file,$(NCONF_FILES),$(call RM,$(ETCDIRE)/$(file));)
	$(Q)$(call RMDIR,$(ETCDIRE))
trafgen_distclean_custom:
	$(Q)$(call RM,$(ETCDIRE)/stddef.h)
	$(Q)$(call RMDIR,$(ETCDIRE))
astraceroute_distclean_custom:
	$(Q)$(call RM,$(ETCDIRE)/geoip.conf)
	$(Q)$(call RMDIR,$(ETCDIRE))

netsniff-ng_install_custom flowtop_install_custom:
	$(Q)$(foreach file,$(NCONF_FILES),$(call INST,$(file),$(ETCDIRE));)
trafgen_install_custom:
	$(Q)$(call INST,trafgen_stddef.h,$(ETCDIRE))
	$(Q)ln -fs $(ETCDIRE)/trafgen_stddef.h $(ETCDIRE)/stddef.h
astraceroute_install_custom:
	$(Q)$(call INST,geoip.conf,$(ETCDIRE))

$(TOOLS):
	$(LD) $(ALL_LDFLAGS) -o $@/$@ $@/*.o $($@-libs)
	$(STRIP) $@/$@

nacl:
	$(Q)echo "$(bold)$(WHAT) $@:$(normal)"
	$(Q)cd curvetun/ && ./nacl_build.sh ~/nacl
	$(Q)source ~/.bashrc

tarball.gz:  ; $(call GIT_ARCHIVE,gzip,gz)
tarball.bz2: ; $(call GIT_ARCHIVE,bzip2,bz2)
tarball.xz:  ; $(call GIT_ARCHIVE,xz,xz)
tarball: tarball.gz tarball.bz2 tarball.xz

tag:
	$(GIT_TAG)

announcement:
	$(Q)echo -e "netsniff-ng $(VERSION_STRING) has been released to the public (http://netsniff-ng.org/).\n" > .MAIL_MSG
	$(Q)echo -e "It can be fetched via Git, through:\n" >> .MAIL_MSG
	$(Q)echo -e "   git clone git://github.com/borkmann/netsniff-ng.git" >> .MAIL_MSG
	$(Q)echo -e "   git checkout $(VERSION_STRING)\n" >> .MAIL_MSG
	$(Q)echo -e "Or via HTTP, through:\n" >> .MAIL_MSG
	$(Q)echo -e "   wget http://pub.netsniff-ng.org/netsniff-ng/netsniff-ng-$(VERSION_STRING).tar.gz\n" >> .MAIL_MSG
	$(Q)echo -e "The release be verified via Git, through (see README):\n" >> .MAIL_MSG
	$(Q)echo -e "   git tag -v $(VERSION_STRING)\n" >> .MAIL_MSG
	$(Q)echo -e "Major high-level changes since the last release are:\n" >> .MAIL_MSG
	$(Q)echo -e "   *** BLURB HERE ***\n" >> .MAIL_MSG
	$(Q)echo -e "Contributors since last release:\n" >> .MAIL_MSG
	$(GIT_PEOPLE) >> .MAIL_MSG
	$(Q)echo -e "Git changelog since the last release:\n" >> .MAIL_MSG
	$(GIT_LOG) >> .MAIL_MSG

release: announcement tag tarball
	$(Q)echo "Released $(bold)$(VERSION_STRING)$(normal)"

FIND_SOURCE_FILES = ( git ls-files '*.[hcS]' 2>/dev/null || \
			find . \( -name .git -type d -prune \) \
				-o \( -name '*.[hcS]' -type f -print \) )

tags ctags:
	$(Q)$(call RM,tags)
	$(FIND_SOURCE_FILES) | xargs ctags -a

cscope:
	$(Q)$(call RM,cscope*)
	$(FIND_SOURCE_FILES) | xargs cscope -b

help:
	$(Q)echo "$(bold)Available tools from the toolkit:$(normal)"
	$(Q)echo " <toolnames>:={$(TOOLS)}"
	$(Q)echo "$(bold)Targets for building the toolkit:$(normal)"
	$(Q)echo " all|toolkit                  - Build the whole toolkit"
	$(Q)echo " allbutcurvetun               - Build all except curvetun"
	$(Q)echo " allbutmausezahn              - Build all except mausezahn"
	$(Q)echo " <toolname>                   - Build only one of the tools"
	$(Q)echo "$(bold)Targets for cleaning the toolkit's build files:$(normal)"
	$(Q)echo " clean|mostlyclean            - Remove all build files"
	$(Q)echo " <toolname>_clean             - Remove only one of the tool's files"
	$(Q)echo "$(bold)Targets for installing the toolkit:$(normal)"
	$(Q)echo " install                      - Install the whole toolkit"
	$(Q)echo " <toolname>_install           - Install only one of the tools"
	$(Q)echo "$(bold)Targets for removing the toolkit:$(normal)"
	$(Q)echo " realclean|distclean|clobber  - Remove the whole toolkit from the system"
	$(Q)echo " <toolname>_distclean         - Remove only one of the tools"
	$(Q)echo " mrproper                     - Remove build and install files"
	$(Q)echo "$(bold)Hacking/development targets:$(normal)"
	$(Q)echo " tag                          - Generate Git tag of current version"
	$(Q)echo " tarball                      - Generate tarball of latest version"
	$(Q)echo " release                      - Generate a new release"
	$(Q)echo " tags                         - Generate sparse ctags"
	$(Q)echo " cscope                       - Generate cscope files"
	$(Q)echo "$(bold)Misc targets:$(normal)"
	$(Q)echo " nacl                         - Execute the build_nacl script"
	$(Q)echo " help                         - Show this help"
	$(Q)echo "$(bold)Available parameters:$(normal)"
	$(Q)echo " DEBUG=1                      - Enable debugging"
	$(Q)echo " PREFIX=/path                 - Install path prefix"
	$(Q)echo " CROSS_COMPILE=/path-prefix   - Kernel-like cross-compiling prefix"
	$(Q)echo " CROSS_LD_LIBRARY_PATH=/path  - Library search path for cross-compiling"
	$(Q)echo " CC=cgcc                      - Use sparse compiler wrapper"
	$(Q)echo " CFLAGS="-O2 -Wall"           - Overwrite CFLAGS for compilation"
	$(Q)echo " CCACHE=                      - Do not use ccache for compilation"
	$(Q)echo " Q=                           - Show verbose garbage"