1#					       -*- Autoconf -*-
2# Process this file with autoconf to produce a configure script.
3
4AC_PREREQ([2.63])
5AC_INIT([openfortivpn], [1.17.1])
6AC_CONFIG_SRCDIR([src/main.c])
7AM_INIT_AUTOMAKE([foreign subdir-objects])
8
9# Checks for programs.
10AC_PROG_CC
11AC_PROG_CC_STDC
12AC_PROG_MKDIR_P
13AC_PROG_SED
14AC_PROG_INSTALL
15AC_USE_SYSTEM_EXTENSIONS
16m4_ifndef([PKG_PROG_PKG_CONFIG], [m4_fatal([Please install pkg-config.])])
17PKG_PROG_PKG_CONFIG
18
19REVISION=""
20AS_IF([test -d .git], [
21	AC_PATH_PROG(GIT, [git], [""], "$PATH:/sbin:/usr/sbin")
22	AS_IF([test "x$GIT" != "x"], [
23		REVISION=`$GIT describe --tags | sed -e 's/-/+git/;y/-/./'`
24	])
25])
26AS_IF([test "x$REVISION" = "x"], [
27	REVISION="unavailable"
28])
29
30AC_SUBST(REVISION)
31
32m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])])
33
34# Checks for libraries.
35PKG_CHECK_MODULES(OPENSSL, [libssl >= 0.9.8 libcrypto >= 0.9.8], [], [AC_MSG_ERROR([Cannot find OpenSSL 0.9.8 or higher.])])
36AC_CHECK_LIB([pthread], [pthread_create], [], [AC_MSG_ERROR([Cannot find libpthread.])])
37AC_CHECK_LIB([util], [forkpty], [], [AC_MSG_ERROR([Cannot find libutil.])])
38PKG_CHECK_MODULES(LIBSYSTEMD, [libsystemd], [AC_DEFINE(HAVE_SYSTEMD)], [AC_MSG_RESULT([libsystemd not present])])
39
40# we assume presence of the following C standard headers
41# and omit them in the following header checks
42#
43# assert.h
44# ctype.h
45# errno.h
46# limits.h
47# signal.h
48# stdarg.h
49# stddef.h
50# stdint.h
51# stdio.h
52# stdlib.h
53# string.h
54
55# Checks for required header files.
56AC_CHECK_HEADERS([ \
57arpa/inet.h \
58fcntl.h \
59getopt.h \
60ifaddrs.h \
61netdb.h \
62net/if.h \
63netinet/in.h \
64netinet/tcp.h \
65pthread.h \
66strings.h \
67sys/ioctl.h \
68syslog.h \
69sys/socket.h \
70sys/stat.h \
71sys/types.h \
72sys/wait.h \
73termios.h \
74unistd.h \
75], [], AC_MSG_ERROR([Required header not found]))
76
77# Checks for header files with prerequisites of other headers.
78AC_CHECK_HEADERS([net/route.h], [], AC_MSG_ERROR([Required header not found]), [#include <net/if.h>])
79
80# Checks for optional header files.
81AC_CHECK_HEADERS([ \
82libutil.h \
83mach/mach.h \
84pty.h \
85semaphore.h \
86util.h \
87])
88
89# Checks for optional header files with prerequisites of other headers.
90AC_CHECK_HEADERS([net/if_var.h],[],[],[#include <net/if.h>])
91
92# Checks for typedefs, structures, and compiler characteristics.
93AC_C_CONST
94AC_C_INLINE
95AC_C_VOLATILE
96AC_TYPE_OFF_T
97AC_TYPE_PID_T
98AC_TYPE_SIZE_T
99AC_TYPE_SSIZE_T
100AC_TYPE_UINT16_T
101AC_TYPE_UINT32_T
102AC_TYPE_UINT8_T
103AC_CHECK_TYPES([struct termios], [], [], [#include <termios.h>])
104
105# Checks for library functions.
106AC_CHECK_FUNCS([ \
107access \
108close \
109connect \
110execv \
111_exit \
112fcntl \
113fileno \
114forkpty \
115freeaddrinfo \
116freeifaddrs \
117gai_strerror \
118getaddrinfo \
119geteuid \
120getifaddrs \
121getopt_long \
122htons \
123inet_addr \
124inet_ntoa \
125ioctl \
126isatty \
127memmem \
128ntohs \
129open \
130openlog \
131pclose \
132popen \
133pthread_cancel \
134pthread_cond_init \
135pthread_cond_signal \
136pthread_cond_wait \
137pthread_create \
138pthread_join \
139pthread_mutexattr_init \
140pthread_mutex_destroy \
141pthread_mutex_init \
142pthread_mutex_lock \
143pthread_mutex_unlock \
144pthread_self \
145pthread_sigmask \
146read \
147select \
148sem_destroy \
149sem_init \
150sem_post \
151sem_wait \
152setenv \
153setsockopt \
154sigaddset \
155sigemptyset \
156sleep \
157socket \
158strcasecmp \
159strdup \
160strncasecmp \
161strsignal \
162strtok_r \
163syslog \
164tcgetattr \
165tcsetattr \
166usleep \
167vsyslog \
168waitpid \
169write \
170], [], AC_MSG_ERROR([Required function not found]))
171
172# Checks for optional functions.
173AC_CHECK_FUNCS([pthread_mutexattr_setrobust])
174# Use PKG_CHECK_MODULES compiler/linker flags
175save_openssl_CPPFLAGS="${CPPFLAGS}"
176save_openssl_LIBS="${LIBS}"
177CPPFLAGS="${OPENSSL_CFLAGS} ${CPPFLAGS}"
178LIBS="${OPENSSL_LIBS} ${LIBS}"
179AC_CHECK_FUNCS([X509_check_host])
180CPPFLAGS="${save_openssl_CPPFLAGS}"
181LIBS="${save_openssl_LIBS}"
182
183# Specialised checks for particular features.
184# When cross compile, don't run the tests.
185AC_ARG_WITH([rt_dst],
186	AS_HELP_STRING([--with-rt_dst],
187		       [disable rtentry with rt_dst testing (for linux target when cross compile)]),
188	AS_IF([test "x$with_rt_dst" = "xyes"],[
189		AC_MSG_NOTICE([HAVE_RT_ENTRY_WITH_RT_DST... 1])
190		AC_DEFINE(HAVE_RT_ENTRY_WITH_RT_DST)
191	])
192)
193AS_IF([test "x$with_rt_dst" = "x"], [
194AC_MSG_CHECKING(whether rtentry is available and has rt_dst)
195AC_LANG(C)
196AC_COMPILE_IFELSE([AC_LANG_PROGRAM([
197#include <sys/types.h>
198#include <sys/socket.h>
199#include <net/route.h>
200static inline struct sockaddr_in *cast_addr(struct sockaddr *addr)
201{
202	return (struct sockaddr_in *) addr;
203}
204],[
205struct rtentry route;
206cast_addr(&(&route)->rt_dst)->sin_family = AF_INET;
207])],[
208	AC_DEFINE(HAVE_RT_ENTRY_WITH_RT_DST)
209	AC_MSG_RESULT(yes)
210], AC_MSG_RESULT(no))
211])
212
213NETSTAT_PATH=""
214PPP_PATH=""
215RESOLVCONF_PATH=""
216
217# prepare possibility to override default locations
218AC_ARG_WITH([netstat],
219	AS_HELP_STRING([--with-netstat],
220		       [set the path to the netstat executable on MacOSX or FreeBSD]),
221	NETSTAT_PATH="$withval"
222)
223# this is for the pppd daemon executable
224AC_ARG_WITH([pppd],
225	AS_HELP_STRING([--with-pppd],
226		       [set the path to the pppd daemon executable]),
227	AS_IF([test ! "x$with_pppd" = "xno" -a ! "x$with_pppd" = "xyes"],[
228		PPP_PATH="$withval"
229		with_pppd="yes"
230		with_ppp="no"
231	])
232)
233# and this is for the ppp user space client on FreeBSD
234AC_ARG_WITH([ppp],
235	AS_HELP_STRING([--with-ppp],
236		       [set the path to the ppp userspace client on FreeBSD]),
237	AS_IF([test ! "x$with_ppp" = "xno" -a ! "x$with_ppp" = "xyes"],[
238		PPP_PATH="$withval"
239		with_ppp="yes"
240		with_pppd="no"
241	])
242)
243
244# override for /proc/net/route detection
245AC_ARG_ENABLE([proc],
246	AS_HELP_STRING([--enable-proc],
247		       [enable route manipulations directly via /proc/net/route \
248			when cross-compiling, use --disable-proc for the opposite]))
249
250# check for netstat if not cross-compiling
251AS_IF([test "x$enable_proc" = "x"], [
252	AC_CHECK_FILE([/proc/net/route],[
253		AS_IF([test "x$enable_proc" = "x"], [
254			enable_proc="yes"
255		])
256	],[
257		AS_IF([test "x$NETSTAT_PATH" = "x"], [
258			AC_CHECK_FILE([/usr/sbin/netstat],[
259				NETSTAT_PATH="/usr/sbin/netstat"
260			],[
261				AC_CHECK_FILE([/usr/bin/netstat],[
262					NETSTAT_PATH="/usr/bin/netstat"
263				],[])
264			])
265		])
266	])
267])
268
269# check for ppp if not specified
270AC_PATH_PROG(PPP, [ppp], [/usr/sbin/ppp], "$PATH:/sbin:/usr/sbin")
271AS_IF([test "x$PPP_PATH" = "x"], [
272	AC_CHECK_FILE([$PPP], [
273		AS_IF([test "x$PPP_PATH" = "x"], [
274			PPP_PATH="$PPP"
275		])
276		AS_IF([test "x$with_ppp" = "x"], [
277			with_ppp="yes"
278		])
279	],[])
280])
281# check for pppd if not specified
282AC_PATH_PROG(PPPD, [pppd], [/usr/sbin/pppd], "$PATH:/sbin:/usr/sbin")
283AS_IF([test "x$PPP_PATH" = "x"], [
284	AC_CHECK_FILE([$PPPD], [
285		AS_IF([test "x$PPP_PATH" = "x"], [
286			PPP_PATH="$PPPD"
287		])
288		AS_IF([test "x$with_pppd" = "x"], [
289			with_pppd="yes"
290		])
291	],[])
292])
293# when neither ppp nor pppd are enabled fall back to a sensible choice for the platform
294AS_IF([test "x$with_ppp" = "x" -a "x$with_pppd" = "x"], [
295	AS_IF([test "x$(uname)" = "xDragonFly"], [
296		with_ppp="yes"
297		PPP_PATH="/usr/sbin/ppp"
298	], [
299		with_pppd="yes"
300		PPP_PATH="/usr/sbin/pppd"
301	])
302])
303# when both are enabled, give pppd the higher priority (we can only use one of them)
304AS_IF([test "x$with_ppp" = "xyes" -a "x$with_pppd" = "xyes"], [
305	with_ppp="no"
306])
307# replace empty settings with "no"
308AS_IF([test "x$with_pppd" = "x"], [
309	with_pppd="no"
310])
311AS_IF([test "x$with_ppp" = "x"], [
312	with_ppp="no"
313])
314
315AS_IF([test "x$with_ppp" = "xyes"], [
316	AC_DEFINE(HAVE_USR_SBIN_PPP, 1)
317	AC_MSG_NOTICE([HAVE_USR_SBIN_PPP... 1])
318],[
319	AC_DEFINE(HAVE_USR_SBIN_PPP, 0)
320	AC_MSG_NOTICE([HAVE_USR_SBIN_PPP... 0])
321])
322AS_IF([test "x$with_pppd" = "xyes"], [
323	AC_DEFINE(HAVE_USR_SBIN_PPPD, 1)
324	AC_MSG_NOTICE([HAVE_USR_SBIN_PPPD... 1])
325],[
326	AC_DEFINE(HAVE_USR_SBIN_PPPD, 0)
327	AC_MSG_NOTICE([HAVE_USR_SBIN_PPPD... 0])
328])
329AS_IF([test "x$enable_proc" = "xyes"], [
330	AC_DEFINE(HAVE_PROC_NET_ROUTE, 1)
331	AC_MSG_NOTICE([HAVE_PROC_NET_ROUTE... 1])
332],[
333	AC_DEFINE(HAVE_PROC_NET_ROUTE, 0)
334	AC_MSG_NOTICE([HAVE_PROC_NET_ROUTE... 0])
335])
336
337AC_SUBST(PPP_PATH)
338AC_MSG_NOTICE([PPP_PATH...] $PPP_PATH)
339
340AC_SUBST(NETSTAT_PATH)
341AS_IF([test "x$NETSTAT_PATH" != "x"], [
342	AC_MSG_NOTICE([NETSTAT_PATH...] $NETSTAT_PATH)
343])
344
345# use resolvconf if present
346AC_PATH_PROG(RESOLVCONF_PATH, [resolvconf], [DISABLED], "$PATH:/sbin:/usr/sbin")
347
348# allow override at configure time
349AC_ARG_WITH([resolvconf],
350	AS_HELP_STRING([--with-resolvconf],
351		       [Set the path to the resolvconf executable. \
352			Set this to "DISABLED" to fully disable resolvconf support. \
353			In that case it will not be compiled in and therefore be \
354			unavailable at runtime.]),
355	RESOLVCONF_PATH="$withval"
356)
357
358AC_SUBST(RESOLVCONF_PATH)
359AS_IF([test "x$RESOLVCONF_PATH" != "x"], [
360	AC_MSG_NOTICE([RESOLVCONF_PATH...] $RESOLVCONF_PATH)
361])
362AS_IF([test "x$RESOLVCONF_PATH" = "xDISABLED"], [
363	AC_DEFINE(HAVE_RESOLVCONF, 0)
364	AC_MSG_NOTICE([HAVE_RESOLVCONF... 0])
365],[
366	AC_DEFINE(HAVE_RESOLVCONF, 1)
367	AC_MSG_NOTICE([HAVE_RESOLVCONF... 1])
368])
369
370# the default for the --use-resolvconf runtime command line option
371AC_ARG_ENABLE([resolvconf],
372	AS_HELP_STRING([--enable-resolvconf],
373		       [Enable usage of resolvconf at runtime by default. \
374			Use --disable-resolvconf for the opposite, note that \
375			resolvconf support will still be compilled in, but \
376			disabled if not explicitly enabled at runtime.]))
377
378# Determine how resolvconf works at build-time if it is installed:
379# * openresolv supports option -l that lists active configurations and returns 0
380# * resolvconf in Ubuntu/Debian does not support listing but returns 99
381#   if invoked without parameters
382# * skip resolvectl which does not work as expected when invoked as resolveconf
383AS_IF([test "x$enable_resolvconf" = "x" -a "x$RESOLVCONF_PATH" != "xDISABLED"], [
384	AC_CHECK_FILE([$RESOLVCONF_PATH],[
385		AS_IF([$RESOLVCONF_PATH -l >/dev/null 2>/dev/null], [
386			enable_resolvconf="yes"
387		],[
388			AS_IF([$RESOLVCONF_PATH  >/dev/null 2>/dev/null ; test $? -eq 99], [
389				enable_resolvconf="yes"
390			],[
391				enable_resolvconf="no"
392			])
393		])
394	],[
395		enable_resolvconf="no"
396	])
397])
398
399AS_IF([test "x$enable_resolvconf" = "xyes"], [
400	AC_DEFINE(USE_RESOLVCONF, 1)
401	AC_MSG_NOTICE([USE_RESOLVCONF... 1])
402],[
403	AC_DEFINE(USE_RESOLVCONF, 0)
404	AC_MSG_NOTICE([USE_RESOLVCONF... 0])
405])
406
407# install systemd service file
408AC_ARG_WITH([systemdsystemunitdir],
409     [AS_HELP_STRING([--with-systemdsystemunitdir=DIR], [directory for systemd service files])],,
410     [with_systemdsystemunitdir=auto])
411AS_IF([test "x$with_systemdsystemunitdir" = "xyes" -o "x$with_systemdsystemunitdir" = "xauto"], [
412     def_systemdsystemunitdir=$($PKG_CONFIG --variable=systemdsystemunitdir systemd)
413
414     AS_IF([test "x$def_systemdsystemunitdir" = "x"],
415   [AS_IF([test "x$with_systemdsystemunitdir" = "xyes"],
416    [AC_MSG_ERROR([systemd support requested but pkg-config unable to query systemd package])])
417    with_systemdsystemunitdir=no],
418   [with_systemdsystemunitdir="$def_systemdsystemunitdir"])])
419AS_IF([test "x$with_systemdsystemunitdir" != "xno"],
420      [AC_SUBST([systemdsystemunitdir], [$with_systemdsystemunitdir])])
421AM_CONDITIONAL([HAVE_SYSTEMD], [test "x$with_systemdsystemunitdir" != "xno"])
422
423AC_COMPILE_IFELSE([AC_LANG_SOURCE([
424#include <sys/types.h>
425#include <sys/socket.h>
426int main(int argc, char **argv){
427        int ret, handle;
428        handle = socket(AF_INET, SOCK_STREAM, 0);
429        ret = setsockopt(handle, SOL_SOCKET, SO_BINDTODEVICE,"lo",3);
430}
431])], [
432	AC_DEFINE(HAVE_SO_BINDTODEVICE, 1)
433	AC_MSG_NOTICE([HAVE_SO_BINDTODEVICE... 1])
434],[
435	AC_DEFINE(HAVE_SO_BINDTODEVICE, 0)
436	AC_MSG_NOTICE([HAVE_SO_BINDTODEVICE... 0])
437])
438
439
440# prepare to get rid of obsolete code (FortiOS 4)
441AC_ARG_ENABLE([obsolete],
442	[AS_HELP_STRING([--enable-obsolete], [enable support for FortiOS 4])],,
443	[enable_obsolete=no])
444AS_CASE(["$enable_obsolete"],
445	[yes], [],
446	[no], [],
447	[AC_MSG_ERROR([unknown option '$enable_obsolete' for --enable-obsolete])])
448AS_IF([test "x$enable_obsolete" = "xyes"], [AC_DEFINE([SUPPORT_OBSOLETE_CODE])])
449
450
451AC_CONFIG_COMMANDS([timestamp], [touch src/.dirstamp])
452AC_OUTPUT(Makefile)
453