Merge with origin/topic/cmake-port.

Needed to readd the broctl/broccoli/binpac submodules manually, as
git seemed to get confused by the existing directories.
This commit is contained in:
Robin Sommer 2010-11-24 21:02:08 -08:00
parent c1768336c4
commit 610d081c4b
125 changed files with 2304 additions and 7592 deletions

12
.gitmodules vendored Normal file
View file

@ -0,0 +1,12 @@
[submodule "aux/bro-aux"]
path = aux/bro-aux
url = git://git.icir.org/bro-aux
[submodule "aux/binpac"]
path = aux/binpac
url = git://git.icir.org/binpac
[submodule "aux/broccoli"]
path = aux/broccoli
url = git://git.icir.org/broccoli
[submodule "aux/broctl"]
path = aux/broctl
url = git://git.icir.org/broctl

276
CMakeLists.txt Normal file
View file

@ -0,0 +1,276 @@
project(Bro)
########################################################################
## CMake Configuration
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)
# Prohibit in-source builds.
if ("${CMAKE_SOURCE_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
message(FATAL_ERROR "In-source builds are not allowed. Please use "
"./configure to choose a build directory and "
"initialize the build configuration.")
endif ()
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
if ("${PROJECT_SOURCE_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}")
# uninstall target
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
@ONLY)
add_custom_target(uninstall COMMAND
${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif ()
########################################################################
## Project/Build Configuration
set(BRO_ROOT_DIR ${CMAKE_INSTALL_PREFIX})
if (NOT POLICYDIR)
# set the default policy installation path (user did not specify one)
set(POLICYDIR ${BRO_ROOT_DIR}/share/bro)
endif ()
# sanitize the policy install directory into an absolute path
# (CMake is confused by ~ as a representation of home directory)
get_filename_component(POLICYDIR ${POLICYDIR} ABSOLUTE)
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" VERSION LIMIT_COUNT 1)
set(EXTRA_COMPILE_FLAGS "-Wall -Wno-unused")
if (ENABLE_DEBUG)
set(CMAKE_BUILD_TYPE Debug)
set(EXTRA_COMPILE_FLAGS "${EXTRA_COMPILE_FLAGS} -DDEBUG")
else ()
set(CMAKE_BUILD_TYPE RelWithDebInfo)
endif ()
# Compiler flags may already exist in CMake cache (e.g. when specifying
# CFLAGS environment variable before running cmake for the the first time)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_COMPILE_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_COMPILE_FLAGS}")
########################################################################
## Dependency Configuration
include(FindRequiredPackage)
# Check cache value first to avoid displaying "Found sed" messages everytime
if (NOT SED_EXE)
find_program(SED_EXE sed)
if (NOT SED_EXE)
message(FATAL_ERROR "Could not find required dependency: sed")
else ()
message(STATUS "Found sed: ${SED_EXE}")
endif ()
endif ()
FindRequiredPackage(Perl)
FindRequiredPackage(FLEX)
FindRequiredPackage(BISON)
FindRequiredPackage(PCAP)
FindRequiredPackage(OpenSSL)
FindRequiredPackage(BIND)
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/aux/binpac/CMakeLists.txt)
add_subdirectory(aux/binpac)
endif ()
FindRequiredPackage(BinPAC)
if (MISSING_PREREQS)
foreach (prereq ${MISSING_PREREQ_DESCS})
message(SEND_ERROR ${prereq})
endforeach ()
message(FATAL_ERROR "Configuration aborted due to missing prerequisites")
endif ()
include_directories(BEFORE
${PCAP_INCLUDE_DIR}
${OpenSSL_INCLUDE_DIR}
${BIND_INCLUDE_DIR}
${BinPAC_INCLUDE_DIR}
)
# Optional Dependencies
set(HAVE_LIBMAGIC false)
find_package(LibMagic)
if (LIBMAGIC_FOUND)
set(HAVE_LIBMAGIC true)
include_directories(BEFORE ${LibMagic_INCLUDE_DIR})
list(APPEND OPTLIBS ${LibMagic_LIBRARY})
endif ()
set(HAVE_LIBZ false)
find_package(ZLIB)
if (ZLIB_FOUND)
set(HAVE_LIBZ true)
include_directories(BEFORE ${ZLIB_INCLUDE_DIR})
list(APPEND OPTLIBS ${ZLIB_LIBRARY})
endif ()
set(USE_GEOIP false)
find_package(LibGeoIP)
if (LIBGEOIP_FOUND)
set(USE_GEOIP true)
include_directories(BEFORE ${LibGeoIP_INCLUDE_DIR})
list(APPEND OPTLIBS ${LibGeoIP_LIBRARY})
endif ()
set(USE_PERFTOOLS false)
if (ENABLE_PERFTOOLS)
find_package(GooglePerftools)
if (GOOGLEPERFTOOLS_FOUND)
set(USE_PERFTOOLS true)
include_directories(BEFORE ${GooglePerftools_INCLUDE_DIR})
list(APPEND OPTLIBS ${GooglePerftools_LIBRARIES})
endif ()
endif ()
########################################################################
## System Introspection
include(TestBigEndian)
test_big_endian(WORDS_BIGENDIAN)
include(OSSpecific)
include(CheckTypes)
include(CheckHeaders)
include(CheckFunctions)
include(MiscTests)
include(PCAPTests)
include(OpenSSLTests)
include(CheckNameserCompat)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
${CMAKE_CURRENT_BINARY_DIR}/config.h)
include_directories(${CMAKE_CURRENT_BINARY_DIR})
########################################################################
## Recurse on sub-directories
add_subdirectory(src)
add_subdirectory(policy)
#add_subdirectory(scripts)
#add_subdirectory(doc)
if (INSTALL_BROCCOLI)
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/aux/broccoli/CMakeLists.txt)
add_subdirectory(aux/broccoli)
else ()
message(FATAL_ERROR "Broccoli selected for installation, "
"but the source code does not exist in "
"${CMAKE_CURRENT_SOURCE_DIR}/aux/broccoli")
endif ()
endif ()
if (INSTALL_BROCTL)
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/aux/broctl/CMakeLists.txt)
add_subdirectory(aux/broctl)
else ()
message(FATAL_ERROR "Broctl selected for installation, "
"but the source code does not exist in "
"${CMAKE_CURRENT_SOURCE_DIR}/aux/broctl")
endif ()
endif ()
if (INSTALL_AUX_TOOLS)
if (EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/aux/bro-aux/CMakeLists.txt)
add_subdirectory(aux/bro-aux)
else ()
message(FATAL_ERROR "Bro auxilliary tools selected for installation, "
"but the source code does not exist in "
"${CMAKE_CURRENT_SOURCE_DIR}/aux/bro-aux")
endif ()
endif ()
########################################################################
## Packaging Setup
include(SetPackageVersion)
SetPackageVersion(${VERSION})
include(SetPackageGenerators)
include(SetPackageFileName)
set(CPACK_PACKAGE_VENDOR "Lawrence Berkeley National Laboratory")
set(CPACK_PACKAGE_CONTACT "info@bro-ids.org")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY
"The Bro Network Intrusion Detection System")
# CPack may enforce file name extensions for certain package generators
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/README
${CMAKE_CURRENT_BINARY_DIR}/README.txt
COPYONLY)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/COPYING
${CMAKE_CURRENT_BINARY_DIR}/COPYING.txt
COPYONLY)
set(CPACK_PACKAGE_DESCRIPTION_FILE ${CMAKE_CURRENT_BINARY_DIR}/README.txt)
set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_BINARY_DIR}/COPYING.txt)
set(CPACK_RESOURCE_FILE_README ${CMAKE_CURRENT_BINARY_DIR}/README.txt)
set(CPACK_RESOURCE_FILE_WELCOME ${CMAKE_CURRENT_BINARY_DIR}/README.txt)
if (APPLE)
# /usr prefix is hardcoded for PackageMaker generator, but that
# directory may not be ideal for OS X (it's tricky to remove
# packages installed there). So instead we rely on CMAKE_INSTALL_PREFIX
# and set the following variable to workaround the hardcoded /usr prefix
set(CPACK_PACKAGING_INSTALL_PREFIX "/")
set(CPACK_PACKAGE_DEFAULT_LOCATION ${CMAKE_INSTALL_PREFIX})
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
# A prefix of /usr would follow Filesystem Hierarchy Standard.
# For RPM packaging by CPack, /usr should be a default, but
# CMAKE_INSTALL_PREFIX also needs to be set to /usr so that
# the default BROPATH is set right at build time
set(CPACK_RPM_PACKAGE_LICENSE "BSD")
endif ()
# Ignore the build directory
set(CPACK_SOURCE_IGNORE_FILES ${CMAKE_BINARY_DIR} ".git")
include(CPack)
########################################################################
## Build Summary
if (CMAKE_BUILD_TYPE)
string(TOUPPER ${CMAKE_BUILD_TYPE} BuildType)
endif ()
if (INSTALL_BROCTL)
if (STANDALONE)
set(BROCTL_INSTALL_MODE "standalone")
else ()
set(BROCTL_INSTALL_MODE "cluster")
endif ()
else ()
set(BROCTL_INSTALL_MODE "false")
endif ()
message(
"\n====================| Bro Build Summary |====================="
"\n"
"\nInstall prefix: ${CMAKE_INSTALL_PREFIX}"
"\nPolicy dir: ${POLICYDIR}"
"\nDebug mode: ${ENABLE_DEBUG}"
"\n"
"\nCC: ${CMAKE_C_COMPILER}"
"\nCFLAGS: ${CMAKE_C_FLAGS} ${CMAKE_C_FLAGS_${BuildType}}"
"\nCXX: ${CMAKE_CXX_COMPILER}"
"\nCXXFLAGS: ${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_${BuildType}}"
"\nCPP: ${CMAKE_CXX_COMPILER}"
"\n"
"\nBroccoli: ${INSTALL_BROCCOLI}"
"\nBroctl: ${BROCTL_INSTALL_MODE}"
"\nAux. Tools: ${INSTALL_AUX_TOOLS}"
"\n"
"\nGeoIP: ${USE_GEOIP}"
"\nlibz: ${HAVE_LIBZ}"
"\nlibmagic: ${HAVE_LIBMAGIC}"
"\nGoogle perftools: ${USE_PERFTOOLS}"
"\n"
"\n================================================================\n"
)

92
INSTALL
View file

@ -2,71 +2,73 @@ Prerequisites
=============
Bro relies on the following libraries and tools, which need to be installed
before you begin with the installation:
before you begin:
* Libpcap
If libpcap is already installed on the system, by default Bro
will use that one. Otherwise, it falls back to a version shipped
with the Bro distribution.
* Libpcap headers and libraries
Network traffic capture library
* Flex
Flex is already installed on most systems, so with luck you can
skip having to install it yourself.
* Flex (Fast Lexical Analyzer)
Flex is already installed on most systems, so with luck you can
skip having to install it yourself.
* Bison or byacc
These come with many systems, but if you get errors compiling
parse.y, you will need to install them. bison is available
from GNU sites such as ftp.gnu.org.
* Bison (GNU Parser Generator)
This comes with many systems, but if you get errors compiling
parse.y, you will need to install it.
* Perl
Used only during the Bro build process
* sed
Used only during the Bro build process
* BIND8 headers and libraries
These are usually already installed as well.
These are usually already installed as well.
* Autotools
If you have checked the source out from Bro's Subversion
repository, you need the autotools suite installed. In this
case, run "./autogen.sh" first right after the check out.
Otherwise the installation steps below will fail.
* OpenSSL headers and libraries
For analysis of SSL certificates by the HTTP analyzer, and
for encrypted Bro-to-Bro communication. These are likely installed,
though some platforms may require installation of a 'devel' package
for the headers.
* CMake 2.8 or greater
CMake is a cross-platform, open-source build system, typically
not installed by default. See http://www.cmake.org for more
information regarding CMake and the installation steps below for
how to use it to build this distribution. CMake generates native
Makefiles that depend on GNU Make by default.
Bro can also make uses of some optional libraries if they are found at
installation time:
* OpenSSL
For analysis of SSL certificates by the HTTP analyzer, and
for encrypted Bro-to-Bro communication.
* Libmagic
For identifying file types (e.g., in FTP transfers).
For identifying file types (e.g., in FTP transfers).
* LibGeoIP
For geo-locating IP addresses.
For geo-locating IP addresses.
* Libz
For decompressing HTTP bodies by the HTTP analyzer, and for
compressed Bro-to-Bro communication.
* Endace's DAG tools:
For native support of Endace DAG cards.
For decompressing HTTP bodies by the HTTP analyzer, and for
compressed Bro-to-Bro communication.
Installation
============
To build and install into /usr/local:
To build and install into /usr/local/bro:
> ./configure
> make
> make install
> ./configure
> cd build
> make
> make install
This will install the Bro binary into /usr/local/bin/bro and the policy
files into /usr/local/share/bro.
This will perform an out-of-source build into the build directory using the
default build options and then install binaries into /usr/local/bro/bin.
As usual you can specify a different installation directory with
You can specify a different installation directory with
> ./configure --prefix=<dir>".
> ./configure --prefix=<dir>
Run "./configure --help" for more options.
Running Bro
===========
@ -77,17 +79,17 @@ http://www.bro-ids.org/wiki for more information.
To run a policy file from /usr/local/share/bro, such as mt.bro, on a
previously captured tcpdump save file named foo:
bro -r foo mt.bro
bro -r foo mt.bro
To run from interface le0:
bro -i le0 mt
bro -i le0 mt
You can alternatively specify interface and scripts to load in your own
policy file:
@load mt
redef interfaces = "le0";
@load mt
redef interfaces = "le0";
and then run
@ -95,10 +97,10 @@ and then run
You can see the BPF filter Bro will use (if not overridden) by executing
bro mt print-filter
bro mt print-filter
To run interactively (e.g., for playing with expression evaluation):
bro
bro
"bro -h" lists the various options.

View file

@ -1,77 +0,0 @@
## Process this file with automake to produce Makefile.in
LIBPCAP_VER = libpcap-0.9.8
LIBPCAP_LIB = $(LIBPCAP_VER)/libpcap.a
EXTRA_DIST = README $(LIBPCAP_VER).tar.gz
# if we don't have ssl, can't build bdcat
if USE_SSL
bdcat_dir = bdcat
else
bdcat_dir =
endif
# don't compile libpcap if they did a '--disable-localpcap' to configure
if USE_LOCALPCAP
built_srcs = $(LIBPCAP_LIB)
LARGE_FILE = "-D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE"
else
built_srcs =
endif
if USEV6
PCAPARGS = --enable-ipv6
else
PCAPARGS =
endif
if USE_BROCCOLI
broccoli = broccoli
else
broccoli =
endif
if USE_BROCTL
broctl = broctl
else
broctl =
endif
BUILT_SOURCES = $(built_srcs)
SUBDIRS = adtrace binpac cf hf nftools rst scripts \
$(bdcat_dir) $(broccoli) $(broctl)
DIST_SUBDIRS = adtrace binpac cf hf nftools rst scripts \
$(bdcat_dir) $(broccoli) $(broctl)
clean-local:
rm -rf $(LIBPCAP_VER)
$(LIBPCAP_LIB): $(top_srcdir)/aux/$(LIBPCAP_VER).tar.gz
@echo "Unpacking libpcap sources"
@gzip -d < $(top_srcdir)/aux/$(LIBPCAP_VER).tar.gz | tar xf -
@echo "Building libpcap"
( cd $(LIBPCAP_VER) && ./configure --prefix=$(prefix) $(PCAPARGS) CFLAGS=$(LARGE_FILE) && $(MAKE) )
@chmod -R 755 $(LIBPCAP_VER)
# This is a hack. These are hardcoded here to mimic the previous
# brolite installation. While these should better go into the
# subdirs' Makefile.am, it's not really worth the effort as
# we will get rid of all this at some point anyway.
install-brolite:
$(INSTALL) ./hf/hf ${bindir}
$(INSTALL) ./hf/nf ${bindir}
$(INSTALL) ./hf/pf ${bindir}
$(INSTALL) ./cf/cf ${bindir}
$(INSTALL) ./rst/rst ${bindir}
- install -d $(prefix)/scripts/
$(INSTALL) ./scripts/host-to-addrs $(prefix)/scripts
$(INSTALL) ./scripts/bro-logchk.pl $(prefix)/scripts
$(INSTALL) ./scripts/host-grep $(prefix)/scripts
$(INSTALL) ./scripts/mvlog $(prefix)/scripts

View file

@ -1,61 +0,0 @@
This directory contains handy auxiliary programs:
adtrace/
Makefile and source for the adtrace utility. This program is used
in conjunction with the localnetMAC.pl perl script to compute the
network address that compose the internal and extern nets that bro
is monitoring. This program when run by itself just reads a pcap
(tcpcump) file and writes out the src MAC, dst MAC, src IP, dst
IP for each packet seen in the file. This output is processed by
the localnetMAC.pl script during 'make install'.
bdcat/
A utility for decrypting encrypted Bro log files.
binpac/
A compiler for generating protocol analyzers from high-level,
declarative specifications. Used extensively for constructing
Bro's protocol analyzers, but capable of stand-alone use for
building analyzers outside of the Bro system.
broccoli/
A C client library for interfacing programs with the Bro system.
Enables sending and receiving of Bro values and events.
cf/
Makefile and source for the "cf" utility. cf reads lines from
stdin and if the line begins with a number, then it assumes that
the number corresponds to a Unix timestamp and replaces it with
the corresponding local time in a readable format. Useful for
running on log files. See cf/cf.man.txt for documentation.
contrib/
Unsupported contributions to Bro.
hf/
The main utility in this subdirectory is hf, which translates
any dotted-quad (in text) appearing on stdin to the corresponding
DNS hostname (via a PTR lookup) on stdout.
nftools/
Utilities for dealing with Bro's custom file format for storing
NetFlow records. nfcollector reads NetFlow data from a socket
and writes it in Bro's format. ftwire2bro reads NetFlow "wire"
format (e.g., as generated by a 'flow-export' directive) and writes
it in Bro's format.
rst/
Makefile and source for the rst utility. "rst" can be invoked by
a Bro script to terminate an established TCP connection by forging
RST tear-down packets. See terminate_connection() in conn.bro.
scripts/
A set of utility scripts for munching on Bro connection summaries.
bro_logchk: orders and scans through FTP and HTTP logs
host-grep: greps a summary file for a particular host's activities
host-to-addrs: converts a hostname to a list of IP addresses
hot-report: formats a summary file in a readable fashion
ip-grep: returns a grep pattern for a given IP address
mon-report: summarizes a particular host's activity
mvlog: compresses and archives log files

View file

@ -1,10 +0,0 @@
## Process this file with automake to produce Makefile.in
AM_CFLAGS=@V_INCLS@
# Should use AM_ vars, but automake 1.5 errors out.
#AM_LDFLAGS = @LDFLAGS@
LDFLAGS = @LDFLAGS@
noinst_PROGRAMS = adtrace
adtrace_SOURCES = adtrace.c ether.h ethertype.h ip.h

View file

@ -1,92 +0,0 @@
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pcap.h>
#include "../../config.h"
#include "ip.h"
#include "ether.h"
#include "ethertype.h"
pcap_t *p;
const u_char* printEAddr(const u_char* pkt, u_char* endp){
const struct ether_header *ep;
int i=0;
ep = (const struct ether_header*) pkt;
if (pkt+ETHER_HDRLEN > endp ||
ntohs(ep->ether_type) != ETHERTYPE_IP){
return 0;
}
for (i = 0; i<ETHER_ADDR_LEN; i++){
if (i>0) putchar(':');
printf("%02x", ep->ether_shost[i]);
}
putchar (' ');
for (i = 0; i<ETHER_ADDR_LEN; i++){
if (i>0) putchar(':');
printf("%02x", ep->ether_dhost[i]);
}
putchar(' ');
return (pkt+ETHER_HDRLEN);
}
void printIPAddr(const u_char* pkt, u_char* endp){
const struct ip* iph;
if (pkt+sizeof(struct ip) > endp) return;
iph = (const struct ip*) pkt;
fputs ((char*) inet_ntoa(iph->ip_src), stdout);
putchar(' ');
puts ((char*) inet_ntoa(iph->ip_dst));
}
void handler(u_char *user, const struct pcap_pkthdr *head, const u_char *packet){
u_char* endp;
endp =(u_char*) packet + head->caplen;
packet = printEAddr(packet, endp);
if (packet)
printIPAddr(packet, endp);
}
void usage(char *av[])
{
fprintf(stderr,"usage: %s filename \n", av[0]);
exit(1);
}
int main (int argc, char *argv[])
{
char *file;
char errbuf[PCAP_ERRBUF_SIZE];
u_char* pkt, endp;
struct pcap_pkthdr *head;
if ( argc != 2 )
usage(argv);
file = argv[1];
p = pcap_open_offline(file, errbuf);
if(p==NULL){
fprintf (stderr, "cannot open %s: %s\n", file, errbuf);
exit(2);
}
if (pcap_datalink(p) != DLT_EN10MB){
fputs ("sorry, currently only ethernet links supported\n", stderr);
exit(1); //if it is not ethernet we are watching we won't have MACs
}
pcap_loop(p, -1, handler, NULL);
pcap_close(p);
return(0);
}

View file

@ -1,59 +0,0 @@
/* @(#) $Header$ (LBL) */
/*
* Copyright (c) 1982, 1986, 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.
*
* @(#)if_ether.h 8.3 (Berkeley) 5/2/95
*/
#define ETHERMTU 1500
/*
* The number of bytes in an ethernet (MAC) address.
*/
#define ETHER_ADDR_LEN 6
/*
* Structure of a DEC/Intel/Xerox or 802.3 Ethernet header.
*/
struct ether_header {
u_int8_t ether_dhost[ETHER_ADDR_LEN];
u_int8_t ether_shost[ETHER_ADDR_LEN];
u_int16_t ether_type;
};
/*
* Length of a DEC/Intel/Xerox or 802.3 Ethernet header; note that some
* compilers may pad "struct ether_header" to a multiple of 4 bytes,
* for example, so "sizeof (struct ether_header)" may not give the right
* answer.
*/
#define ETHER_HDRLEN 14

View file

@ -1,122 +0,0 @@
/*
* Copyright (c) 1993, 1994, 1996
* 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: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header$ (LBL)
*/
/*
* Ethernet types.
*
* We wrap the declarations with #ifdef, so that if a file includes
* <netinet/if_ether.h>, which may declare some of these, we don't
* get a bunch of complaints from the C compiler about redefinitions
* of these values.
*
* We declare all of them here so that no file has to include
* <netinet/if_ether.h> if all it needs are ETHERTYPE_ values.
*/
#ifndef ETHERTYPE_PUP
#define ETHERTYPE_PUP 0x0200 /* PUP protocol */
#endif
#ifndef ETHERTYPE_IP
#define ETHERTYPE_IP 0x0800 /* IP protocol */
#endif
#ifndef ETHERTYPE_ARP
#define ETHERTYPE_ARP 0x0806 /* Addr. resolution protocol */
#endif
#ifndef ETHERTYPE_REVARP
#define ETHERTYPE_REVARP 0x8035 /* reverse Addr. resolution protocol */
#endif
#ifndef ETHERTYPE_NS
#define ETHERTYPE_NS 0x0600
#endif
#ifndef ETHERTYPE_SPRITE
#define ETHERTYPE_SPRITE 0x0500
#endif
#ifndef ETHERTYPE_TRAIL
#define ETHERTYPE_TRAIL 0x1000
#endif
#ifndef ETHERTYPE_MOPDL
#define ETHERTYPE_MOPDL 0x6001
#endif
#ifndef ETHERTYPE_MOPRC
#define ETHERTYPE_MOPRC 0x6002
#endif
#ifndef ETHERTYPE_DN
#define ETHERTYPE_DN 0x6003
#endif
#ifndef ETHERTYPE_LAT
#define ETHERTYPE_LAT 0x6004
#endif
#ifndef ETHERTYPE_SCA
#define ETHERTYPE_SCA 0x6007
#endif
#ifndef ETHERTYPE_REVARP
#define ETHERTYPE_REVARP 0x8035
#endif
#ifndef ETHERTYPE_LANBRIDGE
#define ETHERTYPE_LANBRIDGE 0x8038
#endif
#ifndef ETHERTYPE_DECDNS
#define ETHERTYPE_DECDNS 0x803c
#endif
#ifndef ETHERTYPE_DECDTS
#define ETHERTYPE_DECDTS 0x803e
#endif
#ifndef ETHERTYPE_VEXP
#define ETHERTYPE_VEXP 0x805b
#endif
#ifndef ETHERTYPE_VPROD
#define ETHERTYPE_VPROD 0x805c
#endif
#ifndef ETHERTYPE_ATALK
#define ETHERTYPE_ATALK 0x809b
#endif
#ifndef ETHERTYPE_AARP
#define ETHERTYPE_AARP 0x80f3
#endif
#ifndef ETHERTYPE_8021Q
#define ETHERTYPE_8021Q 0x8100
#endif
#ifndef ETHERTYPE_IPX
#define ETHERTYPE_IPX 0x8137
#endif
#ifndef ETHERTYPE_IPV6
#define ETHERTYPE_IPV6 0x86dd
#endif
#ifndef ETHERTYPE_PPP
#define ETHERTYPE_PPP 0x880b
#endif
#ifndef ETHERTYPE_MPLS
#define ETHERTYPE_MPLS 0x8847
#endif
#ifndef ETHERTYPE_MPLS_MULTI
#define ETHERTYPE_MPLS_MULTI 0x8848
#endif
#ifndef ETHERTYPE_PPPOED
#define ETHERTYPE_PPPOED 0x8863
#endif
#ifndef ETHERTYPE_PPPOES
#define ETHERTYPE_PPPOES 0x8864
#endif
#ifndef ETHERTYPE_LOOPBACK
#define ETHERTYPE_LOOPBACK 0x9000
#endif

View file

@ -1,159 +0,0 @@
/* @(#) $Header$ (LBL) */
/*
* Copyright (c) 1982, 1986, 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.
*
* @(#)ip.h 8.2 (Berkeley) 6/1/94
*/
/*
* Definitions for internet protocol version 4.
* Per RFC 791, September 1981.
*/
#define IPVERSION 4
/*
* Structure of an internet header, naked of options.
*
* We declare ip_len and ip_off to be short, rather than u_short
* pragmatically since otherwise unsigned comparisons can result
* against negative integers quite easily, and fail in subtle ways.
*/
struct ip {
u_int8_t ip_vhl; /* header length, version */
#define IP_V(ip) (((ip)->ip_vhl & 0xf0) >> 4)
#define IP_HL(ip) ((ip)->ip_vhl & 0x0f)
u_int8_t ip_tos; /* type of service */
u_int16_t ip_len; /* total length */
u_int16_t ip_id; /* identification */
u_int16_t ip_off; /* fragment offset field */
#define IP_DF 0x4000 /* dont fragment flag */
#define IP_MF 0x2000 /* more fragments flag */
#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */
u_int8_t ip_ttl; /* time to live */
u_int8_t ip_p; /* protocol */
u_int16_t ip_sum; /* checksum */
struct in_addr ip_src,ip_dst; /* source and dest address */
};
#define IP_MAXPACKET 65535 /* maximum packet size */
/*
* Definitions for IP type of service (ip_tos)
*/
#define IPTOS_LOWDELAY 0x10
#define IPTOS_THROUGHPUT 0x08
#define IPTOS_RELIABILITY 0x04
/*
* Definitions for IP precedence (also in ip_tos) (hopefully unused)
*/
#define IPTOS_PREC_NETCONTROL 0xe0
#define IPTOS_PREC_INTERNETCONTROL 0xc0
#define IPTOS_PREC_CRITIC_ECP 0xa0
#define IPTOS_PREC_FLASHOVERRIDE 0x80
#define IPTOS_PREC_FLASH 0x60
#define IPTOS_PREC_IMMEDIATE 0x40
#define IPTOS_PREC_PRIORITY 0x20
#define IPTOS_PREC_ROUTINE 0x00
/*
* Definitions for options.
*/
#define IPOPT_COPIED(o) ((o)&0x80)
#define IPOPT_CLASS(o) ((o)&0x60)
#define IPOPT_NUMBER(o) ((o)&0x1f)
#define IPOPT_CONTROL 0x00
#define IPOPT_RESERVED1 0x20
#define IPOPT_DEBMEAS 0x40
#define IPOPT_RESERVED2 0x60
#define IPOPT_EOL 0 /* end of option list */
#define IPOPT_NOP 1 /* no operation */
#define IPOPT_RR 7 /* record packet route */
#define IPOPT_TS 68 /* timestamp */
#define IPOPT_SECURITY 130 /* provide s,c,h,tcc */
#define IPOPT_LSRR 131 /* loose source route */
#define IPOPT_SATID 136 /* satnet id */
#define IPOPT_SSRR 137 /* strict source route */
/*
* Offsets to fields in options other than EOL and NOP.
*/
#define IPOPT_OPTVAL 0 /* option ID */
#define IPOPT_OLEN 1 /* option length */
#define IPOPT_OFFSET 2 /* offset within option */
#define IPOPT_MINOFF 4 /* min value of above */
/*
* Time stamp option structure.
*/
struct ip_timestamp {
u_int8_t ipt_code; /* IPOPT_TS */
u_int8_t ipt_len; /* size of structure (variable) */
u_int8_t ipt_ptr; /* index of current entry */
u_int8_t ipt_oflwflg; /* flags, overflow counter */
#define IPTS_OFLW(ip) (((ipt)->ipt_oflwflg & 0xf0) >> 4)
#define IPTS_FLG(ip) ((ipt)->ipt_oflwflg & 0x0f)
union ipt_timestamp {
u_int32_t ipt_time[1];
struct ipt_ta {
struct in_addr ipt_addr;
u_int32_t ipt_time;
} ipt_ta[1];
} ipt_timestamp;
};
/* flag bits for ipt_flg */
#define IPOPT_TS_TSONLY 0 /* timestamps only */
#define IPOPT_TS_TSANDADDR 1 /* timestamps and addresses */
#define IPOPT_TS_PRESPEC 3 /* specified modules only */
/* bits for security (not byte swapped) */
#define IPOPT_SECUR_UNCLASS 0x0000
#define IPOPT_SECUR_CONFID 0xf135
#define IPOPT_SECUR_EFTO 0x789a
#define IPOPT_SECUR_MMMM 0xbc4d
#define IPOPT_SECUR_RESTR 0xaf13
#define IPOPT_SECUR_SECRET 0xd788
#define IPOPT_SECUR_TOPSECRET 0x6bc5
/*
* Internet implementation parameters.
*/
#define MAXTTL 255 /* maximum time to live (seconds) */
#define IPDEFTTL 64 /* default ttl, from RFC 1340 */
#define IPFRAGTTL 60 /* time to live for frags, slowhz */
#define IPTTLDEC 1 /* subtracted when forwarding */
#define IP_MSS 576 /* default maximum segment size */

View file

@ -1,4 +0,0 @@
## Process this file with automake to produce Makefile.in
noinst_PROGRAMS = bdcat
bdcat_SOURCES = bdcat.cc

View file

@ -1,175 +0,0 @@
// $Id: bdcat.cc 6 2004-04-30 00:31:26Z jason $
//
// Decrypts Bro's log files.
//
// Usage: bdcat [-k file-with-secret-rsa-key] [files...]
//
// The key file may be alternatively set via the env variable BDCAT_KEY.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include "openssl/evp.h"
#include "openssl/pem.h"
#include "openssl/err.h"
EVP_PKEY* SecKey = 0;
EVP_CIPHER* CipherType = 0;
void cryptcat(FILE* f)
{
unsigned char magic[7];
unsigned long secret_len;
// Read file header.
if ( ! (fread(&magic, 7, 1, f) &&
fread(&secret_len, sizeof(secret_len), 1, f)) )
{
fprintf(stderr, "can't read file header: %s\n", strerror(errno));
exit(1);
}
if ( memcmp("BROENC1", (const char*) magic, 7) != 0 )
{
fputs("not a Bro encrypted file\n", stderr);
exit(1);
}
secret_len = ntohl(secret_len);
int iv_len = EVP_CIPHER_iv_length(CipherType);
unsigned char secret[secret_len];
unsigned char iv[iv_len];
if ( ! (fread(&secret, secret_len, 1, f) &&
fread(&iv, iv_len, 1, f)) )
{
fprintf(stderr, "can't read file header: %s\n", strerror(errno));
exit(1);
}
// Decrypt data.
EVP_CIPHER_CTX cipher_ctx;
if ( ! EVP_OpenInit(&cipher_ctx, CipherType,
secret, secret_len, iv, SecKey) )
{
fprintf( stderr, "can't init decryption: %s\n",
ERR_error_string(ERR_get_error(), 0));
exit(1);
return;
}
int block_size = EVP_CIPHER_block_size(CipherType);
unsigned char buffer_in[block_size];
unsigned char buffer_out[block_size];
int inl, outl;
while ( (inl = fread(buffer_in, 1, block_size, f)) )
{
if ( ! EVP_OpenUpdate(&cipher_ctx, buffer_out,
&outl, buffer_in, inl) )
{
fprintf( stderr, "can't decrypt: %s\n",
ERR_error_string(ERR_get_error(), 0));
exit(1);
}
if ( outl && ! fwrite(buffer_out, outl, 1, stdout) )
{
fprintf(stderr, "can't write to stdout: %s\n",
strerror(errno));
exit(1);
}
}
if ( ! EVP_OpenFinal(&cipher_ctx, buffer_out, &outl) )
{
fprintf( stderr, "can't decrypt: %s\n",
ERR_error_string(ERR_get_error(), 0));
exit(1);
}
if ( outl && ! fwrite(buffer_out, outl, 1, stdout) )
{
fprintf(stderr, "can't write to stdout: %s\n", strerror(errno));
exit(1);
}
fclose(f);
}
void Usage()
{
fprintf(stderr, "bdcat [-k <sec-key-file>] [files]\n");
exit(1);
}
int main(int argc, char** argv)
{
char* keyfile = getenv("BDCAT_KEY");
// Read options.
char op;
while ( (op = getopt(argc, argv, "k:")) >= 0 )
{
if ( op == 'k' )
keyfile = optarg;
else
Usage();
}
if ( ! keyfile )
{
fputs("no keyfile given\n", stderr);
exit(1);
}
// Init crypto.
ERR_load_crypto_strings();
OpenSSL_add_all_algorithms();
FILE* f = fopen(keyfile, "r");
if ( ! f )
{
fprintf(stderr, "can't open key file %s: %s\n",
keyfile, strerror(errno));
exit(1);
}
SecKey = PEM_read_PrivateKey(f, 0, 0, 0);
if ( ! SecKey )
{
fprintf(stderr, "can't read key from %s: %s\n", keyfile,
ERR_error_string(ERR_get_error(), 0));
exit(1);
}
fclose(f);
// Depending on the OpenSSL version, EVP_*_cbc()
// returns a const or a non-const.
CipherType = (EVP_CIPHER*) EVP_bf_cbc();
// Decrypt the files.
if ( optind == argc )
cryptcat(stdin);
else
{
while ( optind < argc )
{
FILE* f = fopen(argv[optind], "r");
if ( ! f )
{
fprintf(stderr, "can't open %s: %s\n",
argv[optind], strerror(errno));
exit(1);
}
cryptcat(f);
++optind;
}
}
}

