diff -Nru arpon-2.7.2/AUTHOR arpon-3.0-ng+dfsg1/AUTHOR --- arpon-2.7.2/AUTHOR 2014-10-09 17:22:52.000000000 +0000 +++ arpon-3.0-ng+dfsg1/AUTHOR 2016-01-29 02:11:19.000000000 +0000 @@ -1,35 +1,7 @@ -AUTHOR: -======= - - Andrea Di Pasquale aka "spikey" +================================================================================ + AUTHOR +================================================================================ -SPECIAL THANKS: -=============== - - Giuseppe Marco Randazzo aka "zeld" - CMake support. - - - Andrea Barberio aka "insomniac" - Beta Tester. - - - Giuseppe Iuculano aka "Derevko" - Beta tester. - - - Allan Eversun aka "jigp" - Beta tester. - - - Marcio Mendes da Silva aka "Kernel" - Beta tester. - - - Andreas Moog aka "amoog" - Beta tester. - - - Andrea Vittorio aka "sark" - Beta tester. + • Andrea Di Pasquale aka "spikey" - - Mariano Graziano aka "emdel" - Old web designer. - - - Marco Fabre aka "morpe" - Old graphic designer. - - - Fabrizio Oliveri aka "bizio" - Graphic designer. + Founder and Project Leader. diff -Nru arpon-2.7.2/CHANGELOG arpon-3.0-ng+dfsg1/CHANGELOG --- arpon-2.7.2/CHANGELOG 2014-10-14 01:22:05.000000000 +0000 +++ arpon-3.0-ng+dfsg1/CHANGELOG 2016-01-29 02:11:27.000000000 +0000 @@ -1,198 +1,10 @@ -ArpON 2.7.2: -============ - ! Fixed src/arpon.c for the building on the Solaris like systems - ! Fixed CMake build environment on Solaris and DragonFly BSD operating systems supported +================================================================================ + ArpON 3.0-ng 20160129 +================================================================================ -ArpON 2.7.1: -=========== - ! Fixed src/arpon.c for the comparison of unsigned expression for sleep() and libnet_get_ipaddr4() - ! Fixed src/arpon.c for the building on the FreeBSD like systems - ! Fixed CMake build environment on all the operating systems supported - ! Fixed man8/arpon.c man page - ! Fixed img of the algorithms in the doc/ directory - ! Fixed INSTALL + • ArpON has been rewritten from scratch. -ArpON 2.7: -========== - ! Fixed the segment error in timeline thread control +================================================================================ -ArpON 2.6: -========== - + Added support of Gratuitous ARP request for Failover Cluster - + Added support of Gratuitous ARP request for Cluster with load-balancing - + Added support of Gratuitous ARP request for High-Availability (HA) Cluster +vim:ts=4:expandtab -ArpON 2.5: -========== - ! Fixed new DARPI algorithm - ! Fixed new HARPI algorithm - -ArpON 2.4: -========== - + Redesign new SARPI algorithm - + Redesign new DARPI algorithm - + Redesign new HARPI algorithm - + Added support of Gratuitous ARP reply for Failover Cluster - + Added support of Gratuitous ARP reply for Cluster with load-balancing - + Added support of Gratuitous ARP reply for High-Availability (HA) Cluster - - Removed man8/html/arpon.html and man8/html/ directory - ! Fixed help - ! Fixed CMake - ! Fixed man8/arpon.8 man page - ! Fixed algorithms in doc/ directory - -ArpON 2.3: -========== - + Added documentation section in doc/ with more examples - + Added algorithms section in doc/ - ! Fixed CMake for many controls on platforms supported - -ArpON 2.2: -========== - + Added HARPI new algorithm - + Added doc/HARPI.jpg - + Redesign general code - + Redesign general output - + Redesign SARPI, DARPI, HARPI policy for users - ! Fixed SARPI algorithm - ! Fixed DARPI algorithm and now it doesn't affect about race response time from attacks - ! Fixed thread handler of DARPI cache entries timeout - ! Fixed cmake_modules/FindPthread.cmake - ! Fixed doc/DARPI.jpg with new algorithm - ! Fixed doc/SARPI.jpg with new algorithm - ! Fixed help users - ! Fixed CMakeLists.txt - ! Fixed INSTALL - ! Fixed LICENSE - ! Fixed man8/arpon.8 - ! Fixed man8/html/arpon.html - -ArpON 2.1: -========== - + Redesign DARPI algorithm for arp request inbound and arp reply outbound - + Added delete arp cache to SARPI - ! Fixed aprintf() - ! Fixed INSTALL file - ! Fixed AUTHORS file - ! Fixed man page - ! Fixed html man page - ! Fixed DARPI and SARPI algorithms in doc directory - - Removed Makefile - -ArpON 2.0: -========== - + Redesign general code - + Redesign general output - + Added SARPI cache with rw locking - + Added SARPI cache from file option - + Added support unplug/boot/hibernation/suspension interface (OS' features too) - + Added pid file option - + Added cmake installation method - - Removed Arp sniffer, Arp ping - ! Fixed no options output - ! Fixed main with BSD option handler - ! Fixed getopt_long of missing and invalid option - ! Fixed several options names - ! Fixed aprintf with localtime integrated - ! Fixed device handler of auto and list - ! Fixed SIGINT, SIGTERM, SIGQUIT signals with POSIX signals - ! Fixed SIGHUP and SIGCONT POSIX signal for daemon reboot - ! Fixed sleep() with usleep() for thread suspend - ! Fixed rw locking in DARPI and SARPI - ! Fixed SARPI/DARPI soft real time for inbound/outbound packets - ! Fixed SARPI/DARPI Round Robin detached/joinabled scheduling threads - ! Fixed AUTHORS file - ! Fixed INSTALL file - ! Fixed Makefile file - ! Fixed man8/arpon.8 file - ! Fixed man8/html/arpon.html file - -ArpON 1.90: -=========== - + Added Static linking guide in INSTALL file - ! Fixed date structures, device, arp_header, arp_cache, darpi_cache - ! Fixed dnet bug for Linux, it returned "No such process" in arp_add() - ! Fixed dnet bug for Linux, in arp_delete() - ! Fixed makefile - -ArpON 1.80: -=========== - ! Fixed bug multithreaded in Arp reply timeout (Arp out traffic) - ! Fixed bug in aprintf() with logging mode - ! Fixed check file type for pid_file and log_file - ! Fixed bug in device automatically - ! Fixed arpon's output new style! - ! Fixed makefile - -ArpON 1.72: -=========== - + Added Linux Gentoo platform support - ! Fixed arp_cache_add(), now it works with array - ! Fixed bug in darpi, it returned "Unknown error: 0", now it works well - ! Fixed bug and output of daemon mode, now it returned 0 to shell - ! Fixed global signal handler - -ArpON 1.70: -=========== - ! Fixed bug in arp_cache_add(), it returned "No such process" from errno, now arpon works very well, have fun! =) - -ArpON 1.60: -=========== - + Added support to multiplexing handle on multi interface - + Added DARPI Cache entry timeout - + Added Linux Debian platform support - ! Fixed arpon's code style, now it is bsd coding style - ! Fixed SARPI dyagram in doc/ - ! Fixed DARPI dyagram in doc/ - ! Fixed man page and html man page - -ArpON 1.54: -=========== - ! Fixed makefile - ! Fixed network interface list errors - -ArpON 1.50: -=========== - ! Fixed Arp request Inbound bug in darpi_realtime_read_packets(), now it works very well :) - -ArpON 1.44: -=========== - + Added doc/ directory with SARPI and DARPI diagrams - + Added pid file in /var/run/arpon.pid - + Added LICENSE file - ! Adjusted man page - -ArpON 1.40: -=========== - ! Fixed CPU usage, now arpon works well on many cpu architectures, 32 and 64 bit - -ArpON 1.30: -=========== - + Added support to pthreads for all platforms - + Added real time support for BSD platforms - + Added Sanitize environment from LD_PRELOAD attacks - -ArpON 1.20: -=========== - ! Linux platform: timeout now works both for ping to host and ping to broadcast - ! Makefile now uses dynamic libraries linking - -ArpON 1.11: -=========== - + Added NetBSD platform support - + Added OpenBSD platform support - + Added man page - + Added automatic device support in many features - + Added CPU priority (TASK MODE) for real time work with nice values (-n, --nice option) for many CPU architectures (little/big endian with 32/64 bits) - + Added Logging mode (LOG MODE) (-f, --log-file and -g, --log options) - ! Linux platform: changed poll() with select() - ! Adjusted arp_ping_set_timeout() - ! Many define macro replaced by enum - ! Adjusted output style - ! Adjusted time with timezone in many features - ! Adjusted help summary page - -ArpON 1.10: -=========== - - ! First ArpON version ! diff -Nru arpon-2.7.2/cmake/modules/FindHeaders.cmake arpon-3.0-ng+dfsg1/cmake/modules/FindHeaders.cmake --- arpon-2.7.2/cmake/modules/FindHeaders.cmake 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/cmake/modules/FindHeaders.cmake 2016-01-29 01:49:20.000000000 +0000 @@ -0,0 +1,163 @@ +# +# Copyright (C) 2008-2016 Andrea Di Pasquale +# Copyright (C) 2008-2016 Giuseppe Marco Randazzo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# +# $ArpON: FindHeaders.cmake,v 3.0-ng 01/29/2016 02:49:20 spikey Exp $ +# + +include(CheckIncludeFile) + +check_include_file(net/ethernet.h HAVE_NET_ETHERNET_H) +if(NOT HAVE_NET_ETHERNET_H) + message(FATAL_ERROR "Could not find net/ethernet.h!") +endif(NOT HAVE_NET_ETHERNET_H) + +check_include_file(net/if.h HAVE_NET_IF_H) +if(NOT HAVE_NET_IF_H) + message(FATAL_ERROR "Could not find net/if.h!") +endif(NOT HAVE_NET_IF_H) + +check_include_file(net/if_arp.h HAVE_NET_IF_ARP_H) +if(NOT HAVE_NET_IF_ARP_H) + message(FATAL_ERROR "Could not find net/if_arp.h!") +endif(NOT HAVE_NET_IF_ARP_H) + +check_include_file(netinet/ether.h HAVE_NETINET_ETHER_H) +if(NOT HAVE_NETINET_ETHER_H) + message(FATAL_ERROR "Could not find netinet/ether.h!") +endif(NOT HAVE_NETINET_ETHER_H) + +check_include_file(netinet/if_ether.h HAVE_NETINET_IF_ETHER_H) +if(NOT HAVE_NETINET_IF_ETHER_H) + message(FATAL_ERROR "Could not find netinet/if_ether.h!") +endif(NOT HAVE_NETINET_IF_ETHER_H) + +check_include_file(netinet/in.h HAVE_NETINET_IN_H) +if(NOT HAVE_NETINET_IN_H) + message(FATAL_ERROR "Could not find netinet/in.h!") +endif(NOT HAVE_NETINET_IN_H) + +check_include_file(arpa/inet.h HAVE_ARPA_INET_H) +if(NOT HAVE_ARPA_INET_H) + message(FATAL_ERROR "Could not find arpa/inet.h!") +endif(NOT HAVE_ARPA_INET_H) + +check_include_file(sys/socket.h HAVE_SYS_SOCKET_H) +if(NOT HAVE_SYS_SOCKET_H) + message(FATAL_ERROR "Could not find sys/socket.h!") +endif(NOT HAVE_SYS_SOCKET_H) + +check_include_file(sys/types.h HAVE_SYS_TYPES_H) +if(NOT HAVE_SYS_TYPES_H) + message(FATAL_ERROR "Could not find sys/types.h!") +endif(NOT HAVE_SYS_TYPES_H) + +check_include_file(sys/stat.h HAVE_SYS_STAT_H) +if(NOT HAVE_SYS_STAT_H) + message(FATAL_ERROR "Could not find sys/stat.h!") +endif(NOT HAVE_SYS_STAT_H) + +check_include_file(sys/time.h HAVE_SYS_TIME_H) +if(NOT HAVE_SYS_TIME_H) + message(FATAL_ERROR "Could not find sys/time.h") +endif(NOT HAVE_SYS_TIME_H) + +check_include_file(sys/select.h HAVE_SYS_SELECT_H) +if(NOT HAVE_SYS_SELECT_H) + message(FATAL_ERROR "Could not find sys/select.h") +endif(NOT HAVE_SYS_SELECT_H) + +check_include_file(sys/ioctl.h HAVE_SYS_IOCTL_H) +if(NOT HAVE_SYS_IOCTL_H) + message(FATAL_ERROR "Could not find sys/ioctl.h") +endif(NOT HAVE_SYS_IOCTL_H) + +check_include_file(stdio.h HAVE_STDIO_H) +if(NOT HAVE_STDIO_H) + message(FATAL_ERROR "Could not find stdio.h!") +endif(NOT HAVE_STDIO_H) + +check_include_file(stdlib.h HAVE_STDLIB_H) +if(NOT HAVE_STDLIB_H) + message(FATAL_ERROR "Could not find stdlib.h!") +endif(NOT HAVE_STDLIB_H) + +check_include_file(stdbool.h HAVE_STDBOOL_H) +if(NOT HAVE_STDBOOL_H) + message(FATAL_ERROR "Could not find stdbool.h!") +endif(NOT HAVE_STDBOOL_H) + +check_include_file(stdarg.h HAVE_STDARG_H) +if(NOT HAVE_STDARG_H) + message(FATAL_ERROR "Could not find stdarg.h!") +endif(NOT HAVE_STDARG_H) + +check_include_file(unistd.h HAVE_UNISTD_H) +if(NOT HAVE_UNISTD_H) + message(FATAL_ERROR "Could not find unistd.h!") +endif(NOT HAVE_UNISTD_H) + +check_include_file(string.h HAVE_STRING_H) +if(NOT HAVE_STRING_H) + message(FATAL_ERROR "Could not find string.h!") +endif(NOT HAVE_STRING_H) + +check_include_file(getopt.h HAVE_GETOPT_H) +if(NOT HAVE_GETOPT_H) + message(FATAL_ERROR "Could not find getopt.h!") +endif(NOT HAVE_GETOPT_H) + +check_include_file(fcntl.h HAVE_FCNTL_H) +if(NOT HAVE_FCNTL_H) + message(FATAL_ERROR "Could not find fcntl.h!") +endif(NOT HAVE_FCNTL_H) + +check_include_file(time.h HAVE_TIME_H) +if(NOT HAVE_TIME_H) + message(FATAL_ERROR "Could not find time.h!") +endif(NOT HAVE_TIME_H) + +check_include_file(signal.h HAVE_SIGNAL_H) +if(NOT HAVE_SIGNAL_H) + message(FATAL_ERROR "Could not find signal.h!") +endif(NOT HAVE_SIGNAL_H) + +check_include_file(errno.h HAVE_ERRNO_H) +if(NOT HAVE_ERRNO_H) + message(FATAL_ERROR "Could not find errno.h!") +endif(NOT HAVE_ERRNO_H) + +check_include_file(assert.h HAVE_ASSERT_H) +if(NOT HAVE_ASSERT_H) + message(FATAL_ERROR "Could not find assert.h!") +endif(NOT HAVE_ASSERT_H) + +# +# EOF +# +# vim:ts=4:expandtab +# diff -Nru arpon-2.7.2/cmake/modules/FindLibdnet.cmake arpon-3.0-ng+dfsg1/cmake/modules/FindLibdnet.cmake --- arpon-2.7.2/cmake/modules/FindLibdnet.cmake 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/cmake/modules/FindLibdnet.cmake 2016-01-29 01:48:07.000000000 +0000 @@ -0,0 +1,93 @@ +# +# Copyright (C) 2008-2016 Andrea Di Pasquale +# Copyright (C) 2008-2016 Giuseppe Marco Randazzo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# +# $ArpON: FindLibdnet.cmake,v 3.0-ng 01/29/2016 02:48:07 spikey Exp $ +# + +# +# FindLibdnet search and find the Libdnet library path and header path +# +# Usage: +# +# find_package(Libdnet) +# ... +# target_link_libraries(... ${DNET_LIB}) +# +# The following variables are to be set: +# +# CMAKE_INCLUDE_PATH - find the dnet.h or dumbnet.h +# CMAKE_LIBRARY_PATH - find the library +# +# Variable defined by this module: +# +# DNET_INCLUDE_DIR - header directory +# DNET_LIB - library to link +# + +set(libdnet_h dumbnet.h dnet.h) +set(libdnet_names dumbnet dnet) + +set(DNET_H) + +foreach(header ${libdnet_h}) + find_path(DNET_INCLUDE_DIR NAMES ${header} HINTS ${CMAKE_INCLUDE_PATH}) + + if(DNET_INCLUDE_DIR) + set(DNET_H "${header}") + break() + endif(DNET_INCLUDE_DIR) +endforeach(header ${libdnet_h}) + +foreach(libname ${libdnet_names}) + find_library(DNET_LIB NAMES ${libname} HINTS ${CMAKE_LIBRARY_PATH}) + + if(DNET_LIB) + break() + endif(DNET_LIB) +endforeach(libname ${libdnet_names}) + +if(DNET_INCLUDE_DIR AND DNET_LIB) + # + # If dnet.h is called dumbnet.h set the correct CFLAGS compiler parameter. + # + if(DNET_H STREQUAL "dumbnet.h") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_DUMBNET_H") + endif(DNET_H STREQUAL "dumbnet.h") + + include_directories(${DNET_INCLUDE_DIR}) + + message(STATUS "Found library: Libdnet") +else(DNET_INCLUDE_DIR AND DNET_LIB) + message(FATAL_ERROR "Could not find Libdnet! Please see in the ArpON 'README' file.") +endif(DNET_INCLUDE_DIR AND DNET_LIB) + +# +# EOF +# +# vim:ts=4:expandtab +# diff -Nru arpon-2.7.2/cmake/modules/FindLibnet1.cmake arpon-3.0-ng+dfsg1/cmake/modules/FindLibnet1.cmake --- arpon-2.7.2/cmake/modules/FindLibnet1.cmake 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/cmake/modules/FindLibnet1.cmake 2016-01-29 01:50:18.000000000 +0000 @@ -0,0 +1,79 @@ +# +# Copyright (C) 2008-2016 Andrea Di Pasquale +# Copyright (C) 2008-2016 Giuseppe Marco Randazzo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# +# $ArpON: FindLibnet1.cmake,v 3.0-ng 01/29/2016 02:50:18 spikey Exp $ +# + +# +# FindLibnet1 search and find the Libnet1 library path and header path +# +# Usage: +# +# find_package(Libnet1) +# ... +# target_link_libraries(... ${NET_LIB}) +# +# The following variables are to be set: +# +# CMAKE_INCLUDE_PATH - find the libnet.h +# CMAKE_LIBRARY_PATH - find the library +# +# Variable defined by this module: +# +# NET_INCLUDE_DIR - header directory +# NET_LIB - library to link +# + +find_path(NET_INCLUDE_DIR NAMES libnet.h HINTS ${CMAKE_INCLUDE_PATH}) +find_library(NET_LIB NAMES net HINTS ${CMAKE_LIBRARY_PATH}) + +if(NET_INCLUDE_DIR AND NET_LIB) + # + # Match only for Libnet1 (not for Libnet0). + # + file(READ "${NET_INCLUDE_DIR}/libnet.h" FILE_CONTENT) + string(REGEX MATCH + ".*#define[ \t]+LIBNET_VERSION[ \t]+\"([0-9.a-zA-Z-]+)\".*" + LIBNET_VERSION "${FILE_CONTENT}") + + if(LIBNET_VERSION STREQUAL "") + message(FATAL_ERROR "Could not find Libnet1! Please see in the ArpON 'README' file.") + endif(LIBNET_VERSION STREQUAL "") + + include_directories(${NET_INCLUDE_DIR}) + + message(STATUS "Found library: Libnet1") +else(NET_INCLUDE_DIR AND NET_LIB) + message(FATAL_ERROR "Could not find Libnet1! Please see in the ArpON 'README' file.") +endif(NET_INCLUDE_DIR AND NET_LIB) + +# +# EOF +# +# vim:ts=4:expandtab +# diff -Nru arpon-2.7.2/cmake/modules/FindLibpcap.cmake arpon-3.0-ng+dfsg1/cmake/modules/FindLibpcap.cmake --- arpon-2.7.2/cmake/modules/FindLibpcap.cmake 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/cmake/modules/FindLibpcap.cmake 2016-01-29 01:49:52.000000000 +0000 @@ -0,0 +1,67 @@ +# +# Copyright (C) 2008-2016 Andrea Di Pasquale +# Copyright (C) 2008-2016 Giuseppe Marco Randazzo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# +# $ArpON: FindLibpcap.cmake,v 3.0-ng 01/29/2016 02:49:52 spikey Exp $ +# + +# +# FindLibpcap search and find the Libpcap library path and header path +# +# Usage: +# +# find_package(Libpcap) +# ... +# target_link_libraries(... ${PCAP_LIB}) +# +# The following variables are to be set: +# +# CMAKE_INCLUDE_PATH - find the pcap.h +# CMAKE_LIBRARY_PATH - find the library +# +# Variable defined by this module: +# +# PCAP_INCLUDE_DIR - header directory +# PCAP_LIB - library to link +# + +find_path(PCAP_INCLUDE_DIR NAMES pcap.h HINTS ${CMAKE_INCLUDE_PATH}) +find_library(PCAP_LIB NAMES pcap HINTS ${CMAKE_LIBRARY_PATH}) + +if(PCAP_INCLUDE_DIR AND PCAP_LIB) + include_directories(${PCAP_INCLUDE_DIR}) + + message(STATUS "Found library: Libpcap") +else(PCAP_INCLUDE_DIR AND PCAP_LIB) + message(FATAL_ERROR "Could not find Libpcap! Please see in the ArpON 'README' file.") +endif(PCAP_INCLUDE_DIR AND PCAP_LIB) + +# +# EOF +# +# vim:ts=4:expandtab +# diff -Nru arpon-2.7.2/cmake/modules/FindLibrt.cmake arpon-3.0-ng+dfsg1/cmake/modules/FindLibrt.cmake --- arpon-2.7.2/cmake/modules/FindLibrt.cmake 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/cmake/modules/FindLibrt.cmake 2016-01-29 01:48:53.000000000 +0000 @@ -0,0 +1,67 @@ +# +# Copyright (C) 2008-2016 Andrea Di Pasquale +# Copyright (C) 2008-2016 Giuseppe Marco Randazzo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# +# $ArpON: FindLibrt.cmake,v 3.0-ng 01/29/2016 02:48:55 spikey Exp $ +# + +# +# FindLibrt search and find the Librt library path and header path +# +# Usage: +# +# find_package(Librt) +# ... +# target_link_libraries(... ${RT_LIB}) +# +# The following variables are to be set: +# +# CMAKE_INCLUDE_PATH - find the time.h +# CMAKE_LIBRARY_PATH - find the library +# +# Variable defined by this module: +# +# RT_INCLUDE_DIR - header directory +# RT_LIB - library to link +# + +find_path(RT_INCLUDE_DIR NAMES time.h HINTS ${CMAKE_INCLUDE_PATH}) +find_library(RT_LIB NAMES rt HINTS ${CMAKE_LIBRARY_PATH}) + +if(RT_INCLUDE_DIR AND RT_LIB) + include_directories(${RT_INCLUDE_DIR}) + + message(STATUS "Found library: Librt") +else(RT_INCLUDE_DIR AND RT_LIB) + message(FATAL_ERROR "Could not found Librt! Please see in the ArpON 'README' file.") +endif(RT_INCLUDE_DIR AND RT_LIB) + +# +# EOF +# +# vim:ts=4:expandtab +# diff -Nru arpon-2.7.2/cmake/modules/FindPthreads.cmake arpon-3.0-ng+dfsg1/cmake/modules/FindPthreads.cmake --- arpon-2.7.2/cmake/modules/FindPthreads.cmake 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/cmake/modules/FindPthreads.cmake 2016-01-29 01:51:06.000000000 +0000 @@ -0,0 +1,67 @@ +# +# Copyright (C) 2008-2016 Andrea Di Pasquale +# Copyright (C) 2008-2016 Giuseppe Marco Randazzo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# +# $ArpON: FindPthreads.cmake,v 3.0-ng 01/29/2016 02:51:08 spikey Exp $ +# + +# +# FindPthreads search and find the Pthreads library path and header path +# +# Usage: +# +# find_package(Pthreads) +# ... +# target_link_libraries(... ${PTHREADS_LIB}) +# +# The following variables are to be set: +# +# CMAKE_INCLUDE_PATH - find the pthread.h +# CMAKE_LIBRARY_PATH - find the library +# +# Variable defined by this module: +# +# PTHREADS_INCLUDE_DIR - header directory +# PTHREADS_LIB - library to link +# + +find_path(PTHREADS_INCLUDE_DIR NAMES pthread.h HINTS ${CMAKE_INCLUDE_PATH}) +find_library(PTHREADS_LIB NAMES pthread HINTS ${CMAKE_LIBRARY_PATH}) + +if(PTHREADS_INCLUDE_DIR AND PTHREADS_LIB) + include_directories(${PTHREADS_INCLUDE_DIR}) + + message(STATUS "Found library: Pthreads") +else(PTHREADS_INCLUDE_DIR AND PTHREADS_LIB) + message(FATAL_ERROR "Could not found Pthreads! Please see in the ArpON 'README' file.") +endif(PTHREADS_INCLUDE_DIR AND PTHREADS_LIB) + +# +# EOF +# +# vim:ts=4:expandtab +# diff -Nru arpon-2.7.2/cmake/modules/FindSystem.cmake arpon-3.0-ng+dfsg1/cmake/modules/FindSystem.cmake --- arpon-2.7.2/cmake/modules/FindSystem.cmake 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/cmake/modules/FindSystem.cmake 2016-01-29 01:50:41.000000000 +0000 @@ -0,0 +1,50 @@ +# +# Copyright (C) 2008-2016 Andrea Di Pasquale +# Copyright (C) 2008-2016 Giuseppe Marco Randazzo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# +# $ArpON: FindSystem.cmake,v 3.0-ng 01/29/2016 02:50:42 spikey Exp $ +# + +# +# FindSystem match the Operating System +# +# Usage: +# +# find_package(System) +# + +if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + message(STATUS "Building ${PROJECT_NAME} for Operating System: GNU/Linux") +else(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + message(FATAL_ERROR "Operating System not supported") +endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + +# +# EOF +# +# vim:ts=4:expandtab +# diff -Nru arpon-2.7.2/cmake/scripts/cmake_clean-all.cmake arpon-3.0-ng+dfsg1/cmake/scripts/cmake_clean-all.cmake --- arpon-2.7.2/cmake/scripts/cmake_clean-all.cmake 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/cmake/scripts/cmake_clean-all.cmake 2016-01-29 01:51:29.000000000 +0000 @@ -0,0 +1,56 @@ +# +# Copyright (C) 2008-2016 Andrea Di Pasquale +# Copyright (C) 2008-2016 Giuseppe Marco Randazzo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# +# $ArpON: cmake_clean-all.cmake,v 3.0-ng 01/29/2016 02:51:29 spikey Exp $ +# + +set(cmake_generated + ${CMAKE_BINARY_DIR}/CMakeCache.txt + ${CMAKE_BINARY_DIR}/CMakeFiles + ${CMAKE_BINARY_DIR}/cmake_install.cmake + ${CMAKE_BINARY_DIR}/cmake_uninstall.cmake + ${CMAKE_BINARY_DIR}/doc + ${CMAKE_BINARY_DIR}/etc + ${CMAKE_BINARY_DIR}/install_manifest.txt + ${CMAKE_BINARY_DIR}/log + ${CMAKE_BINARY_DIR}/Makefile + ${CMAKE_BINARY_DIR}/man8 + ${CMAKE_BINARY_DIR}/run + ${CMAKE_BINARY_DIR}/src) + +foreach(file ${cmake_generated}) + if(EXISTS ${file}) + file(REMOVE_RECURSE ${file}) + endif(EXISTS ${file}) +endforeach(file ${cmake_generated}) + +# +# EOF +# +# vim:ts=4:expandtab +# diff -Nru arpon-2.7.2/cmake/scripts/cmake_uninstall.cmake.in arpon-3.0-ng+dfsg1/cmake/scripts/cmake_uninstall.cmake.in --- arpon-2.7.2/cmake/scripts/cmake_uninstall.cmake.in 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/cmake/scripts/cmake_uninstall.cmake.in 2016-01-29 01:51:53.000000000 +0000 @@ -0,0 +1,60 @@ +# +# Copyright (C) 2008-2016 Andrea Di Pasquale +# Copyright (C) 2008-2016 Giuseppe Marco Randazzo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# +# $ArpON: cmake_uninstall.cmake.in,v 3.0-ng 01/29/2016 02:51:54 spikey Exp $ +# + +if(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + message(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") +endif(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") + +file(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) +string(REGEX REPLACE "\n" ";" files "${files}") + +foreach(file ${files}) + message(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") + + if(EXISTS "$ENV{DESTDIR}${file}") + exec_program( + "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" + OUTPUT_VARIABLE rm_out + RETURN_VALUE rm_retval) + + if(NOT "${rm_retval}" STREQUAL 0) + message(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") + endif(NOT "${rm_retval}" STREQUAL 0) + else(EXISTS "$ENV{DESTDIR}${file}") + message(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") + endif(EXISTS "$ENV{DESTDIR}${file}") +endforeach(file) + +# +# EOF +# +# vim:ts=4:expandtab +# diff -Nru arpon-2.7.2/CMakeLists.txt arpon-3.0-ng+dfsg1/CMakeLists.txt --- arpon-2.7.2/CMakeLists.txt 2014-10-14 01:58:34.000000000 +0000 +++ arpon-3.0-ng+dfsg1/CMakeLists.txt 2016-01-29 01:52:11.000000000 +0000 @@ -1,84 +1,139 @@ -# - Build arpon +# +# Copyright (C) 2008-2016 Andrea Di Pasquale +# Copyright (C) 2008-2016 Giuseppe Marco Randazzo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# +# $ArpON: CMakeLists.txt,v 3.0-ng 01/29/2016 02:52:15 spikey Exp $ +# + # # The following variables can be modified: # -# CMAKE_C_FLAGS - Set flags for the C compiler # CMAKE_BUILD_TYPE - Set build type: release or debug -# CMAKE_LIBRARY_PATH - Set the library path # CMAKE_INCLUDE_PATH - Set the include path -# CMAKE_INSTALL_PREFIX - Set the install prefix for arpon. -# By default arpon will be installed to /usr/loca/ path. -# -# Copyright 2014 gmrandazzo@gmail.com +# CMAKE_LIBRARY_PATH - Set the library path +# CMAKE_C_FLAGS - Set flags for the C compiler +# CMAKE_INSTALL_PREFIX - Set the install prefix for ArpON. +# By default ArpON will be installed to / path. # -# Redistribution AND use is allowed according to the terms of the BSD 3 clause cmake_minimum_required(VERSION 2.6) -project(ArpON) -set(AUTHOR "Andrea Di Pasquale" INTERNAL "Author") -set(VERSION "2.7.2") -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: Debug Release" FORCE) -endif(NOT CMAKE_BUILD_TYPE) +project(ArpON C) +set(AUTHOR "Andrea Di Pasquale " INTERNAL "Author") +set(VERSION "3.0-ng") + +set(CMAKE_INCLUDE_PATH + /usr/include; + /usr/local/include; + /usr/local/include/libnet11; + /usr/local/include/libnet-1.1; + ${CMAKE_INCLUDE_PATH}) + +set(CMAKE_LIBRARY_PATH + /lib; + /usr/lib; + /usr/lib32; + /usr/lib64; + /usr/local/lib; + /usr/local/lib32; + /usr/local/lib64; + /usr/local/lib/libnet11; + /usr/local/lib/libnet-1.1; + ${CMAKE_LIBRARY_PATH}) -if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) - set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "ArpON install prefix" FORCE) -endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) +include_directories( + ${PROJECT_BINARY_DIR} + ${PROJECT_SOURCE_DIR}/src + ${CMAKE_CURRENT_BINARY_DIR} + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_INCLUDE_PATH}) -set(CMAKE_LIBRARY_PATH /lib; - /usr/lib; - /usrc/lib64; - /usr/local/lib; - /usr/local/lib64; - /usr/local/lib/libnet11; - /usr/local/lib/libnet-1.1; - /usr/pkg/lib; - /usr/pkg/lib/libnet11; - /opt/csw/lib; - ${CMAKE_LIBRARY_PATH}) - -set(CMAKE_INCLUDE_PATH /usr/include/; - /usr/local/include/; - /usr/local/include/libnet11; - /usr/local/include/libnet-1.1; - /usr/pkg/include; - /usr/pkg/include/libnet11; - /opt/csw/include; - ${CMAKE_INCLUDE_PATH}) +set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules/") + +find_package(System) + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release + CACHE STRING "Choose the type of build, options are: Debug Release" + FORCE) +endif(NOT CMAKE_BUILD_TYPE) string(TOLOWER "${CMAKE_BUILD_TYPE}" cmake_build_type_tolower) + if(cmake_build_type_tolower STREQUAL "debug") - message(STATUS "Build Type: Debug") - set(CMAKE_BUILD_TYPE "Debug") - set(CMAKE_C_FLAGS "-Wall -Werror -pedantic -O0 -g") -else() - message(STATUS "Build Type: Release") - set(CMAKE_BUILD_TYPE "Release") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror") -endif() + message(STATUS "Build type: Debug") -include_directories( - ${PROJECT_BINARY_DIR} - ${PROJECT_SOURCE_DIR}/src - ${CMAKE_CURRENT_BINARY_DIR} - ${CMAKE_CURRENT_SOURCE_DIR} - ${CMAKE_INCLUDE_PATH} -) + set(CMAKE_BUILD_TYPE "Debug") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -Wextra -Wformat=2 -Winit-self -Wreturn-type -Wswitch-default -Wswitch-enum -Wunused-parameter -Wuninitialized -Wstrict-aliasing=3 -Wstrict-overflow=5 -Wdeclaration-after-statement -Wundef -Wpointer-arith -Wunsafe-loop-optimizations -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings -Wconversion -Wsizeof-pointer-memaccess -Wlogical-op -Waggregate-return -Wstrict-prototypes -Wold-style-declaration -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wlong-long -Wvariadic-macros -Wvarargs -Wvla -Wdisabled-optimization -Woverlength-strings -O0 -g -ggdb") +else(cmake_build_type_tolower STREQUAL "debug") + message(STATUS "Build type: Release") + + set(CMAKE_BUILD_TYPE "Release") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -Wextra -O3 -DNDEBUG") +endif(cmake_build_type_tolower STREQUAL "debug") + +find_package(Headers) +find_package(Pthreads) +find_package(Librt) +find_package(Libpcap) +find_package(Libnet1) +find_package(Libdnet) -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake_modules/") -find_package(System) -find_package(Pthread) -find_package(DNET) -find_package(NET) -find_package(PCAP) +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + set(CMAKE_INSTALL_PREFIX "/" CACHE PATH "ArpON install prefix" FORCE) +endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + +if(cmake_build_type_tolower STREQUAL "debug") + message(STATUS "Include path: ${CMAKE_INCLUDE_PATH}") + message(STATUS "Library path: ${CMAKE_LIBRARY_PATH}") + message(STATUS "C compiler flags: ${CMAKE_C_FLAGS}") + message(STATUS "Install prefix: ${CMAKE_INSTALL_PREFIX}") +endif(cmake_build_type_tolower STREQUAL "debug") add_subdirectory(src) +add_subdirectory(doc) add_subdirectory(man8) add_subdirectory(etc) +add_subdirectory(log) +add_subdirectory(run) + +configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/scripts/cmake_uninstall.cmake.in" + "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" + IMMEDIATE @ONLY) -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake_uninstall.cmake.in" - "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake" IMMEDIATE @ONLY) -add_custom_target(uninstall "${CMAKE_COMMAND}" -P - "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") +add_custom_target(uninstall + COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake") +add_custom_target(clean-all + COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_SOURCE_DIR}/cmake/scripts/cmake_clean-all.cmake") + +# +# EOF +# +# vim:ts=4:expandtab +# diff -Nru arpon-2.7.2/cmake_modules/FindDNET.cmake arpon-3.0-ng+dfsg1/cmake_modules/FindDNET.cmake --- arpon-2.7.2/cmake_modules/FindDNET.cmake 2014-10-09 17:22:52.000000000 +0000 +++ arpon-3.0-ng+dfsg1/cmake_modules/FindDNET.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -# FindDNET search and find the libdnet library path -# -# Usage: -# -# find_package(DNET) -# ... -# target_link_libraries(... ${DNET_LIB}) -# -# The following variables are to be set: -# CMAKE_INCLUDE_PATH - find the dnet.h or dumbnet.h -# CMAKE_LIBRARY_PATH - find the library -# -# Variable defined by this module: -# DNET_INCLUDE_DIR - header directory -# DNET_LIB - library to link -# -# Copyright 2014 gmrandazzo@gmail.com -# -# Redistribution AND use is allowed according to the terms of the BSD 3 clause - -set(libdnet_h dumbnet.h dnet.h) -set(libdnet_names dumbnet dnet) - -foreach(header ${libdnet_h}) - find_path(DNET_INCLUDE_DIR NAMES ${header} HINTS ${CMAKE_INCLUDE_PATH}) - if(DNET_INCLUDE_DIR) - break() - endif(DNET_INCLUDE_DIR) -endforeach(header ${libdnet_h}) - -foreach(libname ${libdnet_names}) - find_library(DNET_LIB NAMES ${libname} HINTS ${CMAKE_LIBRARY_PATH}) - if(DNET_LIB) - break() - endif(DNET_LIB) -endforeach(libname ${libdnet_names}) - -if(DNET_INCLUDE_DIR AND DNET_LIB) - message(STATUS "Found libdnet") - include_directories(${DNET_INCLUDE_DIR}) -else(DNET_INCLUDE_DIR AND DNET_LIB) - message(FATAL_ERROR "Could not find libdnet! Please Visit: http://libdnet.sourceforge.net/ or see in the arpon 'INSTALL' file.") -endif(DNET_INCLUDE_DIR AND DNET_LIB) diff -Nru arpon-2.7.2/cmake_modules/FindNET.cmake arpon-3.0-ng+dfsg1/cmake_modules/FindNET.cmake --- arpon-2.7.2/cmake_modules/FindNET.cmake 2014-10-09 17:22:52.000000000 +0000 +++ arpon-3.0-ng+dfsg1/cmake_modules/FindNET.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -# FindNET search and find the libnet library path -# -# Usage: -# -# find_package(NET) -# ... -# target_link_libraries(... ${NET_LIB}) -# -# The following variables are to be set: -# CMAKE_INCLUDE_PATH - find the pthread.h -# CMAKE_LIBRARY_PATH - find the library -# -# Variable defined by this module: -# NET_INCLUDE_DIR - header directory -# NET_LIB - library to link -# -# Copyright 2014 gmrandazzo@gmail.com -# -# Redistribution AND use is allowed according to the terms of the BSD 3 clause - -find_path(NET_INCLUDE_DIR NAMES libnet.h HINTS ${CMAKE_INCLUDE_PATH}) - -find_library(NET_LIB NAMES net HINTS ${CMAKE_LIBRARY_PATH}) - -if(NET_INCLUDE_DIR AND NET_LIB) - message(STATUS "Found libnet") - include_directories(${NET_INCLUDE_DIR}) -else(NET_INCLUDE_DIR AND NET_LIB) - message(FATAL_ERROR "Could not find libnet-1.1! Please Visit: http://libnet.sourceforge.net/ or see in the arpon 'INSTALL' file") -endif(NET_INCLUDE_DIR AND NET_LIB) diff -Nru arpon-2.7.2/cmake_modules/FindPCAP.cmake arpon-3.0-ng+dfsg1/cmake_modules/FindPCAP.cmake --- arpon-2.7.2/cmake_modules/FindPCAP.cmake 2014-10-09 17:22:52.000000000 +0000 +++ arpon-3.0-ng+dfsg1/cmake_modules/FindPCAP.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -# FindPCAP search and find the libpcap library path -# -# Usage: -# -# find_package(PCAP) -# ... -# target_link_libraries(... ${PCAP_LIB}) -# -# The following variables are to be set: -# CMAKE_INCLUDE_PATH - find the pthread.h -# CMAKE_LIBRARY_PATH - find the library -# -# Variable defined by this module: -# PCAP_INCLUDE_DIR - header directory -# PCAP_LIB - library to link -# -# Copyright 2014 gmrandazzo@gmail.com -# -# Redistribution AND use is allowed according to the terms of the BSD 3 clause - -find_path(PCAP_INCLUDE_DIR NAMES pcap.h HINTS ${CMAKE_INCLUDE_PATH}) - -find_library(PCAP_LIB NAMES pcap HINTS ${CMAKE_LIBRARY_PATH}) - -if(PCAP_INCLUDE_DIR AND PCAP_LIB) - message(STATUS "Found libpcap") - include_directories(${PCAP_INCLUDE_DIR}) -else(PCAP_INCLUDE_DIR AND PCAP_LIB) - message(FATAL_ERROR "libpcap not found! Please visit http://www.tcpdump.org/ or see in the arpon 'INSTALL' file.") -endif(PCAP_INCLUDE_DIR AND PCAP_LIB) diff -Nru arpon-2.7.2/cmake_modules/FindPthread.cmake arpon-3.0-ng+dfsg1/cmake_modules/FindPthread.cmake --- arpon-2.7.2/cmake_modules/FindPthread.cmake 2014-10-09 17:22:52.000000000 +0000 +++ arpon-3.0-ng+dfsg1/cmake_modules/FindPthread.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,30 +0,0 @@ -# FindPhtread search and find the libphtread library path and header path -# -# Usage: -# -# find_package(Pthread) -# ... -# target_link_libraries(... ${PTHREAD_LIB}) -# -# The following variables are to be set: -# CMAKE_INCLUDE_PATH - find the pthread.h -# CMAKE_LIBRARY_PATH - find the library -# -# Variable defined by this module: -# PTHREAD_INCLUDE_DIR - header directory -# PTHREAD_LIB - library to link -# -# Copyright 2014 gmrandazzo@gmail.com -# -# Redistribution AND use is allowed according to the terms of the BSD 3 clause - -find_path(PTHREAD_INCLUDE_DIR NAMES pthread.h HINTS ${CMAKE_INCLUDE_PATH}) - -find_library(PTHREAD_LIB NAMES pthread HINTS ${CMAKE_LIBRARY_PATH}) - -if(PTHREAD_INCLUDE_DIR AND PTHREAD_LIB) - message(STATUS "Found phtread") - include_directories(${PTHREAD_INCLUDE_DIR}) -else(PTHREAD_INCLUDE_DIR AND PTHREAD_LIB) - message(FATAL_ERROR " pthread not found! \n Please visit http://www.gnu.org/software/libc/libc.html or see in the arpon 'INSTALL' file.") -endif(PTHREAD_INCLUDE_DIR AND PTHREAD_LIB) diff -Nru arpon-2.7.2/cmake_modules/FindSystem.cmake arpon-3.0-ng+dfsg1/cmake_modules/FindSystem.cmake --- arpon-2.7.2/cmake_modules/FindSystem.cmake 2014-10-14 01:10:45.000000000 +0000 +++ arpon-3.0-ng+dfsg1/cmake_modules/FindSystem.cmake 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -# FindSystem match the operating system and set some -# CFLAGS for compile the source code. -# -# Usage: -# -# find_package(System) -# -# Variables: -# CMAKE_C_FLAGS - flags to add to the C compiler for buil arpon -# -# Copyright 2014 gmrandazzo@gmail.com -# -# Redistribution AND use is allowed according to the terms of the BSD 3 clause - -# GET LINUX DISTRIBUTION FOR PREPROCESSOR -DDEBIAN DIRECTIVE USED BY UBUNTU AND DEBIAN -macro(GET_DISTRO) - set(ID_RELEASE) - find_program(LSB_RELEASE NAMES lsb_release PATHS /bin - /sbin - /usr/bin - /usr/sbin - /usr/local/bin - /usr/local/sbin) - if(LSB_RELEASE) - execute_process(COMMAND ${LSB_RELEASE} -i - OUTPUT_VARIABLE ID_RELEASE) - string(REGEX REPLACE ".*:" "" ID_RELEASE "${ID_RELEASE}") - - if(${ID_RELEASE} MATCHES "Ubuntu" OR ${ID_RELEASE} MATCHES "Debian" OR ${ID_RELEASE} MATCHES "LinuxMint") - set( UBUNTU TRUE ) - set( DEBIAN TRUE ) - add_definitions( -DDEBIAN ) - endif(${ID_RELEASE} MATCHES "Ubuntu" OR ${ID_RELEASE} MATCHES "Debian" OR ${ID_RELEASE} MATCHES "LinuxMint") - endif(LSB_RELEASE) -endmacro(GET_DISTRO) - -if(APPLE) - # Mac OS X specific code - message(STATUS "Operating System Found: OS X") -elseif(UNIX) - if(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") - # FreeBSD specific code - message(STATUS "Operating System Found: FreeBSD") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFREEBSD") - endif(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD") - - if(${CMAKE_SYSTEM_NAME} MATCHES "NetBSD") - # NetBSD specific code - message(STATUS "Operating System Found: NetBSD") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNETBSD") - endif(${CMAKE_SYSTEM_NAME} MATCHES "NetBSD") - - if(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") - # OpenBSD specific code - message(STATUS "Operating System Found: OpenBSD") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DOPENBSD") - endif(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD") - - if(${CMAKE_SYSTEM_NAME} MATCHES "DragonFly") - # DragonFly BSD specific code - message(STATUS "Operating System Found: DragonFly BSD") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DFREEBSD") - endif(${CMAKE_SYSTEM_NAME} MATCHES "DragonFly") - - if(${CMAKE_SYSTEM_NAME} MATCHES "SunOS") - # Solaris specific code - message(STATUS "Operating System Found: Solaris") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DSOLARIS -lsocket -lresolv -lnsl") - endif(${CMAKE_SYSTEM_NAME} MATCHES "SunOS") - - if(${CMAKE_SYSTEM_NAME} MATCHES "Linux") - # Linux specific code - message(STATUS "Operating System Found: Linux") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DLINUX") - GET_DISTRO() - endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") -elseif(WIN32) - message(FATAL_ERROR "Windows Operating System Not Supported") -else(APPLE) - message(FATAL_ERROR "Operating System Not Supported") -endif(APPLE) diff -Nru arpon-2.7.2/cmake_uninstall.cmake.in arpon-3.0-ng+dfsg1/cmake_uninstall.cmake.in --- arpon-2.7.2/cmake_uninstall.cmake.in 2010-05-28 20:37:50.000000000 +0000 +++ arpon-3.0-ng+dfsg1/cmake_uninstall.cmake.in 1970-01-01 00:00:00.000000000 +0000 @@ -1,21 +0,0 @@ -IF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") - MESSAGE(FATAL_ERROR "Cannot find install manifest: \"@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt\"") -ENDIF(NOT EXISTS "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt") - -FILE(READ "@CMAKE_CURRENT_BINARY_DIR@/install_manifest.txt" files) -STRING(REGEX REPLACE "\n" ";" files "${files}") -FOREACH(file ${files}) - MESSAGE(STATUS "Uninstalling \"$ENV{DESTDIR}${file}\"") - IF(EXISTS "$ENV{DESTDIR}${file}") - EXEC_PROGRAM( - "@CMAKE_COMMAND@" ARGS "-E remove \"$ENV{DESTDIR}${file}\"" - OUTPUT_VARIABLE rm_out - RETURN_VALUE rm_retval - ) - IF(NOT "${rm_retval}" STREQUAL 0) - MESSAGE(FATAL_ERROR "Problem when removing \"$ENV{DESTDIR}${file}\"") - ENDIF(NOT "${rm_retval}" STREQUAL 0) - ELSE(EXISTS "$ENV{DESTDIR}${file}") - MESSAGE(STATUS "File \"$ENV{DESTDIR}${file}\" does not exist.") - ENDIF(EXISTS "$ENV{DESTDIR}${file}") -ENDFOREACH(file) diff -Nru arpon-2.7.2/debian/arpon.default arpon-3.0-ng+dfsg1/debian/arpon.default --- arpon-2.7.2/debian/arpon.default 2015-02-08 12:25:04.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/arpon.default 2017-09-07 18:26:55.000000000 +0000 @@ -1,16 +1,22 @@ -# Defaults for arpon initscript -# sourced by /etc/init.d/arpon -# installed at /etc/default/arpon by the maintainer scripts +# Options for arpon(8) +# You must choose between static ARP inspection (SARPI), dynamic ARP inspection +# (DARPI), and hybrid ARP inspection' (HARPI). You can also pass other options +# to the daemon as explained in arpon(8), but do NOT pass `--daemon` or +# `--interface` (those will be added automatically as needed). -# You must choose between static ARP inspection (SARPI) and -# dynamic ARP inspection (DARPI) -# -# For SARPI uncomment the following line (please edit also /etc/arpon.sarpi) -# DAEMON_OPTS="-q -f /var/log/arpon/arpon.log -g -s" +DAEMON_ARGS="--sarpi" +# DAEMON_ARGS="--darpi" +# DAEMON_ARGS="--harpi" -# For DARPI uncomment the following line -# DAEMON_OPTS="-q -f /var/log/arpon/arpon.log -g -d" +# when using systemd you have to enable arpon explicitly for each interface +# you want to run it on: +# systemctl enable arpon@IFACE +# systemctl start arpon@IFACE -# Modify to RUN="yes" when you are ready -RUN="no" + +# For the LSB init script, enter a list of interfaces into the list below; +# arpon will be started to protect ARP on these interfaces. +# Note: This is ignored when using systemd! +# INTERFACES="eth0 eth1" +INTERFACES="" diff -Nru arpon-2.7.2/debian/arpon.docs arpon-3.0-ng+dfsg1/debian/arpon.docs --- arpon-2.7.2/debian/arpon.docs 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/arpon.docs 2017-09-07 18:26:55.000000000 +0000 @@ -0,0 +1 @@ +AUTHOR diff -Nru arpon-2.7.2/debian/arpon.init arpon-3.0-ng+dfsg1/debian/arpon.init --- arpon-2.7.2/debian/arpon.init 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/arpon.init 2017-09-07 18:26:55.000000000 +0000 @@ -0,0 +1,182 @@ +#!/bin/sh +# +### BEGIN INIT INFO +# Provides: arpon +# Required-Start: $network $remote_fs +# Required-Stop: $remote_fs +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Anti ARP poisoning daemon +# Description: Anti ARP poisoning daemon +### END INIT INFO + +PATH=/sbin:/bin:/usr/sbin:/usr/bin +NAME=arpon +DAEMON=/usr/sbin/$NAME +DESC="anti ARP poisoning daemon" +LOGDIR=/var/log/arpon # Log directory to use +PIDDIR=/run/ + +test -x $DAEMON || exit 0 + +. /lib/lsb/init-functions + +# Load arpon defaults +if [ -f /etc/default/$NAME ] ; then + . /etc/default/$NAME +fi + +# +# Function that starts the daemon +# +start_instances() +{ + # Return + # 0 if daemons for all interfaces have been started + # 1 if daemons for all interfaces have been started, but at least one + # was already running + # 2 if at least one daemon could not have been stopped + local RET=0 + local IFACE + local EXITCODE + # make sure the log directory exists + mkdir -p /var/log/arpon + for IFACE in $INTERFACES ; do + log_progress_msg "$IFACE" + start-stop-daemon --start --quiet --background --make-pidfile \ + --pidfile "${PIDDIR}/${NAME}-${IFACE}.pid" \ + --exec "$DAEMON" -- -i "$IFACE" $DAEMON_ARGS + EXITCODE=$? + RET=$(($RET|$EXITCODE)) + done + return $RET +} + +stop_instances() +{ + # Return + # 0 if daemons for all interfaces have been stopped + # 1 if daemons for all interfaces have been stopped, but for at least one + # interface it was stopped already + # 2 if at least one daemon could not have been stopped + local RET=0 + local IFACE + local EXITCODE + for IFACE in $INTERFACES ; do + log_progress_msg "$IFACE" + start-stop-daemon --stop --quiet --remove-pidfile \ + --pidfile "${PIDDIR}/${NAME}-${IFACE}.pid" \ + --exec "$DAEMON" --retry=TERM/30/KILL/5 + EXITCODE=$? + RET=$(($RET|$EXITCODE)) + done + return $RET +} + +reload_instances() +{ + # no return value as there is no suitable way to determine if the signal + # was processed properly + local IFACE + for IFACE in $INTERFACES ; do + log_progress_msg "$IFACE" + start-stop-daemon --stop --quiet \ + --pidfile "${PIDDIR}/${NAME}-${IFACE}.pid" \ + --exec "$DAEMON" --signal=HUP + done + return 0 +} + +get_status() +{ + # Return + # 0 if daemons for all interfaces are running + # 1/3 if the daemon for at least one interface is not running + # 4/5/7 if the status of at least one daemon could not be determined + local RET=0 + local IFACE + local EXITCODE + for IFACE in $INTERFACES ; do + start-stop-daemon --status --quiet \ + --pidfile "${PIDDIR}/${NAME}-${IFACE}.pid" \ + --exec "$DAEMON" + EXITCODE=$? + RET=$(($RET|$EXITCODE)) + done + return $RET +} + +case "$1" in + start) + log_daemon_msg "Starting $NAME ($DESC) on interfaces" + start_instances + case "$?" in + 0|1) + log_end_msg 0 + ;; + *) + log_end_msg 1 + ;; + esac + ;; + stop) + log_daemon_msg "Stopping $NAME ($DESC) on interfaces" + stop_instances + case "$?" in + 0|1) + log_end_msg 0 + ;; + *) + log_end_msg 1 + ;; + esac + ;; + restart) + log_daemon_msg "Restarting $NAME ($DESC) on interfaces" + log_progress_msg "stopping:" + stop_instances + case "$?" in + 0|1) + log_progress_msg "starting:" + start_instances + case "$?" in + 0) + log_end_msg 0 + ;; + *) + log_end_msg 1 + ;; + esac + ;; + *) + log_end_msg 1 + ;; + esac + ;; + reload|force-reload) + log_daemon_msg "Reloading $NAME ($DESC) configuration for interfaces" + reload_instances + log_end_msg 0 + ;; + status) + get_status + case "$?" in + 0) + log_success_msg "$NAME is running on all configured interfaces" + ;; + 1|3) + log_failure_msg "$NAME is not running on all configured interfaces" + ;; + *) + log_failure_msg "Could not determine if $NAME is running" + ;; + esac + ;; + *) + N=/etc/init.d/$NAME + echo "Usage: $N {start|stop|restart|reload|force-reload|status}" >&2 + exit 1 + ;; +esac + +exit 0 diff -Nru arpon-2.7.2/debian/arpon.install arpon-3.0-ng+dfsg1/debian/arpon.install --- arpon-2.7.2/debian/arpon.install 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/arpon.install 2017-09-07 18:26:55.000000000 +0000 @@ -0,0 +1 @@ +debian/arpon@.service lib/systemd/system diff -Nru arpon-2.7.2/debian/arpon.logrotate arpon-3.0-ng+dfsg1/debian/arpon.logrotate --- arpon-2.7.2/debian/arpon.logrotate 2015-02-08 12:25:04.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/arpon.logrotate 2017-09-07 18:26:55.000000000 +0000 @@ -1,15 +1,18 @@ /var/log/arpon/arpon.log { weekly missingok - rotate 7 - sharedscripts + rotate 4 postrotate - if [ -e /var/run/arpon.pid ]; then + if [ -e /run/systemd/system ] ; then + if systemctl -q is-active arpon ; then + systemctl -q reload arpon + fi + elif [ -e /var/run/arpon.pid ]; then invoke-rc.d --quiet arpon reload > /dev/null - sleep 10 fi endscript compress + delaycompress notifempty create 640 root root } diff -Nru arpon-2.7.2/debian/arpon.maintscript arpon-3.0-ng+dfsg1/debian/arpon.maintscript --- arpon-2.7.2/debian/arpon.maintscript 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/arpon.maintscript 2017-09-07 18:26:55.000000000 +0000 @@ -0,0 +1 @@ +rm_conffile /etc/arpon.sarpi 3.0-ng+dfsg1-1~ diff -Nru arpon-2.7.2/debian/arpon.postrm arpon-3.0-ng+dfsg1/debian/arpon.postrm --- arpon-2.7.2/debian/arpon.postrm 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/arpon.postrm 2017-09-07 18:26:55.000000000 +0000 @@ -0,0 +1,41 @@ +#!/bin/sh +# postrm script for arpon +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `remove' +# * `purge' +# * `upgrade' +# * `failed-upgrade' +# * `abort-install' +# * `abort-install' +# * `abort-upgrade' +# * `disappear' +# +# for details, see http://www.debian.org/doc/debian-policy/ or +# the debian-policy package + + +case "$1" in + purge) + rm -rf /var/log/arpon + + ;; + remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) + ;; + + *) + echo "postrm called with unknown argument \`$1'" >&2 + exit 1 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 diff -Nru arpon-2.7.2/debian/arpon.service arpon-3.0-ng+dfsg1/debian/arpon.service --- arpon-2.7.2/debian/arpon.service 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/arpon.service 2017-09-07 18:26:55.000000000 +0000 @@ -0,0 +1,13 @@ +[Unit] +Description=Anti ARP poisoning daemon +Documentation=man:arpon(8) +After=network-online.target + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/bin/true +ExecReload=/bin/true + +[Install] +WantedBy=multi-user.target diff -Nru arpon-2.7.2/debian/arpon@.service arpon-3.0-ng+dfsg1/debian/arpon@.service --- arpon-2.7.2/debian/arpon@.service 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/arpon@.service 2017-09-07 18:26:55.000000000 +0000 @@ -0,0 +1,18 @@ +[Unit] +Description=Anti ARP poisoning daemon on interface %I +PartOf=arpon.service +ReloadPropagatedFrom=arpon.service +Documentation=man:arpon(8) + +[Service] +PrivateTmp=true +Type=simple +EnvironmentFile=/etc/default/arpon +ExecStartPre=/bin/mkdir -p /var/log/arpon +ExecStart=/usr/sbin/arpon -i %i $DAEMON_ARGS +PIDFile=/var/run/arpon.pid +ExecReload=/bin/kill -HUP $MAINPID +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff -Nru arpon-2.7.2/debian/changelog arpon-3.0-ng+dfsg1/debian/changelog --- arpon-2.7.2/debian/changelog 2015-02-08 12:25:04.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/changelog 2017-09-07 18:26:55.000000000 +0000 @@ -1,3 +1,52 @@ +arpon (3.0-ng+dfsg1-1) unstable; urgency=low + + * Maintain arpon in pkg-security (Closes: #866832). + * Imported Upstream version 3.0-ng. + - Repacked without doc which contains the linkedin logo and pre-compiled + PDFs without the source, violating the DFSG. + - Drop existing patches, as the new version is a rewrite. + - The libdumbnet library is now properly detected without using + lsb-release (Closes: #783536). + - The permissions of the log file are now 0640 and owned by root:root, the + file is no longer world readable (Closes: #614518). + - Stderr is properly redirected to /dev/null (Closes: #614027). + * Update README.Debian: Mention missing documentation due to repack. + * Update debian/copyright: + - Convert to machine readable format. + - Update for new version. + - Add Files-Excluded for automatic uscan repacking without the doc dir. + * Update debian/watch to deal with dfsg version suffix. + * Package using git-buildpackage: + - Add Vcs-{Git,Browser} to debian/control. + - Add debian/gbp.conf. + * Update to debhelper compatibility level 10, cleanup of debian/rules. + * Drop Build-Depends on lsb-release. + * Introduce a patch to fix gcc-7 compile errors. + * Introduce a patch to adjust the installed files and paths. + * Cleanup of control files: + - Remove dirs, no longer needed. + - Cleanup docs. + - Prefix control files with packagename where appropriate. + * Fix spelling errors in man page. + * Add patch to remove unwanted build options. + * Remove the pre-3.0 configuration file /etc/arpon.sarpi. + - Explain the change in debian/NEWS. + * Remove the /var/log/arpon folder in postrm (not just the contents). + * Simplify and adjust init script for the new version: + - Allow it to start multiple instances of arpon for different interfaces. + - Support the status option. + * Adjust logrotate configuration: + - Only keep 4 weekly rotations. + - Cleanup of unneeded options. + - Updated the postrotate script for usage with systemd. + * Provide a systemd service file. + * Update /etc/default/arpon for new version and init script / service file. + * Bump Standards-Version to 4.1.0. + * Compile with NDEBUG, otherwise the log is flooded with debug messages that + cannot be disabled. + + -- Lukas Schwaighofer Thu, 07 Sep 2017 20:26:55 +0200 + arpon (2.7.2-1) unstable; urgency=low * [863b18a] Imported Upstream version 2.7.2 diff -Nru arpon-2.7.2/debian/compat arpon-3.0-ng+dfsg1/debian/compat --- arpon-2.7.2/debian/compat 2015-02-08 12:25:04.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/compat 2017-09-07 18:26:55.000000000 +0000 @@ -1 +1 @@ -9 +10 diff -Nru arpon-2.7.2/debian/control arpon-3.0-ng+dfsg1/debian/control --- arpon-2.7.2/debian/control 2015-02-08 12:25:04.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/control 2017-09-07 18:26:55.000000000 +0000 @@ -1,14 +1,25 @@ Source: arpon Section: net Priority: optional -Maintainer: Giuseppe Iuculano -Build-Depends: debhelper (>= 9), libnet1-dev, libpcap-dev, libdumbnet-dev, cmake, lsb-release -Standards-Version: 3.9.6 +Maintainer: Debian Security Tools Packaging Team +Uploaders: Lukas Schwaighofer +Build-Depends: + cmake, + debhelper (>= 10), + libdumbnet-dev, + libnet1-dev, + libpcap-dev, +Standards-Version: 4.1.0 Homepage: http://arpon.sourceforge.net +Vcs-Git: https://anonscm.debian.org/git/pkg-security/arpon.git +Vcs-Browser: https://anonscm.debian.org/cgit/pkg-security/arpon.git Package: arpon Architecture: any -Depends: ${shlibs:Depends}, ${misc:Depends}, lsb-base +Depends: + ${misc:Depends}, + ${shlibs:Depends}, + lsb-base, Description: versatile anti ARP poisoning daemon ArpON (Arp handler inspectiON) is a portable handler daemon with some nice tools to handle all ARP aspects. diff -Nru arpon-2.7.2/debian/copyright arpon-3.0-ng+dfsg1/debian/copyright --- arpon-2.7.2/debian/copyright 2015-02-08 12:25:04.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/copyright 2017-09-07 18:26:55.000000000 +0000 @@ -1,29 +1,81 @@ -This package was debianized by Giuseppe Iuculano on -Tue, 29 Jul 2008 23:31:41 +0200. - -It was downloaded from http://arpon.sourceforge.net - -Upstream Author: Andrea Di Pasquale - -Copyright: - -License: - - Redistribution and use in source and binary forms, with or without - modification, are permitted under the terms of the BSD License. - - THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - SUCH DAMAGE. - - -The Debian packaging is © 2008, Giuseppe Iuculano and -is licensed under the BSD +Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Upstream-Name: Arpon +Source: http://arpon.sourceforge.net + The doc directory is removed from the source tarball, because it contains: + * A corporate logo as image. + * Multiple PDF files without sources. +Files-Excluded: doc + +Files: * +Copyright: 2008-2016, Andrea Di Pasquale +License: BSD-2-clause + +Files: */CMakeLists.txt cmake/* +Copyright: 2008-2016, Giuseppe Marco Randazzo + 2008-2016, Andrea Di Pasquale +License: BSD-2-clause + +Files: src/queue.h +Copyright: 1991, 1993, The Regents of the University of California. +License: BSD-4-clause + +Files: debian/* +Copyright: 2008-2015, Giuseppe Iuculano + 2017, Lukas Schwaighofer +License: BSD-2-clause + +License: BSD-2-clause + Copyright (C) 2008-2016 Andrea Di Pasquale + All rights reserved. + . + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + . + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + . + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + . + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + THE POSSIBILITY OF SUCH DAMAGE. + +License: BSD-4-clause + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. All advertising materials mentioning features or use of this software + must display the following acknowledgement: + This product includes software developed by the University of + California, Berkeley and its contributors. + 4. Neither the name of the University nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + . + THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + SUCH DAMAGE. diff -Nru arpon-2.7.2/debian/dirs arpon-3.0-ng+dfsg1/debian/dirs --- arpon-2.7.2/debian/dirs 2015-02-08 12:25:04.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/dirs 1970-01-01 00:00:00.000000000 +0000 @@ -1,4 +0,0 @@ -usr/sbin -var/log/arpon -usr/share/man/man8/ -etc/ diff -Nru arpon-2.7.2/debian/docs arpon-3.0-ng+dfsg1/debian/docs --- arpon-2.7.2/debian/docs 2015-02-08 12:25:04.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/docs 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -AUTHOR -doc/* diff -Nru arpon-2.7.2/debian/gbp.conf arpon-3.0-ng+dfsg1/debian/gbp.conf --- arpon-2.7.2/debian/gbp.conf 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/gbp.conf 2017-09-07 18:26:55.000000000 +0000 @@ -0,0 +1,15 @@ +[DEFAULT] +pristine-tar = True +cleaner = /bin/true +debian-branch = debian/master +upstream-branch = upstream/latest + +[buildpackage] +sign-tags = True +ignore-branch = True + +[import-orig] +filter-pristine-tar = True + +[pq] +patch-numbers = False diff -Nru arpon-2.7.2/debian/init.d arpon-3.0-ng+dfsg1/debian/init.d --- arpon-2.7.2/debian/init.d 2015-02-08 12:25:04.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/init.d 1970-01-01 00:00:00.000000000 +0000 @@ -1,261 +0,0 @@ -#!/bin/sh -# -### BEGIN INIT INFO -# Provides: arpon -# Required-Start: $network $local_fs $remote_fs -# Required-Stop: $remote_fs $local_fs -# Should-Start: $named -# Should-Stop: -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: Start arpon at boot time -### END INIT INFO - -PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin - -DAEMON=/usr/sbin/arpon -NAME=arpon -DESC="anti ARP poisoning daemon" -LOGDIR=/var/log/arpon # Log directory to use - -PIDFILE=/var/run/$NAME.pid - -test -x $DAEMON || exit 0 - -. /lib/lsb/init-functions - -# Default options, these can be overriden by the information -# at /etc/default/arpon -DAEMON_OPTS="-d -l /var/log/arpon/arpon.log" # Additional options given to the server - -DIETIME=4 # Time to wait for the server to die, in seconds - # If this value is set too low you might not - # let some servers to die gracefully and - # 'restart' will not work - -#STARTTIME=2 # Time to wait for the server to start, in seconds - # If this value is set each time the server is - # started (on start or restart) the script will - # stall to try to determine if it is running - # If it is not set and the server takes time - # to setup a pid file the log message might - # be a false positive (says it did not start - # when it actually did) - -LOGFILE=$LOGDIR/$NAME.log # Server logfile -#DAEMONUSER=arpon # Users to run the daemons as. If this value - # is set start-stop-daemon will chuid the server - -# Include defaults if available -if [ -f /etc/default/$NAME ] ; then - . /etc/default/$NAME -fi - -# Use this if you want the user to explicitly set 'RUN' in -# /etc/default/ -if [ "x$RUN" != "xyes" ] ; then - log_failure_msg "$NAME disabled, please adjust the configuration to your needs " - log_failure_msg "and then set RUN to 'yes' in /etc/default/$NAME to enable it." - exit 0 -fi - -set -e - -running_pid() { -# Check if a given process pid's cmdline matches a given name - pid=$1 - name=$2 - [ -z "$pid" ] && return 1 - [ ! -d /proc/$pid ] && return 1 - cmd=`cat /proc/$pid/cmdline | tr "\000" "\n"|head -n 1 |cut -d : -f 1` - # Is this the expected server - [ "$cmd" != "$name" ] && return 1 - return 0 -} - -running() { -# Check if the process is running looking at /proc -# (works for all users) - - # No pidfile, probably no daemon present - [ ! -f "$PIDFILE" ] && return 1 - pid=`cat $PIDFILE` - running_pid $pid $DAEMON || return 1 - return 0 -} - -start_server() { -# Start the process using the wrapper - if [ -z "$DAEMONUSER" ] ; then - start-stop-daemon --start --quiet --pidfile $PIDFILE \ - --exec $DAEMON -- $DAEMON_OPTS -# errcode=$? - else -# if we are using a daemonuser then change the user id - start-stop-daemon --start --quiet --pidfile $PIDFILE \ - --chuid $DAEMONUSER \ - --exec $DAEMON -- $DAEMON_OPTS - errcode=$? - fi - #return $errcode - if running ; then - return 0 - fi -} - -stop_server() { -# Stop the process using the wrapper - if [ -z "$DAEMONUSER" ] ; then - killproc -p $PIDFILE $DAEMON - errcode=$? - else -# if we are using a daemonuser then look for process that match - start-stop-daemon --stop --quiet --pidfile $PIDFILE \ - --user $DAEMONUSER \ - --exec $DAEMON - errcode=$? - fi - - return $errcode -} - -reload_server() { - [ ! -f "$PIDFILE" ] && return 1 - pid=pidofproc $PIDFILE # This is the daemon's pid - # Send a SIGHUP - kill -1 $pid - return $? -} - -force_stop() { -# Force the process to die killing it manually - [ ! -e "$PIDFILE" ] && return - if running ; then - kill -15 $pid - # Is it really dead? - sleep "$DIETIME"s - if running ; then - kill -9 $pid - sleep "$DIETIME"s - if running ; then - echo "Cannot kill $NAME (pid=$pid)!" - exit 1 - fi - fi - fi - rm -f $PIDFILE -} - - -case "$1" in - start) - log_daemon_msg "Starting $DESC " "$NAME" - # Check if it's running first - if running ; then - log_progress_msg "apparently already running" - log_end_msg 0 - exit 0 - fi - if start_server ; then - # NOTE: Some servers might die some time after they start, - # this code will detect this issue if STARTTIME is set - # to a reasonable value - [ -n "$STARTTIME" ] && sleep $STARTTIME # Wait some time - if running ; then - # It's ok, the server started and is running - log_end_msg 0 - else - # It is not running after we did start - log_end_msg 1 - fi - else - # Either we could not start it - log_end_msg 1 - fi - ;; - stop) - log_daemon_msg "Stopping $DESC" "$NAME" - if running ; then - # Only stop the server if we see it running - errcode=0 - stop_server || errcode=$? - log_end_msg $errcode - else - # If it's not running don't do anything - log_progress_msg "apparently not running" - log_end_msg 0 - exit 0 - fi - ;; - force-stop) - # First try to stop gracefully the program - $0 stop - if running; then - # If it's still running try to kill it more forcefully - log_daemon_msg "Stopping (force) $DESC" "$NAME" - errcode=0 - force_stop || errcode=$? - log_end_msg $errcode - fi - ;; - restart|force-reload) - log_daemon_msg "Restarting $DESC" "$NAME" - errcode=0 - stop_server || errcode=$? - # Wait some sensible amount, some server need this - [ -n "$DIETIME" ] && sleep $DIETIME - start_server || errcode=$? - [ -n "$STARTTIME" ] && sleep $STARTTIME - running || errcode=$? - log_end_msg $errcode - ;; - status) - - log_daemon_msg "Checking status of $DESC" "$NAME" - if running ; then - log_progress_msg "running" - log_end_msg 0 - else - log_progress_msg "apparently not running" - log_end_msg 1 - exit 1 - fi - ;; - # Use this if the daemon cannot reload - reload) - log_warning_msg "Reloading $NAME daemon: not implemented, as the daemon" - log_warning_msg "cannot re-read the config file (use restart)." - ;; - # And this if it cann - #reload) - # - # If the daemon can reload its config files on the fly - # for example by sending it SIGHUP, do it here. - # - # If the daemon responds to changes in its config file - # directly anyway, make this a do-nothing entry. - # - # log_daemon_msg "Reloading $DESC configuration files" "$NAME" - # if running ; then - # reload_server - # if ! running ; then - # Process died after we tried to reload - # log_progress_msg "died on reload" - # log_end_msg 1 - # exit 1 - # fi - # else - # log_progress_msg "server is not running" - # log_end_msg 1 - # exit 1 - # fi - #;; - - *) - N=/etc/init.d/$NAME - echo "Usage: $N {start|stop|force-stop|restart|force-reload|status}" >&2 - exit 1 - ;; -esac - -exit 0 diff -Nru arpon-2.7.2/debian/NEWS arpon-3.0-ng+dfsg1/debian/NEWS --- arpon-2.7.2/debian/NEWS 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/NEWS 2017-09-07 18:26:55.000000000 +0000 @@ -0,0 +1,11 @@ +arpon (3.0-ng+dfsg1-1) unstable; urgency=low + + ArpON 3.0-ng is a complete rewrite of arpon and the upgrade requires manual + work. The configuration file is now /etc/arpon.conf (/etc/arpon.sarpi is no + longer used). You have to manually migrate to the new configuration. See + the arpon(8) man page for details. + + The contents of /etc/default/arpon has changed as well. Read the comments + in that file and adjust it as required. + + -- Lukas Schwaighofer Mon, 04 Sep 2017 20:14:21 +0200 diff -Nru arpon-2.7.2/debian/patches/01_fix_path.patch arpon-3.0-ng+dfsg1/debian/patches/01_fix_path.patch --- arpon-2.7.2/debian/patches/01_fix_path.patch 2015-02-08 12:25:04.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/patches/01_fix_path.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -Author: Giuseppe Iuculano -Description: fix some path and use libdumbnet ---- a/Makefile -+++ b/Makefile -@@ -53,8 +53,8 @@ clean: - rm -f $(EXEC) - - install: -- install $(EXEC) $(DESTDIR)/sbin -- install $(MAN) $(DESTDIR)/usr/share/man/man8/ -+ install -D $(EXEC) $(DESTDIR)/usr/sbin/$(EXEC) -+ install -D $(MAN) $(DESTDIR)/usr/share/man/$(MAN) - - uninstall: - rm -f $(DESTDIR)/sbin/$(EXEC) diff -Nru arpon-2.7.2/debian/patches/02_fix_hypen.patch arpon-3.0-ng+dfsg1/debian/patches/02_fix_hypen.patch --- arpon-2.7.2/debian/patches/02_fix_hypen.patch 2015-02-08 12:25:04.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/patches/02_fix_hypen.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,13 +0,0 @@ -Author: Giuseppe Iuculano -Description: Fix hypen. ---- a/man8/arpon.8 -+++ b/man8/arpon.8 -@@ -560,7 +560,7 @@ Prints help summary page. - \&With 0 nice (default), daemon mode, 2 interfaces, en0 with Dynamic - \&Arp Inspection, en1 with Static Arp Inspection and 2 logging files: - \& --\&# arpon -d -f darpi.log -g -i eth0 -z 100 -y -f sarpi.log -g -i eth1 -u 10 -s -+\&# arpon \-d \-f darpi.log \-g \-i eth0 \-z 100 \-y \-f sarpi.log \-g \-i eth1 \-u 10 \-s - \& - \& [09/05/2008 - 18:42:13 CEST] Task is forking to background, using /var/run/arpon.pid pid file... - \& diff -Nru arpon-2.7.2/debian/patches/arpon.sarpi.patch arpon-3.0-ng+dfsg1/debian/patches/arpon.sarpi.patch --- arpon-2.7.2/debian/patches/arpon.sarpi.patch 2015-02-08 12:25:04.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/patches/arpon.sarpi.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,15 +0,0 @@ -Index: arpon/etc/arpon.sarpi -=================================================================== ---- arpon.orig/etc/arpon.sarpi -+++ arpon/etc/arpon.sarpi -@@ -2,8 +2,8 @@ - # - - # Gw -- 192.168.1.1 00:25:53:29:f6:69 -+# 192.168.1.1 00:25:53:29:f6:69 - - # Virtual client -- 172.16.159.1 0:50:56:c0:0:8 -+# 172.16.159.1 0:50:56:c0:0:8 - # diff -Nru arpon-2.7.2/debian/patches/disable-cflags.patch arpon-3.0-ng+dfsg1/debian/patches/disable-cflags.patch --- arpon-2.7.2/debian/patches/disable-cflags.patch 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/patches/disable-cflags.patch 2017-09-07 18:26:55.000000000 +0000 @@ -0,0 +1,57 @@ +Description: Disable additional CFLAGS + CMAKE's default flags for build type release and also those added by the + maintainer should not be added for the debian version, disabling them +Author: Lukas Schwaighofer +Forwarded: not-needed + +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -32,7 +32,6 @@ + # + # The following variables can be modified: + # +-# CMAKE_BUILD_TYPE - Set build type: release or debug + # CMAKE_INCLUDE_PATH - Set the include path + # CMAKE_LIBRARY_PATH - Set the library path + # CMAKE_C_FLAGS - Set flags for the C compiler +@@ -76,26 +75,6 @@ + + find_package(System) + +-if(NOT CMAKE_BUILD_TYPE) +- set(CMAKE_BUILD_TYPE Release +- CACHE STRING "Choose the type of build, options are: Debug Release" +- FORCE) +-endif(NOT CMAKE_BUILD_TYPE) +- +-string(TOLOWER "${CMAKE_BUILD_TYPE}" cmake_build_type_tolower) +- +-if(cmake_build_type_tolower STREQUAL "debug") +- message(STATUS "Build type: Debug") +- +- set(CMAKE_BUILD_TYPE "Debug") +- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -Wextra -Wformat=2 -Winit-self -Wreturn-type -Wswitch-default -Wswitch-enum -Wunused-parameter -Wuninitialized -Wstrict-aliasing=3 -Wstrict-overflow=5 -Wdeclaration-after-statement -Wundef -Wpointer-arith -Wunsafe-loop-optimizations -Wbad-function-cast -Wcast-qual -Wcast-align -Wwrite-strings -Wconversion -Wsizeof-pointer-memaccess -Wlogical-op -Waggregate-return -Wstrict-prototypes -Wold-style-declaration -Wmissing-prototypes -Wmissing-declarations -Wredundant-decls -Wnested-externs -Winline -Wlong-long -Wvariadic-macros -Wvarargs -Wvla -Wdisabled-optimization -Woverlength-strings -O0 -g -ggdb") +-else(cmake_build_type_tolower STREQUAL "debug") +- message(STATUS "Build type: Release") +- +- set(CMAKE_BUILD_TYPE "Release") +- set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Werror -Wextra -O3 -DNDEBUG") +-endif(cmake_build_type_tolower STREQUAL "debug") +- + find_package(Headers) + find_package(Pthreads) + find_package(Librt) +@@ -107,13 +86,6 @@ + set(CMAKE_INSTALL_PREFIX "/" CACHE PATH "ArpON install prefix" FORCE) + endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) + +-if(cmake_build_type_tolower STREQUAL "debug") +- message(STATUS "Include path: ${CMAKE_INCLUDE_PATH}") +- message(STATUS "Library path: ${CMAKE_LIBRARY_PATH}") +- message(STATUS "C compiler flags: ${CMAKE_C_FLAGS}") +- message(STATUS "Install prefix: ${CMAKE_INSTALL_PREFIX}") +-endif(cmake_build_type_tolower STREQUAL "debug") +- + add_subdirectory(src) + #add_subdirectory(doc) + add_subdirectory(man8) diff -Nru arpon-2.7.2/debian/patches/fix_path.patch arpon-3.0-ng+dfsg1/debian/patches/fix_path.patch --- arpon-2.7.2/debian/patches/fix_path.patch 2015-02-08 12:25:04.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/patches/fix_path.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -Index: arpon/src/CMakeLists.txt -=================================================================== ---- arpon.orig/src/CMakeLists.txt -+++ arpon/src/CMakeLists.txt -@@ -8,7 +8,7 @@ if(${CMAKE_INSTALL_PREFIX} STREQUAL "/") - set(arpon_sarpi /etc/arpon.sarpi) - set(install_prefix /sbin) - else(${CMAKE_INSTALL_PREFIX} STREQUAL "/") -- set(arpon_sarpi ${CMAKE_INSTALL_PREFIX}/etc/arpon.sarpi) -+ set(arpon_sarpi /etc/arpon.sarpi) - set(install_prefix ${CMAKE_INSTALL_PREFIX}/sbin) - endif(${CMAKE_INSTALL_PREFIX} STREQUAL "/") - -Index: arpon/etc/CMakeLists.txt -=================================================================== ---- arpon.orig/etc/CMakeLists.txt -+++ arpon/etc/CMakeLists.txt -@@ -14,7 +14,7 @@ if(${CMAKE_INSTALL_PREFIX} STREQUAL "/") - COMPONENT Etcfile) - else(${CMAKE_INSTALL_PREFIX} STREQUAL "/") - install(FILES ${arpon_etc_src} -- DESTINATION ${CMAKE_INSTALL_PREFIX}/etc -+ DESTINATION /etc - PERMISSIONS OWNER_READ GROUP_READ WORLD_READ - COMPONENT Etcfile) - endif(${CMAKE_INSTALL_PREFIX} STREQUAL "/") -Index: arpon/man8/CMakeLists.txt -=================================================================== ---- arpon.orig/man8/CMakeLists.txt -+++ arpon/man8/CMakeLists.txt -@@ -10,7 +10,7 @@ set(arpon_man_src "${CMAKE_SOURCE_DIR}/m - if(${CMAKE_INSTALL_PREFIX} STREQUAL "/") - set(arpon_sarpi_file "/etc/arpon.sarpi") - else(${CMAKE_INSTALL_PREFIX} STREQUAL "/") -- set(arpon_sarpi_file "${CMAKE_INSTALL_PREFIX}/etc/arpon.sarpi") -+ set(arpon_sarpi_file "/etc/arpon.sarpi") - endif(${CMAKE_INSTALL_PREFIX} STREQUAL "/") - - FILE(READ ${arpon_man_src} FILE_CONTENT) diff -Nru arpon-2.7.2/debian/patches/gcc-7-fixes.patch arpon-3.0-ng+dfsg1/debian/patches/gcc-7-fixes.patch --- arpon-2.7.2/debian/patches/gcc-7-fixes.patch 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/patches/gcc-7-fixes.patch 2017-09-07 18:26:55.000000000 +0000 @@ -0,0 +1,48 @@ +Description: Fix gcc-7 compile errors + * Fix comparison between pointer and zero character constant. + * Fix implicit fallthrough by adding a break (though the break will never be + reached since exit is called anyways). + * Add fallthrough comment where fallthrough is intentional. Gcc parses this + comment and recognizes the fallthrough as intentional. +Author: Lukas Schwaighofer +Bug: https://sourceforge.net/p/arpon/bugs/1/ + +--- a/src/opt.c ++++ b/src/opt.c +@@ -222,6 +222,7 @@ + /* Print the version command option, cleanup and exit. */ + std_version(); + exit_cleanup(true); ++ break; + + case 'h': + MSG_DEBUG("-h or --help command option"); +@@ -229,6 +230,7 @@ + /* Print the help screen command option, cleanup and exit. */ + std_help(); + exit_cleanup(true); ++ break; + + case '?': + case ':': +@@ -285,8 +287,8 @@ + } + + /* Re-initialize the interface name command option to no interface? */ +- if (opt->interface != '\0') +- memset(opt->interface, '\0', (size_t)IF_NAMESIZE); ++ if (opt->interface != NULL) ++ memset(opt->interface, 0, (size_t)IF_NAMESIZE); + + /* Set the value of the interface name command option. */ + memcpy(opt->interface, interface, len); +--- a/src/sig.c ++++ b/src/sig.c +@@ -204,6 +204,7 @@ + case SIGINT: + /* Remove ^C symbol from the output terminal. */ + printf("\r"); ++ /* FALLTHRU */ + + case SIGTERM: + MSG_DEBUG("Caught %s (%d)..", SIG_ITOA(sig), sig); diff -Nru arpon-2.7.2/debian/patches/installed-files-paths.patch arpon-3.0-ng+dfsg1/debian/patches/installed-files-paths.patch --- arpon-2.7.2/debian/patches/installed-files-paths.patch 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/patches/installed-files-paths.patch 2017-09-07 18:26:55.000000000 +0000 @@ -0,0 +1,55 @@ +Description: Adjust intalled files and paths + * Arpon is installed to /usr/sbin (not /sbin) in Debian. + * Log file gets placed in a separate folder for logrotate. + * Do not install empty log file and pidfile, will be created dynamically on + daemon startup. + * Doc directory has been cleaned to be DFSG conform, disabled in Cmake. +Author: Lukas Schwaighofer +Forwarded: not-needed + +--- a/src/CMakeLists.txt ++++ b/src/CMakeLists.txt +@@ -30,12 +30,12 @@ + # + + if(${CMAKE_INSTALL_PREFIX} STREQUAL "/") +- set(ARPON_SBIN /sbin/arpon) ++ set(ARPON_SBIN /usr/sbin/arpon) + set(ARPON_DOC /usr/share/doc/arpon/index.html) + set(ARPON_ETC /etc/arpon.conf) +- set(ARPON_LOG /var/log/arpon.log) ++ set(ARPON_LOG /var/log/arpon/arpon.log) + set(ARPON_PID /var/run/arpon.pid) +- set(install_prefix /sbin) ++ set(install_prefix /usr/sbin) + else(${CMAKE_INSTALL_PREFIX} STREQUAL "/") + set(ARPON_SBIN ${CMAKE_INSTALL_PREFIX}/sbin/arpon) + set(ARPON_DOC ${CMAKE_INSTALL_PREFIX}/share/doc/arpon/index.html) +--- a/log/CMakeLists.txt ++++ b/log/CMakeLists.txt +@@ -33,7 +33,7 @@ + + if(${CMAKE_INSTALL_PREFIX} STREQUAL "/") + install(FILES ${arpon_log_src} +- DESTINATION /var/log ++ DESTINATION /var/log/arpon + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ + COMPONENT Log) + else(${CMAKE_INSTALL_PREFIX} STREQUAL "/") +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -115,11 +115,11 @@ + endif(cmake_build_type_tolower STREQUAL "debug") + + add_subdirectory(src) +-add_subdirectory(doc) ++#add_subdirectory(doc) + add_subdirectory(man8) + add_subdirectory(etc) +-add_subdirectory(log) +-add_subdirectory(run) ++#add_subdirectory(log) ++#add_subdirectory(run) + + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/scripts/cmake_uninstall.cmake.in" diff -Nru arpon-2.7.2/debian/patches/man-spelling.patch arpon-3.0-ng+dfsg1/debian/patches/man-spelling.patch --- arpon-2.7.2/debian/patches/man-spelling.patch 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/patches/man-spelling.patch 2017-09-07 18:26:55.000000000 +0000 @@ -0,0 +1,27 @@ +Description: Fix spelling errors in man page. +Author: Lukas Schwaighofer +Bug: https://sourceforge.net/p/arpon/bugs/2/ + +--- a/man8/arpon.8 ++++ b/man8/arpon.8 +@@ -197,9 +197,9 @@ + .PP + The ArpON daemon sets two fundamental kernel network parameters via the sysctl interface on the specified network interface: + .PP +-1) The \fBarp_ignore\fR kernel parameter of the specified network interface is always setted to 8 by ArpON. This is done to disable, in the specified network interface of the Operating System, the sending of the ARP replies in response to received ARP requests for all local addresses (the ARP replies on the specified network interface, will be sent by ArpON instead of the Operating System). ++1) The \fBarp_ignore\fR kernel parameter of the specified network interface is always set to 8 by ArpON. This is done to disable, in the specified network interface of the Operating System, the sending of the ARP replies in response to received ARP requests for all local addresses (the ARP replies on the specified network interface, will be sent by ArpON instead of the Operating System). + .PP +-2) The \fBarp_accept\fR kernel parameter of the specified network interface is always setted to 0 by ArpON. This is done to disable, in the specified network interface of the Operating System, the creating of the new IP entries in the ARP cache triggered by the unsolicited and gratuitous ARP requests and replies (the IP entries in the ARP cache on the specified network interface, will be created or updated by ArpON as static or dynamic IP entries instead of the Operating System). ++2) The \fBarp_accept\fR kernel parameter of the specified network interface is always set to 0 by ArpON. This is done to disable, in the specified network interface of the Operating System, the creating of the new IP entries in the ARP cache triggered by the unsolicited and gratuitous ARP requests and replies (the IP entries in the ARP cache on the specified network interface, will be created or updated by ArpON as static or dynamic IP entries instead of the Operating System). + .PP + The ArpON daemon restores the previously values read from the arp_ignore and arp_accept kernel parameters of the specified network interface when it receives an interrupt signal (SIGINT) or a termination signal (SIGTERM). Remember to restore the values of the arp_ignore and arp_accept kernel parameters of the specified network interface (the default values are 0 for both), if you have terminated the ArpON daemon with other signals, e.g. kill signal (SIGKILL). + .PP +@@ -439,7 +439,7 @@ + .PP + .SH AUTHOR + .TP +-ArpON was writen by Andrea Di Pasquale aka "spikey" . ++ArpON was written by Andrea Di Pasquale aka "spikey" . + .Ve + .PP + .SH COPYRIGHT AND LICENSING diff -Nru arpon-2.7.2/debian/patches/series arpon-3.0-ng+dfsg1/debian/patches/series --- arpon-2.7.2/debian/patches/series 2015-02-08 12:25:04.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/patches/series 2017-09-07 18:26:55.000000000 +0000 @@ -1,2 +1,4 @@ -arpon.sarpi.patch -fix_path.patch +gcc-7-fixes.patch +installed-files-paths.patch +man-spelling.patch +disable-cflags.patch diff -Nru arpon-2.7.2/debian/postrm arpon-3.0-ng+dfsg1/debian/postrm --- arpon-2.7.2/debian/postrm 2015-02-08 12:25:04.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/postrm 1970-01-01 00:00:00.000000000 +0000 @@ -1,43 +0,0 @@ -#!/bin/sh -# postrm script for arpon -# -# see: dh_installdeb(1) - -set -e - -# summary of how this script can be called: -# * `remove' -# * `purge' -# * `upgrade' -# * `failed-upgrade' -# * `abort-install' -# * `abort-install' -# * `abort-upgrade' -# * `disappear' -# -# for details, see http://www.debian.org/doc/debian-policy/ or -# the debian-policy package - - -case "$1" in - purge) - rm -f /var/log/arpon/* - - ;; - remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) - ;; - - *) - echo "postrm called with unknown argument \`$1'" >&2 - exit 1 - ;; -esac - -# dh_installdeb will replace this with shell code automatically -# generated by other debhelper scripts. - -#DEBHELPER# - -exit 0 - - diff -Nru arpon-2.7.2/debian/README.Debian arpon-3.0-ng+dfsg1/debian/README.Debian --- arpon-2.7.2/debian/README.Debian 2015-02-08 12:25:04.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/README.Debian 2017-09-07 18:26:55.000000000 +0000 @@ -1,14 +1,8 @@ arpon for Debian ---------------- -ArpON is a versatile an anti arp poisoning daemon. At this moment there are two arp inspection mode: +The version of arpon in Debian ships without the full documentation, because it +contains non-DFSG-free material. You can read the documentation online: +http://arpon.sourceforge.net/ -- SARPI (Static Arp Inspection) -- DARPI (Dynamic Arp Inspection) - -If you use a static ip address, you should use SARPI. If you use dhcp to retrive your ip address, you should -use DARPI - -Choose your inspection type, and edit /etc/default/arpon - - -- Giuseppe Iuculano Tue, 29 Jul 2008 23:31:41 +0200 + -- Lukas Schwaighofer Tue, 05 Sep 2017 20:00:09 +0200 diff -Nru arpon-2.7.2/debian/rules arpon-3.0-ng+dfsg1/debian/rules --- arpon-2.7.2/debian/rules 2015-02-08 12:25:04.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/rules 2017-09-07 18:26:55.000000000 +0000 @@ -1,32 +1,15 @@ #!/usr/bin/make -f -# See debhelper(7) (uncomment to enable) -# output every command that modifies files on the build system. -#DH_VERBOSE = 1 - -# see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/* -DPKG_EXPORT_BUILDFLAGS = 1 -include /usr/share/dpkg/default.mk -# see FEATURE AREAS in dpkg-buildflags(1) +#DH_VERBOSE = 1 export DEB_BUILD_MAINT_OPTIONS = hardening=+all +# Without NDEBUG, the log is flooded with debug messages that cannot be +# disabled. +export DEB_CPPFLAGS_MAINT_APPEND = -DNDEBUG -# see ENVIRONMENT in dpkg-buildflags(1) -# package maintainers to append CFLAGS -#export DEB_CFLAGS_MAINT_APPEND = -Wall -pedantic -# package maintainers to append LDFLAGS -#export DEB_LDFLAGS_MAINT_APPEND = -Wl,--as-needed - - -# main packaging script based on dh7 syntax %: - dh $@ - -# debmake generated override targets -# This is example for Cmake (See http://bugs.debian.org/641051 ) -#override_dh_auto_configure: -# dh_auto_configure -- \ -# -DCMAKE_LIBRARY_PATH=$(DEB_HOST_MULTIARCH) - - - + dh $@ +# Install prefix has to be set to / (instead of /usr), otherwise most of the +# paths are prefixed with /usr (e.g. /usr/etc/arpon.conf) +override_dh_auto_configure: + dh_auto_configure -- -DCMAKE_INSTALL_PREFIX=/ diff -Nru arpon-2.7.2/debian/watch arpon-3.0-ng+dfsg1/debian/watch --- arpon-2.7.2/debian/watch 2015-02-08 12:25:04.000000000 +0000 +++ arpon-3.0-ng+dfsg1/debian/watch 2017-09-07 18:26:55.000000000 +0000 @@ -1,3 +1,4 @@ -version=3 +version=4 -http://sf.net/arpon/ArpON-(.*)\.tar\.gz +opts="dversionmangle=s/\+dfsg\d*$//,repacksuffix=+dfsg1,repack,compression=xz" \ + http://sf.net/arpon/ArpON-(.*)\.tar\.gz diff -Nru arpon-2.7.2/doc/algorithms/algorithms.html arpon-3.0-ng+dfsg1/doc/algorithms/algorithms.html --- arpon-2.7.2/doc/algorithms/algorithms.html 2014-10-09 17:25:10.000000000 +0000 +++ arpon-3.0-ng+dfsg1/doc/algorithms/algorithms.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,97 +0,0 @@ - - - - - - - .: ArpON - Algorithms :. - - - - - - - - -
-
-
-
- -
-

- -
.: ArpON algorithms :.

-

- -
-ArpON is a Proactive based solution and it defines the policies between all hosts on preventing Man In The Middle through ARP spoofing, ARP Cache Poisoning or ARP Poison Routing (APR). -

-ArpON don't use centralized server or encryption. It uses an authentication of type cooperative between the hosts based on the policies that all hosts with ArpON must respect. These policies allow exactly total protection by these attacks for all hosts that use ArpON. -

-To understand these policies, you need to understand the final algorithm called HARPI and HARPI is like a puzzle. To understand HARPI, you need to understand the pieces of SARPI and DARPI. Finally, HARPI combines SARPI and DARPI in an one protocol solution. -
- -

- -
.: SARPI - Static ARP inspection :.

- -
- -
-SARPI detects and blocks Man In The Middle (MITM) attack through ARP Spoofing, ARP Cache Poisoning, ARP Poison Routing (APR) attacks and it is countermeasure against these attacks and the derived attacks by it, which Sniffing, Hijacking, Injection, Filtering & co attacks for more complex derived attacks, as: DNS Spoofing, WEB Spoofing, Session Hijacking and SSL/TLS Hijacking & co attacks.

-This algorithm is therefore a Point-to-Point, Point-to-Multipoint and Multipoint based solution that requires a daemon in every host of the connection for authenticate each host through an authentication of type cooperative between the hosts.

-It manages a list with static entries, making it an optimal choice in those statically configured networks without DHCP.
-
- -
- -
- -

- -
.: DARPI - Dynamic ARP inspection :.

- -
- -
-DARPI detects and blocks Man In The Middle (MITM) attack through ARP Spoofing, ARP Cache Poisoning, ARP Poison Routing (APR) attacks and it is countermeasure against these attacks and the derived attacks by it, which Sniffing, Hijacking, Injection, Filtering & co attacks for more complex derived attacks, as: DNS Spoofing, WEB Spoofing, Session Hijacking and SSL/TLS Hijacking & co attacks.

-This algorithm is therefore a Point-to-Point, Point-to-Multipoint and Multipoint based solution that requires a daemon in every host of the connection for authenticate each host through an authentication of type cooperative between the hosts.

-It manages uniquely a list with dynamic entries. Therefore it's an optimal solution in dynamically configured networks having DHCP.
-
- -
- -
-

- - -
.: HARPI - Hybrid ARP inspection :.

- -
- -
-HARPI detects and blocks Man In The Middle (MITM) attack through ARP Spoofing, ARP Cache Poisoning, ARP Poison Routing (APR) attacks and it is countermeasure against these attacks and the derived attacks by it, which Sniffing, Hijacking, Injection, Filtering & co attacks for more complex derived attacks, as: DNS Spoofing, WEB Spoofing, Session Hijacking and SSL/TLS Hijacking & co attacks.

-This algorithm is therefore a Point-to-Point, Point-to-Multipoint and Multipoint based solution that requires a daemon in every host of the connection for authenticate each host through an authentication of type cooperative between the hosts.

-It manages two lists simultaneously: a list with static entries and a list with dynamic entries. Therefore it's an optimal solution in statically and dynamically (DHCP) configured networks together.
-
- -
- -
-

- -
- - - -
Copyright (C) 2008-2014 Andrea Di Pasquale < spikey.it@gmail.com >
- - - - - - Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/algorithms/img/algo/DARPI2.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/algorithms/img/algo/DARPI2.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/algorithms/img/algo/DARPI.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/algorithms/img/algo/DARPI.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/algorithms/img/algo/HARPI2.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/algorithms/img/algo/HARPI2.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/algorithms/img/algo/HARPI.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/algorithms/img/algo/HARPI.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/algorithms/img/algo/SARPI2.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/algorithms/img/algo/SARPI2.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/algorithms/img/algo/SARPI.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/algorithms/img/algo/SARPI.jpg differ diff -Nru arpon-2.7.2/doc/algorithms/style.css arpon-3.0-ng+dfsg1/doc/algorithms/style.css --- arpon-2.7.2/doc/algorithms/style.css 2011-05-10 18:50:07.000000000 +0000 +++ arpon-3.0-ng+dfsg1/doc/algorithms/style.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,478 +0,0 @@ -/* My css to my website */ - -* -{ - padding: 0; - margin: 0; -} - -#contorno -{ - /*background-color: black;*/ - /*padding-top: 3px; - padding-bottom: 3px; - padding-left: 8px; - padding-right: 8px;*/ - width: 100%; - height: 100%; - -moz-border-radius: 8px; -webkit-border-radius: 8px; - margin-left: auto; - margin-right: auto; - margin-top: auto; -} - -#contorno1 -{ - /*background-color: black;*/ - /*padding-top: 3px; - padding-bottom: 3px; - padding-left: 8px; - padding-right: 8px;*/ - width: 70%; - height: 100%; - -moz-border-radius: 8px; -webkit-border-radius: 8px; - margin-left: auto; - margin-right: auto; - margin-top: auto; -} - -#tab2 -{ - padding-left: 10px; - padding-right: 10px; -} - -#tab3 -{ - padding-left: 5px; - padding-right: 5px; -} - -#tab -{ - padding-left: 50px; - padding-right: 10px; -} - -body -{ - color: black; - /*background-color: black;*/ - font-family: "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif, Comic Sans MS; - font-size: 83%; - /*margin: 20px auto; - padding-left: 10px; - padding-right: 10px; */ -} - - -iframe -{ - width: 100%; - height: 380px; - overflow: auto; - border: 0px solid white; - padding: 5px; -} - -a:link -{ - text-decoration: none; - color: orange; -} - -a:visited -{ - color: orange; - text-decoration: none; -} - -a:hover -{ - color: black; - background: orange; - /*background-color:#DFE2E7;*/ - text-decoration: overline underline; -} - -a.img:hover { - background-color: white; -} - -a.im -{ - background: white; -} - -a:hover.im -{ - background: white; -} - -#question li -{ - list-style-type: none; -} - -li -{ - list-style-type: none; - margin-left: 1em; -} - - -#header -{ - clear:both; - color: #9400d3; - background-color:#FFFFFF; - padding: 2px 0px 2px 0px; - margin:0px 0px 0px 0px; -} - -#titolo -{ - color: #9400d3; - background-color:#FFFFFF; - font-size: 210%; - font-weight: bold; - padding: 0px 0px 0px 0px; - margin: 0px 0px 0px 0px; -} - -#title -{ - color: #666666; - font-weight: bold; - text-family: verdana; - font-size: 100%; -} - -#motto -{ - color: #666666; - background-color: #FFFFFF; - font-size: 70%; - font-weight: normal; - font-style: normal; - padding: 0px 2px 0px 0px; -} - -#informazioni -{ - font-size:100%; - padding: 5px 8px 5px 5px; - margin: 5px 0px 5px 5px; - width: 100%; - float:left; -} - -#question -{ - color: black; - font-family: Arial; - font-size: 150%; - font-weight: bold; -} - -#author -{ - padding-left: 25px; -} - -#return -{ - font-size: 100%; - padding: 0px 0px 0px 0px; - margin: 0px -140px 15px 0px; - width: 100%; - text-align: right; - /*float: right;*/ -} - -#download -{ - font-size: 100%; - margin: 10px; - /*width: 80%;*/ - text-align: right; - /*float: right;*/ -} - -#download a -{ - font-size: 90%; - margin: 10px; -} - -#download a:hover -{ - text-decoration: overline underline; - font-size: 105%; - margin: 10px; - color: #CC0000; - background-color:#DFE2E7; - cursor: crosshair; -} - -#path -{ - width: 100%; - clear: both; - float: left; - font-size: 75%; - font-weight: normal; - margin: 4px 0px 5px 0px; - border-top: 5px solid black; -} - -#links -{ - width: 100%; - float: left; - height: 15%; - margin: 0; - padding: 0; - font: 13px Verdana; -} - -#links ul -{ - margin: 0; - padding: 0; - list-style-type: none; - list-style-image: none; -} - - -#links li -{ - display: inline; - width: 20%; - float:left; - margin: 0; - padding: 0; -} - -#links a:hover -{ - color: black; - background: #ba55d3; - /*background-color:#DFE2E7;*/ - text-decoration: overline underline; - cursor: crosshair; -} - -div#links a span -{ - display: none; -} - -#links a:hover span -{ - display: block; - position: absolute; - top: 20%; - right: 0%; - left: 0%; - width: 100%; - padding: 0; - margin: 5px; - color: #9400d3; - background: white; - font: 10px sans-serif; - text-align: center; -} - -pre:hover -{ - font-style: italic; - font-weight: bold; - color: #9400d3; - background-color:#DFE2E7; -} - -fieldset.main -{ - border: 1px solid black; - -moz-border-radius: 10px; -webkit-border-radius: 10px; -} - - -a.menu1, a.menu1:visited { - color: #ffffff; - background-color: orange; - font-family: Verdana; - font-weight: bold; - display: block; - padding: 4px; - text-decoration: none; - -moz-border-radius: 10px; -webkit-border-radius: 10px; - border: 1px solid black; - margin: 3px; - width: 120px; -} - -a.menu1:hover { - color: #ffffff; - background-color: black; - border: 1px solid orange; - text-decoration: none; -} - -a.menu2, a.menu2:visited { - color: #ffffff; - background-color: orange; - font-family: Verdana; - font-weight: bold; - display: block; - padding: 4px; - text-decoration: none; - -moz-border-radius: 10px; -webkit-border-radius: 10px; - border: 1px solid black; - margin: 3px; - width: 120px; -} - -a.menu2:hover { - color: #ffffff; - background-color: black; - border: 1px solid orange; - text-decoration: none; -} - -a.menu3, a.menu3:visited { - color: #ffffff; - background-color: orange; - font-family: Verdana; - font-weight: bold; - display: block; - padding: 4px; - text-decoration: none; - -moz-border-radius: 10px; -webkit-border-radius: 10px; - border: 1px solid black; - margin: 3px; - width: 120px; -} - -a.menu3:hover { - color: #ffffff; - background-color: black; - border: 1px solid orange; - text-decoration: none; -} - -a.menu4, a.menu4:visited { - color: #ffffff; - background-color: orange; - font-family: Verdana; - font-weight: bold; - display: block; - padding: 4px; - text-decoration: none; - -moz-border-radius: 10px; -webkit-border-radius: 10px; - border: 1px solid black; - margin: 3px; - width: 120px; -} - -a.menu4:hover { - color: #ffffff; - background-color: black; - border: 1px solid orange; - text-decoration: none; -} - - -a.menu5, a.menu5:visited { - color: #ffffff; - background-color: orange; - font-family: Verdana; - font-weight: bold; - display: block; - padding: 4px; - text-decoration: none; - -moz-border-radius: 10px; -webkit-border-radius: 10px; - border: 1px solid black; - margin: 3px; - width: 120px; -} - -a.menu5:hover { - color: #ffffff; - background-color: black; - border: 1px solid orange; - text-decoration: none; -} - -a.menu6, a.menu6:visited { - color: #ffffff; - background-color: orange; - font-family: Verdana; - font-weight: bold; - display: block; - padding: 4px; - text-decoration: none; - -moz-border-radius: 10px; -webkit-border-radius: 10px; - border: 1px solid black; - margin: 3px; - width: 120px; -} - -a.menu6:hover { - color: #ffffff; - background-color: black; - border: 1px solid orange; - text-decoration: none; -} - -td.menu -{ - text-align: center; - width: 16%; -} - -#image -{ - text-align: center; -} - -#menu { - margin-bottom: 10px; - margin-bottom: 10px; -} - -body.color1 #menu a.menu1, -body.color2 #menu a.menu2, -body.color3 #menu a.menu3, -body.color4 #menu a.menu4, -body.color5 #menu a.menu5, -body.color6 #menu a.menu6 -{ - background: white; - color: black; -} - - - -legend.header -{ - font-size: 60px; - color: #009999; - text-align: center; - font-family: tahoma; - margin-bottom: 8px; -} - -#footer -{ - color:#666666; - background-color:#FFFFFF; - width: 100%; - /*border-top: 5px solid black;*/ - font-size: 60%; - text-align: center; - line-height: 1.5em; - clear: both; - margin-bottom: 3px; -} diff -Nru arpon-2.7.2/doc/documentation/documentation.html arpon-3.0-ng+dfsg1/doc/documentation/documentation.html --- arpon-2.7.2/doc/documentation/documentation.html 2014-10-09 17:25:20.000000000 +0000 +++ arpon-3.0-ng+dfsg1/doc/documentation/documentation.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,190 +0,0 @@ - - - - - - - .: ArpON - Documentation :. - - - - - - - - -
-
- -
-

- - -
.: ArpON Documentation :.
- -


- -
-ArpON is a Point-to-Point, Point-to-Multipoint and Multipoint based solutions that requires a daemon in every host of the connection for authenticate each host through an authentication of type cooperative between the hosts.

-Here is explained how ArpON works with many examples. -


- -
.: Point-to-Point based solution :.
- -
-This connection is an example of Point-to-Point based solution. -
-

- -
.: Point-to-Multipoint based solution :.
- -
-This connection is an example of Point-to-Multipoint based solution. -
-

- -
.: Multipoint based solution :.
- -
-These connections are an example of Multipoint based solution. -
-

- -
.: Man In The Middle through local ARP Poisoning/Spoofing :.
- -
-This scenario shows the attack: -
-This scenario shows the defense with ArpON point to point based solution: -
-
-As you can see, the hosts communicate safely, leaving the attacker out. -ARP cache poisoning has no more effect, and the connection is back again secure. -


- -
.: Man In The Middle through global ARP Poisoning/Spoofing :.
- -
-This scenario shows the attack: -
-This scenario shows the defense with ArpON multipoint based solution: -
-
-As you can see, the hosts communicate safely, leaving the attacker out. -ARP cache poisoning has no more effect, and the connection is back again secure. -


- -
.: Man In The Middle through ARP Poisoning/Spoofing for DNS Spoofing :.
- -
-1° scenario: The server is internal to network and the client is external to network. -
-This scenario shows the attack: -
-This scenario shows the defense with ArpON point to point based solution: -
-
-As you can see, the hosts communicate safely, leaving the attacker out. -ARP cache poisoning has no more effect, and the connection is back again secure. -


- -2° scenario: The server is external to network and the client is internal to network. -
-This scenario shows the attack: -
-This scenario shows the defense with ArpON point to point based solution: -
-
-As you can see, the hosts communicate safely, leaving the attacker out. -ARP cache poisoning has no more effect, and the connection is back again secure. -


- -
.: Man In The Middle through ARP Poisoning/Spoofing for WEB Spoofing :.
- -
-1° scenario: The server is internal to network and the client is external to network. -
-This scenario shows the attack: -
-This scenario shows the defense with ArpON point to point based solution: -
-
-As you can see, the hosts communicate safely, leaving the attacker out. -ARP cache poisoning has no more effect, and the connection is back again secure. -


- -2° scenario: The server is external to network and the client is internal to network. -
-This scenario shows the attack: -
-This scenario shows the defense with ArpON point to point based solution: -
-
-As you can see, the hosts communicate safely, leaving the attacker out. -ARP cache poisoning has no more effect, and the connection is back again secure. -


- -
.: Man In The Middle through ARP Poisoning/Spoofing for Session Hijacking :.
- -
-1° scenario: The server is internal to network and the client is external to network. -
-This scenario shows the attack: -
-This scenario shows the defense with ArpON point to point based solution: -
-
-As you can see, the hosts communicate safely, leaving the attacker out. -ARP cache poisoning has no more effect, and the connection is back again secure. -


- -2° scenario: The server is external to network and the client is internal to network. -
-This scenario shows the attack: -
-This scenario shows the defense with ArpON point to point based solution: -
-
-As you can see, the hosts communicate safely, leaving the attacker out. -ARP cache poisoning has no more effect, and the connection is back again secure. -


- -
.: Man In The Middle through ARP Poisoning/Spoofing for SSL/TLS Hijacking :.
- -
-1° scenario: The server is internal to network and the client is external to network. -
-This scenario shows the attack: -
-This scenario shows the defense with ArpON point to point based solution: -
-
-As you can see, the hosts communicate safely, leaving the attacker out. -ARP cache poisoning has no more effect, and the connection is back again secure. -


- -2° scenario: The server is external to network and the client is internal to network. -
-This scenario shows the attack: -
-This scenario shows the defense with ArpON point to point based solution: -
-
-As you can see, the hosts communicate safely, leaving the attacker out. -ARP cache poisoning has no more effect, and the connection is back again secure. -


- -
- -
-
- -
Copyright (C) 2008-2014 Andrea Di Pasquale < spikey.it@gmail.com >
- - - - - - Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/10aSSLHijacking.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/10aSSLHijacking.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/10bSSLHijackingProtect.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/10bSSLHijackingProtect.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/1aLocalARPPoisoning.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/1aLocalARPPoisoning.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/1bLocalARPPoisoningProtect.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/1bLocalARPPoisoningProtect.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/2aGlobalARPPoisoning.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/2aGlobalARPPoisoning.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/2bGlobalARPPoisoningProtect.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/2bGlobalARPPoisoningProtect.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/3aDNSSpoofing.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/3aDNSSpoofing.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/3bDNSSpoofingProtect.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/3bDNSSpoofingProtect.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/4aDNSSpoofing.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/4aDNSSpoofing.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/4bDNSSpoofingProtect.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/4bDNSSpoofingProtect.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/5aWEBSpoofing.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/5aWEBSpoofing.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/5bWEBSpoofingProtect.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/5bWEBSpoofingProtect.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/6aWEBSpoofing.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/6aWEBSpoofing.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/6bWEBSpoofingProtect.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/6bWEBSpoofingProtect.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/7aSessionHijacking.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/7aSessionHijacking.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/7bSessionHijackingProtect.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/7bSessionHijackingProtect.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/8aSessionHijacking.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/8aSessionHijacking.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/8bSessionHijackingProtect.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/8bSessionHijackingProtect.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/9aSSLHijacking.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/9aSSLHijacking.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/9bSSLHijackingProtect.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/9bSSLHijackingProtect.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/Multipoint.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/Multipoint.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/PointToMultipoint.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/PointToMultipoint.jpg differ Binary files /tmp/tmp1rFOcc/vQrp3kB3xC/arpon-2.7.2/doc/documentation/img/doc/PointToPoint.jpg and /tmp/tmp1rFOcc/bDUezX_SdL/arpon-3.0-ng+dfsg1/doc/documentation/img/doc/PointToPoint.jpg differ diff -Nru arpon-2.7.2/doc/documentation/style.css arpon-3.0-ng+dfsg1/doc/documentation/style.css --- arpon-2.7.2/doc/documentation/style.css 2011-05-10 18:41:12.000000000 +0000 +++ arpon-3.0-ng+dfsg1/doc/documentation/style.css 1970-01-01 00:00:00.000000000 +0000 @@ -1,478 +0,0 @@ -/* My css to my website */ - -* -{ - padding: 0; - margin: 0; -} - -#contorno -{ - /*background-color: black;*/ - /*padding-top: 3px; - padding-bottom: 3px; - padding-left: 8px; - padding-right: 8px;*/ - width: 100%; - height: 100%; - -moz-border-radius: 8px; -webkit-border-radius: 8px; - margin-left: auto; - margin-right: auto; - margin-top: auto; -} - -#contorno1 -{ - /*background-color: black;*/ - /*padding-top: 3px; - padding-bottom: 3px; - padding-left: 8px; - padding-right: 8px;*/ - width: 70%; - height: 100%; - -moz-border-radius: 8px; -webkit-border-radius: 8px; - margin-left: auto; - margin-right: auto; - margin-top: auto; -} - -#tab2 -{ - padding-left: 10px; - padding-right: 10px; -} - -#tab3 -{ - padding-left: 5px; - padding-right: 5px; -} - -#tab -{ - padding-left: 50px; - padding-right: 10px; -} - -body -{ - color: black; - /*background-color: black;*/ - font-family: "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif, Comic Sans MS; - font-size: 83%; - /*margin: 20px auto; - padding-left: 10px; - padding-right: 10px; */ -} - - -iframe -{ - width: 100%; - height: 380px; - overflow: auto; - border: 0px solid white; - padding: 5px; -} - -a:link -{ - text-decoration: none; - color: orange; -} - -a:visited -{ - color: orange; - text-decoration: none; -} - -a:hover -{ - color: black; - background: orange; - /*background-color:#DFE2E7;*/ - text-decoration: overline underline; -} - -a.img:hover { - background-color: white; -} - -a.im -{ - background: white; -} - -a:hover.im -{ - background: white; -} - -#question li -{ - list-style-type: none; -} - -li -{ - list-style-type: none; - margin-left: 1em; -} - - -#header -{ - clear:both; - color: #9400d3; - background-color:#FFFFFF; - padding: 2px 0px 2px 0px; - margin:0px 0px 0px 0px; -} - -#titolo -{ - color: #9400d3; - background-color:#FFFFFF; - font-size: 210%; - font-weight: bold; - padding: 0px 0px 0px 0px; - margin: 0px 0px 0px 0px; -} - -#title -{ - color: #666666; - font-weight: bold; - text-family: verdana; - font-size: 100%; -} - -#motto -{ - color: #666666; - background-color: #FFFFFF; - font-size: 70%; - font-weight: normal; - font-style: normal; - padding: 0px 2px 0px 0px; -} - -#informazioni -{ - font-size:100%; - padding: 5px 8px 5px 5px; - margin: 5px 0px 5px 5px; - width: 100%; - float:left; -} - -#question -{ - color: black; - font-family: Arial; - font-size: 150%; - font-weight: bold; -} - -#author -{ - padding-left: 25px; -} - -#return -{ - font-size: 100%; - padding: 0px 0px 0px 0px; - margin: 0px -140px 15px 0px; - width: 100%; - text-align: right; - /*float: right;*/ -} - -#download -{ - font-size: 100%; - margin: 10px; - /*width: 80%;*/ - text-align: right; - /*float: right;*/ -} - -#download a -{ - font-size: 90%; - margin: 10px; -} - -#download a:hover -{ - text-decoration: overline underline; - font-size: 105%; - margin: 10px; - color: #CC0000; - background-color:#DFE2E7; - cursor: crosshair; -} - -#path -{ - width: 100%; - clear: both; - float: left; - font-size: 75%; - font-weight: normal; - margin: 4px 0px 5px 0px; - border-top: 5px solid black; -} - -#links -{ - width: 100%; - float: left; - height: 15%; - margin: 0; - padding: 0; - font: 13px Verdana; -} - -#links ul -{ - margin: 0; - padding: 0; - list-style-type: none; - list-style-image: none; -} - - -#links li -{ - display: inline; - width: 20%; - float:left; - margin: 0; - padding: 0; -} - -#links a:hover -{ - color: black; - background: #ba55d3; - /*background-color:#DFE2E7;*/ - text-decoration: overline underline; - cursor: crosshair; -} - -div#links a span -{ - display: none; -} - -#links a:hover span -{ - display: block; - position: absolute; - top: 20%; - right: 0%; - left: 0%; - width: 100%; - padding: 0; - margin: 5px; - color: #9400d3; - background: white; - font: 10px sans-serif; - text-align: center; -} - -pre:hover -{ - font-style: italic; - font-weight: bold; - color: #9400d3; - background-color:#DFE2E7; -} - -fieldset.main -{ - border: 1px solid black; - -moz-border-radius: 10px; -webkit-border-radius: 10px; -} - - -a.menu1, a.menu1:visited { - color: #ffffff; - background-color: orange; - font-family: Verdana; - font-weight: bold; - display: block; - padding: 4px; - text-decoration: none; - -moz-border-radius: 10px; -webkit-border-radius: 10px; - border: 1px solid black; - margin: 3px; - width: 120px; -} - -a.menu1:hover { - color: #ffffff; - background-color: black; - border: 1px solid orange; - text-decoration: none; -} - -a.menu2, a.menu2:visited { - color: #ffffff; - background-color: orange; - font-family: Verdana; - font-weight: bold; - display: block; - padding: 4px; - text-decoration: none; - -moz-border-radius: 10px; -webkit-border-radius: 10px; - border: 1px solid black; - margin: 3px; - width: 120px; -} - -a.menu2:hover { - color: #ffffff; - background-color: black; - border: 1px solid orange; - text-decoration: none; -} - -a.menu3, a.menu3:visited { - color: #ffffff; - background-color: orange; - font-family: Verdana; - font-weight: bold; - display: block; - padding: 4px; - text-decoration: none; - -moz-border-radius: 10px; -webkit-border-radius: 10px; - border: 1px solid black; - margin: 3px; - width: 120px; -} - -a.menu3:hover { - color: #ffffff; - background-color: black; - border: 1px solid orange; - text-decoration: none; -} - -a.menu4, a.menu4:visited { - color: #ffffff; - background-color: orange; - font-family: Verdana; - font-weight: bold; - display: block; - padding: 4px; - text-decoration: none; - -moz-border-radius: 10px; -webkit-border-radius: 10px; - border: 1px solid black; - margin: 3px; - width: 120px; -} - -a.menu4:hover { - color: #ffffff; - background-color: black; - border: 1px solid orange; - text-decoration: none; -} - - -a.menu5, a.menu5:visited { - color: #ffffff; - background-color: orange; - font-family: Verdana; - font-weight: bold; - display: block; - padding: 4px; - text-decoration: none; - -moz-border-radius: 10px; -webkit-border-radius: 10px; - border: 1px solid black; - margin: 3px; - width: 120px; -} - -a.menu5:hover { - color: #ffffff; - background-color: black; - border: 1px solid orange; - text-decoration: none; -} - -a.menu6, a.menu6:visited { - color: #ffffff; - background-color: orange; - font-family: Verdana; - font-weight: bold; - display: block; - padding: 4px; - text-decoration: none; - -moz-border-radius: 10px; -webkit-border-radius: 10px; - border: 1px solid black; - margin: 3px; - width: 120px; -} - -a.menu6:hover { - color: #ffffff; - background-color: black; - border: 1px solid orange; - text-decoration: none; -} - -td.menu -{ - text-align: center; - width: 16%; -} - -#image -{ - text-align: center; -} - -#menu { - margin-bottom: 10px; - margin-bottom: 10px; -} - -body.color1 #menu a.menu1, -body.color2 #menu a.menu2, -body.color3 #menu a.menu3, -body.color4 #menu a.menu4, -body.color5 #menu a.menu5, -body.color6 #menu a.menu6 -{ - background: white; - color: black; -} - - - -legend.header -{ - font-size: 60px; - color: #009999; - text-align: center; - font-family: tahoma; - margin-bottom: 8px; -} - -#footer -{ - color:#666666; - background-color:#FFFFFF; - width: 100%; - /*border-top: 5px solid black;*/ - font-size: 60%; - text-align: center; - line-height: 1.5em; - clear: both; - margin-bottom: 3px; -} diff -Nru arpon-2.7.2/etc/arpon.conf arpon-3.0-ng+dfsg1/etc/arpon.conf --- arpon-2.7.2/etc/arpon.conf 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/etc/arpon.conf 2016-01-29 02:13:49.000000000 +0000 @@ -0,0 +1,23 @@ +# +# ArpON configuration file. +# +# See the arpon(8) man page for details. +# + +# +# Static entries matching the eth0 network interface: +# +# First static entry: +#192.168.1.1 58:ac:78:10:b9:77 +# Second static entry: +#192.168.1.3 d4:be:d9:fe:8b:45 +# Third static entry: +#192.168.1.4 90:94:e4:bb:1c:10 + +# +# Static entries matching the eth1 network interface: +# +# First static entry: +#10.0.1.1 58:ac:78:88:1a:bb +# Second static entry: +#10.0.10.1 90:94:e4:7e:f4:59 diff -Nru arpon-2.7.2/etc/arpon.sarpi arpon-3.0-ng+dfsg1/etc/arpon.sarpi --- arpon-2.7.2/etc/arpon.sarpi 2014-10-09 17:26:12.000000000 +0000 +++ arpon-3.0-ng+dfsg1/etc/arpon.sarpi 1970-01-01 00:00:00.000000000 +0000 @@ -1,9 +0,0 @@ -# Example of arpon.sarpi -# - - # Gw - 192.168.1.1 00:25:53:29:f6:69 - - # Virtual client - 172.16.159.1 0:50:56:c0:0:8 -# diff -Nru arpon-2.7.2/etc/CMakeLists.txt arpon-3.0-ng+dfsg1/etc/CMakeLists.txt --- arpon-2.7.2/etc/CMakeLists.txt 2014-10-10 18:31:54.000000000 +0000 +++ arpon-3.0-ng+dfsg1/etc/CMakeLists.txt 2016-01-29 01:53:47.000000000 +0000 @@ -1,20 +1,50 @@ -# Install arpon.sarpi # -# Copyright 2014 gmrandazzo@gmail.com +# Copyright (C) 2008-2016 Andrea Di Pasquale +# Copyright (C) 2008-2016 Giuseppe Marco Randazzo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# +# $ArpON: CMakeLists.txt,v 3.0-ng 01/29/2016 02:53:50 spikey Exp $ # -# Redistribution AND use is allowed according to the terms of the New -# BSD license. -set(arpon_etc_src "${CMAKE_SOURCE_DIR}/etc/arpon.sarpi") +set(arpon_etc_src "${CMAKE_SOURCE_DIR}/etc/arpon.conf") if(${CMAKE_INSTALL_PREFIX} STREQUAL "/") - install(FILES ${arpon_etc_src} - DESTINATION /etc - PERMISSIONS OWNER_READ GROUP_READ WORLD_READ - COMPONENT Etcfile) + install(FILES ${arpon_etc_src} + DESTINATION /etc + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + COMPONENT Etc) else(${CMAKE_INSTALL_PREFIX} STREQUAL "/") - install(FILES ${arpon_etc_src} - DESTINATION ${CMAKE_INSTALL_PREFIX}/etc - PERMISSIONS OWNER_READ GROUP_READ WORLD_READ - COMPONENT Etcfile) + install(FILES ${arpon_etc_src} + DESTINATION ${CMAKE_INSTALL_PREFIX}/etc + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + COMPONENT Etc) endif(${CMAKE_INSTALL_PREFIX} STREQUAL "/") + +# +# EOF +# +# vim:ts=4:expandtab +# diff -Nru arpon-2.7.2/INSTALL arpon-3.0-ng+dfsg1/INSTALL --- arpon-2.7.2/INSTALL 2014-10-15 22:45:47.000000000 +0000 +++ arpon-3.0-ng+dfsg1/INSTALL 1970-01-01 00:00:00.000000000 +0000 @@ -1,73 +0,0 @@ -ArpON's install: -================ - -In order to use the ArpON daemon you need these following libraries and software installed in your system: - - - LibPcap >= 0.9.8 - - LibNet11 >= 1.1.2.1 - - LibDNet >= 1.11 - - LibPthread >= all - - Cmake >= 2.6 - -To install ArpON in default path /usr/ do these command: - - $ cd /path/ArpON-$VERSION/ - - where $VERSION is the current version of your ArpON tarball, then: - - $ mkdir build - $ cd build - $ cmake .. - $ make - $ sudo make install - -To install ArpON in a specific destination dir do these command: - - $ mkdir build - $ cd build - $ cmake -DCMAKE_INSTALL_PREFIX=/path/to/install .. - $ make - $ sudo make install - - Usually, the paths of the installation are: /, /usr/ or /usr/local/ - -If you want personalize the compilation parameters with the your custom CFLAGS do these commands: - - $ mkdir build - $ cd build - $ cmake -DCMAKE_INSTALL_PREFIX=/path/to/install -DCMAKE_C_FLAGS="-your-personal-cflags" .. - $ make - $ sudo make install - -To uninstall ArpON do this command: - - $ sudo make uninstall - -If the your dependencies are installed in the other specific paths, you can add this with: - - -DCMAKE_INCLUDE_PATH="/path/to/include/" - -DCMAKE_LIBRARY_PATH="/path/to/library/" - -To use ArpON: - - $ arpon -h - -For any questions about: - - 1) The general options and example of ArpON daemon you can read: - - $ man 8 arpon - - 2) The algorithms documentation you can read: - - /path/ArpON-$VERSION/doc/algorithms/algorithms.html - - 3) The documentation you can read: - - /path/ArpON-$VERSION/doc/documentation/documentation.html - -Please send problems, bugs, questions, desirable enhancements, patch, source code contributions, etc. to: - - Andrea Di Pasquale - -Thank you very much. diff -Nru arpon-2.7.2/LICENSE arpon-3.0-ng+dfsg1/LICENSE --- arpon-2.7.2/LICENSE 2014-10-09 17:28:13.000000000 +0000 +++ arpon-3.0-ng+dfsg1/LICENSE 2016-01-29 01:54:02.000000000 +0000 @@ -1,25 +1,25 @@ - Copyright (C) 2008-2014 Andrea Di Pasquale - All rights reserved. +Copyright (C) 2008-2016 Andrea Di Pasquale +All rights reserved. - Redistribution and use in source and binary forms, with or without - modification, are permitted provided that the following conditions - are met: - 1. Redistributions of source code must retain the above copyright - notice(s), this list of conditions and the following disclaimer as - the first lines of this file unmodified other than the possible - addition of one or more copyright notices. - 2. Redistributions in binary form must reproduce the above copyright - notice(s), this list of conditions and the following disclaimer in the - documentation and/or other materials provided with the distribution. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY - EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY - DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - DAMAGE. +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGE. diff -Nru arpon-2.7.2/log/CMakeLists.txt arpon-3.0-ng+dfsg1/log/CMakeLists.txt --- arpon-2.7.2/log/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/log/CMakeLists.txt 2016-01-29 01:54:18.000000000 +0000 @@ -0,0 +1,50 @@ +# +# Copyright (C) 2008-2016 Andrea Di Pasquale +# Copyright (C) 2008-2016 Giuseppe Marco Randazzo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# +# $ArpON: CMakeLists.txt,v 3.0-ng 01/29/2016 02:54:19 spikey Exp $ +# + +set(arpon_log_src "${CMAKE_SOURCE_DIR}/log/arpon.log") + +if(${CMAKE_INSTALL_PREFIX} STREQUAL "/") + install(FILES ${arpon_log_src} + DESTINATION /var/log + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ + COMPONENT Log) +else(${CMAKE_INSTALL_PREFIX} STREQUAL "/") + install(FILES ${arpon_log_src} + DESTINATION ${CMAKE_INSTALL_PREFIX}/log + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ + COMPONENT Log) +endif(${CMAKE_INSTALL_PREFIX} STREQUAL "/") + +# +# EOF +# +# vim:ts=4:expandtab +# diff -Nru arpon-2.7.2/man8/arpon.8 arpon-3.0-ng+dfsg1/man8/arpon.8 --- arpon-2.7.2/man8/arpon.8 2014-10-14 01:55:14.000000000 +0000 +++ arpon-3.0-ng+dfsg1/man8/arpon.8 2016-01-29 01:54:52.000000000 +0000 @@ -1,31 +1,31 @@ -.\" $ arpon.8,v 1.54 07/06/2008 15:35:20 zeld Exp $ -.\" $ arpon.8.v 2.7.2 10/14/2014 03:54:27 spikey Exp $ .\" -.\" Copyright (c) 2008-2014 Andrea Di Pasquale -.\" All rights reserved. +.\" Copyright (C) 2008-2016 Andrea Di Pasquale +.\" All rights reserved. .\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice(s), this list of conditions and the following disclaimer as -.\" the first lines of this file unmodified other than the possible -.\" addition of one or more copyright notices. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice(s), this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY -.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -.\" DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY -.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -.\" CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH -.\" DAMAGE. +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +.\" IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, +.\" INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +.\" SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +.\" STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +.\" IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +.\" THE POSSIBILITY OF SUCH DAMAGE. +.\" +.\" $ArpON: arpon.8,v 3.0-ng 01/29/2016 02:54:53 spikey Exp $ .\" .\" Standard preamble: .\" ======================================================================== @@ -156,347 +156,336 @@ .\" ======================================================================== .\" .\"End of Preamble. Start of man page. -.TH arpon 8 "14 October 2014" +.TH arpon 8 "29 January 2016" "ArpON 3.0-ng" .SH NAME -arpon \- ARP handler inspection +\fBArpON\fR \- ARP handler inspection +.ti +8 +.br +.ad +.PP +.SH IMPORTANT NOTICE +.PP +Since ArpON 3.0-ng (next generation), ArpON has been rewritten from scratch, therefore all the old versions of ArpON (lower of 3.0-ng) are deprecated. Please upgrade all installations of ArpON and read carefully the documentation specified below and this man page of ArpON. +.PP .SH SYNOPSIS .na .B arpon -[ -.B \-npqfgiolcxSyDHevh -] - -.br -.ti +6 -[ -.B \-n -.I Nice value -] -[ -.B \-p -.I Pid file -] -.br -.ti +6 -[ -.B \-f -.I Log file -] -.br -.ti +6 -[ -.B \-i -.I Iface -] -.br -.ti +6 -[ -.B \-c -.I Cache file -] -[ -.B \-x -.I Timeout -] -.br -.ti +6 -[ -.B \-y -.I Timeout -] +[\fBOPTIONS\fR] [\fBSARPI\fR | \fBDARPI\fR | \fBHARPI\fR] .br .ti +8 .br .ad .SH DESCRIPTION .LP -ArpON (ARP handler inspection) is a portable handler daemon that make ARP protocol secure in order to avoid the Man In The Middle (MITM) attack through ARP Spoofing, ARP Cache Poisoning or ARP Poison Routing (APR) attacks. It blocks also the derived attacks by it, which Sniffing, Hijacking, Injection, Filtering & co attacks for more complex derived attacks, as: DNS Spoofing, WEB Spoofing, Session Hijacking and SSL/TLS Hijacking & co attacks. -.PP -This is possible using three kinds of anti ARP Spoofing tecniques: the first is based on SARPI or "Static ARP Inspection" in statically configured networks without DHCP; the second on DARPI or "Dynamic ARP Inspection" in dynamically configured networks having DHCP; the third on HARPI or "Hybrid ARP Inspection" in "hybrid" networks, that is in statically and dynamically (DHCP) configured networks together. -.PP -ArpON is therefore a proactive Point-to-Point, Point-to-Multipoint and Multipoint based solution that requires a daemon in every host of the connection for authenticate each host through an authentication of type cooperative between the hosts and that doesn't modify the classic ARP standard base protocol by IETF, but rather sets precise policies by using SARPI for static networks, DARPI for dynamic networks and HARPI for hybrid networks thus making today's standardized protocol working and secure from any foreign intrusion. +\fBArpON\fR (\fBARP handler inspection\fR) is a Host-based solution that make the ARP standardized protocol secure in order to avoid the Man In The Middle (MITM) attack through the ARP spoofing, ARP cache poisoning or ARP poison routing attack. .PP -.SH FEATURES +This is possible using three kinds of anti ARP spoofing techniques: .PP -- Support for interfaces: Ethernet, Wireless +1) \fBSARPI\fR (\fBStatic ARP Inspection\fR) for the statically configured networks without DHCP; .br -- Manages the network interface with: Unplug iface, Boot OS, Hibernation OS, Suspension OS +2) \fBDARPI\fR (\fBDynamic ARP Inspection\fR) for the dynamically configured networks with DHCP; .br -- Proactive based solution for connections: Point-to-Point, Point-to-Multipoint, Multipoint +3) \fBHARPI\fR (\fBHybrid ARP Inspection\fR) for the statically and dynamically configured networks with DHCP. +.PP +The goal of ArpON is therefore to provide a secure and efficient network daemon that provides the SARPI, DARPI and HARPI anti ARP spoofing technique, thus making the ARP standardized protocol secure from any foreign intrusion. +.PP +ArpON sets of policies in the ARP cache for all the static and or dynamic entries matching the specified network interface (or that matching the several specified network interfaces if run concurrently several daemons of ArpON for different network interfaces), through the run of SARPI, DARPI or HARPI anti ARP spoofing technique. +.PP +ArpON have to be run with the root privileges. ArpON have to be configured using command-line options and a configuration file. ArpON reloads the configuration of the specified network interface and rereads its configuration file when it receives a hangup signal (SIGHUP) by executing itself with the name and options it was started with. ArpON exits correctly when it receives an interrupt signal (SIGINT) or a termination signal (SIGTERM). +.PP +.SH IMPORTANT NOTE +.PP +The ArpON daemon sets two fundamental kernel network parameters via the sysctl interface on the specified network interface: +.PP +1) The \fBarp_ignore\fR kernel parameter of the specified network interface is always setted to 8 by ArpON. This is done to disable, in the specified network interface of the Operating System, the sending of the ARP replies in response to received ARP requests for all local addresses (the ARP replies on the specified network interface, will be sent by ArpON instead of the Operating System). +.PP +2) The \fBarp_accept\fR kernel parameter of the specified network interface is always setted to 0 by ArpON. This is done to disable, in the specified network interface of the Operating System, the creating of the new IP entries in the ARP cache triggered by the unsolicited and gratuitous ARP requests and replies (the IP entries in the ARP cache on the specified network interface, will be created or updated by ArpON as static or dynamic IP entries instead of the Operating System). +.PP +The ArpON daemon restores the previously values read from the arp_ignore and arp_accept kernel parameters of the specified network interface when it receives an interrupt signal (SIGINT) or a termination signal (SIGTERM). Remember to restore the values of the arp_ignore and arp_accept kernel parameters of the specified network interface (the default values are 0 for both), if you have terminated the ArpON daemon with other signals, e.g. kill signal (SIGKILL). +.PP +.SH OPTIONS SUMMARY +.PP +The available options are: +.PP +.TP +.SH GENERAL OPTIONS +.PP +.TP +\-d (\--daemon) +Daemonize the ArpON. +.TP +\-i (\--interface) +Use the specified network interface. +.PP +.TP +.SH SARPI 'STATIC ARP INSPECTION' OPTION +.PP +SARPI anti ARP spoofing technique manages and sets the policies in the ARP cache only for all the static entries matching the specified network interface, in order to avoid the Man In The Middle (MITM) attack through the ARP spoofing, ARP cache poisoning or ARP poison routing. Therefore SARPI is an optimal choice in those statically configured networks without DHCP. SARPI sets these policies: +.PP +1) \fBCLEAN\fR: SARPI cleans from the ARP cache only all the entries matching the specified network interface, that are present or not present in the configuration file; .br -- Type of authentication for host: Cooperative between the hosts +2) \fBUPDATE\fR: SARPI updates in the ARP cache only all the static entries matching the specified network interface, that are present in the configuration file; .br -- Support for networks: Statically, Dynamically (DHCP), Hybrid network that is statically and dynamically +3) \fBREFRESH\fR: SARPI refreshes in the ARP cache only a static entry matching the specified network interface, that is present in the configuration file; .br -- Retro compatible with: classic ARP standard base protocol by IETF +4) \fBALLOW\fR: SARPI sets up in the ARP cache only a dynamic entry matching the specified network interface, that is not present in the configuration file. +.PP +Therefore SARPI requires a specified network interface and the specification in the configuration file of the ARP cache only for all the static entries matching the specified network interface. +.TP +\-S (\--sarpi) +Run SARPI anti ARP spoofing technique. +.PP +.TP +.SH DARPI 'DYNAMIC ARP INSPECTION' OPTION +.PP +DARPI anti ARP spoofing technique manages and sets the policies in the ARP cache only for all the dynamic entries matching the specified network interface, in order to avoid the Man In The Middle (MITM) attack through the ARP spoofing, ARP cache poisoning or ARP poison routing. Therefore DARPI is an optimal choice in those dynamically configured networks with DHCP. DARPI sets these policies: +.PP +1) \fBCLEAN\fR: DARPI cleans from the ARP cache only all the entries matching the specified network interface; .br -- Support of Gratuitous ARP request and reply for: Failover Cluster, Cluster with load-balancing, High-Availability (HA) Cluster +2) \fBALLOW\fR: DARPI sets up in the ARP cache only a dynamic entry matching the specified network interface; .br -- Blocks the Man In The Middle (MITM) attack through: ARP Spoofing, ARP Cache Poisoning, ARP Poison Routing (APR) +3) \fBDENY\fR: DARPI cleans up from the ARP cache only a dynamic entry matching the specified network interface. +.PP +Therefore DARPI requires a specified network interface and it doesn't requires any specification in the configuration file of the ARP cache only for all the dynamic entries matching the specified network interface. +.TP +\-D (\--darpi) +Run DARPI anti ARP spoofing technique. +.PP +.TP +.SH HARPI 'HYBRID ARP INSPECTION' OPTION +.PP +HARPI anti ARP spoofing technique manages and sets the policies in the ARP cache for both all the static and dynamic entries matching the specified network interface, in order to avoid the Man In The Middle (MITM) attack through the ARP spoofing, ARP cache poisoning or ARP poison routing. Therefore HARPI is an optimal choice in those statically and dynamically configured networks with DHCP. HARPI sets and combines these policies of the SARPI and DARPI: +.PP +1) \fBCLEAN\fR: HARPI cleans from the ARP cache only all the entries matching the specified network interface, that are present or not present in the configuration file; .br -- Three kinds of anti ARP Spoofing tecniques: SARPI or Static ARP Inspection, DARPI or Dynamic ARP Inspection, HARPI or Hybrid ARP Inspection +2) \fBUPDATE\fR: HARPI updates in the ARP cache only all the static entries matching the specified network interface, that are present in the configuration file; .br -- Blocks the derived attacks: Sniffing, Hijacking, Injection, Filtering & co attacks +3) \fBREFRESH\fR: HARPI refreshes in the ARP cache only a static entry matching the specified network interface, that is present in the configuration file; .br -- Blocks the complex derived attacks: DNS Spoofing, WEB Spoofing, Session Hijacking, SSL/TLS Hijacking & co attacks +4) \fBALLOW\fR: HARPI sets up in the ARP cache only a dynamic entry matching the specified network interface, that is not present in the configuration file; .br -- Tested against: Ettercap, Cain & Abel, DSniff, Yersinia, scapy, netcut, Metasploit, arpspoof, sslsniff, sslstrip & co tools +5) \fBDENY\fR: HARPI cleans up from the ARP cache only a dynamic entry matching the specified network interface, that is not present in the configuration file. .PP -.SH OPTIONS +Therefore HARPI requires a specified network interface, the specification in the configuration file of the ARP cache only for all the static entries matching the specified network interface; instead it doesn't requires any specification in the configuration file of the ARP cache only for all the dynamic entries matching the specified network interface. .TP -.SH TASK MODE -.PP +\-H (\--harpi) +Run HARPI anti ARP spoofing technique. .PP .TP -\-n (\--nice) -Sets PID's CPU priority (Default: 0 nice). -.TP -\-p (\--pid-file) -Sets the pid file (Default /var/run/arpon.pid). +.SH STANDARD OPTIONS +.PP .TP -\-q (\--quiet) -Works in background task. -.IP +\-v (\--version) +Print the version and exit. .TP -.SH LOG MODE +\-h (\--help) +Print the help screen and exit. .PP +.SH FILES +.PP +The available files are: .PP .TP -\-f (\--log-file) -Sets the log file (Default: /var/log/arpon.log). +\fBARPON_ETC\fR +.br +The configuration file contains the configuration data of ArpON and it is used when run the SARPI or HARPI anti ARP spoofing technique, for the specification in the ARP cache only for all the static entries matching the specified network interface (or that matching the several specified network interfaces if run concurrently several daemons of ArpON for different network interfaces). This file should be writable by root only but it is recommended (though not necessary) that it be world-readable. .TP -\-g (\--log) -Works in logging mode. -.IP +\fBARPON_LOG\fR +.br +The log file contains the log data of ArpON. If there are several daemons of ArpON running concurrently for different network interfaces, this contains the log data of all the daemons of ArpON. This file should be readable only by root, and need not be readable by anyone else. .TP -.SH DEVICE MANAGER +\fBARPON_PID\fR +.br +The pid file contains the process ID of ArpON. If there are several daemons of ArpON running concurrently for different network interfaces, this contains the process ID of the one started last. The content of this file is not sensitive; it can be world-readable. +.Ve .PP -ArpON is an ARP handler and it is able to handle network devices automatically (default) or manually, to print a list of up network interfaces of the system. +.SH EXAMPLES .PP -It identifies the interface's datalink layer you are using but it supports only Ethernet/Wireless as datalink. It sets the netowrk interface and check running, online ready and it deletes the PROMISCUE flag. The online ready checks unplug (virtual and physical), boot, hibernation and suspension OS' features for Ethernet/Wireless card. It handles these features and reset the network interface automatically when it will ready. +These examples shows how to use all three kinds of anti ARP spoofing techniques. .PP +In the same host, we have three network interfaces with different subnet classes and we would set the ARP cache for all the static and dynamic entries matching the eth0, wlan0 and eth1 network interfaces. This scenario requires the run concurrently of three daemons of ArpON: .PP .TP -\-i (\--iface) -Sets your device manually. -.TP -\-o (\--iface-auto) -Sets device automatically. -.TP -\-l (\--iface-list) -Prints all supported devices. +.SH SARPI 'STATIC ARP INSPECTION' EXAMPLE .PP -.TP -.SH STATIC ARP INSPECTION +The eth0 network interface has the 192.168.1.2/24 IP address. We have only three static entries of the ARP cache: .PP -SARPI detects and blocks Man In The Middle (MITM) attack through ARP Spoofing, ARP Cache Poisoning, ARP Poison Routing (APR) attacks and it is countermeasure against these attacks and the derived attacks by it, which Sniffing, Hijacking, Injection, Filtering & co attacks for more complex derived attacks, as: DNS Spoofing, WEB Spoofing, Session Hijacking and SSL/TLS Hijacking & co attacks. +1) 192.168.1.1 at 58:ac:78:10:b9:77; +.br +2) 192.168.1.3 at d4:be:d9:fe:8b:45; +.br +3) 192.168.1.4 at 90:94:e4:bb:1c:10. .PP -This solution is therefore a Point-to-Point, Point-to-Multipoint and Multipoint based solution that requires a daemon in every host of the connection for authenticate each host through an authentication of type cooperative between the hosts. +and we have no dynamic entries of the ARP cache. This is the ideal case where we have to use the SARPI anti ARP spoofing technique, therefore specify in the configuration file of the ARP cache only all the static entries matching the eth0 network interface: .PP -It manages a list with static entries, making it an optimal choice in those statically configured networks without DHCP. +\& $ sudo nano ARPON_ETC .PP -Finally, it's possible to use SARPI as a daemon, using the "TASK MODE" and "LOG MODE" feature of ArpON. It supports daemon exit by SIGINT, SIGTERM, SIGQUIT and daemon reboot by SIGHUP and SIGCONT POSIX signals. +Therefore: .PP -.TP -\-c (\--sarpi-cache) -Sets SARPI entries from file (Default: arpon_sarpi). -.TP -\-x (\--sarpi-timeout) -Sets SARPI Cache refresh timeout (Default: 5 minuts). -.TP -\-S (\--sarpi) -Manages ARP Cache statically. +.Vb 13 +\& # +\& # ArpON configuration file. +\& # +\& # See the arpon(8) man page for details. +\& # +\& +\& # +\& # Static entries matching the eth0 network interface: +\& # +\& # First static entry: +\& 192.168.1.1 58:ac:78:10:b9:77 +\& # Second static entry: +\& 192.168.1.3 d4:be:d9:fe:8b:45 +\& # Third static entry: +\& 192.168.1.4 90:94:e4:bb:1c:10 +.Ve .PP -.TP -.SH DYNAMIC ARP INSPECTION +Daemonize the ArpON and run SARPI anti ARP spoofing technique on the eth0 network interface: .PP -DARPI detects and blocks Man In The Middle (MITM) attack through ARP Spoofing, ARP Cache Poisoning, ARP Poison Routing (APR) attacks and it is countermeasure against these attacks and the derived attacks by it, which Sniffing, Hijacking, Injection, Filtering & co attacks for more complex derived attacks, as: DNS Spoofing, WEB Spoofing, Session Hijacking and SSL/TLS Hijacking & co attacks. +\& $ sudo arpon -d -i eth0 -S .PP -This solution is therefore a Point-to-Point, Point-to-Multipoint and Multipoint based solution that requires a daemon in every host of the connection for authenticate each host through an authentication of type cooperative between the hosts. +Read the log file: .PP -It manages uniquely a list with dynamic entries. Therefore it's an optimal solution in dynamically configured networks having DHCP. +\& $ sudo tail -f ARPON_LOG .PP -Finally, it's possible to use DARPI as a daemon, using the "TASK MODE" and "LOG MODE" feature of ArpON. It supports daemon exit by SIGINT, SIGTERM, SIGQUIT and daemon reboot by SIGHUP and SIGCONT POSIX signals. +Read the pid file: .PP -.TP -\-y (\--darpi-timeout) -Sets DARPI entries response max timeout (Default: 5 seconds). -.TP -\-D (\--darpi) -Manages ARP Cache dynamically. +\& $ cat ARPON_PID .PP .TP -.SH HYBRID ARP INSPECTION +.SH DARPI 'DYNAMIC ARP INSPECTION' EXAMPLE .PP -HARPI detects and blocks Man In The Middle (MITM) attack through ARP Spoofing, ARP Cache Poisoning, ARP Poison Routing (APR) attacks and it is countermeasure against these attacks and the derived attacks by it, which Sniffing, Hijacking, Injection, Filtering & co attacks for more complex derived attacks, as: DNS Spoofing, WEB Spoofing, Session Hijacking and SSL/TLS Hijacking & co attacks. +The wlan0 network interface has the 172.16.1.2/24 IP address. We have no static entries of the ARP cache, and we have only dynamic entries of the ARP cache. This is the ideal case where we have to use the DARPI anti ARP spoofing technique, therefore daemonize the ArpON and run DARPI anti ARP spoofing technique on the wlan0 network interface: .PP -This solution is therefore a Point-to-Point, Point-to-Multipoint and Multipoint based solution that requires a daemon in every host of the connection for authenticate each host through an authentication of type cooperative between the hosts. +\& $ sudo arpon -d -i wlan0 -D .PP -It manages two lists simultaneously: a list with static entries and a list with dynamic entries. Therefore it's an optimal solution in statically and dynamically (DHCP) configured networks together. -.PP -Finally, it's possible to use DARPI as a daemon, using the "TASK MODE" and "LOG MODE" feature of ArpON. It supports daemon exit by SIGINT, SIGTERM, SIGQUIT and daemon reboot by SIGHUP and SIGCONT POSIX signals. +Read the log file: .PP -.TP -\-c (\--sarpi-cache) -Sets HARPI entries from file (Default: arpon_sarpi). -.TP -\-x (\--sarpi-timeout) -Sets HARPI Cache refresh timeout (Default: 5 minuts). -.TP -\-y (\--darpi-timeout) -Sets HARPI entries response max timeout (Default: 5 seconds). -.TP -\-H (\--harpi) -Manage ARP Cache statically and dynamically. +\& $ sudo tail -f ARPON_LOG .PP -.TP -.SH MISC FEATURES +Read the pid file: .PP -Other. -.TP -\-e (\--license) -Prints license page. -.TP -\-v (\--version) -Prints version number. -.TP -\-h (\--help) -Prints help summary page. - +\& $ cat ARPON_PID .PP -.SH EXAMPLES .TP -\&You remember that ArpON is a proactive Point-to-Point, Point-to-Multipoint and Multipoint based solution that requires a daemon in every host of the connection for authenticate each host through an authentication of type cooperative between the hosts. -.VE +.SH HARPI 'HYBRID ARP INSPECTION' EXAMPLE .PP -\&- \s-1SARPI\s0 \s-1"Static\s0 \s-1ARP\s0 \s-1Inspection":\s0 +The eth1 network interface has the 10.0.1.2/16 IP address. We have only two static entries of the ARP cache: +.PP +1) 10.0.1.1 at 58:ac:78:88:1a:bb; +.br +2) 10.0.10.1 at 90:94:e4:7e:f4:59. +.PP +and we have the rest of entries as dynamic entries of the ARP cache. This is the ideal case where we have to use the HARPI anti ARP spoofing technique, therefore specify in the configuration file of the ARP cache only all the static entries matching the eth1 network interface: +.PP +\& $ sudo nano ARPON_ETC +.PP +Therefore: .PP .Vb 13 -\& -\& Example of arpon_sarpi: -\& -\& # Example of arpon.sarpi -\& # -\& 192.168.1.1 0:25:53:29:f6:69 -\& 172.16.159.1 0:50:56:c0:0:8 -\% # -\& -\& With 1 minut of SARPI cache refresh timeout: -\& -\& riemann:build root# arpon -i en1 -x 1 -S -\& -\& 17:04:43 WAIT LINK on en1... -\& 17:04:47 SARPI on -\& DATE = <10/14/2014> -\& DEV = -\& HW = <0:23:6c:7f:28:e7> -\& IP = <192.168.1.4> -\& CACHE = -\& 17:04:47 ARP cache, REFRESH -\& src HW = <0:25:53:29:f6:69> -\& src IP = <192.168.1.1> -\& 17:05:04 ARP cache, IGNORE -\& src HW = <0:11:d8:70:ef:1f> -\& src IP = <192.168.1.75> -\& 17:05:47 ARP cache, UPDATE -\& src HW = <0:25:53:29:f6:69> -\& src IP = <192.168.1.1> -\& src HW = <0:50:56:c0:0:8> -\& src IP = <172.16.159.1> -\& ... -\& +\& # +\& # ArpON configuration file. +\& # +\& # See the arpon(8) man page for details. +\& # +\& +\& # +\& # Static entries matching the eth0 network interface: +\& # +\& # First static entry: +\& 192.168.1.1 58:ac:78:10:b9:77 +\& # Second static entry: +\& 192.168.1.3 d4:be:d9:fe:8b:45 +\& # Third static entry: +\& 192.168.1.4 90:94:e4:bb:1c:10 +\& +\& # +\& # Static entries matching the eth1 network interface: +\& # +\& # First static entry: +\& 10.0.1.1 58:ac:78:88:1a:bb +\& # Second static entry: +\& 10.0.10.1 90:94:e4:7e:f4:59 .Ve .PP +Daemonize the ArpON and run HARPI anti ARP spoofing technique on the eth1 network interface: .PP -\&- \s-1DARPI\s0 \s-1"Dynamic\s0 \s-1ARP\s0 \s-1Inspection":\s0 +\& $ sudo arpon -d -i eth1 -H .PP -.Vb 13 -\& -\& With 1 second of DARPI entries response max timeout: -\& -\& riemann:build root# arpon -i en1 -y 1 -D -\& -\& 17:10:24 WAIT LINK on en1... -\& 17:10:27 DARPI on -\& DATE = <10/14/2014> -\& DEV = -\& HW = <0:23:6c:7f:28:e7> -\& IP = <192.168.1.4> -\& 17:10:27 ARP cache, DENY -\& src HW = <0:11:d8:70:ef:1f> -\& src IP = <192.168.1.1> -\& 17:10:27 ARP cache, ACCEPT -\& src HW = <0:25:53:29:f6:69> -\& src IP = <192.168.1.1> -\& 17:10:31 ARP cache, ACCEPT -\& src HW = <0:11:d8:70:ef:1f> -\& src IP = <192.168.1.75> -\& ... -\& +Read the log file: +.PP +\& $ sudo tail -f ARPON_LOG +.PP +Read the pid file: +.PP +\& $ cat ARPON_PID .Ve .PP +.SH DOCUMENTATION +.TP +Please see also the documentation file: +.PP +\& \fBARPON_DOC\fR .PP -\&- \s-1HARPI\0 \s-1"Hybrid\s0 \s-1ARP\s0 \s-1Inspection":\s0 +It contains the retrieving tutorial; the building tutorial; the installation tutorial; the user tutorial with many examples and scenarios; the development tutorial with the Activity diagrams of the SARPI, DARPI and HARPI anti ARP spoofing technique and with modular source code well commented; the bug report tutorial that takes you step-by-step through all of the features of ArpON. +.Ve .PP -.Vb 13 -\& -\& Example of arpon_sarpi: -\& -\& # Example of arpon.sarpi -\& # -\& 192.168.1.1 0:25:53:29:f6:69 -\& 172.16.159.1 0:50:56:c0:0:8 -\% # -\& -\& With 6 minuts of SARPI Cache refresh timeout and 1 second of DARPI entries response max timeout: -\& -\& riemann:build root# arpon -i en1 -x 6 -y 1 -H -\& -\& 17:14:05 WAIT LINK on en1... -\& 17:14:07 HARPI on -\& DATE = <10/14/2014> -\& DEV = -\& HW = <0:23:6c:7f:28:e7> -\& IP = <192.168.1.4> -\& CACHE = -\& 17:14:07 ARP cache, ACCEPT -\& src HW = <0:11:d8:70:ef:1f> -\& src IP = <192.168.1.75> -\& 17:14:18 ARP cache, DENY -\& src HW = <0:11:d8:70:ef:1f> -\& src IP = <192.168.1.151> -\& 17:14:18 ARP cache, ACCEPT -\& src HW = <0:1b:63:c9:b2:96> -\& src IP = <192.168.1.151> -\& 17:15:06 ARP cache, REFRESH -\& src HW = <0:25:53:29:f6:69> -\& src IP = <192.168.1.1> -\& 17:20:07 ARP cache, UPDATE -\& src HW = <0:25:53:29:f6:69> -\& src IP = <192.168.1.1> -\& src HW = <0:50:56:c0:0:8> -\& src IP = <172.16.159.1> -\& ... +.SH DEVELOPMENT AND BUGS +.TP +Please send questions, desirable enhancements, patch, source code contributions, problems, bugs, etc... to author or via the Bug tracking system, as specified in the documentation file specified above and in the official website: +.PP +\& http://arpon.sourceforge.net .Ve .PP .SH AUTHOR .TP -ArpON was writen by: -.Vb 1 -\& -\& Andrea Di Pasquale +ArpON was writen by Andrea Di Pasquale aka "spikey" . .Ve .PP -The current version is available via http: -.Vb 1 -\& -\& http://arpon.sourceforge.net +.SH COPYRIGHT AND LICENSING +.PP +Copyright (C) 2008-2016 Andrea Di Pasquale +.br +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGE. .Ve .PP -.SH BUGS -.TP -Please send problems, bugs, questions, desirable enhancements, patch, source code contributions, etc. to: -.Vb 1 -\& -\& spikey.it@gmail.com +.SH NOTES +.PP +The ArpON daemon is completely compatible with the ARP standardized protocol as described in these official RFC documents: +.PP +1. \fBRFC 826\fR: +.br +\& http://tools.ietf.org/html/rfc826 +.PP +2. \fBRFC 2131\fR: +.br +\& http://tools.ietf.org/html/rfc2131 +.PP +3. \fBRFC 3927\fR: +.br +\& http://tools.ietf.org/html/rfc3927 +.PP +4. \fBRFC 5227\fR: +.br +\& http://tools.ietf.org/html/rfc5227 +.PP +The ArpON daemon sets the arp_ignore and the arp_accept fundamental kernel network parameters via the sysctl interface as described in this official kernel document: +.PP +1. \fBIP sysctl\fR: +.br +\& http://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt .RE + +.\" +.\" EOF +.\" diff -Nru arpon-2.7.2/man8/CMakeLists.txt arpon-3.0-ng+dfsg1/man8/CMakeLists.txt --- arpon-2.7.2/man8/CMakeLists.txt 2014-10-10 18:31:54.000000000 +0000 +++ arpon-3.0-ng+dfsg1/man8/CMakeLists.txt 2016-01-29 01:55:15.000000000 +0000 @@ -1,28 +1,85 @@ - # Compress man pages # -# Copyright 2014 gmrandazzo@gmail.com +# Copyright (C) 2008-2016 Andrea Di Pasquale +# Copyright (C) 2008-2016 Giuseppe Marco Randazzo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# +# $ArpON: CMakeLists.txt,v 3.0-ng 01/29/2016 02:55:15 spikey Exp $ # -# Redistribution AND use is allowed according to the terms of the New -# BSD license. set(arpon_man_src "${CMAKE_SOURCE_DIR}/man8/arpon.8") if(${CMAKE_INSTALL_PREFIX} STREQUAL "/") - set(arpon_sarpi_file "/etc/arpon.sarpi") + set(ARPON_DOC_FILE + "/usr/share/doc/arpon/index.html") + set(ARPON_ETC_FILE + "/etc/arpon.conf") + set(ARPON_LOG_FILE + "/var/log/arpon.log") + set(ARPON_PID_FILE + "/var/run/arpon.pid") else(${CMAKE_INSTALL_PREFIX} STREQUAL "/") - set(arpon_sarpi_file "${CMAKE_INSTALL_PREFIX}/etc/arpon.sarpi") + set(ARPON_DOC_FILE + "${CMAKE_INSTALL_PREFIX}/share/doc/arpon/index.html") + set(ARPON_ETC_FILE + "${CMAKE_INSTALL_PREFIX}/etc/arpon.conf") + set(ARPON_LOG_FILE + "${CMAKE_INSTALL_PREFIX}/log/arpon.log") + set(ARPON_PID_FILE + "${CMAKE_INSTALL_PREFIX}/run/arpon.pid") endif(${CMAKE_INSTALL_PREFIX} STREQUAL "/") -FILE(READ ${arpon_man_src} FILE_CONTENT) -STRING(REGEX REPLACE "arpon_sarpi" "${arpon_sarpi_file}" MODIFIED_FILE_CONTENT "${FILE_CONTENT}") -FILE(WRITE ${PROJECT_BINARY_DIR}/man8/arpon.8 "${MODIFIED_FILE_CONTENT}") +file(READ ${arpon_man_src} FILE_CONTENT) +string(REGEX REPLACE "ARPON_DOC" "${ARPON_DOC_FILE}" + MODIFIED_FILE_CONTENT1 "${FILE_CONTENT}") + +string(REGEX REPLACE "ARPON_ETC" "${ARPON_ETC_FILE}" + MODIFIED_FILE_CONTENT2 "${MODIFIED_FILE_CONTENT1}") + +string(REGEX REPLACE "ARPON_LOG" "${ARPON_LOG_FILE}" + MODIFIED_FILE_CONTENT3 "${MODIFIED_FILE_CONTENT2}") + +string(REGEX REPLACE "ARPON_PID" "${ARPON_PID_FILE}" + MODIFIED_FILE_CONTENT4 "${MODIFIED_FILE_CONTENT3}") +file(WRITE ${PROJECT_BINARY_DIR}/man8/arpon.8 "${MODIFIED_FILE_CONTENT4}") if(${CMAKE_INSTALL_PREFIX} STREQUAL "/") - INSTALL(FILES ${PROJECT_BINARY_DIR}/man8/arpon.8 DESTINATION /usr/share/man/man8 - PERMISSIONS OWNER_READ GROUP_READ WORLD_READ - COMPONENT Man) + install(FILES + ${PROJECT_BINARY_DIR}/man8/arpon.8 DESTINATION /usr/share/man/man8 + PERMISSIONS OWNER_READ GROUP_READ WORLD_READ + COMPONENT Man) else(${CMAKE_INSTALL_PREFIX} STREQUAL "/") - INSTALL(FILES ${PROJECT_BINARY_DIR}/man8/arpon.8 DESTINATION ${CMAKE_INSTALL_PREFIX}/share/man/man8 - PERMISSIONS OWNER_READ GROUP_READ WORLD_READ - COMPONENT Man) + install(FILES + ${PROJECT_BINARY_DIR}/man8/arpon.8 DESTINATION + ${CMAKE_INSTALL_PREFIX}/share/man/man8 + PERMISSIONS OWNER_READ GROUP_READ WORLD_READ + COMPONENT Man) endif(${CMAKE_INSTALL_PREFIX} STREQUAL "/") + +# +# EOF +# +# vim:ts=4:expandtab +# diff -Nru arpon-2.7.2/README arpon-3.0-ng+dfsg1/README --- arpon-2.7.2/README 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/README 2016-01-29 03:12:32.000000000 +0000 @@ -0,0 +1,1640 @@ +================================================================================ + + d8888 .d88888b. 888b 888 + d88888 d88P" "Y88b 8888b 888 + d88P888 888 888 88888b 888 + d88P 888 888d888 88888b. 888 888 888Y88b 888 + d88P 888 888P" 888 "88b 888 888 888 Y88b888 + d88P 888 888 888 888 888 888 888 Y88888 + d8888888888 888 888 d88P Y88b. .d88P 888 Y8888 + d88P 888 888 88888P" "Y88888P" 888 Y888 + 888 + 888 + 888 + + ARP handler inspection + + (http://arpon.sourceforge.net) + + Copyright (C) 2008-2016 Andrea Di Pasquale + +================================================================================ + INDEX +================================================================================ + + 1. IMPORTANT NOTICE + 2. WHAT IS ARPON? + 3. FEATURES + 4. SUPPORTED OPERATING SYSTEMS + 5. REQUIRED SOFTWARE AND LIBRARIES + 6. STABLE RELEASE VIA THE HTTP MIRROR + 7. VERSION + 8. CHANGELOG + 9. BUILDING AND INSTALLATION + 10. UPGRADE + 11. QUICK START + 12. ARPON DAEMON + 13. IMPORTANT NOTE + 14. OPTIONS SUMMARY + 15. FILES + 16. EXAMPLES + 17. HOW TO USE ARPON + 18. UNINSTALLATION + 19. SUPPORT THE DEVELOPMENT + 20. DEVELOPMENT RELEASE VIA THE GIT REPOSITORY + 21. ACTIVITY DIAGRAMS + 22. COMPILE TIME BUGS + 23. RUNTIME BUGS + 24. SUPPORT THE PROJECT + 25. AUTHOR + 26. COPYRIGHT AND LICENSING + 27. THANKS + 28. REFERENCE WEBSITE + 29. NOTES + +================================================================================ + 1. IMPORTANT NOTICE +================================================================================ + +Since ArpON 3.0-ng (next generation), ArpON has been rewritten from scratch, +therefore all the old versions of ArpON (lower of 3.0-ng) are deprecated. +Please upgrade all installations of ArpON and read carefully the documentation +and the man page of ArpON. + +================================================================================ + 2. WHAT IS ARPON? +================================================================================ + +ArpON (ARP handler inspection) is a Host-based solution that make the ARP +standardized protocol secure in order to avoid the Man In The Middle (MITM) +attack through the ARP spoofing, ARP cache poisoning or ARP poison routing +attack. + +This is possible using three kinds of anti ARP spoofing techniques: + + 1. SARPI (Static ARP Inspection) for the statically configured networks + without DHCP; + 2. DARPI (Dynamic ARP Inspection) for the dynamically configured networks + with DHCP; + 3. HARPI (Hybrid ARP Inspection) for the statically and dynamically + configured networks with DHCP. + +The goal of ArpON is therefore to provide a secure and efficient network daemon +that provides the SARPI, DARPI and HARPI anti ARP spoofing technique, thus +making the ARP standardized protocol secure from any foreign intrusion. + +================================================================================ + 3. FEATURES +================================================================================ + +The features of ArpON are: + + • FREE. ArpON is released under the BSD open source license. This means that + you have total freedom to modify and use it with your system, even if it's + commercial. + + • POPULAR. ArpON is used as the network daemon by many users, both the + network managers and academic researchers. ArpON is downloaded several + hundred of times every month. + + • TESTED AND RELIABLE. Many users have contributed over the years in testing + ArpON on a wide range of Man In The Middle (MITM) attack tools through the + ARP spoofing, ARP cache poisoning or ARP poison routing. + + • EASY TO USE. ArpON is distributed as a single tarball that once compiled, + runs on every supported Operating System. You launch the executable, and + from that moment the Operating System is able to avoid the Man In The + Middle (MITM) attack through the ARP spoofing, ARP cache poisoning or ARP + poison routing. + + • MULTI-PLATFORM. Many developers have contributed over the years in porting + ArpON on a wide range of GNU/Linux distributions. + + • COMPATIBLE AND PORTABLE. ArpON is completely compatible with the ARP + standardized protocol. ArpON is an network daemon that runs in user space, + this also means that ArpON will be easily portable to other Operating + Systems. + + • WELL DOCUMENTED. The documentation of ArpON is easy and complete. The + documentation contains the retrieving tutorial; the building tutorial; the + installation tutorial; the user tutorial with many examples and scenarios; + the development tutorial with the Activity diagrams of the SARPI, DARPI + and HARPI anti ARP spoofing technique and with modular source code well + commented; the bug report tutorial that takes you step-by-step through all + of the features of ArpON. + +================================================================================ + 4. SUPPORTED OPERATING SYSTEMS +================================================================================ + +ArpON supports the GNU/Linux Operating System and a wide range of distributions. + +================================================================================ + 5. REQUIRED SOFTWARE AND LIBRARIES +================================================================================ + +The source code compilation of the stable release of ArpON requires the +following software and libraries installed in the System: + + • GNU Binutils: + + http://sourceware.org/binutils/ + + • GNU C Compiler (GCC): + + http://gcc.gnu.org + + • Cmake 2.6 (or higher): + + http://cmake.org + + • GNU Make: + + http://www.gnu.org/software/make/ + + • GNU C Library (Glibc) with POSIX Threads (Pthreads): + + http://www.gnu.org/software/libc/libc.html + + • GNU C Library (Glibc) with Realtime Extensions (Librt): + + http://www.gnu.org/software/libc/libc.html + + • Libpcap with development libraries 1.0.0 (or higher): + + http://www.tcpdump.org + + • Libnet1 with development libraries 1.1.2.1 (or higher): + + http://packetfactory.openwall.net/projects/libnet/ + + • Libdnet with development libraries 1.11 (or higher): + + http://libdnet.sourceforge.net + +The development release of ArpON also requires the following software installed +in the System: + + • Git: + + http://git-scm.com + + • GNU C Debugger (GDB): + + http://sourceware.org/gdb/ + +The documentation of ArpON also requires the following software installed in the +System: + + • Visual Paradigm: + + http://www.visual-paradigm.com + + • OpenOffice Draw: + + http://www.openoffice.org + + • VRT Network Equipment: + + http://www.vrt.com.au/downloads/vrt-network-equipment/ + +================================================================================ + 6. STABLE RELEASE VIA THE HTTP MIRROR +================================================================================ + +The latest stable release of ArpON is available via the HTTP mirror, please +follow these steps: + + 1. First you have to download the tarball via the HTTP mirror: + + $ wget http://sourceforge.net/projects/arpon/files/latest/download \ + -O arpon.tar.gz + + 2. After you have successfully downloaded the tarball, download the MD5 file + of the tarball via the HTTP mirror: + + $ wget http://sourceforge.net/projects/arpon/files/latest.md5/download \ + -O latest.md5 + + 3. Generate the MD5 of your tarball downloaded: + + $ md5sum arpon.tar.gz | awk '{print $1}' > arpon.md5 + + 4. Validate the MD5 of your tarball downloaded: + + $ diff -u latest.md5 arpon.md5 + + If you have not the output of the diff, the tarball downloaded is valid. + + 5. If the tarball si valid, untar the tarball downloaded: + + $ mkdir arpon + $ tar -xvzf arpon.tar.gz -C arpon --strip-components=1 + + 6. After you have successfully downloaded and validated the tarball then + you must initiate the building and installation. + +================================================================================ + 7. VERSION +================================================================================ + +The version of ArpON is available in: + + $ cat /path/to/arpon/VERSION + +================================================================================ + 8. CHANGELOG +================================================================================ + +The changelog of ArpON is available in: + + $ cat /path/to/arpon/CHANGELOG + +================================================================================ + 9. BUILDING AND INSTALLATION +================================================================================ + +To build and install the ArpON, please follow these steps: + + • To install the ArpON in the default "/" path: + + $ cd /path/to/arpon + $ mkdir build + $ cd build + $ cmake .. + $ make + $ sudo make install + + • To install the ArpON in an other path: + + $ cd /path/to/arpon + $ mkdir build + $ cd build + $ cmake -DCMAKE_INSTALL_PREFIX="/path/to/install" .. + $ make + $ sudo make install + + Usually the paths of the installation are: "/", "/usr" or "/usr/local". + + • If the your dependencies are installed in the other paths: + + $ cd /path/to/arpon + $ mkdir build + $ cd build + $ cmake -DCMAKE_INCLUDE_PATH="/path/to/include1;/path/to/include2" \ + -DCMAKE_LIBRARY_PATH="/path/to/library1;/path/to/library2" .. + $ make + $ sudo make install + + • If you want personalize the CFLAGS compiler parameters: + + $ cd /path/to/arpon + $ mkdir build + $ cd build/ + $ cmake -DCMAKE_C_FLAGS="your-cflags-here" .. + $ make + $ sudo make install + +================================================================================ + 10. UPGRADE +================================================================================ + +To upgrade the ArpON, please follow the steps of the building and installation +(with the same path of your previous installation of ArpON) that will overwrite +all the files of ArpON. + +================================================================================ + 11. QUICK START +================================================================================ + +To start quickly with ArpON, please follow these guidelines: + + 1. See the documentation file of ArpON. It contains the retrieving tutorial; + the building tutorial; the installation tutorial; the user tutorial with + many examples and scenarios; the development tutorial with the Activity + diagrams of the SARPI, DARPI and HARPI anti ARP spoofing technique and + with modular source code well commented; the bug report tutorial that + takes you step-by-step through all of the features of ArpON. Please note + that: + + If you chose the default "/" path of the installation, open with a + browser web this file: + + /usr/share/doc/arpon/index.html + + Else open with a browser web this file: + + PATH/share/doc/arpon/index.html + + where PATH is the path of your installation. + + 2. See the man page of ArpON: + + $ man 8 arpon + + 3. See the help screen of ArpON: + + $ sudo arpon -h + +================================================================================ + 12. ARPON DAEMON +================================================================================ + +The synopsis of ArpON daemon command is: + + arpon [OPTIONS] [SARPI | DARPI | HARPI] + +ArpON sets of policies in the ARP cache for all the static and or dynamic +entries matching the specified network interface (or that matching the several +specified network interfaces if run concurrently several daemons of ArpON for +different network interfaces), through the run of SARPI, DARPI or HARPI anti +ARP spoofing technique. + +ArpON have to be run with the root privileges. ArpON have to be configured using +command-line options and a configuration file. ArpON reloads the configuration +of the specified network interface and rereads its configuration file when it +receives a hangup signal (SIGHUP) by executing itself with the name and options +it was started with. ArpON exits correctly when it receives an interrupt signal +(SIGINT) or a termination signal (SIGTERM). + +================================================================================ + 13. IMPORTANT NOTE +================================================================================ + +The ArpON daemon sets two fundamental kernel network parameters via the sysctl +interface on the specified network interface: + + 1. The arp_ignore kernel parameter of the specified network interface is + always setted to 8 by ArpON. This is done to disable, in the specified + network interface of the Operating System, the sending of the ARP replies in + response to received ARP requests for all local addresses (the ARP replies + on the specified network interface, will be sent by ArpON instead of the + Operating System). + + 2. The arp_accept kernel parameter of the specified network interface is + always setted to 0 by ArpON. This is done to disable, in the specified + network interface of the Operating System, the creating of the new IP + entries in the ARP cache triggered by the unsolicited and gratuitous ARP + requests and replies (the IP entries in the ARP cache on the specified + network interface, will be created or updated by ArpON as static or dynamic + IP entries instead of the Operating System). + +The ArpON daemon restores the previously values read from the arp_ignore and +arp_accept kernel parameters of the specified network interface when it receives +an interrupt signal (SIGINT) or a termination signal (SIGTERM). Remember to +restore the values of the arp_ignore and arp_accept kernel parameters of the +specified network interface (the default values are 0 for both), if you have +terminated the ArpON daemon with other signals, e.g. kill signal (SIGKILL). + +================================================================================ + 14. OPTIONS SUMMARY +================================================================================ + +The available options of ArpON daemon command are: + + • General options: + + -d, --daemon + Daemonize the ArpON. + + -i, --interface + Use the specified network interface. + + • SARPI 'Static ARP Inspection' option: + + SARPI anti ARP spoofing technique manages and sets the policies in the ARP + cache only for all the static entries matching the specified network + interface, in order to avoid the Man In The Middle (MITM) attack through + the ARP spoofing, ARP cache poisoning or ARP poison routing. Therefore + SARPI is an optimal choice in those statically configured networks + without DHCP. SARPI sets these policies: + + 1) CLEAN: SARPI cleans from the ARP cache only all the entries matching + the specified network interface, that are present or not present in the + configuration file; + 2) UPDATE: SARPI updates in the ARP cache only all the static entries + matching the specified network interface, that are present in the + configuration file; + 3) REFRESH: SARPI refreshes in the ARP cache only a static entry matching + the specified network interface, that is present in the configuration + file; + 4) ALLOW: SARPI sets up in the ARP cache only a dynamic entry matching the + specified network interface, that is not present in the configuration + file. + + Therefore SARPI requires a specified network interface and the + specification in the configuration file of the ARP cache only for all the + static entries matching the specified network interface. + + -S, --sarpi + Run SARPI anti ARP spoofing technique. + + • DARPI 'Dynamic ARP Inspection' option: + + DARPI anti ARP spoofing technique manages and sets the policies in the ARP + cache only for all the dynamic entries matching the specified network + interface, in order to avoid the Man In The Middle (MITM) attack through + the ARP spoofing, ARP cache poisoning or ARP poison routing. Therefore + DARPI is an optimal choice in those dynamically configured networks with + DHCP. DARPI sets these policies: + + 1) CLEAN: DARPI cleans from the ARP cache only all the entries matching + the specified network interface; + 2) ALLOW: DARPI sets up in the ARP cache only a dynamic entry matching + the specified network interface; + 3) DENY: DARPI cleans up from the ARP cache only a dynamic entry matching + the specified network interface. + + Therefore DARPI requires a specified network interface and it doesn't + requires any specification in the configuration file of the ARP cache only + for all the dynamic entries matching the specified network interface. + + -D, --darpi + Run DARPI anti ARP spoofing technique. + + • HARPI 'Hybrid ARP Inspection' option: + + HARPI anti ARP spoofing technique manages and sets the policies in the ARP + cache for both all the static and dynamic entries matching the specified + network interface, in order to avoid the Man In The Middle (MITM) attack + through the ARP spoofing, ARP cache poisoning or ARP poison routing. + Therefore HARPI is an optimal choice in those statically and dynamically + configured networks with DHCP. HARPI sets and combines these policies of + the SARPI and DARPI: + + 1) CLEAN: HARPI cleans from the ARP cache only all the entries matching + the specified network interface, that are present or not present in the + configuration file; + 2) UPDATE: HARPI updates in the ARP cache only all the static entries + matching the specified network interface, that are present in the + configuration file; + 3) REFRESH: HARPI refreshes in the ARP cache only a static entry matching + the specified network interface, that is present in the configuration + file; + 4) ALLOW: HARPI sets up in the ARP cache only a dynamic entry matching + the specified network interface, that is not present in the + configuration file; + 5) DENY: HARPI cleans up from the ARP cache only a dynamic entry matching + the specified network interface, that is not present in the + configuration file. + + Therefore HARPI requires a specified network interface, the specification + in the configuration file of the ARP cache only for all the static entries + matching the specified network interface; instead it doesn't requires any + specification in the configuration file of the ARP cache only for all the + dynamic entries matching the specified network interface. + + -H, --harpi + Run HARPI anti ARP spoofing technique. + + • Standard options: + + -v, --version + Print the version and exit. + + -h, --help + Print the help screen and exit. + +================================================================================ + 15. FILES +================================================================================ + +The available files of ArpON daemon command are: + + • The configuration file contains the configuration data of ArpON and it is + used when run the SARPI or HARPI anti ARP spoofing technique, for the + specification in the ARP cache only for all the static entries matching + the specified network interface (or that matching the several specified + network interfaces if run concurrently several daemons of ArpON for + different network interfaces). This file should be writable by root only + but it is recommended (though not necessary) that it be world-readable. + Please note that: + + If you chose the default "/" path of the installation, the configuration + file is: + + /etc/arpon.conf + + Else the configuration file is: + + PATH/etc/arpon.conf + + where PATH is the path of your installation. + + • The log file contains the log data of ArpON. If there are several + daemons of ArpON running concurrently for different network interfaces, + this contains the log data of all the daemons of ArpON. This file should + be readable only by root, and need not be readable by anyone else. Please + note that: + + If you chose the default "/" path of the installation, the log file is: + + /var/log/arpon.log + + Else the log file is: + + PATH/log/arpon.log + + where PATH is the path of your installation. + + • The pid file contains the process ID of ArpON. If there are several + daemons of ArpON running concurrently for different network interfaces, + this contains the process ID of the one started last. The content of this + file is not sensitive; it can be world-readable. Please note that: + + If you chose the default "/" path of the installation, the pid file is: + + /var/run/arpon.pid + + Else the pid file is: + + PATH/run/arpon.pid + + where PATH is the path of your installation. + +================================================================================ + 16. EXAMPLES +================================================================================ + +These examples shows how to use all three kinds of anti ARP spoofing techniques +of ArpON daemon. Note that these examples use the default "/" path of the +installation of the files. + +In the same host, we have three network interfaces with different subnet classes +and we would set the ARP cache for all the static and dynamic entries matching +the eth0, wlan0 and eth1 network interfaces. This scenario requires the run +concurrently of three daemons of ArpON: + + • SARPI 'Static ARP Inspection' example: + + The eth0 network interface has the 192.168.1.2/24 IP address. We have only + three static entries of the ARP cache: + + 1) 192.168.1.1 at 58:ac:78:10:b9:77; + 2) 192.168.1.3 at d4:be:d9:fe:8b:45; + 3) 192.168.1.4 at 90:94:e4:bb:1c:10. + + and we have no dynamic entries of the ARP cache. This is the ideal case + where we have to use the SARPI anti ARP spoofing technique, therefore + specify in the configuration file of the ARP cache only all the static + entries matching the eth0 network interface: + + $ sudo nano /etc/arpon.conf + + Therefore: + + # + # ArpON configuration file. + # + # See the arpon(8) man page for details. + # + + # + # Static entries matching the eth0 network interface: + # + # First static entry: + 192.168.1.1 58:ac:78:10:b9:77 + # Second static entry: + 192.168.1.3 d4:be:d9:fe:8b:45 + # Third static entry: + 192.168.1.4 90:94:e4:bb:1c:10 + + Daemonize the ArpON and run SARPI anti ARP spoofing technique on the eth0 + network interface: + + $ sudo arpon -d -i eth0 -S + + Read the log file: + + $ sudo tail -f /var/log/arpon.log + + Read the pid file: + + $ cat /var/run/arpon.pid + + • DARPI 'Dynamic ARP Inspection' example: + + The wlan0 network interface has the 172.16.1.2/24 IP address. We have no + static entries of the ARP cache, and we have only dynamic entries of the + ARP cache. This is the ideal case where we have to use the DARPI anti ARP + spoofing technique, therefore daemonize the ArpON and run DARPI anti ARP + spoofing technique on the wlan0 network interface: + + $ sudo arpon -d -i wlan0 -D + + Read the log file: + + $ sudo tail -f /var/log/arpon.log + + Read the pid file: + + $ cat /var/run/arpon.pid + + • HARPI 'Hybrid ARP Inspection' example: + + The eth1 network interface has the 10.0.1.2/16 IP address. We have only + two static entries of the ARP cache: + + 1) 10.0.1.1 at 58:ac:78:88:1a:bb; + 2) 10.0.10.1 at 90:94:e4:7e:f4:59. + + and we have the rest of entries as dynamic entries of the ARP cache. This + is the ideal case where we have to use the HARPI anti ARP spoofing + technique, therefore specify in the configuration file of the ARP cache + only all the static entries matching the eth1 network interface: + + $ sudo nano /etc/arpon.conf + + Therefore: + + # + # ArpON configuration file. + # + # See the arpon(8) man page for details. + # + + # + # Static entries matching the eth0 network interface: + # + # First static entry: + 192.168.1.1 58:ac:78:10:b9:77 + # Second static entry: + 192.168.1.3 d4:be:d9:fe:8b:45 + # Third static entry: + 192.168.1.4 90:94:e4:bb:1c:10 + + # + # Static entries matching the eth1 network interface: + # + # First static entry: + 10.0.1.1 58:ac:78:88:1a:bb + # Second static entry: + 10.0.10.1 90:94:e4:7e:f4:59 + + Daemonize the ArpON and run HARPI anti ARP spoofing technique on the eth1 + network interface: + + $ sudo arpon -d -i eth1 -H + + Read the log file: + + $ sudo tail -f /var/log/arpon.log + + Read the pid file: + + $ cat /var/run/arpon.pid + +================================================================================ + 17. HOW TO USE ARPON +================================================================================ + +The available scenarios of ArpON, that explain respectively how ArpON works and +how to use ArpON are: + + • Half-duplex ArpON defense: + + This scenario shows the half-duplex Man In The Middle (half-duplex MITM) + attack through the ARP spoofing. The attacker is attacking only the host + A, therefore the attacker is intercepting only the communications from the + host A to host B: + + If you chose the default "/" path of the installation, open with an image + viewer application this file: + + /usr/share/doc/arpon/scenario/halfduplexattack.jpg + + or open with a Pdf viewer application this file: + + /usr/share/doc/arpon/scenario/halfduplexattack.pdf + + or open with the OpenOffice Draw application this file: + + /usr/share/doc/arpon/scenario/halfduplexattack.odg + + Else open with an image viewer application this file: + + PATH/share/doc/arpon/scenario/halfduplexattack.jpg + + or open with a Pdf viewer application this file: + + PATH/share/doc/arpon/scenario/halfduplexattack.pdf + + or open with the OpenOffice Draw application this file: + + PATH/share/doc/arpon/scenario/halfduplexattack.odg + + Run the ArpON only in the host A in order to avoid the half-duplex attack: + + If you chose the default "/" path of the installation, open with an image + viewer application this file: + + /usr/share/doc/arpon/scenario/halfduplexdefense.jpg + + or open with a Pdf viewer application this file: + + /usr/share/doc/arpon/scenario/halfduplexdefense.pdf + + or open with the OpenOffice Draw application this file: + + /usr/share/doc/arpon/scenario/halfduplexdefense.odg + + Else open with an image viewer application this file: + + PATH/share/doc/arpon/scenario/halfduplexdefense.jpg + + or open with a Pdf viewer application this file: + + PATH/share/doc/arpon/scenario/halfduplexdefense.pdf + + or open with the OpenOffice Draw application this file: + + PATH/share/doc/arpon/scenario/halfduplexdefense.odg + + The communications between the host A and the host B are back again + secure, leaving the attacker out. + + • Full-duplex ArpON defense: + + This scenario shows the full-duplex Man In The Middle (full-duplex MITM) + attack through the ARP spoofing. The attacker is attacking both the host + A and the host B, therefore the attacker is intercepting all the + communications between the host A and the host B: + + If you chose the default "/" path of the installation, open with an image + viewer application this file: + + /usr/share/doc/arpon/scenario/fullduplexattack.jpg + + or open with a Pdf viewer application this file: + + /usr/share/doc/arpon/scenario/fullduplexattack.pdf + + or open with the OpenOffice Draw application this file: + + /usr/share/doc/arpon/scenario/fullduplexattack.odg + + Else open with an image viewer application this file: + + PATH/share/doc/arpon/scenario/fullduplexattack.jpg + + or open with a Pdf viewer application this file: + + PATH/share/doc/arpon/scenario/fullduplexattack.pdf + + or open with the OpenOffice Draw application this file: + + PATH/share/doc/arpon/scenario/fullduplexattack.odg + + Run the ArpON only in the host A in order to avoid the half-duplex attack: + + If you chose the default "/" path of the installation, open with an image + viewer application this file: + + /usr/share/doc/arpon/scenario/fullduplexhalfdefense.jpg + + or open with a Pdf viewer application this file: + + /usr/share/doc/arpon/scenario/fullduplexhalfdefense.pdf + + or open with the OpenOffice Draw application this file: + + /usr/share/doc/arpon/scenario/fullduplexhalfdefense.odg + + Else open with an image viewer application this file: + + PATH/share/doc/arpon/scenario/fullduplexhalfdefense.jpg + + or open with a Pdf viewer application this file: + + PATH/share/doc/arpon/scenario/fullduplexhalfdefense.pdf + + or open with the OpenOffice Draw application this file: + + PATH/share/doc/arpon/scenario/fullduplexhalfdefense.odg + + The communications from the host A to host B are back again secure, + leaving the attacker out. Finally, run the ArpON also in the host B in + order to avoid the full-duplex attack: + + If you chose the default "/" path of the installation, open with an image + viewer application this file: + + /usr/share/doc/arpon/scenario/fullduplexfulldefense.jpg + + or open with a Pdf viewer application this file: + + /usr/share/doc/arpon/scenario/fullduplexfulldefense.pdf + + or open with the OpenOffice Draw application this file: + + /usr/share/doc/arpon/scenario/fullduplexfulldefense.odg + + Else open with an image viewer application this file: + + PATH/share/doc/arpon/scenario/fullduplexfulldefense.jpg + + or open with a Pdf viewer application this file: + + PATH/share/doc/arpon/scenario/fullduplexfulldefense.pdf + + or open with the OpenOffice Draw application this file: + + PATH/share/doc/arpon/scenario/fullduplexfulldefense.odg + + The communications between the host A and the host B are back again + secure, leaving the attacker out. + +================================================================================ + 18. UNINSTALLATION +================================================================================ + +To uninstall ArpON: + + $ cd /path/to/arpon/build + $ sudo make uninstall + +================================================================================ + 19. SUPPORT THE DEVELOPMENT +================================================================================ + +If you are a developer and you wish write any fix, feature or OS port of ArpON, +please follow these steps, make it available under the BSD open source license +and contribute to the project sending the patch: + + 1. Clone or pull via the GIT repository and use the latest development + release of ArpON. + 2. Understand the Activity diagrams of ArpON, that explain respectively the + algorithms and the policies of SARPI, DARPI and HARPI anti ARP spoofing + technique. + 3. Create a new devel branch and personalize the build type from Release to + Debug: + + $ cd /path/to/arpon + $ git checkout -b devel + $ mkdir debug + $ cd debug + $ cmake -DCMAKE_BUILD_TYPE="debug" .. + $ make VERBOSE=1 + + 4. Before to see any codes, study and adhere the FreeBSD encoding standard: + + https://www.freebsd.org/cgi/man.cgi?query=style&sektion=9 + + 5. Write any fix, feature or OS port for ArpON and test it in Debug build + type: + + $ cd /path/to/arpon + $ vim file_to_edit_1 file_to_edit_2 file_to_edit_N + $ cd /path/to/arpon/debug + $ make VERBOSE=1 + $ sudo make install + $ sudo arpon [OPTIONS] [SARPI | DARPI | HARPI] + + 6. Switch the build type from Debug to Release and test, test and test it + again in Release build type: + + $ cd /path/to/arpon/debug + $ sudo make uninstall + $ cd .. + $ mkdir release + $ cd release + $ cmake -DCMAKE_BUILD_TYPE="release" .. + $ make + $ sudo make install + $ sudo arpon [OPTIONS] [SARPI | DARPI | HARPI] + + 7. Commit the changes into devel branch and create the patch: + + $ cd /path/to/arpon/ + $ rm -Rf debug release + $ git add -A + $ git commit -m "Describe your patch" + $ git format-patch master --stdout > patch.diff + + 8. Send the created patch.diff file with any details to author or via the + Bug tracking system: + + http://sourceforge.net/p/arpon/bugs/ + + 9. The author will review the code, make any necessary changes and merge the + code into the proper branch. + 10. You will receive full credit as a contributor to the project. + +================================================================================ + 20. DEVELOPMENT RELEASE VIA THE GIT REPOSITORY +================================================================================ + +The latest development release of ArpON is available via the GIT repository: + + http://sourceforge.net/p/arpon/code/ci/master/tree/ + +Please follow these steps: + + 1. First you have to clone the project via the GIT repository: + + $ git clone git://git.code.sourceforge.net/p/arpon/code arpon + $ cd arpon + + Or via the GIT repository over HTTP protocol: + + $ git clone http://git.code.sourceforge.net/p/arpon/code arpon + $ cd arpon + + 2. If you already had the repository cloned, you will need to pull the + latest changes: + + $ cd /path/to/arpon + $ git pull + + 3. After you have successfully cloned or pulled the repository then you must + initiate the building and installation. + +================================================================================ + 21. ACTIVITY DIAGRAMS +================================================================================ + +All the available algorithms of ArpON are compatible with the ARP standardized +protocol as described in these official RFC documents: + + 1. RFC 826: + + http://tools.ietf.org/html/rfc826 + + 2. RFC 2131: + + http://tools.ietf.org/html/rfc2131 + + 3. RFC 3927: + + http://tools.ietf.org/html/rfc3927 + + 4. RFC 5227: + + http://tools.ietf.org/html/rfc5227 + +Note that all the available algorithms of ArpON set the arp_ignore and the +arp_accept fundamental kernel network parameters via the sysctl interface as +described in this official kernel document: + + 1. IP sysctl: + + http://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt + +Therefore the available Activity diagrams of ArpON, that explain respectively +the algorithms and the policies of all three kinds of anti ARP spoofing +techniques are: + + • SARPI 'Static ARP Inspection' Activity diagram: + + If you chose the default "/" path of the installation, open with an image + viewer application this file: + + /usr/share/doc/arpon/uml/SARPI.jpg + + or open with a Pdf viewer application this file: + + /usr/share/doc/arpon/uml/SARPI.pdf + + or open with the Visual paradigm application this file: + + /usr/share/doc/arpon/uml/SARPI.vpp + + Else open with an image viewer application this file: + + PATH/share/doc/arpon/uml/SARPI.jpg + + or open with a Pdf viewer application this file: + + PATH/share/doc/arpon/uml/SARPI.pdf + + or open with the Visual paradigm application this file: + + PATH/share/doc/arpon/uml/SARPI.vpp + + To understand the SARPI 'Static ARP Inspection' Activity diagram, it is + very important to understand this network diagram, that show a simple + case of execution of the SARPI algorithm, in order to permit the + communication between the host A (with a static IP address) and the host + B (with a static IP address): + + If you chose the default "/" path of the installation, open with an image + viewer application this file: + + /usr/share/doc/arpon/network/SARPI.jpg + + or open with a Pdf viewer application this file: + + /usr/share/doc/arpon/network/SARPI.pdf + + or open with the OpenOffice Draw application this file: + + /usr/share/doc/arpon/network/SARPI.odg + + Else open with an image viewer application this file: + + PATH/share/doc/arpon/network/SARPI.jpg + + or open with a Pdf viewer application this file: + + PATH/share/doc/arpon/network/SARPI.pdf + + or open with the OpenOffice Draw application this file: + + PATH/share/doc/arpon/network/SARPI.odg + + Instead this network diagram shows a simple case of execution of the + SARPI algorithm, in order to permit the communication between the host A + (with a static IP address) and the host B (with a static IP address), + leaving the host C (attacker) out from the communication: + + If you chose the default "/" path of the installation, open with an image + viewer application this file: + + /usr/share/doc/arpon/network/SARPI_defense.jpg + + or open with a Pdf viewer application this file: + + /usr/share/doc/arpon/network/SARPI_defense.pdf + + or open with the OpenOffice Draw application this file: + + /usr/share/doc/arpon/network/SARPI_defense.odg + + Else open with an image viewer application this file: + + PATH/share/doc/arpon/network/SARPI_defense.jpg + + or open with a Pdf viewer application this file: + + PATH/share/doc/arpon/network/SARPI_defense.pdf + + or open with the OpenOffice Draw application this file: + + PATH/share/doc/arpon/network/SARPI_defense.odg + + • DARPI 'Dynamic ARP Inspection' Activity diagram: + + If you chose the default "/" path of the installation, open with an image + viewer application this file: + + /usr/share/doc/arpon/uml/DARPI.jpg + + or open with a Pdf viewer application this file: + + /usr/share/doc/arpon/uml/DARPI.pdf + + or open with the Visual paradigm application this file: + + /usr/share/doc/arpon/uml/DARPI.vpp + + Else open with an image viewer application this file: + + PATH/share/doc/arpon/uml/DARPI.jpg + + or open with a Pdf viewer application this file: + + PATH/share/doc/arpon/uml/DARPI.pdf + + or open with the Visual paradigm application this file: + + PATH/share/doc/arpon/uml/DARPI.vpp + + To understand the DARPI 'Dynamic ARP Inspection' Activity diagram, it is + very important to understand this network diagram, that show a simple + case of execution of the DARPI algorithm, in order to permit the + communication between the host A (with a dynamic IP address) and the host + B (with a dynamic IP address), checking any network errors: + + If you chose the default "/" path of the installation, open with an image + viewer application this file: + + /usr/share/doc/arpon/network/DARPI.jpg + + or open with a Pdf viewer application this file: + + /usr/share/doc/arpon/network/DARPI.pdf + + or open with the OpenOffice Draw application this file: + + /usr/share/doc/arpon/network/DARPI.odg + + Else open with an image viewer application this file: + + PATH/share/doc/arpon/network/DARPI.jpg + + or open with a Pdf viewer application this file: + + PATH/share/doc/arpon/network/DARPI.pdf + + or open with the OpenOffice Draw application this file: + + PATH/share/doc/arpon/network/DARPI.odg + + Instead this network diagram shows a simple case of execution of the + DARPI algorithm, in order to permit the communication between the host A + (with a dynamic IP address) and the host B (with a dynamic IP address), + leaving the host C (attacker) out from the communication: + + If you chose the default "/" path of the installation, open with an image + viewer application this file: + + /usr/share/doc/arpon/network/DARPI_defense.jpg + + or open with a Pdf viewer application this file: + + /usr/share/doc/arpon/network/DARPI_defense.pdf + + or open with the OpenOffice Draw application this file: + + /usr/share/doc/arpon/network/DARPI_defense.odg + + Else open with an image viewer application this file: + + PATH/share/doc/arpon/network/DARPI_defense.jpg + + or open with a Pdf viewer application this file: + + PATH/share/doc/arpon/network/DARPI_defense.pdf + + or open with the OpenOffice Draw application this file: + + PATH/share/doc/arpon/network/DARPI_defense.odg + + • HARPI 'Hybrid ARP Inspection' Activity diagram that combines the SARPI and + DARPI Activity diagram: + + If you chose the default "/" path of the installation, open with an image + viewer application this file: + + /usr/share/doc/arpon/uml/HARPI.jpg + + or open with a Pdf viewer application this file: + + /usr/share/doc/arpon/uml/HARPI.pdf + + or open with the Visual paradigm application this file: + + /usr/share/doc/arpon/uml/HARPI.vpp + + Else open with an image viewer application this file: + + PATH/share/doc/arpon/uml/HARPI.jpg + + or open with a Pdf viewer application this file: + + PATH/share/doc/arpon/uml/HARPI.pdf + + or open with the Visual paradigm application this file: + + PATH/share/doc/arpon/uml/HARPI.vpp + + To understand the HARPI 'Hybrid ARP Inspection' Activity diagram, it is + very important to understand these network diagrams, where the first one + show a simple case of execution of the HARPI algorithm, in order to permit + the communication between the host A (with a static IP address) and the + host B (with a static IP address): + + If you chose the default "/" path of the installation, open with an image + viewer application this file: + + /usr/share/doc/arpon/network/HARPI_static.jpg + + or open with a Pdf viewer application this file: + + /usr/share/doc/arpon/network/HARPI_static.pdf + + or open with the OpenOffice Draw application this file: + + /usr/share/doc/arpon/network/HARPI_static.odg + + Else open with an image viewer application this file: + + PATH/share/doc/arpon/network/HARPI_static.jpg + + or open with a Pdf viewer application this file: + + PATH/share/doc/arpon/network/HARPI_static.pdf + + or open with the OpenOffice Draw application this file: + + PATH/share/doc/arpon/network/HARPI_static.odg + + Instead this network diagram shows a simple case of execution of the + HARPI algorithm, in order to permit the communication between the host A + (with a static IP address) and the host B (with a static IP address), + leaving the host C (attacker) out from the communication: + + If you chose the default "/" path of the installation, open with an image + viewer application this file: + + /usr/share/doc/arpon/network/HARPI_static_defense.jpg + + or open with a Pdf viewer application this file: + + /usr/share/doc/arpon/network/HARPI_static_defense.pdf + + or open with the OpenOffice Draw application this file: + + /usr/share/doc/arpon/network/HARPI_static_defense.odg + + Else open with an image viewer application this file: + + PATH/share/doc/arpon/network/HARPI_static_defense.jpg + + or open with a Pdf viewer application this file: + + PATH/share/doc/arpon/network/HARPI_static_defense.pdf + + or open with the OpenOffice Draw application this file: + + PATH/share/doc/arpon/network/HARPI_static_defense.odg + + The second one show a simple case of execution of the HARPI algorithm, + in order to permit the communication between the host A (with a dynamic + IP address) and the host B (with a dynamic IP address), checking any + network errors: + + If you chose the default "/" path of the installation, open with an image + viewer application this file: + + /usr/share/doc/arpon/network/HARPI_dynamic.jpg + + or open with a Pdf viewer application this file: + + /usr/share/doc/arpon/network/HARPI_dynamic.pdf + + or open with the OpenOffice Draw application this file: + + /usr/share/doc/arpon/network/HARPI_dynamic.odg + + Else open with an image viewer application this file: + + PATH/share/doc/arpon/network/HARPI_dynamic.jpg + + or open with a Pdf viewer application this file: + + PATH/share/doc/arpon/network/HARPI_dynamic.pdf + + or open with the OpenOffice Draw application this file: + + PATH/share/doc/arpon/network/HARPI_dynamic.odg + + Instead this network diagram shows a simple case of execution of the + HARPI algorithm, in order to permit the communication between the host A + (with a dynamic IP address) and the host B (with a dynamic IP address), + leaving the host C (attacker) out from the communication: + + If you chose the default "/" path of the installation, open with an image + viewer application this file: + + /usr/share/doc/arpon/network/HARPI_dynamic_defense.jpg + + or open with a Pdf viewer application this file: + + /usr/share/doc/arpon/network/HARPI_dynamic_defense.pdf + + or open with the OpenOffice Draw application this file: + + /usr/share/doc/arpon/network/HARPI_dynamic_defense.odg + + Else open with an image viewer application this file: + + PATH/share/doc/arpon/network/HARPI_dynamic_defense.jpg + + or open with a Pdf viewer application this file: + + PATH/share/doc/arpon/network/HARPI_dynamic_defense.pdf + + or open with the OpenOffice Draw application this file: + + PATH/share/doc/arpon/network/HARPI_dynamic_defense.odg + + The third one show a simple case of execution of the HARPI algorithm, + in order to permit the communication between the host A (with a dynamic + IP address) and the host B (with a static IP address), checking any + network errors: + + If you chose the default "/" path of the installation, open with an image + viewer application this file: + + /usr/share/doc/arpon/network/HARPI_hybrid.jpg + + or open with a Pdf viewer application this file: + + /usr/share/doc/arpon/network/HARPI_hybrid.pdf + + or open with the OpenOffice Draw application this file: + + /usr/share/doc/arpon/network/HARPI_hybrid.odg + + Else open with an image viewer application this file: + + PATH/share/doc/arpon/network/HARPI_hybrid.jpg + + or open with a Pdf viewer application this file: + + PATH/share/doc/arpon/network/HARPI_hybrid.pdf + + or open with the OpenOffice Draw application this file: + + PATH/share/doc/arpon/network/HARPI_hybrid.odg + + Instead this network diagram shows a simple case of execution of the + HARPI algorithm, in order to permit the communication between the host A + (with a dynamic IP address) and the host B (with a static IP address), + leaving the host C (attacker) out from the communication: + + If you chose the default "/" path of the installation, open with an image + viewer application this file: + + /usr/share/doc/arpon/network/HARPI_hybrid_defense.jpg + + or open with a Pdf viewer application this file: + + /usr/share/doc/arpon/network/HARPI_hybrid_defense.pdf + + or open with the OpenOffice Draw application this file: + + /usr/share/doc/arpon/network/HARPI_hybrid_defense.odg + + Else open with an image viewer application this file: + + PATH/share/doc/arpon/network/HARPI_hybrid_defense.jpg + + or open with a Pdf viewer application this file: + + PATH/share/doc/arpon/network/HARPI_hybrid_defense.pdf + + or open with the OpenOffice Draw application this file: + + PATH/share/doc/arpon/network/HARPI_hybrid_defense.odg + +================================================================================ + 22. COMPILE TIME BUGS +================================================================================ + +If you are not able to compile ArpON on your System, please follow these steps +to make a simple bug report in order to help us to find the bug and fix it: + + 1. Clean the ArpON build directory: + + $ cd /path/to/arpon/build + $ make clean-all + + 2. Create the report directory: + + $ mkdir /tmp/report + +We need the following informations: + + 1. A description of your Operating System: + + $ uname -a > /tmp/report/os.log + + 2. A description of your GNU/Linux distribution: + + If you have the lsb_release command: + + $ lsb_release -a > /tmp/report/distro.log + + Else if you have not the lsb_release command: + + $ cp /etc/os-release /tmp/report/distro.log + + Else if you have not the os-release file put your distribution name: + + $ echo "your-distro-here" > /tmp/report/distro.log + + 3. The version of ArpON: + + $ cp ../VERSION /tmp/report + + 4. The CMake cache file: + + $ cmake .. + $ cp CMakeCache.txt /tmp/report + + 5. The entire output from make: + + $ make VERBOSE=1 >> /tmp/report/make_out.log \ + 2>> /tmp/report/make_err.log + + 6. Make a tarball of your report: + + $ cd /tmp + $ tar -pcvzf report.tar.gz report + report/ + report/distro.log + report/os.log + report/make_err.log + report/CMakeCache.txt + report/VERSION + report/make_out.log + + 7. Send the report.tar.gz tarball to author or via the Bug tracking system: + + http://sourceforge.net/p/arpon/bugs/ + +================================================================================ + 23. RUNTIME BUGS +================================================================================ + +If the bug is critical and results in a segmentation fault, please follow these +steps to make a detailed bug report in order to help us to find the bug and fix +it: + + 1. Recompile the ArpON in debug build type: + + $ cd /path/to/arpon + $ mkdir debug + $ cd debug + $ cmake -DCMAKE_BUILD_TYPE="debug" .. + $ make + $ sudo make install + + 2. Create the report directory: + + $ mkdir /tmp/report + +We need the following informations: + + 1. A description of your Operating System: + + $ uname -a > /tmp/report/os.log + + 2. A description of your GNU/Linux distribution: + + If you have the lsb_release command: + + $ lsb_release -a > /tmp/report/distro.log + + Else if you have not the lsb_release command: + + $ cp /etc/os-release /tmp/report/distro.log + + Else if you have not the os-release file put your distribution name: + + $ echo "your-distro-here" > /tmp/report/distro.log + + 3. The version of ArpON: + + $ cp ../VERSION /tmp/report + + 4. The stacktrace of ArpON that reproduces the bug: + + Override any limit for coredumps: + + $ ulimit -c unlimited + + Enter in the directory where there is the ArpON executable: + + If you chose the default "/" path of the installation, enter in: + + $ cd /sbin + + Else enter in: + + $ cd PATH/sbin + + where PATH is the path of your installation. + + Run the ArpON executable and reproduce the bug (it'll create the + coredump): + + $ sudo arpon your-parameters-here + + Create the stacktrace of the bug with the gdb and the coredump: + + $ sudo gdb --batch --quiet -ex "thread apply all bt full" -ex "quit" \ + arpon core >> /tmp/report/stacktrace.log 2>> /tmp/report/stacktrace.log + + Please note that the path of the coredump depends by your OS setting. + + 5. The log file of ArpON: + + If you chose the default "/" path of the installation, copy this file: + + $ cp /var/log/arpon.log /tmp/report + + Else copy this file: + + $ cp PATH/log/arpon.log /tmp/report + + where PATH is the path of your installation. + + 6. Make a tarball of your report: + + $ cd /tmp + $ tar -pcvzf report.tar.gz report + report/ + report/distro.log + report/arpon.log + report/os.log + report/stacktrace.log + report/VERSION + + 7. Send the report.tar.gz tarball to author or via the Bug tracking system: + + http://sourceforge.net/p/arpon/bugs/ + +================================================================================ + 24. SUPPORT THE PROJECT +================================================================================ +We are always happy about donations in any form. + +If you are a corporate user, vendor or private user, we would gladly accept any +donations, either monetary or in goods (network hardware, etc). We assure you +that any donation we receive is very much appreciated and used for further +development of ArpON software. + +If you are interested in making a donation, please contact the author. + +================================================================================ + 25. AUTHOR +================================================================================ + +ArpON was writen by Andrea Di Pasquale aka "spikey" : + + http://it.linkedin.com/pub/andrea-di-pasquale/1b/3b0/252/ + +================================================================================ + 26. COPYRIGHT AND LICENSING +================================================================================ + +Copyright (C) 2008-2016 Andrea Di Pasquale +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +THE POSSIBILITY OF SUCH DAMAGE. + +================================================================================ + 27. THANKS +================================================================================ + +The list of the contributors to the project is available in: + + $ cat /path/to/arpon/THANKS + +================================================================================ + 28. REFERENCE WEBSITE +================================================================================ + +The reference website of ArpON project is here: + + http://arpon.sourceforge.net + +================================================================================ + 29. NOTES +================================================================================ + +The ArpON daemon is completely compatible with the ARP standardized protocol as +described in these official RFC documents: + + 1. RFC 826: + + http://tools.ietf.org/html/rfc826 + + 2. RFC 2131: + + http://tools.ietf.org/html/rfc2131 + + 3. RFC 3927: + + http://tools.ietf.org/html/rfc3927 + + 4. RFC 5227: + + http://tools.ietf.org/html/rfc5227 + +The ArpON daemon sets the arp_ignore and the arp_accept fundamental kernel +network parameters via the sysctl interface as described in this official kernel +document: + + 1. IP sysctl: + + http://www.kernel.org/doc/Documentation/networking/ip-sysctl.txt + +================================================================================ + +vim:ts=4:expandtab + diff -Nru arpon-2.7.2/run/CMakeLists.txt arpon-3.0-ng+dfsg1/run/CMakeLists.txt --- arpon-2.7.2/run/CMakeLists.txt 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/run/CMakeLists.txt 2016-01-29 01:55:40.000000000 +0000 @@ -0,0 +1,50 @@ +# +# Copyright (C) 2008-2016 Andrea Di Pasquale +# Copyright (C) 2008-2016 Giuseppe Marco Randazzo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# +# $ArpON: CMakeLists.txt,v 3.0-ng 01/29/2016 02:55:41 spikey Exp $ +# + +set(arpon_run_src "${CMAKE_SOURCE_DIR}/run/arpon.pid") + +if(${CMAKE_INSTALL_PREFIX} STREQUAL "/") + install(FILES ${arpon_run_src} + DESTINATION /var/run + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + COMPONENT Run) +else(${CMAKE_INSTALL_PREFIX} STREQUAL "/") + install(FILES ${arpon_run_src} + DESTINATION ${CMAKE_INSTALL_PREFIX}/run + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + COMPONENT Run) +endif(${CMAKE_INSTALL_PREFIX} STREQUAL "/") + +# +# EOF +# +# vim:ts=4:expandtab +# diff -Nru arpon-2.7.2/src/arpca.c arpon-3.0-ng+dfsg1/src/arpca.c --- arpon-2.7.2/src/arpca.c 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/arpca.c 2016-01-29 02:06:18.000000000 +0000 @@ -0,0 +1,461 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: arpca.c,v 3.0-ng 01/29/2016 03:06:19 spikey Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_DUMBNET_H +#include +#else /* !HAVE_DUMBNET_H */ +#include +#endif /* HAVE_DUMBNET_H */ + +#include "arpca.h" +#include "exit.h" +#include "intf.h" +#include "ispn.h" +#include "msg.h" +#include "opt.h" +#include "unused.h" + +/* + * ARP cache structure definition. + */ +typedef struct arp_cache { + arp_t *dnet; /* Dnet ARP cache handle. */ + int fd; /* ARP cache file descriptor. */ +} arpc_t; + +/* + * Function prototypes not exported. + */ +static void arpca_init(void); +static void arpca_destroy(void); +static void arpca_loop(void); +static int arpca_clean(const struct arp_entry *entry, void *arg); +static void arpca_add(const struct arp_entry *entry); + +/* + * Initialize the ARP cache structure. + */ +static arpc_t *arp = NULL; + +/* + * Initialize the ARP cache mutex. + */ +static pthread_mutex_t arpca_mtx = PTHREAD_MUTEX_INITIALIZER; + +/* + * Initialize and cleanup the ARP cache. + */ +void +arpca_cleanup(void) +{ + + MSG_DEBUG("Start ARP cache cleanup"); + + /* Initialize the ARP cache structure. */ + arpca_init(); + + MSG_DEBUG("Clean up the ARP cache (possible entries poisoned).."); + + /* Open, loop and cleanup the ARP cache. */ + arpca_loop(); + + MSG_DEBUG("End ARP cache cleanup"); +} + +/* + * Initialize the ARP cache structure. + */ +static void +arpca_init(void) +{ + + /* Allocate the ARP cache structure. */ + if ((arp = (arpc_t *)malloc(sizeof(arpc_t))) == NULL) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("arpc_t *arp allocate in the memory"); + + /* Initialize the dnet ARP cache handle. */ + arp->dnet = NULL; + MSG_DEBUG("arp->dnet = NULL"); + + /* Initialize the ARP cache file descriptor. */ + arp->fd = -1; + MSG_DEBUG("arp->fd = -1"); + + /* Push arpca_destroy() to be called on exit_clean(). */ + exit_push(arpca_destroy, "arpca_destroy"); +} + +/* + * Destroy the ARP cache structure. + */ +static void +arpca_destroy(void) +{ + + do { + /* Unlock the mutex of the ARP cache before the destruction. */ + if (pthread_mutex_unlock(&arpca_mtx) != 0) + break; + + /* ARP cache structure previously allocated? */ + if (arp != NULL) { + /* Dnet ARP cache handle previously open? */ + if (arp->dnet != NULL) { + /* Close the dnet ARP cache handle. */ + arp_close(arp->dnet); + + /* Set the dnet ARP cache handle to NULL. */ + arp->dnet = NULL; + + MSG_DEBUG("Close arp->dnet successful"); + } + + /* ARP cache file descriptor previously open? */ + if (arp->fd != -1) { + /* Close the ARP cache file descriptor. */ + if (close(arp->fd) < 0) + break; + + MSG_DEBUG("Close arp->fd successful"); + } + + /* Deallocate the ARP cache structure. */ + free(arp); + + /* Set the ARP cache structure to NULL. */ + arp = NULL; + + MSG_DEBUG("arpc_t *arp deallocate from the memory"); + } + + return; + } while (0); + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Open, loop and cleanup the ARP cache. + */ +static void +arpca_loop(void) +{ + + do { + /* Open the dnet ARP cache handle. */ + if ((arp->dnet = arp_open()) == NULL) + break; + + MSG_DEBUG("Open arp->dnet successful"); + + /* Open the ARP cache file descriptor. */ + if ((arp->fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + break; + + MSG_DEBUG("Open arp->fd successful"); + + /* + * Cleanup the current IP entries from the dnet + * ARP cache handle (possible entries poisoned). + */ + if (arp_loop(arp->dnet, arpca_clean, NULL) < 0) + break; + + MSG_DEBUG("Cleanup the ARP cache successful"); + + return; + } while (0); + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Cleanup the current IP entry from the ARP cache (possible entry poisoned). + */ +static int +arpca_clean(const struct arp_entry *entry, UNUSED(void *arg)) +{ + + do { + struct in_addr ip; + uint32_t network, netmask; + char *smac = NULL, *sip = NULL, *interface = NULL; + + /* MAC network byte order to string. */ + if ((smac = addr_ntoa(&entry->arp_ha)) == NULL) + break; + + /* IP network byte order to string. */ + if ((sip = addr_ntoa(&entry->arp_pa)) == NULL) + break; + + /* Get the IP addr from the entry. */ + ip.s_addr = entry->arp_pa.addr_ip; + + /* Get the Net addr from the interface. */ + network = (intf_getnetwork())->s_addr; + + /* Get the Mask addr from the interface. */ + netmask = (intf_getnetmask())->s_addr; + + /* + * IP entry is not part of the same network of the interface? + * Therefore: + * + * IP entry is not part of the same network of the interface = + * (IP entry addr & Interface Mask addr) != Interface Net addr + */ + if ((ip.s_addr & netmask) != network) { + MSG_DEBUG("Skip clean, %s is at %s", sip, smac); + return 0; + } + + /* + * Delete the current IP entry from the ARP cache + * (possible entry poisoned) (POLICY: CLEAN). + */ + arpca_delete(&ip); + + /* Get the interface name command option. */ + interface = opt_getinterface(); + + /* Print the CLEAN policy info message. */ + ISPN_CLEAN(sip, smac); + + MSG_DEBUG("Cleanup %s from the ARP cache successful", sip); + + return 0; + } while (0); + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Delete the IP entry from the ARP cache. + */ +void +arpca_delete(struct in_addr *ip) +{ + + do { + struct arp_entry entry; + char UNUSED(*sip) = NULL; + + /* Lock the mutex of the ARP cache. */ + if (pthread_mutex_lock(&arpca_mtx) != 0) + break; + + /* Struct in_addr to struct addr format. */ + addr_pack(&entry.arp_pa, ADDR_TYPE_IP, IP_ADDR_BITS, + &ip->s_addr, IP_ADDR_LEN); + + /* Restore the value of the errno. */ + errno = 0; + + /* Delete the IP entry from ARP cache via the dnet ARP cache handle. */ + if (arp_delete(arp->dnet, &entry) < 0) { + /* IP entry not found in the ARP cache or error? */ + if (errno != ENXIO) + break; + } + +#ifndef NDEBUG + /* IP network byte order to string. */ + if ((sip = addr_ntoa(&entry.arp_pa)) == NULL) + break; + + /* IP entry not found in the ARP cache? */ + if (errno == ENXIO) + MSG_DEBUG("Skip delete %s from the ARP cache successful", sip); + else + MSG_DEBUG("Delete %s from the ARP cache successful", sip); +#endif /* !NDEBUG */ + + /* Unlock the mutex of the ARP cache. */ + if (pthread_mutex_unlock(&arpca_mtx) != 0) + break; + + return; + } while (0); + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Overwrite the IP entry as permanent (or not) + * in the ARP cache with the addresses. + */ +void +arpca_overwrite(struct ether_addr *mac, struct in_addr *ip, int op) +{ + + do { + struct arp_entry entry; + char UNUSED(*smac) = NULL, UNUSED(*sip) = NULL; + + /* Lock the mutex of the ARP cache. */ + if (pthread_mutex_lock(&arpca_mtx) != 0) + break; + + /* Struct ether_addr to struct addr format. */ + addr_pack(&entry.arp_ha, ADDR_TYPE_ETH, ETH_ADDR_BITS, + mac->ether_addr_octet, ETH_ADDR_LEN); + + /* Struct in_addr to struct addr format. */ + addr_pack(&entry.arp_pa, ADDR_TYPE_IP, IP_ADDR_BITS, + &ip->s_addr, IP_ADDR_LEN); + + /* Overwrite the IP entry in the ARP cache as permanent? */ + if (op == ARPCA_PERMANENT) { + /* + * Overwrite the permanent IP entry in the + * ARP cache via the dnet ARP cache handle. + */ + if (arp_add(arp->dnet, &entry) < 0) + break; + + MSG_DEBUG("Overwrite as permanent in the ARP cache successful"); + } else { + /* + * Overwrite the not permanent IP entry in the + * ARP cache via the ARP cache file descriptor. + */ + arpca_add(&entry); + } + +#ifndef NDEBUG + /* MAC network byte order to string. */ + if ((smac = addr_ntoa(&entry.arp_ha)) == NULL) + break; + + /* IP network byte order to string. */ + if ((sip = addr_ntoa(&entry.arp_pa)) == NULL) + break; +#endif /* !NDEBUG */ + + MSG_DEBUG("Overwrite %s at %s in the ARP cache successful", sip, smac); + + /* Unlock the mutex of the ARP cache. */ + if (pthread_mutex_unlock(&arpca_mtx) != 0) + break; + + return; + } while (0); + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * The dnet provides the arp_add() function in order to add a permanent IP + * entry in the ARP cache. Therefore, this our function provides the same + * behavior in order to add a not permanent IP entry in the ARP cache. + */ +static void +arpca_add(const struct arp_entry *entry) +{ + + do { + struct arpreq ar; + char *interface = NULL; + + /* Initialize the ARP request structure. */ + memset(&ar, 0, sizeof(struct arpreq)); + + /* Set the protocol address (IP addr) in the ARP request structure. */ + if (addr_ntos(&entry->arp_pa, &ar.arp_pa) < 0) + break; + + /* Set the hardware address (MAC addr) in the ARP request structure. */ + if (addr_ntos(&entry->arp_ha, &ar.arp_ha) < 0) + break; + + /* + * Set the ethernet hardware address format + * (MAC addr) in the ARP request structure. + */ + ar.arp_ha.sa_family = ARP_HRD_ETH; + + /* + * Set the completed entry (the hardware address + * is valid) flag in the ARP request structure. + */ + ar.arp_flags = ATF_COM; + + /* Get the interface name command option. */ + interface = opt_getinterface(); + + /* Copy the interface in the ARP request structure. */ + strncpy(ar.arp_dev, interface, IF_NAMESIZE); + + /* + * Overwrite the IP entry in the ARP cache + * via the ARP cache file descriptor. + */ + if (ioctl(arp->fd, SIOCSARP, &ar) < 0) + break; + + MSG_DEBUG("Overwrite as not permanent in the ARP cache successful"); + + return; + } while (0); + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/arpca.h arpon-3.0-ng+dfsg1/src/arpca.h --- arpon-2.7.2/src/arpca.h 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/arpca.h 2016-01-29 02:08:56.000000000 +0000 @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: arpca.h,v 3.0-ng 01/29/2016 03:08:58 spikey Exp $ + */ + +#ifndef _ARPCA_H_ +#define _ARPCA_H_ + +/* + * ARP cache IP entry op codes exported. + */ +#define ARPCA_PERMANENT (1 << 0) /* Permanent. */ +#define ARPCA_NOTPERMANENT (1 << 1) /* Not permanent. */ + +/* + * Function prototypes exported. + */ +extern void arpca_cleanup(void); +extern void arpca_delete(struct in_addr *ip); +extern void arpca_overwrite(struct ether_addr *mac, struct in_addr *ip, int op); + +#endif /* !_ARPCA_H_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/arpon.c arpon-3.0-ng+dfsg1/src/arpon.c --- arpon-2.7.2/src/arpon.c 2014-10-14 02:01:51.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/arpon.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,4598 +0,0 @@ -/* - * Copyright (C) 2008-2014 Andrea Di Pasquale - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice(s), this list of conditions and the following disclaimer as - * the first lines of this file unmodified other than the possible - * addition of one or more copyright notices. - * 2. Redistributions in binary form must reproduce the above copyright - * notice(s), this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY - * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE - * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES - * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH - * DAMAGE. - * - * $ArpON: arpon.c,v 2.7.2 10/14/2014 03:56:04 Andrea Di Pasquale Exp $ - */ - -#include -#ifdef SOLARIS -#include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifndef LINUX -#include -#endif -#include -#ifdef LINUX -#include -#endif -#ifdef NETBSD -#include -#elif !defined OPENBSD && !defined SOLARIS -#include -#elif defined SOLARIS -#include -#endif -#ifdef LINUX -#include -#endif -#ifdef OPENBSD -#include -#endif -#include -#include -#ifdef DEBIAN -#include -#else -#include -#endif -#ifdef FREEBSD -#ifdef ETHERTYPE_IPV6 -#undef ETHERTYPE_IPV6 -#endif -#endif -#include -#ifdef FREEBSD -#ifndef ETHERTYPE_IPV6 -#define ETHERTYPE_IPV6 0x86DD /* IP protocol version 6 */ -#endif -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "include/queue.h" - -#include "config.h" - -#if defined NETBSD || defined OPENBSD || defined LINUX || defined SOLARIS -#define octet ether_addr_octet -#endif /* struct ether addr. */ - -#define ERROR(str) aprintf(stderr, 0, "ERROR: %s:%d %s.\n\n", \ - __FILE__, __LINE__, str) - -enum iface_t { IFACE_MANUAL, IFACE_AUTO, IFACE_LIST, IFACE_NULL }; -enum inspec_t { INSPEC_SARPI, INSPEC_DARPI, INSPEC_HARPI, INSPEC_NULL }; - -struct iface { - char dev[IF_NAMESIZE]; - int dev_offset; - struct ether_addr dev_mac; - struct in_addr dev_inet4; - struct in_addr dev_netmask; -}; - -struct arp_header { - /* - * ARP header. - */ - struct arp_hdr ah_header; - /* - * Ethernet header. - */ - struct arp_ethip ah_addresses; -}; - -/* - * For libdnet. - * Required for arp_t fileno. - */ -struct arp_handle { - int fd; - int seq; -}; - -struct arp_cache { - TAILQ_ENTRY(arp_cache) entries; - struct ether_addr ac_mac; - struct in_addr ac_ip; -}; - -struct sarpi_cache { - TAILQ_ENTRY(sarpi_cache) entries; - struct ether_addr sc_mac; - struct in_addr sc_ip; -}; - -struct darpi_cache1 { - TAILQ_ENTRY(darpi_cache1) entries; - struct in_addr dc_ip; - time_t tm_entry; -}; - -struct darpi_cache2 { - TAILQ_ENTRY(darpi_cache2) entries; - struct in_addr dc_ip; - time_t tm_entry; -}; - -struct darpi_cache3 { - TAILQ_ENTRY(darpi_cache3) entries; - struct in_addr dc_ip; - time_t tm_entry; -}; - -static int task_mode_cpu_priority(int, int, int); -static int task_mode_daemon(void); -static FILE *task_mode_pid_open(void); -static void task_mode_pid_close(FILE *); -static int task_mode_log(void); -static FILE *task_mode_log_open(void); -static void task_mode_log_close(FILE *); -static int iface_manager(void); -static int iface_check_uplink(void); -static void iface_check_uplink_thread_sigusr1(int); -static void *iface_check_uplink_thread(void *); -static void iface_set_name(char *); -static void iface_unset_name(void); -static int iface_check_datalink(char *); -static int iface_check_running(void); -static int iface_check_online(void); -static void iface_check_online_packet(unsigned char *, - const struct pcap_pkthdr *, const unsigned char *); -static int iface_del_promisc(void); -static int iface_get_mac_address(void); -static int iface_get_inet4_addresses(void); -static void iface_info_print(void); -static arp_t *arp_cache_open(void); -static void arp_cache_close(arp_t *); -static int arp_cache_add(char *); -static int arp_cache_del(char *); -static int arp_cache_del_all(void); -static int arp_cache_list_create(const struct arp_entry *, void *); -static void arp_cache_list_destroy(void); -static int sarpi_set_timeout(char *); -static void sarpi_manager_thread_sigusr1(int); -static void *sarpi_manager_thread(void *); -static int sarpi_realtime(void); -static void sarpi_realtime_thread_sigusr1(int); -static void *sarpi_realtime_thread(void *); -static pcap_t *sarpi_realtime_open_packets(void); -static void sarpi_realtime_close_packets(pcap_t *); -static void sarpi_realtime_read_packets(unsigned char *, - const struct pcap_pkthdr *, const unsigned char *); -static int sarpi_cache_file_restore(void); -static int sarpi_cache_list_create(const struct arp_entry *, void *); -static void sarpi_cache_list_refresh_thread_sigusr1(int); -static void *sarpi_cache_list_refresh_thread(void *); -static void sarpi_cache_list_destroy(void); -static int darpi_set_timeout(char *); -static void darpi_manager_thread_sigusr1(int); -static void *darpi_manager_thread(void *); -static int darpi_realtime(void); -static void darpi_realtime_thread_sigusr1(int); -static void *darpi_realtime_thread(void *); -static pcap_t *darpi_realtime_open_packets(void); -static void darpi_realtime_close_packets(pcap_t *); -static void darpi_realtime_read_packets(unsigned char *, - const struct pcap_pkthdr *, const unsigned char *); -static int darpi_realtime_send_packet(struct in_addr *); -static int darpi_cache1_list_create(struct in_addr *); -static void darpi_cache1_list_check_thread_sigusr1(int); -static void *darpi_cache1_list_check_thread(void *); -static void darpi_cache1_list_destroy(void); -static int darpi_cache2_list_create(struct in_addr *); -static void darpi_cache2_list_check_thread_sigusr1(int); -static void *darpi_cache2_list_check_thread(void *); -static void darpi_cache2_list_destroy(void); -static int darpi_cache3_list_create(struct in_addr *); -static void darpi_cache3_list_check_thread_sigusr1(int); -static void *darpi_cache3_list_check_thread(void *); -static void darpi_cache3_list_destroy(void); -static void harpi_manager_thread_sigusr1(int); -static void *harpi_manager_thread(void *); -static int harpi_realtime(void); -static void harpi_realtime_thread_sigusr1(int); -static void *harpi_realtime_thread(void *); -static pcap_t *harpi_realtime_open_packets(void); -static void harpi_realtime_close_packets(pcap_t *); -static void harpi_realtime_read_packets(unsigned char *, - const struct pcap_pkthdr *, const unsigned char *); -static void aprintf(FILE *, int, char *, ...); -static void license(void); -static void version(void); -static void help(void); -static int main_signal(void); -static void *main_signal_thread(void *); -static int main_start(void); -static void main_stop(void); - -/* - * iface informations. - */ -static struct iface dev; -/* - * ARP cache. - */ -static struct arp_cache *arp_cache_begin, *arp_cache_next, *arp_cache_pos; -static TAILQ_HEAD(, arp_cache) arp_cache_head; -/* - * SARPI cache. - */ -static struct sarpi_cache *sarpi_cache_begin, *sarpi_cache_next, - *sarpi_cache_pos; -static TAILQ_HEAD(, sarpi_cache) sarpi_cache_head; -/* - * DARPI 1 cache. - */ -static struct darpi_cache1 *darpi_cache1_begin, *darpi_cache1_next, - *darpi_cache1_pos; -static TAILQ_HEAD(, darpi_cache1) darpi_cache1_head; -/* - * DARPI 2 cache. - */ -static struct darpi_cache2 *darpi_cache2_begin, *darpi_cache2_next, - *darpi_cache2_pos; -static TAILQ_HEAD(, darpi_cache2) darpi_cache2_head; -/* - * DARPI 3 cache. - */ -static struct darpi_cache3 *darpi_cache3_begin, *darpi_cache3_next, - *darpi_cache3_pos; -static TAILQ_HEAD(, darpi_cache3) darpi_cache3_head; -/* - * Signal handler. - */ -static sigset_t sigse; -/* - * Thread handler for: - * thread[0] = Signal handler - * thread[1] = SARPI/DARPI/HARPI manager - * thread[2] = Iface uplink handler - * thread[3] = SARPI/DARPI/HARPI - * thread[4] = SARPI/DARPI/HARPI - * thread[5] = DARPI/HARPI - * thread[6] = DARPI/HARPI - * thread[7] = HARPI. - */ -static pthread_t thread[8]; -static pthread_attr_t join_attr, detach_attr; -static pthread_rwlock_t rlock, wlock, rlock2, wlock2, - rlock3, wlock3, rlock4, wlock4; -/* - * Default nice value for CPU priority. - */ -static int cpu_priority = 0; -/* - * Default pid file. - */ -static char *pid_file = "/var/run/arpon.pid"; -static pid_t pid_main; -/* - * Default log file. - */ -static char *log_file = "/var/log/arpon.log"; -/* - * Default log mode, with -1 is off. - */ -static int log_mode = -1; -/* - * Default SARPI cache file. - */ -static char *sarpi_cache_file = arpon_sarpi; -/* - * Default ARP cache refresh timeout, 5 minuts. - */ -static int sarpi_timeout = 5; -/* - * Default DARPI cache entry timeout, 5 seconds. - */ -static int darpi_timeout = 5; -/* - * Device name. - */ -static char *ddev = NULL; -/* - * Default Iface type. - */ -static enum iface_t dif = IFACE_NULL; -/* - * Default Inspection type. - */ -static enum inspec_t dinspec = INSPEC_NULL; - -/********************** - * Task mode handler: * - **********************/ - -/* - * Sets CPU priority for who. - */ -static int -task_mode_cpu_priority(int which, int who, int prio) -{ - - if (cpu_priority != 0) { - if (setpriority(which, who, prio) < 0) { - ERROR(strerror(errno)); - - return (-1); - } - } - - return (0); -} - -/* - * Demonize the process. - */ -static int -task_mode_daemon(void) -{ - struct stat stats; - FILE *pid_fstream; - int fd; - - if ((pid_fstream = task_mode_pid_open()) == NULL) { - return (-1); - } - - if (stat(pid_file, &stats) < 0) { - aprintf(stderr, 0, "ERROR: %s\n\n", strerror(errno)); - - return (-1); - } - - task_mode_pid_close(pid_fstream); - - if (S_ISREG(stats.st_mode) == 0) { - aprintf(stderr, 0, "ERROR: %s is not a regular file.\n\n", pid_file); - - return (-1); - } - - aprintf(stdout, 1, "PID = <%s>\n\n", pid_file); - - switch (fork()) { - case (-1): - ERROR(strerror(errno)); - return (-1); - - case (0): - break; - - default: - exit(EXIT_SUCCESS); - } - - if (setsid() < 0) { - ERROR(strerror(errno)); - - return (-1); - } - - /* - * PID CPU Scheduling. - */ - if (task_mode_cpu_priority(PRIO_PROCESS, getpid(), cpu_priority) < 0) { - return (-1); - } - - /* - * Write arpon.pid file. - */ - if ((pid_fstream = task_mode_pid_open()) == NULL) { - kill(pid_main, SIGTERM); - - exit(EXIT_FAILURE); - } - - fprintf(pid_fstream, "%d\n", (int)getpid()); - fflush(pid_fstream); - task_mode_pid_close(pid_fstream); - - if ((fd = open("/dev/null", O_RDWR, 0)) < 0) { - ERROR(strerror(errno)); - - return (-1); - } - - dup2(fd, STDIN_FILENO); - dup2(fd, STDOUT_FILENO); - - if (fd > 2) { - close(fd); - } - - return (0); -} - -/* - * Open pid file. - */ -static FILE * -task_mode_pid_open(void) -{ - FILE *pid_fstream; - - if ((pid_fstream = fopen(pid_file, "w+")) == NULL) { - aprintf(stderr, 0, "ERROR: %s: %s\n\n", pid_file, strerror(errno)); - - return (NULL); - } - - return (pid_fstream); -} - -/* - * Close pid file. - */ -static void -task_mode_pid_close(FILE *pid_fstream) -{ - - if (pid_fstream != NULL) { - fclose(pid_fstream); - } -} - - -/* - * Logging mode. - */ -static int -task_mode_log(void) -{ - struct stat stats; - FILE *log_fstream; - - if ((log_fstream = task_mode_log_open()) == NULL) { - return (-1); - } - - if (stat(log_file, &stats) < 0) { - aprintf(stderr, 0, "ERROR: %s: %s\n\n", log_file, strerror(errno)); - - return (-1); - } - - task_mode_log_close(log_fstream); - - if (S_ISREG(stats.st_mode) == 0) { - aprintf(stderr, 0, "ERROR: %s is not a regular file.\n\n", log_file); - - return (-1); - } - - /* - * Logging mode: - * 0: on - * -1: off. - */ - log_mode = 0; - - return (0); -} - -/* - * Open log file. - */ -static FILE * -task_mode_log_open(void) -{ - FILE *log_fstream; - - if ((log_fstream = fopen(log_file, "a+")) == NULL) { - aprintf(stderr, 0, "ERROR: %s: %s\n\n", log_file, strerror(errno)); - - return (NULL); - } - - return (log_fstream); -} - -/* - * Close log file. - */ -static void -task_mode_log_close(FILE *log_fstream) -{ - - if (log_fstream != NULL) { - fclose(log_fstream); - } -} - -/******************* - * iface Handler: * - *******************/ - -/* - * Handles the network iface with following modes: - * - Manual, - * - Automatic (First iface that can to be used), - * - Listing eventual network ifaces. - * - boot/unplug/hibernation/suspension interface - * - * Doing the following operations: - * - Verifying Datalink - * - Selecting the network iface to be used - * - Verifying iface running - * - Veryfying iface online ready - * - Putting down the promiscue flag if found set - * - Reading MAC Address - * - Reading IP, netmask inet4 addresses - * - Printing out network ifaces dates. - */ -static int -iface_manager(void) -{ - char errbuf[PCAP_ERRBUF_SIZE]; - pcap_if_t *ifc; - - if (pcap_findalldevs(&ifc, errbuf) < 0) { - ERROR(errbuf); - - return (-1); - } - - /* - * For SARPI and DARPI. - */ - if (dif == IFACE_NULL) { - dif = IFACE_AUTO; - } - - for (; ifc != NULL; ifc = ifc->next) { - switch (dif) { - case (IFACE_MANUAL): - if (strncmp(ddev, ifc->name, IF_NAMESIZE) == 0) { - if ((ifc->flags & PCAP_IF_LOOPBACK) == 0) { - if (iface_check_datalink(ifc->name) < 0) { - aprintf(stderr, 0, "ERROR: %s interface's datalink " \ - "is not supported!\n\n", ddev); - pcap_freealldevs(ifc); - - exit(-1); - } - - iface_set_name(ifc->name); - - if (iface_del_promisc() < 0 || - iface_get_mac_address() < 0 || - iface_get_inet4_addresses() < 0) { - pcap_freealldevs(ifc); - - exit(-1); - } - - pcap_freealldevs(ifc); - - return (0); - } else { - aprintf(stderr, 0, "ERROR: %s interface is not " \ - "supported!\n\n", ddev); - pcap_freealldevs(ifc); - - exit(-1); - } - } - break; - - case (IFACE_AUTO): - if ((ifc->flags & PCAP_IF_LOOPBACK) == 0) { - if (iface_check_datalink(ifc->name) < 0) { - break; - } - - iface_set_name(ifc->name); - - if (iface_del_promisc() < 0 || - iface_get_mac_address() < 0 || - iface_get_inet4_addresses() < 0) { - iface_unset_name(); - - break; - } - - pcap_freealldevs(ifc); - - return (0); - } - break; - - case (IFACE_LIST): - if ((ifc->flags & PCAP_IF_LOOPBACK) == 0) { - if (iface_check_datalink(ifc->name) < 0) { - break; - } - - iface_set_name(ifc->name); - - if (iface_del_promisc() < 0 || - iface_get_mac_address() < 0 || - iface_get_inet4_addresses() < 0) { - pcap_freealldevs(ifc); - - return (-1); - } - } - break; - - default: - break; - } - } - - if (dif == IFACE_MANUAL) { - if (strncmp(ddev, dev.dev, IF_NAMESIZE) != 0) { - aprintf(stderr, 0, "ERROR: %s interface not found!\n\n", ddev); - pcap_freealldevs(ifc); - - exit(-1); - } - } else if (dif == IFACE_AUTO) { - if (dev.dev[0] == '\0') { - aprintf(stderr, 0, "ERROR: Interface not found!\n\n"); - pcap_freealldevs(ifc); - - exit(-1); - } - } - - pcap_freealldevs(ifc); - return (0); -} - -/* - * Check automatically iface uplink: - * - boot - * - unplug ethernet/wireless - * - hibernation - * - suspension - */ -static int -iface_check_uplink(void) -{ - - pthread_attr_init(&join_attr); - pthread_attr_setschedpolicy(&join_attr, SCHED_RR); - - /* - * Thread 3 joinabled, checks automatically iface uplink. - */ - if (pthread_create(&thread[2], &join_attr, - iface_check_uplink_thread, (void *) NULL) != 0) { - ERROR(strerror(errno)); - - pthread_attr_destroy(&join_attr); - exit(-1); - } - - pthread_attr_destroy(&join_attr); - return (0); -} - -/* - * Iface uplink signal handler. - */ -static void -iface_check_uplink_thread_sigusr1(int sig) -{ - - pthread_exit((void *) 0); -} - -/* - * Check automatically iface uplink. - * If uplink is down stops daemon, waits uplink up - * and restart the daemon. - */ -static void * -iface_check_uplink_thread(void *arg) -{ - struct sigaction saction; - int ret, ret2; - -#ifdef NETBSD - saction.sa_flags = 0; -#endif - saction.sa_handler = iface_check_uplink_thread_sigusr1; - - if (sigaction(SIGUSR1, &saction, NULL) < 0) { - ERROR(strerror(errno)); - - pthread_exit((void *) -1); - } - - while (1) { - if ((ret = iface_check_running()) < 0) { - pthread_exit((void *) -1); - } else if (ret > 0) { - /* - * iface down/suspend. - */ - - while (1) { - if ((ret2 = iface_check_running()) < 0) { - pthread_exit((void *) -1); - } else if (ret2 == 0) { - /* - * Iface up/restore. - * Reboot the daemon. - */ - kill(0, SIGHUP); - break; - } - - /* - * Check each 1 second. - */ - sleep(1); - } - } - - /* - * Iface up. - * Check each 1 second. - */ - sleep(1); - } - - pthread_exit((void *) 0); -} - -/* - * Sets the network iface. - */ -static void -iface_set_name(char *name) -{ - - memset(dev.dev, '\0', IF_NAMESIZE); - strncpy(dev.dev, name, IF_NAMESIZE); -} - -/* - * Unset the network iface. - */ -static void -iface_unset_name(void) -{ - - memset(dev.dev, '\0', IF_NAMESIZE); -} - -/* - * Checks the datalink. Accepting EN10MB only - * (and so only ethernet and wireless ifaces). - */ -static int -iface_check_datalink(char *devarg) -{ - char errbuf[PCAP_ERRBUF_SIZE]; - pcap_t *pcap; - int datalink; - - if ((pcap = pcap_open_live(devarg, BUFSIZ, 0, 0, errbuf)) == NULL) { - ERROR(errbuf); - - return (-1); - } - - if ((datalink = pcap_datalink(pcap)) < 0) { - ERROR(pcap_geterr(pcap)); - - return (-1); - } - - /* - * Set network offset if it is - * ethernet network iface. - */ - if (datalink == DLT_EN10MB) { - dev.dev_offset = 14; - pcap_close(pcap); - - return (0); - } - - pcap_close(pcap); - - return (-1); -} - -/* - * Checks if iface is running. - */ -static int -iface_check_running(void) -{ - struct ifreq ifr; - int sd; - - if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { - ERROR(strerror(errno)); - - return (-1); - } - - memset(ifr.ifr_name, '\0', IF_NAMESIZE); - strncpy(ifr.ifr_name, dev.dev, IF_NAMESIZE); - - if (ioctl(sd, SIOCGIFFLAGS, &ifr) < 0) { - ERROR(strerror(errno)); - close(sd); - - return (-1); - } - - /* - * iface is not running. - */ - if ((ifr.ifr_flags & IFF_RUNNING) == 0) { - close(sd); - - return (1); - } - - /* - * iface running. - */ - close(sd); - - return (0); -} - -/* - * Wait first packet for online check. - */ -static int -iface_check_online(void) -{ - struct bpf_program compiled_filter; - char errbuf[PCAP_ERRBUF_SIZE], *filter = "arp"; - pcap_t *pcap; - int ret; -#ifndef LINUX - unsigned int op = 1; -#endif - - if ((pcap = pcap_open_live(dev.dev, BUFSIZ, 0, 0, errbuf)) == NULL) { - ERROR(errbuf); - - return (-1); - } - -#ifndef LINUX - /* - * BSD, differently from linux does not - * support automatic socket soft real time - * (Linux Socket Filter). - * Therefore on BSD platform it's necessary - * to use this I/O Control. - */ - if (ioctl(pcap_fileno(pcap), BIOCIMMEDIATE, &op) < 0) { - ERROR(strerror(errno)); - pcap_close(pcap); - - return (-1); - } -#endif - - if (pcap_compile(pcap, &compiled_filter, - filter, 0, dev.dev_netmask.s_addr) < 0) { - ERROR(pcap_geterr(pcap)); - pcap_close(pcap); - - return (-1); - } - - if (pcap_setfilter(pcap, &compiled_filter) < 0) { - ERROR(pcap_geterr(pcap)); - pcap_close(pcap); - - return (-1); - } - - /* - * Wait first packet. - */ - if ((ret = pcap_loop(pcap, 1, iface_check_online_packet, NULL)) < 0) { - pcap_freecode(&compiled_filter); - - switch (ret) { - case (-1): - ERROR(pcap_geterr(pcap)); - pcap_close(pcap); - - return (-1); - - case (-2): - default: - pcap_close(pcap); - /* - * Offline. - */ - return (1); - } - } - - /* - * Online. - */ - - pcap_freecode(&compiled_filter); - pcap_close(pcap); - - return (0); -} - -/* - * Wait an ARP packet. - */ -static void -iface_check_online_packet(unsigned char *arg, const struct pcap_pkthdr - *header, const unsigned char *packet) -{ - - /* - * ARP traffic is ok. - */ - return; -} - -/* - * Putting down the promiscue flag if - * found set in network iface. - */ -static int -iface_del_promisc(void) -{ - struct ifreq ifr; - int sd; - - if ((sd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - ERROR(strerror(errno)); - - return (-1); - } - - strncpy(ifr.ifr_name, dev.dev, sizeof(char) * IF_NAMESIZE); - ifr.ifr_name[sizeof(char) * strlen(ifr.ifr_name)] = '\0'; - - if (ioctl(sd, SIOCGIFFLAGS, &ifr) < 0) { - ERROR(strerror(errno)); - close(sd); - - return (-1); - } - - if (ifr.ifr_flags & IFF_PROMISC) { - /* - * Remove Promisc flag - */ - ifr.ifr_flags &= ~IFF_PROMISC; - - if (ioctl(sd, SIOCSIFFLAGS, &ifr) < 0) { - ERROR(strerror(errno)); - close(sd); - - return (-1); - } - } - - close(sd); - return (0); -} - -/* - * Reading network ifaces hw-MAC address. - */ -static int -iface_get_mac_address(void) -{ - eth_addr_t mac; - eth_t *if_eth; - int i; - - if ((if_eth = eth_open(dev.dev)) == NULL) { - ERROR(strerror(errno)); - - return (-1); - } - - if (eth_get(if_eth, &mac) < 0) { - ERROR(strerror(errno)); - eth_close(if_eth); - - return (-1); - } - - for (i = 0; i < ETHER_ADDR_LEN; i++) { - dev.dev_mac.octet[i] = mac.data[i]; - } - - eth_close(if_eth); - - return (0); -} - -/* - * Checks and saves IPv4 and Netmask network adresses. - */ -static int -iface_get_inet4_addresses(void) -{ - char errbuf_lnet[LIBNET_ERRBUF_SIZE], errbuf_pcap[PCAP_ERRBUF_SIZE]; - libnet_t *lnet; - bpf_u_int32 network; - int ret, ret2, state = 0; - - /* - * Get netmask and IPv4 addresses. - * Case of errors, it waits: - * - running iface - * - IPv4 assigned - * - online iface. - */ - while (1) { - dev.dev_netmask.s_addr = 0; - - if (pcap_lookupnet(dev.dev, &network, - &(dev.dev_netmask.s_addr), errbuf_pcap) < 0) { - if (dif == IFACE_LIST) { - return (0); - } else { - if (errno == EADDRNOTAVAIL) { - /* - * Use the state for one first WARNING print. - */ - if (state == 0) { - aprintf(stdout, 1, "WARNING: %s\n", errbuf_pcap); - - if (dinspec == INSPEC_NULL) { - exit(EXIT_FAILURE); - } - - state = 1; - } - continue; - } else { - if (dif != IFACE_AUTO) { - ERROR(errbuf_pcap); - } - - return (-1); - } - } - } else { - /* Checks iface running. - * Return: - * -1: Error - * 0: iface running - * 1: iface is not running. - */ - if ((ret = iface_check_running()) < 0) { - return (-1); - } - /* - * iface running. - */ - else if (ret == 0) { - /* - * Check iface online with - * first packet received. - */ - if (dif != IFACE_LIST && dinspec != INSPEC_NULL) { - aprintf(stdout, 1, "WAIT LINK on %s...\n", - dev.dev); - - while (1) { - /* - * Check iface online. - * Return: - * -1: Error - * 0: Online - * 1: Offline - */ - if ((ret2 = iface_check_online()) < 0) { - return (-1); - } else if (ret2 == 1) { - sleep(1); - continue; - } else { - break; - } - } - } - - /* - * Get IPv4 address. - */ - if ((lnet = libnet_init(LIBNET_LINK, dev.dev, - errbuf_lnet)) == NULL) { - if (dif == IFACE_LIST) { - return (0); - } else { - ERROR(errbuf_lnet); - - return (-1); - } - } - - dev.dev_inet4.s_addr = 0; - - if ((dev.dev_inet4.s_addr = libnet_get_ipaddr4(lnet)) == -1) { - ERROR(libnet_geterror(lnet)); - - return (-1); - } - - libnet_destroy(lnet); - break; - } - - /* - * iface is not running. - */ - } - - /* - * Check each 1 second. - */ - sleep(1); - } - - if (dinspec == INSPEC_NULL) { - aprintf(stdout, 0, "DEV = <%s>\n", dev.dev); - aprintf(stdout, 0, "HW = <%s>\n", ether_ntoa(&(dev.dev_mac))); - aprintf(stdout, 0, "IP = <%s>\n", inet_ntoa(dev.dev_inet4)); - - switch (dif) { - case (IFACE_MANUAL): - case (IFACE_AUTO): - aprintf(stdout, 0, "\n"); - break; - - case (IFACE_LIST): - case (IFACE_NULL): - break; - } - } - - return (0); -} - -/* - * Prints network ifaces informations. - * For SARPI and DARPI. - */ -static void -iface_info_print(void) -{ - struct tm tm_cur; - time_t time_cur; - - time_cur = time(NULL); - tm_cur = *(struct tm *) localtime(&time_cur); - - switch (dinspec) { - case (INSPEC_SARPI): - aprintf(stdout, 1, "SARPI on\n"); - break; - - case (INSPEC_DARPI): - aprintf(stdout, 1, "DARPI on\n"); - break; - - case (INSPEC_HARPI): - aprintf(stdout, 1, "HARPI on\n"); - break; - - case (INSPEC_NULL): - break; - } - - aprintf(stdout, 0, "\t DATE = <%02d/%02d/%04d>\n", - tm_cur.tm_mon + 1, tm_cur.tm_mday, tm_cur.tm_year + 1900); - aprintf(stdout, 0, "\t DEV = <%s>\n ", dev.dev); - aprintf(stdout, 0, "\t HW = <%s>\n ", ether_ntoa(&(dev.dev_mac))); - aprintf(stdout, 0, "\t IP = <%s>\n", inet_ntoa(dev.dev_inet4)); -} - -/******************** - * ARP Cache handler: - ********************/ - -/* - * Open ARP cache. - */ -static arp_t * -arp_cache_open(void) -{ - arp_t *arp; - - if ((arp = arp_open()) == NULL) { - ERROR(strerror(errno)); - - return (NULL); - } - - return (arp); -} - -/* - * Close ARP cache. - */ -static void -arp_cache_close(arp_t *arp) -{ - - arp_close(arp); -} - -/* - * Adds ARP cache entry. - */ -static int -arp_cache_add(char *arg) -{ - struct arp_entry entry; - char c_mac[18], c_ip[16]; - arp_t *arp; - - if ((arp = arp_cache_open()) == NULL) { - return (-1); - } - - sscanf(arg, "%15s %17s", c_ip, c_mac); - c_mac[sizeof(char) * strlen(c_mac)] = '\0'; - c_ip[sizeof(char) * strlen(c_ip)] = '\0'; - - if (addr_aton(c_mac, &entry.arp_ha) < 0) { - ERROR(strerror(errno)); - arp_cache_close(arp); - - return (-1); - } - - if (addr_aton(c_ip, &entry.arp_pa) < 0) { - ERROR(strerror(errno)); - arp_cache_close(arp); - - return (-1); - } - - arp_add(arp, &entry); - - arp_cache_close(arp); - - return (0); -} - -/* - * Search entry in ARP cache, if is found it will delete. - */ -static int -arp_cache_del(char *arg) -{ - struct arp_entry entry; - arp_t *arp; - int i; - - if ((arp = arp_cache_open()) == NULL) { - return (-1); - } - - /* - * Read ARP cache. - */ - if (arp_loop(arp, arp_cache_list_create, NULL) < 0) { - arp_cache_close(arp); - - return (-1); - } - - /* - * Search IPv4 in ARP Cache. - */ - TAILQ_FOREACH(arp_cache_pos, &arp_cache_head, entries) { - if (strcmp(arg, inet_ntoa(arp_cache_pos->ac_ip)) == 0) { - for (i = 0; i < ETHER_ADDR_LEN; i++) { - entry.arp_ha.addr_eth.data[i] = arp_cache_pos->ac_mac.octet[i]; - } - - if (addr_aton(inet_ntoa(arp_cache_pos->ac_ip), &entry.arp_pa) < 0) { - ERROR(strerror(errno)); - arp_cache_list_destroy(); - arp_cache_close(arp); - - return (-1); - } - - arp_delete(arp, &entry); - - arp_cache_list_destroy(); - arp_cache_close(arp); - - return (0); - } - } - - /* - * Entry not found! - */ - arp_cache_list_destroy(); - arp_cache_close(arp); - - return (1); -} - -/* - * Delete all found entries in the ARP - * cache reading ARP cache tail. - */ -static int -arp_cache_del_all(void) -{ - struct arp_entry entry; - arp_t *arp; - int i; - - if ((arp = arp_cache_open()) == NULL) { - return (-1); - } - - /* - * Read ARP cache. - */ - if (arp_loop(arp, arp_cache_list_create, NULL) < 0) { - arp_cache_close(arp); - - return (-1); - } - - TAILQ_FOREACH(arp_cache_pos, &arp_cache_head, entries) { - for (i = 0; i < ETHER_ADDR_LEN; i++) { - entry.arp_ha.addr_eth.data[i] = arp_cache_pos->ac_mac.octet[i]; - } - - if (addr_aton(inet_ntoa(arp_cache_pos->ac_ip), &entry.arp_pa) < 0) { - ERROR(strerror(errno)); - arp_cache_list_destroy(); - arp_cache_close(arp); - - return (-1); - } - - arp_delete(arp, &entry); - } - - arp_cache_list_destroy(); - arp_cache_close(arp); - - return (0); -} - -/* - * Create ARP cache tail using one entry or it adds simply a new entry. - */ -static int -arp_cache_list_create(const struct arp_entry *entry, void *arg) -{ - struct ether_addr mac; - struct in_addr ip; - register int i; - - for (i = 0; i < ETHER_ADDR_LEN; i++) { - mac.octet[i] = entry->arp_ha.addr_eth.data[i]; - } - - ip.s_addr = entry->arp_pa.addr_ip; - - if (arp_cache_begin == NULL) { - TAILQ_INIT(&arp_cache_head); - - if ((arp_cache_begin = malloc(sizeof(struct arp_cache))) == NULL) { - ERROR(strerror(errno)); - - return (-1); - } - - memcpy(&arp_cache_begin->ac_mac, &mac, sizeof(mac)); - memcpy(&arp_cache_begin->ac_ip, &ip, sizeof(ip)); - TAILQ_INSERT_HEAD(&arp_cache_head, arp_cache_begin, entries); - } else { - if ((arp_cache_next = malloc(sizeof(struct arp_cache))) == NULL) { - ERROR(strerror(errno)); - - return (-1); - } - - memcpy(&arp_cache_next->ac_mac, &mac, sizeof(mac)); - memcpy(&arp_cache_next->ac_ip, &ip, sizeof(ip)); - TAILQ_INSERT_TAIL(&arp_cache_head, arp_cache_next, entries); - } - - return (0); -} - -/* - * Destroy ARP cache tail. - */ -static void -arp_cache_list_destroy(void) -{ - - while (TAILQ_EMPTY(&arp_cache_head) == 0) { - arp_cache_pos = TAILQ_FIRST(&arp_cache_head); - - TAILQ_REMOVE(&arp_cache_head, arp_cache_pos, entries); - free(arp_cache_pos); - } -} - - -/****************** - * SARPI handler: * - ******************/ - -/* - * Sets ARP cache timeout for automatic update. - */ -static int -sarpi_set_timeout(char *timeout) -{ - int val = atoi(timeout); - - /* - * Don't accept timeout < 0. - */ - if (val < 0) { - aprintf(stderr, 0, - "ERROR: SARPI timeout %d minuts out of the range.\n\n", val); - - return (-1); - } - - sarpi_timeout = val; - - return (0); -} - -/* - * SARPI manager signal handler. - */ -static void -sarpi_manager_thread_sigusr1(int sig) -{ - - sarpi_cache_list_destroy(); - pthread_exit((void *) 0); -} - -/* - * Handles SARPI through two thread for parallelism: - * - 1: Update automatically the ARP cache - * - 2: Works in soft real time, in other words it - * listens to the inbound/outbound arp packets. - */ -static void * -sarpi_manager_thread(void *arg) -{ - struct sigaction saction; - -#ifdef NETBSD - saction.sa_flags = 0; -#endif - saction.sa_handler = sarpi_manager_thread_sigusr1; - - if (sigaction(SIGUSR1, &saction, NULL) < 0) { - ERROR(strerror(errno)); - - pthread_exit((void *) -1); - } - - /* - * Iface work. - */ - if (iface_manager() < 0) { - pthread_exit((void *) -1); - } - - if (iface_check_uplink() < 0) { - pthread_exit((void *) -1); - } - - iface_info_print(); - - /* - * PID Parent CPU Scheduling. - */ - if (task_mode_cpu_priority(PRIO_PROCESS, getpid(), cpu_priority) < 0) { - pthread_exit((void *) -1); - } - - /* - * Delete all ARP Cache entries (Possible entries poisoned). - */ - if (arp_cache_del_all() < 0) { - pthread_exit((void *) -1); - } - - pthread_rwlock_init(&rlock, NULL); - pthread_rwlock_init(&wlock, NULL); - - /* - * ARP Cache entries protected from file. - */ - if (sarpi_cache_file_restore() < 0) { - exit(-1); - } - - pthread_attr_init(&detach_attr); - pthread_attr_setdetachstate(&detach_attr, PTHREAD_CREATE_DETACHED); - pthread_attr_setschedpolicy(&detach_attr, SCHED_RR); - - /* - * Thread 4 detached, update automatically the ARP cache. - */ - if (pthread_create(&thread[3], &detach_attr, - sarpi_cache_list_refresh_thread, (void *) NULL) != 0) { - ERROR(strerror(errno)); - sarpi_cache_list_destroy(); - - pthread_exit((void *) -1); - } - - /* - * Thread 5 detached, realtime inbound/outbound work. - */ - if (sarpi_realtime() < 0) { - sarpi_cache_list_destroy(); - - pthread_exit((void *) -1); - } - - pthread_exit((void *) 0); -} - -/* - * SARPI Realtime, process ARP reply - * inbound/outbound ARP packets. - */ -static int -sarpi_realtime(void) -{ - - pthread_attr_init(&detach_attr); - pthread_attr_setdetachstate(&detach_attr, PTHREAD_CREATE_DETACHED); - pthread_attr_setschedpolicy(&detach_attr, SCHED_RR); - - /* - * Thread 5 detached, Works in soft real time, in other - * words it listens to the inbound/outbound ARP packets. - */ - if (pthread_create(&thread[4], &detach_attr, sarpi_realtime_thread, - (void *) NULL) != 0) { - ERROR(strerror(errno)); - - return (-1); - } - - pthread_attr_destroy(&detach_attr); - - return (0); -} - -/* - * SARPI realtime signal handler. - */ -static void -sarpi_realtime_thread_sigusr1(int sig) -{ - - pthread_exit((void *) 0); -} - -/* - * Use thread for non blocking to pcap_loop(). - */ -static void * -sarpi_realtime_thread(void *arg) -{ - struct sigaction saction; - pcap_t *pcap; - -#ifdef NETBSD - saction.sa_flags = 0; -#endif - saction.sa_handler = sarpi_realtime_thread_sigusr1; - - if (sigaction(SIGUSR1, &saction, NULL) < 0) { - ERROR(strerror(errno)); - - pthread_exit((void *) -1); - } - - if ((pcap = sarpi_realtime_open_packets()) == NULL) { - pthread_exit((void *) -1); - } - - while (1) { - if (pcap_loop(pcap, 1, sarpi_realtime_read_packets, NULL) < 0) { - ERROR(pcap_geterr(pcap)); - sarpi_realtime_close_packets(pcap); - - pthread_exit((void *) -1); - } - } - - sarpi_realtime_close_packets(pcap); - - pthread_exit((void *) 0); -} - -/* - * Open pcap file descriptor. - */ -static pcap_t * -sarpi_realtime_open_packets(void) -{ - struct bpf_program compiled_filter; - char errbuf[PCAP_ERRBUF_SIZE], *filter = "arp"; - pcap_t *pcap; -#ifndef LINUX - unsigned int op = 1; -#endif - - if ((pcap = pcap_open_live(dev.dev, BUFSIZ, 0, 0, errbuf)) == NULL) { - ERROR(errbuf); - - return (NULL); - } - -#ifndef LINUX - /* - * BSD, differently from linux does not - * support automatic socket soft real time - * (Linux Socket Filter). - * Therefore on BSD platform it's necessary - * to use this I/O Control. - */ - if (ioctl(pcap_fileno(pcap), BIOCIMMEDIATE, &op) < 0) { - ERROR(strerror(errno)); - - return (NULL); - } -#endif - - if (pcap_compile(pcap, &compiled_filter, filter, 0, - dev.dev_netmask.s_addr) < 0) { - ERROR(pcap_geterr(pcap)); - sarpi_realtime_close_packets(pcap); - - return (NULL); - } - - if (pcap_setfilter(pcap, &compiled_filter) < 0) { - ERROR(pcap_geterr(pcap)); - sarpi_realtime_close_packets(pcap); - - return (NULL); - } - - pcap_freecode(&compiled_filter); - return (pcap); -} - -/* - * Close pcap file descriptor. - */ -static void -sarpi_realtime_close_packets(pcap_t *pcap) -{ - - pcap_close(pcap); -} - -/* - * SARPI I/O - * Read doc/SARPI.jpg algorithm. - */ -static void -sarpi_realtime_read_packets(unsigned char *arg, const struct pcap_pkthdr - *header, const unsigned char *packet) -{ - struct ether_addr src_mac, dst_mac; - struct arp_header *arp_packet; - char c_src_ip[16], c_src_mac[18], c_dst_ip[16], c_dst_mac[18], - c_ap_ip[16], entry[34]; - int i; - - /* - * ARP Packet. - */ - arp_packet = (struct arp_header *) (packet + dev.dev_offset); - - /* - * Convert the source MAC/IPv4 to string. - */ - snprintf(c_src_ip, 16, "%d.%d.%d.%d", - arp_packet->ah_addresses.ar_spa[0], - arp_packet->ah_addresses.ar_spa[1], - arp_packet->ah_addresses.ar_spa[2], - arp_packet->ah_addresses.ar_spa[3]); - - for (i = 0; i < ETHER_ADDR_LEN; i++) { - src_mac.octet[i] = arp_packet->ah_addresses.ar_sha[i]; - } - strncpy(c_src_mac, ether_ntoa(&src_mac), sizeof(char) * 18); - c_src_mac[sizeof(char) * strlen(c_src_mac)] = '\0'; - - /* - * Convert the destination MAC/IPv4 to string - */ - snprintf(c_dst_ip, 16, "%d.%d.%d.%d", - arp_packet->ah_addresses.ar_tpa[0], - arp_packet->ah_addresses.ar_tpa[1], - arp_packet->ah_addresses.ar_tpa[2], - arp_packet->ah_addresses.ar_tpa[3]); - - for (i = 0; i < ETHER_ADDR_LEN; i++) { - dst_mac.octet[i] = arp_packet->ah_addresses.ar_tha[i]; - } - - strncpy(c_dst_mac, ether_ntoa(&dst_mac), sizeof(char) * 18); - c_dst_mac[sizeof(char) * strlen(c_dst_mac)] = '\0'; - - /* - * In request, possible source address poisoned. - * In reply, possible ARP Gratuitous for ARP poisoning. - */ - if (ntohs(arp_packet->ah_header.ar_op) == ARP_OP_REQUEST) { - /* - * Check if it is a broadcast address. - */ - if (strcmp(c_src_ip, inet_ntoa(dev.dev_inet4)) != 0 && - strcmp(c_dst_ip, inet_ntoa(dev.dev_inet4)) != 0 && - strcmp(c_src_ip, c_dst_ip) == 0) { - /* - * Search ARP reply source in SARPI (ARP cache) entries. - */ - TAILQ_FOREACH(sarpi_cache_pos, &sarpi_cache_head, entries) { - /* - * Convert MAC/IPv4 to string form. - */ - memset(c_ap_ip, '\0', sizeof(char) * 16); - strncpy(c_ap_ip, inet_ntoa(sarpi_cache_pos->sc_ip), - sizeof(char) * 16); - c_ap_ip[sizeof(char) * strlen(c_ap_ip)] = '\0'; - - /* - * In reply, possible ARP Gratuitous for ARP poisoning. - * Check if source is found in SARPI Cache. - */ - if (strcmp(c_src_ip, c_ap_ip) == 0) { - /* - * Source is Found! We reset static entry. - */ - aprintf(stdout, 1, "ARP cache, REFRESH\n"); - - /* - * Refresh static ARP Cache entry. - */ - snprintf(entry, 34, "%15s %17s", - inet_ntoa(sarpi_cache_pos->sc_ip), - ether_ntoa(&(sarpi_cache_pos->sc_mac))); - entry[strlen(entry)] = '\0'; - - if (arp_cache_del(c_src_ip) < 0) { - exit(EXIT_FAILURE); - } - - if (arp_cache_add(entry) < 0) { - exit(EXIT_FAILURE); - } - - aprintf(stdout, 0, "\t src HW = <%s>\n", - ether_ntoa(&(sarpi_cache_pos->sc_mac))); - aprintf(stdout, 0, "\t src IP = <%s>\n", - inet_ntoa(sarpi_cache_pos->sc_ip)); - - return; - } - } - - /* - * Entry is not found in SARPI cache. - * This entry is not protected by SARPI! - * In request, possible source address poisoned. - * In reply, possible ARP Gratuitous for ARP poisoning. - */ - aprintf(stdout, 1, "ARP cache, IGNORE\n"); - aprintf(stdout, 0, "\t src HW = <%s>\n", c_src_mac); - aprintf(stdout, 0, "\t src IP = <%s>\n", c_src_ip); - } - } else if (ntohs(arp_packet->ah_header.ar_op) == ARP_OP_REPLY) { - /* - * Check if we are the destionation address. - */ - if (strcmp(c_dst_ip, inet_ntoa(dev.dev_inet4)) == 0 && - strcmp(c_dst_mac, ether_ntoa(&(dev.dev_mac))) == 0) { - /* - * Search ARP reply source in SARPI (ARP cache) entries. - */ - TAILQ_FOREACH(sarpi_cache_pos, &sarpi_cache_head, entries) { - /* - * Convert MAC/IPv4 to string form. - */ - memset(c_ap_ip, '\0', sizeof(char) * 16); - strncpy(c_ap_ip, inet_ntoa(sarpi_cache_pos->sc_ip), - sizeof(char) * 16); - c_ap_ip[sizeof(char) * strlen(c_ap_ip)] = '\0'; - - /* - * In reply, possible ARP Gratuitous for ARP poisoning. - * Check if source is found in SARPI Cache. - */ - if (strcmp(c_src_ip, c_ap_ip) == 0) { - /* - * Source is Found! We reset static entry. - */ - aprintf(stdout, 1, "ARP cache, REFRESH\n"); - - /* - * Refresh static ARP Cache entry. - */ - snprintf(entry, 34, "%15s %17s", - inet_ntoa(sarpi_cache_pos->sc_ip), - ether_ntoa(&(sarpi_cache_pos->sc_mac))); - entry[strlen(entry)] = '\0'; - - if (arp_cache_del(c_src_ip) < 0) { - exit(EXIT_FAILURE); - } - - if (arp_cache_add(entry) < 0) { - exit(EXIT_FAILURE); - } - - aprintf(stdout, 0, "\t src HW = <%s>\n", - ether_ntoa(&(sarpi_cache_pos->sc_mac))); - aprintf(stdout, 0, "\t src IP = <%s>\n", - inet_ntoa(sarpi_cache_pos->sc_ip)); - - return; - } - } - - /* - * Entry is not found in SARPI cache. - * This entry is not protected by SARPI! - * In request, possible source address poisoned. - * In reply, possible ARP Gratuitous for ARP poisoning. - */ - aprintf(stdout, 1, "ARP cache, IGNORE\n"); - aprintf(stdout, 0, "\t src HW = <%s>\n", c_src_mac); - aprintf(stdout, 0, "\t src IP = <%s>\n", c_src_ip); - } - /* - * Check if we are the source address. - */ - else if (strcmp(c_src_ip, inet_ntoa(dev.dev_inet4)) == 0 && - strcmp(c_src_mac, ether_ntoa(&(dev.dev_mac))) == 0) { - /* - * Search ARP request destination in SARPI (ARP cache) entries. - */ - TAILQ_FOREACH(sarpi_cache_pos, &sarpi_cache_head, entries) { - /* - * Convert MAC/IPv4 to string form. - */ - memset(c_ap_ip, '\0', sizeof(char) * 16); - strncpy(c_ap_ip, inet_ntoa(sarpi_cache_pos->sc_ip), - sizeof(char) * 16); - c_ap_ip[sizeof(char) * strlen(c_ap_ip)] = '\0'; - - /* - * In request, possible source address poisoned. - * Check if destination is found in SARPI Cache. - */ - if (strcmp(c_dst_ip, c_ap_ip) == 0) { - /* - * Source is Found! We reset static entry. - */ - aprintf(stdout, 1, "ARP cache, REFRESH\n"); - - /* - * Refresh static ARP Cache entry. - */ - snprintf(entry, 34, "%15s %17s", - inet_ntoa(sarpi_cache_pos->sc_ip), - ether_ntoa(&(sarpi_cache_pos->sc_mac))); - entry[strlen(entry)] = '\0'; - - if (arp_cache_del(c_dst_ip) < 0) { - exit(EXIT_FAILURE); - } - - if (arp_cache_add(entry) < 0) { - exit(EXIT_FAILURE); - } - - aprintf(stdout, 0, "\t src HW = <%s>\n", - ether_ntoa(&(sarpi_cache_pos->sc_mac))); - aprintf(stdout, 0, "\t src IP = <%s>\n", - inet_ntoa(sarpi_cache_pos->sc_ip)); - - return; - } - } - - /* - * Entry is not found in SARPI cache. - * This entry is not protected by SARPI! - * In request, possible source address poisoned. - * In reply, possible ARP Gratuitous for ARP poisoning. - */ - aprintf(stdout, 1, "ARP cache, IGNORE\n"); - aprintf(stdout, 0, "\t src HW = <%s>\n", c_dst_mac); - aprintf(stdout, 0, "\t src IP = <%s>\n", c_dst_ip); - } - } -} - -/* - * Sets static ARP cache entries from file. - * Parsing of example: - * - * # Example of sarpi.cache - * # - * 192.168.1.1 aa:bb:cc:dd:ee:ff - * ... - */ -static int -sarpi_cache_file_restore(void) -{ - struct addr aip, amac; - struct arp_entry entry; - char buf[100], ip[16], mac[18]; - FILE *fd; - int i; - - if ((fd = fopen(sarpi_cache_file, "r")) == NULL) { - aprintf(stderr, 0, "ERROR: Configure static " \ - "ARP Cache entries in %s!\n\n", sarpi_cache_file); - - return (-1); - } - - aprintf(stdout, 0, "\t CACHE = <%s>\n", sarpi_cache_file); - - for (i = 1; feof(fd) == 0; i++) { - if (fgets(buf, 100, fd) == NULL) { - break; - } - - /* - * Comment or new line. - */ - if (buf[0] == '#' || buf[0] == '\n') { - continue; - } - - /* - * Space line and Tab line with no entry. - */ - if (buf[0] == ' ' || buf[0] == '\t') { - if (buf[1] == '#' || buf[1] == '\n' || - buf[1] == ' ' || buf[1] == '\t') - continue; - } - - memset(ip, '\0', 16); - memset(mac, '\0', 18); - - sscanf(buf, "%15s %17s", ip, mac); - - if (addr_pton(ip, &aip) < 0) { - aprintf(stderr, 0, "ERROR: " - "It is not IPv4. Reconfigure %s:%d line!\n\n", - sarpi_cache_file, i); - fclose(fd); - - return (-1); - } else if (addr_pton(mac, &amac) < 0) { - aprintf(stderr, 0, "ERROR: " - "It is not Mac-hw. Reconfigure %s:%d line!\n\n", - sarpi_cache_file, i); - fclose(fd); - - return (-1); - } - - memcpy(&(entry.arp_pa), &aip, sizeof(aip)); - memcpy(&(entry.arp_ha), &amac, sizeof(amac)); - - if (sarpi_cache_list_create(&entry, NULL) < 0) { - fclose(fd); - - return (-1); - } - } - - fclose(fd); - return (0); -} - -/* - * Adds SARPI cache tail. - */ -static int -sarpi_cache_list_create(const struct arp_entry *entry, void *arg) -{ - struct ether_addr mac; - struct in_addr ip; - int i; - - for (i = 0; i < ETHER_ADDR_LEN; i++) { - mac.octet[i] = entry->arp_ha.addr_eth.data[i]; - } - - ip.s_addr = entry->arp_pa.addr_ip; - - pthread_rwlock_wrlock(&wlock); - - if (sarpi_cache_begin == NULL) { - TAILQ_INIT(&sarpi_cache_head); - - if ((sarpi_cache_begin = malloc(sizeof(struct arp_cache))) == NULL) { - ERROR(strerror(errno)); - - pthread_rwlock_unlock(&wlock); - - return (-1); - } - - memcpy(&sarpi_cache_begin->sc_mac, &mac, sizeof(mac)); - memcpy(&sarpi_cache_begin->sc_ip, &ip, sizeof(ip)); - TAILQ_INSERT_HEAD(&sarpi_cache_head, sarpi_cache_begin, entries); - - pthread_rwlock_unlock(&wlock); - - return (0); - } - - if ((sarpi_cache_next = malloc(sizeof(struct arp_cache))) == NULL) { - ERROR(strerror(errno)); - - pthread_rwlock_unlock(&wlock); - - return (-1); - } - - memcpy(&sarpi_cache_next->sc_mac, &mac, sizeof(mac)); - memcpy(&sarpi_cache_next->sc_ip, &ip, sizeof(ip)); - TAILQ_INSERT_TAIL(&sarpi_cache_head, sarpi_cache_next, entries); - - pthread_rwlock_unlock(&wlock); - - return (0); -} - -/* - * SARPI cache list signal handler. - */ -static void -sarpi_cache_list_refresh_thread_sigusr1(int sig) -{ - - pthread_exit((void *) 0); -} - -/* - * During every timeout it updates SARPI - * cache static entries in ARP cache. - */ -static void * -sarpi_cache_list_refresh_thread(void *arg) -{ - struct sigaction saction; - char entry[34]; -#ifdef NETBSD - int ret = 0; -#endif - -#ifdef NETBSD - saction.sa_flags = 0; -#endif - saction.sa_handler = sarpi_cache_list_refresh_thread_sigusr1; - - if (sigaction(SIGUSR1, &saction, NULL) < 0) { - ERROR(strerror(errno)); - - pthread_exit((void *) -1); - } - - for (;;) { - /* - * Sleep for thread suspend. - */ - - /* - * Convert by seconds to minuts. - */ -#ifdef NETBSD - if ((ret = sleep(sarpi_timeout * 60)) > 0) { -#else - if (sleep(sarpi_timeout * 60) > 0) { -#endif - ERROR(strerror(errno)); - - pthread_exit((void *) -1); - } - -#ifdef NETBSD - /* - * For SIGINT, SIGTERM, SIGQUIT, - * It exited. - */ - - if (ret != 0) { - pthread_exit((void *) -1); - } -#endif - - aprintf(stdout, 1, "ARP cache, UPDATE\n"); - - pthread_rwlock_rdlock(&rlock); - pthread_rwlock_wrlock(&wlock); - - TAILQ_FOREACH(sarpi_cache_pos, &sarpi_cache_head, entries) { - /* - * Refresh ARP Cache entries. - */ - - snprintf(entry, 34, "%15s %17s", - inet_ntoa(sarpi_cache_pos->sc_ip), - ether_ntoa(&(sarpi_cache_pos->sc_mac))); - entry[strlen(entry)] = '\0'; - - if (arp_cache_del(inet_ntoa(sarpi_cache_pos->sc_ip)) < 0) { - pthread_rwlock_unlock(&wlock); - pthread_rwlock_unlock(&rlock); - - pthread_exit((void *) -1); - } - - if (arp_cache_add(entry) < 0) { - pthread_rwlock_unlock(&wlock); - pthread_rwlock_unlock(&rlock); - - pthread_exit((void *) -1); - } - - aprintf(stdout, 0, "\t src HW = <%s>\n", - ether_ntoa(&(sarpi_cache_pos->sc_mac))); - aprintf(stdout, 0, "\t src IP = <%s>\n", - inet_ntoa(sarpi_cache_pos->sc_ip)); - } - - pthread_rwlock_unlock(&wlock); - pthread_rwlock_unlock(&rlock); - } - - pthread_exit((void *) 0); -} - -/* - * Destroy SARPI cache tail. - */ -static void -sarpi_cache_list_destroy(void) -{ - - pthread_rwlock_rdlock(&rlock); - - while (TAILQ_EMPTY(&sarpi_cache_head) == 0) { - pthread_rwlock_wrlock(&wlock); - - sarpi_cache_pos = TAILQ_FIRST(&sarpi_cache_head); - - TAILQ_REMOVE(&sarpi_cache_head, sarpi_cache_pos, entries); - free(sarpi_cache_pos); - - pthread_rwlock_unlock(&wlock); - } - - pthread_rwlock_unlock(&rlock); -} - -/****************** - * DARPI handler: * - ******************/ - -/* - * Set DARPI Cache entry timeout. - */ -static int -darpi_set_timeout(char *timeout) -{ - int val = atoi(timeout); - - /* - * Don't accept timeout < 0. - */ - if (val < 0) { - aprintf(stderr, 0, - "ERROR: DARPI timeout %d seconds out of the range.\n\n", val); - - return (-1); - } - - darpi_timeout = val; - - return (0); -} - -/* - * DARPI manager signal handler. - */ -static void -darpi_manager_thread_sigusr1(int sig) -{ - - darpi_cache1_list_destroy(); - darpi_cache2_list_destroy(); - darpi_cache3_list_destroy(); - pthread_exit((void *) 0); -} - -/* - * Handles DARPI, delete all found entries - * in the ARP cache to delete some poisoned - * hosts then it starts realtime execution - * to reads the packets: - * - ARP request - * - ARP reply. - */ -static void * -darpi_manager_thread(void *arg) -{ - struct sigaction saction; - -#ifdef NETBSD - saction.sa_flags = 0; -#endif - saction.sa_handler = darpi_manager_thread_sigusr1; - - if (sigaction(SIGUSR1, &saction, NULL) < 0) { - ERROR(strerror(errno)); - - pthread_exit((void *) -1); - } - - /* - * Iface work. - */ - if (iface_manager() < 0) { - pthread_exit((void *) -1); - } - - if (iface_check_uplink() < 0) { - pthread_exit((void *) -1); - } - - iface_info_print(); - - /* - * PID CPU Scheduling. - */ - if (task_mode_cpu_priority(PRIO_PROCESS, getpid(), cpu_priority) < 0) { - pthread_exit((void *) -1); - } - - /* - * Delete all ARP Cache entries (Possible entries poisoned). - */ - if (arp_cache_del_all() < 0) { - pthread_exit((void *) -1); - } - - /* - * Thread 4 detached, inbound/outbound work. - */ - if (darpi_realtime() < 0) { - pthread_exit((void *) -1); - } - - pthread_exit((void *) 0); -} - -/* - * DARPI Realtime execution, process all - * inbound/outbound ARP packets. - */ -static int -darpi_realtime(void) -{ - - pthread_attr_init(&detach_attr); - pthread_attr_setdetachstate(&detach_attr, PTHREAD_CREATE_DETACHED); - pthread_attr_setschedpolicy(&detach_attr, SCHED_RR); - - /* - * Thread 4 detached, realtime inbound/outbound work. - */ - if (pthread_create(&thread[3], &detach_attr, darpi_realtime_thread, - (void *) NULL) != 0) { - ERROR(strerror(errno)); - - return (-1); - } - - pthread_attr_destroy(&detach_attr); - - pthread_attr_init(&detach_attr); - pthread_attr_setdetachstate(&detach_attr, PTHREAD_CREATE_DETACHED); - pthread_attr_setschedpolicy(&detach_attr, SCHED_RR); - - /* - * Thread 5 detached, Check each DARPI Cache 1 entry with - * timeout, possible host doesn't present in the network. - */ - pthread_create(&thread[4], &detach_attr, - darpi_cache1_list_check_thread, (void *) NULL); - - /* - * Thread 6 detached, Check each DARPI Cache 2 entry with - * timeout, possible host doesn't present in the network. - */ - pthread_create(&thread[5], &detach_attr, - darpi_cache2_list_check_thread, (void *) NULL); - - /* - * Thread 7 detached, Check each DARPI Cache 3 entry with - * timeout, possible host doesn't present in the network. - */ - pthread_create(&thread[6], &detach_attr, - darpi_cache3_list_check_thread, (void *) NULL); - - pthread_attr_destroy(&detach_attr); - - darpi_cache1_list_destroy(); - darpi_cache2_list_destroy(); - darpi_cache3_list_destroy(); - - return (0); -} - -/* - * DARPI realtime signal handler. - */ -static void -darpi_realtime_thread_sigusr1(int sig) -{ - - pthread_exit((void *) 0); -} - -/* - * Use thread for non blocking to pcap_loop(). - */ -static void * -darpi_realtime_thread(void *arg) -{ - struct sigaction saction; - pcap_t *pcap; - -#ifdef NETBSD - saction.sa_flags = 0; -#endif - saction.sa_handler = darpi_realtime_thread_sigusr1; - - if (sigaction(SIGUSR1, &saction, NULL) < 0) { - ERROR(strerror(errno)); - - pthread_exit((void *) -1); - } - - if ((pcap = darpi_realtime_open_packets()) == NULL) { - pthread_exit((void *) -1); - } - - pthread_rwlock_init(&rlock2, NULL); - pthread_rwlock_init(&wlock2, NULL); - pthread_rwlock_init(&rlock3, NULL); - pthread_rwlock_init(&wlock3, NULL); - pthread_rwlock_init(&rlock4, NULL); - pthread_rwlock_init(&wlock4, NULL); - - while (1) { - if (pcap_loop(pcap, 1, darpi_realtime_read_packets, NULL) < 0) { - ERROR(pcap_geterr(pcap)); - - pthread_rwlock_destroy(&wlock2); - pthread_rwlock_destroy(&rlock2); - pthread_rwlock_destroy(&wlock3); - pthread_rwlock_destroy(&rlock3); - pthread_rwlock_destroy(&wlock4); - pthread_rwlock_destroy(&rlock4); - darpi_realtime_close_packets(pcap); - - pthread_exit((void *) -1); - } - } - - pthread_rwlock_destroy(&wlock2); - pthread_rwlock_destroy(&rlock2); - pthread_rwlock_destroy(&wlock3); - pthread_rwlock_destroy(&rlock3); - pthread_rwlock_destroy(&wlock4); - pthread_rwlock_destroy(&rlock4); - darpi_realtime_close_packets(pcap); - - pthread_exit((void *) 0); -} - -/* - * Open pcap file descriptor. - */ -static pcap_t * -darpi_realtime_open_packets(void) -{ - struct bpf_program compiled_filter; - char errbuf[PCAP_ERRBUF_SIZE], *filter = "arp"; - pcap_t *pcap; -#ifndef LINUX - unsigned int op = 1; -#endif - - if ((pcap = pcap_open_live(dev.dev, BUFSIZ, 0, 0, errbuf)) == NULL) { - ERROR(errbuf); - - return (NULL); - } - -#ifndef LINUX - /* - * BSD, differently from linux does not - * support automatic socket soft real time - * (Linux Socket Filter). - * Therefore on BSD platform it's necessary - * to use this I/O Control. - */ - if (ioctl(pcap_fileno(pcap), BIOCIMMEDIATE, &op) < 0) { - ERROR(strerror(errno)); - - return (NULL); - } -#endif - - if (pcap_compile(pcap, &compiled_filter, filter, 0, - dev.dev_netmask.s_addr) < 0) { - ERROR(pcap_geterr(pcap)); - darpi_realtime_close_packets(pcap); - - return (NULL); - } - - if (pcap_setfilter(pcap, &compiled_filter) < 0) { - ERROR(pcap_geterr(pcap)); - darpi_realtime_close_packets(pcap); - - return (NULL); - } - - pcap_freecode(&compiled_filter); - return (pcap); -} - -/* - * Close pcap file descriptor. - */ -static void -darpi_realtime_close_packets(pcap_t *pcap) -{ - - pcap_close(pcap); -} - -/* - * DARPI I/O - * Read doc/DARPI.jpg algorithm. - */ -static void -darpi_realtime_read_packets(unsigned char *arg, const struct pcap_pkthdr - *header, const unsigned char *packet) -{ - struct ether_addr src_mac, dst_mac; - struct in_addr src_ip, dst_ip; - struct arp_header *arp_packet; - char c_src_ip[16], c_src_mac[18], c_dst_ip[16], c_dst_mac[18], entry[34]; - int i, ret = 0; - - /* - * ARP Packet. - */ - arp_packet = (struct arp_header *) (packet + dev.dev_offset); - - /* - * Convert source MAC/IPv4 string. - */ - snprintf(c_src_ip, 16, "%d.%d.%d.%d", - arp_packet->ah_addresses.ar_spa[0], - arp_packet->ah_addresses.ar_spa[1], - arp_packet->ah_addresses.ar_spa[2], - arp_packet->ah_addresses.ar_spa[3]); - inet_aton(c_src_ip, &src_ip); - - for (i = 0; i < ETHER_ADDR_LEN; i++) { - src_mac.octet[i] = arp_packet->ah_addresses.ar_sha[i]; - } - strncpy(c_src_mac, ether_ntoa(&src_mac), sizeof(char) * 18); - c_src_mac[sizeof(char) * strlen(c_src_mac)] = '\0'; - - /* - * Convert destination MAC/IPv4 string. - */ - snprintf(c_dst_ip, 16, "%d.%d.%d.%d", - arp_packet->ah_addresses.ar_tpa[0], - arp_packet->ah_addresses.ar_tpa[1], - arp_packet->ah_addresses.ar_tpa[2], - arp_packet->ah_addresses.ar_tpa[3]); - inet_aton(c_dst_ip, &dst_ip); - - for (i = 0; i < ETHER_ADDR_LEN; i++) { - dst_mac.octet[i] = arp_packet->ah_addresses.ar_tha[i]; - } - strncpy(c_dst_mac, ether_ntoa(&dst_mac), sizeof(char) * 18); - c_dst_mac[sizeof(char) * strlen(c_dst_mac)] = '\0'; - - if (ntohs(arp_packet->ah_header.ar_op) == ARP_OP_REQUEST) { - /* - * Check if it is a broadcast address. - */ - if (strcmp(c_src_ip, inet_ntoa(dev.dev_inet4)) != 0 && - strcmp(c_dst_ip, inet_ntoa(dev.dev_inet4)) != 0 && - strcmp(c_src_ip, c_dst_ip) == 0) { - if (darpi_realtime_send_packet(&src_ip) < 0) { - exit(EXIT_FAILURE); - } - - if ((ret = arp_cache_del(c_src_ip)) < 0) { - exit(EXIT_FAILURE); - } else if (ret == 0) { - aprintf(stdout, 1, "ARP cache, DENY\n"); - aprintf(stdout, 0, "\t src HW = <%s>\n", c_src_mac); - aprintf(stdout, 0, "\t src IP = <%s>\n", c_src_ip); - } - } - /* - * Check if we are the source address. - */ - else if (strcmp(c_src_mac, ether_ntoa(&(dev.dev_mac))) == 0 && - strcmp(c_src_ip, inet_ntoa(dev.dev_inet4)) == 0) { - - /* - * DARPI 1 Cache Add/Refresh. - */ - if (darpi_cache1_list_create(&dst_ip) < 0) { - exit(EXIT_FAILURE); - } - - /* - * Check in DARPI 3 Cache if this outbound request - * derives by an inbound request. - */ - TAILQ_FOREACH(darpi_cache3_pos, &darpi_cache3_head, entries) { - if (strcmp(inet_ntoa(darpi_cache3_pos->dc_ip), c_dst_ip) == 0) { - /* - * Entry found in DARPI 3 cache! - */ - TAILQ_REMOVE(&darpi_cache3_head, darpi_cache3_pos, entries); - free(darpi_cache3_pos); - - return; - } - } - - /* - * Entry not found in DARPI 3 cache! - * DARPI 2 Cache Add/Refresh. - */ - if (darpi_cache2_list_create(&dst_ip) < 0) { - exit(EXIT_FAILURE); - } - } - /* - * Check if we are the destination address. - */ - else if (strcmp(c_dst_ip, inet_ntoa(dev.dev_inet4)) == 0) { - /* - * Possible ARP Gratuitous for ARP Poisoning. - * Search entry in DARPI 2 cache, if it matches it - * is to inserted in ARP cache, else if it doesn't - * exist, it is to deleted from ARP cache. - */ - TAILQ_FOREACH(darpi_cache2_pos, &darpi_cache2_head, entries) { - if (strcmp(inet_ntoa(darpi_cache2_pos->dc_ip), c_src_ip) == 0) { - /* - * Entry found in DARPI 2 cache! - */ - TAILQ_REMOVE(&darpi_cache2_head, darpi_cache2_pos, entries); - free(darpi_cache2_pos); - - return; - } - } - - /* - * Entry not found in DARPI 2 cache! - */ - if (darpi_realtime_send_packet(&src_ip) < 0) { - exit(EXIT_FAILURE); - } - - /* - * DARPI 3 Cache Add/Refresh. - */ - if (darpi_cache3_list_create(&src_ip) < 0) { - exit(EXIT_FAILURE); - } - } - } else if (ntohs(arp_packet->ah_header.ar_op) == ARP_OP_REPLY) { - /* - * Check if we are the destination address. - */ - if (strcmp(c_dst_mac, ether_ntoa(&(dev.dev_mac))) == 0 && - strcmp(c_dst_ip, inet_ntoa(dev.dev_inet4)) == 0) { - /* - * Possible ARP Gratuitous for ARP Poisoning. - * Search entry in DARPI 1 cache, if it matches it - * is to inserted in ARP cache, else if it doesn't - * exist, it is to deleted from ARP cache. - */ - TAILQ_FOREACH(darpi_cache1_pos, &darpi_cache1_head, entries) { - if (strcmp(inet_ntoa(darpi_cache1_pos->dc_ip), c_src_ip) == 0) { - /* - * Entry found in DARPI 1 cache! - */ - TAILQ_REMOVE(&darpi_cache1_head, darpi_cache1_pos, entries); - free(darpi_cache1_pos); - - memset(entry, '\0', 34); - snprintf(entry, 34, "%15s %17s", c_src_ip, c_src_mac); - entry[strlen(entry)] = '\0'; - - if (arp_cache_del(c_src_ip) < 0) { - exit(EXIT_FAILURE); - } - - if (arp_cache_add(entry) < 0) { - exit(EXIT_FAILURE); - } - - aprintf(stdout, 1, "ARP cache, ACCEPT\n"); - aprintf(stdout, 0, "\t src HW = <%s>\n", c_src_mac); - aprintf(stdout, 0, "\t src IP = <%s>\n", c_src_ip); - - return; - } - } - - /* - * Entry not found in DARPI 1 cache! - */ - if (darpi_realtime_send_packet(&src_ip) < 0) { - exit(EXIT_FAILURE); - } - - if ((ret = arp_cache_del(c_src_ip)) < 0) { - exit(EXIT_FAILURE); - } else if (ret == 0) { - aprintf(stdout, 1, "ARP cache, DENY\n"); - aprintf(stdout, 0, "\t src HW = <%s>\n", c_src_mac); - aprintf(stdout, 0, "\t src IP = <%s>\n", c_src_ip); - } - } - } -} - -/* - * DARPI Send ARP request Outbound - * Read doc/DARPI.jpg algorithm. - */ -static int -darpi_realtime_send_packet(struct in_addr *dst_ip) -{ - struct ether_addr *dst_mac; - char errbuf[LIBNET_ERRBUF_SIZE]; - libnet_t *lnet; - - if ((lnet = libnet_init(LIBNET_LINK, dev.dev, errbuf)) == NULL) { - ERROR(errbuf); - return (-1); - } - - dst_mac = ether_aton("ff:ff:ff:ff:ff:ff"); - - if (libnet_autobuild_arp(ARPOP_REQUEST, - (u_int8_t *) &(dev.dev_mac), /* Source Mac */ - (u_int8_t *) &(dev.dev_inet4), /* Source IP */ - (u_int8_t *) dst_mac, /* Destination Mac */ - (u_int8_t *) dst_ip, /* Destination IP */ - lnet ) < 0) { - ERROR(libnet_geterror(lnet)); - libnet_destroy(lnet); - return (-1); - } - - if (libnet_autobuild_ethernet((u_int8_t *) dst_mac, - ETHERTYPE_ARP, lnet) < 0) { - ERROR(libnet_geterror(lnet)); - libnet_destroy(lnet); - return (-1); - } - - /* Sends (Ethernet + Arp) Packet */ - if (libnet_write(lnet) < 0) { - ERROR(libnet_geterror(lnet)); - libnet_destroy(lnet); - return (-1); - } - - libnet_destroy(lnet); - return (0); -} - -/* - * Create or adds DARPI cache 1 tail. - */ -static int -darpi_cache1_list_create(struct in_addr *entry) -{ - struct in_addr ip; - - ip.s_addr = entry->s_addr; - - pthread_rwlock_wrlock(&wlock2); - - if (darpi_cache1_begin == NULL) { - TAILQ_INIT(&darpi_cache1_head); - - if ((darpi_cache1_begin = malloc( - sizeof(struct darpi_cache1))) == NULL) { - ERROR(strerror(errno)); - pthread_rwlock_unlock(&wlock2); - - return (-1); - } - - memcpy(&darpi_cache1_begin->dc_ip, &ip, sizeof(ip)); - darpi_cache1_begin->tm_entry = time(NULL); - TAILQ_INSERT_HEAD(&darpi_cache1_head, darpi_cache1_begin, entries); - - pthread_rwlock_unlock(&wlock2); - - return (0); - } - - if ((darpi_cache1_next = malloc(sizeof(struct darpi_cache1))) == NULL) { - ERROR(strerror(errno)); - pthread_rwlock_unlock(&wlock2); - - return (-1); - } - - memcpy(&darpi_cache1_next->dc_ip, &ip, sizeof(ip)); - darpi_cache1_next->tm_entry = time(NULL); - TAILQ_INSERT_TAIL(&darpi_cache1_head, darpi_cache1_next, entries); - - pthread_rwlock_unlock(&wlock2); - - return (0); -} - -/* - * DARPI cache 1 list signal handler. - */ -static void -darpi_cache1_list_check_thread_sigusr1(int sig) -{ - - pthread_exit((void *) 0); -} - -/* - * DARPI Cache 1 entry timeout. - * When DARPI reads ARP Request Outbound, it writes an - * entry in DARPI Cache, if this entry replies with ARP - * Reply Inbound it's ok, else if it doesn't replies, - * it probably doesn't exist. This timeout in this case, - * delete this entry from DARPI Cache. - */ -static void * -darpi_cache1_list_check_thread(void *arg) -{ - struct sigaction saction; - time_t tm_entry; - int diff_time_entry = 0; - -#ifdef NETBSD - saction.sa_flags = 0; -#endif - saction.sa_handler = darpi_cache1_list_check_thread_sigusr1; - - if (sigaction(SIGUSR1, &saction, NULL) < 0) { - ERROR(strerror(errno)); - - pthread_exit((void *) -1); - } - - while (1) { - /* - * Each 1 second, it check diff time of each entry. - */ - if (sleep(1) > 0) { - ERROR(strerror(errno)); - - pthread_exit((void *) -1); - } - - tm_entry = time(NULL); - - pthread_rwlock_rdlock(&rlock2); - pthread_rwlock_wrlock(&wlock2); - - TAILQ_FOREACH(darpi_cache1_pos, &darpi_cache1_head, entries) { - diff_time_entry = difftime(tm_entry, darpi_cache1_pos->tm_entry); - - if (diff_time_entry >= darpi_timeout) { - TAILQ_REMOVE(&darpi_cache1_head, darpi_cache1_pos, entries); - free(darpi_cache1_pos); - - diff_time_entry = 0; - break; - } - - diff_time_entry = 0; - } - - pthread_rwlock_unlock(&wlock2); - pthread_rwlock_unlock(&rlock2); - } - - pthread_exit((void *) 0); -} - -/* - * Destroy DARPI cache 1 tail. - */ -static void -darpi_cache1_list_destroy(void) -{ - - pthread_rwlock_rdlock(&rlock2); - - while (TAILQ_EMPTY(&darpi_cache1_head) == 0) { - pthread_rwlock_wrlock(&wlock2); - - darpi_cache1_pos = TAILQ_FIRST(&darpi_cache1_head); - - TAILQ_REMOVE(&darpi_cache1_head, darpi_cache1_pos, entries); - free(darpi_cache1_pos); - - pthread_rwlock_unlock(&wlock2); - } - - pthread_rwlock_unlock(&rlock2); -} - -/* - * Create or adds DARPI cache 2 tail. - */ -static int -darpi_cache2_list_create(struct in_addr *entry) -{ - struct in_addr ip; - - ip.s_addr = entry->s_addr; - - pthread_rwlock_wrlock(&wlock3); - - if (darpi_cache2_begin == NULL) { - TAILQ_INIT(&darpi_cache2_head); - - if ((darpi_cache2_begin = malloc( - sizeof(struct darpi_cache2))) == NULL) { - ERROR(strerror(errno)); - pthread_rwlock_unlock(&wlock3); - - return (-1); - } - - memcpy(&darpi_cache2_begin->dc_ip, &ip, sizeof(ip)); - darpi_cache2_begin->tm_entry = time(NULL); - TAILQ_INSERT_HEAD(&darpi_cache2_head, darpi_cache2_begin, entries); - - pthread_rwlock_unlock(&wlock3); - - return (0); - } - - if ((darpi_cache2_next = malloc(sizeof(struct darpi_cache2))) == NULL) { - ERROR(strerror(errno)); - pthread_rwlock_unlock(&wlock3); - - return (-1); - } - - memcpy(&darpi_cache2_next->dc_ip, &ip, sizeof(ip)); - darpi_cache2_next->tm_entry = time(NULL); - TAILQ_INSERT_TAIL(&darpi_cache2_head, darpi_cache2_next, entries); - - pthread_rwlock_unlock(&wlock3); - - return (0); -} - -/* - * DARPI cache 2 list signal handler. - */ -static void -darpi_cache2_list_check_thread_sigusr1(int sig) -{ - - pthread_exit((void *) 0); -} - -/* - * DARPI Cache 2 entry timeout. - * When DARPI reads ARP Request Outbound, it writes an - * entry in DARPI Cache, if this entry replies with ARP - * Reply Inbound it's ok, else if it doesn't replies, - * it probably doesn't exist. This timeout in this case, - * delete this entry from DARPI Cache. - */ -static void * -darpi_cache2_list_check_thread(void *arg) -{ - struct sigaction saction; - time_t tm_entry; - int diff_time_entry = 0; - -#ifdef NETBSD - saction.sa_flags = 0; -#endif - saction.sa_handler = darpi_cache2_list_check_thread_sigusr1; - - if (sigaction(SIGUSR1, &saction, NULL) < 0) { - ERROR(strerror(errno)); - - pthread_exit((void *) -1); - } - - while (1) { - /* - * Each 1 second, it check diff time of each entry. - */ - if (sleep(1) > 0) { - ERROR(strerror(errno)); - - pthread_exit((void *) -1); - } - - tm_entry = time(NULL); - - pthread_rwlock_rdlock(&rlock3); - pthread_rwlock_wrlock(&wlock3); - - TAILQ_FOREACH(darpi_cache2_pos, &darpi_cache2_head, entries) { - diff_time_entry = difftime(tm_entry, darpi_cache2_pos->tm_entry); - - if (diff_time_entry >= darpi_timeout) { - TAILQ_REMOVE(&darpi_cache2_head, darpi_cache2_pos, entries); - free(darpi_cache2_pos); - - diff_time_entry = 0; - break; - } - - diff_time_entry = 0; - } - - pthread_rwlock_unlock(&wlock3); - pthread_rwlock_unlock(&rlock3); - } - - pthread_exit((void *) 0); -} - -/* - * Destroy DARPI 2 cache tail. - */ -static void -darpi_cache2_list_destroy(void) -{ - - pthread_rwlock_rdlock(&rlock3); - - while (TAILQ_EMPTY(&darpi_cache2_head) == 0) { - pthread_rwlock_wrlock(&wlock3); - - darpi_cache2_pos = TAILQ_FIRST(&darpi_cache2_head); - - TAILQ_REMOVE(&darpi_cache2_head, darpi_cache2_pos, entries); - free(darpi_cache2_pos); - - pthread_rwlock_unlock(&wlock3); - } - - pthread_rwlock_unlock(&rlock3); -} - -/* - * Create or adds DARPI cache 3 tail. - */ -static int -darpi_cache3_list_create(struct in_addr *entry) -{ - struct in_addr ip; - - ip.s_addr = entry->s_addr; - - pthread_rwlock_wrlock(&wlock4); - - if (darpi_cache3_begin == NULL) { - TAILQ_INIT(&darpi_cache3_head); - - if ((darpi_cache3_begin = malloc( - sizeof(struct darpi_cache3))) == NULL) { - ERROR(strerror(errno)); - pthread_rwlock_unlock(&wlock4); - - return (-1); - } - - memcpy(&darpi_cache3_begin->dc_ip, &ip, sizeof(ip)); - darpi_cache3_begin->tm_entry = time(NULL); - TAILQ_INSERT_HEAD(&darpi_cache3_head, darpi_cache3_begin, entries); - - pthread_rwlock_unlock(&wlock4); - - return (0); - } - - if ((darpi_cache3_next = malloc(sizeof(struct darpi_cache3))) == NULL) { - ERROR(strerror(errno)); - pthread_rwlock_unlock(&wlock4); - - return (-1); - } - - memcpy(&darpi_cache3_next->dc_ip, &ip, sizeof(ip)); - darpi_cache3_next->tm_entry = time(NULL); - TAILQ_INSERT_TAIL(&darpi_cache3_head, darpi_cache3_next, entries); - - pthread_rwlock_unlock(&wlock4); - - return (0); -} - -/* - * DARPI cache 3 list signal handler. - */ -static void -darpi_cache3_list_check_thread_sigusr1(int sig) -{ - - pthread_exit((void *) 0); -} - -/* - * DARPI Cache 3 entry timeout. - * When DARPI reads ARP Request Outbound, it writes an - * entry in DARPI Cache, if this entry replies with ARP - * Reply Inbound it's ok, else if it doesn't replies, - * it probably doesn't exist. This timeout in this case, - * delete this entry from DARPI Cache. - */ -static void * -darpi_cache3_list_check_thread(void *arg) -{ - struct sigaction saction; - time_t tm_entry; - int diff_time_entry = 0; - -#ifdef NETBSD - saction.sa_flags = 0; -#endif - saction.sa_handler = darpi_cache3_list_check_thread_sigusr1; - - if (sigaction(SIGUSR1, &saction, NULL) < 0) { - ERROR(strerror(errno)); - - pthread_exit((void *) -1); - } - - while (1) { - /* - * Each 1 second, it check diff time of each entry. - */ - if (sleep(1) > 0) { - ERROR(strerror(errno)); - - pthread_exit((void *) -1); - } - - tm_entry = time(NULL); - - pthread_rwlock_rdlock(&rlock4); - pthread_rwlock_wrlock(&wlock4); - - TAILQ_FOREACH(darpi_cache3_pos, &darpi_cache3_head, entries) { - diff_time_entry = difftime(tm_entry, darpi_cache3_pos->tm_entry); - - if (diff_time_entry >= darpi_timeout) { - TAILQ_REMOVE(&darpi_cache3_head, darpi_cache3_pos, entries); - free(darpi_cache3_pos); - - diff_time_entry = 0; - break; - } - - diff_time_entry = 0; - } - - pthread_rwlock_unlock(&wlock4); - pthread_rwlock_unlock(&rlock4); - } - - pthread_exit((void *) 0); -} - -/* - * Destroy DARPI 3 cache tail. - */ -static void -darpi_cache3_list_destroy(void) -{ - - pthread_rwlock_rdlock(&rlock4); - - while (TAILQ_EMPTY(&darpi_cache3_head) == 0) { - pthread_rwlock_wrlock(&wlock4); - - darpi_cache3_pos = TAILQ_FIRST(&darpi_cache3_head); - - TAILQ_REMOVE(&darpi_cache3_head, darpi_cache3_pos, entries); - free(darpi_cache3_pos); - - pthread_rwlock_unlock(&wlock4); - } - - pthread_rwlock_unlock(&rlock4); -} - -/****************** - * HARPI handler: * - ******************/ - -/* - * HARPI manager signal handler. - */ -static void -harpi_manager_thread_sigusr1(int sig) -{ - - sarpi_cache_list_destroy(); - darpi_cache1_list_destroy(); - darpi_cache2_list_destroy(); - darpi_cache3_list_destroy(); - pthread_exit((void *) 0); -} - -/* - * Handles HARPI: - * - * Working to parallel: - * - * 1) DARPI delete all found entries - * in the ARP cache to delete some poisoned - * hosts then it starts realtime execution - * to reads the packets: - * - ARP Request - * - ARP Reply - * - * 2) SARPI through two thread for parallelism: - * - 1: Update automatically the ARP cache - * - 2: Works in soft real time, in other words it - * listens to the inbound/outbound arp packets. - */ -static void * -harpi_manager_thread(void *arg) -{ - struct sigaction saction; - -#ifdef NETBSD - saction.sa_flags = 0; -#endif - saction.sa_handler = harpi_manager_thread_sigusr1; - - if (sigaction(SIGUSR1, &saction, NULL) < 0) { - ERROR(strerror(errno)); - - pthread_exit((void *) -1); - } - - /* - * Iface work. - */ - if (iface_manager() < 0) { - pthread_exit((void *) -1); - } - - if (iface_check_uplink() < 0) { - pthread_exit((void *) -1); - } - - iface_info_print(); - - /* - * PID CPU Scheduling. - */ - if (task_mode_cpu_priority(PRIO_PROCESS, getpid(), cpu_priority) < 0) { - pthread_exit((void *) -1); - } - - /* - * Delete all ARP Cache entries (Possible entries poisoned). - */ - if (arp_cache_del_all() < 0) { - pthread_exit((void *) -1); - } - - pthread_rwlock_init(&rlock, NULL); - pthread_rwlock_init(&wlock, NULL); - - /* - * ARP Cache entries protected from file. - */ - if (sarpi_cache_file_restore() < 0) { - exit(-1); - } - - pthread_attr_init(&detach_attr); - pthread_attr_setdetachstate(&detach_attr, PTHREAD_CREATE_DETACHED); - pthread_attr_setschedpolicy(&detach_attr, SCHED_RR); - - /* - * Thread 4 detached, update automatically the ARP cache. - */ - if (pthread_create(&thread[3], &detach_attr, - sarpi_cache_list_refresh_thread, (void *) NULL) != 0) { - ERROR(strerror(errno)); - sarpi_cache_list_destroy(); - - pthread_exit((void *) -1); - } - - /* - * Thread 5 detached, inbound/outbound work. - */ - if (harpi_realtime() < 0) { - pthread_exit((void *) -1); - } - - pthread_exit((void *) 0); -} - -/* - * HARPI Realtime execution, process all - * inbound/outbound ARP packets. - */ -static int -harpi_realtime(void) -{ - - pthread_attr_init(&detach_attr); - pthread_attr_setdetachstate(&detach_attr, PTHREAD_CREATE_DETACHED); - pthread_attr_setschedpolicy(&detach_attr, SCHED_RR); - - /* - * Thread 5 detached, realtime inbound/outbound work. - */ - if (pthread_create(&thread[4], &detach_attr, harpi_realtime_thread, - (void *) NULL) != 0) { - ERROR(strerror(errno)); - - return (-1); - } - - pthread_attr_destroy(&detach_attr); - - pthread_attr_init(&detach_attr); - pthread_attr_setdetachstate(&detach_attr, PTHREAD_CREATE_DETACHED); - pthread_attr_setschedpolicy(&detach_attr, SCHED_RR); - - /* - * Thread 6 detached, Check each DARPI Cache 1 entry with - * timeout, possible host doesn't present in the network. - */ - pthread_create(&thread[5], &detach_attr, - darpi_cache1_list_check_thread, (void *) NULL); - - /* - * Thread 7 detached, Check each DARPI Cache 2 entry with - * timeout, possible host doesn't present in the network. - */ - pthread_create(&thread[6], &detach_attr, - darpi_cache2_list_check_thread, (void *) NULL); - - /* - * Thread 8 detached, Check each DARPI Cache 3 entry with - * timeout, possible host doesn't present in the network. - */ - pthread_create(&thread[7], &detach_attr, - darpi_cache3_list_check_thread, (void *) NULL); - - pthread_attr_destroy(&detach_attr); - - darpi_cache1_list_destroy(); - darpi_cache2_list_destroy(); - darpi_cache3_list_destroy(); - - return (0); -} - -/* - * HARPI realtime signal handler. - */ -static void -harpi_realtime_thread_sigusr1(int sig) -{ - - pthread_exit((void *) 0); -} - -/* - * Use thread for non blocking to pcap_loop(). - */ -static void * -harpi_realtime_thread(void *arg) -{ - struct sigaction saction; - pcap_t *pcap; - -#ifdef NETBSD - saction.sa_flags = 0; -#endif - saction.sa_handler = harpi_realtime_thread_sigusr1; - - if (sigaction(SIGUSR1, &saction, NULL) < 0) { - ERROR(strerror(errno)); - - pthread_exit((void *) -1); - } - - if ((pcap = harpi_realtime_open_packets()) == NULL) { - pthread_exit((void *) -1); - } - - pthread_rwlock_init(&rlock2, NULL); - pthread_rwlock_init(&wlock2, NULL); - pthread_rwlock_init(&rlock3, NULL); - pthread_rwlock_init(&wlock3, NULL); - pthread_rwlock_init(&rlock4, NULL); - pthread_rwlock_init(&wlock4, NULL); - - while (1) { - if (pcap_loop(pcap, 1, harpi_realtime_read_packets, NULL) < 0) { - ERROR(pcap_geterr(pcap)); - - pthread_rwlock_destroy(&wlock2); - pthread_rwlock_destroy(&rlock2); - pthread_rwlock_destroy(&wlock3); - pthread_rwlock_destroy(&rlock3); - pthread_rwlock_destroy(&wlock4); - pthread_rwlock_destroy(&rlock4); - harpi_realtime_close_packets(pcap); - - pthread_exit((void *) -1); - } - } - - pthread_rwlock_destroy(&wlock2); - pthread_rwlock_destroy(&rlock2); - pthread_rwlock_destroy(&wlock3); - pthread_rwlock_destroy(&rlock3); - pthread_rwlock_destroy(&wlock4); - pthread_rwlock_destroy(&rlock4); - harpi_realtime_close_packets(pcap); - - pthread_exit((void *) 0); -} - -/* - * Open pcap file descriptor. - */ -static pcap_t * -harpi_realtime_open_packets(void) -{ - struct bpf_program compiled_filter; - char errbuf[PCAP_ERRBUF_SIZE], *filter = "arp"; - pcap_t *pcap; -#ifndef LINUX - unsigned int op = 1; -#endif - - if ((pcap = pcap_open_live(dev.dev, BUFSIZ, 0, 0, errbuf)) == NULL) { - ERROR(errbuf); - - return (NULL); - } - -#ifndef LINUX - /* - * BSD, differently from linux does not - * support automatic socket soft real time - * (Linux Socket Filter). - * Therefore on BSD platform it's necessary - * to use this I/O Control. - */ - if (ioctl(pcap_fileno(pcap), BIOCIMMEDIATE, &op) < 0) { - ERROR(strerror(errno)); - - return (NULL); - } -#endif - - if (pcap_compile(pcap, &compiled_filter, filter, 0, - dev.dev_netmask.s_addr) < 0) { - ERROR(pcap_geterr(pcap)); - harpi_realtime_close_packets(pcap); - - return (NULL); - } - - if (pcap_setfilter(pcap, &compiled_filter) < 0) { - ERROR(pcap_geterr(pcap)); - harpi_realtime_close_packets(pcap); - - return (NULL); - } - - pcap_freecode(&compiled_filter); - return (pcap); -} - -/* - * Close pcap file descriptor. - */ -static void -harpi_realtime_close_packets(pcap_t *pcap) -{ - - pcap_close(pcap); -} - -/* - * HARPI I/O. - * Read doc/HARPI.jpg algorithm. - */ -static void -harpi_realtime_read_packets(unsigned char *arg, const struct pcap_pkthdr - *header, const unsigned char *packet) -{ - struct ether_addr src_mac, dst_mac; - struct in_addr src_ip, dst_ip; - struct arp_header *arp_packet; - char c_src_ip[16], c_src_mac[18], c_dst_ip[16], c_dst_mac[18], c_ap_ip[16], - entry[34]; - int i, ret = 0, state = 0; - - /* - * ARP Packet. - */ - arp_packet = (struct arp_header *) (packet + dev.dev_offset); - - /* - * Convert source MAC/IPv4 string. - */ - snprintf(c_src_ip, 16, "%d.%d.%d.%d", - arp_packet->ah_addresses.ar_spa[0], - arp_packet->ah_addresses.ar_spa[1], - arp_packet->ah_addresses.ar_spa[2], - arp_packet->ah_addresses.ar_spa[3]); - inet_aton(c_src_ip, &src_ip); - - for (i = 0; i < ETHER_ADDR_LEN; i++) { - src_mac.octet[i] = arp_packet->ah_addresses.ar_sha[i]; - } - strncpy(c_src_mac, ether_ntoa(&src_mac), sizeof(char) * 18); - c_src_mac[sizeof(char) * strlen(c_src_mac)] = '\0'; - - /* - * Convert destination MAC/IPv4 string. - */ - snprintf(c_dst_ip, 16, "%d.%d.%d.%d", - arp_packet->ah_addresses.ar_tpa[0], - arp_packet->ah_addresses.ar_tpa[1], - arp_packet->ah_addresses.ar_tpa[2], - arp_packet->ah_addresses.ar_tpa[3]); - inet_aton(c_dst_ip, &dst_ip); - - for (i = 0; i < ETHER_ADDR_LEN; i++) { - dst_mac.octet[i] = arp_packet->ah_addresses.ar_tha[i]; - } - strncpy(c_dst_mac, ether_ntoa(&dst_mac), sizeof(char) * 18); - c_dst_mac[sizeof(char) * strlen(c_dst_mac)] = '\0'; - - if (ntohs(arp_packet->ah_header.ar_op) == ARP_OP_REQUEST) { - /* - * Check if it is a broadcast address. - */ - if (strcmp(c_src_ip, inet_ntoa(dev.dev_inet4)) != 0 && - strcmp(c_dst_ip, inet_ntoa(dev.dev_inet4)) != 0 && - strcmp(c_src_ip, c_dst_ip) == 0) { - /* - * Search ARP reply/request source in SARPI (ARP cache) entries. - */ - TAILQ_FOREACH(sarpi_cache_pos, &sarpi_cache_head, entries) { - /* - * Convert MAC/IPv4 to string form. - */ - memset(c_ap_ip, '\0', sizeof(char) * 16); - strncpy(c_ap_ip, inet_ntoa(sarpi_cache_pos->sc_ip), - sizeof(char) * 16); - c_ap_ip[sizeof(char) * strlen(c_ap_ip)] = '\0'; - - state = 1; - - /* - * In request, possible source address poisoned. - * In reply, possible ARP Gratuitous for ARP poisoning. - * Check if source is found in SARPI Cache. - */ - if (strcmp(c_src_ip, c_ap_ip) == 0) { - /* - * Source is Found! We reset static entry. - */ - state = 0; - - aprintf(stdout, 1, "ARP cache, REFRESH\n"); - - /* - * Refresh static ARP Cache entry. - */ - snprintf(entry, 34, "%15s %17s", - inet_ntoa(sarpi_cache_pos->sc_ip), - ether_ntoa(&(sarpi_cache_pos->sc_mac))); - entry[strlen(entry)] = '\0'; - - if (arp_cache_del(c_src_ip) < 0) { - exit(EXIT_FAILURE); - } - - if (arp_cache_add(entry) < 0) { - exit(EXIT_FAILURE); - } - - aprintf(stdout, 0, "\t src HW = <%s>\n", - ether_ntoa(&(sarpi_cache_pos->sc_mac))); - aprintf(stdout, 0, "\t src IP = <%s>\n", - inet_ntoa(sarpi_cache_pos->sc_ip)); - - break; - } - } - - /* - * Source is not found in SARPI Cache. - */ - if (state == 1) { - if (darpi_realtime_send_packet(&src_ip) < 0) { - exit(EXIT_FAILURE); - } - - if ((ret = arp_cache_del(c_src_ip)) < 0) { - exit(EXIT_FAILURE); - } else if (ret == 0) { - aprintf(stdout, 1, "ARP cache, DENY\n"); - aprintf(stdout, 0, "\t src HW = <%s>\n", c_src_mac); - aprintf(stdout, 0, "\t src IP = <%s>\n", c_src_ip); - } - } - } - /* - * Check if we are the source address. - */ - else if (strcmp(c_src_mac, ether_ntoa(&(dev.dev_mac))) == 0 && - strcmp(c_src_ip, inet_ntoa(dev.dev_inet4)) == 0) { - /* - * Search ARP Reply/Request source in SARPI (ARP cache) entries. - */ - TAILQ_FOREACH(sarpi_cache_pos, &sarpi_cache_head, entries) { - /* - * Convert MAC/IPv4 to string form. - */ - memset(c_ap_ip, '\0', sizeof(char) * 16); - strncpy(c_ap_ip, inet_ntoa(sarpi_cache_pos->sc_ip), - sizeof(char) * 16); - c_ap_ip[sizeof(char) * strlen(c_ap_ip)] = '\0'; - - state = 1; - - /* - * Check if destination is not found in SARPI Cache. - */ - if (strcmp(c_dst_ip, c_ap_ip) == 0) { - /* - * Destination found in SARPI Cache! - */ - state = 0; - break; - } - } - - /* - * Destination is not found in SARPI Cache! - */ - if (state == 1) { - /* - * DARPI 1 Cache Add/Refresh. - */ - if (darpi_cache1_list_create(&dst_ip) < 0) { - exit(EXIT_FAILURE); - } - - /* - * Check in DARPI 3 Cache if this outbound request - * derives by an inbound request. - */ - TAILQ_FOREACH(darpi_cache3_pos, &darpi_cache3_head, entries) { - if (strcmp(inet_ntoa(darpi_cache3_pos->dc_ip), - c_dst_ip) == 0) { - /* - * Entry found in DARPI 3 cache! - */ - TAILQ_REMOVE(&darpi_cache3_head, darpi_cache3_pos, - entries); - free(darpi_cache3_pos); - - return; - } - } - - /* - * Entry not found in DARPI 3 cache! - * DARPI 2 Cache Add/Refresh. - */ - if (darpi_cache2_list_create(&dst_ip) < 0) { - exit(EXIT_FAILURE); - } - } - } - /* - * Check if we are the destination address. - */ - else if (strcmp(c_dst_ip, inet_ntoa(dev.dev_inet4)) == 0) { - /* - * Search ARP reply/request source in SARPI (ARP cache) entries. - */ - TAILQ_FOREACH(sarpi_cache_pos, &sarpi_cache_head, entries) { - /* - * Convert MAC/IPv4 to string form. - */ - memset(c_ap_ip, '\0', sizeof(char) * 16); - strncpy(c_ap_ip, inet_ntoa(sarpi_cache_pos->sc_ip), - sizeof(char) * 16); - c_ap_ip[sizeof(char) * strlen(c_ap_ip)] = '\0'; - - state = 1; - - /* - * In request, possible source address poisoned. - * In reply, possible ARP Gratuitous for ARP poisoning. - * Check if source is found in SARPI Cache. - */ - if (strcmp(c_src_ip, c_ap_ip) == 0) { - /* - * Source is Found! We will reset static entry with reply. - */ - state = 0; - break; - } - } - - /* - * Destination is not found in SARPI Cache! - */ - if (state == 1) { - /* - * Possible ARP Gratuitous for ARP Poisoning. - * Search entry in DARPI 2 cache, if it matches it - * is to inserted in ARP cache, else if it doesn't - * exist, it is to deleted from ARP cache. - */ - TAILQ_FOREACH(darpi_cache2_pos, - &darpi_cache2_head, entries) { - if (strcmp(inet_ntoa(darpi_cache2_pos->dc_ip), - c_src_ip) == 0) { - /* - * Entry found in DARPI 2 cache! - */ - TAILQ_REMOVE(&darpi_cache2_head, - darpi_cache2_pos, entries); - free(darpi_cache2_pos); - - return; - } - } - - /* - * Entry not found in DARPI 2 cache! - */ - if (darpi_realtime_send_packet(&src_ip) < 0) { - exit(EXIT_FAILURE); - } - - /* - * DARPI 3 Cache Add/Refresh. - */ - if (darpi_cache3_list_create(&src_ip) < 0) { - exit(EXIT_FAILURE); - } - } - } - } else if (ntohs(arp_packet->ah_header.ar_op) == ARP_OP_REPLY) { - /* - * Check if we are the destination address. - */ - if (strcmp(c_dst_mac, ether_ntoa(&(dev.dev_mac))) == 0 && - strcmp(c_dst_ip, inet_ntoa(dev.dev_inet4)) == 0) { - /* - * Search ARP reply/request source in SARPI (ARP cache) entries. - */ - TAILQ_FOREACH(sarpi_cache_pos, &sarpi_cache_head, entries) { - /* - * Convert MAC/IPv4 to string form. - */ - memset(c_ap_ip, '\0', sizeof(char) * 16); - strncpy(c_ap_ip, inet_ntoa(sarpi_cache_pos->sc_ip), - sizeof(char) * 16); - c_ap_ip[sizeof(char) * strlen(c_ap_ip)] = '\0'; - - state = 1; - - /* - * In request, possible source address poisoned. - * In reply, possible ARP Gratuitous for ARP poisoning. - * Check if source is found in SARPI Cache. - */ - if (strcmp(c_src_ip, c_ap_ip) == 0) { - /* - * Source is Found! We reset static entry. - */ - state = 0; - - aprintf(stdout, 1, "ARP cache, REFRESH\n"); - - /* - * Refresh static ARP Cache entry. - */ - snprintf(entry, 34, "%15s %17s", - inet_ntoa(sarpi_cache_pos->sc_ip), - ether_ntoa(&(sarpi_cache_pos->sc_mac))); - entry[strlen(entry)] = '\0'; - - if (arp_cache_del(c_src_ip) < 0) { - exit(EXIT_FAILURE); - } - - if (arp_cache_add(entry) < 0) { - exit(EXIT_FAILURE); - } - - aprintf(stdout, 0, "\t src HW = <%s>\n", - ether_ntoa(&(sarpi_cache_pos->sc_mac))); - aprintf(stdout, 0, "\t src IP = <%s>\n", - inet_ntoa(sarpi_cache_pos->sc_ip)); - - break; - } - } - - /* - * Source is not found in SARPI Cache. - */ - if (state == 1) { - /* - * Possible ARP Gratuitous for ARP Poisoning. - * Search entry in DARPI 1 cache, if it matches it - * is to inserted in ARP cache, else if it doesn't - * exist, it is to deleted from ARP cache. - */ - TAILQ_FOREACH(darpi_cache1_pos, &darpi_cache1_head, entries) { - if (strcmp(inet_ntoa(darpi_cache1_pos->dc_ip), - c_src_ip) == 0) { - /* - * Entry found in DARPI 1 cache! - */ - TAILQ_REMOVE(&darpi_cache1_head, - darpi_cache1_pos, entries); - free(darpi_cache1_pos); - - memset(entry, '\0', 34); - snprintf(entry, 34, "%15s %17s", c_src_ip, c_src_mac); - entry[strlen(entry)] = '\0'; - - if (arp_cache_del(c_src_ip) < 0) { - exit(EXIT_FAILURE); - } - - if (arp_cache_add(entry) < 0) { - exit(EXIT_FAILURE); - } - - aprintf(stdout, 1, "ARP cache, ACCEPT\n"); - aprintf(stdout, 0, "\t src HW = <%s>\n", c_src_mac); - aprintf(stdout, 0, "\t src IP = <%s>\n", c_src_ip); - - return; - } - } - - /* - * Entry not found in DARPI 1 cache! - */ - if (darpi_realtime_send_packet(&src_ip) < 0) { - exit(EXIT_FAILURE); - } - - if ((ret = arp_cache_del(c_src_ip)) < 0) { - exit(EXIT_FAILURE); - } else if (ret == 0) { - aprintf(stdout, 1, "ARP cache, DENY\n"); - aprintf(stdout, 0, "\t src HW = <%s>\n", c_src_mac); - aprintf(stdout, 0, "\t src IP = <%s>\n", c_src_ip); - } - } - } - /* - * Check if we are the source address. - */ - else if (strcmp(c_src_mac, ether_ntoa(&(dev.dev_mac))) == 0 && - strcmp(c_src_ip, inet_ntoa(dev.dev_inet4)) == 0) { - /* - * Search ARP reply/request source in SARPI (ARP cache) entries. - */ - TAILQ_FOREACH(sarpi_cache_pos, &sarpi_cache_head, entries) { - /* - * Convert MAC/IPv4 to string form. - */ - memset(c_ap_ip, '\0', sizeof(char) * 16); - strncpy(c_ap_ip, inet_ntoa(sarpi_cache_pos->sc_ip), - sizeof(char) * 16); - c_ap_ip[sizeof(char) * strlen(c_ap_ip)] = '\0'; - - state = 1; - - /* - * In request, possible source address poisoned. - * In reply, possible ARP Gratuitous for ARP poisoning. - * Check if source is found in SARPI Cache. - */ - if (strcmp(c_dst_ip, c_ap_ip) == 0) { - /* - * Source is Found! We reset static entry. - */ - state = 0; - - aprintf(stdout, 1, "ARP cache, REFRESH\n"); - - /* - * Refresh static ARP Cache entry. - */ - snprintf(entry, 34, "%15s %17s", - inet_ntoa(sarpi_cache_pos->sc_ip), - ether_ntoa(&(sarpi_cache_pos->sc_mac))); - entry[strlen(entry)] = '\0'; - - if (arp_cache_del(c_dst_ip) < 0) { - exit(EXIT_FAILURE); - } - - if (arp_cache_add(entry) < 0) { - exit(EXIT_FAILURE); - } - - aprintf(stdout, 0, "\t src HW = <%s>\n", - ether_ntoa(&(sarpi_cache_pos->sc_mac))); - aprintf(stdout, 0, "\t src IP = <%s>\n", - inet_ntoa(sarpi_cache_pos->sc_ip)); - - break; - } - } - } - } -} - -/***************** - * Misc handler: * - *****************/ - -/* - * My printf() with logging mode. - */ -static void -aprintf(FILE *stream, int ltime, char *fmt, ...) -{ - struct tm tm_cur; - time_t time_cur; - FILE *log_fstream; - va_list ap; - - if (stream != NULL) { - if (ltime == 1) { - time_cur = time(NULL); - tm_cur = *(struct tm *) localtime(&time_cur); - fprintf(stream, "%02d:%02d:%02d ", - tm_cur.tm_hour, tm_cur.tm_min, tm_cur.tm_sec); - } - - va_start(ap, fmt); - vfprintf(stream, fmt, ap); - va_end(ap); - } - - if (log_mode == 0) { - if ((log_fstream = task_mode_log_open()) == NULL) { - kill(pid_main, SIGTERM); - - exit(EXIT_FAILURE); - } - - if (ltime == 1) { - time_cur = time(NULL); - tm_cur = *(struct tm *) localtime(&time_cur); - fprintf(log_fstream, "%02d:%02d:%02d ", - tm_cur.tm_hour, tm_cur.tm_min, tm_cur.tm_sec); - } - - va_start(ap, fmt); - vfprintf(log_fstream, fmt, ap); - va_end(ap); - - fflush(log_fstream); - - task_mode_log_close(log_fstream); - } -} - -/* - * Prints my license. - */ -static void -license(void) -{ - -#define COPYRIGHT \ -"Copyright (C) 2008-2014 Andrea Di Pasquale \n" \ -"All rights reserved.\n" \ -"\n" \ -"Redistribution and use in source and binary forms, with or without\n" \ -"modification, are permitted provided that the following conditions\n" \ -"are met:\n" \ -"1. Redistributions of source code must retain the above copyright\n" \ -" notice(s), this list of conditions and the following disclaimer as\n" \ -" the first lines of this file unmodified other than the possible\n" \ -" addition of one or more copyright notices.\n" \ -"2. Redistributions in binary form must reproduce the above copyright\n" \ -" notice(s), this list of conditions and the following disclaimer in " \ -"the\n" \ -" documentation and/or other materials provided with the " \ -"distribution.\n" \ -"\n" \ -"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY\n"\ -"EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE " \ -"IMPLIED\n" \ -"WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR " \ -"PURPOSE ARE\n" \ -"DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE " \ -"LIABLE FOR ANY\n" \ -"DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL " \ -"DAMAGES\n" \ -"(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR\n" \ -"SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) " \ -"HOWEVER\n" \ -"CAUSED AND ON ANY THEORY OF LIABILITY, WHETER IN CONTRACT, STRICT\n" \ -"LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY " \ -"WAY\n" \ -"OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF " \ -"SUCH\n" \ -"DAMAGE.\n\n" - - printf(COPYRIGHT); - -#undef COPYRIGHT -} - -/* - * Prints version. - */ -static void -version(void) -{ - - printf("ArpON \"ARP handler inspection\" 2.7.2 " \ - "(http://arpon.sourceforge.net)\n\n"); -} - -/* - * Prints help summary page. - */ -static void -help(void) -{ - -#define HELP \ -"Usage: arpon [Options] {SARPI | DARPI | HARPI}\n" \ -"\n" \ -"TASK MODE\n" \ -" -n, --nice Sets PID's CPU priority\n" \ -" (Default Nice: %d)\n" \ -" -p, --pid-file Sets the pid file\n" \ -" (Default: %s)\n" \ -" -q, --quiet Works in background task\n" \ -"\n" \ -"LOG MODE\n" \ -" -f, --log-file Sets the log file\n" \ -" (Default: %s)\n" \ -" -g, --log Works in logging mode\n" \ -"\n" \ -"DEVICE MANAGER\n" \ -" -i, --iface Sets your device manually\n" \ -" -o, --iface-auto Sets device automatically\n" \ -" -l, --iface-list Prints all supported interfaces\n" \ -"\n" \ -"STATIC ARP INSPECTION\n" \ -" -c, --sarpi-cache Sets SARPI entries from file\n" \ -" (Default: %s)\n" \ -" -x, --sarpi-timeout Sets SARPI Cache refresh timeout\n"\ -" (Default: %d minuts)\n" \ -" -S, --sarpi Manages ARP Cache statically\n" \ -"\n" \ -"DYNAMIC ARP INSPECTION\n" \ -" -y, --darpi-timeout Sets DARPI entries response max " \ -"timeout\n" \ -" (Default: %d seconds)\n" \ -" -D, --darpi Manages ARP Cache dynamically\n" \ -"\n" \ -"HYBRID ARP INSPECTION\n" \ -" -c, --sarpi-cache Sets HARPI entries from file\n" \ -" (Default: %s)\n" \ -" -x, --sarpi-timeout Sets HARPI Cache refresh timeout\n"\ -" (Default: %d minuts)\n" \ -" -y, --darpi-timeout Sets HARPI entries response max " \ -"timeout\n" \ -" (Default: %d seconds)\n" \ -" -H, --harpi Manages ARP Cache\n" \ -" statically and dynamically\n" \ -"\n" \ -"MISC FEATURES\n" \ -" -e, --license Prints license page\n" \ -" -v, --version Prints version number\n" \ -" -h, --help Prints help summary page\n" \ -"\n" \ -"SEE THE MAN PAGE FOR MANY DESCRIPTIONS AND EXAMPLES\n\n" - - printf(HELP, cpu_priority, pid_file, log_file, - sarpi_cache_file, sarpi_timeout, darpi_timeout, - sarpi_cache_file, sarpi_timeout, darpi_timeout); - -#undef HELP -} - -/***************** - * Main handler: * - *****************/ - -/* - * Main signal handler. - */ -static int -main_signal(void) -{ - - pthread_attr_init(&join_attr); - pthread_attr_setschedpolicy(&join_attr, SCHED_RR); - - /* - * Thread 1 joinabled, signal handler. - */ - if (pthread_create(&thread[0], &join_attr, - main_signal_thread, (void *) NULL) != 0) { - ERROR(strerror(errno)); - pthread_attr_destroy(&join_attr); - - return (-1); - } - - pthread_join(thread[0], NULL); - pthread_attr_destroy(&join_attr); - - return (0); -} - -/* - * This thread is main signal handler of: - * - SIGINT, SIGTERM, SIGQUIT: Exit - * - SIGHUP, SIGCONT: Reboot - * and handler for all threads. - */ -static void * -main_signal_thread(void *arg) -{ - int sig; - - while (1) { -#ifndef SOLARIS - sigwait(&sigse, &sig); -#else - sig = sigwait(&sigse); -#endif - switch (sig) { - case (SIGINT): - case (SIGTERM): - case (SIGQUIT): - switch (dinspec) { - case (INSPEC_SARPI): - aprintf(stdout, 0, "\r\nSARPI Interrupt...\n\n"); - break; - - case (INSPEC_DARPI): - aprintf(stdout, 0, "\r\nDARPI Interrupt...\n\n"); - break; - - case (INSPEC_HARPI): - aprintf(stdout, 0, "\r\nHARPI Interrupt...\n\n"); - break; - - case (INSPEC_NULL): - break; - } - - exit(-1); - - case (SIGHUP): - case (SIGCONT): - /* - * Stop all threads and start their (Reboot). - * Thread[0] = Signal is not restarted - * Thread[1] = SARPI/DARPI/HARPI manager yes - * Thread[2] = Iface uplink yes - * Thread[3] = SARPI/DARPI/HARPI 1° Thread yes - * Thread[4] = SARPI/DARPI/HARPI 2° Thread yes - * Thread[5] = DARPI/HARPI 3° Thread yes - * Thread[6] = HARPI 4° Thread yes - */ - main_stop(); - - if (main_start() < 0) { - pthread_exit((void *) -1); - } - break; - - default: - break; - } - } - - pthread_exit((void *) 0); -} - -/* - * Start all threads in this order: - * - SARPI: - * SARPI manager -> Iface uplink -> SARPI 1° & 2° - * - * - DARPI: - * DARPI manager -> Iface uplink -> DARPI 1° & 2° & 3° & 4° - * - * - HARPI: - * HARPI manager -> Iface uplink -> HARPI 1° & 2° & 3° & 4° & 5° - */ -static int -main_start(void) -{ - - pthread_attr_init(&detach_attr); - pthread_attr_setdetachstate(&detach_attr, PTHREAD_CREATE_DETACHED); - pthread_attr_setschedpolicy(&detach_attr, SCHED_RR); - - switch (dinspec) { - case (INSPEC_SARPI): - /* - * Thread 2 detached, start SARPI manager. - */ - if (pthread_create(&thread[1], &detach_attr, sarpi_manager_thread, - (void *) NULL) != 0) { - ERROR(strerror(errno)); - - return (-1); - } - - pthread_attr_destroy(&detach_attr); - break; - - case (INSPEC_DARPI): - /* - * Thread 2 detached, start DARPI manager. - */ - if (pthread_create(&thread[1], &detach_attr, darpi_manager_thread, - (void *) NULL) != 0) { - ERROR(strerror(errno)); - - return (-1); - } - - pthread_attr_destroy(&detach_attr); - break; - - case (INSPEC_HARPI): - /* - * Thread 2 detached, start HARPI manager. - */ - if (pthread_create(&thread[1], &detach_attr, harpi_manager_thread, - (void *) NULL) != 0) { - ERROR(strerror(errno)); - - return (-1); - } - - pthread_attr_destroy(&detach_attr); - break; - - case (INSPEC_NULL): - break; - } - - return (0); -} - -/* - * Stop these threads: - * thread[0] = Signal handler is not stopped - * thread[1] = SARPI/DARPI/HARPI manager yes - * thread[2] = Iface uplink yes - * thread[3] = SARPI/DARPI/HARPI 1° thread yes - * thread[4] = SARPI/DARPI/HARPI 2° thread yes - * thread[5] = DARPI/HARPI 3° thread yes - * thread[6] = DARPU/HARPI 4° thread yes - * thread[7] = HARPI 5° thread yes. - */ -static void -main_stop(void) -{ - int i; - - for (i = 1; i < 8; i++) { - pthread_kill(thread[i], SIGUSR1); - } -} - -/* - * Main. - */ -int -main(int argc, char *argv[], char *envp[]) -{ - struct option longopts[] = { - { "nice", required_argument, NULL, 'n' }, - { "pid-file", required_argument, NULL, 'p' }, - { "quiet", no_argument, NULL, 'q' }, - { "log-file", required_argument, NULL, 'f' }, - { "log", no_argument, NULL, 'g' }, - { "iface", required_argument, NULL, 'i' }, - { "iface-auto", no_argument, NULL, 'o' }, - { "iface-list", no_argument, NULL, 'l' }, - { "sarpi-cache", required_argument, NULL, 'c' }, - { "sarpi-timeout", required_argument, NULL, 'x' }, - { "sarpi", no_argument, NULL, 'S' }, - { "darpi-timeout", required_argument, NULL, 'y' }, - { "darpi", no_argument, NULL, 'D' }, - { "harpi", no_argument, NULL, 'H' }, - { "license", no_argument, NULL, 'e' }, - { "version", no_argument, NULL, 'v' }, - { "help", no_argument, NULL, 'h' }, - { NULL, 0, NULL, 0 } - }; - int gopt, j; - - /* - * Check if SARPI or DARPI timeout is setted without option. - */ - j = 0; - - /* - * Sanitize environment from LD_PRELOAD attacks. - */ - if (getenv("LD_PRELOAD") != NULL) { - unsetenv("LD_PRELOAD"); - execve(argv[0], argv, envp); - } - - aprintf(stdout, 0, "\n"); - - if (getuid() != 0x0) { - aprintf(stderr, 0, "ERROR: must run as root!\n\n"); - return (-1); - } - - if (argc == 1) { - aprintf(stderr, 0, - "ERROR: Use -h or --help for more information.\n\n"); - - return (0); - } - - pid_main = getpid(); - - while ((gopt = getopt_long(argc, argv, "n:p:qf:gi:olc:x:Sy:DHevh", - longopts, NULL)) != -1) { - switch(gopt) { - case ('n'): - cpu_priority = atoi(optarg); - break; - - case ('p'): - pid_file = optarg; - break; - - case ('q'): - if (task_mode_daemon() < 0) { - return (-1); - } - break; - - case ('f'): - log_file = optarg; - break; - - case ('g'): - if (task_mode_log() < 0) { - return (-1); - } - break; - - case ('i'): - dif = IFACE_MANUAL; - ddev = optarg; - break; - - case ('o'): - dif = IFACE_AUTO; - break; - - case ('l'): - dif = IFACE_LIST; - - if (iface_manager() < 0) { - return (-1); - } - - aprintf(stdout, 0, "\n"); - return (0); - - case ('c'): - sarpi_cache_file = optarg; - - if (j == 2) { - j = 3; - } else { - j = 1; - } - break; - - case ('x'): - if (sarpi_set_timeout(optarg) < 0) { - return (-1); - } - - if (j == 2) { - j = 3; - } else { - j = 1; - } - break; - - case ('S'): - if (dinspec != INSPEC_NULL) { - aprintf(stderr, 0, "ERROR: Can't use both DARPI and " \ - "SARPI or HARPI on same interface!\n\n"); - - return (-1); - } - - dinspec = INSPEC_SARPI; - break; - - case ('y'): - if (darpi_set_timeout(optarg) < 0) { - return (-1); - } - - if (j == 1) { - j = 3; - } else { - j = 2; - } - break; - - case ('D'): - if (dinspec != INSPEC_NULL) { - aprintf(stderr, 0, "ERROR: Can't use both SARPI and " \ - "DARPI or HARPI on same interface!\n\n"); - - return (-1); - } - - dinspec = INSPEC_DARPI; - break; - - case ('H'): - if (dinspec != INSPEC_NULL) { - aprintf(stderr, 0, "ERROR: Can't use both HARPI and " \ - "SARPI or DARPI on same interface!\n\n"); - - return (-1); - } - - dinspec = INSPEC_HARPI; - break; - - case ('e'): - license(); - return (0); - - case ('v'): - version(); - return (0); - - case ('h'): - help(); - return (0); - - case (':'): - case ('?'): - aprintf(stderr, 0, "\n"); - return (-1); - - default: - break; - } - } - argc -= optind; - argv += optind; - - if (dinspec == INSPEC_NULL) { - if (j != 0) { - switch (j) { - case (1): - aprintf(stderr, 0, "ERROR: SARPI required " \ - "-S option to work!\n\n"); - return (-1); - - case (2): - aprintf(stderr, 0, "ERROR: DARPI required " \ - "-D option to work!\n\n"); - return (-1); - - case (3): - aprintf(stderr, 0, "ERROR: HARPI required " \ - "-H option to work!\n\n"); - return (-1); - - default: - break; - } - } else { - aprintf(stderr, 0, "ERROR: Choose SARPI, DARPI or HARPI!\n\n"); - - return(-1); - } - } else { - switch (dinspec) { - case (INSPEC_SARPI): - if (j == 2) { - aprintf(stderr, 0, "ERROR: SARPI doesn't " \ - "required DARPI options!\n\n"); - return (-1); - } - break; - - case (INSPEC_DARPI): - if (j == 1) { - aprintf(stderr, 0, "ERROR: DARPI doesn't " \ - "required SARPI options!\n\n"); - return (-1); - } - break; - - case (INSPEC_HARPI): - case (INSPEC_NULL): - default: - break; - } - } - - sigemptyset(&sigse); - sigaddset(&sigse, SIGINT); - sigaddset(&sigse, SIGTERM); - sigaddset(&sigse, SIGQUIT); - sigaddset(&sigse, SIGHUP); - sigaddset(&sigse, SIGCONT); - - if (pthread_sigmask(SIG_BLOCK, &sigse, NULL) < 0) { - ERROR(strerror(errno)); - - return (-1); - } - - if (main_start() < 0) { - return (-1); - } - - if (main_signal() < 0) { - return (-1); - } - - return (0); -} - -/* - * EOF. - */ diff -Nru arpon-2.7.2/src/CMakeLists.txt arpon-3.0-ng+dfsg1/src/CMakeLists.txt --- arpon-2.7.2/src/CMakeLists.txt 2014-10-11 15:22:58.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/CMakeLists.txt 2016-01-29 02:07:40.000000000 +0000 @@ -1,23 +1,111 @@ -# Compile the arpon.c source code # -# Copyright 2014 gmrandazzo@gmail.com +# Copyright (C) 2008-2016 Andrea Di Pasquale +# Copyright (C) 2008-2016 Giuseppe Marco Randazzo +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR +# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES +# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +# IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, +# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, +# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING +# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF +# THE POSSIBILITY OF SUCH DAMAGE. +# +# $ArpON: CMakeLists.txt,v 3.0-ng 01/29/2016 03:07:40 spikey Exp $ # -# Redistribution AND use is allowed according to the terms of the BSD 3 clause if(${CMAKE_INSTALL_PREFIX} STREQUAL "/") - set(arpon_sarpi /etc/arpon.sarpi) - set(install_prefix /sbin) + set(ARPON_SBIN /sbin/arpon) + set(ARPON_DOC /usr/share/doc/arpon/index.html) + set(ARPON_ETC /etc/arpon.conf) + set(ARPON_LOG /var/log/arpon.log) + set(ARPON_PID /var/run/arpon.pid) + set(install_prefix /sbin) else(${CMAKE_INSTALL_PREFIX} STREQUAL "/") - set(arpon_sarpi ${CMAKE_INSTALL_PREFIX}/etc/arpon.sarpi) - set(install_prefix ${CMAKE_INSTALL_PREFIX}/sbin) + set(ARPON_SBIN ${CMAKE_INSTALL_PREFIX}/sbin/arpon) + set(ARPON_DOC ${CMAKE_INSTALL_PREFIX}/share/doc/arpon/index.html) + set(ARPON_ETC ${CMAKE_INSTALL_PREFIX}/etc/arpon.conf) + set(ARPON_LOG ${CMAKE_INSTALL_PREFIX}/log/arpon.log) + set(ARPON_PID ${CMAKE_INSTALL_PREFIX}/run/arpon.pid) + set(install_prefix ${CMAKE_INSTALL_PREFIX}/sbin) endif(${CMAKE_INSTALL_PREFIX} STREQUAL "/") -configure_file ( +configure_file( "${PROJECT_SOURCE_DIR}/src/config.h.in" "${PROJECT_BINARY_DIR}/src/config.h") + include_directories("${PROJECT_BINARY_DIR}/src") +add_executable( + arpon + arpca.c + arpca.h + config.h.in + darpi.c + darpica.c + darpica.h + darpi.h + dmn.c + dmn.h + env.c + env.h + exit.c + exit.h + harpi.c + harpi.h + intf.c + intf.h + ispn.c + ispn.h + main.c + msg.c + msg.h + opt.c + opt.h + proc.c + proc.h + queue.h + rt.c + rt.h + sarpi.c + sarpica.c + sarpica.h + sarpi.h + sig.c + sig.h + std.c + std.h + thd.c + thd.h + unused.h + ver.h) -add_executable(arpon arpon.c include/queue.h) -target_link_libraries(arpon ${NET_LIB} ${DNET_LIB} ${PCAP_LIB} ${PTHREAD_LIB}) -set_target_properties(arpon PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) -install(TARGETS arpon RUNTIME DESTINATION ${install_prefix} COMPONENT Application) +target_link_libraries(arpon + ${PTHREADS_LIB} ${RT_LIB} ${PCAP_LIB} ${NET_LIB} ${DNET_LIB}) + +set_target_properties(arpon + PROPERTIES INSTALL_RPATH_USE_LINK_PATH TRUE) + +install(TARGETS arpon + RUNTIME DESTINATION ${install_prefix} + COMPONENT Application) + +# +# EOF +# +# vim:ts=4:expandtab +# diff -Nru arpon-2.7.2/src/config.h.in arpon-3.0-ng+dfsg1/src/config.h.in --- arpon-2.7.2/src/config.h.in 2014-10-09 22:21:59.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/config.h.in 2016-01-29 01:59:28.000000000 +0000 @@ -1 +1,65 @@ -#define arpon_sarpi "@arpon_sarpi@" +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: config.h.in,v 3.0-ng 01/29/2016 02:59:28 spikey Exp $ + */ + +#ifndef _CONFIG_H_IN_ +#define _CONFIG_H_IN_ + +/* + * Binary file. + */ +#define SBIN_FILE "@ARPON_SBIN@" + +/* + * Documentation file. + */ +#define DOC_FILE "@ARPON_DOC@" + +/* + * Configuration file. + */ +#define ETC_FILE "@ARPON_ETC@" + +/* + * Log file. + */ +#define LOG_FILE "@ARPON_LOG@" + +/* + * Pid file. + */ +#define PID_FILE "@ARPON_PID@" + +#endif /* !_CONFIG_H_IN_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/darpi.c arpon-3.0-ng+dfsg1/src/darpi.c --- arpon-2.7.2/src/darpi.c 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/darpi.c 2016-01-29 01:56:38.000000000 +0000 @@ -0,0 +1,269 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: darpi.c,v 3.0-ng 01/29/2016 02:56:40 spikey Exp $ + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "arpca.h" +#include "darpica.h" +#include "darpi.h" +#include "intf.h" +#include "ispn.h" +#include "msg.h" +#include "opt.h" +#include "unused.h" + +/* + * DARPI live capture handler of the I/O ARP packets + * read from the network traffic of the interface. + */ +void +darpi_handler(int op, struct ether_addr *macsrc, struct in_addr *ipsrc, + UNUSED(struct ether_addr *macdst), struct in_addr *ipdst) +{ + + do { + char smacsrc[INTF_ETHERSTRLEN], sipsrc[INET_ADDRSTRLEN], + UNUSED(smacdst[INTF_ETHERSTRLEN]), UNUSED(sipdst[INET_ADDRSTRLEN]), + *interface = NULL; + + MSG_DEBUG("Start DARPI live capture handler"); + + /* Get the interface name command option. */ + interface = opt_getinterface(); + + /* MAC src addr network byte order to string. */ + strncpy(smacsrc, ether_ntoa(macsrc), INTF_ETHERSTRLEN); + + /* IP src addr network byte order to string. */ + strncpy(sipsrc, inet_ntoa(*ipsrc), INET_ADDRSTRLEN); + +#ifndef NDEBUG + /* MAC dst addr network byte order to string. */ + strncpy(smacdst, ether_ntoa(macdst), INTF_ETHERSTRLEN); + + /* IP dst addr network byte order to string. */ + strncpy(sipdst, inet_ntoa(*ipdst), INET_ADDRSTRLEN); +#endif /* !NDEBUG */ + + /* Check the type of the ARP packet read. */ + if (op & INTF_ARPOP_REQUEST) { + /* + * Check the I/O bound direction of the ARP request + * packet read (sent by us or sent to us). + */ + if (op & INTF_ARPOP_OUTBOUND) { + /* + * Check if the ARP request packet is a gratuitous + * ARP request packet, probe ARP request packet or + * simple ARP request packet. + */ + if (op & INTF_ARPOP_GRATUITOUS) { + /* Gratuitous ARP request packet to outbound. */ + INTF_OUTBOUND("Gratuitous ARP request"); + } else if (op & INTF_ARPOP_PROBE) { + /* Probe ARP request packet to outbound. */ + INTF_OUTBOUND("Probe ARP request"); + } else { + /* Simple ARP request packet to outbound. */ + INTF_OUTBOUND("ARP request"); + + /* + * Add the entry in the DARPI cache with + * the destination IP address of the ARP request + * packet and the current local time. + */ + darpica_enqueue(ipdst); + } + + /* Break immediately. */ + break; + } else if (op & INTF_ARPOP_INBOUND) { + /* + * Check if the ARP request packet is a gratuitous + * ARP request packet, probe ARP request packet or + * simple ARP request packet. + */ + if (op & INTF_ARPOP_GRATUITOUS) { + /* Gratuitous ARP request packet from inbound. */ + INTF_INBOUND("Gratuitous ARP request"); + + /* + * Send an ARP request to source IP (with MAC + * broadcast) address of the ARP request packet + * (in the next ARP packet read, follow the + * outbound ARP request). + */ + intf_inject(ARPOP_REQUEST, ipsrc); + } else if (op & INTF_ARPOP_PROBE) { + /* Probe ARP request packet from inbound. */ + INTF_INBOUND("Probe ARP request"); + + /* + * Send a probe ARP reply to source IP (with MAC + * broadcast) address of the ARP request packet + * (in the next ARP packet read, follow the + * outbound ARP reply). + */ + intf_inject(ARPOP_REPLY, ipsrc); + + /* Break immediately. */ + break; + } else { + /* Simple ARP request packet from inbound. */ + INTF_INBOUND("ARP request"); + + /* + * Check if the source IP address of the ARP + * request packet exists in the DARPI cache. + */ + if (darpica_ismember(ipsrc) == false) { + /* + * Send an ARP request to source IP (with MAC + * broadcast) address of the ARP request packet + * (in the next ARP packet read, follow the + * outbound ARP request). + */ + intf_inject(ARPOP_REQUEST, ipsrc); + } + + /* + * Send an ARP reply to source IP (with MAC broadcast) + * address of the ARP request packet (in the next ARP + * packet read, follow the outbound ARP reply). + */ + intf_inject(ARPOP_REPLY, ipsrc); + } + } + } else if (op & INTF_ARPOP_REPLY) { + /* + * Check the I/O bound direction of the ARP reply + * packet read (sent by us or sent to us). + */ + if (op & INTF_ARPOP_OUTBOUND) { + /* + * Check if the ARP reply packet is a gratuitous + * ARP reply packet, probe ARP reply packet or + * simple ARP reply packet. + */ + if (op & INTF_ARPOP_GRATUITOUS) { + /* Gratuitous ARP reply packet to outbound. */ + INTF_OUTBOUND("Gratuitous ARP reply"); + } else if (op & INTF_ARPOP_PROBE) { + /* Probe ARP reply packet to outbound. */ + INTF_OUTBOUND("Probe ARP reply"); + } else { + /* Simple ARP reply packet to outbound. */ + INTF_OUTBOUND("ARP reply"); + } + + /* Break immediately. */ + break; + } else if (op & INTF_ARPOP_INBOUND) { + /* + * Check if the ARP reply packet is a gratuitous + * ARP reply packet, probe ARP reply packet or + * simple ARP reply packet. + */ + if (op & INTF_ARPOP_GRATUITOUS) { + /* Gratuitous ARP reply packet from inbound. */ + INTF_INBOUND("Gratuitous ARP reply"); + } else if (op & INTF_ARPOP_PROBE) { + /* Probe ARP reply packet from inbound. */ + INTF_INBOUND("Probe ARP reply"); + + /* Break immediately. */ + break; + } else { + /* Simple ARP reply packet from inbound. */ + INTF_INBOUND("ARP reply"); + + /* + * Check if the source IP address of the ARP + * reply packet exists in the DARPI cache. + */ + if (darpica_ismember(ipsrc) == true) { + /* + * Delete the first or the only + * entry not expired from the DARPI cache + * of the source IP address of the ARP + * reply packet. + */ + darpica_dequeue(ipsrc); + + /* + * Overwrite the not permanent IP entry in the + * ARP cache of the source IP address of the ARP + * reply packet with the same source + * addresses (POLICY: ALLOW). + */ + arpca_overwrite(macsrc, ipsrc, ARPCA_NOTPERMANENT); + + /* Print the ALLOW policy info message. */ + ISPN_ALLOW(sipsrc, smacsrc); + + /* Break immediately. */ + break; + } + } + + /* + * Send an ARP request to source IP (with MAC broadcast) + * address of the ARP reply packet (in the next ARP + * packet read, follow the outbound ARP request. + */ + intf_inject(ARPOP_REQUEST, ipsrc); + } + } + + /* + * Delete the IP entry from the ARP cache of the source + * IP address of the ARP packet (POLICY: DENY). + */ + arpca_delete(ipsrc); + + /* Print the DENY policy info message. */ + ISPN_DENY(sipsrc, smacsrc); + } while (0); + + MSG_DEBUG("End DARPI live capture handler"); +} + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/darpica.c arpon-3.0-ng+dfsg1/src/darpica.c --- arpon-2.7.2/src/darpica.c 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/darpica.c 2016-01-29 02:08:03.000000000 +0000 @@ -0,0 +1,507 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: darpica.c,v 3.0-ng 01/29/2016 03:08:04 spikey Exp $ + */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "darpica.h" +#include "exit.h" +#include "msg.h" +#include "queue.h" +#include "rt.h" +#include "thd.h" +#include "unused.h" + +/* + * DARPI timeout of the DARPI cache + * (Expiry for each IP entry of the DARPI cache). + */ +#define DARPICA_TIMEOUT 1.0 /* 1 second. */ + +/* + * Timeout of the DARPI cache + * (Expiry for each loop of the DARPI cache handler). + */ +#define DARPICA_LOOPTIMEOUT 1 /* 1 second. */ + +/* + * DARPI cache queue structure definition. + */ +typedef struct dca_queue { + double time; /* DARPI cache local time entry. */ + struct in_addr ip; /* DARPI cache IP addr entry. */ + + TAILQ_ENTRY(dca_queue) next; /* Next DARPI cache queue element. */ +} dca_t; + +/* + * Function prototypes not exported. + */ +static void darpica_init(void); +static void darpica_destroy(void); +static void darpica_dequeuetop(void); +static void *darpica_handler(void *arg); + +/* + * Initialize the DARPI cache queue structure. + */ +static TAILQ_HEAD(dca, dca_queue) dca_head = TAILQ_HEAD_INITIALIZER(dca_head); + +/* + * Initialize the DARPI cache mutex. + */ +static pthread_mutex_t darpica_mtx = PTHREAD_MUTEX_INITIALIZER; + +/* + * Configure the DARPI cache. + */ +void +darpica_configure(void) +{ + + MSG_DEBUG("Start DARPI cache configure"); + + /* Initialize the DARPI cache queue structure. */ + darpica_init(); + + /* Register the DARPI cache handler thread. */ + thd_register(darpica_handler, NULL, "darpica_handler"); + + MSG_DEBUG("End DARPI cache configure"); +} + +/* + * Initialize the DARPI cache queue structure. + */ +static void +darpica_init(void) +{ + + /* Set the DARPI cache queue structure to NULL. */ + TAILQ_INIT(&dca_head); + MSG_DEBUG("Initialize DARPI cache queue successful"); + + /* Push darpica_destroy() to be called on exit_clean(). */ + exit_push(darpica_destroy, "darpica_destroy"); +} + +/* + * Destroy the DARPI cache queue structure. + */ +static void +darpica_destroy(void) +{ + + /* Unlock the mutex of the DARPI cache before the destruction. */ + if (pthread_mutex_unlock(&darpica_mtx) != 0) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } + + /* No empty DARPI cache queue structure? */ + if (TAILQ_EMPTY(&dca_head) == 0) { + /* Loop until the DARPI cache queue structure is empty. */ + do { + /* Dequeue the DARPI cache entry. */ + darpica_dequeuetop(); + } while (TAILQ_EMPTY(&dca_head) == 0); + + /* Re-initialize the DARPI cache queue structure to NULL. */ + TAILQ_INIT(&dca_head); + } + + MSG_DEBUG("Destroy DARPI cache queue successful"); +} + +/* + * Dequeue the DARPI cache queue element from the DARPI cache queue structure. + */ +static void +darpica_dequeuetop(void) +{ + dca_t *cur = NULL; + double UNUSED(stime); + char UNUSED(*sip) = NULL; + + /* Get the first DARPI cache queue element. */ + cur = TAILQ_FIRST(&dca_head); + + /* Dequeue the first DARPI cache queue element. */ + TAILQ_REMOVE(&dca_head, cur, next); + +#ifndef NDEBUG + /* Get the DARPI cache local time entry. */ + stime = cur->time; +#endif /* !NDEBUG */ + + MSG_DEBUG("cur->time = %lf", stime); + +#ifndef NDEBUG + /* Get the DARPI cache IP addr entry. */ + sip = inet_ntoa(cur->ip); +#endif /* !NDEBUG */ + + MSG_DEBUG("cur->ip = %s", sip); + + /* Deallocate the DARPI cache queue element. */ + free(cur); + + MSG_DEBUG("dca_t *cur deallocate from the memory"); + MSG_DEBUG("Dequeue <%lf, %s> DARPI cache entry successful", stime, sip); +} + +/* + * Enqueue the DARPI cache queue element in the DARPI cache queue structure. + */ +void +darpica_enqueue(struct in_addr *ip) +{ + + do { + dca_t *new = NULL; + double UNUSED(stime); + char UNUSED(*sip) = NULL; + + /* Lock the mutex of the DARPI cache. */ + if (pthread_mutex_lock(&darpica_mtx) != 0) + break; + + /* Allocate the DARPI cache queue element. */ + if ((new = (dca_t *)malloc(sizeof(dca_t))) == NULL) + break; + + MSG_DEBUG("dca_t *new allocate in the memory"); + + /* Initialize the DARPI cache local time entry. */ + new->time = rt_getlocaltime(); + +#ifndef NDEBUG + /* Current local time. */ + stime = new->time; +#endif /* !NDEBUG */ + + MSG_DEBUG("new->time = %lf", stime); + + /* Initialize the DARPI cache IP addr entry. */ + new->ip = *ip; + +#ifndef NDEBUG + /* IP addr network byte order to string. */ + sip = inet_ntoa(new->ip); +#endif /* !NDEBUG */ + + MSG_DEBUG("cur->ip = %s", sip); + + /* Empty DARPI cache queue structure? */ + if (TAILQ_EMPTY(&dca_head) != 0) { + /* Enqueue the DARPI cache queue element in the head. */ + TAILQ_INSERT_HEAD(&dca_head, new, next); + MSG_DEBUG("H-Enqueue <%lf, %s> DARPI cache entry successful", + stime, sip); + } else { + /* Enqueue the DARPI cache queue element in the tail. */ + TAILQ_INSERT_TAIL(&dca_head, new, next); + MSG_DEBUG("T-Enqueue <%lf, %s> DARPI cache entry successful", + stime, sip); + } + + /* Unlock the mutex of the DARPI cache. */ + if (pthread_mutex_unlock(&darpica_mtx) != 0) + break; + + return; + } while (0); + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Find a DARPI cache queue element in the DARPI cache queue structure. + */ +bool +darpica_ismember(struct in_addr *ip) +{ + + do { + bool ret; + double UNUSED(stime); + char UNUSED(*sip) = NULL; + + /* Lock the mutex of the DARPI cache. */ + if (pthread_mutex_lock(&darpica_mtx) != 0) + break; + + /* Return value to false. */ + ret = false; + + /* No empty DARPI cache queue structure? */ + if (TAILQ_EMPTY(&dca_head) == 0) { + dca_t *cur = NULL; + + /* Looking the IP addr in the DARPI cache queue structure. */ + TAILQ_FOREACH(cur, &dca_head, next) { + if (ip->s_addr == cur->ip.s_addr) { +#ifndef NDEBUG + /* Local time of the DARPI cache queue element. */ + stime = cur->time; + + /* + * IP addr network byte order of the + * DARPI cache queue element to string. + */ + sip = inet_ntoa(cur->ip); +#endif /* !NDEBUG */ + + /* IP addr found, it is a DARPI cache queue element. */ + MSG_DEBUG("<%lf, %s> DARPI cache entry found", stime, sip); + + /* Return value to true. */ + ret = true; + + /* Therefore break. */ + break; + } + } + } + + /* IP addr not found? It is not a DARPI cache queue element? */ + if (ret == false) { +#ifndef NDEBUG + /* IP addr network byte order to string. */ + sip = inet_ntoa(*ip); +#endif /* !NDEBUG */ + + /* IP addr not found, it is not a DARPI cache queue element. */ + MSG_DEBUG("<%s> DARPI cache entry not found", sip); + } + + /* Unlock the mutex of the DARPI cache. */ + if (pthread_mutex_unlock(&darpica_mtx) != 0) + break; + + return ret; + } while (0); + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Dequeue the DARPI cache queue element from the DARPI cache queue structure. + */ +void +darpica_dequeue(struct in_addr *ip) +{ + + do { + dca_t *elm = NULL, *cur = NULL; + double UNUSED(stime); + char UNUSED(*sip) = NULL; + + /* Lock the mutex of the DARPI cache. */ + if (pthread_mutex_lock(&darpica_mtx) != 0) + break; + + /* Looking the IP addr in the DARPI cache queue structure. */ + TAILQ_FOREACH(elm, &dca_head, next) { + if (ip->s_addr == elm->ip.s_addr) { + /* Get the specified DARPI cache queue element. */ + cur = elm; + +#ifndef NDEBUG + /* Get the DARPI cache local time entry. */ + stime = cur->time; + + /* Get the DARPI cache IP addr entry. */ + sip = inet_ntoa(cur->ip); +#endif /* !NDEBUG */ + + /* IP addr found, it is a DARPI cache queue element. */ + MSG_DEBUG("<%lf, %s> DARPI cache entry found", stime, sip); + + /* Therefore break. */ + break; + } + } + + /* IP addr not found? It is not a DARPI cache queue element? */ + if (cur == NULL) { +#ifndef NDEBUG + /* IP addr network byte order to string. */ + sip = inet_ntoa(*ip); +#endif /* !NDEBUG */ + + /* IP addr not found, it is not a DARPI cache queue element. */ + MSG_DEBUG("<%s> DARPI cache entry not found", sip); + } else { + /* Dequeue the specified DARPI cache queue element. */ + TAILQ_REMOVE(&dca_head, cur, next); + + MSG_DEBUG("cur->time = %lf", stime); + MSG_DEBUG("cur->ip = %s", sip); + + /* Deallocate the DARPI cache queue element. */ + free(cur); + + MSG_DEBUG("dca_t *cur deallocate from the memory"); + MSG_DEBUG("Dequeue <%lf, %s> DARPI cache entry successful", + stime, sip); + } + + /* Unlock the mutex of the DARPI cache. */ + if (pthread_mutex_unlock(&darpica_mtx) != 0) + break; + + return; + } while (0); + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Delete the entries expired from the DARPI cache + * (difftime(current local time, TIME) >= DARPI timeout of the DARPI cache). + */ +static void * +darpica_handler(UNUSED(void *arg)) +{ + + /* Initialize the thread. */ + thd_init(); + + MSG_DEBUG("Start DARPI cache handler"); + + /* Loop each time that the timeout of the DARPI cache expires. */ + while (1) { + /* Lock the mutex of the DARPI cache. */ + if (pthread_mutex_lock(&darpica_mtx) != 0) + break; + + /* No empty DARPI cache queue structure? */ + if (TAILQ_EMPTY(&dca_head) == 0) { + dca_t *cur = NULL, *tmp = NULL; + double ltime, UNUSED(stime); + char UNUSED(*sip) = NULL; + + /* Initialize the current local time. */ + ltime = rt_getlocaltime(); + + MSG_DEBUG("Delete of the expired entries from the DARPI cache.."); + + /* + * Delete all the entries expired + * from the DARPI cache queue structure. + */ + for (cur = TAILQ_FIRST(&dca_head); cur != NULL; cur = tmp) { + /* Get the next DARPI cache queue element. */ + tmp = TAILQ_NEXT(cur, next); + +#ifndef NDEBUG + /* DARPI cache local time entry. */ + stime = cur->time; + + /* DARPI cache IP addr entry network byte order to string. */ + sip = inet_ntoa(cur->ip); +#endif /* !NDEBUG */ + + /* + * DARPI cache entry expired? Therefore: + * + * DARPI cache entry expired = + * difftime(current local time, TIME) >= + * DARPI timeout of the DARPI cache + */ + if (rt_difftime(ltime, cur->time) >= DARPICA_TIMEOUT) { + /* + * Delete the entry + * expired from the DARPI cache. + */ + MSG_DEBUG("<%lf, %s> DARPI cache entry expired", + stime, sip); + + /* Dequeue the specified DARPI cache queue element. */ + TAILQ_REMOVE(&dca_head, cur, next); + + MSG_DEBUG("cur->time = %lf", stime); + MSG_DEBUG("cur->ip = %s", sip); + + /* Deallocate the DARPI cache queue element. */ + free(cur); + + MSG_DEBUG("dca_t *cur deallocate from the memory"); + MSG_DEBUG("Dequeue <%lf, %s> DARPI cache entry successful", + stime, sip); + } else { + /* + * entry not expired, therefore + * no delete of it from the DARPI cache. + */ + MSG_DEBUG("<%lf, %s> DARPI cache entry not expired", + stime, sip); + } + } + } else { + /* Empty DARPI cache queue structure. */ + MSG_DEBUG("No delete of the expired entries from the DARPI cache"); + } + + /* Unlock the mutex of the DARPI cache. */ + if (pthread_mutex_unlock(&darpica_mtx) != 0) + break; + + /* + * Suspend the execution of the calling thread until + * the timeout of the DARPI cache expires (1 second). + */ + thd_suspend(DARPICA_LOOPTIMEOUT); + } + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + + /* Never reaches here. */ + return NULL; +} + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/darpica.h arpon-3.0-ng+dfsg1/src/darpica.h --- arpon-2.7.2/src/darpica.h 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/darpica.h 2016-01-29 02:08:38.000000000 +0000 @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: darpica.h,v 3.0-ng 01/29/2016 03:08:39 spikey Exp $ + */ + +#ifndef _DARPICA_H_ +#define _DARPICA_H_ + +/* + * Function prototype exported. + */ +extern void darpica_configure(void); +extern void darpica_enqueue(struct in_addr *ip); +extern bool darpica_ismember(struct in_addr *ip); +extern void darpica_dequeue(struct in_addr *ip); + +#endif /* !_DARPICA_H_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/darpi.h arpon-3.0-ng+dfsg1/src/darpi.h --- arpon-2.7.2/src/darpi.h 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/darpi.h 2016-01-29 01:58:48.000000000 +0000 @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: darpi.h,v 3.0-ng 01/29/2016 02:58:49 spikey Exp $ + */ + +#ifndef _DARPI_H_ +#define _DARPI_H_ + +/* + * Function prototype exported. + */ +extern void darpi_handler(int op, struct ether_addr *macsrc, + struct in_addr *ipsrc, struct ether_addr *macdst, struct in_addr *ipdst); + +#endif /* !_DARPI_H_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/dmn.c arpon-3.0-ng+dfsg1/src/dmn.c --- arpon-2.7.2/src/dmn.c 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/dmn.c 2016-01-29 02:05:59.000000000 +0000 @@ -0,0 +1,351 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: dmn.c,v 3.0-ng 01/29/2016 03:05:59 spikey Exp $ + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "dmn.h" +#include "env.h" +#include "exit.h" +#include "ispn.h" +#include "msg.h" +#include "opt.h" + +/* + * Root directory. + */ +#define DMN_ROOTDIR "/" + +/* + * User file creation mask. + */ +#define DMN_USERMASK 0 + +/* + * Null device. + */ +#define DMN_NULLDEV "/dev/null" + +/* + * Pid file permissions to 644. + */ +#define DMN_PIDPERMS S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH + +/* + * Function prototypes not exported. + */ +static void dmn_forktwice(void); +static void dmn_setenvironment(char **argv); +static void dmn_redirectstreams(void); +static FILE *dmn_initpid(void); +static void dmn_putpid(FILE *pid); +static void dmn_destroypid(FILE **pid); + +/* + * Daemonize the process. + */ +void +dmn_daemonize(char **argv) +{ + FILE *pid = NULL; + + MSG_DEBUG("Start daemonize process"); + + do { + /* No specified daemonize command option? */ + if (opt_getdaemon() == false) { + MSG_DEBUG("No daemonize process"); + break; + } + + /* Call the fork twice. */ + dmn_forktwice(); + + /* Set the environment. */ + dmn_setenvironment(argv); + + /* Redirect the standard I/O/E to /dev/null character device. */ + dmn_redirectstreams(); + } while (0); + + /* Initialize the pid file stream. */ + pid = dmn_initpid(); + + /* Put the PID in the pid file stream. */ + dmn_putpid(pid); + + /* Destroy the pid file stream. */ + dmn_destroypid(&pid); + + MSG_DEBUG("End daemonize process"); +} + +/* + * Fork twice. + */ +static void +dmn_forktwice(void) +{ + + do { + pid_t pid; + + /* Fork off the parent process. */ + if ((pid = fork()) < 0) + break; + + /* Grandparent process exit. */ + if (pid > 0) { + MSG_DEBUG("Grandparent PID = %d exit", getpid()); + + /* Cleanup and exit. */ + exit_cleanup(true); + } + + /* On success the parent process becomes the session leader. */ + if (setsid() < 0) { + break; + } + + /* Ignore when the controlling terminal is closed. */ + if (signal(SIGHUP, SIG_IGN) == SIG_ERR) + break; + + /* Fork off the grandchild process. */ + if ((pid = fork()) < 0) { + break; + } + + /* Parent process exit allowing the grandparent process to terminate. */ + if (pid > 0) { + MSG_DEBUG("Parent PID = %d exit", getpid()); + + /* Cleanup and exit. */ + exit_cleanup(true); + } + + /* Get the grandchild process ID. */ + pid = getpid(); + + MSG_DEBUG("Grandchild PID = %d is running", pid); + MSG_INFO("Background process is running (%d).", pid); + + return; + } while (0); + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Set the environment. + */ +static void +dmn_setenvironment(char **argv) +{ + const char *path = NULL; + + /* Get the environment binary path file. */ + path = env_getpath(*(argv + 0)); + + /* Global or local environment binary path file? */ + if (strcmp(path, SBIN_FILE) == 0) { + /* Set the current working directory to the root directory. */ + if (chdir(DMN_ROOTDIR) < 0) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("cwd = %s", DMN_ROOTDIR); + } else { + /* No change the current working directory (local directory). */ + MSG_DEBUG("cwd = %s", path); + } + + /* Set the user file creation mask to zero. */ + umask(DMN_USERMASK); + MSG_DEBUG("umask = %d", DMN_USERMASK); +} + +/* + * Redirect the standard input, output and error to /dev/null character device. + */ +static void +dmn_redirectstreams(void) +{ + + do { + int fd; + + /* Open the /dev/null character device. */ + if ((fd = open(DMN_NULLDEV, O_RDWR, 0)) < 0) + break; + + /* Redirect the standard input to /dev/null character device. */ + if (dup2(fd, STDIN_FILENO) < 0) + break; + + /* Redirect the standard output to /dev/null character device. */ + if (dup2(fd, STDOUT_FILENO) < 0) + break; + + /* Redirect the standard error to /dev/null character device. */ + if (dup2(fd, STDERR_FILENO) < 0) + break; + + /* Close the /dev/null character device. */ + if (fd > 2) { + if (close(fd) < 0) + break; + } + + MSG_DEBUG("Redirect I/O/E streams to /dev/null successful"); + + return; + } while (0); + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Initialize the pid file stream of the PID. + */ +static FILE * +dmn_initpid(void) +{ + + do { + struct stat stats; + FILE *pid = NULL; + + /* Check if the pid file exist. */ + if (stat(PID_FILE, &stats) < 0) { + if (errno == ENOENT) { + int fd; + + /* Create and open the pid file with the 644 perms. */ + if ((fd = open(PID_FILE, O_CREAT, DMN_PIDPERMS)) < 0) + break; + + /* Close the pid file descriptor. */ + if (close(fd) < 0) + break; + + /* Call again. */ + if (stat(PID_FILE, &stats) < 0) + break; + + MSG_DEBUG("Create %s with 644 perms successful", PID_FILE); + } else { + break; + } + } + + /* Check if the pid file is a regular file. */ + if (S_ISREG(stats.st_mode) == 0) { + MSG_WARN("%s is not a regular file", PID_FILE); + exit(EXIT_FAILURE); + } + + /* Fix the pid file perms to 644. */ + if (chmod(PID_FILE, DMN_PIDPERMS) < 0) + break; + + /* Open the pid file stream to write. */ + if ((pid = fopen(PID_FILE, "w")) == NULL) + break; + + MSG_DEBUG("Open %s successful", PID_FILE); + + return pid; + } while (0); + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Put the PID in the pid file stream. + */ +static void +dmn_putpid(FILE *pid) +{ + pid_t id; + + /* Get the Process ID. */ + id = getpid(); + + /* Print the PID in the pid file stream. */ + fprintf(pid, "%d", id); + + /* Flush the pid file stream. */ + if (fflush(pid) == EOF) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("Put %d in %s successful", id, PID_FILE); +} + +/* + * Destroy the pid file stream of the PID. + */ +static void +dmn_destroypid(FILE **pid) +{ + + /* Close the pid file stream. */ + if (fclose(*pid) == EOF) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } + + /* Set the pid file stream to NULL. */ + *pid = NULL; + + MSG_DEBUG("Close %s successful", PID_FILE); +} + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/dmn.h arpon-3.0-ng+dfsg1/src/dmn.h --- arpon-2.7.2/src/dmn.h 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/dmn.h 2016-01-29 02:03:23.000000000 +0000 @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: dmn.h,v 3.0-ng 01/29/2016 03:03:24 spikey Exp $ + */ + +#ifndef _DMN_H_ +#define _DMN_H_ + +/* + * Function prototype exported. + */ +extern void dmn_daemonize(char **argv); + +#endif /* !_DMN_H_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/env.c arpon-3.0-ng+dfsg1/src/env.c --- arpon-2.7.2/src/env.c 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/env.c 2016-01-29 01:58:06.000000000 +0000 @@ -0,0 +1,112 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: env.c,v 3.0-ng 01/29/2016 02:58:08 spikey Exp $ + */ + +#include + +#include +#include +#include +#include +#include + +#include "config.h" +#include "env.h" +#include "msg.h" + +/* + * Environment variable of the preload shared objects. + */ +#define ENV_LDPRELOAD "LD_PRELOAD" + +/* + * Root User ID. + */ +#define ENV_ROOTUID 0 + +/* + * Root Group ID. + */ +#define ENV_ROOTGID 0 + +/* + * Audit the environment. + */ +void +env_audit(char **argv, char **envp) +{ + + do { + /* Avoid the $LD_PRELOAD attack. */ + if (getenv(ENV_LDPRELOAD) != NULL) { + /* Unset $LD_PRELOAD environment variable. */ + if (unsetenv(ENV_LDPRELOAD) < 0) + break; + + /* Re-exec the current process without $LD_PRELOAD. */ + if (execve(env_getpath(*(argv + 0)), argv, envp) < 0) + break; + } + + /* Root user? */ + if (getuid() != ENV_ROOTUID || getgid() != ENV_ROOTGID) { + /* Print the info message and exit. */ + INFO("You don't have permission to run."); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("Audit environment successful"); + + return; + } while (0); + + ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Get the value of the environment binary path file. + */ +const char * +env_getpath(const char *bin) +{ + + /* Local environment binary path file? */ + if (*(bin + 0) == '.' && *(bin + 1) == '/') + return bin; + + /* Global environment binary path file. */ + return SBIN_FILE; +} + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/env.h arpon-3.0-ng+dfsg1/src/env.h --- arpon-2.7.2/src/env.h 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/env.h 2016-01-29 02:00:04.000000000 +0000 @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: env.h,v 3.0-ng 01/29/2016 03:00:05 spikey Exp $ + */ + +#ifndef _ENV_H_ +#define _ENV_H_ + +/* + * Function prototypes exported. + */ +extern void env_audit(char **argv, char **envp); +extern const char *env_getpath(const char *bin); + +#endif /* !_ENV_H_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/exit.c arpon-3.0-ng+dfsg1/src/exit.c --- arpon-2.7.2/src/exit.c 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/exit.c 2016-01-29 02:04:36.000000000 +0000 @@ -0,0 +1,187 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: exit.c,v 3.0-ng 01/29/2016 03:04:38 spikey Exp $ + */ + +#include +#include +#include +#include +#include +#include + +#include "exit.h" +#include "msg.h" +#include "queue.h" +#include "thd.h" + +/* + * Exit callback stack structure definition. + */ +typedef struct exit_stack { + void (*callback)(void); /* Exit callback routine. */ + const char *name; /* Exit callback name. */ + + LIST_ENTRY(exit_stack) next; /* Next exit callback stack element. */ +} exit_t; + +/* + * Function prototype not exported. + */ +static void (*exit_pop(const char **name))(void); + +/* + * Initialize the exit callback stack structure. + */ +static LIST_HEAD(exit, exit_stack) exit_head = LIST_HEAD_INITIALIZER(exit_head); + +/* + * Push the exit callback stack element in the exit callback stack structure. + */ +void +exit_push(void (*callback)(void), const char *name) +{ + exit_t *new = NULL, *cur = NULL; + + /* Empty exit callback stack structure? */ + if (LIST_EMPTY(&exit_head) != 0) { + /* Set the exit callback stack structure to NULL. */ + LIST_INIT(&exit_head); + MSG_DEBUG("Initialize exit callback cleanup successful"); + } else { + /* Exit callback already previously pushed? */ + LIST_FOREACH(cur, &exit_head, next) { + if (strcmp(cur->name, name) == 0) { + /* Exit callback already pushed, therefore do nothing. */ + MSG_DEBUG("%s() exit callback already pushed", name); + return; + } + } + } + + /* Allocate the exit callback stack element. */ + if ((new = (exit_t *)malloc(sizeof(exit_t))) == NULL) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("exit_t *new allocate in the memory"); + + /* Initialize the exit callback routine. */ + new->callback = callback; + MSG_DEBUG("new->callback = %p", (void *)*new->callback); + + /* Initialize the exit callback name. */ + new->name = name; + MSG_DEBUG("new->name = %s", new->name); + + /* Push the exit callback stack element. */ + LIST_INSERT_HEAD(&exit_head, new, next); + + MSG_DEBUG("Push %s() exit callback successful", name); +} + +/* + * Cleanup all the exit callbacks from the exit callback + * stack structure and run each exit callback routine found. + */ +void +exit_cleanup(bool callexit) +{ + + MSG_DEBUG("Start exit callback cleanup"); + + /* Cleanup all the thread contexts. */ + thd_cleanup(); + + /* No empty exit callback stack structure? */ + if (LIST_EMPTY(&exit_head) == 0) { + /* Loop until the exit callback stack structure is empty. */ + do { + void (*callback)(void) = NULL; + const char *name = NULL; + + /* Pop the exit callback routine. */ + callback = exit_pop(&name); + MSG_DEBUG("Start cleanup %s() exit callback..", name); + + /* Run the exit callback routine. */ + callback(); + } while (LIST_EMPTY(&exit_head) == 0); + + /* Re-initialize the exit callback stack structure to NULL. */ + LIST_INIT(&exit_head); + } + + /* Need call exit()? */ + if (callexit == true) { + /* + * Call _exit() instead of exit() to no call + * any functions registered with atexit(). + */ + _exit(EXIT_SUCCESS); + } +} + +/* + * Pop the exit callback stack element from the exit callback stack structure. + */ +static void +(*exit_pop(const char **name))(void) +{ + exit_t *cur = NULL; + void (*callback)(void) = NULL; + + /* Get the first exit callback stack element. */ + cur = LIST_FIRST(&exit_head); + + /* Pop the first exit callback stack element. */ + LIST_REMOVE(cur, next); + + /* Get the exit callback routine. */ + callback = cur->callback; + MSG_DEBUG("cur->callback = %p", (void *)*callback); + + /* Get the exit callback name. */ + *name = cur->name; + MSG_DEBUG("cur->name = %s", *name); + + /* Deallocate the exit callback stack element. */ + free(cur); + + MSG_DEBUG("exit_t *cur deallocate from the memory"); + MSG_DEBUG("Pop %s() exit callback successful", *name); + + return callback; +} + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/exit.h arpon-3.0-ng+dfsg1/src/exit.h --- arpon-2.7.2/src/exit.h 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/exit.h 2016-01-29 02:00:24.000000000 +0000 @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: exit.h,v 3.0-ng 01/29/2016 03:00:25 spikey Exp $ + */ + +#ifndef _EXIT_H_ +#define _EXIT_H_ + +/* + * Function prototypes exported. + */ +extern void exit_push(void (*callback)(void), const char *name); +extern void exit_cleanup(bool callexit); + +#endif /* !_EXIT_H_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/harpi.c arpon-3.0-ng+dfsg1/src/harpi.c --- arpon-2.7.2/src/harpi.c 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/harpi.c 2016-01-29 02:05:43.000000000 +0000 @@ -0,0 +1,330 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: harpi.c,v 3.0-ng 01/29/2016 03:05:44 spikey Exp $ + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "arpca.h" +#include "darpica.h" +#include "harpi.h" +#include "intf.h" +#include "ispn.h" +#include "msg.h" +#include "opt.h" +#include "sarpica.h" +#include "unused.h" + +/* + * HARPI live capture handler of the I/O ARP packets + * read from the network traffic of the interface. + */ +void +harpi_handler(int op, struct ether_addr *macsrc, struct in_addr *ipsrc, + UNUSED(struct ether_addr *macdst), struct in_addr *ipdst) +{ + + do { + char smacsrc[INTF_ETHERSTRLEN], sipsrc[INET_ADDRSTRLEN], + UNUSED(smacdst[INTF_ETHERSTRLEN]), UNUSED(sipdst[INET_ADDRSTRLEN]), + *interface = NULL; + struct ether_addr *macentry = NULL; + + MSG_DEBUG("Start HARPI live capture handler"); + + /* Get the interface name command option. */ + interface = opt_getinterface(); + + /* MAC src addr network byte order to string. */ + strncpy(smacsrc, ether_ntoa(macsrc), INTF_ETHERSTRLEN); + + /* IP src addr network byte order to string. */ + strncpy(sipsrc, inet_ntoa(*ipsrc), INET_ADDRSTRLEN); + +#ifndef NDEBUG + /* MAC dst addr network byte order to string. */ + strncpy(smacdst, ether_ntoa(macdst), INTF_ETHERSTRLEN); + + /* IP dst addr network byte order to string. */ + strncpy(sipdst, inet_ntoa(*ipdst), INET_ADDRSTRLEN); +#endif /* !NDEBUG */ + + /* Check the type of the ARP packet read. */ + if (op & INTF_ARPOP_REQUEST) { + /* + * Check the I/O bound direction of the ARP request + * packet read (sent by us or sent to us). + */ + if (op & INTF_ARPOP_OUTBOUND) { + /* + * Check if the ARP request packet is a gratuitous + * ARP request packet, probe ARP request packet or + * simple ARP request packet. + */ + if (op & INTF_ARPOP_GRATUITOUS) { + /* Gratuitous ARP request packet to outbound. */ + INTF_OUTBOUND("Gratuitous ARP request"); + } else if (op & INTF_ARPOP_PROBE) { + /* Probe ARP request packet to outbound. */ + INTF_OUTBOUND("Probe ARP request"); + } else { + /* Simple ARP request packet to outbound. */ + INTF_OUTBOUND("ARP request"); + + /* + * Check if the destination IP address of the ARP + * request packet exists in the SARPI cache. + */ + if (sarpica_ismember(ipdst) == NULL) { + /* + * Add the entry in the DARPI cache + * with the destination IP address of the ARP + * request packet and the current local time. + */ + darpica_enqueue(ipdst); + } + } + + /* Break immediately. */ + break; + } else if (op & INTF_ARPOP_INBOUND) { + /* + * Check if the ARP request packet is a gratuitous + * ARP request packet, probe ARP request packet or + * simple ARP request packet. + */ + if (op & INTF_ARPOP_GRATUITOUS) { + /* Gratuitous ARP request packet from inbound. */ + INTF_INBOUND("Gratuitous ARP request"); + + /* + * Check if the source IP address of the ARP + * request packet exists in the SARPI cache. + */ + if ((macentry = sarpica_ismember(ipsrc)) == NULL) { + /* + * Send an ARP request to source IP (with MAC + * broadcast) address of the ARP request packet + * (in the next ARP packet read, follow the + * outbound ARP request). + */ + intf_inject(ARPOP_REQUEST, ipsrc); + } + } else if (op & INTF_ARPOP_PROBE) { + /* Probe ARP request packet from inbound. */ + INTF_INBOUND("Probe ARP request"); + + /* + * Send a probe ARP reply to source IP (with MAC + * broadcast) address of the ARP request packet + * (in the next ARP packet read, follow the + * outbound ARP reply). + */ + intf_inject(ARPOP_REPLY, ipsrc); + + /* Break immediately. */ + break; + } else { + /* Simple ARP request packet from inbound. */ + INTF_INBOUND("ARP request"); + + /* + * Check if the source IP address of the ARP + * request packet exists in the SARPI cache. + */ + if ((macentry = sarpica_ismember(ipsrc)) == NULL) { + /* + * Check if the source IP address of the ARP + * request packet exists in the DARPI cache. + */ + if (darpica_ismember(ipsrc) == false) { + /* + * Send an ARP request to source IP (with + * MAC broadcast) address of the ARP request + * packet (in the next ARP packet read, + * follow the outbound ARP request). + */ + intf_inject(ARPOP_REQUEST, ipsrc); + } + } + + /* + * Send an ARP reply to source IP (with MAC + * broadcast) address of the ARP request + * packet (in the next ARP packet read, + * follow the outbound ARP reply). + */ + intf_inject(ARPOP_REPLY, ipsrc); + } + } + } else if (op & INTF_ARPOP_REPLY) { + /* + * Check the I/O bound direction of the ARP reply + * packet read (sent by us or sent to us). + */ + if (op & INTF_ARPOP_OUTBOUND) { + /* + * Check if the ARP reply packet is a gratuitous + * ARP reply packet, probe ARP reply packet or + * simple ARP reply packet. + */ + if (op & INTF_ARPOP_GRATUITOUS) { + /* Gratuitous ARP reply packet to outbound. */ + INTF_OUTBOUND("Gratuitous ARP reply"); + } else if (op & INTF_ARPOP_PROBE) { + /* Probe ARP reply packet to outbound. */ + INTF_OUTBOUND("Probe ARP reply"); + } else { + /* Simple ARP reply packet to outbound. */ + INTF_OUTBOUND("ARP reply"); + } + + /* Break immediately. */ + break; + } else if (op & INTF_ARPOP_INBOUND) { + /* + * Check if the ARP reply packet is a gratuitous + * ARP reply packet, probe ARP reply packet or + * simple ARP reply packet. + */ + if (op & INTF_ARPOP_GRATUITOUS) { + /* Gratuitous ARP reply packet from inbound. */ + INTF_INBOUND("Gratuitous ARP reply"); + + /* + * Check if the source IP address of the ARP + * reply packet exists in the SARPI cache. + */ + macentry = sarpica_ismember(ipsrc); + } else if (op & INTF_ARPOP_PROBE) { + /* Probe ARP reply packet from inbound. */ + INTF_INBOUND("Probe ARP reply"); + + /* Break immediately. */ + break; + } else { + /* Simple ARP reply packet from inbound. */ + INTF_INBOUND("ARP reply"); + + /* + * Check if the source IP address of the ARP + * reply packet exists in the SARPI cache. + */ + if ((macentry = sarpica_ismember(ipsrc)) == NULL) { + /* + * Check if the source IP address of the ARP + * reply packet exists in the DARPI cache. + */ + if (darpica_ismember(ipsrc) == true) { + /* + * Delete the first or the only + * entry not expired from the DARPI cache + * of the source IP address of the ARP + * reply packet. + */ + darpica_dequeue(ipsrc); + + /* + * Overwrite the not permanent IP entry in the + * ARP cache of the source IP address of the ARP + * reply packet with the same source + * addresses (POLICY: ALLOW). + */ + arpca_overwrite(macsrc, ipsrc, ARPCA_NOTPERMANENT); + + /* Print the ALLOW policy info message. */ + ISPN_ALLOW(sipsrc, smacsrc); + + /* Break immediately. */ + break; + } + } + } + + /* + * Check if the source IP address of the ARP + * reply packet exists in the SARPI cache. + */ + if (macentry == NULL) { + /* + * Send an ARP request to source IP (with MAC + * broadcast) address of the ARP reply packet + * (in the next ARP packet read, follow the + * outbound ARP request). + */ + intf_inject(ARPOP_REQUEST, ipsrc); + } + } + } + + /* + * Check if the source IP address of the ARP packet exists + * in the SARPI cache. + */ + if (macentry == NULL) { + /* + * Delete the IP entry from the ARP cache of the source + * IP address of the ARP packet (POLICY: DENY). + */ + arpca_delete(ipsrc); + + /* Print the DENY policy info message. */ + ISPN_DENY(sipsrc, smacsrc); + } else { + char *smacentry = NULL; + + /* + * Overwrite the permanent IP entry in the ARP cache of the + * source IP address of the ARP packet with the + * entry from the SARPI cache (POLICY: REFRESH). + */ + arpca_overwrite(macentry, ipsrc, ARPCA_PERMANENT); + + /* MAC entry addr network byte order to string. */ + smacentry = ether_ntoa(macentry); + + /* Print the REFRESH policy info message. */ + ISPN_REFRESH(sipsrc, smacentry); + } + } while (0); + + MSG_DEBUG("End HARPI live capture handler"); +} + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/harpi.h arpon-3.0-ng+dfsg1/src/harpi.h --- arpon-2.7.2/src/harpi.h 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/harpi.h 2016-01-29 02:07:03.000000000 +0000 @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: harpi.h,v 3.0-ng 01/29/2016 03:07:04 spikey Exp $ + */ + +#ifndef _HARPI_H_ +#define _HARPI_H_ + +/* + * Function prototype exported. + */ +extern void harpi_handler(int op, struct ether_addr *macsrc, + struct in_addr *ipsrc, struct ether_addr *macdst, struct in_addr *ipdst); + +#endif /* !_HARPI_H_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/include/queue.h arpon-3.0-ng+dfsg1/src/include/queue.h --- arpon-2.7.2/src/include/queue.h 2008-06-23 20:33:05.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/include/queue.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,483 +0,0 @@ -/* - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)queue.h 8.5 (Berkeley) 8/20/94 - */ - -#ifndef _SYS_QUEUE_H_ -#define _SYS_QUEUE_H_ - -/* - * This file defines five types of data structures: singly-linked lists, - * slingly-linked tail queues, lists, tail queues, and circular queues. - * - * A singly-linked list is headed by a single forward pointer. The elements - * are singly linked for minimum space and pointer manipulation overhead at - * the expense of O(n) removal for arbitrary elements. New elements can be - * added to the list after an existing element or at the head of the list. - * Elements being removed from the head of the list should use the explicit - * macro for this purpose for optimum efficiency. A singly-linked list may - * only be traversed in the forward direction. Singly-linked lists are ideal - * for applications with large datasets and few or no removals or for - * implementing a LIFO queue. - * - * A singly-linked tail queue is headed by a pair of pointers, one to the - * head of the list and the other to the tail of the list. The elements are - * singly linked for minimum space and pointer manipulation overhead at the - * expense of O(n) removal for arbitrary elements. New elements can be added - * to the list after an existing element, at the head of the list, or at the - * end of the list. Elements being removed from the head of the tail queue - * should use the explicit macro for this purpose for optimum efficiency. - * A singly-linked tail queue may only be traversed in the forward direction. - * Singly-linked tail queues are ideal for applications with large datasets - * and few or no removals or for implementing a FIFO queue. - * - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before - * or after an existing element or at the head of the list. A list - * may only be traversed in the forward direction. - * - * A tail queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or - * after an existing element, at the head of the list, or at the end of - * the list. A tail queue may only be traversed in the forward direction. - * - * A circle queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or after - * an existing element, at the head of the list, or at the end of the list. - * A circle queue may be traversed in either direction, but has a more - * complex end of list detection. - * - * For details on the use of these macros, see the queue(3) manual page. - * - * - * SLIST LIST STAILQ TAILQ CIRCLEQ - * _HEAD + + + + + - * _ENTRY + + + + + - * _INIT + + + + + - * _EMPTY + + + + + - * _FIRST + + + + + - * _NEXT + + + + + - * _PREV - - - + + - * _LAST - - + + + - * _FOREACH + + - + + - * _INSERT_HEAD + + + + + - * _INSERT_BEFORE - + - + + - * _INSERT_AFTER + + + + + - * _INSERT_TAIL - - + + + - * _REMOVE_HEAD + - + - - - * _REMOVE + + + + + - * - */ - -/* - * Singly-linked List definitions. - */ -#define SLIST_HEAD(name, type) \ -struct name { \ - struct type *slh_first; /* first element */ \ -} - -#define SLIST_ENTRY(type) \ -struct { \ - struct type *sle_next; /* next element */ \ -} - -/* - * Singly-linked List functions. - */ -#define SLIST_EMPTY(head) ((head)->slh_first == NULL) - -#define SLIST_FIRST(head) ((head)->slh_first) - -#define SLIST_FOREACH(var, head, field) \ - for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next) - -#define SLIST_INIT(head) { \ - (head)->slh_first = NULL; \ -} - -#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ - (elm)->field.sle_next = (slistelm)->field.sle_next; \ - (slistelm)->field.sle_next = (elm); \ -} while (0) - -#define SLIST_INSERT_HEAD(head, elm, field) do { \ - (elm)->field.sle_next = (head)->slh_first; \ - (head)->slh_first = (elm); \ -} while (0) - -#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) - -#define SLIST_REMOVE_HEAD(head, field) do { \ - (head)->slh_first = (head)->slh_first->field.sle_next; \ -} while (0) - -#define SLIST_REMOVE(head, elm, type, field) do { \ - if ((head)->slh_first == (elm)) { \ - SLIST_REMOVE_HEAD((head), field); \ - } \ - else { \ - struct type *curelm = (head)->slh_first; \ - while( curelm->field.sle_next != (elm) ) \ - curelm = curelm->field.sle_next; \ - curelm->field.sle_next = \ - curelm->field.sle_next->field.sle_next; \ - } \ -} while (0) - -/* - * Singly-linked Tail queue definitions. - */ -#define STAILQ_HEAD(name, type) \ -struct name { \ - struct type *stqh_first;/* first element */ \ - struct type **stqh_last;/* addr of last next element */ \ -} - -#define STAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).stqh_first } - -#define STAILQ_ENTRY(type) \ -struct { \ - struct type *stqe_next; /* next element */ \ -} - -/* - * Singly-linked Tail queue functions. - */ -#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) - -#define STAILQ_INIT(head) do { \ - (head)->stqh_first = NULL; \ - (head)->stqh_last = &(head)->stqh_first; \ -} while (0) - -#define STAILQ_FIRST(head) ((head)->stqh_first) -#define STAILQ_LAST(head) (*(head)->stqh_last) - -#define STAILQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \ - (head)->stqh_last = &(elm)->field.stqe_next; \ - (head)->stqh_first = (elm); \ -} while (0) - -#define STAILQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.stqe_next = NULL; \ - *(head)->stqh_last = (elm); \ - (head)->stqh_last = &(elm)->field.stqe_next; \ -} while (0) - -#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ - if (((elm)->field.stqe_next = (tqelm)->field.stqe_next) == NULL)\ - (head)->stqh_last = &(elm)->field.stqe_next; \ - (tqelm)->field.stqe_next = (elm); \ -} while (0) - -#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) - -#define STAILQ_REMOVE_HEAD(head, field) do { \ - if (((head)->stqh_first = \ - (head)->stqh_first->field.stqe_next) == NULL) \ - (head)->stqh_last = &(head)->stqh_first; \ -} while (0) - -#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \ - if (((head)->stqh_first = (elm)->field.stqe_next) == NULL) \ - (head)->stqh_last = &(head)->stqh_first; \ -} while (0) - - -#define STAILQ_REMOVE(head, elm, type, field) do { \ - if ((head)->stqh_first == (elm)) { \ - STAILQ_REMOVE_HEAD(head, field); \ - } \ - else { \ - struct type *curelm = (head)->stqh_first; \ - while( curelm->field.stqe_next != (elm) ) \ - curelm = curelm->field.stqe_next; \ - if((curelm->field.stqe_next = \ - curelm->field.stqe_next->field.stqe_next) == NULL) \ - (head)->stqh_last = &(curelm)->field.stqe_next; \ - } \ -} while (0) - -/* - * List definitions. - */ -#define LIST_HEAD(name, type) \ -struct name { \ - struct type *lh_first; /* first element */ \ -} - -#define LIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define LIST_ENTRY(type) \ -struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ -} - -/* - * List functions. - */ - -#define LIST_EMPTY(head) ((head)->lh_first == NULL) - -#define LIST_FIRST(head) ((head)->lh_first) - -#define LIST_FOREACH(var, head, field) \ - for((var) = (head)->lh_first; (var); (var) = (var)->field.le_next) - -#define LIST_INIT(head) do { \ - (head)->lh_first = NULL; \ -} while (0) - -#define LIST_INSERT_AFTER(listelm, elm, field) do { \ - if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ - (listelm)->field.le_next->field.le_prev = \ - &(elm)->field.le_next; \ - (listelm)->field.le_next = (elm); \ - (elm)->field.le_prev = &(listelm)->field.le_next; \ -} while (0) - -#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.le_prev = (listelm)->field.le_prev; \ - (elm)->field.le_next = (listelm); \ - *(listelm)->field.le_prev = (elm); \ - (listelm)->field.le_prev = &(elm)->field.le_next; \ -} while (0) - -#define LIST_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.le_next = (head)->lh_first) != NULL) \ - (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ - (head)->lh_first = (elm); \ - (elm)->field.le_prev = &(head)->lh_first; \ -} while (0) - -#define LIST_NEXT(elm, field) ((elm)->field.le_next) - -#define LIST_REMOVE(elm, field) do { \ - if ((elm)->field.le_next != NULL) \ - (elm)->field.le_next->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = (elm)->field.le_next; \ -} while (0) - -/* - * Tail queue definitions. - */ -#define TAILQ_HEAD(name, type) \ -struct name { \ - struct type *tqh_first; /* first element */ \ - struct type **tqh_last; /* addr of last next element */ \ -} - -#define TAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first } - -#define TAILQ_ENTRY(type) \ -struct { \ - struct type *tqe_next; /* next element */ \ - struct type **tqe_prev; /* address of previous next element */ \ -} - -/* - * Tail queue functions. - */ -#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) - -#define TAILQ_FOREACH(var, head, field) \ - for (var = TAILQ_FIRST(head); var; var = TAILQ_NEXT(var, field)) - -#define TAILQ_FOREACH_REVERSE(var, head, field, headname) \ - for (var = TAILQ_LAST(head, headname); \ - var; var = TAILQ_PREV(var, headname, field)) - -#define TAILQ_FIRST(head) ((head)->tqh_first) - -#define TAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) - -#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) - -#define TAILQ_PREV(elm, headname, field) \ - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) - -#define TAILQ_INIT(head) do { \ - (head)->tqh_first = NULL; \ - (head)->tqh_last = &(head)->tqh_first; \ -} while (0) - -#define TAILQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ - (head)->tqh_first->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (head)->tqh_first = (elm); \ - (elm)->field.tqe_prev = &(head)->tqh_first; \ -} while (0) - -#define TAILQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.tqe_next = NULL; \ - (elm)->field.tqe_prev = (head)->tqh_last; \ - *(head)->tqh_last = (elm); \ - (head)->tqh_last = &(elm)->field.tqe_next; \ -} while (0) - -#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ - (elm)->field.tqe_next->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (listelm)->field.tqe_next = (elm); \ - (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ -} while (0) - -#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ - (elm)->field.tqe_next = (listelm); \ - *(listelm)->field.tqe_prev = (elm); \ - (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ -} while (0) - -#define TAILQ_REMOVE(head, elm, field) do { \ - if (((elm)->field.tqe_next) != NULL) \ - (elm)->field.tqe_next->field.tqe_prev = \ - (elm)->field.tqe_prev; \ - else \ - (head)->tqh_last = (elm)->field.tqe_prev; \ - *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ -} while (0) - -/* - * Circular queue definitions. - */ -#define CIRCLEQ_HEAD(name, type) \ -struct name { \ - struct type *cqh_first; /* first element */ \ - struct type *cqh_last; /* last element */ \ -} - -#define CIRCLEQ_ENTRY(type) \ -struct { \ - struct type *cqe_next; /* next element */ \ - struct type *cqe_prev; /* previous element */ \ -} - -/* - * Circular queue functions. - */ -#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head)) - -#define CIRCLEQ_FIRST(head) ((head)->cqh_first) - -#define CIRCLEQ_FOREACH(var, head, field) \ - for((var) = (head)->cqh_first; \ - (var) != (void *)(head); \ - (var) = (var)->field.cqe_next) - -#define CIRCLEQ_INIT(head) do { \ - (head)->cqh_first = (void *)(head); \ - (head)->cqh_last = (void *)(head); \ -} while (0) - -#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - (elm)->field.cqe_next = (listelm)->field.cqe_next; \ - (elm)->field.cqe_prev = (listelm); \ - if ((listelm)->field.cqe_next == (void *)(head)) \ - (head)->cqh_last = (elm); \ - else \ - (listelm)->field.cqe_next->field.cqe_prev = (elm); \ - (listelm)->field.cqe_next = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ - (elm)->field.cqe_next = (listelm); \ - (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ - if ((listelm)->field.cqe_prev == (void *)(head)) \ - (head)->cqh_first = (elm); \ - else \ - (listelm)->field.cqe_prev->field.cqe_next = (elm); \ - (listelm)->field.cqe_prev = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ - (elm)->field.cqe_next = (head)->cqh_first; \ - (elm)->field.cqe_prev = (void *)(head); \ - if ((head)->cqh_last == (void *)(head)) \ - (head)->cqh_last = (elm); \ - else \ - (head)->cqh_first->field.cqe_prev = (elm); \ - (head)->cqh_first = (elm); \ -} while (0) - -#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.cqe_next = (void *)(head); \ - (elm)->field.cqe_prev = (head)->cqh_last; \ - if ((head)->cqh_first == (void *)(head)) \ - (head)->cqh_first = (elm); \ - else \ - (head)->cqh_last->field.cqe_next = (elm); \ - (head)->cqh_last = (elm); \ -} while (0) - -#define CIRCLEQ_LAST(head) ((head)->cqh_last) - -#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next) - -#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev) - -#define CIRCLEQ_REMOVE(head, elm, field) do { \ - if ((elm)->field.cqe_next == (void *)(head)) \ - (head)->cqh_last = (elm)->field.cqe_prev; \ - else \ - (elm)->field.cqe_next->field.cqe_prev = \ - (elm)->field.cqe_prev; \ - if ((elm)->field.cqe_prev == (void *)(head)) \ - (head)->cqh_first = (elm)->field.cqe_next; \ - else \ - (elm)->field.cqe_prev->field.cqe_next = \ - (elm)->field.cqe_next; \ -} while (0) - - -#endif /* !_SYS_QUEUE_H_ */ diff -Nru arpon-2.7.2/src/intf.c arpon-3.0-ng+dfsg1/src/intf.c --- arpon-2.7.2/src/intf.c 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/intf.c 2016-01-29 02:00:42.000000000 +0000 @@ -0,0 +1,1137 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: intf.c,v 3.0-ng 01/29/2016 03:00:44 spikey Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "exit.h" +#include "intf.h" +#include "ispn.h" +#include "msg.h" +#include "opt.h" +#include "thd.h" +#include "unused.h" + +/* + * Any device. + */ +#define INTF_ANYDEV "any" + +/* + * Nflog device. + */ +#define INTF_NFLOGDEV "nflog" + +/* + * Nfqueue device. + */ +#define INTF_NFQUEUEDEV "nfqueue" + +/* + * Ethernet header (14 bytes) + ARP header (28 bytes) total length. + */ +#define INTF_HDRLEN sizeof(struct ether_header) + \ + sizeof(struct ether_arp) +/* + * Snapshot capture length. + */ +#define INTF_SNAPLEN (int)INTF_HDRLEN /* 14 + 28 = 42 bytes. */ + +/* + * Promiscuous mode. + */ +#define INTF_PROMISC 0 /* Disabled. */ + +/* + * Read capture timeout. + */ +#define INTF_READTIMEOUT 1 /* 1 millisecond. */ + +/* + * Buffer capture size. + */ +#define INTF_BUFFERSIZE 16 * 1024 * 1024 /* 16 MiB. */ + +/* + * Non-blocking mode. + */ +#define INTF_NONBLOCKING 1 /* Enabled. */ + +/* + * Ethernet datalink. + */ +#define INTF_ETHDATALINK DLT_EN10MB + +/* + * Loop suspend timeout. + */ +#define INTF_LOOPTIMEOUT 5 /* 5 seconds. */ + +/* + * ARP filter. + */ +#define INTF_ARPFILTER "arp" + +/* + * No seconds. + */ +#define INTF_SECS 0 + +/* + * Milliseconds to microseconds. + */ +#define INTF_MILLI2MICRO(x) x * 1000 + +/* + * Live capture counter. + */ +#define INTF_LOOPCOUNT -1 /* All ARP packets received. */ + +/* + * IP address length. + */ +#define INTF_IP_ALEN 4 /* 4 bytes. */ + +/* + * All IP addresses. + */ +#define INTF_IPZEROSTRADDR "0.0.0.0" + +/* + * MAC broadcast address. + */ +#define INTF_MACBROSTRADDR "ff:ff:ff:ff:ff:ff" + +/* + * ARP operation type to string. + */ +#define INTF_ATOA(x) x == ARPOP_REQUEST ? "ARP request" : "ARP reply" + +/* + * Interface config structure definition. + */ +typedef struct intf_config { + /* Pcap configuration on the interface. */ + pcap_t *pcap; /* Pcap capture handle. */ + char pcap_errbuf[PCAP_ERRBUF_SIZE]; /* Pcap error buffer. */ + + /* Libnet configuration on the interface. */ + libnet_t *lnet; /* Libnet network handle. */ + char lnet_errbuf[LIBNET_ERRBUF_SIZE]; /* Libnet error buffer. */ + + /* Interface configuration. */ + struct ether_addr mac; /* Interface MAC addr config. */ + struct in_addr ip; /* Interface IP addr config. */ + struct in_addr network; /* Interface Net addr config. */ + struct in_addr netmask; /* Interface Mask addr config. */ +} intf_t; + +/* + * Function prototypes not exported. + */ +static void intf_autoconfinterface(char *interface); +static void intf_init(void); +static void intf_destroy(void); +static int intf_isvalidinterface(char *interface); +static void intf_setmac(char *interface); +static int intf_setip(char *interface); +static void intf_setarpfilter(void); +static void intf_decoder(unsigned char *callback, + const struct pcap_pkthdr *header, const unsigned char *bytes); + +/* + * Initialize the interface config structure. + */ +static intf_t *cfg = NULL; + +/* + * Initialize and configure the interface. + */ +void +intf_configure(void) +{ + char *interface = NULL; + + MSG_DEBUG("Start configure interface"); + + /* No specified interface name command option? */ + if (*((interface = opt_getinterface()) + 0) == '\0') { + /* Print the info message and exit. */ + MSG_WARN("No specified network interface"); + exit(EXIT_FAILURE); + } + + /* Autoconf the specified interface name. */ + intf_autoconfinterface(interface); + + /* Set the ARP filter on the interface. */ + intf_setarpfilter(); + + MSG_DEBUG("End configure interface"); +} + +/* + * Autoconf the interface name from the command option structure. + */ +static void +intf_autoconfinterface(char *interface) +{ + + MSG_DEBUG("Autoconf %s network interface..", interface); + + /* + * Loop until the interface is found and MAC addr, + * IP addr, Net and Mask addrs are available. + */ + while (1) { + /* Initialize the interface config structure. */ + intf_init(); + + do { + /* No valid specified interface name? */ + if (intf_isvalidinterface(interface) < 0) + break; + + /* Set the interface MAC addr config. */ + intf_setmac(interface); + + /* Set the interface IP addrs config. */ + if (intf_setip(interface) < 0) + break; + + MSG_DEBUG("Autoconf %s network interface successful", interface); + + return; + } while (0); + + /* Destroy the interface config structure. */ + intf_destroy(); + + MSG_WARN("No autoconf %s network interface, retry in 5 seconds..", + interface); + + /* Suspend the execution of the thread for 5 seconds. */ + thd_suspend(INTF_LOOPTIMEOUT); + + /* Loop again. */ + continue; + } +} + +/* + * Initialize the interface config structure. + */ +static void +intf_init(void) +{ + + /* Allocate the interface config structure. */ + if ((cfg = (intf_t *)malloc(sizeof(intf_t))) == NULL) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("intf_t *cfg allocate in the memory"); + + /* Initialize the pcap capture handle. */ + cfg->pcap = NULL; + MSG_DEBUG("cfg->pcap = NULL"); + + /* Initialize the pcap error buffer. */ + memset(&cfg->pcap_errbuf, '\0', (size_t)PCAP_ERRBUF_SIZE); + MSG_DEBUG("cfg->pcap_errbuf = \\0"); + + /* Initialize the libnet network handle. */ + cfg->lnet = NULL; + MSG_DEBUG("cfg->lnet = NULL"); + + /* Initialize the libnet error buffer. */ + memset(&cfg->lnet_errbuf, '\0', (size_t)LIBNET_ERRBUF_SIZE); + MSG_DEBUG("cfg->lnet_errbuf = \\0"); + + /* Initialize the interface MAC addr config. */ + memset(&cfg->mac, 0, sizeof(cfg->mac)); + MSG_DEBUG("cfg->mac = 0:0:0:0:0:0"); + + /* Initialize the interface IP addr config. */ + memset(&cfg->ip, 0, sizeof(cfg->ip)); + MSG_DEBUG("cfg->ip = 0.0.0.0"); + + /* Initialize the interface Net addr config. */ + memset(&cfg->network, 0, sizeof(cfg->network)); + MSG_DEBUG("cfg->network = 0.0.0.0"); + + /* Initialize the interface Mask addr config. */ + memset(&cfg->netmask, 0, sizeof(cfg->netmask)); + MSG_DEBUG("cfg->netmask = 0.0.0.0"); + + /* Push intf_destroy() to be called on exit_cleanup(). */ + exit_push(intf_destroy, "intf_destroy"); +} + +/* + * Destroy the interface config structure. + */ +static void +intf_destroy(void) +{ + + /* Interface config structure previously allocated? */ + if (cfg != NULL) { + /* Pcap capture handle had never been open? */ + if (cfg->pcap != NULL) { + struct pcap_stat UNUSED(stat); + +#ifndef NDEBUG + /* Get the captured (and not) packets statistics. */ + if (pcap_stats(cfg->pcap, &stat) < 0) { + MSG_ERROR("%s", pcap_geterr(cfg->pcap)); + exit(EXIT_FAILURE); + } +#endif /* !NDEBUG */ + + MSG_DEBUG("Packets received by filter = %u", stat.ps_recv); + MSG_DEBUG("Packets dropped by kernel = %u", stat.ps_drop); + MSG_DEBUG("Packets dropped by interface = %u", stat.ps_ifdrop); + + /* Close the pcap capture handle. */ + pcap_close(cfg->pcap); + + /* Set the pcap capture handle to NULL. */ + cfg->pcap = NULL; + + MSG_DEBUG("Close cfg->pcap successful"); + } + + /* Libnet network handle had never been initialized? */ + if (cfg->lnet != NULL) { + /* Destroy the libnet network handle. */ + libnet_destroy(cfg->lnet); + + /* Set the libnet network handle to NULL. */ + cfg->lnet = NULL; + + MSG_DEBUG("Destroy cfg->lnet successful"); + } + + /* Deallocate the interface config structure. */ + free(cfg); + + /* Set the interface config structure to NULL. */ + cfg = NULL; + + MSG_DEBUG("intf_t *cfg deallocate from the memory"); + } +} + +/* + * Validate the interface name from the command option structure. + */ +static int +intf_isvalidinterface(char *interface) +{ + + do { + pcap_if_t *alldevs = NULL, *dev = NULL; + int snapshot; + bool valid = false; + + /* Allocate and set the list of interfaces that can be open by pcap. */ + if (pcap_findalldevs(&alldevs, cfg->pcap_errbuf) < 0) + break; + + /* No interfaces that can be open by pcap? */ + if (alldevs == NULL) { + /* Print the info message and exit. */ + MSG_DEBUG("No exist network interface in the system"); + return -1; + } + + /* Walk through the list of interfaces that can be open by pcap. */ + for (dev = alldevs; dev != NULL; dev = dev->next) { + /* Skip the pseudo interfaces. */ + if (strcmp(dev->name, INTF_ANYDEV) == 0 || + strcmp(dev->name, INTF_NFLOGDEV) == 0 || + strcmp(dev->name, INTF_NFQUEUEDEV) == 0) { + continue; + } + + /* Skip the loopback interface. */ + if ((dev->flags & PCAP_IF_LOOPBACK) != 0) + continue; + + /* Valid specified interface name for pcap? */ + if (strncmp(interface, dev->name, (size_t)IF_NAMESIZE) == 0) { + /* Valid specified interface name for pcap. */ + valid = true; + break; + } + } + + /* No valid specified interface name for pcap? */ + if (valid == false) { + MSG_DEBUG("No valid specified network interface"); + + /* Deallocate the list of interfaces that can be open by pcap. */ + pcap_freealldevs(alldevs); + + return -1; + } + + /* Create the pcap capture handle to look at packets on the network. */ + if ((cfg->pcap = pcap_create(interface, cfg->pcap_errbuf)) == NULL) + break; + + MSG_DEBUG("interface = %s", interface); + + /* Set the snapshot capture length to 42 bytes. */ + if (pcap_set_snaplen(cfg->pcap, INTF_SNAPLEN) < 0) { + MSG_ERROR("No set snaplen to %s network interface", interface); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("snaplen = %d", INTF_SNAPLEN); + + /* Disable the promiscuous mode on the interface. */ + if (pcap_set_promisc(cfg->pcap, INTF_PROMISC) < 0) { + MSG_ERROR("No disable promisc to %s network interface", interface); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("promisc = %d", INTF_PROMISC); + + /* Set the read capture timeout to 1 millisecond. */ + if (pcap_set_timeout(cfg->pcap, INTF_READTIMEOUT) < 0) { + MSG_ERROR("No set timeout to %s network interface", interface); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("read_timeout = %d", INTF_READTIMEOUT); + + /* Set the buffer capture size to 16 MiB. */ + if (pcap_set_buffer_size(cfg->pcap, INTF_BUFFERSIZE) < 0) { + MSG_ERROR("No set buffer size to %s network interface", interface); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("buffer_size = %d", INTF_BUFFERSIZE); + + /* Activate the pcap capture handle. */ + if (pcap_activate(cfg->pcap) < 0) { + MSG_ERROR("No activate %s network interface", interface); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("Activate cfg->pcap successful"); + + /* Get the snapshot capture length. */ + if ((snapshot = pcap_snapshot(cfg->pcap)) < 0) { + MSG_ERROR("No get snapshot from %s network interface", interface); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("snapshot = %d", snapshot); + + /* Assigned shapshot is the same of our snapshot? */ + if (snapshot != INTF_SNAPLEN) { + MSG_ERROR("No assigned snaplen to %s network interface", interface); + exit(EXIT_FAILURE); + } + + /* Valid Ethernet link-layer header type for the live capture? */ + if (pcap_datalink(cfg->pcap) != INTF_ETHDATALINK) { + MSG_WARN("No Ethernet specified network interface"); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("type = Ethernet/Wi-Fi"); + + /* Enable the non-blocking mode. */ + if (pcap_setnonblock(cfg->pcap, INTF_NONBLOCKING, cfg->pcap_errbuf) < 0) + break; + + MSG_DEBUG("non-blocking = %d", INTF_NONBLOCKING); + + /* Deallocate the list of interfaces that can be open by pcap. */ + pcap_freealldevs(alldevs); + + MSG_DEBUG("%s network interface is valid", interface); + + return 0; + } while (0); + + MSG_ERROR("%s", cfg->pcap_errbuf); + exit(EXIT_FAILURE); +} + +/* + * Set the value of the interface MAC addr in the interface config structure. + */ +static void +intf_setmac(char *interface) +{ + struct libnet_ether_addr *mac = NULL; + + /* Initialize the libnet network handle. */ + if ((cfg->lnet = libnet_init( + LIBNET_LINK, /* Link layer interface. */ + interface, /* Specified interface. */ + cfg->lnet_errbuf)) == NULL) { + MSG_ERROR("%s", cfg->lnet_errbuf); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("Initialize cfg->lnet successful"); + + /* Get the interface MAC addr to libnet. */ + if ((mac = libnet_get_hwaddr(cfg->lnet)) == NULL) { + MSG_ERROR("%s", libnet_geterror(cfg->lnet)); + exit(EXIT_FAILURE); + } + + /* MAC addr available. */ + MSG_DEBUG("MAC address available on the network interface"); + + /* Set the value of the interface MAC addr config. */ + memcpy(&cfg->mac.ether_addr_octet, mac->ether_addr_octet, (size_t)ETH_ALEN); + MSG_DEBUG("cfg->mac = %s", ether_ntoa(&cfg->mac)); +} + +/* + * Set the value of the interface IP addrs in the interface config structure. + */ +static int +intf_setip(char *interface) +{ + uint32_t ip, network, netmask; + + /* Get the interface IP addr to libnet. */ + if ((ip = libnet_get_ipaddr4(cfg->lnet)) == (uint32_t)-1) { + /* No IP addr available? */ + if (errno == EADDRNOTAVAIL) { + MSG_WARN("No IP address available"); + return -1; + } else { + MSG_ERROR("%s", libnet_geterror(cfg->lnet)); + exit(EXIT_FAILURE); + } + } + + /* IP addr available. */ + MSG_DEBUG("IP address available on the network interface"); + + /* Get the interface Net and Mask addrs to pcap. */ + if (pcap_lookupnet( + interface, /* Specified interface. */ + &network, /* Net addr. */ + &netmask, /* Mask addr. */ + cfg->pcap_errbuf) < 0) { + /* No Net and Mask addrs available? */ + if (errno == EADDRNOTAVAIL) { + MSG_WARN("No Net and Mask addresses available"); + return -1; + } else { + MSG_ERROR("%s", cfg->pcap_errbuf); + exit(EXIT_FAILURE); + } + } + + /* Net and Mask addrs available. */ + MSG_DEBUG("Net and Mask addresses available on the network interface"); + + /* Set the value of the interface IP addr config. */ + cfg->ip.s_addr = ip; + MSG_DEBUG("cfg->ip = %s", inet_ntoa(cfg->ip)); + + /* Set the value of the interface Net addr config. */ + cfg->network.s_addr = network; + MSG_DEBUG("cfg->network = %s", inet_ntoa(cfg->network)); + + /* Set the value of the interface Mask addr config. */ + cfg->netmask.s_addr = netmask; + MSG_DEBUG("cfg->netmask = %s", inet_ntoa(cfg->netmask)); + + return 0; +} + +/* + * Get the value of the interface Net addr from the interface config structure. + */ +struct in_addr * +intf_getnetwork(void) +{ + + MSG_DEBUG("cfg->network = %s", inet_ntoa(cfg->network)); + + /* Get the value of the interface Net addr config. */ + return &cfg->network; +} + +/* + * Get the value of the interface Mask addr from the interface config structure. + */ +struct in_addr * +intf_getnetmask(void) +{ + + MSG_DEBUG("cfg->netmask = %s", inet_ntoa(cfg->netmask)); + + /* Get the value of the interface Mask addr config. */ + return &cfg->netmask; +} + +/* + * Set the ARP filter on the interface. + */ +static void +intf_setarpfilter(void) +{ + + do { + struct bpf_program bpf; + + /* Compile the ARP string filter and allocate the ARP filter program. */ + if (pcap_compile( + cfg->pcap, + &bpf, /* ARP filter program. */ + INTF_ARPFILTER, /* ARP string filter. */ + 0, /* Not optimized. */ + cfg->netmask.s_addr) < 0) { + break; + } + + /* Set the compiled ARP filter program on the interface. */ + if (pcap_setfilter(cfg->pcap, &bpf) < 0) + break; + + /* Deallocate the ARP filter program. */ + pcap_freecode(&bpf); + + MSG_DEBUG("Set ARP filter on the network interface successful"); + + return; + } while (0); + + MSG_ERROR("%s", pcap_geterr(cfg->pcap)); + exit(EXIT_FAILURE); +} + +/* + * Live capture of the I/O ARP packets read from the network traffic + * of the interface and run the live capture decoder callback routine. + */ +void * +intf_capture(void *callback) +{ + struct timeval timeout; + int fd; + + /* Initialize the thread. */ + thd_init(); + + MSG_DEBUG("Capture on %s..", opt_getinterface()); + + /* Get the pcap capture handle file descriptor. */ + if ((fd = pcap_get_selectable_fd(cfg->pcap)) < 0) { + MSG_ERROR("No selectable file descriptor from pcap"); + exit(EXIT_FAILURE); + } + + /* Set the read capture timeout to 1 millisecond. */ + timeout.tv_sec = INTF_SECS; /* No seconds. */ + timeout.tv_usec = INTF_MILLI2MICRO(INTF_READTIMEOUT); + + /* + * Loop until the network traffic of the interface is up. + * This loop uses select + pcap in order to process the + * I/O asynchronous ARP packets read from the buffer. + */ + while (1) { + fd_set fdread; + + /* Clear the set. */ + FD_ZERO(&fdread); + + /* Add the pcap capture handle file descriptor to set. */ + FD_SET(fd, &fdread); + + /* + * Monitor the pcap capture handle file descriptor + * until it becomes ready for the reading. + */ + if (select(fd + 1, &fdread, NULL, NULL, &timeout) < 0) { + /* Interrupt signal? */ + if (errno == EINTR) { + /* Loop again with the time remaining calculated by select. */ + continue; + } + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } + + /* Pcap capture handle file descriptor is ready to reading? */ + if (FD_ISSET(fd, &fdread) != 0) { + /* + * Process the live capture from the network traffic (read from + * the buffer) and run the live capture decoder callback routine. + */ + if (pcap_dispatch( + cfg->pcap, + INTF_LOOPCOUNT, /* Live capture counter to all the packets + * received into buffer to be processed. */ + intf_decoder, /* Live capture decoder callback routine. */ + callback) < 0) { /* ARP Inspection live capture + * handler callback routine. */ + /* Network of the interface down? */ + if (errno == ENETDOWN) { + MSG_WARN("Network is down, wait for 5 seconds.."); + + /* Suspend the execution of the thread for 5 seconds. */ + thd_suspend(INTF_LOOPTIMEOUT); + + MSG_DEBUG("Send a hangup signal to ourself"); + + /* Request to ourself the reboot of ArpON. */ + kill(getpid(), SIGHUP); + } else { + MSG_ERROR("%s", pcap_geterr(cfg->pcap)); + exit(EXIT_FAILURE); + } + } + } + + /* Re-set the read capture timeout to 1 millisecond. */ + timeout.tv_sec = INTF_SECS; /* No seconds. */ + timeout.tv_usec = INTF_MILLI2MICRO(INTF_READTIMEOUT); + } + + /* Never reaches here. */ + return NULL; +} + +/* + * Live capture decoder of the I/O ARP packets read from + * the network traffic of the interface and run the ARP + * Inspection live capture handler callback routine. + */ +static void +intf_decoder(unsigned char *callback, const struct pcap_pkthdr *header, + const unsigned char *bytes) +{ + + do { + const struct ether_header *heth = NULL; + const struct ether_arp *harp = NULL; + struct ether_addr macsrc, macdst; + struct in_addr ipzero, ipsrc, ipdst; + void (*handler)(int, struct ether_addr *, struct in_addr *, + struct ether_addr *, struct in_addr *) = NULL; + int op; + + MSG_DEBUG("Start live capture decoder"); + + /* Skip the malformed ARP packet read. */ + if (header->caplen > header->len || header->caplen > INTF_SNAPLEN) { + MSG_DEBUG("Skip the malformed ARP packet read"); + + /* Break immediately. */ + break; + } + + /* Skip the truncated ARP packet read. */ + if (header->caplen < sizeof(*heth) + sizeof(*harp)) { + MSG_DEBUG("Skip the truncated ARP packet read"); + + /* Break immediately. */ + break; + } + + /* Extract the Etherner header from the bytes. */ + heth = (const struct ether_header *)bytes; + + /* Extract the ARP header and ARP addresses from the bytes. */ + harp = (const struct ether_arp *)(heth + 1); + + /* Skip the ARP packet read that isn't a request or reply. */ + if (ntohs(heth->ether_type) != ETHERTYPE_ARP && /* ARP. */ + ntohs(harp->arp_hrd) != ARPHRD_ETHER && /* Eth addr format. */ + ntohs(harp->arp_pro) != ETHERTYPE_IP && /* IP addr format. */ + ntohs(harp->arp_hln) != ETH_ALEN && /* Eth addr len. */ + ntohs(harp->arp_pln) != INTF_IP_ALEN && /* IP addr len. */ + ntohs(harp->arp_op) != ARPOP_REQUEST && /* ARP request. */ + ntohs(harp->arp_op) != ARPOP_REPLY) { /* ARP reply. */ + MSG_DEBUG("Skip the ARP packet read that isn't a request or reply"); + + /* Break immediately. */ + break; + } + + /* All IP addrs to network byte order. */ + if (inet_aton(INTF_IPZEROSTRADDR, &ipzero) == 0) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("ipzero = %s", inet_ntoa(ipzero)); + + /* Copy SHA network byte order to MAC src addr network byte order. */ + memcpy(macsrc.ether_addr_octet, harp->arp_sha, ETH_ALEN); + MSG_DEBUG("macsrc = %s", ether_ntoa(&macsrc)); + + /* Copy SPA network byte order to IP src addr network byte order. */ + memcpy(&ipsrc.s_addr, harp->arp_spa, INTF_IP_ALEN); + MSG_DEBUG("ipsrc = %s", inet_ntoa(ipsrc)); + + /* + * IP src addr is not part of the same network of the interface? + * Therefore: + * + * IP src addr is not part of the same network of the interface = + * (IP src addr & Interface Mask addr) != Interface Net addr && + * IP src addr != All IP addrs + */ + if ((ipsrc.s_addr & cfg->netmask.s_addr) != cfg->network.s_addr && + memcmp(&ipsrc.s_addr, &ipzero.s_addr, INTF_IP_ALEN) != 0) { + MSG_DEBUG("Skip the ARP packet read that is not part of network"); + + /* Break immediately. */ + break; + } + + /* Copy THA network byte order to MAC dst addr network byte order. */ + memcpy(macdst.ether_addr_octet, harp->arp_tha, ETH_ALEN); + MSG_DEBUG("macdst = %s", ether_ntoa(&macdst)); + + /* Copy TPA network byte order to IP dst addr network byte order. */ + memcpy(&ipdst.s_addr, harp->arp_tpa, INTF_IP_ALEN); + MSG_DEBUG("ipdst = %s", inet_ntoa(ipdst)); + + /* + * IP dst addr is not part of the same network of the interface? + * Therefore: + * + * IP dst addr is not part of the same network of the interface = + * (IP dst addr & Interface Mask addr) != Interface Net addr && + * IP dst addr != All IP addrs + */ + if ((ipdst.s_addr & cfg->netmask.s_addr) != cfg->network.s_addr && + memcmp(&ipdst.s_addr, &ipzero.s_addr, INTF_IP_ALEN) != 0) { + MSG_DEBUG("Skip the ARP packet read that is not part of network"); + + /* Break immediately. */ + break; + } + + /* Initialize the ARP packet op code. */ + op = INTF_ARPOP_INIT; + MSG_DEBUG("op = ARP"); + + /* Check the type of the ARP packet read. */ + switch (ntohs(harp->arp_op)) { + case ARPOP_REQUEST: + /* ARP request packet. */ + op |= INTF_ARPOP_REQUEST; + MSG_DEBUG("op |= Request"); + break; + + /* ARPOP_REPLY. */ + default: + /* ARP reply packet. */ + op |= INTF_ARPOP_REPLY; + MSG_DEBUG("op |= Reply"); + break; + } + + /* + * Check if the ARP request/reply packet is a gratuitous ARP request/ + * reply packet, therefore: + * + * Gratuitous ARP request/reply packet sent by us or sent to us = + * IP src addr == IP dst addr + */ + if (memcmp( + &ipsrc.s_addr, /* IP src addr. */ + &ipdst.s_addr, /* IP dst addr. */ + INTF_IP_ALEN) == 0) { + /* Gratuitous ARP request/reply packet. */ + op |= INTF_ARPOP_GRATUITOUS; + MSG_DEBUG("op |= Gratuitous"); + + /* + * Check if the gratuitous ARP request/reply packet is a no valid + * gratuitous ARP request/reply packet, therefore: + * + * Gratuitous ARP request/reply packet no valid = + * IP src addr == All IP addrs && + * IP dst addr == All IP addrs + */ + if (memcmp( + &ipsrc.s_addr, /* IP src addr. */ + &ipzero.s_addr, /* All IP addrs. */ + INTF_IP_ALEN) == 0 && + memcmp( + &ipdst.s_addr, /* IP dst addr. */ + &ipzero.s_addr, /* All IP addrs. */ + INTF_IP_ALEN) == 0) { + MSG_DEBUG("Skip the ARP packet read that is not valid"); + + /* Break immediately. */ + break; + } + + /* + * Check the I/O bound direction of the gratuitous ARP request/ + * reply packet read (sent by us or sent to us), therefore: + * + * Gratuitous ARP request/reply packet sent by us = + * MAC src addr == Interface MAC addr && + * IP src/dst addr == Interface IP addr + * + * Gratuitous ARP request/reply packet sent to us = + * IP src/dst addr != Interface IP addr + */ + if (memcmp( + macsrc.ether_addr_octet, /* MAC src addr. */ + &cfg->mac.ether_addr_octet, /* Interface MAC addr. */ + ETH_ALEN) == 0 && + memcmp( + &ipsrc.s_addr, /* IP src/dst addr. */ + &cfg->ip.s_addr, /* Interface IP addr. */ + INTF_IP_ALEN) == 0) { + /* Gratuitous ARP request/reply packet sent by us. */ + op |= INTF_ARPOP_OUTBOUND; + MSG_DEBUG("op |= Outbound"); + } else if ( + memcmp( + &ipsrc.s_addr, /* IP src/dst addr. */ + &cfg->ip.s_addr, /* Interface IP addr. */ + INTF_IP_ALEN) != 0) { + /* Gratuitous ARP request/reply packet sent to us. */ + op |= INTF_ARPOP_INBOUND; + MSG_DEBUG("op |= Inbound"); + } + } + + /* + * Check if the ARP request/reply packet is a probe ARP request/reply + * packet, therefore: + * + * Probe ARP request/reply packet sent by us or sent to us = + * (IP src addr == All IP addrs && + * IP dst addr == Interface IP addr) || + * (IP src addr == Interface IP addr && + * IP dst addr == All IP addrs) + */ + if ((memcmp( + &ipsrc.s_addr, /* IP src addr. */ + &ipzero.s_addr, /* All IP addrs. */ + INTF_IP_ALEN) == 0 && + memcmp( + &ipdst.s_addr, /* IP dst addr. */ + &cfg->ip.s_addr, /* Interface IP addr. */ + INTF_IP_ALEN) == 0) || + (memcmp( + &ipsrc.s_addr, /* IP src addr. */ + &cfg->ip.s_addr, /* Interface IP addr. */ + INTF_IP_ALEN) == 0 && + memcmp( + &ipdst.s_addr, /* IP dst addr. */ + &ipzero.s_addr, /* All IP addrs. */ + INTF_IP_ALEN) == 0)) { + /* Probe ARP request/reply packet. */ + op |= INTF_ARPOP_PROBE; + MSG_DEBUG("op |= Probe"); + + /* + * Check the I/O bound direction of the probe ARP request/reply + * packet read (sent by us or sent to us), therefore: + * + * Probe ARP request/reply packet sent by us = + * MAC src addr == Interface MAC addr + * + * Probe ARP request packet sent to us = + * MAC src addr != Interface MAC addr + */ + if (memcmp( + macsrc.ether_addr_octet, /* MAC src addr. */ + &cfg->mac.ether_addr_octet, /* Interface MAC addr. */ + ETH_ALEN) == 0) { + /* Probe ARP request/reply sent by us. */ + op |= INTF_ARPOP_OUTBOUND; + MSG_DEBUG("op |= Outbound"); + } else { + /* Probe ARP request/reply sent to us. */ + op |= INTF_ARPOP_INBOUND; + MSG_DEBUG("op |= Inbound"); + } + } + + /* + * Check if the ARP request/reply packet is not a gratuitous ARP + * request/reply packet or a probe ARP request/reply packet. + */ + if ((op & INTF_ARPOP_GRATUITOUS) == 0 && /* No gratuitous ARP packet. */ + (op & INTF_ARPOP_PROBE) == 0) { /* No probe ARP packet. */ + /* + * Check the I/O bound direction of the ARP request/reply packet + * read (sent by us or sent to us), therefore: + * + * ARP request/reply packet sent by us = + * MAC src addr == Interface MAC addr && + * IP src addr == Interface IP addr + * + * ARP request/reply packet sent to us = + * IP dst addr == Interface IP addr + */ + if (memcmp( + macsrc.ether_addr_octet, /* MAC src addr. */ + &cfg->mac.ether_addr_octet, /* Interface MAC addr. */ + ETH_ALEN) == 0 && + memcmp( + &ipsrc.s_addr, /* IP src addr. */ + &cfg->ip.s_addr, /* Interface IP addr. */ + INTF_IP_ALEN) == 0) { + /* ARP request/reply packet sent by us. */ + op |= INTF_ARPOP_OUTBOUND; + MSG_DEBUG("op |= Outbound"); + } else if ( + memcmp( + &ipdst.s_addr, /* IP dst addr. */ + &cfg->ip.s_addr, /* Interface IP addr. */ + INTF_IP_ALEN) == 0) { + /* ARP request/reply packet sent to us. */ + op |= INTF_ARPOP_INBOUND; + MSG_DEBUG("op |= Inbound"); + } + } + + /* Skip the ARP packet read that isn't matched by decoder. */ + if ((op & INTF_ARPOP_OUTBOUND) == 0 && /* No ARP packet sent by us. */ + (op & INTF_ARPOP_INBOUND) == 0) { /* No ARP packet sent to us. */ + MSG_DEBUG("Skip the ARP packet read that isn't matched by decoder"); + + /* Break immediately. */ + break; + } + + /* Set the ARP Inspection live capture handler callback routine. */ + handler = (void (*)(int, struct ether_addr *, struct in_addr *, + struct ether_addr *, struct in_addr *))callback; + + /* Run the ARP Inspection live capture handler callback routine. */ + handler(op, &macsrc, &ipsrc, &macdst, &ipdst); + } while (0); + + MSG_DEBUG("End live capture decoder"); +} + +/* + * Inject an ARP packet in the network traffic of the interface. + */ +void +intf_inject(int op, struct in_addr *ip) +{ + + do { + struct ether_addr *mac = NULL; + char UNUSED(*smac) = NULL, UNUSED(*sip) = NULL; + + /* MAC broadcast addr string to MAC addr network byte order. */ + if ((mac = ether_aton(INTF_MACBROSTRADDR)) == NULL) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } + + /* Autobuild the ARP header inside the libnet network handle. */ + if (libnet_autobuild_arp( + (uint16_t)op, /* ARP operation type. */ + (const uint8_t *)&cfg->mac, /* SHA to interface MAC addr. */ + (const uint8_t *)&cfg->ip, /* SPA to interface IP addr. */ + (const uint8_t *)mac, /* THA to mac. */ + (uint8_t *)ip, /* TPA to ip. */ + cfg->lnet) < 0) + break; + + /* Autobuild the Ethernet header inside the libnet network handle. */ + if (libnet_autobuild_ethernet( + (const uint8_t *)mac, /* Destination address to mac. */ + ETHERTYPE_ARP, /* Upper ARP layer protocol type. */ + cfg->lnet) < 0) + break; + + /* Send the ARP packet built inside the libnet network handle. */ + if (libnet_write(cfg->lnet) < 0) + break; + + /* Clear the ARP packet built inside the libnet network handle. */ + libnet_clear_packet(cfg->lnet); + +#ifndef NDEBUG + /* THA network byte order to string. */ + smac = ether_ntoa(mac); + + /* TPA network byte order to string. */ + sip = inet_ntoa(*ip); +#endif /* !NDEBUG */ + + MSG_DEBUG("Sent %s packet to %s (%s)", INTF_ATOA(op), smac, sip); + + return; + } while (0); + + MSG_ERROR("%s", libnet_geterror(cfg->lnet)); + exit(EXIT_FAILURE); +} + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/intf.h arpon-3.0-ng+dfsg1/src/intf.h --- arpon-2.7.2/src/intf.h 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/intf.h 2016-01-29 01:56:56.000000000 +0000 @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: intf.h,v 3.0-ng 01/29/2016 02:56:56 spikey Exp $ + */ + +#ifndef _INTF_H_ +#define _INTF_H_ + +/* + * MAC addr string length. + */ +#define INTF_ETHERSTRLEN 18 /* 18 bytes. */ + +/* + * ARP packet op codes exported. + */ +#define INTF_ARPOP_INIT 0x00 /* No ARP. */ +#define INTF_ARPOP_REQUEST 0x01 /* ARP request. */ +#define INTF_ARPOP_REPLY 0x02 /* ARP reply. */ +#define INTF_ARPOP_GRATUITOUS 0x04 /* Gratuitous ARP. */ +#define INTF_ARPOP_PROBE 0x08 /* Probe ARP. */ +#define INTF_ARPOP_OUTBOUND 0x10 /* ARP outbound. */ +#define INTF_ARPOP_INBOUND 0x20 /* ARP inbound. */ + +/* + * Print the outbound packet info message to standard output and log file. + */ +#define INTF_OUTBOUND(type) do { \ + MSG_DEBUG(">>>>>>>>>>>>>>>>>>>>> PACKET TRACER >>>>>>>>>>>>>>>>>>>>>"); \ + MSG_DEBUG("%s, outbound on %s", type, interface); \ + MSG_DEBUG("src mac = %s, src ip = %s", smacsrc, sipsrc); \ + MSG_DEBUG("dst mac = %s, dst ip = %s", smacdst, sipdst); \ +} while (0) + +/* + * Print the inbound packet info message to standard output and log file. + */ +#define INTF_INBOUND(type) do { \ + MSG_DEBUG("<<<<<<<<<<<<<<<<<<<<< PACKET TRACER <<<<<<<<<<<<<<<<<<<<<"); \ + MSG_DEBUG("%s, inbound on %s", type, interface); \ + MSG_DEBUG("src mac = %s, src ip = %s", smacsrc, sipsrc); \ + MSG_DEBUG("dst mac = %s, dst ip = %s", smacdst, sipdst); \ +} while (0) + +/* + * Function prototypes exported. + */ +extern void intf_configure(void); +extern struct in_addr *intf_getnetwork(void); +extern struct in_addr *intf_getnetmask(void); +extern void *intf_capture(void *callback); +extern void intf_inject(int op, struct in_addr *ip); + +#endif /* !_INTF_H_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/ispn.c arpon-3.0-ng+dfsg1/src/ispn.c --- arpon-2.7.2/src/ispn.c 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/ispn.c 2016-01-29 02:05:27.000000000 +0000 @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: ispn.c,v 3.0-ng 01/29/2016 03:05:27 spikey Exp $ + */ + +#include +#include + +#include +#include +#include + +#include "arpca.h" +#include "darpica.h" +#include "darpi.h" +#include "harpi.h" +#include "intf.h" +#include "ispn.h" +#include "msg.h" +#include "opt.h" +#include "proc.h" +#include "sarpica.h" +#include "sarpi.h" +#include "thd.h" +#include "unused.h" + +/* + * Function prototypes not exported. + */ +static void ispn_handle(int ispn, char *interface); +static void ispn_handlesarpi(char *interface); +static void ispn_handledarpi(char *interface); +static void ispn_handleharpi(char *interface); + +/* + * Initialize and start the ARP Inspection on the interface. + */ +void +ispn_start(void) +{ + int ispn; + char *interface = NULL; + + MSG_DEBUG("Start ARP Inspection activate"); + + /* No specified ARP Inspection command option? */ + if ((ispn = opt_getinspection()) == ISPN_NONE) { + /* Print the info message and exit. */ + MSG_WARN("No specified ARP Inspection"); + exit(EXIT_FAILURE); + } + + /* Get the interface command option. */ + interface = opt_getinterface(); + + MSG_INFO("Start %s on %s", ISPN_ATOA(ispn), interface); + + /* Configure the proc files in the proc file system. */ + proc_configure(); + + /* Cleanup the ARP cache. */ + arpca_cleanup(); + + /* Handle the ARP Inspection on the interface name command option. */ + ispn_handle(ispn, interface); + + MSG_DEBUG("End ARP Inspection activate"); +} + +/* + * Handle the ARP Inspection on the interface. + */ +static void +ispn_handle(int ispn, char *interface) +{ + + /* Handle the ARP Inspection. */ + switch(ispn) { + case ISPN_SARPI: + MSG_DEBUG("Run SARPI on %s..", interface); + + /* Handle and activate the SARPI. */ + ispn_handlesarpi(interface); + break; + + case ISPN_DARPI: + MSG_DEBUG("Run DARPI on %s..", interface); + + /* Handle and activate the DARPI. */ + ispn_handledarpi(interface); + break; + + /* ISPN_HARPI. */ + default: + MSG_DEBUG("Run HARPI on %s..", interface); + + /* Handle and activate the HARPI. */ + ispn_handleharpi(interface); + break; + } +} + +/* + * Handle the SARPI on the interface. + */ +static void +ispn_handlesarpi(UNUSED(char *interface)) +{ + + MSG_DEBUG("Handle the SARPI on %s..", interface); + + /* Configure the SARPI cache and register the SARPI cache handler thread. */ + sarpica_configure(); + + MSG_DEBUG("SARPI cache handler ready and running on %s", interface); + + /* Register the SARPI live capture handler thread. */ + thd_register(intf_capture, sarpi_handler, "intf_capture"); + + MSG_DEBUG("SARPI live capture handler ready and running on %s", interface); +} + +/* + * Handle the DARPI on the interface. + */ +static void +ispn_handledarpi(UNUSED(char *interface)) +{ + + MSG_DEBUG("Handle the DARPI on %s..", interface); + + /* Configure the DARPI cache and register the DARPI cache handler thread. */ + darpica_configure(); + + MSG_DEBUG("DARPI cache handler ready and running on %s", interface); + + /* Register the DARPI live capture handler thread. */ + thd_register(intf_capture, darpi_handler, "intf_capture"); + + MSG_DEBUG("DARPI live capture handler ready and running on %s", interface); +} + +/* + * Handle the HARPI on the interface. + */ +static void +ispn_handleharpi(UNUSED(char *interface)) +{ + + MSG_DEBUG("Handle the HARPI on %s..", interface); + + /* Configure the SARPI cache and register the SARPI cache handler thread. */ + sarpica_configure(); + + MSG_DEBUG("SARPI cache ready and running on %s", interface); + + /* Configure the DARPI cache and register the DARPI cache handler thread. */ + darpica_configure(); + + MSG_DEBUG("DARPI cache handler ready and running on %s", interface); + + /* Register the HARPI live capture handler thread. */ + thd_register(intf_capture, harpi_handler, "intf_capture"); + + MSG_DEBUG("HARPI live capture handler ready and running on %s", interface); +} + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/ispn.h arpon-3.0-ng+dfsg1/src/ispn.h --- arpon-2.7.2/src/ispn.h 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/ispn.h 2016-01-29 02:04:53.000000000 +0000 @@ -0,0 +1,95 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: ispn.h,v 3.0-ng 01/29/2016 03:04:54 spikey Exp $ + */ + +#ifndef _ISPN_H_ +#define _ISPN_H_ + +/* + * ARP Inspection codes exported. + */ +#define ISPN_NONE (1 << 0) /* No ARP Inspection. */ +#define ISPN_SARPI (1 << 1) /* Static ARP Inspection. */ +#define ISPN_DARPI (1 << 2) /* Dynamic ARP Inspection. */ +#define ISPN_HARPI (1 << 3) /* Hybrid ARP Inspection. */ + +/* + * ARP Inspection code to string. + */ +#define ISPN_ATOA(x) x == ISPN_SARPI ? "SARPI" : \ + x == ISPN_DARPI ? "DARPI" : \ + x == ISPN_HARPI ? "HARPI" : "NONE" + +/* + * Print the CLEAN policy info message to standard output and log file. + */ +#define ISPN_CLEAN(ip, mac) do { \ + MSG_INFO("CLEAN, %s was at %s on %s", ip, mac, interface); \ +} while (0) + +/* + * Print the UPDATE policy info message to standard output and log file. + */ +#define ISPN_UPDATE(ip, mac) do { \ + MSG_INFO("UPDATE, %s is at %s on %s", ip, mac, interface); \ +} while (0) + +/* + * Print the REFRESH policy info message to standard output and log file. + */ +#define ISPN_REFRESH(ip, mac) do { \ + MSG_INFO("REFRESH, %s is at %s on %s", ip, mac, interface); \ +} while (0) + +/* + * Print the ALLOW policy info message to standard output and log file. + */ +#define ISPN_ALLOW(ip, mac) do { \ + MSG_INFO("ALLOW, %s is at %s on %s", ip, mac, interface); \ +} while (0) + +/* + * Print the DENY policy info message to standard output and log file. + */ +#define ISPN_DENY(ip, mac) do { \ + MSG_INFO("DENY, %s was at %s on %s", ip, mac, interface); \ +} while (0) + +/* + * Function prototype exported. + */ +extern void ispn_start(void); + +#endif /* !_ISPN_H_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/main.c arpon-3.0-ng+dfsg1/src/main.c --- arpon-2.7.2/src/main.c 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/main.c 2016-01-29 02:02:46.000000000 +0000 @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: main.c,v 3.0-ng 01/29/2016 03:02:46 spikey Exp $ + */ + +#include +#include + +#include +#include + +#include "dmn.h" +#include "env.h" +#include "exit.h" +#include "intf.h" +#include "ispn.h" +#include "opt.h" +#include "sig.h" +#include "thd.h" + +/* + * ArpON Main. + */ +int +main(int argc, char **argv, char **envp) +{ + + /* Audit the environment. */ + env_audit(argv, envp); + + /* Register the main thread. */ + thd_register(NULL, NULL, "main"); + + /* Parse the command options. */ + opt_parse(argc, argv); + + /* Configure the interface. */ + intf_configure(); + + /* Daemonize the process. */ + dmn_daemonize(argv); + + /* Start the ARP Inspection on the interface. */ + ispn_start(); + + /* Handle the signals. */ + sig_handle(argv, envp); + + /* Never reaches here. */ + return 0; +} + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/msg.c arpon-3.0-ng+dfsg1/src/msg.c --- arpon-2.7.2/src/msg.c 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/msg.c 2016-01-29 02:09:13.000000000 +0000 @@ -0,0 +1,364 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: msg.c,v 3.0-ng 01/29/2016 03:09:14 spikey Exp $ + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "exit.h" +#include "msg.h" +#include "unused.h" + +/* + * Max timestamp length. + */ +#define MSG_TIMESTAMPSIZE 16 /* 16 bytes. */ + +/* + * Max message length. + */ +#define MSG_MESSAGESIZE 512 /* 512 bytes. */ + +/* + * Log file permissions to 640. + */ +#define MSG_LOGPERMS S_IRUSR | S_IWUSR | S_IRGRP + +/* + * Function prototypes not exported. + */ +static void msg_init(void); +static void msg_destroy(void); +static void msg_gettimestamp(char *ts); +static void msg_putmessage(FILE *stream, const char *msg); + +/* + * Initialize the log file stream. + */ +static FILE *log = NULL; + +/* + * Initialize the message mutex. + */ +static pthread_mutex_t msg_mtx = PTHREAD_MUTEX_INITIALIZER; + +/* + * Initialize the log file stream and print the message with logging. + * The syntax of each message is: + * + * timestamp1 [log level] message1 + * timestamp2 [log level] message2 + * ... + * timestampN [log level] messageN + */ +void +msg(FILE *stream, const char *level, const char *fmt, ...) +{ + + do { + char ts[MSG_TIMESTAMPSIZE], msg[MSG_MESSAGESIZE]; + va_list ap; + int len1, len2, tot_len = MSG_MESSAGESIZE; + + /* Lock the mutex of the message. */ + if (pthread_mutex_lock(&msg_mtx) != 0) + break; + + /* Log file stream of the messages already initialized and open? */ + if (log == NULL) { + /* Initialize the log file stream of the messages. */ + msg_init(); + } + + /* Get the timestamp of the message. */ + msg_gettimestamp(ts); + + /* Initialize the message. */ + memset(msg, '\0', (size_t)tot_len); + + /* Write the timestamp with log level in the message. */ + if ((len1 = snprintf(msg, (size_t)tot_len, "%s [%s] ", ts, level)) < 0) + break; + + /* Update the total length of the message. */ + tot_len -= len1; + + /* No message truncated. */ + assert(tot_len > 0); + + /* Append the rest of the message. */ + va_start(ap, fmt); + + if ((len2 = vsnprintf(&msg[len1], (size_t)tot_len, fmt, ap)) < 0) + break; + + va_end(ap); + + /* Update the total length of the message. */ + tot_len -= len2; + + /* No message truncated. */ + assert(tot_len > 0); + + /* Print the message in the log file stream and the file stream. */ + msg_putmessage(stream, msg); + + /* Unlock the mutex of the message. */ + if (pthread_mutex_unlock(&msg_mtx) != 0) + break; + + return; + } while (0); + + ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Initialize the log file stream of the messages. + */ +static void +msg_init(void) +{ + + do { + struct stat stats; + bool UNUSED(logcreate) = false; + + /* Check if the log file exist. */ + if (stat(LOG_FILE, &stats) < 0) { + if (errno == ENOENT) { + int fd; + + /* Create and open the log file with the 640 perms. */ + if ((fd = open(LOG_FILE, O_CREAT, MSG_LOGPERMS)) < 0) + break; + + /* Close the log file descriptor. */ + if (close(fd) < 0) + break; + + /* Call again. */ + if (stat(LOG_FILE, &stats) < 0) + break; + +#ifndef NDEBUG + /* Log file created. */ + logcreate = true; +#endif /* !NDEBUG */ + } else { + break; + } + } + + /* Check if the log file is a regular file. */ + if (S_ISREG(stats.st_mode) == 0) { + ERROR("%s is not a regular file", LOG_FILE); + exit(EXIT_FAILURE); + } + + /* Fix the log file perms to 640. */ + if (chmod(LOG_FILE, MSG_LOGPERMS) < 0) + break; + + /* Open the log file stream to append. */ + if ((log = fopen(LOG_FILE, "a")) == NULL) + break; + +#ifndef NDEBUG + /* Unlock the mutex of the message. */ + if (pthread_mutex_unlock(&msg_mtx) != 0) + break; + + /* Log file created? */ + if (logcreate == true) + MSG_DEBUG("Create %s with 640 perms successful", LOG_FILE); +#endif /* !NDEBUG */ + + MSG_DEBUG("Open %s successful", LOG_FILE); + MSG_DEBUG("Start logging"); + + /* Push msg_destroy() to be called on exit_cleanup(). */ + exit_push(msg_destroy, "msg_destroy"); + +#ifndef NDEBUG + /* Lock the mutex of the message. */ + if (pthread_mutex_lock(&msg_mtx) != 0) + break; +#endif /* !NDEBUG */ + + return; + } while (0); + + ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Destroy the log file stream of the messages. + */ +static void +msg_destroy(void) +{ + + do { + /* Unlock the mutex of the message before the destruction. */ + if (pthread_mutex_unlock(&msg_mtx) != 0) + break; + + /* Log file stream of the messages already destroyed and closed? */ + if (log != NULL) { + MSG_DEBUG("End logging"); + MSG_DEBUG("Close %s successful", LOG_FILE); + + /* Close the log file stream. */ + if (fclose(log) == EOF) + break; + + /* Set the log file stream to NULL. */ + log = NULL; + } + + return; + } while (0); + + ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Get the timestamp of the message. + */ +static void +msg_gettimestamp(char *ts) +{ + + do { + struct tm *tinfo = NULL; + time_t rtime; + int len = MSG_TIMESTAMPSIZE; + + /* Initialize the timestamp. */ + memset(ts, '\0', (size_t)len); + + /* Get the current time of the system. */ + if ((rtime = time(NULL)) == (time_t)-1) + break; + + /* Current time to local time. */ + if ((tinfo = localtime(&rtime)) == NULL) + break; + + /* Local time to timestamp. */ + if (strftime(ts, (size_t)len, "%b %d %H:%M:%S", tinfo) == 0) + break; + + return; + } while (0); + + ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Put the message in the log file stream and the file stream. + */ +static void +msg_putmessage(FILE *stream, const char *msg) +{ + + do { + struct stat stats; + + /* Check if the log file exist. */ + if (stat(LOG_FILE, &stats) < 0) { + if (errno == ENOENT) { + /* Close the log file stream. */ + if (fclose(log) == EOF) + break; + + /* Set the log file stream to NULL. */ + log = NULL; + + /* Re-initialize the log file stream. */ + msg_init(); + + /* Call again. */ + if (stat(LOG_FILE, &stats) < 0) + break; + } else { + break; + } + } + + /* Check if the log file is a regular file. */ + if (S_ISREG(stats.st_mode) == 0) { + ERROR("%s is not a regular file", LOG_FILE); + exit(EXIT_FAILURE); + } + + /* Print the message in the log file stream. */ + fprintf(log, "%s", msg); + + /* Flush the log file stream. */ + if (fflush(log) == EOF) + break; + + /* Print the message in the file stream. */ + fprintf(stream, "%s", msg); + + /* Flush the file stream. */ + if (fflush(stream) == EOF) + break; + + return; + } while (0); + + ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/msg.h arpon-3.0-ng+dfsg1/src/msg.h --- arpon-2.7.2/src/msg.h 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/msg.h 2016-01-29 02:02:28.000000000 +0000 @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: msg.h,v 3.0-ng 01/29/2016 03:02:30 spikey Exp $ + */ + +#ifndef _MSG_H_ +#define _MSG_H_ + +/* + * Remove the path from the filename. + */ +#define __SHORT_FILE__ \ + strrchr(__FILE__, '/') != NULL ? \ + strrchr(__FILE__, '/') + 1 : __FILE__ + +/* + * Print the info message to standard output. + */ +#define INFO(fmt, ...) do { \ + printf(fmt "\n", ##__VA_ARGS__); \ +} while (0); + +/* + * Print the error message to standard error. + */ +#define ERROR(fmt, ...) do { \ + fprintf(stderr, "ERROR: " "%s:%d %s: `" fmt "'.\n", \ + __SHORT_FILE__, __LINE__, __func__, ##__VA_ARGS__); \ +} while (0); + +/* + * Print the info message to standard output and log file. + */ +#define MSG_INFO(fmt, ...) do { \ + msg(stdout, "INFO", fmt "\n", ##__VA_ARGS__); \ +} while (0) + +/* + * If debug enabled, print the info message to standard output and log file. + */ +#ifndef NDEBUG +#define MSG_DEBUG(fmt, ...) do { \ + msg(stdout, "DEBUG", "%s: " fmt ".\n", __func__, ##__VA_ARGS__); \ +} while (0) +#else /* NDEBUG */ +#define MSG_DEBUG(...) /* Null instruction. */ +#endif /* !NDEBUG */ + +/* + * Print the warning message to standard error and log file. + */ +#define MSG_WARN(fmt, ...) do { \ + msg(stderr, "WARN", fmt ".\n", ##__VA_ARGS__); \ +} while (0) + +/* + * Print the error message to standard error and log file. + */ +#define MSG_ERROR(fmt, ...) do { \ + msg(stderr, "ERROR", "%s:%d %s: `" fmt "'.\n", \ + __SHORT_FILE__, __LINE__, __func__, ##__VA_ARGS__); \ +} while (0) + +/* + * Print the bug message to standard error and log file. + */ +#define MSG_BUG(fmt, ...) do { \ + msg(stderr, "BUG", fmt "\n", ##__VA_ARGS__); \ +} while (0) + +/* + * Function prototype exported. + */ +extern void msg(FILE *stream, const char *level, const char *fmt, ...); + +#endif /* !_MSG_H_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/opt.c arpon-3.0-ng+dfsg1/src/opt.c --- arpon-2.7.2/src/opt.c 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/opt.c 2016-01-29 01:56:19.000000000 +0000 @@ -0,0 +1,340 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: opt.c,v 3.0-ng 01/29/2016 02:56:20 spikey Exp $ + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "exit.h" +#include "ispn.h" +#include "msg.h" +#include "opt.h" +#include "std.h" + +/* + * Boolean to string. + */ +#define OPT_BTOA(x) x == true ? "true" : "false" + +/* + * Vector characters to string. + */ +#define OPT_VTOA(x) x[0] == '\0' ? "\\0" : x + +/* + * Command option structure definition. + */ +typedef struct opt_option { + bool daemon; /* Daemonize command option. */ + char interface[IF_NAMESIZE]; /* Interface name command option. */ + int inspection; /* ARP Inspection command option. */ +} opt_t; + +/* + * Function prototypes not exported. + */ +static void opt_init(void); +static void opt_destroy(void); +static void opt_loop(int argc, char **argv); +static void opt_setdaemon(void); +static void opt_setinterface(char *interface); +static void opt_setinspection(int inspection); + +/* + * Initialize the command option structure. + */ +static opt_t *opt = NULL; + +/* + * Initialize and parse the command option. + */ +void +opt_parse(int argc, char **argv) +{ + + MSG_DEBUG("Start command option parse"); + + /* No specified command option? */ + if (argc == 1) { + MSG_DEBUG("No command option parse"); + + /* Print the help screen, cleanup and exit. */ + std_help(); + exit_cleanup(true); + } + + /* Initialize the command option structure. */ + opt_init(); + + /* Parse the command option and set the command option structure. */ + opt_loop(argc, argv); + + MSG_DEBUG("End command option parse"); +} + +/* + * Initialize the command option structure. + */ +static void +opt_init(void) +{ + + /* Allocate the command option structure. */ + if ((opt = (opt_t *)malloc(sizeof(opt_t))) == NULL) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("opt_t *opt allocate in the memory"); + + /* Initialize the daemonize command option. */ + opt->daemon = false; + MSG_DEBUG("opt->daemon = false"); + + /* Initialize the interface name command option. */ + memset(opt->interface, '\0', (size_t)IF_NAMESIZE); + MSG_DEBUG("opt->interface = \\0"); + + /* Initialize the ARP Inspection command option. */ + opt->inspection = ISPN_NONE; + MSG_DEBUG("opt->inspection = NONE"); + + /* Push opt_destroy() to be called on exit_cleanup(). */ + exit_push(opt_destroy, "opt_destroy"); +} + +/* + * Destroy the command option structure. + */ +static void +opt_destroy(void) +{ + + /* Command option structure previously allocated? */ + if (opt != NULL) { + /* Deallocate the command option structure. */ + free(opt); + + /* Set the command option structure to NULL. */ + opt = NULL; + + MSG_DEBUG("opt_t *opt deallocate from the memory"); + } +} + +/* + * Parse the command option and set the values in the command option structure. + */ +static void +opt_loop(int argc, char **argv) +{ + const struct option long_opt[] = { + /* General command options. */ + {"daemon", no_argument, 0, 'd'}, + {"interface", required_argument, 0, 'i'}, + + /* ARP Inspection command options. */ + {"sarpi", no_argument, 0, 'S'}, + {"darpi", no_argument, 0, 'D'}, + {"harpi", no_argument, 0, 'H'}, + + /* Standard command options. */ + {"version", no_argument, 0, 'v'}, + {"help", no_argument, 0, 'h'}, + {NULL, 0, 0, 0} + }; + const char *short_opt = "di:SDHvh"; + int gopt; + + /* Parse the specified command option from the command line. */ + while ((gopt = getopt_long(argc, argv, short_opt, long_opt, NULL)) != -1) { + switch (gopt) { + case 'd': + MSG_DEBUG("-d or --daemon command option"); + + /* Set the daemonize command option. */ + opt_setdaemon(); + break; + + case 'i': + MSG_DEBUG("-i or --interface command option"); + + /* Set the interface name command option. */ + opt_setinterface(optarg); + break; + + case 'S': + MSG_DEBUG("-S or --sarpi command option"); + + /* Set the SARPI comman option. */ + opt_setinspection(ISPN_SARPI); + break; + + case 'D': + MSG_DEBUG("-D or --darpi command option"); + + /* Set the DARPI command option. */ + opt_setinspection(ISPN_DARPI); + break; + + case 'H': + MSG_DEBUG("-H or --harpi command option"); + + /* Set the HARPI command option. */ + opt_setinspection(ISPN_HARPI); + break; + + case 'v': + MSG_DEBUG("-v or --version command option"); + + /* Print the version command option, cleanup and exit. */ + std_version(); + exit_cleanup(true); + + case 'h': + MSG_DEBUG("-h or --help command option"); + + /* Print the help screen command option, cleanup and exit. */ + std_help(); + exit_cleanup(true); + + case '?': + case ':': + default: + MSG_DEBUG("No valid command option"); + + /* Print the help screen and exit. */ + std_help(); + exit(EXIT_FAILURE); + } + } + + MSG_DEBUG("Command option looped"); +} + +/* + * Set the value of the daemonize in the command option structure. + */ +static void +opt_setdaemon(void) +{ + + /* Set the value of the daemonize command option. */ + opt->daemon = true; + MSG_DEBUG("opt->daemon = true"); +} + +/* + * Get the value of the daemonize from the command option structure. + */ +bool +opt_getdaemon(void) +{ + + MSG_DEBUG("opt->daemon = %s", OPT_BTOA(opt->daemon)); + + /* Get the value of the daemonize command option. */ + return opt->daemon; +} + +/* + * Set the value of the interface name in the command option structure. + */ +static void +opt_setinterface(char *interface) +{ + size_t len = strlen(interface); + + /* Check the length of the interface name command option. */ + if (len >= IF_NAMESIZE) { + /* Print the info message and exit. */ + MSG_WARN("No valid specified network interface"); + exit(EXIT_FAILURE); + } + + /* Re-initialize the interface name command option to no interface? */ + if (opt->interface != '\0') + memset(opt->interface, '\0', (size_t)IF_NAMESIZE); + + /* Set the value of the interface name command option. */ + memcpy(opt->interface, interface, len); + + MSG_DEBUG("opt->interface = %s", opt->interface); +} + +/* + * Get the value of the interface name from the command option structure. + */ +char * +opt_getinterface(void) +{ + + MSG_DEBUG("opt->interface = %s", OPT_VTOA(opt->interface)); + + /* Get the value of the interface name command option. */ + return opt->interface; +} + +/* + * Set the value of the ARP Inspection in the command option structure. + */ +static void +opt_setinspection(int inspection) +{ + + /* Set the value of the ARP Inspection command option. */ + opt->inspection = inspection; + + MSG_DEBUG("opt->inspection = %s", ISPN_ATOA(opt->inspection)); +} + +/* + * Get the value of the ARP Inspection from the command option structure. + */ +int +opt_getinspection(void) +{ + + MSG_DEBUG("opt->inspection = %s", ISPN_ATOA(opt->inspection)); + + /* Get the value of the ARP Inspection command option. */ + return opt->inspection; +} + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/opt.h arpon-3.0-ng+dfsg1/src/opt.h --- arpon-2.7.2/src/opt.h 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/opt.h 2016-01-29 01:59:44.000000000 +0000 @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: opt.h,v 3.0-ng 01/29/2016 02:59:45 spikey Exp $ + */ + +#ifndef _OPT_H_ +#define _OPT_H_ + +/* + * Function prototypes exported. + */ +extern void opt_parse(int argc, char **argv); +extern bool opt_getdaemon(void); +extern char *opt_getinterface(void); +extern int opt_getinspection(void); + +#endif /* !_OPT_H_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/proc.c arpon-3.0-ng+dfsg1/src/proc.c --- arpon-2.7.2/src/proc.c 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/proc.c 2016-01-29 01:57:19.000000000 +0000 @@ -0,0 +1,460 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: proc.c,v 3.0-ng 01/29/2016 02:57:20 spikey Exp $ + */ + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "exit.h" +#include "msg.h" +#include "opt.h" +#include "proc.h" +#include "queue.h" + +/* + * Proc root path file. + */ +#define PROC_ROOTPATH "/proc/sys/net/ipv4/conf/" + +/* + * Proc arp_ignore file. + */ +#define PROC_ARPIGNOREPATH "/arp_ignore" + +/* + * Proc arp_accept file. + */ +#define PROC_ARPACCEPTPATH "/arp_accept" + +/* + * New value of proc arp_ignore file to disable, in the specified network + * interface of the Operating System, the sending of the ARP replies in + * response to received ARP requests for all local addresses. + */ +#define PROC_ARPIGNOREVALUE 8 + +/* + * New value of proc arp_accept file to disable, in the specified network + * interface of the Operating System, the creating of the new IP entries + * in the ARP cache triggered by the unsolicited and gratuitous ARP requests + * and replies. + */ +#define PROC_ARPACCEPTVALUE 0 + +/* + * Proc file list structure definition. + */ +typedef struct proc_list { + char *path; /* Proc path file. */ + int value; /* Proc value file. */ + + LIST_ENTRY(proc_list) next; /* Next proc file list element. */ +} proc_t; + +/* + * Function prototypes not exported. + */ +static void proc_init(void); +static void proc_destroy(void); +static char *proc_get(int *value); +static void proc_setprocfs(char *path, int value, bool ignore); +static void proc_loadfile(const char *file); +static int proc_getprocfs(char *path); +static void proc_put(char *path, int value); +static void proc_setvalues(void); + +/* + * Initialize the proc file list structure. + */ +static LIST_HEAD(proc, proc_list) proc_head = LIST_HEAD_INITIALIZER(proc_head); + +/* + * Initialize and configure the proc files in the proc file system. + */ +void +proc_configure(void) +{ + + MSG_DEBUG("Start configure proc file system files"); + + /* Initialize the proc file list structure. */ + proc_init(); + + /* Load the proc arp_ignore file in the proc file list structure. */ + proc_loadfile(PROC_ARPIGNOREPATH); + + /* Load the proc arp_accept file in the proc file list structure. */ + proc_loadfile(PROC_ARPACCEPTPATH); + + /* Set the new values of the proc files in the proc file system. */ + proc_setvalues(); + + MSG_DEBUG("End configure proc file system files"); +} + +/* + * Initialize the proc file list structure. + */ +static void +proc_init(void) +{ + + /* Set the proc file list structure to NULL. */ + LIST_INIT(&proc_head); + MSG_DEBUG("Initialize proc file list successful"); + + /* + * Push proc_destroy() to be called on exit(). + * (In case of error, segmentation fault or bus error). + */ + if (atexit(proc_destroy) != 0) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("Push proc_destroy() to be called on exit"); + + /* Push proc_destroy() to be called on exit_cleanup(). */ + exit_push(proc_destroy, "proc_destroy"); +} + +/* + * Destroy the proc file list structure. + */ +static void +proc_destroy(void) +{ + + /* No empty proc file list structure? */ + if (LIST_EMPTY(&proc_head) == 0) { + /* Loop until the proc file list structure is empty. */ + do { + char *path = NULL; + int value; + + /* Get the proc file. */ + if ((path = proc_get(&value)) == NULL) { + /* Proc path file not previously allocated. */ + continue; + } + + MSG_DEBUG("Restore %s proc file to %d value..", path, value); + + /* + * Restore the previously value read of + * the proc file in the proc file system. + */ + proc_setprocfs(path, value, true); + + /* Deallocate the proc path file. */ + free(path); + MSG_DEBUG("*path deallocate from the memory"); + } while (LIST_EMPTY(&proc_head) == 0); + + /* Re-initialize the proc file list structure to NULL. */ + LIST_INIT(&proc_head); + } + + MSG_DEBUG("Destroy proc file list successful"); +} + +/* + * Get the proc file list element from the proc file list structure. + */ +static char * +proc_get(int *value) +{ + proc_t *cur = NULL; + char *path = NULL; + + /* Get the first proc file list element. */ + cur = LIST_FIRST(&proc_head); + + /* Remove the first proc file list element. */ + LIST_REMOVE(cur, next); + + /* Get the proc path file. */ + path = cur->path; + MSG_DEBUG("cur->path = %s", path); + + /* Get the proc value file. */ + *value = cur->value; + MSG_DEBUG("cur->value = %d", *value); + + /* Deallocate the proc file list element. */ + free(cur); + + MSG_DEBUG("proc_t *cur deallocate from the memory"); + MSG_DEBUG("Get %s proc file successful", path); + + return path; +} + +/* + * Set the new value of the specified proc file in the proc file system. + */ +static void +proc_setprocfs(char *path, int value, bool ignore) +{ + + do { + struct stat stats; + FILE *file = NULL; + + /* Check if the proc path file exist. */ + if (stat(path, &stats) < 0) { + /* + * In case that the proc file is not exist, ignore the set of the + * new value of the specified proc file in the proc file system? + */ + if (errno == ENOENT) { + if (ignore == true) { + MSG_DEBUG("Skip set %s proc file to %d value", path, value); + return; + } + } + + /* Else exit on error. */ + break; + } + + /* Check if the proc path file is a regular file. */ + if (S_ISREG(stats.st_mode) == 0) { + MSG_WARN("%s is not a regular file", path); + exit(EXIT_FAILURE); + } + + /* Open the proc file stream to write. */ + if ((file = fopen(path, "w")) == NULL) + break; + + /* Set the new value of the proc file in the proc file stream. */ + fprintf(file, "%d", value); + + /* Flush the proc file stream. */ + if (fflush(file) == EOF) + break; + + /* Close the proc file stream. */ + if (fclose(file) == EOF) + break; + + MSG_DEBUG("Set %s proc file to %d value successful", path, value); + + return; + } while (0); + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Load the specified proc file in the proc file list structure. + */ +static void +proc_loadfile(const char *file) +{ + char *interface = NULL, *path = NULL; + size_t len1, len2, len3, tot_len; + int value; + + /* Get the interface command option. */ + interface = opt_getinterface(); + + /* Calculate all the proc parts path file lengths. */ + len1 = strlen(PROC_ROOTPATH); + len2 = strlen(interface); + len3 = strlen(file); + + /* Calculate the sum of all the proc parts path file lengths. */ + tot_len = len1 + len2 + len3 + 1; + + /* Allocate the proc path file. */ + if ((path = (char *)malloc(tot_len)) == NULL) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("*path allocate in the memory"); + + /* Set the value of the proc root path file. */ + memcpy(path, PROC_ROOTPATH, len1); + + /* Set the value of the proc interface path file. */ + tot_len = len1; + memcpy(&path[tot_len], interface, len2); + + /* Set the value of the specified proc path file. */ + tot_len += len2; + memcpy(&path[tot_len], file, len3); + + /* Set the terminator character of the proc path file. */ + tot_len += len3; + path[tot_len] = '\0'; + + MSG_DEBUG("path = %s", path); + + /* Get the value of the specified proc file from the proc file system. */ + value = proc_getprocfs(path); + MSG_DEBUG("value = %d", value); + + /* Put the proc file list element in the proc file list structure. */ + proc_put(path, value); +} + +/* + * Get the value of the specified proc file from the proc file system. + */ +static int +proc_getprocfs(char *path) +{ + + do { + struct stat stats; + FILE *file = NULL; + int value; + + /* Check if the proc path file exist. */ + if (stat(path, &stats) < 0) + break; + + /* Check if the proc path file is a regular file. */ + if (S_ISREG(stats.st_mode) == 0) { + MSG_WARN("%s is not a regular file", path); + exit(EXIT_FAILURE); + } + + /* Open the proc file stream to read. */ + if ((file = fopen(path, "r")) == NULL) + break; + + /* Get the value of the proc file from the proc file stream. */ + if (fscanf(file, "%d", &value) == EOF) + break; + + /* Close the proc file stream. */ + if (fclose(file) == EOF) + break; + + MSG_DEBUG("Get %d value from %s proc file successful", value, path); + + return value; + } while (0); + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Put the proc file list element in the proc file list structure. + */ +static void +proc_put(char *path, int value) +{ + proc_t *new = NULL; + + /* Allocate the proc file list element. */ + if ((new = (proc_t *)malloc(sizeof(proc_t))) == NULL) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("proc_t *new allocate in the memory"); + + /* Initialize the proc path file entry. */ + new->path = path; + MSG_DEBUG("new->path = %s", new->path); + + /* Initialize the proc value file entry. */ + new->value = value; + MSG_DEBUG("new->value = %d", new->value); + + /* Empty proc file list structure? */ + if (LIST_EMPTY(&proc_head) != 0) { + /* Insert the proc file list element in the head. */ + LIST_INSERT_HEAD(&proc_head, new, next); + MSG_DEBUG("H-Insert <%s, %d> proc file successful", path, value); + } else { + proc_t *first = NULL; + + /* Get the first proc file list element. */ + first = LIST_FIRST(&proc_head); + + /* Insert the proc file list element after the first or head. */ + LIST_INSERT_AFTER(first, new, next); + MSG_DEBUG("A-Insert <%s, %d> proc file successful", path, value); + } +} + +/* + * Set the new values of the proc files in the proc file system. + */ +static void +proc_setvalues(void) +{ + proc_t *cur = NULL; + + /* Loop for each proc file element. */ + LIST_FOREACH(cur, &proc_head, next) { + char *file = NULL; + + /* Get the proc specified proc path file. */ + file = strrchr(cur->path, '/'); + + /* arp_ignore or arp_accept proc file? */ + if (strcmp(file, PROC_ARPIGNOREPATH) == 0) { + /* + * Set the new value of the arp_ignore + * proc file in the proc file system. + */ + proc_setprocfs(cur->path, PROC_ARPIGNOREVALUE, false); + } else { + /* + * Set the new value of the arp_accept + * proc file in the proc file system. + */ + proc_setprocfs(cur->path, PROC_ARPACCEPTVALUE, false); + } + } + + MSG_DEBUG("Set values of the proc files successful"); +} + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/proc.h arpon-3.0-ng+dfsg1/src/proc.h --- arpon-2.7.2/src/proc.h 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/proc.h 2016-01-29 01:57:45.000000000 +0000 @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: proc.h,v 3.0-ng 01/29/2016 02:57:45 spikey Exp $ + */ + +#ifndef _PROC_H_ +#define _PROC_H_ + +/* + * Function prototype exported. + */ +extern void proc_configure(void); + +#endif /* !_PROC_H_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/queue.h arpon-3.0-ng+dfsg1/src/queue.h --- arpon-2.7.2/src/queue.h 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/queue.h 2016-01-29 02:14:17.000000000 +0000 @@ -0,0 +1,486 @@ +/* + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + */ + +#ifndef _SYS_QUEUE_H_ +#define _SYS_QUEUE_H_ + +/* + * This file defines five types of data structures: singly-linked lists, + * slingly-linked tail queues, lists, tail queues, and circular queues. + * + * A singly-linked list is headed by a single forward pointer. The elements + * are singly linked for minimum space and pointer manipulation overhead at + * the expense of O(n) removal for arbitrary elements. New elements can be + * added to the list after an existing element or at the head of the list. + * Elements being removed from the head of the list should use the explicit + * macro for this purpose for optimum efficiency. A singly-linked list may + * only be traversed in the forward direction. Singly-linked lists are ideal + * for applications with large datasets and few or no removals or for + * implementing a LIFO queue. + * + * A singly-linked tail queue is headed by a pair of pointers, one to the + * head of the list and the other to the tail of the list. The elements are + * singly linked for minimum space and pointer manipulation overhead at the + * expense of O(n) removal for arbitrary elements. New elements can be added + * to the list after an existing element, at the head of the list, or at the + * end of the list. Elements being removed from the head of the tail queue + * should use the explicit macro for this purpose for optimum efficiency. + * A singly-linked tail queue may only be traversed in the forward direction. + * Singly-linked tail queues are ideal for applications with large datasets + * and few or no removals or for implementing a FIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may only be traversed in the forward direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may only be traversed in the forward direction. + * + * A circle queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or after + * an existing element, at the head of the list, or at the end of the list. + * A circle queue may be traversed in either direction, but has a more + * complex end of list detection. + * + * For details on the use of these macros, see the queue(3) manual page. + * + * SLIST LIST STAILQ TAILQ CIRCLEQ + * _HEAD + + + + + + * _ENTRY + + + + + + * _INIT + + + + + + * _EMPTY + + + + + + * _FIRST + + + + + + * _NEXT + + + + + + * _PREV - - - + + + * _LAST - - + + + + * _FOREACH + + - + + + * _INSERT_HEAD + + + + + + * _INSERT_BEFORE - + - + + + * _INSERT_AFTER + + + + + + * _INSERT_TAIL - - + + + + * _REMOVE_HEAD + - + - - + * _REMOVE + + + + + + * + */ + +/* + * Singly-linked List definitions. + */ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +/* + * Singly-linked List functions. + */ +#define SLIST_EMPTY(head) ((head)->slh_first == NULL) + +#define SLIST_FIRST(head) ((head)->slh_first) + +#define SLIST_FOREACH(var, head, field) \ + for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next) + +#define SLIST_INIT(head) { \ + (head)->slh_first = NULL; \ +} + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + (elm)->field.sle_next = (slistelm)->field.sle_next; \ + (slistelm)->field.sle_next = (elm); \ +} while (0) + +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.sle_next = (head)->slh_first; \ + (head)->slh_first = (elm); \ +} while (0) + +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#define SLIST_REMOVE_HEAD(head, field) do { \ + (head)->slh_first = (head)->slh_first->field.sle_next; \ +} while (0) + +#define SLIST_REMOVE(head, elm, type, field) do { \ + if ((head)->slh_first == (elm)) { \ + SLIST_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = (head)->slh_first; \ + while( curelm->field.sle_next != (elm) ) \ + curelm = curelm->field.sle_next; \ + curelm->field.sle_next = \ + curelm->field.sle_next->field.sle_next; \ + } \ +} while (0) + +/* + * Singly-linked Tail queue definitions. + */ +#define STAILQ_HEAD(name, type) \ +struct name { \ + struct type *stqh_first; /* first element */ \ + struct type **stqh_last; /* addr of last next element */ \ +} + +#define STAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).stqh_first } + +#define STAILQ_ENTRY(type) \ +struct { \ + struct type *stqe_next; /* next element */ \ +} + +/* + * Singly-linked Tail queue functions. + */ +#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) + +#define STAILQ_INIT(head) do { \ + (head)->stqh_first = NULL; \ + (head)->stqh_last = &(head)->stqh_first; \ +} while (0) + +#define STAILQ_FIRST(head) ((head)->stqh_first) +#define STAILQ_LAST(head) (*(head)->stqh_last) + +#define STAILQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \ + (head)->stqh_last = &(elm)->field.stqe_next; \ + (head)->stqh_first = (elm); \ +} while (0) + +#define STAILQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.stqe_next = NULL; \ + *(head)->stqh_last = (elm); \ + (head)->stqh_last = &(elm)->field.stqe_next; \ +} while (0) + +#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ + if (((elm)->field.stqe_next = (tqelm)->field.stqe_next) == NULL) \ + (head)->stqh_last = &(elm)->field.stqe_next; \ + (tqelm)->field.stqe_next = (elm); \ +} while (0) + +#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) + +#define STAILQ_REMOVE_HEAD(head, field) do { \ + if (((head)->stqh_first = \ + (head)->stqh_first->field.stqe_next) == NULL) \ + (head)->stqh_last = &(head)->stqh_first; \ +} while (0) + +#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \ + if (((head)->stqh_first = (elm)->field.stqe_next) == NULL) \ + (head)->stqh_last = &(head)->stqh_first; \ +} while (0) + +#define STAILQ_REMOVE(head, elm, type, field) do { \ + if ((head)->stqh_first == (elm)) { \ + STAILQ_REMOVE_HEAD(head, field); \ + } \ + else { \ + struct type *curelm = (head)->stqh_first; \ + while( curelm->field.stqe_next != (elm) ) \ + curelm = curelm->field.stqe_next; \ + if((curelm->field.stqe_next = \ + curelm->field.stqe_next->field.stqe_next) == NULL) \ + (head)->stqh_last = &(curelm)->field.stqe_next; \ + } \ +} while (0) + +/* + * List definitions. + */ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List functions. + */ + +#define LIST_EMPTY(head) ((head)->lh_first == NULL) + +#define LIST_FIRST(head) ((head)->lh_first) + +#define LIST_FOREACH(var, head, field) \ + for((var) = (head)->lh_first; (var); (var) = (var)->field.le_next) + +#define LIST_INIT(head) do { \ + (head)->lh_first = NULL; \ +} while (0) + +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ + if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ + (listelm)->field.le_next->field.le_prev = \ + &(elm)->field.le_next; \ + (listelm)->field.le_next = (elm); \ + (elm)->field.le_prev = &(listelm)->field.le_next; \ +} while (0) + +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.le_prev = (listelm)->field.le_prev; \ + (elm)->field.le_next = (listelm); \ + *(listelm)->field.le_prev = (elm); \ + (listelm)->field.le_prev = &(elm)->field.le_next; \ +} while (0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.le_next = (head)->lh_first) != NULL) \ + (head)->lh_first->field.le_prev = &(elm)->field.le_next; \ + (head)->lh_first = (elm); \ + (elm)->field.le_prev = &(head)->lh_first; \ +} while (0) + +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + +#define LIST_REMOVE(elm, field) do { \ + if ((elm)->field.le_next != NULL) \ + (elm)->field.le_next->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = (elm)->field.le_next; \ +} while (0) + +/* + * Tail queue definitions. + */ +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ +} + +#define TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first } + +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ +} + +/* + * Tail queue functions. + */ +#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) + +#define TAILQ_FOREACH(var, head, field) \ + for (var = TAILQ_FIRST(head); var; var = TAILQ_NEXT(var, field)) + +#define TAILQ_FOREACH_REVERSE(var, head, field, headname) \ + for (var = TAILQ_LAST(head, headname); \ + var; var = TAILQ_PREV(var, headname, field)) + +#define TAILQ_FIRST(head) ((head)->tqh_first) + +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) + +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) + +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) + +#define TAILQ_INIT(head) do { \ + (head)->tqh_first = NULL; \ + (head)->tqh_last = &(head)->tqh_first; \ +} while (0) + +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ + if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ + (head)->tqh_first->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (head)->tqh_first = (elm); \ + (elm)->field.tqe_prev = &(head)->tqh_first; \ +} while (0) + +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.tqe_next = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &(elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL) \ + (elm)->field.tqe_next->field.tqe_prev = \ + &(elm)->field.tqe_next; \ + else \ + (head)->tqh_last = &(elm)->field.tqe_next; \ + (listelm)->field.tqe_next = (elm); \ + (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ +} while (0) + +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + (elm)->field.tqe_next = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ +} while (0) + +#define TAILQ_REMOVE(head, elm, field) do { \ + if (((elm)->field.tqe_next) != NULL) \ + (elm)->field.tqe_next->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ +} while (0) + +/* + * Circular queue definitions. + */ +#define CIRCLEQ_HEAD(name, type) \ +struct name { \ + struct type *cqh_first; /* first element */ \ + struct type *cqh_last; /* last element */ \ +} + +#define CIRCLEQ_ENTRY(type) \ +struct { \ + struct type *cqe_next; /* next element */ \ + struct type *cqe_prev; /* previous element */ \ +} + +/* + * Circular queue functions. + */ +#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head)) + +#define CIRCLEQ_FIRST(head) ((head)->cqh_first) + +#define CIRCLEQ_FOREACH(var, head, field) \ + for((var) = (head)->cqh_first; \ + (var) != (void *)(head); \ + (var) = (var)->field.cqe_next) + +#define CIRCLEQ_INIT(head) do { \ + (head)->cqh_first = (void *)(head); \ + (head)->cqh_last = (void *)(head); \ +} while (0) + +#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ + (elm)->field.cqe_next = (listelm)->field.cqe_next; \ + (elm)->field.cqe_prev = (listelm); \ + if ((listelm)->field.cqe_next == (void *)(head)) \ + (head)->cqh_last = (elm); \ + else \ + (listelm)->field.cqe_next->field.cqe_prev = (elm); \ + (listelm)->field.cqe_next = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \ + (elm)->field.cqe_next = (listelm); \ + (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ + if ((listelm)->field.cqe_prev == (void *)(head)) \ + (head)->cqh_first = (elm); \ + else \ + (listelm)->field.cqe_prev->field.cqe_next = (elm); \ + (listelm)->field.cqe_prev = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \ + (elm)->field.cqe_next = (head)->cqh_first; \ + (elm)->field.cqe_prev = (void *)(head); \ + if ((head)->cqh_last == (void *)(head)) \ + (head)->cqh_last = (elm); \ + else \ + (head)->cqh_first->field.cqe_prev = (elm); \ + (head)->cqh_first = (elm); \ +} while (0) + +#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \ + (elm)->field.cqe_next = (void *)(head); \ + (elm)->field.cqe_prev = (head)->cqh_last; \ + if ((head)->cqh_first == (void *)(head)) \ + (head)->cqh_first = (elm); \ + else \ + (head)->cqh_last->field.cqe_next = (elm); \ + (head)->cqh_last = (elm); \ +} while (0) + +#define CIRCLEQ_LAST(head) ((head)->cqh_last) + +#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next) + +#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev) + +#define CIRCLEQ_REMOVE(head, elm, field) do { \ + if ((elm)->field.cqe_next == (void *)(head)) \ + (head)->cqh_last = (elm)->field.cqe_prev; \ + else \ + (elm)->field.cqe_next->field.cqe_prev = \ + (elm)->field.cqe_prev; \ + if ((elm)->field.cqe_prev == (void *)(head)) \ + (head)->cqh_first = (elm)->field.cqe_next; \ + else \ + (elm)->field.cqe_prev->field.cqe_next = \ + (elm)->field.cqe_next; \ +} while (0) + +#endif /* !_SYS_QUEUE_H_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/rt.c arpon-3.0-ng+dfsg1/src/rt.c --- arpon-2.7.2/src/rt.c 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/rt.c 2016-01-29 02:01:07.000000000 +0000 @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: rt.c,v 3.0-ng 01/29/2016 03:01:08 spikey Exp $ + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include "msg.h" +#include "rt.h" + +/* + * Nanoseconds to seconds. + */ +#define RT_NANOTOSECS 1000000000.0 + +/* + * Microseconds to seconds. + */ +#define RT_MICROTOSECS 1000000.0 + +/* + * Retrieve the normalized current local time with max high precision. + */ +double +rt_getlocaltime(void) +{ +#if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0) + struct timespec ts; + double time; +#if defined(CLOCK_MONOTONIC_RAW) + /* + * Monotonic time measure with access to a raw hardware-based time. + * + * This clock is not affected by discontinuous jumps in the system time + * (e.g., if the system administrator manually changes the clock) and it + * is not affected by the incremental adjustments performed by adjtime + * and NTP. + */ + const clockid_t id = CLOCK_MONOTONIC_RAW; + + MSG_DEBUG("Retrieve monotonic_raw time measure.."); +#elif defined(CLOCK_MONOTONIC) + /* + * Monotonic time measure. + * + * This clock is not affected by discontinuous jumps in the system time + * (e.g., if the system administrator manually changes the clock), but + * is affected by the incremental adjustments performed by adjtime + * and NTP. + */ + const clockid_t id = CLOCK_MONOTONIC; + + MSG_DEBUG("Retrieve monotonic time measure.."); +#else /* !CLOCK_* */ + /* + * System-wide clock that measures the real time. + * + * This clock is affected by discontinuous jumps in the system time + * (e.g., if the system administrator manually changes the clock), and + * by the incremental adjustments performed by adjtime and NTP. + */ + const clockid_t id = CLOCK_REALTIME; + + MSG_DEBUG("Retrieve realtime measure with clock_gettime().."); +#endif /* CLOCK_* */ + + /* + * Retrieve the current local time with + * the precision of the specified id. + */ + if (clock_gettime(id, &ts) < 0) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } + + /* Normalize the current local time to seconds. */ + time = (double)ts.tv_sec + (double)ts.tv_nsec / RT_NANOTOSECS; +#else /* !_POSIX_TIMERS */ + struct timeval tm; + double time; + + /* + * System-wide clock that measures the real time. + * + * This clock is affected by discontinuous jumps in the system time + * (e.g., if the system administrator manually changes the clock), and + * by the incremental adjustments performed by adjtime and NTP. + */ + MSG_DEBUG("Retrieve realtime measure with gettimeofday().."); + + /* Retrieve the current local time with the realtime precision. */ + if (gettimeofday(&tm, NULL) < 0) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } + + /* Normalize the current local time to seconds. */ + time = (double)tm.tv_sec + (double)tm.tv_usec / RT_MICROTOSECS; +#endif /* _POSIX_TIMERS */ + + MSG_DEBUG("time = %lf", time); + + return time; +} + +/* + * Measure the elapsed time between two retrieved normalized local times. + */ +double +rt_difftime(double timeend, double timestart) +{ + double timeelapsed; + + MSG_DEBUG("timeend = %lf", timeend); + MSG_DEBUG("timestart = %lf", timestart); + + /* Measure the elapsed time between two retrieved normalized local times. */ + timeelapsed = timeend - timestart; + + MSG_DEBUG("timeelapsed = %lf", timeelapsed); + + return timeelapsed; +} + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/rt.h arpon-3.0-ng+dfsg1/src/rt.h --- arpon-2.7.2/src/rt.h 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/rt.h 2016-01-29 01:58:27.000000000 +0000 @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: rt.h,v 3.0-ng 01/29/2016 02:58:27 spikey Exp $ + */ + +#ifndef _RT_H_ +#define _RT_H_ + +/* + * Function prototype exported. + */ +extern double rt_getlocaltime(void); +extern double rt_difftime(double timeend, double timestart); + +#endif /* !_RT_H_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/sarpi.c arpon-3.0-ng+dfsg1/src/sarpi.c --- arpon-2.7.2/src/sarpi.c 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/sarpi.c 2016-01-29 02:03:54.000000000 +0000 @@ -0,0 +1,228 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: sarpi.c,v 3.0-ng 01/29/2016 03:03:55 spikey Exp $ + */ + +#include +#include +#include +#include + +#include +#include +#include + +#include "arpca.h" +#include "intf.h" +#include "ispn.h" +#include "msg.h" +#include "opt.h" +#include "sarpica.h" +#include "sarpi.h" +#include "unused.h" + +/* + * SARPI live capture handler of the I/O ARP packets + * read from the network traffic of the interface. + */ +void +sarpi_handler(int op, struct ether_addr *macsrc, struct in_addr *ipsrc, + UNUSED(struct ether_addr *macdst), UNUSED(struct in_addr *ipdst)) +{ + + do { + char smacsrc[INTF_ETHERSTRLEN], sipsrc[INET_ADDRSTRLEN], + UNUSED(smacdst[INTF_ETHERSTRLEN]), UNUSED(sipdst[INET_ADDRSTRLEN]), + *interface = NULL; + struct ether_addr *macentry = NULL; + + MSG_DEBUG("Start SARPI live capture handler"); + + /* Get the interface name command option. */ + interface = opt_getinterface(); + + /* MAC src addr network byte order to string. */ + strncpy(smacsrc, ether_ntoa(macsrc), INTF_ETHERSTRLEN); + + /* IP src addr network byte order to string. */ + strncpy(sipsrc, inet_ntoa(*ipsrc), INET_ADDRSTRLEN); + +#ifndef NDEBUG + /* MAC dst addr network byte order to string. */ + strncpy(smacdst, ether_ntoa(macdst), INTF_ETHERSTRLEN); + + /* IP dst addr network byte order to string. */ + strncpy(sipdst, inet_ntoa(*ipdst), INET_ADDRSTRLEN); +#endif /* !NDEBUG */ + + /* Check the type of the ARP packet read. */ + if (op & INTF_ARPOP_REQUEST) { + /* + * Check the I/O bound direction of the ARP request + * packet read (sent by us or sent to us). + */ + if (op & INTF_ARPOP_OUTBOUND) { + /* + * Check if the ARP request packet is a gratuitous + * ARP request packet, probe ARP request packet or + * simple ARP request packet. + */ + if (op & INTF_ARPOP_GRATUITOUS) { + /* Gratuitous ARP request packet to outbound. */ + INTF_OUTBOUND("Gratuitous ARP request"); + } else if (op & INTF_ARPOP_PROBE) { + /* Probe ARP request packet to outbound. */ + INTF_OUTBOUND("Probe ARP request"); + } else { + /* Simple ARP request packet to outbound. */ + INTF_OUTBOUND("ARP request"); + } + + /* Break immediately. */ + break; + } else if (op & INTF_ARPOP_INBOUND) { + /* + * Check if the ARP request packet is a gratuitous + * ARP request packet, probe ARP request packet or + * simple ARP request packet. + */ + if (op & INTF_ARPOP_GRATUITOUS) { + /* Gratuitous ARP request packet from inbound. */ + INTF_INBOUND("Gratuitous ARP request"); + } else if (op & INTF_ARPOP_PROBE) { + /* Probe ARP request packet from inbound. */ + INTF_INBOUND("Probe ARP request"); + + /* + * Send a probe ARP reply to source IP (with MAC + * broadcast) address of the ARP request packet + * (in the next ARP packet read, follow the + * outbound ARP reply). + */ + intf_inject(ARPOP_REPLY, ipsrc); + + /* Break immediately. */ + break; + } else { + /* Simple ARP request packet from inbound. */ + INTF_INBOUND("ARP request"); + + /* + * Send an ARP reply to source IP (with MAC broadcast) + * address of the ARP request packet (in the next ARP + * packet read, follow the outbound ARP reply). + */ + intf_inject(ARPOP_REPLY, ipsrc); + } + } + } else if (op & INTF_ARPOP_REPLY) { + /* + * Check the I/O bound direction of the ARP reply + * packet read (sent by us or sent to us). + */ + if (op & INTF_ARPOP_OUTBOUND) { + /* + * Check if the ARP reply packet is a gratuitous + * ARP reply packet, probe ARP reply packet or + * simple ARP reply packet. + */ + if (op & INTF_ARPOP_GRATUITOUS) { + /* Gratuitous ARP reply packet to outbound. */ + INTF_OUTBOUND("Gratuitous ARP reply"); + } else if (op & INTF_ARPOP_PROBE) { + /* Probe ARP reply packet to outbound. */ + INTF_OUTBOUND("Probe ARP reply"); + } else { + /* Simple ARP reply packet to outbound. */ + INTF_OUTBOUND("ARP reply"); + } + + /* Break immediately. */ + break; + } else if (op & INTF_ARPOP_INBOUND) { + /* + * Check if the ARP reply packet is a gratuitous + * ARP reply packet, probe ARP reply packet or + * simple ARP reply packet. + */ + if (op & INTF_ARPOP_GRATUITOUS) { + /* Gratuitous ARP reply packet from inbound. */ + INTF_INBOUND("Gratuitous ARP reply"); + } else if (op & INTF_ARPOP_PROBE) { + /* Probe ARP reply packet from inbound. */ + INTF_INBOUND("Probe ARP reply"); + + /* Break immediately. */ + break; + } else { + /* Simple ARP reply packet from inbound. */ + INTF_INBOUND("ARP reply"); + } + } + } + + /* + * Check if the source IP address of the ARP packet + * exists in the SARPI cache. + */ + if ((macentry = sarpica_ismember(ipsrc)) == NULL) { + /* + * Overwrite the not permanent IP entry in the ARP cache of + * the source IP address of the ARP packet with the same + * source addresses (POLICY: ALLOW). + */ + arpca_overwrite(macsrc, ipsrc, ARPCA_NOTPERMANENT); + + /* Print the ALLOW policy info message. */ + ISPN_ALLOW(sipsrc, smacsrc); + } else { + char *smacentry = NULL; + + /* + * Overwrite the permanent IP entry in the ARP cache of the + * source IP address of the ARP packet with the + * entry from the SARPI cache (POLICY: REFRESH). + */ + arpca_overwrite(macentry, ipsrc, ARPCA_PERMANENT); + + /* MAC entry addr network byte order to string. */ + smacentry = ether_ntoa(macentry); + + /* Print the REFRESH policy info message. */ + ISPN_REFRESH(sipsrc, smacentry); + } + } while (0); + + MSG_DEBUG("End SARPI live capture handler"); +} + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/sarpica.c arpon-3.0-ng+dfsg1/src/sarpica.c --- arpon-2.7.2/src/sarpica.c 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/sarpica.c 2016-01-29 02:09:44.000000000 +0000 @@ -0,0 +1,516 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: sarpica.c,v 3.0-ng 01/29/2016 03:09:44 spikey Exp $ + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "arpca.h" +#include "config.h" +#include "exit.h" +#include "intf.h" +#include "ispn.h" +#include "msg.h" +#include "opt.h" +#include "queue.h" +#include "sarpica.h" +#include "thd.h" +#include "unused.h" + +/* + * Configuration file permissions to 644. + */ +#define SARPICA_ETCPERMS S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH + +/* + * Max configuration file line length. + */ +#define SARPICA_LINESIZE 512 /* 512 bytes. */ + +/* + * SARPI timeout of the SARPI cache + * (Expiry for each loop of the SARPI cache handler). + */ +#define SARPICA_LOOPTIMEOUT 600 /* 600 seconds = 10 minuts. */ + +/* + * SARPI cache queue structure definition. + */ +typedef struct sca_queue { + struct ether_addr mac; /* SARPI cache MAC addr entry. */ + struct in_addr ip; /* SARPI cache IP addr entry. */ + + TAILQ_ENTRY(sca_queue) next; /* Next SARPI cache queue element. */ +} sca_t; + +/* + * Function prototypes not exported. + */ +static void sarpica_init(void); +static void sarpica_destroy(void); +static void sarpica_dequeuetop(void); +static FILE *sarpica_initconf(void); +static void sarpica_loadconf(FILE *conf); +static void sarpica_enqueue(struct ether_addr *mac, struct in_addr *ip); +static void sarpica_destroyconf(FILE **conf); +static void *sarpica_handler(void *arg); + +/* + * Initialize the SARPI cache queue structure. + */ +static TAILQ_HEAD(sca, sca_queue) sca_head = TAILQ_HEAD_INITIALIZER(sca_head); + +/* + * Configure the SARPI cache. + */ +void +sarpica_configure(void) +{ + FILE *conf = NULL; + + MSG_DEBUG("Start SARPI cache configure"); + + /* Initialize the SARPI cache queue structure. */ + sarpica_init(); + + /* Initialize the configuration file stream. */ + conf = sarpica_initconf(); + + /* Load the SARPI cache queue structure from the config file stream. */ + sarpica_loadconf(conf); + + /* Destroy the configuration file stream. */ + sarpica_destroyconf(&conf); + + /* Register the SARPI cache handler thread. */ + thd_register(sarpica_handler, NULL, "sarpica_handler"); + + MSG_DEBUG("End SARPI cache configure"); +} + +/* + * Initialize the SARPI cache queue structure. + */ +static void +sarpica_init(void) +{ + + /* Set the SARPI cache queue structure to NULL. */ + TAILQ_INIT(&sca_head); + MSG_DEBUG("Initialize SARPI cache queue successful"); + + /* Push sarpica_destroy() to be called on exit_clean(). */ + exit_push(sarpica_destroy, "sarpica_destroy"); +} + +/* + * Destroy the SARPI cache queue structure. + */ +static void +sarpica_destroy(void) +{ + + /* No empty SARPI cache queue structure? */ + if (TAILQ_EMPTY(&sca_head) == 0) { + /* Loop until the SARPI cache queue structure is empty. */ + do { + /* Dequeue the SARPI cache entry. */ + sarpica_dequeuetop(); + } while (TAILQ_EMPTY(&sca_head) == 0); + + /* Re-initialize the SARPI cache queue structure to NULL. */ + TAILQ_INIT(&sca_head); + } + + MSG_DEBUG("Destroy SARPI cache queue successful"); +} + +/* + * Dequeue the SARPI cache queue element from the SARPI cache queue structure. + */ +static void +sarpica_dequeuetop(void) +{ + sca_t *cur = NULL; + char UNUSED(*smac) = NULL, UNUSED(*sip) = NULL; + + /* Get the first SARPI cache queue element. */ + cur = TAILQ_FIRST(&sca_head); + + /* Dequeue the first SARPI cache queue element. */ + TAILQ_REMOVE(&sca_head, cur, next); + +#ifndef NDEBUG + /* Get the SARPI cache MAC addr entry. */ + smac = ether_ntoa(&cur->mac); +#endif /* !NDEBUG */ + + MSG_DEBUG("cur->mac = %s", smac); + +#ifndef NDEBUG + /* Get the SARPI cache IP addr entry. */ + sip = inet_ntoa(cur->ip); +#endif /* !NDEBUG */ + + MSG_DEBUG("cur->ip = %s", sip); + + /* Deallocate the SARPI cache queue element. */ + free(cur); + + MSG_DEBUG("sca_t *cur deallocate from the memory"); + MSG_DEBUG("Dequeue <%s, %s> SARPI cache entry successful", smac, sip); +} + +/* + * Initialize the configuration file stream. + */ +static FILE * +sarpica_initconf(void) +{ + + do { + struct stat stats; + FILE *conf = NULL; + + /* Check if the configuration file exist. */ + if (stat(ETC_FILE, &stats) < 0) { + if (errno == ENOENT) { + MSG_WARN("%s is not exist", ETC_FILE); + exit(EXIT_FAILURE); + } else { + break; + } + } + + /* Check if the configuration file is a regular file. */ + if (S_ISREG(stats.st_mode) == 0) { + MSG_WARN("%s is not a regular file", ETC_FILE); + exit(EXIT_FAILURE); + } + + /* Fix the configuration file perms to 644. */ + if (chmod(ETC_FILE, SARPICA_ETCPERMS) < 0) + break; + + /* Open the configuration file stream to read. */ + if ((conf = fopen(ETC_FILE, "r")) == NULL) + break; + + MSG_DEBUG("Open %s successful", ETC_FILE); + + return conf; + } while (0); + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Add the entries in the SARPI cache queue structure + * with the entries from the configuration file stream. + */ +static void +sarpica_loadconf(FILE *conf) +{ + char line[SARPICA_LINESIZE]; + int linenum = 0; + + MSG_DEBUG("Start configuration file loader"); + + /* Loop until the end of configuration file is reached. */ + while (fgets(line, SARPICA_LINESIZE, conf) != NULL) { + char sip[INET_ADDRSTRLEN], smac[INTF_ETHERSTRLEN]; + struct in_addr ip; + struct ether_addr *mac = NULL; + char *p = NULL, *q = NULL; + uint32_t network, netmask; + + /* Update the line number counter. */ + linenum++; + + /* Skip the comment line. */ + if (strchr(line, '#') != NULL) + continue; + + /* Trim out the new line. */ + if ((p = strchr(line, '\n'))) + *p = '\0'; + + /* Set q pointer to line. */ + q = line; + + /* Trim out the initial spaces of the line. */ + while (q < line + sizeof(line) && *q == ' ') + q++; + + /* Skip the empty line. */ + if (line[0] == '\0' || *q == '\0') + continue; + + /* Get the IP and MAC addrs from the line. */ + if (sscanf(q, "%15s %17s", sip, smac) != 2) { + MSG_WARN("Invalid line in %s at %d line", ETC_FILE, linenum); + exit(EXIT_FAILURE); + } + + /* MAC addr string to MAC addr network byte order. */ + if ((mac = ether_aton(smac)) == NULL) { + MSG_WARN("Invalid MAC address in %s at %d line", ETC_FILE, linenum); + exit(EXIT_FAILURE); + } + + /* IP addr string to IP addr network byte order. */ + if (inet_aton(sip, &ip) == 0) { + MSG_WARN("Invalid IP address in %s at %d line", ETC_FILE, linenum); + exit(EXIT_FAILURE); + } + + /* Get the Net addr from the interface. */ + network = (intf_getnetwork())->s_addr; + + /* Get the Mask addr from the interface. */ + netmask = (intf_getnetmask())->s_addr; + + /* + * IP entry is not part of the same network of the interface? + * Therefore: + * + * IP entry is not part of the same network of the interface = + * (IP entry addr & Interface Mask addr) != Interface Net addr + */ + if ((ip.s_addr & netmask) != network) { + MSG_DEBUG("Skip line read = %s %s", sip, smac); + continue; + } + + MSG_DEBUG("Line read = %s %s", sip, smac); + + /* Add the entry in the SARPI cache queue structure. */ + sarpica_enqueue(mac, &ip); + } + + MSG_DEBUG("End configuration file loader"); +} + +/* + * Enqueue the SARPI cache queue element in the SARPI cache queue structure. + */ +static void +sarpica_enqueue(struct ether_addr *mac, struct in_addr *ip) +{ + sca_t *new = NULL; + char UNUSED(*smac) = NULL, UNUSED(*sip) = NULL; + + /* Allocate the SARPI cache queue element. */ + if ((new = (sca_t *)malloc(sizeof(sca_t))) == NULL) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("sca_t *new allocate in the memory"); + + /* Initialize the SARPI cache MAC addr entry. */ + new->mac = *mac; + +#ifndef NDEBUG + /* MAC addr network byte order to string. */ + smac = ether_ntoa(&new->mac); +#endif /* !NDEBUG */ + + MSG_DEBUG("new->mac = %s", smac); + + /* Initialize the SARPI cache IP addr entry. */ + new->ip = *ip; + +#ifndef NDEBUG + /* IP addr network byte order to string. */ + sip = inet_ntoa(new->ip); +#endif /* !NDEBUG */ + + MSG_DEBUG("new->ip = %s", sip); + + /* Empty SARPI cache queue structure? */ + if (TAILQ_EMPTY(&sca_head) != 0) { + /* Enqueue the SARPI cache queue element in the head. */ + TAILQ_INSERT_HEAD(&sca_head, new, next); + MSG_DEBUG("H-Enqueue <%s, %s> SARPI cache entry successful", smac, sip); + } else { + /* Enqueue the SARPI cache queue element in the tail. */ + TAILQ_INSERT_TAIL(&sca_head, new, next); + MSG_DEBUG("T-Enqueue <%s, %s> SARPI cache entry successful", smac, sip); + } +} + +/* + * Find a SARPI cache queue element in the SARPI cache queue structure. + */ +struct ether_addr * +sarpica_ismember(struct in_addr *ip) +{ + char UNUSED(*smac) = NULL, UNUSED(*sip) = NULL; + + /* No empty SARPI cache queue structure? */ + if (TAILQ_EMPTY(&sca_head) == 0) { + sca_t *cur = NULL; + + /* Looking the IP addr in the SARPI cache queue structure. */ + TAILQ_FOREACH(cur, &sca_head, next) { + if (ip->s_addr == cur->ip.s_addr) { +#ifndef NDEBUG + /* + * IP addr network byte order of the + * SARPI cache queue element to string. + */ + sip = inet_ntoa(cur->ip); + + /* + * MAC addr network byte order of the + * SARPI cache queue element to string. + */ + smac = ether_ntoa(&cur->mac); +#endif /* !NDEBUG */ + + /* IP addr found, it is a SARPI cache queue element. */ + MSG_DEBUG("<%s, %s> SARPI cache entry found", smac, sip); + + return &cur->mac; + } + } + } + +#ifndef NDEBUG + /* IP addr network byte order to string. */ + sip = inet_ntoa(*ip); +#endif /* !NDEBUG */ + + /* IP addr not found, it is not a SARPI cache queue element. */ + MSG_DEBUG("<%s> SARPI cache entry not found", sip); + + return NULL; +} + +/* + * Destroy the configuration file stream. + */ +static void +sarpica_destroyconf(FILE **conf) +{ + + /* Close the configuration file stream. */ + if (fclose(*conf) == EOF) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } + + /* Set the configuration file stream to NULL. */ + *conf = NULL; + + MSG_DEBUG("Close %s successful", ETC_FILE); +} + +/* + * Overwrite the IP entries in the ARP cache with the + * entries from the SARPI cache queue structure. + */ +static void * +sarpica_handler(UNUSED(void *arg)) +{ + char *interface = NULL; + + /* Initialize the thread. */ + thd_init(); + + MSG_DEBUG("Start SARPI cache handler"); + + /* Get the interface name command option. */ + interface = opt_getinterface(); + + /* Loop each time that the SARPI timeout of the SARPI cache expires. */ + while (1) { + /* No empty SARPI cache queue structure? */ + if (TAILQ_EMPTY(&sca_head) == 0) { + sca_t *cur = NULL; + + MSG_DEBUG("Update of the static entries from the SARPI cache.."); + + /* + * Update all the IP entries in the ARP cache with the + * entries from the SARPI cache queue structure. + */ + TAILQ_FOREACH(cur, &sca_head, next) { + char *smac = NULL, *sip = NULL; + + /* SARPI cache MAC addr entry network byte order to string. */ + smac = ether_ntoa(&cur->mac); + + /* SARPI cache IP addr entry network byte order to string. */ + sip = inet_ntoa(cur->ip); + + /* + * Overwrite the permanent IP entry in the ARP + * cache with the entry from the SARPI + * cache queue structure (POLICY: UPDATE). + */ + arpca_overwrite(&cur->mac, &cur->ip, ARPCA_PERMANENT); + + /* Print the UPDATE policy info message. */ + ISPN_UPDATE(sip, smac); + } + } else { + /* Empty SARPI cache queue structure. */ + MSG_DEBUG("No update of the static entries from the SARPI cache"); + } + + /* + * Suspend the execution of the calling thread until the + * SARPI timeout of the SARPI cache expires (600 seconds). + */ + thd_suspend(SARPICA_LOOPTIMEOUT); + } + + /* Never reaches here. */ + return NULL; +} + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/sarpica.h arpon-3.0-ng+dfsg1/src/sarpica.h --- arpon-2.7.2/src/sarpica.h 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/sarpica.h 2016-01-29 02:08:21.000000000 +0000 @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: sarpica.h,v 3.0-ng 01/29/2016 03:08:22 spikey Exp $ + */ + +#ifndef _SARPICA_H_ +#define _SARPICA_H_ + +/* + * Function prototype exported. + */ +extern void sarpica_configure(void); +extern struct ether_addr *sarpica_ismember(struct in_addr *ip); + +#endif /* !_SARPICA_H_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/sarpi.h arpon-3.0-ng+dfsg1/src/sarpi.h --- arpon-2.7.2/src/sarpi.h 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/sarpi.h 2016-01-29 02:02:10.000000000 +0000 @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: sarpi.h,v 3.0-ng 01/29/2016 03:02:11 spikey Exp $ + */ + +#ifndef _SARPI_H_ +#define _SARPI_H_ + +/* + * Function prototype exported. + */ +extern void sarpi_handler(int op, struct ether_addr *macsrc, + struct in_addr *ipsrc, struct ether_addr *macdst, struct in_addr *ipdst); + +#endif /* !_SARPI_H_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/sig.c arpon-3.0-ng+dfsg1/src/sig.c --- arpon-2.7.2/src/sig.c 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/sig.c 2016-01-29 02:06:37.000000000 +0000 @@ -0,0 +1,329 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: sig.c,v 3.0-ng 01/29/2016 03:06:38 spikey Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "config.h" +#include "env.h" +#include "exit.h" +#include "msg.h" +#include "sig.h" + +/* + * Integer signal to string. + */ +#define SIG_ITOA(x) x == SIGINT ? "interrupt signal" : \ + x == SIGTERM ? "termination signal" : \ + x == SIGHUP ? "hangup signal" : \ + x == SIGSEGV ? "segmentation fault signal" : \ + x == SIGBUS ? "bus error signal" : "unknown signal" + +/* + * Function prototypes not exported. + */ +static void sig_init(void); +static void sig_destroy(void); +static void sig_setblockmask(void); +static void sig_loop(char **argv, char **envp); +static void sig_handleterm(int sig); +static void sig_handlehup(char **argv, char **envp); +static void sig_handlebug(int sig); + +/* + * Initialize the signal mask. + */ +static sigset_t mask = {{0}}; + +/* + * Initialize and handle the signal. + */ +void +sig_handle(char **argv, char **envp) +{ + + MSG_DEBUG("Start signal handle"); + + /* Initialize the signal mask. */ + sig_init(); + + /* Set and block the signal mask. */ + sig_setblockmask(); + + /* Handle the signal masked. */ + sig_loop(argv, envp); +} + +/* + * Initialize the signal mask. + */ +static void +sig_init(void) +{ + + /* Initialize the signal mask. */ + if (sigemptyset(&mask) < 0) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("Initialize signal mask successful"); + + /* Push sig_destroy() to be called on exit_cleanup(). */ + exit_push(sig_destroy, "sig_destroy"); +} + +/* + * Destroy and unblock the signal mask. + */ +static void +sig_destroy(void) +{ + + do { + /* Unblock the signal mask. */ + if (pthread_sigmask(SIG_UNBLOCK, &mask, NULL) != 0) + break; + + /* Destroy the signal mask. */ + if (sigemptyset(&mask) < 0) + break; + + MSG_DEBUG("Unblock signal mask successful"); + + return; + } while (0); + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Set and block the value of the signal mask. + */ +static void +sig_setblockmask(void) +{ + + do { + /* Add the interrupt signal in the signal mask. */ + if (sigaddset(&mask, SIGINT) < 0) + break; + + MSG_DEBUG("Add %s to signal mask..", SIG_ITOA(SIGINT)); + + /* Add the termination signal in the signal mask. */ + if (sigaddset(&mask, SIGTERM) < 0) + break; + + MSG_DEBUG("Add %s to signal mask..", SIG_ITOA(SIGTERM)); + + /* Add the hangup signal in the signal mask. */ + if (sigaddset(&mask, SIGHUP) < 0) + break; + + MSG_DEBUG("Add %s to signal mask..", SIG_ITOA(SIGHUP)); + + /* Add the segmentation fault signal in the signal mask. */ + if (sigaddset(&mask, SIGSEGV) < 0) + break; + + MSG_DEBUG("Add %s to signal mask..", SIG_ITOA(SIGSEGV)); + + /* Add the bus error signal in the signal mask. */ + if (sigaddset(&mask, SIGBUS) < 0) + break; + + MSG_DEBUG("Add %s to signal mask...", SIG_ITOA(SIGBUS)); + + /* Block the signal mask. */ + if (pthread_sigmask(SIG_BLOCK, &mask, NULL) != 0) + break; + + MSG_DEBUG("Block signal mask successful"); + + return; + } while (0); + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Handle the signal masked. + */ +static void +sig_loop(char **argv, char **envp) +{ + + /* Loop until a signal is caught. */ + while (1) { + int sig; + + /* Suspend the execution of the main thread until a signal is caught. */ + if (sigwait(&mask, &sig) != 0) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } + + /* Handle the signal caught of the main thread. */ + switch(sig) { + case SIGINT: + /* Remove ^C symbol from the output terminal. */ + printf("\r"); + + case SIGTERM: + MSG_DEBUG("Caught %s (%d)..", SIG_ITOA(sig), sig); + + /* Handle the interrupt or termination signal. */ + sig_handleterm(sig); + + /* Never reaches here. */ + break; + + case SIGHUP: + MSG_DEBUG("Caught %s (%d)..", SIG_ITOA(sig), sig); + + /* Handle the hangup signal. */ + sig_handlehup(argv, envp); + + /* Never reaches here. */ + break; + + case SIGSEGV: + case SIGBUS: + MSG_DEBUG("Caught %s (%d)..", SIG_ITOA(sig), sig); + + /* Handle the segmentation fault or bus error signal. */ + sig_handlebug(sig); + + /* Never reaches here. */ + break; + + default: + MSG_DEBUG("Caught no valid %s (%d)..", SIG_ITOA(sig), sig); + + /* Ignore the no valid signal. */ + break; + } + } +} + +/* + * Handle the interrupt or termination signal. + */ +static void +sig_handleterm(int sig) +{ + + MSG_DEBUG("Handle the %s..", SIG_ITOA(sig)); + + /* Print the correct termination name. */ + switch (sig) { + case SIGINT: + MSG_INFO("Interrupt requested, quitting now."); + break; + + /* SIGTERM. */ + default: + MSG_INFO("Termination requested, quitting now."); + break; + } + + /* Cleanup and exit. */ + exit_cleanup(true); +} + +/* + * Handle the hangup signal. + */ +static void +sig_handlehup(char **argv, char **envp) +{ + const char *path = NULL; + + MSG_DEBUG("Handle the %s..", SIG_ITOA(SIGHUP)); + MSG_INFO("Hangup requested, rebooting now..."); + + /* Get the environment binary path file. */ + path = env_getpath(*(argv + 0)); + + MSG_DEBUG("Re-exec the current process from %s binary path file..", path); + + /* Cleanup without exit. */ + exit_cleanup(false); + + /* Re-exec the current process. */ + if (execve(path, argv, envp) < 0) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } +} + +/* + * Handle the segmentation fault or bus error signal. + */ +static void +sig_handlebug(int sig) +{ + + MSG_DEBUG("Handle the %s..", SIG_ITOA(sig)); + + /* Print the correct bug name. */ + switch (sig) { + case SIGSEGV: + MSG_BUG("Ops... SEGMENTATION FAULT!"); + break; + + /* SIGBUS. */ + default: + MSG_BUG("Ops... BUS ERROR!"); + break; + } + + MSG_BUG("Please open with a browser web the documentation: %s", DOC_FILE); + MSG_BUG("Follow the steps explained in the \"Runtime bugs\" section."); + MSG_BUG("Thank you so much and have a nice day!"); + + /* Exit immediately. */ + exit(EXIT_FAILURE); +} + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/sig.h arpon-3.0-ng+dfsg1/src/sig.h --- arpon-2.7.2/src/sig.h 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/sig.h 2016-01-29 02:01:33.000000000 +0000 @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: sig.h,v 3.0-ng 01/29/2016 03:01:34 spikey Exp $ + */ + +#ifndef _SIG_H_ +#define _SIG_H_ + +/* + * Function prototype exported. + */ +extern void sig_handle(char **argv, char **envp); + +#endif /* !_SIG_H_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/std.c arpon-3.0-ng+dfsg1/src/std.c --- arpon-2.7.2/src/std.c 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/std.c 2016-01-29 02:07:20.000000000 +0000 @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: std.c,v 3.0-ng 01/29/2016 03:07:22 spikey Exp $ + */ + +#include + +#include "msg.h" +#include "std.h" +#include "ver.h" + +/* + * Print the version. + */ +void +std_version(void) +{ + + INFO("%s \"%s\" %s (%s)", VER_NAMESHORT, VER_NAMELONG, VER_NUMBER, VER_URL); + + MSG_DEBUG("Print version successful"); +} + +/* + * Print the help screen. + */ +void +std_help(void) +{ + + /* Print the version. */ + std_version(); + + INFO("Usage: %s [OPTIONS] [SARPI | DARPI | HARPI]", VER_NAMECASE); + INFO(""); + INFO("GENERAL OPTIONS"); + INFO(" -d, --daemon Daemonize the %s", VER_NAMECASE); + INFO(" -i, --interface Use the specified network interface"); + INFO(""); + INFO("SARPI 'STATIC ARP INSPECTION' OPTION"); + INFO(" -S, --sarpi Run SARPI anti ARP spoofing technique"); + INFO("") + INFO("DARPI 'DYNAMIC ARP INSPECTION' OPTION"); + INFO(" -D, --darpi Run DARPI anti ARP spoofing technique"); + INFO(""); + INFO("HARPI 'HYBRID ARP INSPECTION' OPTION"); + INFO(" -H, --harpi Run HARPI anti ARP spoofing technique"); + INFO(""); + INFO("STANDARD OPTIONS"); + INFO(" -v, --version Print the version and exit"); + INFO(" -h, --help Print this help screen and exit"); + INFO(""); + INFO("SEE THE MAN PAGE FOR MANY DESCRIPTIONS AND EXAMPLES."); + + MSG_DEBUG("Print help successful"); +} + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/std.h arpon-3.0-ng+dfsg1/src/std.h --- arpon-2.7.2/src/std.h 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/std.h 2016-01-29 01:59:08.000000000 +0000 @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: std.h,v 3.0-ng 01/29/2016 02:59:09 spikey Exp $ + */ + +#ifndef _STD_H_ +#define _STD_H_ + +/* + * Function prototypes exported. + */ +extern void std_version(void); +extern void std_help(void); + +#endif /* !_STD_H_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/thd.c arpon-3.0-ng+dfsg1/src/thd.c --- arpon-2.7.2/src/thd.c 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/thd.c 2016-01-29 02:04:17.000000000 +0000 @@ -0,0 +1,375 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: thd.c,v 3.0-ng 01/29/2016 03:04:19 spikey Exp $ + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "msg.h" +#include "queue.h" +#include "thd.h" +#include "unused.h" + +/* + * No nanoseconds. + */ +#define THD_NANOSECS 0 + +/* + * Thread context exit status to string. + */ +#define THD_ETOA(x) x == PTHREAD_CANCELED ? "Cancel" : "Exit" + +/* + * Thread context stack structure definition. + */ +typedef struct thd_stack { + pthread_t id; /* Thread context ID. */ + const char *name; /* Thread context name. */ + + LIST_ENTRY(thd_stack) next; /* Next thread context stack element. */ +} thd_t; + +/* + * Function prototypes not exported. + */ +static void thd_push(pthread_t id, const char *name); +static pthread_t thd_pop(const char **name); +static void thd_unregister(pthread_t id, const char *name); + +/* + * Initialize the thread context stack structure. + */ +static LIST_HEAD(thd, thd_stack) thd_head = LIST_HEAD_INITIALIZER(thd_head); + +/* + * Initialize the thread context mutex initialization. + */ +static pthread_mutex_t thd_mtxinit = PTHREAD_MUTEX_INITIALIZER; + +/* + * Initialize the thread context condition initialization. + */ +static pthread_cond_t thd_condinit = PTHREAD_COND_INITIALIZER; + +/* + * Register the thread context. + */ +void +thd_register(void *(*routine)(void *), void *arg, const char *name) +{ + + do { + /* Register the main thread context? */ + if (routine == NULL && arg == NULL) { + MSG_DEBUG("Skip create %s() thread context successful", name); + + /* Only push the main thread context. */ + thd_push(pthread_self(), name); + } else { + pthread_t id; + + /* Lock the mutex initialization of the thread context. */ + if (pthread_mutex_lock(&thd_mtxinit) != 0) + break; + + /* Register the thread context calling the routine. */ + if (pthread_create(&id, NULL, routine, arg) != 0) + break; + + MSG_DEBUG("Create %s() thread context successful", name); + + /* Push the thread context. */ + thd_push(id, name); + + MSG_DEBUG("Wait signal from %s() thread context..", name); + + /* Wait the condition initialization from the thread context. */ + if (pthread_cond_wait(&thd_condinit, &thd_mtxinit) != 0) + break; + + MSG_DEBUG("%s() thread context ready and initialized", name); + + /* Unlock the mutex initialization of the thread context. */ + if (pthread_mutex_unlock(&thd_mtxinit) != 0) + break; + } + + MSG_DEBUG("Register %s() thread context successful", name); + + return; + } while (0); + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Push the thread context stack element in the thread stack structure. + */ +static void +thd_push(pthread_t id, const char *name) +{ + thd_t *new = NULL; + + /* Empty thread context stack structure? */ + if (LIST_EMPTY(&thd_head) != 0) { + /* Set the thread context stack structure to NULL. */ + LIST_INIT(&thd_head); + MSG_DEBUG("Initialize thread context cleanup successful"); + } + + /* Allocate the thread context stack element. */ + if ((new = (thd_t *)malloc(sizeof(thd_t))) == NULL) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } + + MSG_DEBUG("thd_t *new allocate in the memory"); + + /* Initialize the thread context ID. */ + new->id = id; + + /* pthread_t is an opaque type, therefore check it. */ + assert(sizeof(new->id) == sizeof(unsigned long int)); + MSG_DEBUG("new->id = %lu", new->id); + + /* Initialize the thread context name. */ + new->name = name; + MSG_DEBUG("new->name = %s", new->name); + + /* Push the thread context stack element. */ + LIST_INSERT_HEAD(&thd_head, new, next); + + MSG_DEBUG("Push %s() thread context successful", name); +} + +/* + * Initialize the calling thread context. + */ +void +thd_init(void) +{ + + do { + thd_t UNUSED(*cur) = NULL; + + /* Lock the mutex initialization of the thread context. */ + if (pthread_mutex_lock(&thd_mtxinit) != 0) + break; + + /* Enable the cancellation of the calling thread context. */ + if (pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL) != 0) + break; + + /* Enable asynchronous cancellation of the calling thread context. */ + if (pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL) != 0) + break; + +#ifndef NDEBUG + /* Looking for the name of the calling thread context. */ + LIST_FOREACH(cur, &thd_head, next) { + if (pthread_equal(cur->id, pthread_self()) != 0) + break; + } +#endif /* !NDEBUG */ + + MSG_DEBUG("%s() sends signal to main thread context..", cur->name); + + /* Send the condition initialization to main thread context. */ + if (pthread_cond_signal(&thd_condinit) != 0) + break; + + MSG_DEBUG("Initialization %s() thread context successful", cur->name); + + /* Unlock the mutex initialization of the thread context. */ + if (pthread_mutex_unlock(&thd_mtxinit) != 0) + break; + + return; + } while (0); + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Suspend the execution of the caller thread context for specified seconds. + */ +void +thd_suspend(int seconds) +{ + struct timespec tv; + int ret; + + tv.tv_sec = seconds; /* Number of seconds. */ + tv.tv_nsec = THD_NANOSECS; /* No nanoseconds. */ + + /* Suspend the execution of the caller thread context (no interruptible). */ + while ((ret = nanosleep(&tv, &tv)) < 0 && errno == EINTR); + + /* Some error? */ + if (ret < 0) { + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); + } +} + +/* + * Cleanup all the thread contexts from the thread context + * stack structure and unregister each thread context found. + */ +void +thd_cleanup(void) +{ + + do { + MSG_DEBUG("Start thread context cleanup"); + + /* + * Send the condition initialization to main thread context + * before the unregistration of all the threads context. + */ + if (pthread_cond_signal(&thd_condinit) != 0) + break; + + /* + * Unlock the mutex initialization of the thread context + * before the unregistration of all the threads context. + */ + if (pthread_mutex_unlock(&thd_mtxinit) != 0) + break; + + /* No empty thread context stack structure? */ + if (LIST_EMPTY(&thd_head) == 0) { + /* Loop until the thread context stack structure is empty. */ + do { + pthread_t id; + const char *name = NULL; + + /* Pop the thread context ID. */ + id = thd_pop(&name); + MSG_DEBUG("Start cleanup %s() thread context..", name); + + /* Unregister the thread context. */ + thd_unregister(id, name); + } while (LIST_EMPTY(&thd_head) == 0); + + /* Re-initialize the thread context stack structure to NULL. */ + LIST_INIT(&thd_head); + } + + MSG_DEBUG("End thread context cleanup"); + + return; + } while (0); + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * Pop the thread context stack element from the thread context stack structure. + */ +static pthread_t +thd_pop(const char **name) +{ + thd_t *cur = NULL; + pthread_t id; + + /* Get the first thread context stack element. */ + cur = LIST_FIRST(&thd_head); + + /* Pop the first thread context stack element. */ + LIST_REMOVE(cur, next); + + /* Get the thread context ID. */ + id = cur->id; + + /* pthread_t is an opaque type, therefore check it. */ + assert(sizeof(id) == sizeof(unsigned long int)); + MSG_DEBUG("cur->id = %lu", id); + + /* Get the thread context name. */ + *name = cur->name; + MSG_DEBUG("cur->name = %s", *name); + + /* Deallocate the thread context stack element. */ + free(cur); + + MSG_DEBUG("thd_t *cur deallocate from the memory"); + MSG_DEBUG("Pop %s() thread context successful", *name); + + return id; +} + +/* + * Unegister the thread context. + */ +static void +thd_unregister(pthread_t id, UNUSED(const char *name)) +{ + + do { + void *res = NULL; + + /* Unregister the main thread context? */ + if (pthread_equal(id, pthread_self()) != 0) { + MSG_DEBUG("Skip cancel %s() thread context successful", name); + } else { + /* Unregister the thread context. */ + if (pthread_cancel(id) != 0) + break; + + /* Join with the thread context to see the exit status. */ + if (pthread_join(id, &res) != 0) + break; + + MSG_DEBUG("%s %s() thread context successful", THD_ETOA(res), name); + } + + MSG_DEBUG("Unregister %s() thread context successful", name); + + return; + } while (0); + + MSG_ERROR("%s", strerror(errno)); + exit(EXIT_FAILURE); +} + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/thd.h arpon-3.0-ng+dfsg1/src/thd.h --- arpon-2.7.2/src/thd.h 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/thd.h 2016-01-29 02:05:09.000000000 +0000 @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: thd.h,v 3.0-ng 01/29/2016 03:05:10 spikey Exp $ + */ + +#ifndef _THD_H_ +#define _THD_H_ + +/* + * Function prototypes exported. + */ +extern void thd_register(void *(*routine)(void *), void *arg, const char *name); +extern void thd_init(void); +extern void thd_suspend(int seconds); +extern void thd_cleanup(void); + +#endif /* !_THD_H_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/unused.h arpon-3.0-ng+dfsg1/src/unused.h --- arpon-2.7.2/src/unused.h 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/unused.h 2016-01-29 02:03:06.000000000 +0000 @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: unused.h,v 3.0-ng 01/29/2016 03:03:08 spikey Exp $ + */ + +#ifndef _UNUSED_H_ +#define _UNUSED_H_ + +/* + * Unused GCC attribute macro. + */ +#ifdef __GNUC__ +#define UNUSED(x) x __attribute__((__unused__)) +#else /* !__GNUC__ */ +#define UNUSED(x) x +#endif /* __GNUC__ */ + +#endif /* !_UNUSED_H_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/src/ver.h arpon-3.0-ng+dfsg1/src/ver.h --- arpon-2.7.2/src/ver.h 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/src/ver.h 2016-01-29 02:01:55.000000000 +0000 @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2008-2016 Andrea Di Pasquale + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR OR HIS RELATIVES BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING + * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + * + * $ArpON: ver.h,v 3.0-ng 01/29/2016 03:01:55 spikey Exp $ + */ + +#ifndef _VER_H_ +#define _VER_H_ + +/* + * Name definitions. + */ +#define VER_NAMESHORT "ArpON" +#define VER_NAMELONG "ARP handler inspection" +#define VER_NAMECASE "arpon" + +/* + * Version definition. + */ +#define VER_NUMBER "3.0-ng" + +/* + * Url reference to web site definition. + */ +#define VER_URL "http://arpon.sourceforge.net" + +#endif /* !_VER_H_ */ + +/* + * EOF + * + * vim:ts=4:expandtab + */ diff -Nru arpon-2.7.2/THANKS arpon-3.0-ng+dfsg1/THANKS --- arpon-2.7.2/THANKS 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/THANKS 2016-01-29 02:11:48.000000000 +0000 @@ -0,0 +1,19 @@ +================================================================================ + THANKS +================================================================================ + + • Giuseppe Marco Randazzo aka "zeld" + + CMake Software Developer. + + • Federico Losacco aka "flosacco" + + Functional Tester. + + • Domenico Gisonna aka "crius" + + Functional Tester. + + • Fabrizio Oliveri aka "bizio" + + Logo Graphic Designer. diff -Nru arpon-2.7.2/VERSION arpon-3.0-ng+dfsg1/VERSION --- arpon-2.7.2/VERSION 1970-01-01 00:00:00.000000000 +0000 +++ arpon-3.0-ng+dfsg1/VERSION 2016-01-29 02:11:56.000000000 +0000 @@ -0,0 +1 @@ +3.0-ng