1#!/bin/sh
2#
3# p0f - build script
4# ------------------
5#
6# Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>
7#
8# Distributed under the terms and conditions of GNU LGPL.
9#
10
11PROGNAME="p0f"
12VERSION="3.09b"
13
14test "$CC" = "" && CC="gcc"
15
16BASIC_CFLAGS="-Wall -Wno-format -I/usr/local/include/ \
17              -I/opt/local/include/ -DVERSION=\"$VERSION\" $CFLAGS"
18
19BASIC_LDFLAGS="-L/usr/local/lib/ -L/opt/local/lib $LDFLAGS"
20
21USE_CFLAGS="-fstack-protector-all -fPIE -D_FORTIFY_SOURCE=2 -g -ggdb \
22            $BASIC_CFLAGS"
23
24USE_LDFLAGS="-Wl,-z,relro -pie $BASIC_LDFLAGS"
25
26if [ "$OSTYPE" = "cygwin" ]; then
27  USE_LIBS="-lwpcap $LIBS"
28elif [ "$OSTYPE" = "solaris" ]; then
29  USE_LIBS="-lsocket -lnsl $LIBS"
30else
31  USE_LIBS="-lpcap $LIBS"
32fi
33
34OBJFILES="api.c process.c fp_tcp.c fp_mtu.c fp_http.c readfp.c"
35
36echo "Welcome to the build script for $PROGNAME $VERSION!"
37echo "Copyright (C) 2012 by Michal Zalewski <lcamtuf@coredump.cx>"
38echo
39
40if [ "$#" -gt "1" ]; then
41
42  echo "[-] Please specify one build target at a time."
43  exit 1
44
45fi
46
47if [ "$1" = "clean" -o "$1" = "publish" ]; then
48
49  echo "[*] Cleaning up build environment..."
50  rm -f -- "$PROGNAME" *.exe *.o a.out *~ core core.[1-9][0-9]* *.stackdump COMPILER-WARNINGS 2>/dev/null
51
52  ( cd tools && make clean ) &>/dev/null
53
54  if [ "$1" = "publish" ]; then
55
56    if [ ! "`basename -- \"$PWD\"`" = "$PROGNAME" ]; then
57      echo "[-] Invalid working directory."
58      exit 1
59    fi
60
61    if [ ! "$HOSTNAME" = "raccoon" ]; then
62      echo "[-] You are not my real dad!"
63      exit 1
64    fi
65
66    TARGET="/var/www/lcamtuf/p0f3/$PROGNAME-devel.tgz"
67
68    echo "[*] Creating $TARGET..."
69
70    cd ..
71    rm -rf "$PROGNAME-$VERSION"
72    cp -pr "$PROGNAME" "$PROGNAME-$VERSION"
73    tar cfvz "$TARGET" "$PROGNAME-$VERSION"
74
75  fi
76
77  echo "[+] All done!"
78
79  exit 0
80
81elif [ "$1" = "all" -o "$1" = "" ]; then
82
83  echo "[+] Configuring production build."
84  BASIC_CFLAGS="$BASIC_CFLAGS -O3"
85  USE_CFLAGS="$USE_CFLAGS -O3"
86
87elif [ "$1" = "debug" ]; then
88
89  echo "[+] Configuring debug build."
90  BASIC_CFLAGS="$BASIC_CFLAGS -DDEBUG_BUILD=1"
91  USE_CFLAGS="$USE_CFLAGS -DDEBUG_BUILD=1"
92
93else
94
95  echo "[-] Unrecognized build target '$1', sorry."
96  exit 1
97
98fi
99
100rm -f COMPILER-WARNINGS 2>/dev/null
101
102echo -n "[*] Checking for a sane build environment... "
103
104if ls -ld ./ | grep -q '^d.......w'; then
105
106  echo "FAIL (bad permissions)"
107  echo
108  echo "Duuude, don't build stuff in world-writable directories."
109  echo
110  exit 1
111
112fi
113
114TMP=".build-$$"
115
116rm -f "$TMP" 2>/dev/null
117
118if [ -f "$TMP" ]; then
119
120  echo "FAIL (can't delete)"
121  echo
122  echo "Check directory permissions and try again."
123  echo
124  exit 1
125
126fi
127
128touch "$TMP" 2>/dev/null
129
130if [ ! -f "$TMP" ]; then
131
132  echo "FAIL (can't create)"
133  echo
134  echo "Check directory permissions and try again."
135  echo
136  exit 1
137
138fi
139
140if [ ! -s "$PROGNAME.c" ]; then
141
142  echo "FAIL (no source)"
143  echo
144  echo "I'm no doctor, but I think the source code is missing from CWD."
145  echo
146  exit 1
147
148fi
149
150echo "OK"
151
152echo -n "[*] Checking for working GCC... "
153
154rm -f "$TMP" || exit 1
155
156echo "int main() { return 0; }" >"$TMP.c" || exit 1
157$CC $BASIC_CFLAGS $BASIC_LDFLAGS "$TMP.c" -o "$TMP" >"$TMP.log" 2>&1
158
159if [ ! -x "$TMP" ]; then
160
161  echo "FAIL"
162  echo
163  echo "Your compiler can't produce working binaries. You need a functioning install of"
164  echo "GCC and libc (including development headers) to continue. If you have these,"
165  echo "try setting CC, CFLAGS, and LDFLAGS appropriately."
166  echo
167  echo "Output from an attempt to execute GCC:"
168  cat "$TMP.log" | head -10
169  echo
170  rm -f "$TMP" "$TMP.log" "$TMP.c"
171  exit 1
172
173fi
174
175echo "OK"
176
177echo -n "[*] Checking for *modern* GCC... "
178
179rm -f "$TMP" "$TMP.c" "$TMP.log" || exit 1
180
181echo "int main() { return 0; }" >"$TMP.c" || exit 1
182$CC $USE_CFLAGS $USE_LDFLAGS "$TMP.c" -o "$TMP" >"$TMP.log" 2>&1
183
184if [ ! -x "$TMP" ]; then
185
186  echo "FAIL (but we can live with it)"
187  USE_CFLAGS="$BASIC_CFLAGS"
188  USE_LDFLAGS="$BASIC_LDFLAGS"
189
190else
191
192  echo "OK"
193
194fi
195
196echo -n "[*] Checking if memory alignment is required... "
197
198rm -f "$TMP" "$TMP.c" "$TMP.log" || exit 1
199
200echo -e "#include \"types.h\"\nvolatile u8 tmp[6]; int main() { printf(\"%d\x5cn\", *(u32*)(tmp+1)); return 0; }" >"$TMP.c" || exit 1
201$CC $USE_CFLAGS $USE_LDFLAGS "$TMP.c" -o "$TMP" >"$TMP.log" 2>&1
202
203if [ ! -x "$TMP" ]; then
204
205  echo "FAIL"
206  echo
207  echo "Well, something went horribly wrong, sorry. Here's the output from GCC:"
208  echo
209  cat "$TMP.log"
210  echo
211  echo "Sorry! You may want to ping <lcamtuf@coredump.cx> about this."
212  echo
213  rm -f "$TMP.log"
214  exit 1
215
216else
217
218  ulimit -c 0 >/dev/null 2>&1
219  ./"$TMP" >/dev/null 2>&1
220
221  if [ "$?" = "0" ]; then
222
223    echo "nope"
224
225  else
226
227    echo "yes"
228    USE_CFLAGS="$USE_CFLAGS -DALIGN_ACCESS=1"
229
230  fi
231
232fi
233
234
235echo -n "[*] Checking for working libpcap... "
236
237rm -f "$TMP" "$TMP.c" "$TMP.log" || exit 1
238
239echo -e "#include <pcap.h>\nint main() { char i[PCAP_ERRBUF_SIZE]; pcap_lookupdev(i); return 0; }" >"$TMP.c" || exit 1
240$CC $USE_CFLAGS $USE_LDFLAGS "$TMP.c" -o "$TMP" $USE_LIBS >"$TMP.log" 2>&1
241
242if [ ! -x "$TMP" ]; then
243  echo "FAIL"
244  echo
245
246  if [ "$OSTYPE" = "cygwin" ]; then
247
248    echo "You need a functioning install of winpcap. Download both of those:"
249    echo
250    echo "  Main library    : http://www.winpcap.org/install/default.htm"
251    echo "  Developer tools : http://www.winpcap.org/devel.htm"
252    echo
253    echo "Under cygwin, copy the contents of wpdpack/include to /usr/include/, and"
254    echo "wpdpack/lib to /lib/. At that point, you should be able to build p0f."
255    echo
256
257  else
258
259    echo "You need a functioning installation of libpcap (including development headers)."
260    echo "You can download it from here:"
261    echo
262    echo "  http://www.tcpdump.org/#latest-release"
263    echo
264
265  fi
266
267  echo "If you have the library installed at an unorthodox location, try setting CFLAGS"
268  echo "and LDFLAGS to point us in the right direction."
269  echo
270  echo "Output from an attempt to compile sample program:"
271  cat "$TMP.log" | head -10
272  echo
273  rm -f "$TMP" "$TMP.log" "$TMP.c"
274  exit 1
275
276fi
277
278echo "OK"
279
280echo -n "[*] Checking for working BPF... "
281
282rm -f "$TMP" "$TMP.c" "$TMP.log" || exit 1
283
284echo -e "#include <pcap.h>\n#include <pcap-bpf.h>\nint main() { return 0; }" >"$TMP.c" || exit 1
285$CC $USE_CFLAGS $USE_LDFLAGS "$TMP.c" -o "$TMP" $USE_LIBS >"$TMP.log" 2>&1
286
287if [ ! -x "$TMP" ]; then
288
289  rm -f "$TMP" "$TMP.c" "$TMP.log" || exit 1
290
291  echo -e "#include <pcap.h>\n#include <net/bpf.h>\nint main() { return 0; }" >"$TMP.c" || exit 1
292  $CC $USE_CFLAGS $USE_LDFLAGS "$TMP.c" -o "$TMP" $USE_LIBS >"$TMP.log" 2>&1
293
294  if [ ! -x "$TMP" ]; then
295    echo "FAIL"
296    echo
297    echo "Could not find a working version of pcap-bpf.h or net/bpf.h on your system."
298    echo "If it's available in a non-standard directory, set CFLAGS accordingly; if it"
299    echo "lives under a different name, you may need to edit the source and recompile."
300    echo
301
302    rm -f "$TMP" "$TMP.log" "$TMP.c"
303    exit 1
304
305  fi
306
307  USE_CFLAGS="$USE_CFLAGS -DNET_BPF=1"
308
309fi
310
311echo "OK"
312
313rm -f "$TMP" "$TMP.log" "$TMP.c" || exit 1
314
315echo "[+] Okay, you seem to be good to go. Fingers crossed!"
316
317echo -n "[*] Compiling $PROGNAME... "
318
319rm -f "$PROGNAME" || exit 1
320
321$CC $USE_CFLAGS $USE_LDFLAGS "$PROGNAME.c" $OBJFILES -o "$PROGNAME" $USE_LIBS >"$TMP.log" 2>&1
322
323if [ ! -x "$PROGNAME" ]; then
324
325  echo "FAIL"
326  echo
327  echo "Well, something went horribly wrong, sorry. Here's the output from GCC:"
328  echo
329  cat "$TMP.log"
330  echo
331  echo "Sorry! You may want to ping <lcamtuf@coredump.cx> about this."
332  echo
333  rm -f "$TMP.log"
334  exit 1
335
336fi
337
338if [ -s "$TMP.log" ]; then
339
340  echo "OK (see COMPILER-WARNINGS)"
341  mv "$TMP.log" COMPILER-WARNINGS
342
343  test "$1" = "debug" && cat COMPILER-WARNINGS
344
345else
346
347  rm -f "$TMP.log"
348  echo "OK"
349
350fi
351
352echo "[*] Compiling tools: "
353cd tools && make
354
355echo
356echo "Well, that's it. Be sure to review README. If you run into any problems, you"
357echo "can reach the author at <lcamtuf@coredump.cx>."
358echo
359
360exit 0
361