1
aux/binpac Submodule

@ -0,0 +1 @@
Subproject commit 10243a89bb563a22eccd0e1bba842edfb82da33f

1
aux/bro-aux Submodule

@ -0,0 +1 @@
Subproject commit afb29b38bcb08b67f2a86ea580a9b55d1a9ace05

1
aux/broccoli Submodule

@ -0,0 +1 @@
Subproject commit 35318e2a35d537c804567957f884f40c95a58424

1
aux/broctl Submodule

@ -0,0 +1 @@
Subproject commit 2467a76106bad6a2224b7902d686dd6749088bd8

View file

@ -1,5 +0,0 @@
## Process this file with automake to produce Makefile.in
noinst_PROGRAMS = cf
cf_CFLAGS = -I$(top_srcdir)/src -I../src/ -I../../src
cf_SOURCES = cf.c version.c

View file

@ -1,133 +0,0 @@
.\" @(#) $Id: cf.1 2410 2005-12-27 00:58:20Z vern $ (LBL)
.\"
.\" Copyright (c) 2004
.\" The Regents of the University of California. All rights reserved.
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that: (1) source code distributions
.\" retain the above copyright notice and this paragraph in its entirety, (2)
.\" distributions including binary code include the above copyright notice and
.\" this paragraph in its entirety in the documentation or other materials
.\" provided with the distribution, and (3) all advertising materials mentioning
.\" features or use of this software display the following acknowledgement:
.\" ``This product includes software developed by the University of California,
.\" Lawrence Berkeley Laboratory and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.TH CF 1 "December 20, 2005"
.UC 4
.SH NAME
cf - unix time to formated time and date filter
.SH SYNOPSIS
.B cf
[
.B -f fmt
] [
.B -lpsu
] [
.I file ...
]
.SH DESCRIPTION
This filter reads the named files (or from stdin if there are none)
and replaces numeric timestamps found at the beginning of each line
with a formated time and date time and date. For example:
.LP
.RS
.na
.nh
\% echo '1074558944 default format' | cf
.br
Jan 19 16:35:44 default format
.ad
.hy
.RE
The default format is '%b\ %e\ %H:%M:%S'. The
.B \-l
flag appends the year ('%Y') to the default format. There are two
ways to specify a custom format; one is with the
.B \-f
flag. The other is to set the
.B CFTIMEFMT
environment variable. Finally, using an empty format with the
.B \-f
flag causes
.B cf
to revert to its default format.
Note that the
.B \-f
and
.B \-l
flags override the
.B CFTIMEFMT
environment variable.
.SH OPTIONS
.LP
.TP
.B \-f fmt
Specify a strftime(1) format string. For example:
.LP
.RS
.RS
.na
.nh
% echo '1074558944 custom format' | \\
cf -f '%Y-%m-%d\ %H:%M:%S'
.br
2004-01-19 16:35:44 custom format
.ad
.hy
.RE
.LP
.RE
.TP
.B \-l
Use the long format (which includes the year). For example:
.LP
.RS
.RS
.na
.nh
% echo '1074558944 long format' | cf -l
.br
Jan 19 16:35:44 2004 long format
.ad
.hy
.RE
.RE
.TP
.B \-p
Preserve sub-second timestamp info. For example:
.LP
.RS
.RS
.na
.nh
% echo '1100980501.867105 preserve format' | cf -p
.br
Nov 20 11:55:01.867105 preserve format
.ad
.hy
.RE
.RE
.TP
.B \-s
Do strict checking of the timestamp. The number is only considered
to be a valid timestamp and converted if it 9 or more characters
long and contains one or less dots.
.TP
.B \-u
Format using UTC (Coordinated Universal) instead of local time.
.LP
.SH "SEE ALSO"
.na
.nh
hf(1), strftime(3)
.ad
.hy
.\" .SH BUGS

View file

@ -1,189 +0,0 @@
/*
* Copyright (c) 1991, 1994, 1995, 1996, 1998, 1999, 2001, 2004
* 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: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char copyright[] =
"@(#) Copyright (c) 1991, 1994, 1995, 1996, 1998, 1999, 2001, 2004\n\
The Regents of the University of California. All rights reserved.\n";
static const char rcsid[] =
"@(#) $Id: cf.c 5857 2008-06-26 23:00:03Z vern $ (LBL)";
#endif
#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
static char *argv0;
extern char *optarg;
extern int optind, opterr;
int preserve = 0;
int strict = 0;
int utc = 0;
char *sfmt = "%b %e %H:%M:%S";
char *lfmt = "%b %e %H:%M:%S %Y";
char *fmt;
/* Forwards */
int main(int, char **);
void doone(FILE *, FILE *);
void usage(void);
int
main(argc, argv)
int argc;
char **argv;
{
register char *cp;
register int status, didany, op;
FILE *f;
int targc;
char **targv;
if ((cp = strrchr(argv[0], '/')) != NULL)
argv0 = cp + 1;
else
argv0 = argv[0];
/* Set default format */
if ((fmt = getenv("CFTIMEFMT")) == NULL)
fmt = sfmt;
opterr = 0;
while ((op = getopt(argc, argv, "f:lpsu")) != EOF)
switch (op) {
case 'f':
if (*optarg == '\0')
fmt = sfmt;
else
fmt = optarg;
break;
case 'l':
fmt = lfmt;
break;
case 'p':
++preserve;
break;
case 's':
++strict;
break;
case 'u':
++utc;
break;
default:
usage();
/* NOTREACHED */
}
targc = argc - optind;
targv = &argv[optind];
status = 0;
didany = 0;
while (targc > 0) {
f = fopen(*targv, "r");
if (f) {
doone(f, stdout);
(void) fclose(f);
} else {
(void) fprintf(stderr, "%s: fopen: ", argv0);
perror(*targv);
status |= 1;
}
--targc;
++targv;
++didany;
}
if (!didany)
doone(stdin, stdout);
exit(status);
}
void
doone(fin, fout)
FILE *fin, *fout;
{
time_t ts;
register char *bp, *dotbp;
register struct tm *tp;
register int dot_count;
char buf[1024];
char tstr[128] = "";
static time_t lastts = 0;
while (fgets(buf, sizeof(buf), fin)) {
bp = buf;
dotbp = NULL;
if (isdigit(*bp)) {
ts = atol(bp);
++bp;
dot_count = 0;
while (isdigit(*bp) || *bp == '.') {
if (*bp == '.') {
dotbp = bp;
++dot_count;
}
++bp;
}
if (strict && (bp - buf < 9 || dot_count > 1 ||
(bp - buf > 10 && dot_count != 1))) {
/* Doesn't look like a genuine timestamp -
* skip it.
*/
fputs(buf, fout);
continue;
}
if (lastts != ts) {
if (!utc)
tp = localtime(&ts);
else
tp = gmtime(&ts);
(void)strftime(tstr, sizeof(tstr), fmt, tp);
lastts = ts;
}
fputs(tstr, fout);
if (preserve && dotbp != NULL)
bp = dotbp;
}
fputs(bp, fout);
}
}
void
usage()
{
extern char version[];
(void)fprintf(stderr, "%s version %s\n", argv0, version);
(void)fprintf(stderr, "usage: %s [-f fmt] [-lpsu] [file ...]\n", argv0);
exit(1);
}

View file

@ -1,43 +0,0 @@
/* @(#) $Header$ (LBL) */
/* Define __P() macro, if necessary */
#ifndef __P
#if __STDC__
#define __P(protos) protos
#else
#define __P(protos) ()
#endif
#endif
/* inline foo */
#ifdef __GNUC__
#define inline __inline
#else
#define inline
#endif
/*
* Handle new and old "dead" routine prototypes
*
* For example:
*
* __dead void foo(void) __attribute__((volatile));
*
*/
#ifdef __GNUC__
#ifndef __dead
#define __dead volatile
#endif
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
#ifndef __attribute__
#define __attribute__(args)
#endif
#endif
#else
#ifndef __dead
#define __dead
#endif
#ifndef __attribute__
#define __attribute__(args)
#endif
#endif

View file

@ -1 +0,0 @@
char version[] = "1.2";

View file

@ -1,8 +0,0 @@
This directory contains unsupported contributions to Bro. If you have
something to contribute to this directory please send it to us.
policy/
miscellaneous .bro policy file you might find useful
scripts/
miscellaneous support scripts, alternate report formats, etc.

View file

@ -1,8 +0,0 @@
Contents of this directory:
syslog.bro: Bro analyzer for broccoli-based syslog data
user-check.bro: Bro analyzer for syslog-based user data (bad usernames, etc.)
client-heartbeat.bro: Generate heartbeat events and send to other Bro's
server-heartbeat.bro: Generate alarm if don't receive a heartbeat event

View file

@ -1,55 +0,0 @@
# client-heartbeat.bro
# Send heartbeat events to a remote server
# $Id: client-heartbeat.bro,v 1.3 2007/02/26 07:03:20 jason Exp $
# load remote communications
@load remote
global bro_heartbeat_interval = 15 min &redef;
# heartbeat server (ip address)
global bro_heartbeat_server: addr = 127.0.0.1 &redef;
# name of this host (optional, its not used)
global myhostname = "foo.example.com" &redef;
global myip = 127.0.0.1 &redef;
######################################################################
# Shouldn't need to modifiy anything below this
# (Unless your not using SSL, then you will)
######################################################################
# who to 'heartbeat' to (i.e. the heartbeat server)
# usually hostname-service (i.e. host.lbl.gov-syslog)
redef Remote::destinations += {
["server-heartbeat"] = [$host=bro_heartbeat_server,
$retry=60 sec, $connect=T, $ssl=F],
};
# do nothing in the client
event heartbeat_event( ts: double, myip: addr, hostname: string )
{
# intentionally left empty
}
# call heartbeat_event and schedule ourselves to run again
event send_heartbeat_event()
{
local hb_host = fmt ("%s", get_event_peer());
# NOT USED
local foo: double = 0.0;
event heartbeat_event( foo, myip, myhostname );
schedule bro_heartbeat_interval { send_heartbeat_event() };
}
# stick us in the queue to run
event bro_init()
{
# waiting till gethostname is put into production bro.bif
# if myhostname == "")
# {
# myhostname = gethostname();
# }
schedule bro_heartbeat_interval { send_heartbeat_event() };
}

View file

@ -1,92 +0,0 @@
# heartbeat-server.bro
# Listen for remote heartbeat events
# $Id: server-heartbeat.bro,v 1.6 2007/02/26 07:03:20 jason Exp $
# To use this analyzer, be sure to redef Remote::destinations
# and probably mail_dest too.
# start listening for remote hosts
@load listen-clear
# how long till 'lost' messages are genterated
global max_timeout = 30 min &redef;
# how often to bug about missing servers (60minutes)
global report_nag_time = 1 hr &redef;
# how many times to do this for? (0 forever)
global report_nag_times: count = 0 &redef;
#################################################
# shouldn't need to modifiy anything below here #
#################################################
# setup our Notice type
redef enum Notice += { LostHeartBeat } ;
global report_missing_heartbeat:
function(t: table[string] of count, idx: string) : interval;
global reported_address_heartbeat: table[string] of count &default=0
&create_expire = report_nag_time &expire_func = report_missing_heartbeat;
# function called when a monitored stream times-out
global lost_heartbeat:
function(t: table[string] of event_peer, idx: string) : interval;
# table holding who we are monitoring (cache peer for use in notice)
global heartbeats : table[string] of event_peer &write_expire = max_timeout &expire_func = lost_heartbeat;
# send email if we expire an entry in the table
function lost_heartbeat(t: table[string] of event_peer, idx: string): interval
{
NOTICE([$note=LostHeartBeat, $src_peer=heartbeats[idx],
$msg=fmt("Lost heartbeat from %s", idx) ]);
# pop him into the report table
reported_address_heartbeat[idx]= report_nag_times;
return 0 sec;
}
# send email if this server is *still* down
function report_missing_heartbeat(t: table[string] of count, idx: string): interval
{
# if he is back, just let this entry expire
if (idx in heartbeats)
{
return 0 secs;
}
NOTICE([$note=LostHeartBeat,
$msg=fmt("Still missing heartbeat from %s", idx) ]);
# pop him back into the report table
local times: count;
times = reported_address_heartbeat[idx];
# if he has time left put him back
if ( times > 1 )
reported_address_heartbeat[idx] = times - 1;
# if he is set to 0, keep him forever
else if (times == 0 )
reported_address_heartbeat[idx] = 0;
# not exactly sure why, but ....
return 60 sec;
}
# update table that we recieved a msg
event heartbeat_event( ts:double, orig_h:addr, info:string )
{
local hb_peer = get_event_peer();
local hb_host = fmt("%s", hb_peer$host);
print fmt("got heartbeat from %s", orig_h) ;
# use this one if you want to be notified if the service
# went down and came back up on a differnt port
#local hb_host = fmt("%s:%s", hb_peer$host, hb_peer$p);
heartbeats[hb_host] = hb_peer;
}

View file

@ -1,418 +0,0 @@
# general syslog analyzer 0.3
#
# NOTES:
# - for now, all IP addresses need to be expressed in IPv4 notation here or it will end up
# looking like 255.255.255.255
@load listen-clear
@load listen-ssl
@load user-check
# put something like this in hostname.bro file
#redef Remote::destinations += {
# ["syslog"] = [$host = 10.0.0.1, $events = /.*/, $connect=F, $retry = 60 secs, $ssl=T],
#};
# list of notices
redef enum Notice += {
LoginFail, # too many failed attempt to a given dest
LoginFailSrc, # num failed logins from source IP exceeds thresh
LoginFailPair, # num failed logins from IP pair exceeds thresh
LoginFailAccount, # num failed accounts from IP->IP exceeds thresh
LoginFailAccountPair, # num failed accounts from IP->account@IP exceeds thresh
LoginFailDict, # num failed authentications for IP->account@IP exceeds thresh
LoginAfterFail, # succ login after a series of bad from source IP
};
global syslog = open_log_file("syslog") &redef;
# overall design is as follows:
#
# SIP --->table[DIPs] of login_record for each SIP<->DIP
# --->count of total failed logins for SIP
# --->count of total failed accounts for SIP
# access cluster data fia the cluster.bro script since it can
# deal better with the general notion.
#
# data will be stored in two tables, one holding global data for the source IP,
# the other holding origIP<->respIP information. There is likely as better
# way to go about this.
# list of ssh auth_strings to ignore;
# gssapi-with-mic: ssh sometimes tries, this, fails, and they
# uses pass phrase to log in. Dont count this type of failure for now
# (may need to revisit this later if every see attack using this)
const skip_auth_strings = {"gssapi-with-mic", } &redef;
### config data ###
const dest_num_fail_logins = 25; # to a single dest
const source_num_fail_logins = 20; # across all hosts, from a single source
const source_num_fail_accounts = 20; #
const pair_num_fail_logins = 25; # applies to single IP<->IP sets
const pair_num_fail_accounts = 20; #
const single_account_fail = 25; # threshold for a single IP -> account@IP fail
# works also as dictionary threshold on a single account
### end config data ###
### data structs ###
# IP<->IP record
type pair_record: record {
total_logins: count &default=0; # failed login count in total
total_accounts: count &default=0; # total count of accounts seen
accounts: table[string] of count; # running count per unique account
#peer: set[count]; # event_peer$id for distributed analysis
};
# source record
type source_record: record {
stotal_logins: count &default=0;
stotal_accounts: count &default=0;
};
# table for source data
global source_list: table[addr] of source_record &write_expire = 24 hr;
# table for pair data
global pair_list: table[addr,addr] of pair_record &write_expire = 24 hr;
global dests : table[addr] of count &write_expire = 1 hr;
### end data structs, config and control
### begin functions and events ###
# for the following events, the existance test takes place since
# there is a chance that the postponed_ssh_login has removed the account
# as a problem. See that event for more information and complaining...
event login_fail_src(ts:double, orig_h:addr)
{
# Here we look for the total number of failed accounts assosciated with
# a source IP.
# make sure the problem still exists for the host
if ( orig_h in source_list )
{
local srec: source_record = source_list[orig_h];
if ( srec$stotal_logins >= source_num_fail_logins )
NOTICE([$note=LoginFailSrc, $src=orig_h,
$msg=fmt("%s Exceeded %d failed logins to multiple hosts",
orig_h, source_num_fail_logins)]);
}
}
event login_fail_account(ts:double, orig_h:addr, account:string)
{
# Here we look at the total number of unique failed accounts assosciated
# with a given source IP.
# make sure the problem still exists for the host
if ( orig_h in source_list )
{
local srec: source_record = source_list[orig_h];
if ( srec$stotal_accounts >= source_num_fail_accounts )
NOTICE([$note=LoginFailAccount, $src=orig_h,
$msg=fmt("%s has %s different account attempts to multiple hosts ",
orig_h, source_num_fail_accounts)]);
}
}
event login_fail_pair(ts:double, orig_h:addr, resp_h:addr, account:string)
{
# Here we look at the number of failed logins for a pair of IP addresses.
# make sure the problem still exists for the host
if ( [orig_h, resp_h] in pair_list )
{
local prec: pair_record = pair_list[orig_h, resp_h];
if ( prec$total_logins >= pair_num_fail_logins )
NOTICE([$note=LoginFailPair, $src=orig_h, $dst=resp_h,
$msg=fmt("%s -> %s Exceeded %s failed logins for %s",
orig_h, resp_h, prec$total_logins, account)]);
}
}
event login_fail_account_pair(ts:double, orig_h:addr, resp_h:addr, account:string)
{
# Here we look at the number of failed accounts per IP pair.
if ( [orig_h, resp_h] in pair_list )
{
local prec: pair_record = pair_list[orig_h, resp_h];
if ( prec$total_logins >= pair_num_fail_accounts )
NOTICE([$note=LoginFailAccountPair, $src=orig_h, $dst=resp_h,
$msg=fmt("%s -> %s Exceeded %s failed accounts",
orig_h, resp_h, prec$total_accounts)]);
}
}
event login_fail_dict(ts:double, orig_h:addr, resp_h:addr, account:string)
{
# Here we look at the number of times an account has failed for a given IP
# pair. This is looking in particular for dictionary attacks
if ( [orig_h, resp_h] in pair_list )
{
local prec: pair_record = pair_list[orig_h, resp_h];
# make sure that the account is still there
if ( account in prec$accounts )
{
if ( prec$accounts[account] >= single_account_fail )
# *finally* we are able to send the notice. seems
# like a lot of work...
NOTICE([$note=LoginFailDict, $src=orig_h, $dst=resp_h,
$msg=fmt("%s -> %s@%s Exceeded %s failed tries",
orig_h, account, resp_h, prec$accounts[account])]);
}
} # end pair check
}
event ssh_login(ts:double, orig_h:addr, resp_h:addr, account:string, auth_type:string)
{
print syslog, fmt("%.1f ssh_login %s -> %s@%s %s", ts, orig_h, account, resp_h, auth_type);
local prec: pair_record;
# run a basic check on the user
check_user(ts, orig_h, resp_h, account, auth_type);
if ( [orig_h,resp_h] in pair_list )
{
# we have seen the pair, have we seen the account?
prec = pair_list[orig_h, resp_h];
if ( account in prec$accounts )
{
# there is a history of failure, check threshold. Also skip the
# informational accounts since there is a great deal of noise with them
if ( (prec$accounts[account] == single_account_fail) && (!informational_user(account)) )
{
NOTICE([$note=LoginAfterFail, $src=orig_h, $dst=resp_h,
$msg=fmt("%s -> %s@%s user login after %s failed logins ",
orig_h, account, resp_h, single_account_fail)]);
}
}
}
else
{
# add new pair list
local tmp_accounts: table[string] of count;
tmp_accounts[account] = 1;
prec$total_logins = 1;
prec$total_accounts = 1;
prec$accounts = tmp_accounts;
pair_list[orig_h, resp_h] = prec;
}
} # end ssh_ok_login
event ssh_fail_login(ts:double, orig_h:addr, resp_h:addr, account:string, auth_type:string)
{
local prec: pair_record;
local srec: source_record;
print syslog, fmt("%.1f ssh_fail_login %s -> %s@%s %s", ts, orig_h, account, resp_h, auth_type);
if (auth_type in skip_auth_strings )
{
print syslog, fmt("ignoring ssh_fail: %s", auth_type);
return;
}
# run a basic check on the user
check_user(ts, orig_h, resp_h, account, "ssh_fail");
# there are a number of accounts that are infrastructural in nature
# and used internally. We skip them for now even though this is
# probably not such a good idea
# include local addrs too and see what happens
#if ( (!is_local_addr(orig_h)) && (!informational_user(account)) )
if ( (!informational_user(account)) )
{
# look at dest
if ( resp_h !in dests )
dests[resp_h] = 0;
++dests[resp_h];
if (dests[resp_h] == dest_num_fail_logins)
NOTICE([$note=LoginFail, $src=orig_h, $dst=resp_h,
$msg=fmt("Exceeded %d failed logins from %s to %s",
dest_num_fail_logins, orig_h, resp_h)]);
if ( orig_h !in source_list )
{ # add a new record
srec$stotal_logins = 1;
srec$stotal_accounts = 1;
source_list[orig_h] = srec;
}
else
{
srec = source_list[orig_h];
# schedule an event to trigger the notice to provide an opportunity
# to correct for pam running thorough 'false negatives'
if ( ++srec$stotal_logins == source_num_fail_logins )
schedule 10 sec { login_fail_src(ts, orig_h) };
# for the time being this is being commented out ...
#if ( ++srec$stotal_accounts == source_num_fail_accounts )
# schedule 10 sec { login_fail_account(ts, orig_h, account) };
}
# look at pair
if ( [orig_h, resp_h] !in pair_list )
{
local tmp_accounts: table[string] of count;
tmp_accounts[account] = 1;
prec$total_logins = 1;
prec$total_accounts = 1;
prec$accounts = tmp_accounts;
}
else
{
prec = pair_list[orig_h, resp_h];
# this is a gross evaluation of the total login failures between two hosts
# which is really the sum of all failures - accounts single or multiple
if ( ++prec$total_logins == pair_num_fail_logins )
schedule 10 sec
{
login_fail_pair(ts, orig_h, resp_h, account)
};
# have we seen the account before?
if ( account !in prec$accounts )
{
prec$accounts[account] = 1;
# look for multiple failures for many accounts: increment since this is new
if ( ++prec$total_accounts == pair_num_fail_accounts )
schedule 10 sec
{
login_fail_account_pair(ts, orig_h, resp_h, account)
};
}
else
{
# look for multiple failures for a single account
if ( ++prec$accounts[account] == single_account_fail )
schedule 10 sec
{
login_fail_dict(ts, orig_h, resp_h, account)
};
}
}
# update data
#print "syslog: ssh_fail, updating source_list and pair_list ", srec, prec;
source_list[orig_h] = srec;
pair_list[orig_h, resp_h] = prec;
} # end initial internal/user filter
}
event postponed_ssh_login(ts:double, orig_h:addr, resp_h:addr, account:string, auth_type:string)
{
# This abomination is a result of a login passing through pam and ssh sending
# sperious 'failed' messages with the final successful login message.
# Here we intercept the data before the scheduled NOTICE event and change it back.
# This is a prime example of how to introduce race conditions into code, but for the time
# being I have nothing better.
print syslog, fmt("%.1f postponed_ssh_login %s -> %s@%s %s", ts, orig_h, account, resp_h, auth_type);
# this code is almost the same as above except that we are removing values (which introduces
# more testing).
local prec: pair_record;
local srec: source_record;
local delta: count = 2; # ammount to decrement
# look at source, skip if record does not exist
if ( orig_h in source_list )
{
srec = source_list[orig_h];
if ( (srec$stotal_logins - delta) >= 0 )
srec$stotal_logins = srec$stotal_logins - delta;
if ( (srec$stotal_accounts - delta) >= 0 )
srec$stotal_accounts = srec$stotal_logins - delta;
}
# look at pair, again skipping unknown sessions (throw weird?)
if ( [orig_h, resp_h] in pair_list )
{
prec = pair_list[orig_h, resp_h];
if ( (prec$total_logins - delta) >= 0 )
prec$total_logins = prec$total_logins - delta;
if ( (prec$total_accounts - delta) >= 0 )
prec$total_accounts = prec$total_logins - delta;
if ( account in prec$accounts )
{
if ( (prec$accounts[account] - delta) >= 0 )
prec$accounts[account] = prec$accounts[account] - delta;
}
} # end pair check
source_list[orig_h] = srec;
pair_list[orig_h, resp_h] = prec;
} # end of postpend
# really want both users, waiting for fix..
#event failed_su(ts:double, orig_h:addr, user:string, user2:string)
event failed_su(ts:double, orig_h:addr, user:string)
{
#print syslog, fmt("%.1f failed_su %s %s", ts, orig_h, user, user2 );
print syslog, fmt("%.1f failed_su %s %s", ts, orig_h, user);
# should generate a notice if too many of these
}
event successful_su (ts:double, orig_h:addr, logname: string, user:string )
{
print syslog, fmt("%.1f sucussful_su %s %s to %s", ts, orig_h, logname, user );
}
event failed_sudo (ts:double, orig_h:addr, user:string )
{
print syslog, fmt("%.1f failed_sudo %s@%s", ts, user, orig_h );
# should generate a notice if too many of these
}
event successful_sudo (ts:double, orig_h:addr, user:string, command:string)
{
print syslog, fmt("%.1f sucussful_sudo %s@%s %s", ts, user, orig_h, command );
}
#other syslog events: Grid stuff
#"gateInit double=$time addr=$runhost addr=$reqhost count=$p \n";
#"gateUser addr=$runhost count=$p2 string=$IDFields[9]\n";
#"gateService addr=$runhost count=$p2 string=$srvFields[8]\n";
#"gateLocalUser addr=$runhost count=$p2 string=$LUFields [10] string=$LUFields[6]\n";
#"gateLocalUID addr=$runhost count=$p2 count=$LUFields[10] string=$LUFields[6]\n";
#print "gateLocalGID addr=$runhost count=$p2 count=$GUFields[9]\n";

View file

@ -1,82 +0,0 @@
# version 0.1
# script to make detailed decisions about user logins
#
# there are three levels of interest -
# informational : general interest (say root) for account use
# suspicious : specific accounts that you do not
# expect to see and should know (such as 'lp')
# dead_man_walkin : accounts that may represent former employies
# or known bad entities.
#
# the choice to differentiate between the second and third may be gratuitious...
#
#
redef enum Notice += {
SuspiciousUser, # a user is seen that should not normally be there
ForbiddenUser, # known bad user account, more dangerous than suspicous
SensitiveRemoteLogin, # root ssh connection from remote host
};
global check_dead_man_walkin = T &redef;
global check_user_list = T &redef;
global check_remote_access_accounts = T &redef;
# this one not finished: might want to flag these someday
const information_accounts = { "operator", } &redef;
const suspicious_accounts = { "lp", "toor", "admin", "test", "r00t", "bash", } &redef;
const forbidden_accounts = { "", } &redef;
# this is for accounts that you do not want logging in remotely
const no_remote_accounts = { "root", "system", "operator", } &redef;
function informational_user(user: string) : bool
{
if ( user in information_accounts )
return T;
return F;
}
function check_user(ts:double, orig_h:addr, resp_h:addr, account:string, auth_type:string) : bool
{
# compare provided user with a list of potential bad accounts
# see note above about hot-ids: this provides a little better
# flexability for general checking
#
#print "checking user: ", account;
if ( check_dead_man_walkin && account in forbidden_accounts )
{
NOTICE([$note=ForbiddenUser,
$msg=fmt("%s -> %s@%s forbidden user login",
orig_h, account, resp_h)]);
return T;
}
if ( check_user_list && account in suspicious_accounts )
{
NOTICE([$note=SuspiciousUser,
$msg=fmt("%s -> %s@%s suspicious user login",
orig_h, account, resp_h)]);
return T;
}
if ( check_remote_access_accounts && account in no_remote_accounts
&& !is_local_addr(orig_h) && auth_type != "ssh_fail" )
{
NOTICE([$note=SensitiveRemoteLogin,
$msg=fmt("%s -> %s@%s successful sensitive remote login",
orig_h, account, resp_h)]);
return T;
}
return F;
}

View file

@ -1,5 +0,0 @@
Contents of this directory:
syslog2broccoli.py: converts syslog data to Broccoli events
bro_report.py: alternate report script

View file

@ -1,553 +0,0 @@
#!/usr/bin/env python
#
# Alternate script to generate a report using the alarm and
# conn files for a given day.
# Notes: My experience is that everyone has their own ideas on what
# Bro reports should look like, so rather than try to please
# everyone, we'd like to include several sample report scripts, and
# encourage people to generate their own script based on the
# sample scripts. This is one such example. If you have your
# own script to contribute, please email to the Bro team.
#
# Brian Tierney, LBL
#
# input: date of report, bro.cfg file, and bro/site/local.site.bro file
# output: a report emailed address specified
#
__doc__="""
Usage: bro_report.py [-s start_time -e end_time] [-x] -m email_address
default start/end time = 24 period ending now
date format = YYYY-MM-DD-HH-mm
[-y] put connection logs at the end of the report
"""
# TO DO:
# add ability to use report_alarms instead of ignore_alarms
# add non-html option (for Vern :-) )
# add css for more formatting options
#
import os, time, sys, datetime, socket, getopt, glob, re
# initialize globals
# set this for your preferences
ignore_alarms = ["AddressScan", "PortScan", "ScanSummary", "AddressDropped"]
# not yet implemented
report_alarms = []
brohome = os.getenv("BROHOME")
if brohome == None:
brohome = "/usr/local/bro" # try using this
path = "%s/logs" % brohome
cf = "%s/bin/cf" % brohome
hf = "%s/bin/hf -l" % brohome
# this program uses mutt to send email with attachment
# Note: probably want to add something like this to your .muttrc file
# set from="bro@brohost.mysite.org"
# There is probably a more standard way to make this work...
mutt = "/usr/local/bin/mutt"
bro_local_nets = "%s/site/local.site.bro" % brohome
use_mtime = 1 # if set, use file modification time to find alarm files,
#conn_reports_at_end = 0 # set if want all connection info at end of the report
########################################################
# otherwise use file name
def get_file_names(start_time, end_time):
"""
using stat, get a list of all files modified on a given date
"""
global alarm_file_list
global conn_file_list
print "looking for alarms between %s and %s " % (time.ctime(start_time), time.ctime(end_time))
alarm_file_list = []
if use_mtime:
globstring = "%s/alarm*" % (path)
alarm_files = glob.glob(globstring)
cnt = 0
for afile in alarm_files:
st = os.stat(afile)
ctime = st[8]
mtime = st[9]
if (mtime >= start_time or ctime >= start_time) and (mtime <= end_time or ctime >= end_time):
alarm_file_list.append(afile)
cnt += 1
else:
rdate = time.strftime("%y-%m-%d", time.localtime(start_time))
globstring = "%s/alarm*%s*" % (path,rdate)
alarm_files = glob.glob(globstring)
cnt = 0
for afile in alarm_files:
alarm_file_list.append(afile)
cnt += 1
#print "Using this list of alarm files: ", alarm_file_list
conn_file_list = []
globstring = "%s/conn*" % (path)
conn_files = glob.glob(globstring)
for cfile in conn_files:
st = os.stat(cfile)
ctime = st[8]
mtime = st[9]
#if mtime >= start_time and mtime <= end_time:
if (mtime >= start_time or ctime >= start_time) and (mtime <= end_time or ctime >= end_time):
conn_file_list.append(cfile)
#print "Using this list of conn files: ", conn_file_list
return cnt
########################################################
def get_time(sdate):
"""
take command line arg and generate time
"""
if len(sdate.split("-")) == 3:
yr,mn,dy = sdate.split("-")
stime = (int(yr), int(mn), int(dy), 0, 0, 0, 0, 0, -1)
elif len(sdate.split("-")) == 4:
yr,mn,dy,hr = sdate.split("-")
stime = (int(yr), int(mn), int(dy), int(hr), 0, 0, 0, 0, -1)
elif len(sdate.split("-")) == 5:
try:
yr,mn,dy,hr,min = sdate.split("-")
except:
print "Error parsing date: ", sdate
usage()
stime = (int(yr), int(mn), int(dy), int(hr), int(min), 0, 0, 0, -1)
else:
print "Invalid data format"
usage()
rtime = time.mktime(stime)
return rtime
########################################################
def get_site_name(broConfig):
f = open(broConfig)
lines = f.readlines()
site_name = "Default"
for line in lines:
if line.startswith("BRO_SITE_NAME"):
site_name = line.split("=")[1]
site_name = site_name.replace('"','')
# no way to pass this directly to mutt, need to put in .muttrc instead
#if line.startswith("BRO_EMAIL_FROM"):
# mail_from = line.split("=")[1]
# mail_from = site_name.replace('"','')
return site_name
########################################################
def get_local_nets(localnets):
"""
reads Bro local.site.bro file to get a list of local networks
"""
# this ugly thing will match IP addresses
regexp = re.compile("([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0 -5])\.([01]?\d\d?|2[0-4]\d|25[0-5])")
f = open(localnets)
lines = f.readlines()
local_nets = []
if len(lines) > 0:
for line in lines:
fields = line.split()
if len(fields) > 0 and not fields[0].startswith("#"): # skip comment lines
#print fields
for f in fields:
match = regexp.match(f)
if match:
t = f.split("/")
local_nets.append(t[0])
else:
print "Bro local nets not found. Exiting. "
sys.exit(-1)
return local_nets
########################################################
def get_local_host(ip1,ip2,sh,dh,local_nets):
"""
based on contents of bro site file, determine which host is local
"""
local_host = ""
if ip2 != "none":
#print "debug:", ip1, ip2, sh, dh, local_nets
# HACK Alert: this will only work for /16 and /24 networks
for net in local_nets:
if net.split(".")[2] == "0": # assume class B
ipa = "%s.%s.0.0" % (ip1.split(".")[0] , ip1.split(".")[1] )
ipb = "%s.%s.0.0" % (ip2.split(".")[0] , ip2.split(".")[1] )
else: # assume class C
ipa = "%s.%s.%s.0" % (ip1.split(".")[0] , ip1.split(".")[1], ip1.split(".")[2] )
ipb = "%s.%s.%s.0" % (ip2.split(".")[0] , ip2.split(".")[1], ip2.split(".")[2] )
if ipa == net:
local_host = sh
break
if ipb == net:
local_host = dh
break
else:
local_host = sh
#print " found local host: ", local_host
if local_host == "": # sometimes see packets not on either net!
local_host = "host from unknown subnet!"
return local_host
########################################################
def create_alarm_info(aline, start_time, end_time):
"""
create log info record from alarm message
"""
# assume tagged alarm file; trick to parse correctly
if aline[:2] != "t=": # if line does not start with "t=", continue
print "Warning: not a tagged alarm: ", aline
return []
reformated_alarm = [t.replace('~',' ') for t in aline.replace('\\ ','~').split()]
ip1 = ip2 = sp = dp = "none"
alarm = msg = tm = tag = ""
for s in reformated_alarm:
field = s.split("=")
if field[0] == "sa":
ip1 = field[1]
if field[0] == "sp":
sp = field[1]
if field[0] == "da":
ip2 = field[1]
if field[0] == "dp":
dp = field[1]
if field[0] == "t":
try:
utime = float(field[1]) # unix-style time in seconds
except:
print "Error, unknown alarm format ", reformated_alarm
return []
if utime < start_time or utime > end_time:
return []
tm = time.ctime(float(field[1]))
if field[0] == "no":
alarm = field[1]
if field[0] == "tag":
tag = field[1]
if field[0] == "msg":
msg = field[1]
msg = msg.replace('\\ ', ' ')
# end for
if alarm in ignore_alarms: # skip if wrong type of alarm
return []
if tag == "":
tag = "missing tag"
print "Warning: Alarm tag not found: ", reformated_alarm
#return [] # only continue for tagged alarms
# look up src/dst addresses
sh = [""]
dh = [""]
try:
sh = socket.gethostbyaddr(ip1);
except:
sh[0] = ip1
try:
dh = socket.gethostbyaddr(ip2);
except:
dh[0] = ip2
#print "hostnames: %s = %s; %s = %s" % (ip1, sh[0], ip2, dh[0])
# save all useful info from this alarm
alarm_info = [alarm, tm, ip1, sp, sh[0], ip2, dp, dh[0], msg, tag, 0]
#print "alarm info: ", alarm_info
return alarm_info
########################################################
def load_alarms(start_time, end_time):
"""
load alarms from alarm log files into alarm_list
"""
# fills in alarm_list and host_list data structure
global alarm_list
global host_list
alarm_list = []
host_list = []
report_date = time.strftime("%y-%m-%d", time.localtime(end_time))
yr, mn, dy = report_date.split("-")
cnt = 0
for afile in alarm_file_list:
print "opening file:", afile
fd = open(afile)
# first read through entire alarm file and create list of hosts involved.
done = 0
while not done:
try:
tl = fd.readline()
except Exception, E:
print E
done = 1
continue
#print "read line: ",tl
if len(tl) == 0:
done = 1
#print "end of file"
continue
alarm_info = create_alarm_info(tl,start_time, end_time)
if alarm_info != []:
cnt += 1
#only add if this alarm for this host pair has not been seen before
alarm_exists = 0
for curr_alarm_info in alarm_list:
alarm,tm,ip1,sp,shost,ip2,dp,dhost,msg,tag,a_cnt = curr_alarm_info
if alarm == alarm_info[0] and ip1 == alarm_info[2] and ip2 == alarm_info[5]:
curr_alarm_info[10] += 1 # increment count
alarm_exists = 1
if not alarm_exists:
alarm_list.append(alarm_info)
# figure out which host is local and add to host_list[]
local_host = get_local_host(alarm_info[2], alarm_info[5], alarm_info[4], alarm_info[7], local_nets)
if local_host not in host_list:
print "Adding to host list: ", local_host
host_list.append(local_host)
#print host_list
#print alarm_list
print "Found %d alarms in this time period " % cnt
return cnt
######################################################################
def print_alarm(alarminfo,out):
""" Formats and outputs the alarms
"""
alarm,tm,ip1,sp,sh,ip2,dp,dh,msg,tag,a_cnt = alarminfo
out.write ('<table border="0" cellspacing="2" cellpadding="2"> \n <tr> \n')
out.write ('<td><div align="right"><strong> ')
# reformat alarm and write to file in a more readable format
alarm_string = '<strong>%s</strong>: <td> %s </td> </tr> \n <tr align="left"> <td align="right"> source: </td> <td align="left"> %s </td> <td> %s </td> <td> port = %s </td> </tr> \n <tr align="left"> <td align="right"> dest: </td> <td align="left"> %s </td> <td> %s </td> <td> port = %s </td> </tr> \n <tr> <td align="right"> alarm message: </td> <td colspan= 3 align="left"> %s %s </td> </tr> </table> \n' % (alarm, tm, ip1, sh, sp, ip2, dh, dp, msg, tag)
out.write(alarm_string)
if a_cnt > 1:
out.write("<ul>%d instances of this alarm for this host pair </ul>" % a_cnt)
out.write ("<p> \n")
######################################################################
def print_connections(connfiles,ip,tag,out):
""" Formats and outputs the connection logs
"""
# there must be a clever way to do this with the pipes module, but this will work for now
# only include connections that have state SF or S1 (should also include RSTO)
cmd = "grep -h ' %s ' %s | grep -e 'SF' -e 'S1' -e 'RSTO' | grep -A 10 -B 5 '%s$' | %s | %s > %s" % (ip, connfiles, tag, cf, hf, "/tmp/bro-report.tmp")
print "running program: ", cmd
os.system(cmd)
f = open("/tmp/bro-report.tmp")
lines = f.readlines() # read entire file
if len(lines) > 0:
out.write ('\n <table border="0" cellspacing="2" cellpadding="2"> \n')
out.write('<tr align="right"><td colspan= 3> Time </td> <td> Duration </td><td> Src host </td><td> Dst host </td> <td> Service </td> <td> Src port </td> <td> Dst port </td> <td> Prot </td> <td> Bytes sent </td><td> Bytes rcv </td> <td> State </td><td> Flag </td><td> Tag </td> </tr>')
for line in lines:
fields = line.split()
out.write('<tr align="right">')
for f in fields:
out.write("<td> %s </td>" % f)
out.write("</tr>")
out.write("</table> \n ")
else:
out.write ("<ul> No suscessful connections found. </ul> \n")
out.write ("<hr>\n")
######################################################################
def usage(m=None):
"""This just prints the doc string for the whole program.
"""
if m: print "Error: %s" % m
print __doc__
sys.exit()
########################################################
def main():
"""
parse opts, collect alarms, generate report
"""
global local_nets
global report_date
global conn_reports_at_end
conn_reports_at_end = 0
try:
options,prog_args = getopt.getopt(sys.argv[1:],'hxys:e:m:')
except getopt.GetoptError, E:
usage(E)
do_today = 0
report_date = sdate = edate = dest = ""
for opt,val in options:
if opt == '-s':
sdate = val
elif opt == '-e':
edate = val
elif opt == '-m':
dest = val
elif opt == '-y':
conn_reports_at_end = 1
else:
usage()
if dest == "":
print "Missing email address for report"
usage()
if sdate == "":
# set defauts
end_time = time.time()
start_time = end_time - (24 * 60 * 60) # number of seconds in 1 day
else:
# if start/stop times given at the command line, convert them to Unix time
if sdate != "":
start_time = get_time(sdate)
if edate == "": # if not specified, add 24 hrs
end_time = start_time + (24 * 60 * 60)
if edate != "":
end_time = get_time(edate)
if sdate == "": # if not specified, subtract 24 hrs
start_time = end_time + (24 * 60 * 60)
else:
end_time = start_time + (24 * 60 * 60) # number of seconds in 1 day
#print "start time: %f, %s " % (start_time, time.ctime(start_time))
#print "end time: %f, %s " % (end_time, time.ctime(end_time))
outfile = "%s/reports/bro.report.%d.html" % (brohome, os.getpid())
out = open(outfile, 'w')
if conn_reports_at_end: # open file to save all conn information, then cat to report at the end
outfile_conn = "%s/reports/bro.report.%d.tmp" % (brohome, os.getpid())
out_conn = open(outfile_conn, 'w')
rstart = time.strftime("%y-%m-%d %H:%M", time.localtime(start_time))
rend = time.strftime("%y-%m-%d %H:%M", time.localtime(end_time))
if get_file_names(start_time, end_time) <= 0:
print "No alarms found for time specified"
out.write ("<HTML><HEAD><TITLE> Bro Report %s to %s </TITLE></HEAD>\n" % (rstart, rend ) )
out.write ("<BODY><p> Bro Report %s-%s <p> \n" % (rstart, rend ) )
out.write ("<BODY><p><p> No alarms found for time specified \n </BODY></HTML>" )
sys.exit(0)
connfiles = ""
for connfile in conn_file_list: # build single string with all names in it
connfiles += "%s " % connfile
#print "connfiles ", connfiles
site_name = get_site_name("%s/etc/bro.cfg" % brohome)
local_nets = get_local_nets(bro_local_nets)
cnt = load_alarms(start_time, end_time)
out.write ("<HTML><HEAD><TITLE> Bro Report %s-%s </TITLE></HEAD>\n" % (rstart, rend ) )
out.write ("<BODY>")
out.write ("<p> Bro Report: %s-%s \n" % (rstart, rend ) )
out.write ("<p> Total Number of Alarms: %d \n " % cnt)
if cnt > 0:
out.write ("<br> List of %s hosts with Alarms in this report: \n <ul> " % site_name)
# now loop through alarm_list and generate report
for host in host_list:
out.write (" <p> <strong> %s </strong>" % (host))
out.write ("</ul> <p> <hr> \n")
else:
print "No Alarms found"
for alarm in alarm_list:
#print alarm
print_alarm(alarm,out)
tag = alarm[9]
if conn_reports_at_end:
taglink = "#alarm%s" % (tag)
out.write ('\n <ul> <a href="%s"> Successful Connections</a> just before and after this alarm </ul> <p>\n' % taglink)
else:
out.write ("Successful Connections just before and after this alarm: \n\n <p> \n" )
print "searching conn files '%s' for tag %s " % ( connfiles, tag)
if conn_reports_at_end:
out_conn.write('<P><A name="%s"></A>\n' % taglink.strip("#"))
if len(connfiles) > 0:
if conn_reports_at_end:
out_conn.write ('\n <p> \n Successful Connections just before and after alarm %s <p>\n' % tag)
print_connections(connfiles, alarm[2], tag, out_conn )
else:
print_connections(connfiles, alarm[2], tag, out )
if conn_reports_at_end and cnt > 0:
out.write ("<hr> \n")
out.write ("<p> Connection Summary Information \n" )
out_conn.close()
out.close()
cmd = "cat %s >> %s " % (outfile_conn, outfile)
print "Running command: ", cmd
os.system(cmd)
# next reopen the file
out = open(outfile, 'a')
out.write ("</body></html> \n")
out.close()
# done building report, now send it
#cmd = "/usr/bin/Mail -s 'Bro Report: %s' %s < %s" % (tm, dest, outfile)
# mail does not handle HTML attachments, so use mutt instead
cmd = "%s -s 'Bro Report from %s: %s to %s ' -a %s %s < /dev/null" % (mutt, socket.gethostname(), rstart, rend, outfile, dest)
print "running program: ", cmd
os.system(cmd)
try:
os.remove("/tmp/bro-report.tmp")
#os.remove(outfile)
except:
pass
sys.exit(0)
######################################################################
if __name__ == '__main__': main()

View file

@ -1,600 +0,0 @@
#! /usr/bin/env python
#
# this script finds the end of the syslog file, and then watches
# for new events to send to Bro. Actually they are reformatted
# as Broccoli events, and written to stdout. Then some other
# process can send them to Bro.
#
# started as a perl script from unknon source
# modified for syslog parsing by Scott Campbell
# more options added by Brian Tierney
#
# CHANGELOG: started 07/07/05
# fixed IPv6 support in sshd login analysis
# 07/12/05 change logic in ssh deny parsing to only look at what
# we want rather than reverse.
#
"""
script that looks at interesting entries in a syslog file
and print out information in a format that broccoli understands
"""
import optparse, logging, re, time
import select, socket, sys, threading
RE_SSH = re.compile(r"[\w,\s,\W]*sshd")
RE_SSH_ACCEPT = re.compile(r"[\w,\s,\W]*Accept")
# all Failures; leads to false possitives
# RE_SSH_FAIL = re.compile(r"[\w,\s,\W]*Failed")
# just failed passwords
RE_SSH_FAIL = re.compile(r"[\w,\s,\W]*Failed[\s]*password")
RE_SSH_FAIL_ILLEGAL_USER = re.compile(r"[\w,\s,\W]*illegal[\s]*user|[\w,\s,\W]*invalid[\s]*user")
RE_SSH_EXCLUDE = re.compile(r"[\w,\s,\W]*com\.apple\.SecurityServer")
# only do failures for now
RE_SUDO = re.compile(r"[\w,\s,\W]*sudo[\w,\s,\W]+failure|[\w,\s,\W]*sudo[\w,\s,\W]+incorrect password attempts")
RE_SUDO_FORMAT1 = re.compile(r"[\w,\s,\W]*sudo[\w,\s,\W]+failure")
RE_SUDO_FORMAT2 = re.compile(r"[\w,\s,\W]*sudo[\w,\s,\W]+incorrect password attempts")
RE_SU_SUCCESS = re.compile(r"[\w,\s\W]*su: \(|[\w,\s,\W]*su: SU |[\w,\s,\W]*su[\w,s,\W]+session opened")
RE_SU_FORMAT1 = re.compile(r"[\w,\s,\W]*session opened for user [\w,\W]+ by [\w,\W]+")
RE_SU_FORMAT2 = re.compile(r"[\w,\s,\W]*su:[\s]*\(to [\w]+\) [\w]+")
RE_SU_FORMAT3 = re.compile(r"[\w,\s,\W]*su: SU")
RE_SU_FAIL = re.compile(r"[\w,\s\W]* BAD SU |[\w,\s,\W]* FAILED SU |[\w,\s,\W]*su[\w,\s,\W]*authentication failure")
RE_SU_FAIL_FORMAT1 = re.compile(r"[\w,\s,\W]*authentication failure")
RE_SU_FAIL_FORMAT2 = re.compile(r"[\w,\s,\W]*FAILED SU")
RE_SU_FAIL_FORMAT3 = re.compile(r"[\w,\s,\W]*BAD SU")
RE_GRID = re.compile(r"[\w,\s\W]* GRAM")
RE_GRID_AUTHORIZE_LOCALUSER = re.compile(r"[\w,\s,\W]* Authorized as local user")
RE_GRID_AUTHORIZE_LOCALUID = re.compile(r"[\w,\s,\W]* Authorized as local uid:")
RE_GRID_AUTHORIZE_LOCALGID = re.compile(r"[\w,\s,\W]* and local gid:")
RE_GRID_AUTHENTICATE = re.compile(r"[\w,\s,\W]* Authenticated globus user:")
RE_GRID_CONNECT = re.compile(r"[\w,\s,\W]* Got connection ")
RE_GRID_SERVICE = re.compile(r"[\w,\s,\W]* Requested service: ")
RE_GRID_INFO = re.compile(r"[\w,\s,W]*gridinfo")
# not done: generate Bro event for these too
RE_NEWUSER = re.compile(r"[\w,\s,\W]*new user:[\w,\s,\W]+useradd")
# not done: generate Bro event for user root sending mail to yahoo, gmail, hotmail, aol, etc.
# (maybe even any .com ?)
RE_ROOT_EMAIL = re.compile(r"[\w,\s,\W]*sendmail[\w,\s,\W]+root[\w,\s,\W]+to `[\w,\s,\W]+\.com")
class HeartBeatThread(threading.Thread):
"""
HeartBeat class that inherits from Python Thread class
"""
def __init__(self, sleep_seconds):
threading.Thread.__init__(self)
self._sleeptime = sleep_seconds
def run(self):
"""
Sends out a heartbeat event, then goes to sleep for 15 minutes
"""
addr = socket.gethostbyname(socket.gethostname())
heartbeat_string = "Syslog_daemon_heartbeat"
while True:
time_double = time.time()
print "heartbeat_event double=%d addr=%s string=%s" % (time_double, addr, heartbeat_string)
time.sleep(self._sleeptime)
def time_conversion(month, date, clocktime):
"""
Convert time string to double, need to handle the
year field
"""
year = time.asctime().split()[-1:][0]
time_str = " ".join((month, date, clocktime, year))
try:
time_tuple = time.strptime(time_str, "%b %d %H:%M:%S %Y")
except:
log.error( "time.strptime error converting %s" % time_str )
return 0.0
time_double = time.mktime(time_tuple)
return time_double
def check_ip(ip):
"""
Covert hostname to IP if necessary, and check if valid IP
"""
try:
ip = socket.gethostbyname(ip)
except:
log.error( "Error converting %s to an IP " % ip )
return ""
# if passed in something that looked like an IP, gethostbyname might not return an error, so best to check
try:
ips = ip.split('.')
except:
log.error("Error spliting IP into components: %s" % ip)
return ""
if len(ips) == 4:
if int(ips[0]) < 256 and int(ips[1]) < 256 and int(ips[2]) < 256 and int(ips[3]) < 256:
return ip
else:
return ""
else:
return ""
def find_user(fields):
"""
Find the user in a list of fields where user is the name in user=name
"""
user = "unknown"
for f in fields:
try:
user1, user2 = f.split('=')
if user1 == 'user' or user1 == 'ruser':
if user2 != "":
return user2
except:
pass
return user
def parse_ssh(line, line_cnt):
"""
print out the ssh fields into the broccoli format
Note: still needs to handle odd syslog formats, such as (double set of timestamps):
Jan 1 00:03:44 127.0.0.1 2005-12-31 21:51:10.163447500 isthiswhatyouwant.jay.lbl.gov sshd[] PAM: Authentication failure for ldoolitt from astound-69-42-20-231.ca.astound.net
There are many different formats, but the following seem fairly consistant:
for username
from hostname
so look for works "for" and "from", and then take the fields after that
"""
fields = line.split()
time_double = time_conversion(fields[0], fields[1], fields[2])
# look for 'from' hostname
n = 0
from_ip = ""
for f in fields:
if f == "from":
from_ip = fields[n+1]
break
n += 1
# check for valid IP (some look like this: "::ffff:128.3.60.86")
ipf = from_ip.split(':')
if len(ipf) > 1:
ip = ipf[len(ipf) - 1]
else:
ip = ipf[0]
# verify that this is a valid IP address
ip = check_ip(ip)
lh_ip = check_ip(fields[3])
success = False
failed = False
auth_type = "unknown"
username = "unknown"
if RE_SSH_ACCEPT.match(line):
success = True
try:
auth_index = fields.index('Accepted')
username_index = fields.index('for')
except ValueError:
log.error( "Error: sshd line with unknown format: line %d,%s" % (line_cnt, line))
return
auth_type = fields[auth_index +1]
username = fields[username_index +1]
if RE_SSH_FAIL.match(line) and not RE_SSH_EXCLUDE.match(line):
failed = True
try:
auth_index = fields.index('Failed')
username_index = fields.index('for')
except ValueError:
log.error( "Error: sshd line with unknown format: line %d,%s" % (line_cnt, line))
return
auth_type = fields[auth_index + 1]
if RE_SSH_FAIL_ILLEGAL_USER.match(line):
username = fields[username_index +3]
else:
username = fields[username_index +1]
if ip and lh_ip:
if success:
print "ssh_login double=%d addr=%s addr=%s string=%s string=%s" % (time_double, ip, lh_ip, username, auth_type)
if failed:
print "ssh_fail_login double=%d addr=%s addr=%s string=%s string=%s" % (time_double, ip, lh_ip, username, auth_type)
else:
log.error( "Error: sshd line with unknown format: line %d" % (line_cnt))
def parse_sudo(line):
"""
print out the sudo fields in the broccoli format
Supports these formats
1. host sudo(pam_unix)[5835]: authentication failure; logname=user uid=0 euid=0 tty=pts/4 ruser= rhost= user=user
2. host sudo: user: 3 incorrect password attempts ;
TTY=pts/11 ; PWD=directory COMMAND=/bin/ls
"""
fields = line.split()
time_double = time_conversion(fields[0], fields[1], fields[2])
# look for user
user = "unknown"
if RE_SUDO_FORMAT1.match(line):
user = find_user(fields)
if RE_SUDO_FORMAT2.match(line):
user = fields[5]
if user == "":
user = "unknown"
# check if need to convert to IP addr
lh_ip = check_ip(fields[3])
if user == "unknown":
log.debug("unhandled user in next line" )
log.debug(line)
print "failed_sudo double=%d addr=%s string=%s " % (time_double, lh_ip, user )
def parse_su_success(line, line_cnt):
"""
print out the su fields in the broccoli format
This one is hard because there are MANY formats used for this, including:
This function handles these 3 formats
1. session opened for user by user
2. (to root) user
3. su: SU
user to root
'su root' succeeded for user
Not quite done: does not always correctly find logname or username
"""
fields = line.split()
time_double = time_conversion(fields[0], fields[1], fields[2])
logname = "unknown"
user = "unknown"
if RE_SU_FORMAT1.match(line):
try:
index = fields.index('user')
except ValueError:
log.error( "Error: su line with unknown format: line %d,%s" % (line_cnt, line))
return
logname = fields[index +1]
user = fields[index +3]
if RE_SU_FORMAT2.match(line):
logname = fields[6].rstrip(')')
user = fields[7]
if RE_SU_FORMAT3.match(line):
try:
index = fields.index('SU')
except ValueError:
log.error( "Error: su line with unknown format: line %d,%s" % (line_cnt, line))
return
user = fields[index +1]
if user == "unknown":
log.debug("unhandled case on line: %d " % line_cnt)
log.debug(line)
lh_ip = check_ip(fields[3])
print "successful_su double=%d addr=%s string=%s string=%s" % (time_double, lh_ip, logname, user)
def parse_su_fail(line, line_cnt):
"""
print out the su fields in the broccoli format
This one is hard because there are MANY formats used for this, including:
authentication failure;
logname=user uid=uid euid=0 tty= ruser=jason rhost= user=root
We match this case only
1. BAD SU user to root
These cases are not handled
FAILED SU (to root) user
'su root' failed for user
"""
fields = line.split()
time_double = time_conversion(fields[0], fields[1], fields[2])
user = "unknown"
if RE_SU_FAIL_FORMAT1.match(line):
user = find_user(fields)
if RE_SU_FAIL_FORMAT2.match(line):
fail_test1 = False
fail_test2 = False
try:
index = fields.index('to')
except:
fail_test1 = True
try:
index = fields.index('(to')
except:
fail_test2 = True
if fail_test1 and fail_test2:
log.error("su fail: -to- not found: line %d" % line_cnt)
else:
user = fields[index +1]
if RE_SU_FAIL_FORMAT3.match(line):
try:
index = fields.index('to')
user = fields[index - 1]
except:
log.error("su fail: -to- not found: line %d " % line_cnt)
if user == "":
user = "unknown"
if user == "unknown":
log.debug("unhandled case on line %d" % line_cnt)
log.debug(line)
lh_ip = check_ip(fields[3])
print "failed_su double=%d addr=%s string=%s" % (time_double, lh_ip, user)
def parse_gate(line, line_cnt):
"""
print out the globus fields in the broccoli format
Not finished
"""
fields = line.split()
time_double = time_conversion(fields[0], fields[1], fields[2])
if RE_GRID_AUTHORIZE_LOCALUSER.match(line):
gate_ip = check_ip(fields[3])
pid = fields[5].strip("gatekeeper[]:")
user = fields[10]
print "gatekeeper_local_user addr=%s count=%s string=%s string=Authorized" % (gate_ip, pid, user)
elif RE_GRID_AUTHORIZE_LOCALUID.match(line):
gate_ip = check_ip(fields[3])
pid = fields[5].strip("gatekeeper[]:")
uid = fields[10]
print "gatekeeper_local_uid addr=%s count=%s string=%s string=Authorized" % (gate_ip, pid, uid)
elif RE_GRID_AUTHORIZE_LOCALGID.match(line):
gate_ip = check_ip(fields[3])
pid = fields[5].strip("gatekeeper[]:")
gid = fields[9]
print "gatekeeper_local_uid addr=%s count=%s string=%s string=Authorized" % (gate_ip, pid, gid)
elif RE_GRID_AUTHENTICATE.match(line):
print "authenticate"
gate_ip = check_ip(fields[3])
pid = fields[5].strip("gatekeeper[]:")
dn = " ".join(fields[9:])
print "gatekeeper_auth_user addr=%s count=%s string=%s string=Authorized" % (gate_ip, pid, dn)
elif RE_GRID_CONNECT.match(line):
gate_ip = check_ip(fields[3])
src_ip = check_ip(fields[8])
pid = fields[5].strip("gatekeeper[]:")
print "gateekeeper_connect double=%d addr=%s addr=%s count=%s" % (time_double, gate_ip, src_ip, pid)
elif RE_GRID_SERVICE.match(line):
gate_ip = check_ip(fields[3])
pid = fields[5].strip("gatekeeper[]:")
service = fields[8]
print "gatekeeper_service double=%d addr=%s count=%s string=%s" % (time_double, gate_ip, pid, service)
else:
log.debug("unhandled case on line %d" % line_cnt)
log.debug(line)
def parse_newuser(line):
"""
print out the newuser fields in the broccoli format
Not finished
"""
fields = line.split()
time_double = time_conversion(fields[0], fields[1], fields[2])
lh_ip = check_ip(fields[3])
#print "new_user double=%d addr=%s string=%s" % (time_double, lh_ip, user)
def parse_root_email(line):
"""
print out the root email fields in the broccoli format
Not finished
"""
fields = line.split()
time_double = time_conversion(fields[0], fields[1], fields[2])
lh_ip = check_ip(fields[3])
#print "root_email double=%d addr=%s addr=%s" % (time_double, lh_ip, ip)
def log_parse(syslog_file, opts):
"""
Continually parse the log file, and print information to stdout
"""
line_cnt = 0
done = 0
if opts.begin_tail or opts.begin:
tail = 0
else:
tail = 1
day = int(time.strftime("%d")) # day that program is started
today = time.strftime("%Y-%m-%d")
while not done:
try:
line = syslog_file.readline()
except Exception, E:
log.error ("Error reading file. Possibly log file was rotated, so try to reopen " )
syslog_file.close()
fname = "%s/all-%s" % (opts.path, today)
try:
syslog_file = open(fname)
except:
log.error( "Error opening syslog file %s " % (fname))
sys.exit(-1)
if len(line) == 0 and opts.begin: # if not tailing the file
done = 1
log.debug ("End of file. Num lines = %d. Exiting" % line_cnt)
sys.exit(1);
if len(line) == 0 and opts.begin_tail and tail == 0:
tail = 1 # start tailing the file
log.debug ("Reached End of file, now tailing the file")
line_cnt += 1
if not (line_cnt % 50000):
log.debug ("Processed %d lines" % line_cnt)
try:
if RE_SSH.match(line) and ( RE_SSH_ACCEPT.match(line) or RE_SSH_FAIL.match(line) ):
parse_ssh(line, line_cnt)
elif RE_SUDO.match(line):
parse_sudo(line)
elif RE_SU_SUCCESS.match(line):
parse_su_success(line, line_cnt)
elif RE_SU_FAIL.match(line):
parse_su_fail(line, line_cnt)
elif RE_GRID.match(line):
parse_gate(line, line_cnt)
elif RE_NEWUSER.match(line):
parse_newuser(line.split())
elif RE_ROOT_EMAIL.match(line):
parse_root_email(line.split())
else:
#This outputs too much information, this should be turned
#on if we set verbose to the next level
#log.debug("Not matching line: %s" % line)
pass
except:
log.error ("Error parsing log file. Corrupt log entry: %s" % line )
continue
sys.stdout.flush()
if tail: # go slow if tailing the file
select.select([], [], [], .01)
# if tailing the file and path is set,
#need to roll over to a new file at midnight
if opts.path:
check_day = int(time.strftime("%d"))
if day != check_day:
# new day, so open new file
syslog_file.close()
today = time.strftime("%Y-%m-%d")
fname = "%s/all-%s" % (opts.path, today)
log.debug( "New Day, so opening new syslog file: %s " % (fname))
try:
syslog_file = open(fname)
except:
log.error( "Error opening syslog file %s " % (fname))
sys.exit(-1)
day = check_day
line_cnt = 0
def log_open(opts):
"""
open the logfile at the beginning or end
depending on the command line arguments
"""
global log
logging.basicConfig()
log = logging.getLogger("sys2broccoli")
if opts.verbose:
log.setLevel(logging.DEBUG)
else:
log.setLevel(logging.NOTSET)
if opts.path and opts.start_date:
fname = "%s/all-%s" % (opts.path, opts.start_date)
else:
fname = opts.syslog_file
try:
syslog_file = open(fname)
except:
log.error( "Error opening syslog file %s " % (fname))
sys.exit(-1)
if opts.begin or opts.begin_tail:
log.debug("Will start at the beginning of the file.")
else:
syslog_file.seek(0, 2)
log_parse(syslog_file, opts)
def main():
"""
Read in the command line arguments, then open the log
"""
parser = optparse.OptionParser()
begin_help = """Start at the begining of the syslog file,
and exit when get to the end"""
parser.add_option("-b", action="store_true", dest="begin",
help=begin_help, default=False)
begin_tail_help = """Start at the begining of the syslog file,
and tail the file when get to the end"""
parser.add_option("-B", action="store_true", dest="begin_tail",
help=begin_tail_help, default=False)
parser.add_option("-v", "--verbose", action="store_true", dest="verbose",
help="be more verbose", default=False)
parser.add_option("-f", "--file", action="store", dest="syslog_file",
help="Location of the syslog file.",
default="/var/log/syslog")
# these are for use on syslog.lbl.gov
parser.add_option("-d", "--dir", action="store", dest="path",
help="Directory of the archived syslog files.")
parser.add_option("-t", "--date", action="store", dest="start_date",
help="Date of file to process.", default=False)
opts, args = parser.parse_args()
heartbeat = HeartBeatThread(900)
heartbeat.setDaemon(True)
heartbeat.start()
log_open(opts)
if __name__ == "__main__": main()

View file

@ -1,16 +0,0 @@
DISTCLEANFILES = hf.c nf.c pf.c
noinst_PROGRAMS = hf nf pf
#LEX = @V_LEX@
#.l.c:
# $(LEX) $(srcdir)/$*.l ; rm -f $@ ; mv lex.yy.c $@
if USE_NBDNS
dns_srcs = nb_dns.c
endif
hf_SOURCES = hf.l setsignal.c version.c nb_dns.h setsignal.h gnuc.h $(dns_srcs)
nf_SOURCES = nf.l setsignal.c
pf_SOURCES = pf.l setsignal.c

View file

@ -1 +0,0 @@
1.0a10

View file

@ -1,43 +0,0 @@
/* @(#) $Header$ (LBL) */
/* Define __P() macro, if necessary */
#ifndef __P
#if __STDC__
#define __P(protos) protos
#else
#define __P(protos) ()
#endif
#endif
/* inline foo */
#ifdef __GNUC__
#define inline __inline
#else
#define inline
#endif
/*
* Handle new and old "dead" routine prototypes
*
* For example:
*
* __dead void foo(void) __attribute__((volatile));
*
*/
#ifdef __GNUC__
#ifndef __dead
#define __dead volatile
#endif
#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5)
#ifndef __attribute__
#define __attribute__(args)
#endif
#endif
#else
#ifndef __dead
#define __dead
#endif
#ifndef __attribute__
#define __attribute__(args)
#endif
#endif

View file

@ -1,950 +0,0 @@
N [0-9]
O ({N}{1,3})
C [0-9A-Fa-f]
H ({C}{1,4})
#include "config.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/stat.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#ifdef NEED_NAMESER_COMPAT_H
#include <arpa/nameser_compat.h>
#else
#include <arpa/nameser.h>
#endif
#ifndef NS_MAXDNAME
#define NS_MAXDNAME 1025
#endif
#ifndef NS_INADDRSZ
#define NS_INADDRSZ 4
#endif
#ifndef NS_IN6ADDRSZ
#define NS_IN6ADDRSZ 16
#endif
#include <ctype.h>
#include <errno.h>
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif
#include <netdb.h>
#include <resolv.h>
#include <setjmp.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#include "setsignal.h"
#include "nb_dns.h"
#undef yywrap
#ifdef FLEX_SCANNER
#define YY_NO_UNPUT
#endif
int yywrap(void);
int yylex(void);
void convert(const char *, int);
#ifdef HAVE_ASYNC_DNS
#define ECHO \
if (!lookup_pass) { (void) fwrite( yytext, yyleng, 1, yyout ); }
int lookup_pass; /* true if lookup only */
#endif
int linemode; /* convert at most one entry per line */
int triedone;
%%
::{O}(\.{O}){3} convert(yytext, 1);
{O}(\.{O}){3} convert(yytext, 0);
{H}(:{H}){7} convert(yytext, 1);
{H}:(:{H}){1,6} convert(yytext, 1);
({H}:){2}(:{H}){1,5} convert(yytext, 1);
({H}:){3}(:{H}){1,4} convert(yytext, 1);
({H}:){4}(:{H}){1,3} convert(yytext, 1);
({H}:){5}(:{H}){1,2} convert(yytext, 1);
({H}:){6}:{H} convert(yytext, 1);
({O}\.){1,3} ECHO; /* anti-backtrack */
{O}((\.{O}){1,2}) ECHO; /* anti-backtrack */
{N}+ ECHO;
[^0-9\n]+ ECHO;
[^0-9\n]+\n {
ECHO;
triedone = 0;
}
\n {
ECHO;
triedone = 0;
}
%%
/*
* Copyright (c) 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1998, 1999, 2000, 2001, 2002, 2004
* 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: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char copyright[] =
"@(#) Copyright (c) 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1998, 1999, 2000, 2001, 2002, 2004\n\
The Regents of the University of California. All rights reserved.\n";
static const char rcsid[] =
"@(#) $Id: hf.l 1420 2005-09-29 22:25:14Z vern $ (LBL)";
#endif
#define HSIZE 8192 /* must be a power of two */
struct htable {
char addr[NS_IN6ADDRSZ];
int af; /* address family */
int alen;
int state;
char *name; /* overloaded variable */
struct htable *next;
} htable[HSIZE];
#define STATE_FREE 0 /* not in use */
#define STATE_RAW 1 /* couldn't translate */
#define STATE_SENTPTR 2
#define STATE_HAVEPTR 3
#define STATE_SENTA 4
#define STATE_HAVEA 5
int strip = 1; /* strip local domain when possible */
int lcase = 1; /* force lowercase */
int shortdomain; /* strip entire domain */
int printboth; /* print both addr & name */
#ifdef HAVE_ASYNC_DNS
int asyncdns; /* 2 pass async dns hack */
int numasync; /* number of outstanding async requests */
int asyncfd;
#endif
int networknumber; /* convert to network numbers */
int check; /* check PTR's against A records */
#ifdef DEBUG
int debug = 0;
#endif
int tmo; /* seconds to wait for a answer from the dns */
int doingdns; /* true if we're waiting for the nameserver */
jmp_buf alrmenv; /* longjmp() buffer */
char *prog;
char domain[64]; /* current domain name (including '.') */
int domainlen; /* length of domain name */
char azero[NS_IN6ADDRSZ];
#ifdef HAVE_ASYNC_DNS
struct nb_dns_info *nd;
#endif
int targc;
char **targv;
extern char *optarg;
extern int optind, opterr;
/* ANSI C defines this */
#ifndef __STDC__
extern char *malloc();
#endif
/* Forwards */
char *a2h(const char *, int, int);
char *addr2host(const char *, int, int);
#ifdef HAVE_ASYNC_DNS
void asyncreap(int);
#endif
struct htable *cacheaddr(const char *, int, int, int, const char *);
#ifdef DEBUG
void dump(void);
#endif
int getdomain(void);
struct htable *hash(const char *, int, int);
#ifdef HAVE_ASYNC_DNS
int ispipe(FILE *);
#endif
struct htable *lookupaddr(const char *, int, int);
int main(int, char **);
void massagename(char *);
RETSIGTYPE timeout(int);
void usage(void);
int
main(argc, argv)
int argc;
char **argv;
{
register char *cp;
register int op;
#ifdef HAVE_ASYNC_DNS
char errstr[NB_DNS_ERRSIZE];
#endif
if ((cp = strrchr(argv[0], '/')) != NULL)
prog = cp + 1;
else
prog = argv[0];
opterr = 0;
while ((op = getopt(argc, argv, "1abcdilnNt:")) != EOF)
switch (op) {
case '1':
++linemode;
break;
case 'a':
#ifdef HAVE_ASYNC_DNS
++asyncdns;
#else
fprintf(stderr,
"%s: warning: -a not supported; ignored\n", prog);
#endif
break;
case 'b':
++printboth;
break;
case 'c':
++check;
break;
#ifdef DEBUG
case 'd':
++debug;
break;
#endif
case 'i':
lcase = 0;
break;
case 'l':
strip = 0;
break;
case 'n':
#ifdef notdef
++networknumber;
#else
fprintf(stderr, "%s: -n not currently impemented\n",
prog);
exit(1);
#endif
break;
case 'N':
++shortdomain;
break;
case 't':
tmo = atoi(optarg);
if (tmo <= 0)
usage();
break;
default:
usage();
}
#ifdef HAVE_ASYNC_DNS
if (asyncdns) {
nd = nb_dns_init(errstr);
if (nd == NULL) {
fprintf(stderr, "%s: nb_dns_init: %s\n", prog, errstr);
exit(1);
}
asyncfd = nb_dns_fd(nd);
/* If no explicit timeout, use resolver retransmit */
if (tmo == 0)
tmo = _res.retrans;
}
#endif
/* Figure out our domain, if necessary */
if (!strip || shortdomain || !getdomain())
domain[0] = '\0';
/* Up number of retries, we really want answers */
_res.retry = 20;
/* Don't search, we'll use only FQDNs */
_res.options &= ~RES_DNSRCH;
/* Setup alarm catcher if -t */
#ifdef HAVE_ASYNC_DNS
if (!asyncdns)
#endif
if (tmo > 0)
(void)setsignal(SIGALRM, timeout);
/* Let yywrap() figure out if there are any arguments to open */
targc = argc - optind;
targv = &argv[optind];
yyin = NULL;
(void)yywrap();
/* Process file opened by yywrap() or stdin if no arguments */
if (yyin) {
#ifdef HAVE_ASYNC_DNS
/* XXX depends on the type of stdin */
/* XXX can we do a test rewind? */
#ifdef notdef
if (asyncdns && yyin == stdin)
fprintf(stderr,
"%s: warning: can't use -a on stdin\n", prog);
#endif
#endif
yylex();
}
#ifdef DEBUG
if (debug) {
fflush(stdout);
dump();
}
#endif
exit(0);
}
int
yywrap()
{
register char *file;
static int didany = 0;
/* Close file, if necessary */
if (yyin) {
#ifdef HAVE_ASYNC_DNS
if (asyncdns) {
if (lookup_pass) {
if (fseek(yyin, 0L, SEEK_SET) < 0) {
fprintf(stderr,
"%s: fseek/rewind: %s\n",
prog, strerror(errno));
exit(1);
}
yyrestart(yyin);
lookup_pass = 0;
asyncreap(1);
return (0);
}
numasync = 0;
}
#endif
if (yyin != stdin)
(void)fclose(yyin);
yyin = NULL;
}
/* Spin through arguments until we run out or successfully open one */
while (targc > 0) {
file = targv[0];
--targc;
++targv;
++didany;
if ((yyin = fopen(file, "r")) != NULL) {
#ifdef HAVE_ASYNC_DNS
if (asyncdns)
lookup_pass = 1;
#endif
return (0);
}
perror(file);
}
if (!didany) {
yyin = stdin;
#ifdef HAVE_ASYNC_DNS
if (asyncdns) {
if (ispipe(yyin)) {
fprintf(stderr,
"%s: warning: can't use -a on a pipe\n",
prog);
asyncdns = 0;
} else
lookup_pass = 1;
}
#endif
}
return (1);
}
int
getdomain()
{
register char *cp;
register struct hostent *hp;
char host[128];
if (gethostname(host, sizeof(host) - 1) < 0)
return (0);
if ((cp = strchr(host, '.')) == NULL) {
/* Not already canonical */
if (tmo > 0)
alarm(tmo);
doingdns = 1;
if (setjmp(alrmenv))
return (0);
hp = gethostbyname(host);
doingdns = 0;
if (hp == NULL)
return (0);
if ((cp = strchr(hp->h_name, '.')) == NULL)
return (0);
}
(void)strncpy(domain, cp, sizeof(domain));
domain[sizeof(domain) - 1] = '\0';
if (lcase)
for (cp = domain; *cp; ++cp)
if (isupper((int)*cp))
*cp = tolower(*cp);
domainlen = strlen(domain);
return (1);
}
RETSIGTYPE
timeout(int signo)
{
if (doingdns) {
doingdns = 0;
longjmp(alrmenv, 1);
}
return RETSIGVAL;
}
/* Convert address to hostname via the dns */
char *
a2h(register const char *ap, register int alen, register int af)
{
register char **pp;
register size_t len;
static struct hostent *hp;
static char *host = NULL;
static size_t hostlen = 0;
/* Look up the PTR */
if (tmo > 0)
alarm(tmo);
doingdns = 1;
if (setjmp(alrmenv))
return (NULL);
hp = gethostbyaddr(ap, alen, af);
doingdns = 0;
if (hp == NULL)
return (NULL);
len = strlen(hp->h_name) + 1;
if (hostlen < len) {
if (len < 132)
len = 132;
if (host == NULL)
host = malloc(len);
else
host = realloc(host, len);
if (host == NULL) {
hostlen = 0;
return (NULL);
}
hostlen = len;
}
(void)strcpy(host, hp->h_name);
/* Done if we aren't checking */
if (!check)
return (host);
#ifndef HAVE_GETHOSTBYNAME2
if (af != AF_INET)
return (NULL);
#endif
/* Check PTR against the A record */
if (tmo > 0)
alarm(tmo);
doingdns = 1;
if (setjmp(alrmenv))
return (NULL);
#ifdef HAVE_GETHOSTBYNAME2
hp = gethostbyname2(host, af);
#else
hp = gethostbyname(host);
#endif
doingdns = 0;
if (hp == NULL)
return (NULL);
if (af != hp->h_addrtype)
return (NULL);
/* Spin through ip addresses looking for a match */
for (pp = hp->h_addr_list; *pp != NULL; ++pp)
if (memcmp(ap, *pp, alen) == 0)
return (host);
return (NULL);
}
/* Convert address to hostname via the cache and/or dns */
char *
addr2host(register const char *ap, register int alen, register int af)
{
register int state;
register char *host;
register struct htable *p;
/* First look in hash table */
p = lookupaddr(ap, alen, af);
if (p != NULL)
return (p->name);
/* Lookup this host */
host = a2h(ap, alen, af);
state = STATE_RAW;
if (host != NULL) {
if (check)
state = STATE_HAVEA;
else
state = STATE_HAVEPTR;
massagename(host);
}
p = cacheaddr(ap, state, alen, af, host);
if (p != NULL)
return (p->name);
return (host);
}
/* Look hash table entry for address */
struct htable *
lookupaddr(register const char *ap, register int alen, register int af)
{
register struct htable *p;
for (p = hash(ap, alen, af); p != NULL; p = p->next)
if (p->af == af && memcmp(p->addr, ap, alen) == 0)
return (p);
return (NULL);
}
void
massagename(register char *name)
{
register char *cp;
if (shortdomain) {
/* Throw away entire domain */
cp = strchr(name, '.');
if (cp)
*cp = '\0';
} else if (strip && *domain != '\0') {
/* Strip the local domain */
cp = name + strlen(name) - domainlen;
if (cp > name && strcasecmp(cp, domain) == 0)
*cp = '\0';
}
if (lcase)
for (cp = name; *cp; ++cp)
if (isupper((int)*cp))
*cp = tolower(*cp);
}
struct htable *
cacheaddr(register const char *ap, register int state, register int alen,
register int af, register const char *host)
{
register struct htable *p, *p2;
/* Don't cache zero */
if (memcmp(ap, azero, alen) == 0)
return (NULL);
/* Look for existing slot in hash table */
for (p = hash(ap, alen, af); p != NULL; p = p->next)
if (p->state != STATE_FREE &&
p->af == af &&
memcmp(p->addr, ap, alen) == 0)
break;
/* Allocate a new slot */
if (p == NULL) {
p = hash(ap, alen, af);
if (p->state != STATE_FREE) {
/* Handle the collision */
p2 = (struct htable *)malloc(sizeof(struct htable));
/* Lose, lose */
if (p2 == NULL)
return (NULL);
memset((char *)p2, 0, sizeof(struct htable));
p2->next = p->next;
p->next = p2;
p = p2;
}
}
/* Install new host */
memmove(p->addr, ap, alen);
p->alen = alen;
p->af = af;
if (host != NULL)
p->name = strdup(host);
if (state != 0)
p->state = state;
if (p->state == STATE_FREE)
abort();
/* Return answer entry */
return (p);
}
#ifdef DEBUG
void
dump()
{
register char *cp;
register int i, j, n, d;
register struct htable *p, *p2;
char buf[132];
d = n = 0;
for (p = htable, i = 0; i < HSIZE; ++p, ++i)
if (p->name) {
++n;
j = 0;
for (p2 = p; p2; p2 = p2->next) {
if ((cp = p2->name) == NULL)
cp = "<nil>";
else if (cp == (char *)1)
cp = "<raw>";
(void)fprintf(stderr, "%4d:%d ", i, j);
if (inet_ntop(p2->af, p2->addr,
buf, sizeof(buf)) == NULL)
(void)fprintf(stderr, "?");
else
(void)fprintf(stderr, "%s", buf);
switch (p2->state) {
case STATE_HAVEA:
(void)fprintf(stderr, " HAVEA");
break;
case STATE_HAVEPTR:
(void)fprintf(stderr, " HAVEPTR");
break;
case STATE_SENTPTR:
(void)fprintf(stderr, " SENTPTR");
break;
case STATE_RAW:
(void)fprintf(stderr, " RAW");
break;
default:
(void)fprintf(stderr, " #%d",
p2->state);
break;
}
(void)fprintf(stderr, " \"%s\"\n", cp);
++d;
++j;
}
}
d -= n;
(void)fprintf(stderr, "%d entries (%d dynamically linked)\n", n, d);
}
#endif
#ifdef HAVE_ASYNC_DNS
void
asyncreap(register int ateof)
{
register char *host;
register int n;
register char **pp;
register struct htable *p;
register struct nb_dns_result *nr;
register struct hostent *hp;
fd_set fds;
struct timeval to;
char errstr[NB_DNS_ERRSIZE];
struct nb_dns_result xxxnr;
nr = &xxxnr;
memset(nr, 0, sizeof(*nr));
while (numasync > 0) {
FD_ZERO(&fds);
FD_SET(asyncfd, &fds);
/* If we're not at EOF, just poll */
if (!ateof) {
to.tv_sec = 0;
to.tv_usec = 0;
} else {
to.tv_sec = tmo;
to.tv_usec = 0;
}
n = select(asyncfd + 1, &fds, NULL, NULL, &to);
if (n < 0) {
fprintf(stderr, "%s: select: %s\n",
prog, strerror(errno));
exit(1);
}
/* Done if timed out */
if (n == 0)
break;
n = nb_dns_activity(nd, nr, errstr);
if (n < 0) {
fprintf(stderr, "%s: nb_dns_activity: %s\n",
prog, errstr);
exit(1);
}
/* Bail if reply doesn't match any current queries */
if (n == 0)
continue;
/* Decrement outstanding request counter */
--numasync;
/* Bail if not a good answer */
if (nr->host_errno != NETDB_SUCCESS)
continue;
/* Bail if no hostname (probably shouldn't happen) */
hp = nr->hostent;
host = hp->h_name;
if (host == NULL)
continue;
/* Recover hash table pointer */
p = (struct htable *)nr->cookie;
switch (p->state) {
case STATE_SENTPTR:
/* Are we done? */
if (!check) {
p->state = STATE_HAVEPTR;
break;
}
/* Now look up the A record */
if (nb_dns_host_request2(nd, host, p->af,
(void *)p, errstr) < 0) {
fprintf(stderr, "%s: nb_dns_host_request: %s\n",
prog, errstr);
p->state = STATE_RAW;
free(p->name);
p->name = NULL;
break;
}
/* Cache the fact that we're looking */
++numasync;
p->state = STATE_SENTA;
break;
case STATE_SENTA:
/* Check A against our address */
if (p->af != hp->h_addrtype) {
p->state = STATE_RAW;
free(p->name);
p->name = NULL;
break;
}
/* Spin through ip addresses looking for a match */
for (pp = hp->h_addr_list; *pp != NULL; ++pp)
if (memcmp(p->addr, *pp, p->alen) == 0)
break;
if (pp == NULL) {
p->state = STATE_RAW;
free(p->name);
p->name = NULL;
break;
}
p->state = STATE_HAVEA;
break;
default:
abort();
}
massagename(host);
if (p->name != NULL)
abort();
if (host != NULL)
p->name = strdup(host);
}
}
#endif
void
convert(register const char *str, register int isv6)
{
register char *host;
register int alen;
register int af;
#ifdef HAVE_ASYNC_DNS
register struct htable *p;
char errstr[NB_DNS_ERRSIZE];
static int num = 0;
#endif
char addr[NS_IN6ADDRSZ];
if (isv6) {
#ifdef AF_INET6
af = AF_INET6;
alen = NS_IN6ADDRSZ;
#else
#ifdef HAVE_ASYNC_DNS
if (!asyncdns || !lookup_pass)
#endif
fputs(str, stdout);
return;
#endif
} else {
af = AF_INET;
alen = NS_INADDRSZ;
}
#ifdef HAVE_ASYNC_DNS
if (asyncdns && lookup_pass) {
if (inet_pton(af, str, addr) != 1)
return;
/* Done if already in hash table */
if (lookupaddr(addr, alen, af) != NULL)
return;
p = cacheaddr(addr, STATE_SENTPTR, alen, af, NULL);
if (p == NULL)
return;
if (nb_dns_addr_request2(nd, addr, af,
(void *)p, errstr) >= 0) {
/* Cache the fact that we're looking */
++numasync;
++num;
} else
fprintf(stderr, "%s: nb_dns_host_request: %s\n",
prog, errstr);
/* reap replies after we send a number of queries */
if (num > 10) {
asyncreap(0);
num = 0;
}
return;
}
#endif
if (linemode && triedone) {
fputs(str, stdout);
return;
}
++triedone;
if (inet_pton(af, str, addr) == 1) {
host = addr2host(addr, alen, af);
if (host != NULL) {
fputs(host, stdout);
if (printboth) {
putchar('(');
fputs(str, stdout);
putchar(')');
}
return;
}
}
fputs(str, stdout);
}
struct htable *
hash(register const char *ap, register int alen, register int af)
{
u_int32_t h;
switch (alen) {
case NS_INADDRSZ:
memmove(&h, ap, sizeof(h));
break;
case NS_IN6ADDRSZ:
memmove(&h, ap + NS_IN6ADDRSZ - sizeof(h), sizeof(h));
break;
default:
abort();
}
return (&htable[h & (HSIZE - 1)]);
}
#ifdef HAVE_ASYNC_DNS
int
ispipe(FILE *f)
{
struct stat sbuf;
if (fstat(fileno(f), &sbuf) < 0) {
fprintf(stderr, "%s: fstat: %s\n", prog, strerror(errno));
exit(1);
}
if ((sbuf.st_mode & S_IFMT) != S_IFREG)
return (1);
return (0);
}
#endif
void
usage()
{
extern char version[];
(void)fprintf(stderr, "Version %s\n", version);
(void)fprintf(stderr, "usage: %s [-1abcdilN] [-t secs] [file ...]\n",
prog);
exit(1);
}

View file

@ -1,612 +0,0 @@
/*
* See the file "COPYING" in the main distribution directory for copyright.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Id: nb_dns.c 7074 2010-09-13 01:52:50Z vern $ (LBL)";
#endif
/*
* nb_dns - non-blocking dns routines
*
* This version works with BIND 9
*
* Note: The code here is way more complicated than it should be but
* although the interface to send requests is public, the routine to
* crack reply buffers is private.
*/
#include "config.h" /* must appear before first ifdef */
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#ifdef NEED_NAMESER_COMPAT_H
#include <arpa/nameser_compat.h>
#endif
#include <errno.h>
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif
#include <netdb.h>
#include <resolv.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#ifdef notdef
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#endif
#include "nb_dns.h"
#if PACKETSZ > 1024
#define MAXPACKET PACKETSZ
#else
#define MAXPACKET 1024
#endif
#ifdef DO_SOCK_DECL
extern int socket(int, int, int);
extern int connect(int, const struct sockaddr *, int);
extern int send(int, const void *, int, int);
extern int recvfrom(int, void *, int, int, struct sockaddr *, int *);
#endif
/* Private data */
struct nb_dns_entry {
struct nb_dns_entry *next;
char name[NS_MAXDNAME + 1];
int qtype; /* query type */
int atype; /* address family */
int asize; /* address size */
u_short id;
void *cookie;
};
#ifndef MAXALIASES
#define MAXALIASES 35
#endif
#ifndef MAXADDRS
#define MAXADDRS 35
#endif
struct nb_dns_hostent {
struct hostent hostent;
int numaliases;
int numaddrs;
char *host_aliases[MAXALIASES + 1];
char *h_addr_ptrs[MAXADDRS + 1];
char hostbuf[8 * 1024];
};
struct nb_dns_info {
int s; /* Resolver file descriptor */
struct sockaddr_in server; /* server address to bind to */
struct nb_dns_entry *list; /* outstanding requests */
struct nb_dns_hostent dns_hostent;
};
/* Forwards */
static int _nb_dns_mkquery(struct nb_dns_info *, const char *, int, int,
void *, char *);
static int _nb_dns_cmpsockaddr(struct sockaddr *, struct sockaddr *, char *);
static char *
my_strerror(int errnum)
{
#if HAVE_STRERROR
extern char *strerror(int);
return strerror(errnum);
#else
static char errnum_buf[32];
snprintf(errnum_buf, sizeof(errnum_buf), "errno %d", errnum);
return errnum_buf;
#endif
}
struct nb_dns_info *
nb_dns_init(char *errstr)
{
register struct nb_dns_info *nd;
nd = (struct nb_dns_info *)malloc(sizeof(*nd));
if (nd == NULL) {
snprintf(errstr, NB_DNS_ERRSIZE, "nb_dns_init: malloc(): %s",
my_strerror(errno));
return (NULL);
}
memset(nd, 0, sizeof(*nd));
nd->s = -1;
/* XXX should be able to init static hostent struct some other way */
(void)gethostbyname("localhost.");
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
snprintf(errstr, NB_DNS_ERRSIZE, "res_init() failed");
free(nd);
return (NULL);
}
nd->s = socket(PF_INET, SOCK_DGRAM, 0);
if (nd->s < 0) {
snprintf(errstr, NB_DNS_ERRSIZE, "socket(): %s",
my_strerror(errno));
free(nd);
return (NULL);
}
/* XXX should use resolver config */
nd->server = _res.nsaddr_list[0];
if (connect(nd->s, (struct sockaddr *)&nd->server,
sizeof(struct sockaddr)) < 0) {
snprintf(errstr, NB_DNS_ERRSIZE, "connect(%s): %s",
inet_ntoa(nd->server.sin_addr), my_strerror(errno));
close(nd->s);
free(nd);
return (NULL);
}
return (nd);
}
void
nb_dns_finish(struct nb_dns_info *nd)
{
register struct nb_dns_entry *ne, *ne2;
ne = nd->list;
while (ne != NULL) {
ne2 = ne;
ne = ne->next;
free(ne2);
}
close(nd->s);
free(nd);
}
int
nb_dns_fd(struct nb_dns_info *nd)
{
return (nd->s);
}
static int
_nb_dns_cmpsockaddr(register struct sockaddr *sa1,
register struct sockaddr *sa2, register char *errstr)
{
register struct sockaddr_in *sin1, *sin2;
#ifdef AF_INET6
register struct sockaddr_in6 *sin6a, *sin6b;
#endif
static const char serr[] = "answer from wrong nameserver (%d)";
if (sa1->sa_family != sa1->sa_family) {
snprintf(errstr, NB_DNS_ERRSIZE, serr, 1);
return (-1);
}
switch (sa1->sa_family) {
case AF_INET:
sin1 = (struct sockaddr_in *)sa1;
sin2 = (struct sockaddr_in *)sa2;
if (sin1->sin_port != sin2->sin_port) {
snprintf(errstr, NB_DNS_ERRSIZE, serr, 2);
return (-1);
}
if (sin1->sin_addr.s_addr != sin2->sin_addr.s_addr) {
snprintf(errstr, NB_DNS_ERRSIZE, serr, 3);
return (-1);
}
break;
#ifdef AF_INET6
case AF_INET6:
sin6a = (struct sockaddr_in6 *)sa1;
sin6b = (struct sockaddr_in6 *)sa2;
if (sin6a->sin6_port != sin6b->sin6_port) {
snprintf(errstr, NB_DNS_ERRSIZE, serr, 2);
return (-1);
}
if (memcmp(&sin6a->sin6_addr, &sin6b->sin6_addr,
sizeof(sin6a->sin6_addr)) != 0) {
snprintf(errstr, NB_DNS_ERRSIZE, serr, 3);
return (-1);
}
break;
#endif
default:
snprintf(errstr, NB_DNS_ERRSIZE, serr, 4);
return (-1);
}
return (0);
}
static int
_nb_dns_mkquery(register struct nb_dns_info *nd, register const char *name,
register int atype, register int qtype, register void * cookie,
register char *errstr)
{
register struct nb_dns_entry *ne;
register HEADER *hp;
register int n;
u_long msg[MAXPACKET / sizeof(u_long)];
/* Allocate an entry */
ne = (struct nb_dns_entry *)malloc(sizeof(*ne));
if (ne == NULL) {
snprintf(errstr, NB_DNS_ERRSIZE, "malloc(): %s",
my_strerror(errno));
return (-1);
}
memset(ne, 0, sizeof(*ne));
strncpy(ne->name, name, sizeof(ne->name));
ne->name[sizeof(ne->name) - 1] = '\0';
ne->qtype = qtype;
ne->atype = atype;
switch (atype) {
case AF_INET:
ne->asize = NS_INADDRSZ;
break;
#ifdef AF_INET6
case AF_INET6:
ne->asize = NS_IN6ADDRSZ;
break;
#endif
default:
snprintf(errstr, NB_DNS_ERRSIZE,
"_nb_dns_mkquery: bad family %d", atype);
return (-1);
}
/* Build the request */
n = res_mkquery(
ns_o_query, /* op code (query) */
name, /* domain name */
ns_c_in, /* query class (internet) */
qtype, /* query type */
NULL, /* data */
0, /* length of data */
NULL, /* new rr */
(u_char *)msg, /* buffer */
sizeof(msg)); /* size of buffer */
if (n < 0) {
snprintf(errstr, NB_DNS_ERRSIZE, "res_mkquery() failed");
free(ne);
return (-1);
}
hp = (HEADER *)msg;
ne->id = htons(hp->id);
if (send(nd->s, (char *)msg, n, 0) != n) {
snprintf(errstr, NB_DNS_ERRSIZE, "send(): %s",
my_strerror(errno));
free(ne);
return (-1);
}
ne->next = nd->list;
ne->cookie = cookie;
nd->list = ne;
return(0);
}
int
nb_dns_host_request(register struct nb_dns_info *nd, register const char *name,
register void *cookie, register char *errstr)
{
return (nb_dns_host_request2(nd, name, AF_INET, cookie, errstr));
}
int
nb_dns_host_request2(register struct nb_dns_info *nd, register const char *name,
register int af, register void *cookie, register char *errstr)
{
register int qtype;
switch (af) {
case AF_INET:
qtype = T_A;
break;
#ifdef AF_INET6
case AF_INET6:
qtype = T_AAAA;
break;
#endif
default:
snprintf(errstr, NB_DNS_ERRSIZE,
"nb_dns_host_request2(): uknown address family %d", af);
return (-1);
}
return (_nb_dns_mkquery(nd, name, af, qtype, cookie, errstr));
}
int
nb_dns_addr_request(register struct nb_dns_info *nd, nb_uint32_t addr,
register void *cookie, register char *errstr)
{
return (nb_dns_addr_request2(nd, (char *)&addr, AF_INET,
cookie, errstr));
}
int
nb_dns_addr_request2(register struct nb_dns_info *nd, char *addrp,
register int af, register void *cookie, register char *errstr)
{
#ifdef AF_INET6
register char *cp;
register int n, i;
register size_t size;
#endif
register u_char *uaddr;
char name[NS_MAXDNAME + 1];
switch (af) {
case AF_INET:
uaddr = (u_char *)addrp;
snprintf(name, sizeof(name), "%u.%u.%u.%u.in-addr.arpa",
(uaddr[3] & 0xff),
(uaddr[2] & 0xff),
(uaddr[1] & 0xff),
(uaddr[0] & 0xff));
break;
#ifdef AF_INET6
case AF_INET6:
uaddr = (u_char *)addrp;
cp = name;
size = sizeof(name);
for (n = NS_IN6ADDRSZ - 1; n >= 0; --n) {
snprintf(cp, size, "%x.%x.",
(uaddr[n] & 0xf),
(uaddr[n] >> 4) & 0xf);
i = strlen(cp);
size -= i;
cp += i;
}
snprintf(cp, size, "ip6.int");
break;
#endif
default:
snprintf(errstr, NB_DNS_ERRSIZE,
"nb_dns_addr_request2(): uknown address family %d", af);
return (-1);
}
return (_nb_dns_mkquery(nd, name, af, T_PTR, cookie, errstr));
}
int
nb_dns_abort_request(struct nb_dns_info *nd, void *cookie)
{
register struct nb_dns_entry *ne, *lastne;
/* Try to find this request on the outstanding request list */
lastne = NULL;
for (ne = nd->list; ne != NULL; ne = ne->next) {
if (ne->cookie == cookie)
break;
lastne = ne;
}
/* Not a currently pending request */
if (ne == NULL)
return (-1);
/* Unlink this entry */
if (lastne == NULL)
nd->list = ne->next;
else
lastne->next = ne->next;
ne->next = NULL;
return (0);
}
/* Returns 1 with an answer, 0 when reply was old, -1 on fatal errors */
int
nb_dns_activity(struct nb_dns_info *nd, struct nb_dns_result *nr, char *errstr)
{
register int msglen, qtype, atype, n, i;
register struct nb_dns_entry *ne, *lastne;
socklen_t fromlen;
struct sockaddr from;
u_long msg[MAXPACKET / sizeof(u_long)];
register char *bp, *ep;
register char **ap, **hap;
register u_int16_t id;
register const u_char *rdata;
register struct hostent *he;
register size_t rdlen;
ns_msg handle;
ns_rr rr;
/* This comes from the second half of do_query() */
fromlen = sizeof(from);
msglen = recvfrom(nd->s, (char *)msg, sizeof(msg), 0, &from, &fromlen);
if (msglen <= 0) {
snprintf(errstr, NB_DNS_ERRSIZE, "recvfrom(): %s",
my_strerror(errno));
return (-1);
}
if (msglen < HFIXEDSZ) {
snprintf(errstr, NB_DNS_ERRSIZE, "recvfrom(): undersized: %d",
msglen);
return (-1);
}
if (ns_initparse((u_char *)msg, msglen, &handle) < 0) {
snprintf(errstr, NB_DNS_ERRSIZE, "ns_initparse(): %s",
my_strerror(errno));
nr->host_errno = NO_RECOVERY;
return (-1);
}
/* RES_INSECURE1 style check */
if (_nb_dns_cmpsockaddr((struct sockaddr *)&nd->server, &from,
errstr) < 0) {
nr->host_errno = NO_RECOVERY;
return (-1);
}
/* Search for this request */
lastne = NULL;
id = ns_msg_id(handle);
for (ne = nd->list; ne != NULL; ne = ne->next) {
if (ne->id == id)
break;
lastne = ne;
}
/* Not an answer to a question we care about anymore */
if (ne == NULL)
return (0);
/* Unlink this entry */
if (lastne == NULL)
nd->list = ne->next;
else
lastne->next = ne->next;
ne->next = NULL;
/* RES_INSECURE2 style check */
/* XXX not implemented */
/* Initialize result struct */
memset(nr, 0, sizeof(*nr));
nr->cookie = ne->cookie;
qtype = ne->qtype;
/* Deal with various errors */
switch (ns_msg_getflag(handle, ns_f_rcode)) {
case ns_r_nxdomain:
nr->host_errno = HOST_NOT_FOUND;
free(ne);
return (1);
case ns_r_servfail:
nr->host_errno = TRY_AGAIN;
free(ne);
return (1);
case ns_r_noerror:
break;
case ns_r_formerr:
case ns_r_notimpl:
case ns_r_refused:
default:
nr->host_errno = NO_RECOVERY;
free(ne);
return (1);
}
/* Loop through records in packet */
memset(&rr, 0, sizeof(rr));
memset(&nd->dns_hostent, 0, sizeof(nd->dns_hostent));
he = &nd->dns_hostent.hostent;
/* XXX no support for aliases */
he->h_aliases = nd->dns_hostent.host_aliases;
he->h_addr_list = nd->dns_hostent.h_addr_ptrs;
he->h_addrtype = ne->atype;
he->h_length = ne->asize;
free(ne);
bp = nd->dns_hostent.hostbuf;
ep = bp + sizeof(nd->dns_hostent.hostbuf);
hap = he->h_addr_list;
ap = he->h_aliases;
for (i = 0; i < ns_msg_count(handle, ns_s_an); i++) {
/* Parse next record */
if (ns_parserr(&handle, ns_s_an, i, &rr) < 0) {
if (errno != ENODEV) {
nr->host_errno = NO_RECOVERY;
return (1);
}
/* All done */
break;
}
/* Ignore records that don't answer our query (e.g. CNAMEs) */
atype = ns_rr_type(rr);
if (atype != qtype)
continue;
rdata = ns_rr_rdata(rr);
rdlen = ns_rr_rdlen(rr);
switch (atype) {
case T_A:
case T_AAAA:
if (rdlen != (unsigned int) he->h_length) {
snprintf(errstr, NB_DNS_ERRSIZE,
"nb_dns_activity(): bad rdlen %d",
(int) rdlen);
nr->host_errno = NO_RECOVERY;
return (-1);
}
if (bp + rdlen >= ep) {
snprintf(errstr, NB_DNS_ERRSIZE,
"nb_dns_activity(): overflow 1");
nr->host_errno = NO_RECOVERY;
return (-1);
}
if (nd->dns_hostent.numaddrs + 1 >= MAXADDRS) {
snprintf(errstr, NB_DNS_ERRSIZE,
"nb_dns_activity(): overflow 2");
nr->host_errno = NO_RECOVERY;
return (-1);
}
memcpy(bp, rdata, rdlen);
*hap++ = bp;
bp += rdlen;
++nd->dns_hostent.numaddrs;
/* Keep looking for more A records */
break;
case T_PTR:
n = dn_expand((const u_char *)msg,
(const u_char *)msg + msglen, rdata, bp, ep - bp);
if (n < 0) {
/* XXX return -1 here ??? */
nr->host_errno = NO_RECOVERY;
return (1);
}
he->h_name = bp;
/* XXX check for overflow */
bp += n; /* returned len includes EOS */
/* "Find first satisfactory answer" */
nr->hostent = he;
return (1);
}
}
nr->hostent = he;
return (1);
}

View file

@ -1,52 +0,0 @@
/* @(#) $Id: nb_dns.h 909 2004-12-09 04:27:10Z jason $ (LBL)
*
* Copyright (c) 2000, 2002
* 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: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
/* Private data */
struct nb_dns_info;
/* Public data */
struct nb_dns_result {
void *cookie;
int host_errno;
struct hostent *hostent;
};
typedef unsigned int nb_uint32_t;
/* Public routines */
struct nb_dns_info *nb_dns_init(char *);
void nb_dns_finish(struct nb_dns_info *);
int nb_dns_fd(struct nb_dns_info *);
int nb_dns_host_request(struct nb_dns_info *, const char *, void *, char *);
int nb_dns_host_request2(struct nb_dns_info *, const char *, int,
void *, char *);
int nb_dns_addr_request(struct nb_dns_info *, nb_uint32_t, void *, char *);
int nb_dns_addr_request2(struct nb_dns_info *, char *, int, void *, char *);
int nb_dns_abort_request(struct nb_dns_info *, void *);
int nb_dns_activity(struct nb_dns_info *, struct nb_dns_result *, char *);
#define NB_DNS_ERRSIZE 256

View file

@ -1,312 +0,0 @@
N [0-9]
O ({N}{1,3})
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <arpa/nameser.h>
#include <ctype.h>
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif
#include <netdb.h>
#include <resolv.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#undef yywrap
#ifdef FLEX_SCANNER
#define YY_NO_UNPUT
#endif
int yywrap(void);
int yylex(void);
char *addr2host(char *);
void convert(char *);
int pad;
%%
{O}\.{O}\.{O}\.{O} convert(yytext);
{O}\.{O}\.{O} if (pad) {
char buf[256];
strcpy(buf, yytext);
strcat(buf, ".0");
convert(buf);
} else {
ECHO;
}
{O}\.{O} if (pad) {
char buf[256];
strcpy(buf, yytext);
strcat(buf, ".0.0");
convert(buf);
} else {
ECHO;
}
{O} if (pad) {
char buf[256];
strcpy(buf, yytext);
strcat(buf, ".0.0.0");
convert(buf);
} else {
ECHO;
}
{N}+ ECHO;
[^0-9\n]+ ECHO;
[^0-9\n]+\n ECHO;
%%
/*
* Copyright (c) 1990, 1991, 1996, 1999, 2000, 2004
* 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: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char copyright[] =
"@(#) Copyright (c) 1990, 1991, 1996, 1999, 2000, 2004\n\
The Regents of the University of California. All rights reserved.\n";
static const char rcsid[] =
"@(#) $Id: nf.l 909 2004-12-09 04:27:10Z jason $ (LBL)";
#endif
#define HSIZE 2048 /* must be a power of two */
struct htable {
u_int addr;
char *name;
struct htable *next;
} htable[HSIZE];
int lcase = 1; /* force lowercase */
int printboth = 0;
#ifdef DEBUG
int debug = 0;
#endif
int targc;
char **targv;
extern char *optarg;
extern int optind, opterr;
/* Forwards */
int main(int, char **);
#ifdef DEBUG
void dump(void);
#endif
int
main(argc, argv)
int argc;
char **argv;
{
register char *cp;
register int op;
char *argv0;
if ((cp = strrchr(argv[0], '/')) != NULL)
argv0 = cp + 1;
else
argv0 = argv[0];
opterr = 0;
while ((op = getopt(argc, argv, "dibp")) != EOF)
switch (op) {
#ifdef DEBUG
case 'd':
++debug;
break;
#endif
case 'i':
lcase = 0;
break;
case 'p':
pad = 1;
break;
case 'b':
printboth = 1;
break;
default:
(void)fprintf(stderr, "usage: %s [-dibp] [file ...]\n",
argv0);
exit(1);
/* NOTREACHED */
}
setnetent(1);
/* Let yywrap() figure out if there are any arguments to open */
targc = argc - optind;
targv = &argv[optind];
yyin = 0;
(void)yywrap();
/* Process file opened by yywrap() or stdin if no arguments */
if (yyin)
yylex();
#ifdef DEBUG
if (debug) {
fflush(stdout);
dump();
}
#endif
exit(0);
}
int
yywrap()
{
register char *file;
static int didany = 0;
/* Close file, if necessary */
if (yyin && yyin != stdin) {
(void)fclose(yyin);
yyin = 0;
}
/* Spin through arguments until we run out or successfully open one */
while (targc > 0) {
file = targv[0];
--targc;
++targv;
++didany;
if ((yyin = fopen(file, "r")) != NULL)
return(0);
else
perror(file);
}
if (!didany)
yyin = stdin;
return(1);
}
void
convert(str)
char *str;
{
fputs(addr2host(str), stdout);
if (printboth) {
putchar('(');
fputs(str, stdout);
putchar(')');
}
}
char *
addr2host(str)
char *str;
{
register u_long addr, net;
register char *cp, *host;
register struct netent *hp;
register struct htable *p, *p2;
struct in_addr ia;
addr = inet_addr(str);
/* First check if we already know about it */
for (p = &htable[addr & (HSIZE - 1)]; p; p = p->next)
if (p->addr == addr && p->name)
return(p->name);
/* Try to lookup this net */
ia.s_addr = addr;
net = inet_netof(ia);
if ((hp = getnetbyaddr(net, AF_INET)) != NULL)
host = hp->n_name;
else
host = inet_ntoa(ia);
if (lcase)
for (cp = host; *cp; ++cp)
if (isupper(*cp))
*cp = tolower(*cp);
/* Malloc space for new hostname */
cp = malloc((u_int) strlen(host) + 1);
if (cp == 0)
return(host);
/* Find slot in hash table */
p = &htable[addr & (HSIZE - 1)];
if (p->name) {
/* Handle the collision */
p2 = (struct htable *)malloc(sizeof(struct htable));
if (p2 == 0) {
/* Lose, lose */
free(cp);
return(host);
}
memset((char *)p2, 0, sizeof(struct htable));
p2->next = p->next;
p->next = p2;
p = p2;
}
/* Install new host */
p->addr = addr;
p->name = strcpy(cp, host);
/* Return answer */
return(p->name);
}
#ifdef DEBUG
void
dump()
{
register int i, j, n, d;
register struct htable *p, *p2;
d = n = 0;
for (p = htable, i = 0; i < HSIZE; ++p, ++i)
if (p->name) {
++n;
j = 0;
for (p2 = p; p2; p2 = p2->next) {
(void)fprintf(stderr,
"%4d:%d 0x%08x \"%s\"\n", i, j,
p2->addr, p2->name ? p2->name : "<nil>");
++d;
++j;
}
}
d -= n;
(void)fprintf(stderr, "%d entries (%d dynamically linked)\n", n, d);
}
#endif

View file

@ -1,196 +0,0 @@
N [0-9]
#include <sys/types.h>
#include <netdb.h>
#include <string.h>
#include <unistd.h>
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#undef yywrap
#ifdef FLEX_SCANNER
#define YY_NO_UNPUT
#endif
int yywrap(void);
int yylex(void);
void convert(char *);
%%
"["{N}+"]" convert(yytext);
[^0-9[\]\n]+\n? ECHO;
.|\n ECHO;
%%
/*
* Copyright (c) 1990, 1991, 1996, 1999, 2000, 2004
* 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: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char copyright[] =
"@(#) Copyright (c) 1990, 1991, 1996, 1999, 2000, 2004\n\
The Regents of the University of California. All rights reserved.\n";
static const char rcsid[] =
"@(#) $Id: pf.l 909 2004-12-09 04:27:10Z jason $ (LBL)";
#endif
#ifdef DEBUG
int debug = 0;
#endif
#define MAX_PORT_NUM 65535
char *port_to_name[MAX_PORT_NUM+1];
int targc;
char **targv;
extern char *optarg;
extern int optind, opterr;
/* Forwards */
int main(int, char **);
char *dup_string(char *);
void portinit(void);
int
main(argc, argv)
int argc;
char **argv;
{
register char *cp;
register int op;
char *argv0;
if ((cp = strrchr(argv[0], '/')) != NULL)
argv0 = cp + 1;
else
argv0 = argv[0];
opterr = 0;
while ((op = getopt(argc, argv, "d")) != EOF)
switch (op) {
#ifdef DEBUG
case 'd':
++debug;
break;
#endif
default:
(void)fprintf(stderr, "usage: %s [-d] [file ...]\n",
argv0);
exit(1);
/* NOTREACHED */
}
/* Let yywrap() figure out if there are any arguments to open */
targc = argc - optind;
targv = &argv[optind];
yyin = 0;
(void)yywrap();
portinit();
/* Process file opened by yywrap() or stdin if no arguments */
if (yyin)
yylex();
#ifdef DEBUG
if (debug) {
register int i;
for (i=0; i <= MAX_PORT_NUM; ++i)
if (port_to_name[i])
fprintf(stderr, "[%d]\t%s\n", i,
port_to_name[i]);
}
#endif /* DEBUG */
exit(0);
}
int
yywrap()
{
register char *file;
static int didany = 0;
/* Close file, if necessary */
if (yyin && yyin != stdin) {
(void)fclose(yyin);
yyin = 0;
}
/* Spin through arguments until we run out or successfully open one */
while (targc > 0) {
file = targv[0];
--targc;
++targv;
++didany;
if ((yyin = fopen(file, "r")) != NULL)
return(0);
else
perror(file);
}
if (!didany)
yyin = stdin;
return(1);
}
char *
dup_string(src)
char *src;
{
char *dst;
dst = malloc(strlen(src)+1);
if (dst)
strcpy(dst, src);
return dst;
}
void
convert(str)
char *str;
{
register int port;
port = atoi(str+1);
if (port >= 0 && port <= MAX_PORT_NUM && port_to_name[port] != 0)
str = port_to_name[port];
fputs(str, stdout);
}
void
portinit()
{
struct servent *sp;
while ((sp = getservent()) != 0) {
if (port_to_name[sp->s_port] == 0 ||
sp->s_proto[0] == 't')
port_to_name[sp->s_port] = dup_string(sp->s_name);
}
endservent();
}

View file

@ -1,82 +0,0 @@
/*
* Copyright (c) 1997
* 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: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char rcsid[] =
"@(#) $Header$ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <sys/types.h>
#ifdef HAVE_MEMORY_H
#include <memory.h>
#endif
#include <signal.h>
#ifdef HAVE_SIGACTION
#include <string.h>
#endif
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
#include "setsignal.h"
/*
* An os independent signal() with BSD semantics, e.g. the signal
* catcher is restored following service of the signal.
*
* When sigset() is available, signal() has SYSV semantics and sigset()
* has BSD semantics and call interface. Unfortunately, Linux does not
* have sigset() so we use the more complicated sigaction() interface
* there.
*
* Did I mention that signals suck?
*/
RETSIGTYPE
(*setsignal (int sig, RETSIGTYPE (*func)(int)))(int)
{
#ifdef HAVE_SIGACTION
struct sigaction old, new;
memset(&new, 0, sizeof(new));
new.sa_handler = func;
#ifdef SA_RESTART
new.sa_flags |= SA_RESTART;
#endif
if (sigaction(sig, &new, &old) < 0)
return (SIG_ERR);
return (old.sa_handler);
#else
#ifdef HAVE_SIGSET
return (sigset(sig, func));
#else
return (signal(sig, func));
#endif
#endif
}

View file

@ -1,27 +0,0 @@
/*
* Copyright (c) 1997
* 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: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* @(#) $Header$ (LBL)
*/
#ifndef setsignal_h
#define setsignal_h
RETSIGTYPE (*setsignal(int, RETSIGTYPE (*)(int)))(int);
#endif

View file

@ -1,75 +0,0 @@
/*
* Copyright (c) 1988, 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.
*/
#if defined(LIBC_SCCS) && !defined(lint)
static const char sccsid[] = "@(#)strerror.c 8.1 (Berkeley) 6/4/93";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
#include <string.h>
#include "gnuc.h"
#ifdef HAVE_OS_PROTO_H
#include "os-proto.h"
#endif
char *
strerror(num)
int num;
{
extern int sys_nerr;
extern char *sys_errlist[];
#define UPREFIX "Unknown error: "
static char ebuf[40] = UPREFIX; /* 64-bit number + slop */
register unsigned int errnum;
register char *p, *t;
char tmp[40];
errnum = num; /* convert to unsigned */
if (errnum < sys_nerr)
return(sys_errlist[errnum]);
/* Do this by hand, so we don't include stdio(3). */
t = tmp;
do {
*t++ = "0123456789"[errnum % 10];
} while (errnum /= 10);
for (p = ebuf + sizeof(UPREFIX) - 1;;) {
*p++ = *--t;
if (t <= tmp)
break;
}
*p = '\0';
return(ebuf);
}

View file

@ -1 +0,0 @@
char version[] = "1.0a10";

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -1,5 +0,0 @@
noinst_PROGRAMS = ftwire2bro nfcollector
ftwire2bro_SOURCES = ftwire2bro.c nfcommon.h
nfcollector_SOURCES = nfcollector.c nfcommon.h

View file

@ -1,94 +0,0 @@
/* $Id:$ */
/* Written by Bernhard Ager (2007). */
/* Works only with NFv5. */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "nfcommon.h"
void leave (int errlvl, const char *msg) {
fprintf (stderr, "%s", msg);
exit (errlvl);
}
void usage () {
puts ("Converts NetFlow v5 files in 'wire' format to bro format.\n"
"A flow-tools file can be converted to 'wire' format with\n"
" flow-export -f 4\n"
"Note this is a hack: The network time is calculated from the\n"
"export time and an optional offset; the exporter is set statically.\n"
"Usage: ftwire2bro [-e <exporter_ip> [-t <offset>]\n"
" <exporter_ip> defaults to 0.0.0.0, <offset> defaults to 0.0\n"
" data is read from stdin and written to stdout");
}
size_t pdusize(NFv5Header hdr) {
return sizeof(hdr)+ntohs(hdr.count)*V5_RECORD_SIZE;
}
int main (int argc, char** argv) {
int opt;
struct in_addr exporter = {0};
double offset = 0.0;
FlowFileSrcPDUHeader ffphdr;
NFv5PDU v5pdu;
unsigned short count;
while ((opt = getopt (argc, argv, "e:t:h")) >= 0) {
switch (opt) {
case 'e':
if (! inet_aton (optarg, &exporter)) {
fprintf (stderr, "could not convert exporter_ip: '%s'\n", optarg);
exit (1);
}
break;
case 't':
offset = atof(optarg);
break;
case 'h':
usage();
exit (0);
default:
/* fprintf (stderr, "Unknown option: %c\n", optopt); */
exit(1);
}
}
while (1) {
if (fread (&(v5pdu.header), sizeof (NFv5Header), 1, stdin) == 0) {
if (feof(stdin))
break;
leave (1, "Could not read header\n");
}
count = ntohs (v5pdu.header.count);
if (ntohs(v5pdu.header.version) != 5)
leave (1, "Header indicates flow not in version 5 format\n");
if (count > V5_RECORD_MAXCOUNT) {
fprintf (stderr, "header indicates too many records: %d\n",
count);
exit (1);
}
if (fread (v5pdu.records, sizeof(NFv5Record), count, stdin) < count)
leave (1, "Could not read enough records from stdin\n");
ffphdr.network_time = ntohl(v5pdu.header.unix_secs) +
ntohl(v5pdu.header.unix_nsecs)/1e9 + offset;
ffphdr.pdu_length = pdusize(v5pdu.header);
ffphdr.ipaddr = exporter.s_addr;
if (fwrite (&ffphdr, sizeof(ffphdr), 1, stdout) == 0)
leave (1, "Could not write ffpheader\n");
if (fwrite (&v5pdu, ffphdr.pdu_length, 1, stdout) == 0)
leave (1, "Could not write netflow PDU\n");
}
return 0;
}

View file

@ -1,83 +0,0 @@
/* $Id;$ */
/* Written by Bernhard Ager (2007). */
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/time.h>
#include <netinet/in.h>
#include "nfcommon.h"
void pleave (int errlvl, const char *msg) {
perror (msg);
exit (errlvl);
}
void usage () {
puts ("collects NetFlow data and writes it to a file (or stdout)\n"
" such that Bro can read the NetFlow dump file.\n"
" Usage: nfcollector [-p <port>] [-o <outputfile>]\n"
" port defaults to 1234, outputfile defaults to stdout");
}
int main (int argc, char** argv) {
int opt;
int s = -1;
char *outfile = NULL;
int outfd = 1; // default to stdout
struct timeval tv;
struct sockaddr_in sa = { .sin_family = AF_INET,
.sin_port = htons(1234),
.sin_addr = {0} };
struct sockaddr_in from;
socklen_t fromlen;
FlowFilePDU ffp;
while ((opt = getopt (argc, argv, "p:o:h")) >= 0) {
switch (opt) {
case 'o':
outfile = malloc (strlen(optarg) + 1);
strcpy (outfile, optarg);
break;
case 'p':
sa.sin_port = htons(atoi(optarg));
break;
case 'h':
usage();
exit (0);
default:
fprintf (stderr, "Unknown option: %c\n", optopt);
}
}
if ((s = socket (PF_INET, SOCK_DGRAM, 0)) < 0)
pleave(1, "opening socket");
if (bind (s, (struct sockaddr*) &sa, sizeof (sa)) < 0)
pleave (1, "bind");
if (outfile && (outfd = open (outfile, O_TRUNC|O_WRONLY|O_CREAT, 0666)) < 0)
pleave (1, "open");
while (1) {
fromlen = sizeof (from);
if ((ffp.header.pdu_length = recvfrom(s, ffp.data, MAX_PKT_SIZE, 0, (struct sockaddr*)&from, &fromlen)) < 0)
pleave (1, "recvfrom");
if (gettimeofday(&tv, NULL) == 0)
ffp.header.network_time = tv.tv_sec + tv.tv_usec / 1000000.;
else {
ffp.header.network_time = -1.;
perror ("gettimeofday");
}
ffp.header.ipaddr = from.sin_addr.s_addr;
write (outfd, &ffp, ffp.header.pdu_length + sizeof (FlowFileSrcPDUHeader));
}
return 0;
}

View file

@ -1,45 +0,0 @@
/* $Id:$ */
/* Written by Bernhard Ager (2007). */
/* For now this only works with IPv4. */
#include "../../config.h"
/* Enough for NFv5 - how about the others? */
#define MAX_PKT_SIZE 8192
/* from FlowSrc.h */
typedef struct {
double network_time;
int pdu_length;
u_int32_t ipaddr;
} FlowFileSrcPDUHeader;
typedef struct {
u_int16_t version;
u_int16_t count;
u_int32_t sysuptime;
u_int32_t unix_secs;
u_int32_t unix_nsecs;
u_int32_t flow_seq;
u_int8_t eng_type;
u_int8_t eng_id;
u_int16_t sample_int;
} NFv5Header;
#define V5_RECORD_SIZE 48
#define V5_RECORD_MAXCOUNT 30
typedef struct {
char data[V5_RECORD_SIZE];
} NFv5Record;
typedef struct {
NFv5Header header;
NFv5Record records[V5_RECORD_MAXCOUNT];
} NFv5PDU;
/* TODO: replace char data[] by NFv5PDU pdu*/
typedef struct {
FlowFileSrcPDUHeader header;
char data [MAX_PKT_SIZE];
} FlowFilePDU;

View file

@ -1,4 +0,0 @@
## Process this file with automake to produce Makefile.in
noinst_PROGRAMS = rst
rst_SOURCES = rst.c

View file

@ -1,380 +0,0 @@
/* $Id: rst.c 7073 2010-09-13 00:45:02Z vern $ */
/* Derived from traceroute, which has the following copyright:
*
* Copyright (c) 1999, 2002
* 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: (1) source code distributions
* retain the above copyright notice and this paragraph in its entirety, (2)
* distributions including binary code include the above copyright notice and
* this paragraph in its entirety in the documentation or other materials
* provided with the distribution, and (3) all advertising materials mentioning
* features or use of this software display the following acknowledgement:
* ``This product includes software developed by the University of California,
* Lawrence Berkeley Laboratory and its contributors.'' 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/
#ifndef lint
static const char copyright[] =
"@(#) Copyright (c) 1999, 2002\nThe Regents of the University of California. All rights reserved.\n";
static const char rcsid[] =
"@(#) $Id: rst.c 7073 2010-09-13 00:45:02Z vern $ (LBL)";
#endif
/* need this due to linux's funny idea of a tcphdr */
#if defined(__linux__)
#define _BSD_SOURCE
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "../../config.h"
/* Forwards */
void gripe(const char *, const char *);
void pgripe(const char *);
u_short in_cksum(register u_short *, register int);
int ones_complement_checksum(const void *, int, u_int32_t);
int tcp_checksum(const struct ip *, const struct tcphdr *, int);
void send_pkt(int, struct in_addr, int, u_int32_t, struct in_addr,
int, u_int32_t, int, int, int, int, const char *);
void terminate(int, const char *, int, u_int32_t, const char *,
int, u_int32_t, int, int, int, int, const char *);
void usage(void);
int main(int, char **);
const char *prog_name;
void gripe(const char *fmt, const char *arg)
{
fprintf(stderr, "%s: ", prog_name);
fprintf(stderr, fmt, arg);
fprintf(stderr, "\n");
}
void pgripe(const char *msg)
{
fprintf(stderr, "%s: %s (%s)\n", prog_name, msg, strerror(errno));
exit(1);
}
/*
* Checksum routine for Internet Protocol family headers (C Version)
*/
u_short
in_cksum(register u_short *addr, register int len)
{
register int nleft = len;
register u_short *w = addr;
register u_short answer;
register int sum = 0;
/*
* Our algorithm is simple, using a 32 bit accumulator (sum),
* we add sequential 16 bit words to it, and at the end, fold
* back all the carry bits from the top 16 bits into the lower
* 16 bits.
*/
while (nleft > 1) {
sum += *w++;
nleft -= 2;
}
/* mop up an odd byte, if necessary */
if (nleft == 1)
sum += *(u_char *)w;
/*
* add back carry outs from top 16 bits to low 16 bits
*/
sum = (sum >> 16) + (sum & 0xffff); /* add hi 16 to low 16 */
sum += (sum >> 16); /* add carry */
answer = ~sum; /* truncate to 16 bits */
return (answer);
}
// - adapted from tcpdump
// Returns the ones-complement checksum of a chunk of b short-aligned bytes.
int ones_complement_checksum(const void *p, int b, u_int32_t sum)
{
const u_short *sp = (u_short *) p; // better be aligned!
b /= 2; // convert to count of short's
/* No need for endian conversions. */
while ( --b >= 0 )
sum += *sp++;
while ( sum > 0xffff )
sum = (sum & 0xffff) + (sum >> 16);
return sum;
}
int tcp_checksum(const struct ip *ip, const struct tcphdr *tp, int len)
{
int tcp_len = tp->th_off * 4 + len;
u_int32_t sum, addl_pseudo;
if ( len % 2 == 1 )
// Add in pad byte.
sum = htons(((const u_char*) tp)[tcp_len - 1] << 8);
else
sum = 0;
sum = ones_complement_checksum((void*) &ip->ip_src.s_addr, 4, sum);
sum = ones_complement_checksum((void*) &ip->ip_dst.s_addr, 4, sum);
addl_pseudo = (htons(IPPROTO_TCP) << 16) | htons((unsigned short) tcp_len);
sum = ones_complement_checksum((void*) &addl_pseudo, 4, sum);
sum = ones_complement_checksum((void*) tp, tcp_len, sum);
return sum;
}
void send_pkt(int s, struct in_addr from, int from_port, u_int32_t from_seq,
struct in_addr to, int to_port, u_int32_t to_seq,
int size, int redundancy, int delay, int flags,
const char *inject)
{
int cc;
int pktlen = 40 + size;
const int max_injection_size = 4096;
char *pkt = malloc(pktlen + max_injection_size + 1024 /* slop */);
struct ip *ip = (struct ip *) pkt;
struct tcphdr *tcp = (struct tcphdr *) &pkt[20];
if ( ! pkt )
pgripe("couldn't malloc memory");
if ( inject && *inject ) {
size = strlen(inject);
if ( size > max_injection_size )
gripe("injection text too large%s", "");
pktlen = 40 + size;
}
memset(pkt, 0, pktlen);
ip->ip_v = IPVERSION;
ip->ip_len = pktlen; /* on FreeBSD, don't use htons(); YMMV */
ip->ip_off = 0;
ip->ip_src = from;
ip->ip_dst = to;
ip->ip_hl = 5;
ip->ip_p = IPPROTO_TCP;
ip->ip_ttl = 255;
ip->ip_id = 0;
ip->ip_sum = in_cksum((u_short *) ip, sizeof(*ip));
if (ip->ip_sum == 0)
ip->ip_sum = 0xffff;
tcp->th_sport = htons(from_port);
tcp->th_dport = htons(to_port);
tcp->th_seq = htonl(from_seq);
tcp->th_ack = htonl(to_seq);
tcp->th_off = 5;
tcp->th_flags = flags;
tcp->th_win = 0;
tcp->th_urp = 0;
tcp->th_sum = 0;
if ( inject && *inject ) {
char *payload = &pkt[40];
strcpy(payload, inject);
} else if ( size > 0 )
{
const char *fill_string =
(inject && *inject) ? inject : "BRO-RST\n";
char *payload = &pkt[40];
int n = strlen(fill_string);
int i;
for ( i = size; i > n + 1; i -= n )
{
strcpy(payload, fill_string);
payload += n;
}
for ( ; i > 0; --i )
*(payload++) = '\n';
}
tcp->th_sum = ~tcp_checksum(ip, tcp, size);
while ( redundancy-- > 0 )
{
cc = send(s, (char *) ip, pktlen, 0);
if (cc < 0 || cc != pktlen)
pgripe("problem in sendto()");
usleep(delay * 1000);
}
free(pkt);
}
void terminate(int s, const char *from_addr, int from_port, u_int32_t from_seq,
const char *to_addr, int to_port, u_int32_t to_seq,
int num, int redundancy, int stride, int delay,
const char *inject)
{
struct sockaddr where_from, where_to;
struct sockaddr_in *from = (struct sockaddr_in *) &where_from;
struct sockaddr_in *to = (struct sockaddr_in *) &where_to;
memset(from, 0, sizeof(*from));
memset(to, 0, sizeof(*to));
#ifdef SIN_LEN
from->sin_len = to->sin_len = sizeof(*to);
#endif /* SIN_LEN */
from->sin_family = to->sin_family = AF_INET;
if ( inet_aton(from_addr, (struct in_addr *) &from->sin_addr) == 0 )
gripe("bad from address %s", from_addr);
if ( inet_aton(to_addr, (struct in_addr *) &to->sin_addr) == 0 )
gripe("bad to address %s", to_addr);
if ( connect(s, &where_to, sizeof(where_to)) < 0 )
pgripe("can't connect");
while ( num-- > 0 )
{
send_pkt(s, from->sin_addr, from_port, from_seq,
to->sin_addr, to_port, to_seq, 0, redundancy, delay,
(*inject ? 0 : TH_RST) | TH_ACK, inject);
if ( num > 0 && stride > 1 )
send_pkt(s, from->sin_addr, from_port, from_seq,
to->sin_addr, to_port, to_seq, stride,
redundancy, delay, TH_ACK, inject);
from_seq += stride;
}
}
void usage()
{
fprintf(stderr, "%s [-R] [-I text-to-inject] [-d delay-msec] [-n num] [-r redundancy] [-s stride] from_addr from_port from_seq to_addr to_port to_seq\n", prog_name);
exit(0);
}
int main(int argc, char **argv)
{
extern char* optarg;
extern int optind, opterr;
const char *from_addr, *to_addr;
char inject[8192];
int from_port, to_port;
u_int32_t from_seq, to_seq;
int delay = 0.0;
int redundancy = 1;
int num = 1;
int stride = 1;
int reverse = 0;
int s;
int on = 1;
int op;
prog_name = argv[0];
opterr = 0;
inject[0] = 0;
while ( (op = getopt(argc, argv, "RI:d:n:r:s:")) != EOF )
switch ( op ) {
case 'R':
reverse = 1;
break;
case 'I':
{
char *ap = optarg;
char *ip;
for ( ip = inject; *ap; ++ip, ++ap ) {
if ( ap[0] == '\\' && ap[1] == 'n' )
*ip = '\n', ++ap;
else
*ip = *ap;
}
}
break;
case 'd':
delay = atoi(optarg);
break;
case 'n':
num = atoi(optarg);
break;
case 'r':
redundancy = atoi(optarg);
break;
case 's':
stride = atoi(optarg);
break;
default:
usage();
break;
}
if ( argc - optind != 6 )
usage();
s = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);
if ( s < 0 )
pgripe("couldn't create raw socket");
setuid(getuid());
if (setsockopt(s, 0, IP_HDRINCL, (char *) &on, sizeof(on)) < 0)
pgripe("can't turn on IP_HDRINCL");
from_addr = argv[optind++];
from_port = atoi(argv[optind++]);
from_seq = strtoul(argv[optind++], 0, 10);
to_addr = argv[optind++];
to_port = atoi(argv[optind++]);
to_seq = strtoul(argv[optind++], 0, 10);
if ( reverse )
terminate(s, to_addr, to_port, to_seq,
from_addr, from_port, from_seq,
num, redundancy, stride, delay, inject);
else
terminate(s, from_addr, from_port, from_seq,
to_addr, to_port, to_seq,
num, redundancy, stride, delay, inject);
return 0;
}

View file

@ -1,3 +0,0 @@
## Process this file with automake to produce Makefile.in
EXTRA_DIST = hot-report mon-report ip-grep ca-create ca-issue bro-logchk.pl host-to-addrs mvlog host-grep lock_file

View file

@ -1,197 +0,0 @@
#!/usr/bin/perl
# Written by:
# James J. Barlow <jbarlow@ncsa.uiuc.edu>
# June 2002
#
# Orders and scans through bro http and ftp logs.
use Getopt::Std;
use Socket;
# Get the options on the command line
getopts('DFHdshra:f:x:');
# Check for invalid options or help option
if ($opt_h || ($opt_a && $opt_x) || (($opt_s || $opt_d) && !$opt_a) ||
($opt_F && $opt_H) || !($opt_F || $opt_H)) {
&Usage;
}
# Read file
if ($opt_f) {
open(INFILE, "$opt_f") || die "Can't open $opt_f: $!\n";
} else {
&Usage;
}
$max = 0;
while (<INFILE>) {
# is it the start of a connection
if (check_start_conn()) {
# Set to resolve IP address if $opt_r.
$resolve = 1;
# Do we want a specific IP address
if ($opt_a) {
if ((($source EQ $opt_a) && !$opt_d) || (($dest EQ $opt_a) && !$opt_s)) {
# Yes, push connection number on list
push @ipconlist, $conn;
} else {
$resolve = 0; # don't try to resolve IP address
}
}
# Do we want to exclude an IP address
if ($opt_x) {
# Check if ipaddr is not excluded address
if (($source NE $opt_x) && ($dest NE $opt_x)) {
# if not push connection number on list
push @ipconlist, $conn;
} else {
$resolve = 0; # don't try to resolve IP address
}
}
# set max connection number
$max = $conn if ($max < $conn);
# Do we want to try and resolve IP addresses
if ($opt_r && $resolve) {
# get source and dest hostnames from IP addresses
$sname = gethostbyaddr(inet_aton($source), AF_INET);
# set source name to IP address if not resolvable
if (!$sname) {
$sname = $source;
}
$dname = gethostbyaddr(inet_aton($dest), AF_INET);
# set destination name to IP address if not resolvable
if (!$dname) {
$dname = $dest;
}
} else {
$sname = $source;
$dname = $dest;
}
# Get timestamp
$time = localtime($secs);
# push connection
push @{$connlist[$conn]}, "$time - $conn ${sname}${source_port} > $dname";
print "$time - $conn ${sname}${source_port} > $dname\n" if $opt_D;
next;
}
# is it a request
if (check_request()) {
# set max connection number
$max = $conn if ($max < $conn);
push @{$connlist[$conn]}, "${time}${conn} $request";
print "${time}${conn} $request\n" if $opt_D;
next;
}
print "Unrecognized line: $_";
}
for ($i=1;$i<=$max;$i++) {
# skip connections not on list if we want specific addrs
# or are excluding addresses
if ($opt_a || $opt_x) {
next if !(grep /^$i$/, @ipconlist);
}
# print connections
foreach $entry (@{$connlist[$i]}) {
print "$entry\n";
}
}
close(INFILE);
sub check_start_conn {
$valid_conn = 0;
# http connection?
if ($opt_H) {
if ((m/^(\d+)\s+%(\d+)\s+start\s+(\S+)\s+>\s+(\S+)/) ||
(m/^(\d+)\.\d+\s+%(\d+)\s+start\s+(\S+)\s+>\s+(\S+)/)) {
$secs = $1;
$conn = $2;
$source = $3;
$dest = $4;
chomp($dest);
$source_port = "";
$valid_conn = 1;
}
# ftp connection?
} elsif ($opt_F) {
if ((m/^(\d+)\s+#(\d+)\s+(\S+)\/(\d+)\s+>\s+(\S+)\/ftp start/) ||
(m/^(\d+)\.\d+\s+#(\d+)\s+(\S+)\/(\d+)\s+>\s+(\S+)\/ftp start/)) {
$secs = $1;
$conn = $2;
$source = $3;
$source_port = "/$4";
$dest = $5;
$valid_conn = 1;
}
}
return $valid_conn;
}
sub check_request {
$valid_request = 0;
if ($opt_H) {
if (m/^%(\d+)\s+\S+\s+(.*)/) {
$conn = $1;
$request = "GET $2";
chomp($request);
$time = "";
$valid_conn = 1;
}
} elsif ($opt_F) {
if (m/^(\d+)\.\d+ #(\d+) (.*)/) {
$time = localtime($1)." - ";
$conn = $2;
$request = $3;
chomp($request);
$valid_conn = 1;
}
}
return $valid_conn;
}
#
# Usage
#
# Prints out usage for script.
sub Usage {
print "Usage:\n";
print " bro-logchk.pl -[hrDFHds] -f filename -a ipaddr -x ipaddr\n";
print " -h print this usage information\n";
print " -F using ftp log\n";
print " -H using http log\n";
print " -r try to resolve IP addresses to hostnames\n";
print " -f file log file to parse\n";
print " -a ipaddr only output connections from this address\n";
print " -s only want matching source address (used with -a option)\n";
print " -d only want matching destination address (used with -a option)\n";
print " -D debug option\n";
print " -x ipaddr exclude connections from this address\n";
print "\n";
exit;
}

View file

@ -1,148 +0,0 @@
#! /bin/sh
######################################################################
# prompt for input for a variable
# $1 name of var
# $2 defualt value
# $3 prompt string (if empty get from config file )
bro_config_input()
{
if [ -z $1 ] ; then
name=""
else
name=$1
fi
if [ -z $2 ] ; then
default=""
else
default=$2
fi
if [ -z "$3" ] ; then
prompt=""
else
prompt=$3
fi
#empty it out
RESP=
desc=$prompt
while [ -z "$RESP" ]; do
echo -n "$desc [$default]: " >&0
read RESP
case "$RESP" in
[Yy]|[Yy][Ee][Ss]) ret="YES"; RESP="YES";;
[Nn]|[Nn][Oo] ) ret="NO"; RESP="NO" ;;
"") ret=$default ; RESP="$default" ;;
*) ret=$RESP;;
esac
done
# set back the value
eval $1=\$ret
eval $name=\$ret
return 1
}
echo "Creating SSL certificate authority"
echo "----------------------------------"
echo
dir=$HOME
if [ "x$BRO_CA_DIR" != "x" ]; then
dir=$BRO_CA_DIR
fi
bro_config_input "dir" $dir "Directory for CA setup"
mkdir -p $dir
if [ $? -ne 0 ]; then
echo "Couldn't create directory $dir."
exit 1
fi
mkdir -p $dir/certs $dir/private
chmod g-rwx,o-rwx $dir/private
echo '01' > $dir/serial
touch $dir/issued.txt
echo "- Directory structure created in directory $dir"
cat - > $dir/openssl.cfg << _EOF
# OpenSSL config file for Root CA
#
# Global variable so it can be used everywhere:
dir = $dir
[ ca ]
default_ca = bro_ca
[ bro_ca ]
certificate = \$dir/ca_cert.pem
database = \$dir/issued.txt
new_certs_dir = \$dir/certs
private_key = \$dir/private/ca_key.pem
serial = \$dir/serial
# Number of days before CRLs are published
default_crl_days = 7
# Number of days a certificate will be valud
default_days = 365
# Digest used to sign issued certificates
default_md = sha1
# Policy for distinguished name in certificate requests
policy = bro_policy
x509_extensions = cert_exts
[ bro_policy ]
commonName = supplied
emailAddress = optional
[ cert_exts ]
# Certificates we hand out must not be used as CA certificates
basicConstraints = CA:false
[ req ]
default_bits = 2048 # Private key length
default_keyfile = \$dir/private/ca_key.pem
default_md = sha1
# Don't ask for distinguished name, use what's given below:
prompt = no
distinguished_name = root_ca_dist_name
x509_extensions = root_ca_exts
[ root_ca_dist_name ]
commonName = Bro Root Certification Authority
[ root_ca_exts ]
basicConstraints = CA:true
_EOF
echo "- OpenSSL config file created at $dir/openssl.cfg"
echo
echo "I will now generate the CA's certificate. You will be asked to"
echo "enter the password for the CA's private key."
echo
openssl req -config $dir/openssl.cfg -x509 -new -out $dir/ca_cert.pem -outform PEM
if [ $? -ne 0 ]; then
echo "Couldn't create root certificate."
exit 1
fi
echo "- Root certificate created successfully"
echo "- Done."

View file

@ -1,112 +0,0 @@
#! /bin/sh
######################################################################
# prompt for input for a variable
# $1 name of var
# $2 defualt value
# $3 prompt string (if empty get from config file )
bro_config_input()
{
if [ -z $1 ] ; then
name=""
else
name=$1
fi
if [ -z $2 ] ; then
default=""
else
default=$2
fi
if [ -z "$3" ] ; then
prompt=""
else
prompt=$3
fi
#empty it out
RESP=
desc=$prompt
while [ -z "$RESP" ]; do
echo -n "$desc [$default]: " >&0
read RESP
case "$RESP" in
[Yy]|[Yy][Ee][Ss]) ret="YES"; RESP="YES";;
[Nn]|[Nn][Oo] ) ret="NO"; RESP="NO" ;;
"") ret=$default ; RESP="$default" ;;
*) ret=$RESP;;
esac
done
# set back the value
eval $1=\$ret
eval $name=\$ret
return 1
}
echo "Issuing SSL certificate"
echo "-----------------------"
echo
dir=$HOME
if [ "x$BRO_CA_DIR" != "x" ]; then
dir=$BRO_CA_DIR
fi
bro_config_input "dir" $dir "CA installation directory"
if [ ! -r $dir/openssl.cfg ]; then
echo "Could not find config file for root CA in $BRO_CA_DIR/openssl.cfg"
exit 1
fi
prefix=bro
bro_config_input "prefix" $prefix "Prefix for the generated certificate request and private key"
if [ "x$OPENSSL_CONF" = "x$BRO_CA_DIR/openssl.cfg" ]; then
OPENSSL_CONF=
echo "*Not* using $BRO_CA_DIR/openssl.cfg as configuration file"
fi
echo
echo "I will now generate a certificate request. You will be asked"
echo "for a passphrase with which the private key will be encrypted."
echo "You will also be asked for a challenge phrase stored in the"
echo "certificate request, which is ignored by OpenSSL."
echo
openssl req -newkey rsa:1024 -days 730 -nodes -keyout ${prefix}_key.pem -keyform PEM -out ${prefix}_req.pem
if [ $? -ne 0 ]; then
echo "Couldn't create certificate request."
exit 1
fi
echo "- Certificate request created in ${prefix}_req.pem, with private key in ${prefix}_key.pem"
echo
echo "Issuing certificate using ${prefix}_req.pem"
openssl ca -config $BRO_CA_DIR/openssl.cfg -days 730 -in ${prefix}_req.pem -notext -out ${prefix}_cert.pem
if [ $? -ne 0 ]; then
echo "Couldn't create certificate. Make sure the parameters"
echo "of the certificate request are unique."
exit 1
fi
echo
echo "- Certificate created in ${prefix}_cert.pem"
cat ${prefix}_key.pem ${prefix}_cert.pem > ${prefix}.pem
rm ${prefix}_key.pem ${prefix}_cert.pem ${prefix}_req.pem
echo "- Created host certificate and key configuration in $prefix.pem"
echo
echo "Now configure your Bro agent to use"
echo " * CA certificate $dir/ca_cert.pem"
echo " * Host certificate $prefix.pem"
echo
echo "- Done."

View file

@ -1,29 +0,0 @@
#! /bin/csh -f
#
# Greps a Bro connection summary file on stdin for the given hosts. Usage:
#
# host-grep [-a] host ...
#
# If -a is specified then we only want lines with *all* of the listed hosts.
if ( "$1" == "-a" ) then
shift
if ( "$2" != "" ) then
# More than one host, recurse.
set h1 = $1
shift
host-grep $h1 | host-grep -a $*
exit
else
# Just one host, fall through.
endif
endif
# Thank you csh, for your totally busted sense of command composition
# and error propagation.
set sheesh=`ip-grep $*`
if ( $status != 0 ) then
exit 1
endif
grep -E " $sheesh "

View file

@ -1,47 +0,0 @@
#! /bin/sh -e
#
# Returns a list of IP addresses associated with hostname $1.
sheesh=`dig +noauthor +noaddit $1 a |
awk '
BEGIN {
name = "'$1'"
if ( name ~ /^[0-9][0-9]*\.[0-9][0-9]*/ )
# An address, not a name.
print name
name = name "."
}
/^;; ANSWER/ {
getline
# First reduce CNAMEs.
while ( $4 == "CNAME" )
{
name = $5
getline
}
# Now pick off the addresses.
while ( $1 == name )
{
print $5
getline
}
++num_answers
}
END {
if ( num_answers == 0 )
{
print "no DNS answers to query for", name >"/dev/stderr"
exit 1;
}
}
'`
echo "$sheesh" | sort -u

View file

@ -1,160 +0,0 @@
#! /bin/sh
#
# Generate readable output from a Bro connection summary file. If the
# -n flag is given, then the input is not run through hf to convert addresses
# to hostnames, otherwise it is. If -x is given, then exact sizes and times
# are reported, otherwise approximate.
#
# Requires the hf and cf utilities. See doc/conn-logs for a summary of
# the mnemonics used to indicate different connection states.
if [ "$1" = "-n" ]
then
shift
HF="cat" export HF
exec $0 "$@"
fi
if [ "$1" = "-x" ]
then
shift
EXACT=1 export EXACT
exec $0 "$@"
fi
usage="usage: hot-report [-n -x] [file ...]"
if [ ! "$HF" ]
then
HF="hf -cl -t 15"
fi
if [ ! "$EXACT" ]
then
EXACT=0
fi
$HF $* | cf |
mawk '
BEGIN {
interactive["telnet"] = interactive["login"] = interative["klogin"] = 1
version_probe["smtp"] = 1
no_flag["www"] = no_flag["gopher"] = no_flag["smtp"] = 1
no_flag["www?"] = no_flag["www??"] = no_flag["gopher?"] = 1
no_flag["http"] = no_flag["http?"] = no_flag["http??"] = 1
no_flag["https"] = 1
no_rej["finger"] = no_rej["time"] = no_rej["daytime"] = 1
no_rej["nntp"] = no_rej["auth"] = 1
}
{
state = $10
if ( state == "REJ" )
marker = "["
else if ( state ~ /S0/ )
marker = "}"
else if ( state ~ /RSTR/ )
marker = state ~ /H/ ? "<[" : ">["
else if ( state ~ /RSTO/ )
marker = ">]"
else if ( state ~ /SHR/ )
marker = "<h"
else
marker = ">"
osize = size($6, state)
rsize = size($7, state)
dur = duration($4, state)
proto = $5
time = $1 " " ($2 "") " " $3
if ( $11 ~ /L/ )
{
ohost = $8
rhost = $9
}
else
{
ohost = $9
rhost = $8
}
status = ""
if ( NF > 11 )
{ # Collect additional status
for ( i = 12; i <= NF; ++i )
status = status " " $i
}
flag_it = flag(proto, $4+0, $6+0, $7+0, state)
printf("%-15s %s%s%s %s %s/%s%s%s%s\n", time, flag_it ? "*" : " ",
ohost, osize, marker, rhost, proto, rsize, dur, status)
}
# Returns true if a connection should be flagged (represents successful
# and sensitive activity), false otherwise
function flag(proto, dur, osize, rsize, state)
{
if ( proto in interactive )
return osize > 200 || rsize > 1000 || dur > 300
if ( proto in version_probe && (osize == 0 || osize == 6) )
return 1
if ( proto in no_rej && (state == "REJ" || state == "S0") )
return 0
if ( proto ~ /^ftpdata-/ || proto ~ /^ftp-data/ )
return 0
return ! (proto in no_flag)
}
function size(bytes, state)
{
if ( state == "S0" )
return ""
if ( state == "REJ" )
return ""
if ( bytes == "?" )
s = "?"
else if ( '$EXACT' )
s = sprintf("%db", bytes)
else if ( bytes < 1000 )
s = sprintf("%.1fkb", bytes / 1000)
else
s = sprintf("%.0fkb", bytes / 1000)
return " " s
}
function duration(t, state)
{
if ( t == "?" )
return " " t
if ( state == "S0" || state == "S1" || state == "REJ" )
return ""
if ( '$EXACT' )
s = sprintf("%.1fs", t)
else if ( t < 60 )
s = sprintf("%.1fm", t / 60)
else
s = sprintf("%.0fm", t / 60)
return " " s
}
'

View file

@ -1,9 +0,0 @@
#! /bin/sh
#
# Returns a grep pattern for matching the IP addresses of the given hosts.
# Note that generally when using the pattern you should surround it with
# some form of anchoring, such as blanks, to avoid false hits.
sheesh=`(for i do host-to-addrs $i; done)`
if [ "$sheesh" = "" ]; then exit 1; fi;
echo "$sheesh" | xargs | sed 's/\./\\./g;s/ /|/g;s/.*/(&)/'

View file

@ -1,70 +0,0 @@
#! /bin/sh
# Inspired by http://members.toast.net/art.ross/rute/node24.html
TAG=default
CMD=
help() {
echo "USAGE: lock_file (lock|unlock) [<tag>]"
echo
echo "lock_file locks or unlocks a lock file, for synchronization"
echo "across multiple processes. The lock command will block until"
echo "the lock can be obtained, upon which it exits with code 0."
echo "The exit code will be 1 on failures, and 2 on input error."
echo "You can use different tags for different locks."
}
while test "x$1" != "x"; do
case "$1" in
"-h"|"--help"|"-help"|"-?"|"help")
help
exit 0
;;
"lock")
CMD=lock
shift 1
;;
"unlock")
CMD=unlock
shift 1
;;
*)
TAG="$1"
shift 1
;;
esac
done
TEMPFILE="/tmp/lock_${TAG}.$$"
LOCKFILE="/tmp/lock_${TAG}.lock"
if test "${CMD}" = "lock"; then
{ echo $$ > $TEMPFILE; } >/dev/null 2>&1 || {
echo "You don't have permission to access `dirname $TEMPFILE`"
exit 1
}
while true; do
ln $TEMPFILE $LOCKFILE >/dev/null 2>&1 && {
rm -f $TEMPFILE
exit 0;
}
if test -e "$LOCKFILE"; then
kill -0 `cat $LOCKFILE` >/dev/null 2>&1 || {
echo "Removing stale lock file"
rm -f $LOCKFILE
}
fi
sleep 1
done
fi
if test "${CMD}" = "unlock"; then
rm -f $LOCKFILE && exit 0
exit 1
fi
exit 2

View file

@ -1,79 +0,0 @@
#! /bin/csh -f
#
# Given Bro connection summary files, reports on the activities of
# particular host(s) or net(s).
#
# mon-report [-n] [-t] [-x] h1 [-a h2] file ...
#
# reports on all connections involving host "h1", or "h1" and "h2" if -a
# specified. -n means that h1 and h2 should be interpreted as IP addresses
# (either host or network) instead of hostnames. -t means to write to stdout
# the raw trace file instead of the hot report. -x is passed along to
# hot-report to specify exact byte counts and durations (unless -t is given).
set usage = "mon-report [-n] [-t] [-x] h1 [-a h2] file ..."
set GREP = "grep -E"
if ( "$1" == "-n" ) then
setenv REPORT_NET
shift
mon-report $*
exit
endif
if ( "$1" == "-t" ) then
setenv REPORT_TO_STDOUT
shift
mon-report $*
exit
endif
if ( "$1" == "-x" ) then
setenv EXACT
shift
mon-report $*
exit
endif
if ( "$1" == "" ) then
echo "$usage"
exit
endif
set h1=$1
shift
set h2
if ( "$1" == "-a" ) then
shift
if ( "$1" == "" ) then
echo "$usage"
exit
endif
setenv H2
set h2=$1
shift
endif
if ( $?REPORT_TO_STDOUT ) then
set out="cat"
else
if ( $?EXACT ) then
set out="hot-report -x"
else
set out="hot-report"
endif
endif
if ( $?REPORT_NET ) then
if ( $?H2 ) then
cat $* | $GREP " `echo $h1 | sed 's/\./\\./g;s/ /|/g'`[. ]" | \
$GREP " `echo $h2 | sed 's/\./\\./g;s/ /|/g'`[. ]" | \
sort -n | $out
else
cat $* | $GREP " `echo $h1 | sed 's/\./\\./g;s/ /|/g'`[. ]" | \
sort -n | $out
endif
else
cat $* | host-grep -a $h1 $h2 | sort -n | $out
endif

View file

@ -1,58 +0,0 @@
#! /usr/bin/env bash
#
# This script may be used as a postprocessor for Bro's log files to
# automatically compress and archive them.
#
# Example use:
#
# 1. Add two lines to your Bro configuration:
#
# redef log_rotate_interval = 6 hrs &redef;
# redef log_postprocessor = "mvlog";
#
# 2. Put the script into your PATH.
#
# 3. Define an environment variable BROBASE giving
# a base directory to store the archived logs in.
#
# Now Bro rotates log files every six hours, gzips them
# and moves them into directories $BROBASE/logs/<date>/
#
# General usage (this is how Bro calls all postprocessors):
#
# mvlog <rotated-file-name> <base-name> <timestamp-when-opened> <timestamp-when-closed>
#
# Example of how Bro may call the script:
#
# mvlog alert.log.28799.1069381104 alert.log 03-11-21_03.18.18 03-11-21_04.0.24
if [ "$BROBASE" == "" ]; then
echo BROBASE not set.
exit 1
fi
# Base of archive.
BASE="$BROBASE/logs"
# Build archive name
DAY=`echo $3 | sed 's/_.*$//'`
FROM=`echo $3 | sed 's/^.*_//' | sed 's/\./:/g'`
TO=`echo $4 | sed 's/^.*._//' | sed 's/\./:/g'`
CENTURY=`date +%Y | sed 's/..$//g'`
DAY="$CENTURY$DAY"
DEST="$BASE/$DAY/$2.$FROM-$TO"
# Create archive sub-dir if not existent.
if [ ! -d "$BASE" ]; then
mkdir "$BASE"
fi
if [ ! -d "$BASE/$DAY" ]; then
mkdir "$BASE/$DAY"
fi
# Zip it and move into archive.
nice gzip -6 <$1 >$DEST.gz && rm $1

View file

@ -0,0 +1,87 @@
# Calling this macro with the name of a list variable will modify that
# list such that any third party libraries that do not come with a
# vanilla Mac OS X system will be replaced by an adjusted library that
# has an install_name relative to the location of any executable that
# links to it.
#
# Also, it will schedule the modified libraries for installation in a
# 'support_libs' subdirectory of the CMAKE_INSTALL_PREFIX.
#
# The case of third party libraries depending on other third party
# libraries is currently not handled by this macro.
#
# Ex.
#
# set(libs /usr/lib/libz.dylib
# /usr/lib/libssl.dylib
# /usr/local/lib/libmagic.dylib
# /usr/local/lib/libGeoIP.dylib
# /usr/local/lib/somestaticlib.a)
#
# include(ChangeMacInstallNames)
# ChangeMacInstallNames(libs)
#
# Should result in ${libs} containing:
# /usr/lib/libz.dylib
# /usr/lib/libssl.dylib
# ${CMAKE_BINARY_DIR}/darwin_support_libs/libmagic.dylib
# ${CMAKE_BINARY_DIR}/darwin_support_libs/libGeoIP.dylib
# /usr/local/lib/somestaticlib.a
#
# such that we can now do:
#
# add_executable(some_exe ${srcs})
# target_link_libraries(some_exe ${libs})
#
# Any binary packages created from such a build should be self-contained
# and provide working installs on vanilla OS X systems.
macro(ChangeMacInstallNames libListVar)
if (APPLE)
find_program(INSTALL_NAME_TOOL install_name_tool)
set(MAC_INSTALL_NAME_DEPS)
set(SUPPORT_BIN_DIR ${CMAKE_BINARY_DIR}/darwin_support_libs)
set(SUPPORT_INSTALL_DIR support_libs)
file(MAKE_DIRECTORY ${SUPPORT_BIN_DIR})
foreach (_lib ${${libListVar}})
# only care about install_name for shared libraries that are
# not shipped in Apple's vanilla OS X installs
string(REGEX MATCH ^/usr/lib/* apple_provided_lib ${_lib})
string(REGEX MATCH dylib$ is_shared_lib ${_lib})
if (NOT apple_provided_lib AND is_shared_lib)
get_filename_component(_libname ${_lib} NAME)
set(_adjustedLib ${SUPPORT_BIN_DIR}/${_libname})
set(_tmpLib
${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/${_libname})
# make a tempory copy so we can adjust permissions
configure_file(${_lib} ${_tmpLib} COPYONLY)
# copy to build directory with correct write permissions
file(COPY ${_tmpLib}
DESTINATION ${SUPPORT_BIN_DIR}
FILE_PERMISSIONS OWNER_READ OWNER_WRITE
GROUP_READ WORLD_READ)
# remove the old library from the list provided as macro
# argument and add the new library with modified install_name
list(REMOVE_ITEM ${libListVar} ${_lib})
list(APPEND ${libListVar} ${_adjustedLib})
# update the install target to install the third party libs
# with modified install_name
install(FILES ${_adjustedLib}
DESTINATION ${SUPPORT_INSTALL_DIR})
# perform the install_name change
execute_process(COMMAND install_name_tool -id
@executable_path/../${SUPPORT_INSTALL_DIR}/${_libname}
${_adjustedLib})
endif ()
endforeach ()
endif ()
endmacro()

View file

@ -0,0 +1,15 @@
include(CheckFunctionExists)
check_function_exists(getopt_long HAVE_GETOPT_LONG)
check_function_exists(mallinfo HAVE_MALLINFO)
check_function_exists(strcasestr HAVE_STRCASESTR)
check_function_exists(strerror HAVE_STRERROR)
check_function_exists(strsep HAVE_STRSEP)
check_function_exists(sigset HAVE_SIGSET)
if (HAVE_SIGSET)
set(SIG_FUNC sigset)
else ()
set(SIG_FUNC signal)
check_function_exists(sigaction HAVE_SIGACTION)
endif ()

28
cmake/CheckHeaders.cmake Normal file
View file

@ -0,0 +1,28 @@
include(CheckIncludeFiles)
include(CheckStructHasMember)
check_include_files(getopt.h HAVE_GETOPT_H)
check_include_files(magic.h HAVE_MAGIC_H)
check_include_files(memory.h HAVE_MEMORY_H)
check_include_files("sys/socket.h;netinet/in.h;net/if.h;netinet/if_ether.h"
HAVE_NETINET_IF_ETHER_H)
check_include_files("sys/socket.h;netinet/in.h;net/if.h;netinet/ip6.h"
HAVE_NETINET_IP6_H)
check_include_files("sys/socket.h;net/if.h;net/ethernet.h" HAVE_NET_ETHERNET_H)
check_include_files(sys/ethernet.h HAVE_SYS_ETHERNET_H)
check_include_files(sys/time.h HAVE_SYS_TIME_H)
check_include_files("time.h;sys/time.h" TIME_WITH_SYS_TIME)
check_include_files(os-proto.h HAVE_OS_PROTO_H)
check_struct_has_member(HISTORY_STATE entries "stdio.h;readline/readline.h"
HAVE_READLINE_HISTORY_ENTRIES)
check_include_files("stdio.h;readline/readline.h" HAVE_READLINE_READLINE_H)
check_include_files("stdio.h;readline/history.h" HAVE_READLINE_HISTORY_H)
if (HAVE_READLINE_READLINE_H AND
HAVE_READLINE_HISTORY_H AND
HAVE_READLINE_HISTORY_ENTRIES)
set(HAVE_READLINE true)
endif ()
check_struct_has_member("struct sockaddr_in" sin_len "netinet/in.h" SIN_LEN)

View file

@ -0,0 +1,21 @@
include(CheckCSourceCompiles)
# Check whether the namser compatibility header is required
# This can be the case on the Darwin platform
check_c_source_compiles("
#include <arpa/nameser.h>
int main() { HEADER *hdr; int d = NS_IN6ADDRSZ; return 0; }"
have_nameser_header)
if (NOT have_nameser_header)
check_c_source_compiles("
#include <arpa/nameser.h>
#include <arpa/nameser_compat.h>
int main() { HEADER *hdr; int d = NS_IN6ADDRSZ; return 0; }"
NEED_NAMESER_COMPAT_H)
if (NOT NEED_NAMESER_COMPAT_H)
message(FATAL_ERROR
"Asynchronous DNS support compatibility check failed.")
endif ()
endif ()

46
cmake/CheckTypes.cmake Normal file
View file

@ -0,0 +1,46 @@
include(CheckTypeSize)
check_type_size("long int" SIZEOF_LONG_INT)
check_type_size("long long" SIZEOF_LONG_LONG)
check_type_size("void *" SIZEOF_VOID_P)
set(CMAKE_EXTRA_INCLUDE_FILES sys/types.h)
check_type_size(int32_t INT32_T)
if (INT32_T)
set(INT32_T int32_t)
else()
set(INT32_T int)
endif()
check_type_size(u_int32_t U_INT32_T)
if (U_INT32_T)
set(U_INT32_T u_int32_t)
else ()
set(INT32_T u_int)
endif ()
check_type_size(u_int16_t U_INT16_T)
if (U_INT16_T)
set(U_INT16_T u_int16_t)
else ()
set(INT16_T u_short)
endif ()
check_type_size(u_int8_t U_INT8_T)
if (U_INT8_T)
set(U_INT8_T u_int8_t)
else ()
set(INT8_T u_char)
endif ()
unset(CMAKE_EXTRA_INCLUDE_FILES)
set(CMAKE_EXTRA_INCLUDE_FILES sys/socket.h)
check_type_size(socklen_t SOCKLEN_T)
if (SOCKLEN_T)
set(SOCKLEN_T socklen_t)
else ()
set(SOCKLEN_T int)
endif ()
unset(CMAKE_EXTRA_INCLUDE_FILES)

101
cmake/FindBIND.cmake Normal file
View file

@ -0,0 +1,101 @@
# - Try to find libpcap include dirs and libraries
#
# Usage of this module as follows:
#
# find_package(BIND)
#
# Variables used by this module, they can change the default behaviour and need
# to be set before calling find_package:
#
# BIND_ROOT_DIR Set this variable to the root installation of BIND
# if the module has problems finding the proper
# installation path.
#
# Variables defined by this module:
#
# BIND_FOUND System has BIND, include and library dirs found
# BIND_INCLUDE_DIR The BIND include directories.
# BIND_LIBRARY The BIND library (if any) required for
# ns_inittab and res_mkquery symbols
find_path(BIND_ROOT_DIR
NAMES include/resolv.h
)
find_path(BIND_INCLUDE_DIR
NAMES resolv.h
HINTS ${BIND_ROOT_DIR}/include
)
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
# the static resolv library is preferred because
# on some systems, the ns_initparse symbol is not
# exported in the shared library (strangely)
# see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=291609
set(bind_libs none libresolv.a resolv bind)
else ()
set(bind_libs none resolv bind)
endif ()
include(CheckCSourceCompiles)
# Find which library has the res_mkquery and ns_initparse symbols
set(CMAKE_REQUIRED_INCLUDES ${BIND_INCLUDE_DIR})
foreach (bindlib ${bind_libs})
if (NOT ${bindlib} MATCHES "none")
find_library(BIND_LIBRARY
NAMES ${bindlib}
HINTS ${BIND_ROOT_DIR}/lib
)
endif ()
set(CMAKE_REQUIRED_LIBRARIES ${BIND_LIBRARY})
check_c_source_compiles("
#include <arpa/nameser.h>
int main() {
ns_initparse(0, 0, 0);
return 0;
}
" ns_initparse_works_${bindlib})
check_c_source_compiles("
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/nameser.h>
#include <resolv.h>
int main() {
int (*p)() = res_mkquery;
}
" res_mkquery_works_${bindlib})
unset(CMAKE_REQUIRED_LIBRARIES)
if (ns_initparse_works_${bindlib} AND res_mkquery_works_${bindlib})
break ()
else ()
set(BIND_LIBRARY BIND_LIBRARY-NOTFOUND)
endif ()
endforeach ()
unset(CMAKE_REQUIRED_INCLUDES)
include(FindPackageHandleStandardArgs)
if (ns_initparse_works_none AND res_mkquery_works_none)
# system does not require linking to a BIND library
find_package_handle_standard_args(BIND DEFAULT_MSG
BIND_INCLUDE_DIR
)
else ()
find_package_handle_standard_args(BIND DEFAULT_MSG
BIND_LIBRARY
BIND_INCLUDE_DIR
)
endif ()
mark_as_advanced(
BIND_ROOT_DIR
BIND_LIBRARY
BIND_INCLUDE_DIR
)

221
cmake/FindBISON.cmake Normal file
View file

@ -0,0 +1,221 @@
# - Find bison executable and provides macros to generate custom build rules
# The module defines the following variables:
#
# BISON_EXECUTABLE - path to the bison program
# BISON_VERSION - version of bison
# BISON_FOUND - true if the program was found
#
# If bison is found, the module defines the macros:
# BISON_TARGET(<Name> <YaccInput> <CodeOutput> [VERBOSE <file>]
# [COMPILE_FLAGS <string>] [HEADER <FILE>])
# which will create a custom rule to generate a parser. <YaccInput> is
# the path to a yacc file. <CodeOutput> is the name of the source file
# generated by bison. A header file containing the token list is also
# generated according to bison's -d option by default or if the HEADER
# option is used, the argument is passed to bison's --defines option to
# specify output file. If COMPILE_FLAGS option is specified, the next
# parameter is added in the bison command line. if VERBOSE option is
# specified, <file> is created and contains verbose descriptions of the
# grammar and parser. The macro defines a set of variables:
# BISON_${Name}_DEFINED - true is the macro ran successfully
# BISON_${Name}_INPUT - The input source file, an alias for <YaccInput>
# BISON_${Name}_OUTPUT_SOURCE - The source file generated by bison
# BISON_${Name}_OUTPUT_HEADER - The header file generated by bison
# BISON_${Name}_OUTPUTS - The sources files generated by bison
# BISON_${Name}_COMPILE_FLAGS - Options used in the bison command line
#
# ====================================================================
# Example:
#
# find_package(BISON)
# BISON_TARGET(MyParser parser.y ${CMAKE_CURRENT_BINARY_DIR}/parser.cpp)
# add_executable(Foo main.cpp ${BISON_MyParser_OUTPUTS})
# ====================================================================
#=============================================================================
# Copyright 2009 Kitware, Inc.
# Copyright 2006 Tristan Carel
# Modified 2010 by Jon Siwek, adding HEADER option
#
# Distributed under the OSI-approved BSD License (the "License"):
# CMake - Cross Platform Makefile Generator
# Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * 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.
#
# * Neither the names of Kitware, Inc., the Insight Software Consortium,
# nor the names of their contributors may be used to endorse or promote
# products derived from this software without specific prior written
# permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT
# HOLDER 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.
#
# This software is distributed WITHOUT ANY WARRANTY; without even the
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the License for more information.
#=============================================================================
FIND_PROGRAM(BISON_EXECUTABLE bison DOC "path to the bison executable")
MARK_AS_ADVANCED(BISON_EXECUTABLE)
IF(BISON_EXECUTABLE)
EXECUTE_PROCESS(COMMAND ${BISON_EXECUTABLE} --version
OUTPUT_VARIABLE BISON_version_output
ERROR_VARIABLE BISON_version_error
RESULT_VARIABLE BISON_version_result
OUTPUT_STRIP_TRAILING_WHITESPACE)
IF(NOT ${BISON_version_result} EQUAL 0)
MESSAGE(SEND_ERROR "Command \"${BISON_EXECUTABLE} --version\" failed with output:\n${BISON_version_error}")
ELSE()
STRING(REGEX REPLACE "^bison \\(GNU Bison\\) ([^\n]+)\n.*" "\\1"
BISON_VERSION "${BISON_version_output}")
ENDIF()
# internal macro
MACRO(BISON_TARGET_option_verbose Name BisonOutput filename)
LIST(APPEND BISON_TARGET_cmdopt "--verbose")
GET_FILENAME_COMPONENT(BISON_TARGET_output_path "${BisonOutput}" PATH)
GET_FILENAME_COMPONENT(BISON_TARGET_output_name "${BisonOutput}" NAME_WE)
ADD_CUSTOM_COMMAND(OUTPUT ${filename}
COMMAND ${CMAKE_COMMAND}
ARGS -E copy
"${BISON_TARGET_output_path}/${BISON_TARGET_output_name}.output"
"${filename}"
DEPENDS
"${BISON_TARGET_output_path}/${BISON_TARGET_output_name}.output"
COMMENT "[BISON][${Name}] Copying bison verbose table to ${filename}"
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
SET(BISON_${Name}_VERBOSE_FILE ${filename})
LIST(APPEND BISON_TARGET_extraoutputs
"${BISON_TARGET_output_path}/${BISON_TARGET_output_name}.output")
ENDMACRO(BISON_TARGET_option_verbose)
# internal macro
MACRO(BISON_TARGET_option_extraopts Options)
SET(BISON_TARGET_extraopts "${Options}")
SEPARATE_ARGUMENTS(BISON_TARGET_extraopts)
LIST(APPEND BISON_TARGET_cmdopt ${BISON_TARGET_extraopts})
ENDMACRO(BISON_TARGET_option_extraopts)
#============================================================
# BISON_TARGET (public macro)
#============================================================
#
MACRO(BISON_TARGET Name BisonInput BisonOutput)
SET(BISON_TARGET_output_header "")
#SET(BISON_TARGET_command_opt "")
SET(BISON_TARGET_cmdopt "")
SET(BISON_TARGET_outputs "${BisonOutput}")
IF(NOT ${ARGC} EQUAL 3 AND
NOT ${ARGC} EQUAL 5 AND
NOT ${ARGC} EQUAL 7 AND
NOT ${ARGC} EQUAL 9)
MESSAGE(SEND_ERROR "Usage")
ELSE()
# Parsing parameters
IF(${ARGC} GREATER 5 OR ${ARGC} EQUAL 5)
IF("${ARGV3}" STREQUAL "VERBOSE")
BISON_TARGET_option_verbose(${Name} ${BisonOutput} "${ARGV4}")
ENDIF()
IF("${ARGV3}" STREQUAL "COMPILE_FLAGS")
BISON_TARGET_option_extraopts("${ARGV4}")
ENDIF()
IF("${ARGV3}" STREQUAL "HEADER")
set(BISON_TARGET_output_header "${ARGV4}")
ENDIF()
ENDIF()
IF(${ARGC} GREATER 7 OR ${ARGC} EQUAL 7)
IF("${ARGV5}" STREQUAL "VERBOSE")
BISON_TARGET_option_verbose(${Name} ${BisonOutput} "${ARGV6}")
ENDIF()
IF("${ARGV5}" STREQUAL "COMPILE_FLAGS")
BISON_TARGET_option_extraopts("${ARGV6}")
ENDIF()
IF("${ARGV5}" STREQUAL "HEADER")
set(BISON_TARGET_output_header "${ARGV6}")
ENDIF()
ENDIF()
IF(${ARGC} EQUAL 9)
IF("${ARGV7}" STREQUAL "VERBOSE")
BISON_TARGET_option_verbose(${Name} ${BisonOutput} "${ARGV8}")
ENDIF()
IF("${ARGV7}" STREQUAL "COMPILE_FLAGS")
BISON_TARGET_option_extraopts("${ARGV8}")
ENDIF()
IF("${ARGV7}" STREQUAL "HEADER")
set(BISON_TARGET_output_header "${ARGV8}")
ENDIF()
ENDIF()
IF(BISON_TARGET_output_header)
# Header's name passed in as argument to be used in --defines option
LIST(APPEND BISON_TARGET_cmdopt
"--defines=${BISON_TARGET_output_header}")
set(BISON_${Name}_OUTPUT_HEADER ${BISON_TARGET_output_header})
ELSE()
# Header's name generated by bison (see option -d)
LIST(APPEND BISON_TARGET_cmdopt "-d")
STRING(REGEX REPLACE "^(.*)(\\.[^.]*)$" "\\2" _fileext "${ARGV2}")
STRING(REPLACE "c" "h" _fileext ${_fileext})
STRING(REGEX REPLACE "^(.*)(\\.[^.]*)$" "\\1${_fileext}"
BISON_${Name}_OUTPUT_HEADER "${ARGV2}")
ENDIF()
LIST(APPEND BISON_TARGET_outputs "${BISON_${Name}_OUTPUT_HEADER}")
ADD_CUSTOM_COMMAND(OUTPUT ${BISON_TARGET_outputs}
${BISON_TARGET_extraoutputs}
COMMAND ${BISON_EXECUTABLE}
ARGS ${BISON_TARGET_cmdopt} -o ${ARGV2} ${ARGV1}
DEPENDS ${ARGV1}
COMMENT "[BISON][${Name}] Building parser with bison ${BISON_VERSION}"
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
# define target variables
SET(BISON_${Name}_DEFINED TRUE)
SET(BISON_${Name}_INPUT ${ARGV1})
SET(BISON_${Name}_OUTPUTS ${BISON_TARGET_outputs})
SET(BISON_${Name}_COMPILE_FLAGS ${BISON_TARGET_cmdopt})
SET(BISON_${Name}_OUTPUT_SOURCE "${BisonOutput}")
ENDIF(NOT ${ARGC} EQUAL 3 AND
NOT ${ARGC} EQUAL 5 AND
NOT ${ARGC} EQUAL 7 AND
NOT ${ARGC} EQUAL 9)
ENDMACRO(BISON_TARGET)
#
#============================================================
ENDIF(BISON_EXECUTABLE)
INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(BISON DEFAULT_MSG BISON_EXECUTABLE)
# FindBISON.cmake ends here

53
cmake/FindBinPAC.cmake Normal file
View file

@ -0,0 +1,53 @@
# - Try to find BinPAC binary and library
#
# Usage of this module as follows:
#
# find_package(BinPAC)
#
# Variables used by this module, they can change the default behaviour and need
# to be set before calling find_package:
#
# BinPAC_ROOT_DIR Set this variable to the root installation of
# BinPAC if the module has problems finding the
# proper installation path.
#
# Variables defined by this module:
#
# BINPAC_FOUND System has BinPAC binary and library
# BinPAC_EXE The binpac executable
# BinPAC_LIBRARY The libbinpac.a library
# BinPAC_INCLUDE_DIR The binpac headers
# look for BinPAC in standard locations or user-provided root
find_path(BinPAC_ROOT_DIR
NAMES include/binpac.h
)
find_file(BinPAC_EXE
NAMES binpac
HINTS ${BinPAC_ROOT_DIR}/bin
)
find_library(BinPAC_LIBRARY
NAMES libbinpac.a
HINTS ${BinPAC_ROOT_DIR}/lib
)
find_path(BinPAC_INCLUDE_DIR
NAMES binpac.h
HINTS ${BinPAC_ROOT_DIR}/include
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(BinPAC DEFAULT_MSG
BinPAC_EXE
BinPAC_LIBRARY
BinPAC_INCLUDE_DIR
)
mark_as_advanced(
BinPAC_ROOT_DIR
BinPAC_EXE
BinPAC_LIBRARY
BinPAC_INCLUDE_DIR
)

View file

@ -0,0 +1,44 @@
# - Try to find GooglePerftools headers and libraries
#
# Usage of this module as follows:
#
# find_package(GooglePerftools)
#
# Variables used by this module, they can change the default behaviour and need
# to be set before calling find_package:
#
# GooglePerftools_ROOT_DIR Set this variable to the root installation of
# GooglePerftools if the module has problems finding
# the proper installation path.
#
# Variables defined by this module:
#
# GOOGLEPERFTOOLS_FOUND System has GooglePerftools libs/headers
# GooglePerftools_LIBRARIES The GooglePerftools libraries
# GooglePerftools_INCLUDE_DIR The location of GooglePerftools headers
find_path(GooglePerftools_ROOT_DIR
NAMES include/google/heap-profiler.h
)
find_library(GooglePerftools_LIBRARIES
NAMES tcmalloc
HINTS ${GooglePerftools_ROOT_DIR}/lib
)
find_path(GooglePerftools_INCLUDE_DIR
NAMES google/heap-profiler.h
HINTS ${GooglePerftools_ROOT_DIR}/include
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(GooglePerftools DEFAULT_MSG
GooglePerftools_LIBRARIES
GooglePerftools_INCLUDE_DIR
)
mark_as_advanced(
GooglePerftools_ROOT_DIR
GooglePerftools_LIBRARIES
GooglePerftools_INCLUDE_DIR
)

44
cmake/FindLibGeoIP.cmake Normal file
View file

@ -0,0 +1,44 @@
# - Try to find GeoIP headers and libraries
#
# Usage of this module as follows:
#
# find_package(LibGeoIP)
#
# Variables used by this module, they can change the default behaviour and need
# to be set before calling find_package:
#
# LibGeoIP_ROOT_DIR Set this variable to the root installation of
# libGeoIP if the module has problems finding the
# proper installation path.
#
# Variables defined by this module:
#
# LIBGEOIP_FOUND System has GeoIP libraries and headers
# LibGeoIP_LIBRARY The GeoIP library
# LibGeoIP_INCLUDE_DIR The location of GeoIP headers
find_path(LibGeoIP_ROOT_DIR
NAMES include/GeoIPCity.h
)
find_library(LibGeoIP_LIBRARY
NAMES GeoIP
HINTS ${LibGeoIP_ROOT_DIR}/lib
)
find_path(LibGeoIP_INCLUDE_DIR
NAMES GeoIPCity.h
HINTS ${LibGeoIP_ROOT_DIR}/include
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LibGeoIP DEFAULT_MSG
LibGeoIP_LIBRARY
LibGeoIP_INCLUDE_DIR
)
mark_as_advanced(
LibGeoIP_ROOT_DIR
LibGeoIP_LIBRARY
LibGeoIP_INCLUDE_DIR
)

44
cmake/FindLibMagic.cmake Normal file
View file

@ -0,0 +1,44 @@
# - Try to find libmagic header and library
#
# Usage of this module as follows:
#
# find_package(LibMagic)
#
# Variables used by this module, they can change the default behaviour and need
# to be set before calling find_package:
#
# LibMagic_ROOT_DIR Set this variable to the root installation of
# libmagic if the module has problems finding the
# proper installation path.
#
# Variables defined by this module:
#
# LIBMAGIC_FOUND System has libmagic and magic.h
# LibMagic_LIBRARY The libmagic library
# LibMagic_INCLUDE_DIR The location of magic.h
find_path(LibMagic_ROOT_DIR
NAMES include/magic.h
)
find_library(LibMagic_LIBRARY
NAMES magic
HINTS ${LibMagic_ROOT_DIR}/lib
)
find_path(LibMagic_INCLUDE_DIR
NAMES magic.h
HINTS ${LibMagic_ROOT_DIR}/include
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(LibMagic DEFAULT_MSG
LibMagic_LIBRARY
LibMagic_INCLUDE_DIR
)
mark_as_advanced(
LibMagic_ROOT_DIR
LibMagic_LIBRARY
LibMagic_INCLUDE_DIR
)

56
cmake/FindOpenSSL.cmake Normal file
View file

@ -0,0 +1,56 @@
# - Try to find openssl include dirs and libraries
#
# Usage of this module as follows:
#
# find_package(OpenSSL)
#
# Variables used by this module, they can change the default behaviour and need
# to be set before calling find_package:
#
# OpenSSL_ROOT_DIR Set this variable to the root installation of
# openssl if the module has problems finding the
# proper installation path.
#
# Variables defined by this module:
#
# OPENSSL_FOUND System has openssl, include and library dirs found
# OpenSSL_INCLUDE_DIR The openssl include directories.
# OpenSSL_LIBRARIES The openssl libraries.
# OpenSSL_CYRPTO_LIBRARY The openssl crypto library.
# OpenSSL_SSL_LIBRARY The openssl ssl library.
find_path(OpenSSL_ROOT_DIR
NAMES include/openssl/ssl.h
)
find_path(OpenSSL_INCLUDE_DIR
NAMES openssl/ssl.h
HINTS ${OpenSSL_ROOT_DIR}/include
)
find_library(OpenSSL_SSL_LIBRARY
NAMES ssl ssleay32 ssleay32MD
HINTS ${OpenSSL_ROOT_DIR}/lib
)
find_library(OpenSSL_CRYPTO_LIBRARY
NAMES crypto
HINTS ${OpenSSL_ROOT_DIR}/lib
)
set(OpenSSL_LIBRARIES ${OpenSSL_SSL_LIBRARY} ${OpenSSL_CRYPTO_LIBRARY}
CACHE STRING "OpenSSL SSL and crypto libraries" FORCE)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(OpenSSL DEFAULT_MSG
OpenSSL_LIBRARIES
OpenSSL_INCLUDE_DIR
)
mark_as_advanced(
OpenSSL_ROOT_DIR
OpenSSL_INCLUDE_DIR
OpenSSL_LIBRARIES
OpenSSL_CRYPTO_LIBRARY
OpenSSL_SSL_LIBRARY
)

44
cmake/FindPCAP.cmake Normal file
View file

@ -0,0 +1,44 @@
# - Try to find libpcap include dirs and libraries
#
# Usage of this module as follows:
#
# find_package(PCAP)
#
# Variables used by this module, they can change the default behaviour and need
# to be set before calling find_package:
#
# PCAP_ROOT_DIR Set this variable to the root installation of
# libpcap if the module has problems finding the
# proper installation path.
#
# Variables defined by this module:
#
# PCAP_FOUND System has libpcap, include and library dirs found
# PCAP_INCLUDE_DIR The libpcap include directories.
# PCAP_LIBRARY The libpcap library.
find_path(PCAP_ROOT_DIR
NAMES include/pcap.h
)
find_path(PCAP_INCLUDE_DIR
NAMES pcap.h
HINTS ${PCAP_ROOT_DIR}/include
)
find_library(PCAP_LIBRARY
NAMES pcap
HINTS ${PCAP_ROOT_DIR}/lib
)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(PCAP DEFAULT_MSG
PCAP_LIBRARY
PCAP_INCLUDE_DIR
)
mark_as_advanced(
PCAP_ROOT_DIR
PCAP_INCLUDE_DIR
PCAP_LIBRARY
)

View file

@ -0,0 +1,44 @@
# A wrapper macro around the standard CMake find_package macro that
# facilitates displaying better error messages by default, or even
# accepting custom error messages on a per package basis.
#
# If a package is not found, then the MISSING_PREREQS variable gets
# set to true and either a default or custom error message appended
# to MISSING_PREREQ_DESCS.
#
# The caller can use these variables to display a list of any missing
# packages and abort the build/configuration if there were any.
#
# Use as follows:
#
# include(FindRequiredPackage)
# FindRequiredPackage(Perl)
# FindRequiredPackage(FLEX "You need to install flex (Fast Lexical Analyzer)")
#
# if (MISSING_PREREQS)
# foreach (prereq ${MISSING_PREREQ_DESCS})
# message(SEND_ERROR ${prereq})
# endforeach ()
# message(FATAL_ERROR "Configuration aborted due to missing prerequisites")
# endif ()
macro(FindRequiredPackage packageName)
find_package(${packageName})
string(TOUPPER ${packageName} canonPackageName)
if (NOT ${canonPackageName}_FOUND)
set(MISSING_PREREQS true)
set(customDesc)
foreach (descArg ${ARGN})
set(customDesc "${customDesc} ${descArg}")
endforeach ()
if (customDesc)
# append the custom error message that was provided as an argument
list(APPEND MISSING_PREREQ_DESCS ${customDesc})
else ()
list(APPEND MISSING_PREREQ_DESCS
" Could not find prerequisite package '${packageName}'")
endif ()
endif ()
endmacro(FindRequiredPackage)

34
cmake/MiscTests.cmake Normal file
View file

@ -0,0 +1,34 @@
include(CheckCXXSourceCompiles)
include(CheckCSourceCompiles)
# This autoconf variable is obsolete; it's portable to assume C89 and signal
# handlers returning void
set(RETSIGTYPE "void")
set(RETSIGVAL "")
check_c_source_compiles("
#include <sys/types.h>
#include <sys/socket.h>
extern int socket(int, int, int);
extern int connect(int, const struct sockaddr *, int);
extern int send(int, const void *, int, int);
extern int recvfrom(int, void *, int, int, struct sockaddr *, int *);
int main() { return 0; }
" DO_SOCK_DECL)
if (DO_SOCK_DECL)
message(STATUS "socket() and friends need explicit declaration")
endif ()
check_cxx_source_compiles("
#include <stdlib.h>
#include <syslog.h>
extern \"C\" {
int openlog(const char* ident, int logopt, int facility);
int syslog(int priority, const char* message_fmt, ...);
int closelog();
}
int main() { return 0; }
" SYSLOG_INT)
if (SYSLOG_INT)
message(STATUS "syslog prototypes need declaration")
endif ()

67
cmake/OSSpecific.cmake Normal file
View file

@ -0,0 +1,67 @@
if (${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
# alternate malloc is faster for FreeBSD, but needs more testing
# need to add way to set this from the command line
set(USE_NMALLOC true)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD")
set(USE_NMALLOC true)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(HAVE_LINUX true)
include_directories(BEFORE ${CMAKE_SOURCE_DIR}/linux-include)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Solaris")
set(SOCKET_LIBS nsl socket)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "osf")
# Workaround ip_hl vs. ip_vhl problem in netinet/ip.h
add_definitions(-D__STDC__=2)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "irix")
list(APPEND CMAKE_C_FLAGS -xansi -signed -g3)
list(APPEND CMAKE_CXX_FLAGS -xansi -signed -g3)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "ultrix")
list(APPEND CMAKE_C_FLAGS -std1 -g3)
list(APPEND CMAKE_CXX_FLAGS -std1 -g3)
include(CheckCSourceCompiles)
check_c_source_compiles("
#include <sys/types.h>
int main() {
void c(const struct a *);
return 0;
}
" have_ultrix_const)
if (NOT have_ultrix_const)
set(NEED_ULTRIX_CONST_HACK true)
endif ()
elseif (${CMAKE_SYSTEM_NAME} MATCHES "hpux" OR
${CMAKE_SYSTEM_NAME} MATCHES "HP-UX")
include(CheckCSourceCompiles)
set(CMAKE_REQUIRED_FLAGS -Aa)
set(CMAKE_REQUIRED_DEFINITIONS -D_HPUX_SOURCE)
check_c_source_compiles("
#include <sys/types.h>
int main() {
int frob(int, char *);
return 0;
}
" have_ansi_prototypes)
unset(CMAKE_REQUIRED_FLAGS)
unset(CMAKE_REQUIRED_DEFINITIONS)
if (have_ansi_prototypes)
add_definitions(-D_HPUX_SOURCE)
list(APPEND CMAKE_C_FLAGS -Aa)
list(APPEND CMAKE_CXX_FLAGS -Aa)
endif ()
if (NOT have_ansi_prototypes)
message(FATAL_ERROR "Can't get HPUX compiler to handle ANSI prototypes")
endif ()
endif ()

72
cmake/OpenSSLTests.cmake Normal file
View file

@ -0,0 +1,72 @@
include(CheckCSourceCompiles)
include(CheckCXXSourceCompiles)
set(CMAKE_REQUIRED_LIBRARIES ${OpenSSL_LIBRARIES})
set(CMAKE_REQUIRED_INCLUDES ${OpenSSL_INCLUDE_DIR})
check_c_source_compiles("
#include <openssl/ssl.h>
int main() { return 0; }
" including_ssl_h_works)
if (NOT including_ssl_h_works)
# On Red Hat we may need to include Kerberos header.
set(CMAKE_REQUIRED_INCLUDES ${OpenSSL_INCLUDE_DIR} /usr/kerberos/include)
check_c_source_compiles("
#include <krb5.h>
#include <openssl/ssl.h>
int main() { return 0; }
" NEED_KRB5_H)
set(CMAKE_REQUIRED_INCLUDES ${OpenSSL_INCLUDE_DIR})
if (NOT NEED_KRB5_H)
message(FATAL_ERROR
"OpenSSL test failure. See CmakeError.log for details.")
else ()
message(STATUS "OpenSSL requires Kerberos header")
include_directories("/usr/kerberos/include")
endif ()
endif ()
# check for OPENSSL_add_all_algorithms_conf function
# and thus OpenSSL >= v0.9.7
check_c_source_compiles("
#include <openssl/evp.h>
int main() {
OPENSSL_add_all_algorithms_conf();
return 0;
}
" openssl_greater_than_0_9_7)
if (NOT openssl_greater_than_0_9_7)
message(FATAL_ERROR "OpenSSL >= v0.9.7 required")
endif ()
check_cxx_source_compiles("
#include <openssl/x509.h>
int main() {
const unsigned char** cpp = 0;
X509** x =0;
d2i_X509(x, cpp, 0);
return 0;
}
" OPENSSL_D2I_X509_USES_CONST_CHAR)
if (NOT OPENSSL_D2I_X509_USES_CONST_CHAR)
# double check that it compiles without const
check_cxx_source_compiles("
#include <openssl/x509.h>
int main() {
unsigned char** cpp = 0;
X509** x =0;
d2i_X509(x, cpp, 0);
return 0;
}
" OPENSSL_D2I_X509_USES_CHAR)
if (NOT OPENSSL_D2I_X509_USES_CHAR)
message(FATAL_ERROR
"Can't determine if openssl_d2i_x509() takes const char parameter")
endif ()
endif ()
unset(CMAKE_REQUIRED_INCLUDES)
unset(CMAKE_REQUIRED_LIBRARIES)

63
cmake/PCAPTests.cmake Normal file
View file

@ -0,0 +1,63 @@
include(CheckFunctionExists)
include(CheckCSourceCompiles)
include(CheckIncludeFiles)
set(CMAKE_REQUIRED_INCLUDES ${LIBPCAP_INCLUDE_DIR})
set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIBRARY})
check_include_files(pcap-int.h HAVE_PCAP_INT_H)
check_function_exists(pcap_freecode HAVE_LIBPCAP_PCAP_FREECODE)
if (NOT HAVE_LIBPCAP_PCAP_FREECODE)
set(DONT_HAVE_LIBPCAP_PCAP_FREECODE true)
message(STATUS "No implementation for pcap_freecode()")
endif ()
check_c_source_compiles("
#include <pcap.h>
int main () {
int snaplen;
int linktype;
struct bpf_program fp;
int optimize;
bpf_u_int32 netmask;
char str[10];
char error[1024];
snaplen = 50;
linktype = DLT_EN10MB;
optimize = 1;
netmask = 0L;
str[0] = 'i'; str[1] = 'p'; str[2] = '\\\\0';
(void)pcap_compile_nopcap(
snaplen, linktype, &fp, str, optimize, netmask, &error);
return 0;
}
" LIBPCAP_PCAP_COMPILE_NOPCAP_HAS_ERROR_PARAMETER)
if (NOT LIBPCAP_PCAP_COMPILE_NOPCAP_HAS_ERROR_PARAMETER)
# double check
check_c_source_compiles("
#include <pcap.h>
int main () {
int snaplen;
int linktype;
struct bpf_program fp;
int optimize;
bpf_u_int32 netmask;
char str[10];
snaplen = 50;
linktype = DLT_EN10MB;
optimize = 1;
netmask = 0L;
str[0] = 'i'; str[1] = 'p'; str[2] = '\\\\0';
(void)pcap_compile_nopcap(snaplen, linktype, &fp, str, optimize, netmask);
return 0;
}
" LIBPCAP_PCAP_COMPILE_NOPCAP_NO_ERROR_PARAMETER)
if (NOT LIBPCAP_PCAP_COMPILE_NOPCAP_NO_ERROR_PARAMETER)
message(FATAL_ERROR
"Can't determine if pcap_compile_nopcap takes an error parameter")
endif ()
endif ()
unset(CMAKE_REQUIRED_INCLUDES)
unset(CMAKE_REQUIRED_LIBRARIES)

View file

@ -0,0 +1,18 @@
# Sets CPACK_PACKAGE_FILE name in the following format:
#
# <project_name>-<version>-<OS/platform>-<arch>
#
# The version must already be set in the VERSION variable
set(CPACK_PACKAGE_FILE_NAME "${CMAKE_PROJECT_NAME}-${VERSION}")
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-${CMAKE_SYSTEM_NAME}")
if (APPLE)
# Only Intel-based Macs are supported. CMAKE_SYSTEM_PROCESSOR may
# return the confusing 'i386' if running a 32-bit kernel, but chances
# are the binary is x86_64 (or more generally 'Intel') compatible.
set(arch "Intel")
else ()
set (arch ${CMAKE_SYSTEM_PROCESSOR})
endif ()
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-${arch}")

View file

@ -0,0 +1,23 @@
# Sets the list of desired package types to be created by the make
# package target. A .tar.gz is always made, and depending on the
# operating system, more are added:
#
# Darwin - PackageMaker
# Linux - RPM if the platform has rpmbuild installed
# DEB is ommitted because CPack does not give enough
# control over how the package is created and lacks support
# for automatic dependency detection.
#
#
# CPACK_GENERATOR is set by this module
set(CPACK_GENERATOR TGZ)
set(CPACK_SOURCE_GENERATOR TGZ)
if (APPLE)
list(APPEND CPACK_GENERATOR PackageMaker)
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
find_program(RPMBUILD_EXE rpmbuild)
if (RPMBUILD_EXE)
set(CPACK_GENERATOR ${CPACK_GENERATOR} RPM)
endif ()
endif ()

View file

@ -0,0 +1,27 @@
# Sets CPack version variables by splitting the first macro argument
# using "." as a delimiter. If the length of the split list is
# greater than 2, all remaining elements are tacked on to the patch
# level version.
macro(SetPackageVersion _version)
string(REPLACE "." " " version_numbers ${_version})
separate_arguments(version_numbers)
list(GET version_numbers 0 CPACK_PACKAGE_VERSION_MAJOR)
list(REMOVE_AT version_numbers 0)
list(GET version_numbers 0 CPACK_PACKAGE_VERSION_MINOR)
list(REMOVE_AT version_numbers 0)
list(LENGTH version_numbers version_length)
while (version_length GREATER 0)
list(GET version_numbers 0 patch_level)
if (CPACK_PACKAGE_VERSION_PATCH)
set(CPACK_PACKAGE_VERSION_PATCH
"${CPACK_PACKAGE_VERSION_PATCH}.${patch_level}")
else ()
set(CPACK_PACKAGE_VERSION_PATCH ${patch_level})
endif ()
list(REMOVE_AT version_numbers 0)
list(LENGTH version_numbers version_length)
endwhile ()
endmacro(SetPackageVersion)

View file

@ -0,0 +1,35 @@
function(uninstall_manifest manifestPath)
file(READ "${manifestPath}" files)
string(REGEX REPLACE "\n" ";" files "${files}")
foreach (file ${files})
set(fileName $ENV{DESTDIR}${file})
if (EXISTS "${fileName}" OR IS_SYMLINK "${fileName}")
message(STATUS "Uninstalling: ${fileName}")
execute_process(
COMMAND @CMAKE_COMMAND@ -E remove "${fileName}"
OUTPUT_VARIABLE rm_out
RESULT_VARIABLE rm_retval
)
if (NOT ${rm_retval} EQUAL 0)
message(FATAL_ERROR "Problem when removing: ${fileName}")
endif ()
else ()
message(STATUS "Does not exist: ${fileName}")
endif ()
endforeach ()
endfunction(uninstall_manifest)
file(GLOB install_manifests @CMAKE_CURRENT_BINARY_DIR@/install_manifest*.txt)
if (install_manifests)
foreach (manifest ${install_manifests})
uninstall_manifest(${manifest})
endforeach ()
else ()
message(FATAL_ERROR "Cannot find any install manifests in: "
"\"@CMAKE_CURRENT_BINARY_DIR@/install_manifest*.txt\"")
endif ()

148
config.h.in Normal file
View file

@ -0,0 +1,148 @@
/* enable IPV6 processing */
#cmakedefine BROv6
/* Old libpcap versions (< 0.6.1) need defining pcap_freecode and
pcap_compile_nopcap */
#cmakedefine DONT_HAVE_LIBPCAP_PCAP_FREECODE
/* should explicitly declare socket() and friends */
#cmakedefine DO_SOCK_DECL
/* Define if you have the <getopt.h> header file. */
#cmakedefine HAVE_GETOPT_H
/* Define if you have the `getopt_long' function. */
#cmakedefine HAVE_GETOPT_LONG
/* Define if you have the `magic' library (-lmagic). */
#cmakedefine HAVE_LIBMAGIC
/* Define if you have the `z' library (-lz). */
#cmakedefine HAVE_LIBZ
/* We are on a Linux system */
#cmakedefine HAVE_LINUX
/* Define if you have the <magic.h> header file. */
#cmakedefine HAVE_MAGIC_H
/* Define if you have the `mallinfo' function. */
#cmakedefine HAVE_MALLINFO
/* Define if you have the <memory.h> header file. */
#cmakedefine HAVE_MEMORY_H
/* Define if you have the <netinet/if_ether.h> header file. */
#cmakedefine HAVE_NETINET_IF_ETHER_H
/* Define if you have the <netinet/ip6.h> header file. */
#cmakedefine HAVE_NETINET_IP6_H
/* Define if you have the <net/ethernet.h> header file. */
#cmakedefine HAVE_NET_ETHERNET_H
/* We are on a OpenBSD system */
#cmakedefine HAVE_OPENBSD
/* have os-proto.h */
#cmakedefine HAVE_OS_PROTO_H
/* Define if you have the <pcap-int.h> header file. */
#cmakedefine HAVE_PCAP_INT_H
/* line editing & history powers */
#cmakedefine HAVE_READLINE
/* Define if you have the `sigaction' function, but not `sigset'. */
#cmakedefine HAVE_SIGACTION
/* Define if you have the `sigset' function. */
#cmakedefine HAVE_SIGSET
/* Define if you have the `strcasestr' function. */
#cmakedefine HAVE_STRCASESTR
/* Define if you have the `strerror' function. */
#cmakedefine HAVE_STRERROR
/* Define if you have the `strsep' function. */
#cmakedefine HAVE_STRSEP
/* Define if you have the <sys/ethernet.h> header file. */
#cmakedefine HAVE_SYS_ETHERNET_H
/* Some libpcap versions use an extra parameter (error) in pcap_compile_nopcap
*/
#cmakedefine LIBPCAP_PCAP_COMPILE_NOPCAP_HAS_ERROR_PARAMETER
/* Include krb5.h */
#cmakedefine NEED_KRB5_H
/* Compatibility for Darwin */
#cmakedefine NEED_NAMESER_COMPAT_H
/* d2i_x509 uses const char** */
#cmakedefine OPENSSL_D2I_X509_USES_CONST_CHAR
/* Define as the return type of signal handlers (`int' or `void'). */
#define RETSIGTYPE @RETSIGTYPE@
/* signal function return value */
#define RETSIGVAL @RETSIGVAL@
/* have sin_len field in sockaddr_in */
#cmakedefine SIN_LEN
/* The size of `long int', as computed by sizeof. */
#define SIZEOF_LONG_INT @SIZEOF_LONG_INT@
/* The size of `long long', as computed by sizeof. */
#define SIZEOF_LONG_LONG @SIZEOF_LONG_LONG@
/* The size of `void *', as computed by sizeof. */
#define SIZEOF_VOID_P @SIZEOF_VOID_P@
/* should we declare syslog() and openlog() */
#cmakedefine SYSLOG_INT
/* Define if you have <sys/time.h> */
#cmakedefine HAVE_SYS_TIME_H
/* Define if you can safely include both <sys/time.h> and <time.h>. */
#cmakedefine TIME_WITH_SYS_TIME
/* GeoIP geographic lookup functionality */
#cmakedefine USE_GEOIP
/* Use Google's perftools */
#cmakedefine USE_PERFTOOLS
/* Version number of package */
#define VERSION "@VERSION@"
/* whether words are stored with the most significant byte first */
#cmakedefine WORDS_BIGENDIAN
/* ultrix can't hack const */
#cmakedefine NEED_ULTRIX_CONST_HACK
#ifdef NEED_ULTRIX_CONST_HACK
#define const
#endif
/* Define int32_t */
#define int32_t @INT32_T@
/* use sigset() instead of signal() */
#define signal @SIG_FUNC@
/* define to int if socklen_t not available */
#define socklen_t @SOCKLEN_T@
/* Define u_int16_t */
#define u_int16_t @U_INT16_T@
/* Define u_int32_t */
#define u_int32_t @U_INT32_T@
/* Define u_int8_t */
#define u_int8_t @U_INT8_T@

189
configure vendored Executable file
View file

@ -0,0 +1,189 @@
#!/bin/sh
# Convenience wrapper for easily viewing/setting options that
# the project's CMake scripts will recognize
# check for `cmake` command
type cmake > /dev/null 2>&1 || {
echo "\
This package requires CMake, please install it first, then you may
use this configure script to access CMake equivalent functionality.\
" >&2;
exit 1;
}
usage="\
Usage: $0 [OPTION]... [VAR=VALUE]...
Build Directory:
--builddir=DIR place build files in directory [build]
Installation Directories:
--prefix=PREFIX installation directory [/usr/local/bro]
--policydir=PATH policy file installation directory
[PREFIX/share/bro]
Optional Features:
--enable-debug compile in debugging mode
--enable-brov6 enable IPv6 processing
--enable-perftools use Google's perftools
--enable-cluster install Broctl configured for cluster operation
(overridden by --disable-broctl)
--disable-broccoli don't build or install the Broccoli library
--disable-broctl don't install Broctl
--disable-auxtools don't build or install auxilliary tools
Required Packages in Non-Standard Locations:
--with-openssl=PATH path to OpenSSL install root
--with-bind=PATH path to BIND install root
--with-pcap=PATH path to libpcap install root
--with-binpac=PATH path to BinPAC install root
Optional Packages in Non-Standard Locations:
--with-libmagic=PATH path to libmagic install root
--with-geoip=PATH path to the libGeoIP install root
--with-perftools=PATH path to Google Perftools install root
Influential Environment Variables (only on first invocation
per build directory):
CC C compiler command
CFLAGS C compiler flags
CXX C++ compiler command
CXXFLAGS C++ compiler flags
"
sourcedir="$( cd "$( dirname "$0" )" && pwd )"
# Function to append a CMake cache entry definition to the
# CMakeCacheEntries variable
# $1 is the cache entry variable name
# $2 is the cache entry variable type
# $3 is the cache entry variable value
append_cache_entry () {
CMakeCacheEntries="$CMakeCacheEntries -D $1:$2=$3"
}
# set defaults
builddir=build
CMakeCacheEntries=""
append_cache_entry CMAKE_INSTALL_PREFIX PATH /usr/local/bro
append_cache_entry BRO_ROOT_DIR PATH /usr/local/bro
append_cache_entry PY_MOD_INSTALL_DIR PATH /usr/local/bro/lib/broctl
append_cache_entry POLICYDIR STRING /usr/local/bro/share/bro
append_cache_entry ENABLE_DEBUG BOOL false
append_cache_entry BROv6 BOOL false
append_cache_entry ENABLE_PERFTOOLS BOOL false
append_cache_entry BinPAC_SKIP_INSTALL BOOL true
append_cache_entry BUILD_SHARED_LIBS BOOL true
append_cache_entry INSTALL_AUX_TOOLS BOOL true
append_cache_entry INSTALL_BROCCOLI BOOL true
append_cache_entry INSTALL_BROCTL BOOL true
append_cache_entry STANDALONE BOOL true
# parse arguments
while [ $# -ne 0 ]; do
case "$1" in
-*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
*) optarg= ;;
esac
case "$1" in
--help|-h)
echo "${usage}" 1>&2
exit 1
;;
--builddir=*)
builddir=$optarg
;;
--prefix=*)
append_cache_entry CMAKE_INSTALL_PREFIX PATH $optarg
append_cache_entry BRO_ROOT_DIR PATH $optarg
append_cache_entry PY_MOD_INSTALL_DIR PATH $optarg/lib/broctl
if [ "$user_set_policydir" != "true" ]; then
append_cache_entry POLICYDIR STRING $optarg/share/bro
fi
;;
--policydir=*)
append_cache_entry POLICYDIR STRING $optarg
user_set_policydir="true"
;;
--enable-debug)
append_cache_entry ENABLE_DEBUG BOOL true
;;
--enable-brov6)
append_cache_entry BROv6 BOOL true
;;
--enable-perftools)
append_cache_entry ENABLE_PERFTOOLS BOOL true
;;
--disable-broccoli)
append_cache_entry INSTALL_BROCCOLI BOOL false
;;
--disable-broctl)
append_cache_entry INSTALL_BROCTL BOOL false
user_disabled_broctl="true"
;;
--enable-cluster)
if [ "$user_disabled_broctl" != "true" ]; then
append_cache_entry STANDALONE BOOL false
fi
;;
--disable-auxtools)
append_cache_entry INSTALL_AUX_TOOLS BOOL false
;;
--with-openssl=*)
append_cache_entry OpenSSL_ROOT_DIR PATH $optarg
;;
--with-bind=*)
append_cache_entry BIND_ROOT_DIR PATH $optarg
;;
--with-pcap=*)
append_cache_entry PCAP_ROOT_DIR PATH $optarg
;;
--with-binpac=*)
append_cache_entry BinPAC_ROOT_DIR PATH $optarg
;;
--with-libmagic=*)
append_cache_entry LibMagic_ROOT_DIR PATH $optarg
;;
--with-geoip=*)
append_cache_entry LibGeoIP_ROOT_DIR PATH $optarg
;;
--with-perftools=*)
append_cache_entry GooglePerftools_ROOT_DIR PATH $optarg
;;
*)
echo "Invalid option '$1'. Try $0 --help to see available options."
exit 1
;;
esac
shift
done
if [ -d $builddir ]; then
# If build directory exists, check if it has a CMake cache
if [ -f $builddir/CMakeCache.txt ]; then
# If the Cmake cache exists, then check that it thinks
# the source tree exists where it's currently located
cmakehomedir=`grep CMAKE_HOME_DIRECTORY $builddir/CMakeCache.txt | \
sed 's/CMAKE_HOME_DIRECTORY:INTERNAL=//g'`
if [ "$cmakehomedir" != "$sourcedir" ]; then
# The source tree moved since the build was last configured
echo "\
The source tree has been moved from:
$cmakehomedir
to:
$sourcedir
To reconfigure in the new source directory, please delete:
$builddir/CMakeCache.txt" >&2
exit 1
fi
fi
else
# Create build directory
mkdir -p $builddir
fi
echo "Build Directory : $builddir"
echo "Source Directory: $sourcedir"
cd $builddir
cmake $CMakeCacheEntries $sourcedir

10
policy/CMakeLists.txt Normal file
View file

@ -0,0 +1,10 @@
install(DIRECTORY ./ DESTINATION ${POLICYDIR} FILES_MATCHING
PATTERN "summaries" EXCLUDE
PATTERN "all.bro" EXCLUDE
PATTERN "bro.init"
PATTERN "*.bro"
PATTERN "*.sig"
PATTERN "*.osf"
)
install(DIRECTORY DESTINATION ${POLICYDIR}/site)

View file

@ -13,9 +13,9 @@
#include <net/if_arp.h>
#ifdef HAVE_NET_ETHERNET_H
#include <net/ethernet.h>
#elif HAVE_SYS_ETHERNET_H
#elif defined(HAVE_SYS_ETHERNET_H)
#include <sys/ethernet.h>
#elif HAVE_NETINET_IF_ETHER_H
#elif defined(HAVE_NETINET_IF_ETHER_H)
#include <netinet/if_ether.h>
#endif

View file

@ -113,10 +113,8 @@ const Analyzer::Config Analyzer::analyzer_configs[] = {
SMTP_Analyzer::Available, 0, false },
{ AnalyzerTag::SSH, "SSH", SSH_Analyzer::InstantiateAnalyzer,
SSH_Analyzer::Available, 0, false },
#ifdef USE_OPENSSL
{ AnalyzerTag::SSL, "SSL", SSLProxy_Analyzer::InstantiateAnalyzer,
SSLProxy_Analyzer::Available, 0, false },
#endif
{ AnalyzerTag::Telnet, "TELNET", Telnet_Analyzer::InstantiateAnalyzer,
Telnet_Analyzer::Available, 0, false },
@ -167,9 +165,7 @@ const Analyzer::Config Analyzer::analyzer_configs[] = {
{ AnalyzerTag::Contents_SMB, "CONTENTS_SMB", 0, 0, 0, false },
{ AnalyzerTag::Contents_RPC, "CONTENTS_RPC", 0, 0, 0, false },
{ AnalyzerTag::Contents_NFS, "CONTENTS_NFS", 0, 0, 0, false },
#ifdef USE_OPENSSL
{ AnalyzerTag::Contents_SSL, "CONTENTS_SSL", 0, 0, 0, false },
#endif
};
AnalyzerTimer::~AnalyzerTimer()

View file

@ -29,9 +29,7 @@ namespace AnalyzerTag {
DCE_RPC, DNS, Finger, FTP, Gnutella, HTTP, Ident, IRC,
Login, NCP, NetbiosSSN, NFS, NTP, POP3, Portmapper, Rlogin,
RPC, Rsh, SMB, SMTP, SSH,
#ifdef USE_OPENSSL
SSL,
#endif
Telnet,
// Application-layer analyzers, binpac-generated.
@ -45,9 +43,7 @@ namespace AnalyzerTag {
Contents, ContentLine, NVT, Zip, Contents_DNS, Contents_NCP,
Contents_NetbiosSSN, Contents_Rlogin, Contents_Rsh,
Contents_DCE_RPC, Contents_SMB, Contents_RPC, Contents_NFS,
#ifdef USE_OPENSSL
Contents_SSL,
#endif
// End-marker.
LastAnalyzer
};

View file

@ -8,13 +8,8 @@
#include <sys/types.h>
#include <regex.h>
#ifdef USE_INT64
# define FMT_INT "%lld"
# define FMT_UINT "%llu"
#else
# define FMT_INT "%d"
# define FMT_UINT "%u"
#endif
static TableType* bt_tracker_headers = 0;
static RecordType* bittorrent_peer;

399
src/CMakeLists.txt Normal file
View file

@ -0,0 +1,399 @@
include_directories(${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR}
)
configure_file(version.c.in ${CMAKE_CURRENT_BINARY_DIR}/version.c)
# This creates a custom command to transform a bison output file (inFile)
# into outFile in order to avoid symbol conflicts:
# - replaces instances of 'yylex' in inFile with yylexPrefix
# - replaces instances of 'yy' in inFile with yyPrefix
# - deletes instances of 'extern char.*getenv' in inFile
# - writes results to outFile and adds it to list TRANSFORMED_BISON_OUTPUTS
macro(REPLACE_YY_PREFIX_TARGET inFile outFile yylexPrefix yyPrefix)
set(args "'/extern char.*getenv/d")
set(args "${args}\;s/yylex/${yylexPrefix}lex/")
set(args "${args}\;s/yy/${yyPrefix}/g'" < ${inFile} > ${outFile})
add_custom_command(OUTPUT ${outFile}
COMMAND ${SED_EXE}
ARGS ${args}
DEPENDS ${inFile}
COMMENT "[sed] replacing stuff in ${inFile}"
)
list(APPEND TRANSFORMED_BISON_OUTPUTS ${outFile})
endmacro(REPLACE_YY_PREFIX_TARGET)
########################################################################
## Create targets to generate parser and scanner code
set(BISON_FLAGS "--debug")
# BIF parser/scanner
bison_target(BIFParser builtin-func.y
${CMAKE_CURRENT_BINARY_DIR}/bif_parse.cc
HEADER ${CMAKE_CURRENT_BINARY_DIR}/bif_parse.h
VERBOSE ${CMAKE_CURRENT_BINARY_DIR}/bif_parse.output
COMPILE_FLAGS "${BISON_FLAGS}")
flex_target(BIFScanner builtin-func.l ${CMAKE_CURRENT_BINARY_DIR}/bif_lex.cc)
add_flex_bison_dependency(BIFScanner BIFParser)
# Rule parser/scanner
bison_target(RuleParser rule-parse.y
${CMAKE_CURRENT_BINARY_DIR}/rup.cc
HEADER ${CMAKE_CURRENT_BINARY_DIR}/rup.h
VERBOSE ${CMAKE_CURRENT_BINARY_DIR}/rule_parse.output
COMPILE_FLAGS "${BISON_FLAGS}")
replace_yy_prefix_target(${CMAKE_CURRENT_BINARY_DIR}/rup.cc
${CMAKE_CURRENT_BINARY_DIR}/rule-parse.cc
rules_ rules_)
replace_yy_prefix_target(${CMAKE_CURRENT_BINARY_DIR}/rup.h
${CMAKE_CURRENT_BINARY_DIR}/rule-parse.h
rules_ rules_)
flex_target(RuleScanner rule-scan.l ${CMAKE_CURRENT_BINARY_DIR}/rule-scan.cc
COMPILE_FLAGS "-Prules_")
# RE parser/scanner
bison_target(REParser re-parse.y
${CMAKE_CURRENT_BINARY_DIR}/rep.cc
HEADER ${CMAKE_CURRENT_BINARY_DIR}/re-parse.h
VERBOSE ${CMAKE_CURRENT_BINARY_DIR}/re_parse.output
COMPILE_FLAGS "${BISON_FLAGS}")
replace_yy_prefix_target(${CMAKE_CURRENT_BINARY_DIR}/rep.cc
${CMAKE_CURRENT_BINARY_DIR}/re-parse.cc
re_ RE_)
flex_target(REScanner re-scan.l ${CMAKE_CURRENT_BINARY_DIR}/re-scan.cc
COMPILE_FLAGS "-Pre_")
add_flex_bison_dependency(REScanner REParser)
# Parser/Scanner
bison_target(Parser parse.y
${CMAKE_CURRENT_BINARY_DIR}/p.cc
HEADER ${CMAKE_CURRENT_BINARY_DIR}/broparse.h
VERBOSE ${CMAKE_CURRENT_BINARY_DIR}/parse.output
COMPILE_FLAGS "${BISON_FLAGS}")
replace_yy_prefix_target(${CMAKE_CURRENT_BINARY_DIR}/p.cc
${CMAKE_CURRENT_BINARY_DIR}/parse.cc
bro yy)
flex_target(Scanner scan.l ${CMAKE_CURRENT_BINARY_DIR}/scan.cc
COMPILE_FLAGS "-Pbro")
########################################################################
## bifcl (BIF compiler) target
set(bifcl_SRCS
${BISON_BIFParser_OUTPUTS}
${FLEX_BIFScanner_OUTPUTS}
bif_arg.cc
)
add_executable(bifcl ${bifcl_SRCS})
target_link_libraries(bifcl)
########################################################################
## bifcl-dependent targets
# A macro to define a command that uses the BIF compiler to produce
# C++ segments and Bro language declarations from .bif file
# The outputs are appended to list ALL_BIF_OUTPUTS
# Outputs that should be installed are appended to INSTALL_BIF_OUTPUTS
macro(BIF_TARGET bifInput)
get_bif_output_files(${bifInput} bifOutputs)
add_custom_command(OUTPUT ${bifOutputs}
COMMAND bifcl
ARGS ${CMAKE_CURRENT_SOURCE_DIR}/${bifInput}
DEPENDS ${bifInput}
COMMENT "[BIFCL] Processing ${bifInput}"
)
list(APPEND ALL_BIF_OUTPUTS ${bifOutputs})
list(APPEND INSTALL_BIF_OUTPUTS
${CMAKE_CURRENT_BINARY_DIR}/${bifInput}.bro)
endmacro(BIF_TARGET)
# returns a list of output files that bifcl will produce
# for given input file in ${outputFileVar}
macro(GET_BIF_OUTPUT_FILES inputFile outputFileVar)
set(${outputFileVar}
${inputFile}.bro
${inputFile}.func_def
${inputFile}.func_h
${inputFile}.func_init
${inputFile}.netvar_def
${inputFile}.netvar_h
${inputFile}.netvar_init
)
endmacro(GET_BIF_OUTPUT_FILES)
set(BIF_SRCS
bro.bif
event.bif
const.bif
common-rw.bif
finger-rw.bif
ident-rw.bif
dns-rw.bif
ftp-rw.bif
smtp-rw.bif
http-rw.bif
strings.bif
smb-rw.bif
)
foreach (bift ${BIF_SRCS})
bif_target(${bift})
endforeach ()
########################################################################
## BinPAC-dependent targets
set(BINPAC_AUXSRC
binpac.pac
bro.pac
binpac_bro.h
)
# A macro to define a command that uses the BinPac compiler to
# produce C++ code that implements a protocol parser/analyzer
# The outputs of the command are appended to list ALL_BINPAC_OUTPUTS
macro(BINPAC_TARGET pacFile)
get_filename_component(basename ${pacFile} NAME_WE)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${basename}_pac.h
${CMAKE_CURRENT_BINARY_DIR}/${basename}_pac.cc
COMMAND ${BinPAC_EXE}
ARGS -d ${CMAKE_CURRENT_BINARY_DIR}
-I ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/${pacFile}
DEPENDS ${BinPAC_EXE} ${pacFile}
${BINPAC_AUXSRC} ${ARGN}
COMMENT "[BINPAC] Processing ${pacFile}"
)
list(APPEND ALL_BINPAC_OUTPUTS
${CMAKE_CURRENT_BINARY_DIR}/${basename}_pac.h
${CMAKE_CURRENT_BINARY_DIR}/${basename}_pac.cc)
endmacro(BINPAC_TARGET)
binpac_target(binpac-lib.pac)
binpac_target(binpac_bro-lib.pac)
binpac_target(bittorrent.pac
bittorrent-protocol.pac bittorrent-analyzer.pac)
binpac_target(dce_rpc.pac
dce_rpc-protocol.pac dce_rpc-analyzer.pac)
binpac_target(dce_rpc_simple.pac
dce_rpc-protocol.pac)
binpac_target(dhcp.pac
dhcp-protocol.pac dhcp-analyzer.pac)
binpac_target(dns.pac
dns-protocol.pac dns-analyzer.pac)
binpac_target(dns_tcp.pac
dns.pac)
binpac_target(http.pac
http-protocol.pac http-analyzer.pac)
binpac_target(ncp.pac)
binpac_target(netflow.pac
netflow-protocol.pac netflow-analyzer.pac)
binpac_target(rpc.pac
rpc-analyzer.pac portmap-analyzer.pac)
binpac_target(smb.pac
smb-protocol.pac smb-pipe.pac smb-mailslot.pac)
binpac_target(ssl.pac
ssl-defs.pac ssl-protocol.pac ssl-analyzer.pac)
binpac_target(ssl-record-layer.pac
ssl-defs.pac ssl.pac)
########################################################################
## bro target
# define a command that's used to run the make_dbg_constants.pl script
# building the bro binary depends on the outputs of this script
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/DebugCmdConstants.h
${CMAKE_CURRENT_BINARY_DIR}/DebugCmdInfoConstants.cc
COMMAND ${PERL_EXECUTABLE}
ARGS ${CMAKE_CURRENT_SOURCE_DIR}/make_dbg_constants.pl
${CMAKE_CURRENT_SOURCE_DIR}/DebugCmdInfoConstants.in
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/make_dbg_constants.pl
${CMAKE_CURRENT_SOURCE_DIR}/DebugCmdInfoConstants.in
COMMENT "[Perl] Processing debug commands"
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
)
set(dns_SRCS nb_dns.c nb_dns.h)
set(openssl_SRCS X509.cc SSLCiphers.cc SSLInterpreter.cc SSLProxy.cc
SSLv2.cc SSLv3.cc SSLv3Automaton.cc)
if (USE_NMALLOC)
set(malloc_SRCS malloc.c)
endif ()
set(bro_SRCS
${CMAKE_CURRENT_BINARY_DIR}/version.c
${ALL_BIF_OUTPUTS}
${ALL_BINPAC_OUTPUTS}
${TRANSFORMED_BISON_OUTPUTS}
${FLEX_RuleScanner_OUTPUTS}
${FLEX_REScanner_OUTPUTS}
${FLEX_Scanner_OUTPUTS}
${CMAKE_CURRENT_BINARY_DIR}/DebugCmdConstants.h
main.cc
net_util.cc
util.cc
Active.cc
Analyzer.cc
Anon.cc
ARP.cc
Attr.cc
BackDoor.cc
Base64.cc
BitTorrent.cc
BitTorrentTracker.cc
BPF_Program.cc
BroString.cc
CCL.cc
ChunkedIO.cc
CompHash.cc
Conn.cc
ConnCompressor.cc
ContentLine.cc
DCE_RPC.cc
DFA.cc
DHCP-binpac.cc
DNS.cc
DNS-binpac.cc
DNS_Mgr.cc
DbgBreakpoint.cc
DbgHelp.cc
DbgWatch.cc
Debug.cc
DebugCmds.cc
DebugLogger.cc
Desc.cc
Dict.cc
Discard.cc
DPM.cc
EquivClass.cc
Event.cc
EventHandler.cc
EventLauncher.cc
EventRegistry.cc
Expr.cc
FTP.cc
File.cc
FileAnalyzer.cc
Finger.cc
FlowSrc.cc
Frag.cc
Frame.cc
Func.cc
Gnutella.cc
HTTP.cc
HTTP-binpac.cc
Hash.cc
ICMP.cc
ID.cc
Ident.cc
IntSet.cc
InterConn.cc
IOSource.cc
IRC.cc
List.cc
Logger.cc
Login.cc
MIME.cc
NCP.cc
NFA.cc
NFS.cc
NTP.cc
NVT.cc
Net.cc
NetVar.cc
NetbiosSSN.cc
Obj.cc
OSFinger.cc
PacketFilter.cc
PacketSort.cc
PersistenceSerializer.cc
PktSrc.cc
PIA.cc
PolicyFile.cc
POP3.cc
Portmap.cc
PrefixTable.cc
PriorityQueue.cc
Queue.cc
RE.cc
RPC.cc
Reassem.cc
RemoteSerializer.cc
Rlogin.cc
RSH.cc
Rule.cc
RuleAction.cc
RuleCondition.cc
RuleMatcher.cc
ScriptAnaly.cc
SmithWaterman.cc
SMB.cc
SMTP.cc
SSH.cc
SSL-binpac.cc
Scope.cc
SerializationFormat.cc
SerialObj.cc
Serializer.cc
Sessions.cc
StateAccess.cc
Stats.cc
SteppingStone.cc
Stmt.cc
TCP.cc
TCP_Endpoint.cc
TCP_Reassembler.cc
TCP_Rewriter.cc
Telnet.cc
Timer.cc
Traverse.cc
Trigger.cc
TwoWise.cc
Type.cc
UDP.cc
Val.cc
Var.cc
XDR.cc
ZIP.cc
bsd-getopt-long.c
cq.c
md5.c
patricia.c
setsignal.c
UDP_Rewriter.cc
DNS_Rewriter.cc
PacketDumper.cc
Rewriter.cc
strsep.c
${dns_SRCS}
${malloc_SRCS}
${openssl_SRCS}
)
add_definitions(-DPOLICYDEST="${POLICYDIR}")
add_executable(bro ${bro_SRCS})
set(brolibs
${BinPAC_LIBRARY}
${PCAP_LIBRARY}
${OpenSSL_LIBRARIES}
${BIND_LIBRARY}
${OPTLIBS}
)
include(ChangeMacInstallNames)
ChangeMacInstallNames(brolibs)
target_link_libraries(bro ${brolibs})
install(TARGETS bro DESTINATION bin)
install(FILES ${INSTALL_BIF_OUTPUTS} DESTINATION ${POLICYDIR})
set(BRO_EXE bro
CACHE STRING "Bro executable binary" FORCE)

View file

@ -7,6 +7,7 @@
#include <sys/time.h>
#include <netinet/in.h>
#include <assert.h>
#include <openssl/ssl.h>
#include "config.h"
#include "ChunkedIO.h"
@ -650,11 +651,6 @@ void ChunkedIOFd::Stats(char* buffer, int length)
ChunkedIO::Stats(buffer + i, length - i);
}
#ifdef USE_OPENSSL
#include <openssl/ssl.h>
SSL_CTX* ChunkedIOSSL::ctx;
ChunkedIOSSL::ChunkedIOSSL(int arg_socket, bool arg_server)
@ -1174,8 +1170,6 @@ void ChunkedIOSSL::Stats(char* buffer, int length)
ChunkedIO::Stats(buffer + i, length - i);
}
#endif /* USE_OPENSSL */
#ifdef HAVE_LIBZ
bool CompressedChunkedIO::Init()

View file

@ -11,6 +11,13 @@
#include <list>
#ifdef NEED_KRB5_H
# include <krb5.h>
#endif
#include <openssl/ssl.h>
#include <openssl/err.h>
class CompressedChunkedIO;
// #define DEBUG_COMMUNICATION 10
@ -214,17 +221,7 @@ private:
pid_t pid;
};
#ifdef USE_OPENSSL
#ifdef NEED_KRB5_H
# include <krb5.h>
#endif
#include <openssl/ssl.h>
#include <openssl/err.h>
// Chunked I/O using an SSL connection.
class ChunkedIOSSL : public ChunkedIO {
public:
// Argument is an open socket and a flag indicating whether we are the
@ -287,8 +284,6 @@ private:
static SSL_CTX* ctx;
};
#endif /* USE_OPENSSL */
#ifdef HAVE_LIBZ
#include <zlib.h>

View file

@ -6,11 +6,11 @@
#include <sys/types.h>
#include <sys/socket.h>
#if TIME_WITH_SYS_TIME
#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
@ -53,9 +53,7 @@ public:
const char* ReqHost() const { return host; }
uint32 ReqAddr() const { return addr; }
#ifdef HAVE_NB_DNS
int MakeRequest(nb_dns_info* nb_dns);
#endif
int RequestPending() const { return request_pending; }
void RequestDone() { request_pending = 0; }
@ -66,7 +64,6 @@ protected:
int request_pending;
};
#ifdef HAVE_NB_DNS
int DNS_Mgr_Request::MakeRequest(nb_dns_info* nb_dns)
{
if ( ! nb_dns )
@ -80,7 +77,6 @@ int DNS_Mgr_Request::MakeRequest(nb_dns_info* nb_dns)
else
return nb_dns_addr_request(nb_dns, addr, (void*) this, err) >= 0;
}
#endif
class DNS_Mapping {
public:
@ -350,13 +346,11 @@ DNS_Mgr::DNS_Mgr(DNS_MgrMode arg_mode)
host_mappings.SetDeleteFunc(DNS_Mgr_mapping_delete_func);
addr_mappings.SetDeleteFunc(DNS_Mgr_mapping_delete_func);
#ifdef HAVE_NB_DNS
char err[NB_DNS_ERRSIZE];
nb_dns = nb_dns_init(err);
if ( ! nb_dns )
warn(fmt("problem initializing NB-DNS: %s", err));
#endif
dns_mapping_valid = dns_mapping_unverified = dns_mapping_new_name =
dns_mapping_lost_name = dns_mapping_name_changed =
@ -372,10 +366,8 @@ DNS_Mgr::DNS_Mgr(DNS_MgrMode arg_mode)
DNS_Mgr::~DNS_Mgr()
{
#ifdef HAVE_NB_DNS
if ( nb_dns )
nb_dns_finish(nb_dns);
#endif
delete [] cache_name;
delete [] dir;
@ -410,14 +402,12 @@ bool DNS_Mgr::Init()
did_init = 1;
#ifdef HAVE_NB_DNS
io_sources.Register(this, true);
// We never set idle to false, having the main loop only calling us from
// time to time. If we're issuing more DNS requests than we can handle
// in this way, we are having problems anyway ...
idle = true;
#endif
return true;
}
@ -531,7 +521,6 @@ void DNS_Mgr::Resolve()
int i;
#ifdef HAVE_NB_DNS
int first_req = 0;
int num_pending = min(requests.length(), MAX_PENDING_REQUESTS);
int last_req = num_pending - 1;
@ -597,7 +586,6 @@ void DNS_Mgr::Resolve()
--num_pending;
}
}
#endif
// All done with the list of requests.
for ( i = requests.length() - 1; i >= 0; --i )
@ -860,7 +848,6 @@ TableVal* DNS_Mgr::LookupNameInCache(string name)
return d->AddrsSet();
}
#ifdef HAVE_NB_DNS
void DNS_Mgr::AsyncLookupAddr(dns_mgr_addr_type host, LookupCallback* callback)
{
if ( ! did_init )
@ -956,13 +943,10 @@ void DNS_Mgr::IssueAsyncRequests()
++asyncs_pending;
}
}
#endif
void DNS_Mgr::GetFds(int* read, int* write, int* except)
{
#ifdef HAVE_NB_DNS
*read = nb_dns_fd(nb_dns);
#endif
}
double DNS_Mgr::NextTimestamp(double* network_time)
@ -971,7 +955,6 @@ double DNS_Mgr::NextTimestamp(double* network_time)
return asyncs_timeouts.size() ? timer_mgr->Time() : -1.0;
}
#ifdef HAVE_NB_DNS
void DNS_Mgr::CheckAsyncAddrRequest(dns_mgr_addr_type addr, bool timeout)
{
// Note that this code is a mirror of that for CheckAsyncHostRequest.
@ -1030,13 +1013,9 @@ void DNS_Mgr::CheckAsyncHostRequest(const char* host, bool timeout)
// eventually times out.
}
}
#endif
void DNS_Mgr::Process()
{
#ifndef HAVE_NB_DNS
internal_error("DNS_Mgr::Process(): should never be reached");
#else
while ( asyncs_timeouts.size() > 0 )
{
@ -1084,9 +1063,8 @@ void DNS_Mgr::Process()
IssueAsyncRequests();
}
#endif
}
#ifdef HAVE_NB_DNS
int DNS_Mgr::AnswerAvailable(int timeout)
{
int fd = nb_dns_fd(nb_dns);
@ -1116,4 +1094,3 @@ int DNS_Mgr::AnswerAvailable(int timeout)
return status;
}
#endif

View file

@ -79,10 +79,8 @@ public:
virtual void Timeout() = 0;
};
#ifdef HAVE_NB_DNS
void AsyncLookupAddr(dns_mgr_addr_type host, LookupCallback* callback);
void AsyncLookupName(string name, LookupCallback* callback);
#endif
protected:
friend class LookupCallback;
@ -102,7 +100,6 @@ protected:
void LoadCache(FILE* f);
void Save(FILE* f, PDict(DNS_Mapping)& m);
#ifdef HAVE_NB_DNS
// Selects on the fd to see if there is an answer available (timeout is
// secs). Returns 0 on timeout, -1 on EINTR, and 1 if answer is ready.
int AnswerAvailable(int timeout);
@ -115,8 +112,6 @@ protected:
void CheckAsyncAddrRequest(dns_mgr_addr_type addr, bool timeout);
void CheckAsyncHostRequest(const char* host, bool timeout);
#endif
// IOSource interface.
virtual void GetFds(int* read, int* write, int* except);
virtual double NextTimestamp(double* network_time);

View file

@ -105,7 +105,6 @@ void ODesc::Add(uint32 u)
}
}
#ifdef USE_INT64
void ODesc::Add(int64 i)
{
if ( IsBinary() )
@ -129,7 +128,6 @@ void ODesc::Add(uint64 u)
Add(tmp);
}
}
#endif
void ODesc::Add(double d)
{

View file

@ -57,10 +57,8 @@ public:
void AddN(const char* s, int len) { AddBytes(s, len); }
void Add(int i);
void Add(uint32 u);
#ifdef USE_INT64
void Add(int64 i);
void Add(uint64 u);
#endif
void Add(double d);
// Add s as a counted string.

View file

@ -5,11 +5,11 @@
#include "config.h"
#include <sys/types.h>
#if TIME_WITH_SYS_TIME
#ifdef TIME_WITH_SYS_TIME
# include <sys/time.h>
# include <time.h>
#else
# if HAVE_SYS_TIME_H
# ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
# else
# include <time.h>
@ -233,10 +233,7 @@ BroFile::~BroFile()
delete [] name;
delete [] access;
#ifdef USE_OPENSSL
delete [] cipher_buffer;
#endif
#ifdef USE_PERFTOOLS
heap_checker->UnIgnoreObject(this);
@ -257,12 +254,9 @@ void BroFile::Init()
print_hook = true;
raw_output = false;
t = 0;
#ifdef USE_OPENSSL
pub_key = 0;
cipher_ctx = 0;
cipher_buffer = 0;
#endif
#ifdef USE_PERFTOOLS
heap_checker->IgnoreObject(this);
@ -348,9 +342,7 @@ int BroFile::Close()
if ( ! is_open )
return 1;
#ifdef USE_OPENSSL
FinishEncrypt();
#endif
// Do not close stdout/stderr.
if ( f == stdout || f == stderr )
@ -640,19 +632,6 @@ void BroFile::CloseCachedFiles()
}
}
#ifndef USE_OPENSSL
void BroFile::InitEncrypt(const char* keyfile)
{
if ( keyfile )
{
error("file encryption requested, but OpenSSL support not compiled in.");
Close();
}
}
#else
void BroFile::InitEncrypt(const char* keyfile)
{
if ( ! (pub_key || keyfile) )
@ -716,14 +695,12 @@ void BroFile::InitEncrypt(const char* keyfile)
int buf_size = MIN_BUFFER_SIZE + EVP_CIPHER_block_size(cipher_type);
cipher_buffer = new unsigned char[buf_size];
}
#endif
void BroFile::FinishEncrypt()
{
if ( ! is_open )
return;
#ifdef USE_OPENSSL
if ( ! pub_key )
return;
@ -742,7 +719,6 @@ void BroFile::FinishEncrypt()
delete cipher_ctx;
cipher_ctx = 0;
}
#endif
}
@ -757,7 +733,6 @@ int BroFile::Write(const char* data, int len)
if ( ! len )
len = strlen(data);
#ifdef USE_OPENSSL
if ( cipher_ctx )
{
while ( len )
@ -789,7 +764,6 @@ int BroFile::Write(const char* data, int len)
return 1;
}
#endif
len = fwrite(data, 1, len, f);
if ( len <= 0 )

View file

@ -10,7 +10,6 @@
#include "Obj.h"
#include "Attr.h"
#ifdef USE_OPENSSL
# ifdef NEED_KRB5_H
# include <krb5.h>
# endif // NEED_KRB5_H
@ -19,7 +18,6 @@ extern "C" {
# include "openssl/pem.h"
# include "openssl/err.h"
}
#endif
class BroType;
class RotateTimer;
@ -149,13 +147,11 @@ protected:
static double default_rotation_interval;
static double default_rotation_size;
#ifdef USE_OPENSSL
EVP_PKEY* pub_key;
EVP_CIPHER_CTX* cipher_ctx;
static const int MIN_BUFFER_SIZE = 1024;
unsigned char* cipher_buffer;
#endif
};

Some files were not shown because too many files have changed in this diff Show more