diff --git a/aux/binpac/AUTHORS b/aux/binpac/AUTHORS deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/aux/binpac/CHANGES b/aux/binpac/CHANGES deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/aux/binpac/COPYING b/aux/binpac/COPYING deleted file mode 100644 index 2a9a9e934b..0000000000 --- a/aux/binpac/COPYING +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) 1995-2007 -// 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. diff --git a/aux/binpac/ChangeLog b/aux/binpac/ChangeLog deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/aux/binpac/INSTALL b/aux/binpac/INSTALL deleted file mode 100644 index 095b1eb406..0000000000 --- a/aux/binpac/INSTALL +++ /dev/null @@ -1,231 +0,0 @@ -Installation Instructions -************************* - -Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004 Free -Software Foundation, Inc. - -This file is free documentation; the Free Software Foundation gives -unlimited permission to copy, distribute and modify it. - -Basic Installation -================== - -These are generic installation instructions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, and a -file `config.log' containing compiler output (useful mainly for -debugging `configure'). - - It can also use an optional file (typically called `config.cache' -and enabled with `--cache-file=config.cache' or simply `-C') that saves -the results of its tests to speed up reconfiguring. (Caching is -disabled by default to prevent problems with accidental use of stale -cache files.) - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If you are using the cache, and at -some point `config.cache' contains results you don't want to keep, you -may remove or edit it. - - The file `configure.ac' (or `configure.in') is used to create -`configure' by a program called `autoconf'. You only need -`configure.ac' if you want to change it or regenerate `configure' using -a newer version of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. - - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - -Compilers and Options -===================== - -Some systems require unusual options for compilation or linking that the -`configure' script does not know about. Run `./configure --help' for -details on some of the pertinent environment variables. - - You can give `configure' initial values for configuration parameters -by setting variables in the command line or in the environment. Here -is an example: - - ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix - - *Note Defining Variables::, for more details. - -Compiling For Multiple Architectures -==================================== - -You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - If you have to use a `make' that does not support the `VPATH' -variable, you have to compile the package for one architecture at a -time in the source code directory. After you have installed the -package for one architecture, use `make distclean' before reconfiguring -for another architecture. - -Installation Names -================== - -By default, `make install' will install the package's files in -`/usr/local/bin', `/usr/local/man', etc. You can specify an -installation prefix other than `/usr/local' by giving `configure' the -option `--prefix=PREFIX'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -give `configure' the option `--exec-prefix=PREFIX', the package will -use PREFIX as the prefix for installing programs and libraries. -Documentation and other data files will still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=DIR' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - -Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - -There may be some features `configure' cannot figure out automatically, -but needs to determine by the type of machine the package will run on. -Usually, assuming the package is built to be run on the _same_ -architectures, `configure' can figure that out, but if it prints a -message saying it cannot guess the machine type, give it the -`--build=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name which has the form: - - CPU-COMPANY-SYSTEM - -where SYSTEM can have one of these forms: - - OS KERNEL-OS - - See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the machine type. - - If you are _building_ compiler tools for cross-compiling, you should -use the `--target=TYPE' option to select the type of system they will -produce code for. - - If you want to _use_ a cross compiler, that generates code for a -platform different from the build platform, you should specify the -"host" platform (i.e., that on which the generated programs will -eventually be run) with `--host=TYPE'. - -Sharing Defaults -================ - -If you want to set default values for `configure' scripts to share, you -can create a site shell script called `config.site' that gives default -values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Defining Variables -================== - -Variables not defined in a site shell script can be set in the -environment passed to `configure'. However, some packages may run -configure again during the build, and the customized values of these -variables may be lost. In order to avoid this problem, you should set -them in the `configure' command line, using `VAR=value'. For example: - - ./configure CC=/usr/local2/bin/gcc - -will cause the specified gcc to be used as the C compiler (unless it is -overridden in the site shell script). - -`configure' Invocation -====================== - -`configure' recognizes the following options to control how it operates. - -`--help' -`-h' - Print a summary of the options to `configure', and exit. - -`--version' -`-V' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`--cache-file=FILE' - Enable the cache: use and save the results of the tests in FILE, - traditionally `config.cache'. FILE defaults to `/dev/null' to - disable caching. - -`--config-cache' -`-C' - Alias for `--cache-file=config.cache'. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`configure' also accepts some other, not widely useful, options. Run -`configure --help' for more details. - diff --git a/aux/binpac/Makefile.am b/aux/binpac/Makefile.am deleted file mode 100644 index 7c93dcde5c..0000000000 --- a/aux/binpac/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -## Process this file with automake to produce Makefile.in - -EXTRA_DIST = README VERSION CHANGES TODO depcomp shtool autogen.sh -SUBDIRS = lib src diff --git a/aux/binpac/NEWS b/aux/binpac/NEWS deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/aux/binpac/README b/aux/binpac/README deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/aux/binpac/TODO b/aux/binpac/TODO deleted file mode 100644 index 4b2833f224..0000000000 --- a/aux/binpac/TODO +++ /dev/null @@ -1,34 +0,0 @@ -Big features -* Variable context (xid, call in RPC)? -- no variable context -* Helpers -* Connection states and actions -* Case and analyzer redef -* &also withinput -* Explicit analyzer context (interface + instantiation) "withcontext" -+ Interface with C++ and Bro (events, extern, weird) -+ Incremental input -+ ASCII protocols -+ Reassembly -- Dealing with exceptions -- Dependency analysis to save parsing time on unused fields -- Performance measurement - -Small features -* Restructure the code: break up pac.{h,cc} -* ref counting (to keep certain structures) -* analyzer context as a parameter of class -* &autolength -* find a better name for "analyzer_context" ("analcxt", "context", "analyzer") $context -* &if -* &autolength (now &restofdata) -* Use vector<> instead of array<>? -* set end_of_data when &length = ... -- make the `default' case mandatory? -- &inline -- &warn and &check? (follow &if) -- typedef? - -Binpac 1 -- create a namespace for each .pac file -- type equivalence -- byteorder() for every type? diff --git a/aux/binpac/VERSION b/aux/binpac/VERSION deleted file mode 100644 index 49d59571fb..0000000000 --- a/aux/binpac/VERSION +++ /dev/null @@ -1 +0,0 @@ -0.1 diff --git a/aux/binpac/autogen.sh b/aux/binpac/autogen.sh deleted file mode 100755 index 4f01b6fbf2..0000000000 --- a/aux/binpac/autogen.sh +++ /dev/null @@ -1,114 +0,0 @@ -#!/bin/sh - -# Initialization script to set up the initial configuration files etc. -# shtool usage inspired by the autogen script of the ferite scripting -# language -- cheers Chris :) -# -# This is 'borrowed' from netdude, with minor changes for bro - -BLD_ON=`./shtool echo -n -e %B` -BLD_OFF=`./shtool echo -n -e %b` - -srcdir=`dirname $0` -NAME=binpac - -DIE=0 - -echo -echo " "${BLD_ON}"Binpac Build Tools Setup"${BLD_OFF} -echo "====================================================" -echo -echo "Checking whether we have all tools available ..." - -(autoconf --version) < /dev/null > /dev/null 2>&1 || { - echo - echo ${BLD_ON}"Error"${BLD_OFF}": You must have \`autoconf' installed to." - echo "Download the appropriate package for your distribution," - echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" - DIE=1 -} - -(automake --version) < /dev/null > /dev/null 2>&1 || { - echo - echo ${BLD_ON}"Error"${BLD_OFF}": You must have \`automake' installed." - echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz" - echo "(or a newer version if it is available)" - DIE=1 - NO_AUTOMAKE=yes -} - -# if no automake, don't bother testing for aclocal -test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || { - echo - echo ${BLD_ON}"Error"${BLD_OFF}": Missing \`aclocal'. The version of \`automake'" - echo "installed doesn't appear recent enough." - echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz" - echo "(or a newer version if it is available)" - DIE=1 -} - -if test "$DIE" -eq 1; then - exit 1 -fi - -echo "All necessary tools found." -echo - -if [ -d autom4te.cache ] ; then - echo "Removing autom4te.cache ..." - rm -rf autom4te.cache - #echo - #echo ${BLD_ON}"Error"${BLD_OFF}": autom4te.cache directory exists" - #echo "please remove it, and rerun this script" - #echo - #exit 1 -fi - -echo -echo "running "${BLD_ON}"aclocal"${BLD_OFF} -echo "----------------------------------------------------" -aclocal -I . $ACLOCAL_FLAGS -if [ $? -ne 0 ]; then - echo "*** ERROR($NAME), aborting." - exit 1 -fi - -echo -echo "running "${BLD_ON}"autoheader"${BLD_OFF} -echo "----------------------------------------------------" -autoheader -if [ $? -ne 0 ]; then - echo "*** ERROR($NAME), aborting." - exit 1 -fi - -echo -echo "running "${BLD_ON}"automake"${BLD_OFF} -echo "----------------------------------------------------" -automake -a -c -if [ $? -ne 0 ]; then - echo "*** ERROR($NAME), aborting." - exit 1 -fi - -echo -echo "running "${BLD_ON}"autoconf"${BLD_OFF} -echo "----------------------------------------------------" -autoconf -if [ $? -ne 0 ]; then - echo "*** ERROR($NAME), aborting." - exit 1 -fi - -if ! test "x$BROBUILD" = xyes; then -echo -echo "Setup finished. Now run:" -echo -echo " $ "${BLD_ON}"./configure"${BLD_OFF}" (with options as needed, try --help)" -echo -echo "and then" -echo -echo " $ "${BLD_ON}"make"${BLD_OFF} -echo " # "${BLD_ON}"make install"${BLD_OFF} -echo -fi diff --git a/aux/binpac/configure.in b/aux/binpac/configure.in deleted file mode 100644 index e4d4c3074a..0000000000 --- a/aux/binpac/configure.in +++ /dev/null @@ -1,55 +0,0 @@ -AC_INIT -AC_CONFIG_SRCDIR([src/pac_main.cc]) - -AC_CANONICAL_SYSTEM - -AC_CONFIG_AUX_DIR(.) -AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(binpac, esyscmd([tr -d '\n' < VERSION])) - -dnl Commands for funkier shell output: -BLD_ON=`./shtool echo -n -e %B` -BLD_OFF=`./shtool echo -n -e %b` - -dnl ################################################ -dnl # Checks for programs -dnl ################################################ -AM_PROG_LEX -AC_PROG_YACC -AC_PROG_CXX -AC_PROG_RANLIB -AC_PROG_INSTALL - -m4_ifdef([AC_COMPUTE_INT], [], [AC_DEFUN([AC_COMPUTE_INT], [_AC_COMPUTE_INT([$2],[$1],[$3],[$4])])]) - -AC_COMPUTE_INT([SIZEOF_UNSIGNED_INT], [sizeof(unsigned int)]) -AC_SUBST(SIZEOF_UNSIGNED_INT) - -AC_ARG_ENABLE(debug, - [ --enable-debug no compiler optimizations], - debug="yes" - CFLAGS="-DDEBUG `echo $CFLAGS | sed -e 's/-O2//'`" - CXXFLAGS="-DDEBUG `echo $CXXFLAGS | sed -e 's/-O2//'`", - debug="no") - -AC_C_BIGENDIAN( - AC_DEFINE(WORDS_BIGENDIAN,1,[whether words are stored with the most significant byte first]) - dnl This is intentionally named differently so as to not collide with WORDS_BIGENDIAN - HOST_BIGENDIAN="#define HOST_BIGENDIAN 1" - AC_SUBST(HOST_BIGENDIAN)) - -AC_CONFIG_FILES([ -Makefile -src/Makefile -lib/Makefile -lib/binpac.h -]) -AC_OUTPUT - -echo -echo " "${BLD_ON}"Binpac Configuration Summary"${BLD_OFF} -echo "==========================================================" -echo -echo " - Debugging enabled: "${BLD_ON}$debug${BLD_OFF} -echo -exit 0 diff --git a/aux/binpac/lib/Makefile.am b/aux/binpac/lib/Makefile.am deleted file mode 100644 index 7ff8dca88f..0000000000 --- a/aux/binpac/lib/Makefile.am +++ /dev/null @@ -1,8 +0,0 @@ -## Process this file with automake to produce Makefile.in - -noinst_LIBRARIES = libbinpac.a - -libbinpac_a_SOURCES = \ - binpac_buffer.cc binpac_bytestring.cc \ - binpac.h binpac_analyzer.h binpac_buffer.h \ - binpac_bytestring.h binpac_exception.h binpac_regex.h diff --git a/aux/binpac/lib/README b/aux/binpac/lib/README deleted file mode 100644 index c57ca2ebab..0000000000 --- a/aux/binpac/lib/README +++ /dev/null @@ -1,3 +0,0 @@ -This directory contains a library needed by generated C++ code from -binpac. Note that the library is not needed by the binpac compiler -itself. diff --git a/aux/binpac/lib/binpac.h.in b/aux/binpac/lib/binpac.h.in deleted file mode 100644 index 920a699409..0000000000 --- a/aux/binpac/lib/binpac.h.in +++ /dev/null @@ -1,142 +0,0 @@ -// $Id: binpac.h,v 1.1.4.2 2006/06/02 15:13:13 rpang Exp $ -// Do not edit binpac.h, edit binpac.h.in instead! - -#ifndef binpac_h -#define binpac_h - -#include - -@HOST_BIGENDIAN@ -#ifdef HOST_BIGENDIAN -# define HOST_BYTEORDER bigendian -#else -# define HOST_BYTEORDER littleendian -#endif - -#include -#include -#include -#include -#include - -#define BINPAC_ASSERT(x) assert(x) - -using namespace std; - -namespace binpac { - -const int bigendian = 0; -const int littleendian = 1; -const int unspecified_byteorder = -1; - -#ifndef pac_type_defs -#define pac_type_defs - -typedef char int8; -typedef short int16; -typedef long int32; -typedef unsigned char uint8; -typedef unsigned short uint16; -typedef unsigned int uint32; -typedef void *nullptr; -typedef void *voidptr; -typedef uint8 *byteptr; -typedef const uint8 *const_byteptr; -typedef const char *const_charptr; - -#if @SIZEOF_UNSIGNED_INT@ != 4 -#error "unexpected size of unsigned int" -#endif - -#endif /* pac_type_defs */ - -/* Handling byte order */ - -namespace { - -inline int16 pac_swap(int16 x) - { - return (x >> 8) | ((x & 0xff) << 8); - } - -inline uint16 pac_swap(uint16 x) - { - return (x >> 8) | ((x & 0xff) << 8); - } - -inline int32 pac_swap(int32 x) - { - return (x >> 24) | - ((x & 0xff0000) >> 8) | - ((x & 0xff00) << 8) | - ((x & 0xff) << 24); - } - -inline uint32 pac_swap(uint32 x) - { - return (x >> 24) | - ((x & 0xff0000) >> 8) | - ((x & 0xff00) << 8) | - ((x & 0xff) << 24); - } - -#define FixByteOrder(byteorder, x) (byteorder == HOST_BYTEORDER ? (x) : pac_swap(x)) - -template -inline T UnMarshall(const u_char *data, int byteorder) - { - T result = 0; - for ( int i = 0; i < (int) sizeof(T); ++i ) - result = ( result << 8 ) | - data[byteorder == bigendian ? i : sizeof(T) - 1 - i]; - return result; - } - -inline const char* do_fmt(const char* format, va_list ap) - { - static char buf[1024]; - vsnprintf(buf, sizeof(buf), format, ap); - return buf; - } - -inline string strfmt(const char* format, ...) - { - va_list ap; - va_start(ap, format); - const char* r = do_fmt(format, ap); - va_end(ap); - return string(r); - } - -} // anonymous namespace - -#define binpac_fmt(x...) strfmt(x).c_str() - -class RefCount -{ -public: - RefCount() { count = 1; } - void Ref() { ++count; } - int Unref() { BINPAC_ASSERT(count > 0); return --count; } - -private: - int count; -}; - -namespace { - inline void Unref(RefCount *x) - { - if ( x && x->Unref() <= 0 ) - delete x; - } -} // anonymous namespace - -} // namespace binpac - -#include "binpac_analyzer.h" -#include "binpac_buffer.h" -#include "binpac_bytestring.h" -#include "binpac_exception.h" -#include "binpac_regex.h" - -#endif /* binpac_h */ diff --git a/aux/binpac/lib/binpac_analyzer.h b/aux/binpac/lib/binpac_analyzer.h deleted file mode 100644 index b9228da5de..0000000000 --- a/aux/binpac/lib/binpac_analyzer.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef binpac_an_h -#define binpac_an_h - -namespace binpac { - -// TODO: Add the Done() function - -// The interface for a connection analyzer -class ConnectionAnalyzer { -public: - virtual ~ConnectionAnalyzer() {} - virtual void NewData(bool is_orig, - const u_char *begin_of_data, - const u_char *end_of_data) = 0; -}; - -// The interface for a flow analyzer -class FlowAnalyzer { -public: - virtual ~FlowAnalyzer() {} - virtual void NewData(const u_char *begin_of_data, - const u_char *end_of_data) = 0; -}; - -} // namespace binpac - -#endif // binpac_an_h diff --git a/aux/binpac/lib/binpac_buffer.cc b/aux/binpac/lib/binpac_buffer.cc deleted file mode 100644 index 1b12b58eab..0000000000 --- a/aux/binpac/lib/binpac_buffer.cc +++ /dev/null @@ -1,465 +0,0 @@ -#include -#include -#include // for memcpy - -#define binpac_regex_h - -#include "binpac.h" -#include "binpac_buffer.h" - -namespace binpac { - -extern double network_time(); - -namespace { - const u_char CR = '\r'; - const u_char LF = '\n'; -} - -FlowBuffer::FlowBuffer(LineBreakStyle linebreak_style) - { - buffer_length_ = 0; - buffer_ = 0; - - orig_data_begin_ = 0; - orig_data_end_ = 0; - - linebreak_style_ = linebreak_style; - ResetLineState(); - - mode_ = UNKNOWN_MODE; - frame_length_ = 0; - chunked_ = false; - - data_seq_at_orig_data_end_ = 0; - eof_ = false; - have_pending_request_ = false; - - buffer_n_ = 0; - - NewMessage(); - } - -FlowBuffer::~FlowBuffer() - { - if ( buffer_ ) - free(buffer_); - } - -void FlowBuffer::NewMessage() - { - BINPAC_ASSERT(frame_length_ >= 0); - - int bytes_to_advance = 0; - if ( buffer_n_ == 0 ) - { - switch ( mode_ ) - { - case LINE_MODE: - bytes_to_advance = (frame_length_ + - (linebreak_style_ == STRICT_CRLF ? - 2 : 1)); - break; - case FRAME_MODE: - bytes_to_advance = frame_length_; - break; - case UNKNOWN_MODE: - break; - } - } - - orig_data_begin_ += bytes_to_advance; - BINPAC_ASSERT(orig_data_begin_ <= orig_data_end_); - - buffer_n_ = 0; - message_complete_ = false; - } - -void FlowBuffer::ResetLineState() - { - switch ( linebreak_style_ ) - { - case CR_OR_LF: - state_ = CR_OR_LF_0; - break; - case STRICT_CRLF: - state_ = STRICT_CRLF_0; - break; - default: - BINPAC_ASSERT(0); - break; - } - } - -void FlowBuffer::ExpandBuffer(int length) - { - if ( buffer_length_ >= length ) - return; - // So length > 0 - if ( length < 512 ) - length = 512; - - if ( length < buffer_length_ * 2 ) - length = buffer_length_ * 2; - - // Allocate a new buffer and copy the existing contents - buffer_length_ = length; - u_char *new_buf = (u_char *) realloc(buffer_, buffer_length_); - BINPAC_ASSERT(new_buf); -#if 0 - u_char* new_buf = new u_char[buffer_length_]; - if ( buffer_ && buffer_n_ > 0 ) - memcpy(new_buf, buffer_, buffer_n_); - delete [] buffer_; -#endif - buffer_ = new_buf; - } - -void FlowBuffer::NewLine() - { - FlowBuffer::NewMessage(); - mode_ = LINE_MODE; - frame_length_ = 0; - chunked_ = false; - have_pending_request_ = true; - if ( state_ == FRAME_0 ) - ResetLineState(); - MarkOrCopyLine(); - } - -void FlowBuffer::NewFrame(int frame_length, bool chunked) - { - FlowBuffer::NewMessage(); - mode_ = FRAME_MODE; - frame_length_ = frame_length; - chunked_ = chunked; - have_pending_request_ = true; - MarkOrCopyFrame(); - } - -void FlowBuffer::GrowFrame(int length) - { - BINPAC_ASSERT(frame_length_ >= 0); - if ( length <= frame_length_ ) - return; - BINPAC_ASSERT(! chunked_ || frame_length_ == 0); - mode_ = FRAME_MODE; - frame_length_ = length; - MarkOrCopyFrame(); - } - -void FlowBuffer::DiscardData() - { - mode_ = UNKNOWN_MODE; - message_complete_ = false; - have_pending_request_ = false; - orig_data_begin_ = orig_data_end_ = 0; - - buffer_n_ = 0; - frame_length_ = 0; - } - -void FlowBuffer::set_eof() - { - // fprintf(stderr, "EOF\n"); - eof_ = true; - if ( chunked_ ) - frame_length_ = orig_data_end_ - orig_data_begin_; - if ( frame_length_ < 0 ) - frame_length_ = 0; - } - -void FlowBuffer::NewData(const_byteptr begin, const_byteptr end) - { - BINPAC_ASSERT(begin <= end); - - ClearPreviousData(); - - BINPAC_ASSERT((buffer_n_ == 0 && message_complete_) || - orig_data_begin_ == orig_data_end_); - - orig_data_begin_ = begin; - orig_data_end_ = end; - data_seq_at_orig_data_end_ += (end - begin); - - MarkOrCopy(); - } - -void FlowBuffer::MarkOrCopy() - { - if ( ! message_complete_ ) - { - switch ( mode_ ) - { - case LINE_MODE: - MarkOrCopyLine(); - break; - - case FRAME_MODE: - MarkOrCopyFrame(); - break; - - default: - break; - } - } - } - -void FlowBuffer::ClearPreviousData() - { - // All previous data must have been processed or buffered already - if ( orig_data_begin_ < orig_data_end_ ) - { - BINPAC_ASSERT(buffer_n_ == 0); - if ( chunked_ ) - { - if ( frame_length_ > 0 ) - { - frame_length_ -= - (orig_data_end_ - orig_data_begin_); - } - orig_data_begin_ = orig_data_end_; - } - } - } - -void FlowBuffer::NewGap(int length) - { - ClearPreviousData(); - - if ( chunked_ && frame_length_ >= 0 ) - { - frame_length_ -= length; - if ( frame_length_ < 0 ) - frame_length_ = 0; - } - - orig_data_begin_ = orig_data_end_ = 0; - MarkOrCopy(); - } - -void FlowBuffer::MarkOrCopyLine() - { - switch ( linebreak_style_ ) - { - case CR_OR_LF: - MarkOrCopyLine_CR_OR_LF(); - break; - case STRICT_CRLF: - MarkOrCopyLine_STRICT_CRLF(); - break; - default: - BINPAC_ASSERT(0); - break; - } - } - -/* -Finite state automaton for CR_OR_LF: -(!--line is complete, *--add to buffer) - -CR_OR_LF_0: - CR: CR_OR_LF_1 ! - LF: CR_OR_LF_0 ! - .: CR_OR_LF_0 * - -CR_OR_LF_1: - CR: CR_OR_LF_1 ! - LF: CR_OR_LF_0 - .: CR_OR_LF_0 * -*/ - -void FlowBuffer::MarkOrCopyLine_CR_OR_LF() - { - if ( state_ == CR_OR_LF_1 && - orig_data_begin_ < orig_data_end_ && *orig_data_begin_ == LF ) - { - state_ = CR_OR_LF_0; - ++orig_data_begin_; - } - - const_byteptr data; - for ( data = orig_data_begin_; data < orig_data_end_; ++data ) - { - switch ( *data ) - { - case CR: - state_ = CR_OR_LF_1; - goto found_end_of_line; - - case LF: - // state_ = CR_OR_LF_0; - goto found_end_of_line; - - default: - // state_ = CR_OR_LF_0; - break; - } - } - - AppendToBuffer(orig_data_begin_, orig_data_end_ - orig_data_begin_); - return; - -found_end_of_line: - if ( buffer_n_ == 0 ) - { - frame_length_ = data - orig_data_begin_; - } - else - { - AppendToBuffer(orig_data_begin_, data + 1 - orig_data_begin_); - // But eliminate the last CR or LF - --buffer_n_; - } - message_complete_ = true; - -#if DEBUG_FLOW_BUFFER - fprintf(stderr, "%.6f Line complete: [%s]\n", - network_time(), - string((const char *) begin(), (const char *) end()).c_str()); -#endif - } - -/* -Finite state automaton and STRICT_CRLF: -(!--line is complete, *--add to buffer) - -STRICT_CRLF_0: - CR: STRICT_CRLF_1 * - LF: STRICT_CRLF_0 * - .: STRICT_CRLF_0 * - -STRICT_CRLF_1: - CR: STRICT_CRLF_1 * - LF: STRICT_CRLF_0 ! (--buffer_n_) - .: STRICT_CRLF_0 * -*/ - -void FlowBuffer::MarkOrCopyLine_STRICT_CRLF() - { - const_byteptr data; - for ( data = orig_data_begin_; data < orig_data_end_; ++data ) - { - switch ( *data ) - { - case CR: - state_ = STRICT_CRLF_1; - break; - - case LF: - if ( state_ == STRICT_CRLF_1 ) - { - state_ = STRICT_CRLF_0; - goto found_end_of_line; - } - break; - - default: - state_ = STRICT_CRLF_0; - break; - } - } - - AppendToBuffer(orig_data_begin_, orig_data_end_ - orig_data_begin_); - return; - -found_end_of_line: - if ( buffer_n_ == 0 ) - { - frame_length_ = data - 1 - orig_data_begin_; - } - else - { - AppendToBuffer(orig_data_begin_, data + 1 - orig_data_begin_); - // Pop the preceding CR and LF from the buffer - buffer_n_ -= 2; - } - - message_complete_ = true; - -#if DEBUG_FLOW_BUFFER - fprintf(stderr, "%.6f Line complete: [%s]\n", - network_time(), - string((const char *) begin(), (const char *) end()).c_str()); -#endif - } - -// Invariants: -// -// When buffer_n_ == 0: -// Frame = [orig_data_begin_..(orig_data_begin_ + frame_length_)] -// -// When buffer_n_ > 0: -// Frame = [0..buffer_n_][orig_data_begin_..] - -void FlowBuffer::MarkOrCopyFrame() - { - if ( mode_ == FRAME_MODE && state_ == CR_OR_LF_1 && - orig_data_begin_ < orig_data_end_ ) - { - // Skip the lingering LF - if ( *orig_data_begin_ == LF ) - { - ++orig_data_begin_; - } - state_ = FRAME_0; - } - - if ( buffer_n_ == 0 ) - { - // If there is enough data - if ( frame_length_ >= 0 && - orig_data_end_ - orig_data_begin_ >= frame_length_ ) - { - // Do nothing except setting the message complete flag - message_complete_ = true; - } - else - { - if ( ! chunked_ ) - { - AppendToBuffer(orig_data_begin_, - orig_data_end_ - orig_data_begin_); - } - message_complete_ = false; - } - } - else - { - BINPAC_ASSERT(!chunked_); - int bytes_to_copy = orig_data_end_ - orig_data_begin_; - message_complete_ = false; - if ( frame_length_ >= 0 && buffer_n_ + bytes_to_copy >= frame_length_ ) - { - bytes_to_copy = frame_length_ - buffer_n_; - message_complete_ = true; - } - AppendToBuffer(orig_data_begin_, bytes_to_copy); - } - -#if DEBUG_FLOW_BUFFER - if ( message_complete_ ) - { - fprintf(stderr, "%.6f frame complete: [%s]\n", - network_time(), - string((const char *) begin(), - (const char *) end()).c_str()); - } -#endif - } - -void FlowBuffer::AppendToBuffer(const_byteptr data, int len) - { - if ( len <= 0 ) - return; - - BINPAC_ASSERT(! chunked_); - ExpandBuffer(buffer_n_ + len); - memcpy(buffer_ + buffer_n_, data, len); - buffer_n_ += len; - - orig_data_begin_ += len; - BINPAC_ASSERT(orig_data_begin_ <= orig_data_end_); - } - -} // namespace binpac diff --git a/aux/binpac/lib/binpac_buffer.h b/aux/binpac/lib/binpac_buffer.h deleted file mode 100644 index 2eb197e7b9..0000000000 --- a/aux/binpac/lib/binpac_buffer.h +++ /dev/null @@ -1,148 +0,0 @@ -#ifndef binpac_buffer_h -#define binpac_buffer_h - -#include -#include "binpac.h" - -namespace binpac { - -class FlowBuffer { -public: - enum LineBreakStyle { - CR_OR_LF, // CR or LF or CRLF - STRICT_CRLF, // CR followed by LF - CR_LF_NUL, // CR or LF or CR-LF or CR-NUL - }; - - FlowBuffer(LineBreakStyle linebreak_style = CR_OR_LF); - virtual ~FlowBuffer(); - - void NewData(const_byteptr begin, const_byteptr end); - void NewGap(int length); - - // Discard unprocessed data - void DiscardData(); - - // Whether there is enough data for the frame - bool ready() const{ return message_complete_ || mode_ == UNKNOWN_MODE; } - - inline const_byteptr begin() const - { - BINPAC_ASSERT(ready()); - return ( buffer_n_ == 0 ) ? - orig_data_begin_ : buffer_; - } - - inline const_byteptr end() const - { - BINPAC_ASSERT(ready()); - if ( buffer_n_ == 0 ) - { - BINPAC_ASSERT(frame_length_ >= 0); - const_byteptr end = orig_data_begin_ + frame_length_; - BINPAC_ASSERT(end <= orig_data_end_); - return end; - } - else - return buffer_ + buffer_n_; - } - - inline int data_length() const - { - if ( buffer_n_ > 0 ) - return buffer_n_; - - if ( frame_length_ < 0 || - orig_data_begin_ + frame_length_ > orig_data_end_ ) - return orig_data_end_ - orig_data_begin_; - else - return frame_length_; - } - - inline bool data_available() const - { - return buffer_n_ > 0 || orig_data_end_ > orig_data_begin_; - } - - void NewLine(); - // A negative frame_length represents a frame till EOF - void NewFrame(int frame_length, bool chunked_); - void GrowFrame(int new_frame_length); - - int data_seq() const - { - int data_seq_at_orig_data_begin = - data_seq_at_orig_data_end_ - - (orig_data_end_ - orig_data_begin_); - if ( buffer_n_ > 0 ) - return data_seq_at_orig_data_begin; - else - return data_seq_at_orig_data_begin + data_length(); - } - bool eof() const { return eof_; } - void set_eof(); - - bool have_pending_request() const { return have_pending_request_; } - -protected: - // Reset the buffer for a new message - void NewMessage(); - - void ClearPreviousData(); - - // Expand the buffer to at least bytes. If there - // are contents in the existing buffer, copy them to the new - // buffer. - void ExpandBuffer(int length); - - // Reset line state when transit from frame mode to line mode. - void ResetLineState(); - - void AppendToBuffer(const_byteptr data, int len); - - // MarkOrCopy{Line,Frame} sets message_complete_ and - // marks begin/end pointers if a line/frame is complete, - // otherwise it clears message_complete_ and copies all - // the original data to the buffer. - // - void MarkOrCopy(); - void MarkOrCopyLine(); - void MarkOrCopyFrame(); - - void MarkOrCopyLine_CR_OR_LF(); - void MarkOrCopyLine_STRICT_CRLF(); - - int buffer_n_; // number of bytes in the buffer - int buffer_length_; // size of the buffer - u_char *buffer_; - bool message_complete_; - int frame_length_; - bool chunked_; - const_byteptr orig_data_begin_, orig_data_end_; - - LineBreakStyle linebreak_style_; - - enum { - UNKNOWN_MODE, - LINE_MODE, - FRAME_MODE, - } mode_; - - enum { - CR_OR_LF_0, - CR_OR_LF_1, - STRICT_CRLF_0, - STRICT_CRLF_1, - FRAME_0, - } state_; - - int data_seq_at_orig_data_end_; - bool eof_; - bool have_pending_request_; -}; - -typedef FlowBuffer *flow_buffer_t; - -} // namespace binpac - -#endif // binpac_buffer_h diff --git a/aux/binpac/lib/binpac_bytestring.cc b/aux/binpac/lib/binpac_bytestring.cc deleted file mode 100644 index b74fe369b1..0000000000 --- a/aux/binpac/lib/binpac_bytestring.cc +++ /dev/null @@ -1,24 +0,0 @@ -#define binpac_regex_h - -#include -#include "binpac_bytestring.h" - -namespace binpac -{ - -std::string std_string(bytestring const *s) - { - return std::string((const char *) s->begin(), (const char *) s->end()); - } - -int bytestring_to_int(bytestring const *s) - { - return atoi((const char *) s->begin()); - } - -double bytestring_to_double(bytestring const *s) - { - return atof((const char *) s->begin()); - } - -} // namespace binpac diff --git a/aux/binpac/lib/binpac_bytestring.h b/aux/binpac/lib/binpac_bytestring.h deleted file mode 100644 index 13d1879aed..0000000000 --- a/aux/binpac/lib/binpac_bytestring.h +++ /dev/null @@ -1,199 +0,0 @@ -#ifndef binpac_bytestring_h -#define binpac_bytestring_h - -#include -#include -#include "binpac.h" - -namespace binpac -{ - -template class datastring; - -template -class const_datastring -{ -public: - const_datastring() - : begin_(0), end_(0) - { - } - - const_datastring(T const *data, int length) - : begin_(data), end_(data + length) - { - } - - const_datastring(const T *begin, const T *end) - : begin_(begin), end_(end) - { - } - - const_datastring(datastring const &s) - : begin_(s.begin()), end_(s.end()) - { - } - - void init(const T *data, int length) - { - begin_ = data; - end_ = data + length; - } - - T const *begin() const { return begin_; } - T const *end() const { return end_; } - int length() const { return end_ - begin_; } - - T const &operator[](int index) const - { - return begin()[index]; - } - - bool operator==(const_datastring const &s) - { - if ( length() != s.length() ) - return false; - return memcmp((const void *) begin(), (const void *) s.begin(), - sizeof(T) * length()) == 0; - } - - void set_begin(T const *begin) { begin_ = begin; } - void set_end(T const *end) { end_ = end; } - -private: - T const *begin_; - T const *end_; -}; - -typedef const_datastring const_bytestring; - -template -class datastring -{ -public: - datastring() - { - clear(); - } - - datastring(T *data, int len) - { - set(data, len); - } - - datastring(T const *begin, T const *end) - { - set_const(begin, end - begin); - } - - datastring(datastring const &x) - : data_(x.data()), length_(x.length()) - { - } - - explicit datastring(const_datastring const &x) - { - set_const(x.begin(), x.length()); - } - - datastring const &operator=(datastring const &x) - { - BINPAC_ASSERT(!data_); - set(x.data(), x.length()); - return *this; - } - - void init(T const *begin, int length) - { - BINPAC_ASSERT(!data_); - set_const(begin, length); - } - - void clear() - { - data_ = 0; length_ = 0; - } - - void free() - { - if ( data_ ) - delete [] data_; - clear(); - } - - void clone() - { - set_const(begin(), length()); - } - - datastring const &operator=(const_datastring const &x) - { - BINPAC_ASSERT(!data_); - set_const(x.begin(), x.length()); - return *this; - } - - T const &operator[](int index) const - { - return begin()[index]; - } - - T *data() const { return data_; } - int length() const { return length_; } - - T const *begin() const { return data_; } - T const *end() const { return data_ + length_; } - -private: - void set(T *data, int len) - { - data_ = data; - length_ = len; - } - - void set_const(T const *data, int len) - { - length_ = len; - data_ = new T[len + 1]; - memcpy(data_, data, sizeof(T) * len); - data_[len] = 0; - } - - T * data_; - int length_; -}; - -typedef datastring bytestring; - -inline const char *c_str(bytestring const &s) - { - return (const char *) s.begin(); - } - -inline std::string std_str(const_bytestring const &s) - { - return std::string((const char *) s.begin(), (const char *) s.end()); - } - -inline bool operator==(bytestring const &s1, const char *s2) - { - return strcmp(c_str(s1), s2) == 0; - } - -inline void get_pointers(const_bytestring const &s, - uint8 const **pbegin, uint8 const **pend) - { - *pbegin = s.begin(); - *pend = s.end(); - } - -inline void get_pointers(bytestring const *s, - uint8 const **pbegin, uint8 const **pend) - { - *pbegin = s->begin(); - *pend = s->end(); - } - -} // namespace binpac - -#endif // binpac_bytestring_h diff --git a/aux/binpac/lib/binpac_exception.h b/aux/binpac/lib/binpac_exception.h deleted file mode 100644 index 3feda3d69d..0000000000 --- a/aux/binpac/lib/binpac_exception.h +++ /dev/null @@ -1,112 +0,0 @@ -#ifndef binpac_exception_h -#define binpac_exception_h - -namespace binpac { - -class Exception -{ -public: - Exception(const char* m = 0) - : msg_("binpac exception: ") - { - if ( m ) - append(m); - // abort(); - } - - void append(string m) { msg_ += m; } - string msg() const { return msg_; } - const char* c_msg() const { return msg().c_str(); } - -protected: - string msg_; -}; - -class ExceptionOutOfBound : public Exception -{ -public: - ExceptionOutOfBound(const char* where, int len_needed, int len_given) - { - append(binpac_fmt("out_of_bound: %s: %d > %d", - where, len_needed, len_given)); - } -}; - -class ExceptionInvalidCase : public Exception -{ -public: - ExceptionInvalidCase(const char* location, - int index, - const char *expected) - : location_(location), - index_(index), - expected_(expected) - { - append(binpac_fmt("invalid case: %s: %d (%s)", - location, index, expected)); - } - -protected: - const char* location_; - int index_; - string expected_; -}; - -class ExceptionInvalidCaseIndex : public Exception -{ -public: - ExceptionInvalidCaseIndex(const char* location, - int index) - : location_(location), - index_(index) - { - append(binpac_fmt("invalid index for case: %s: %d", - location, index)); - } - -protected: - const char* location_; - int index_; -}; - -class ExceptionInvalidOffset : public Exception -{ -public: - ExceptionInvalidOffset(const char* location, - int min_offset, int offset) - : location_(location), - min_offset_(min_offset), offset_(offset) - { - append(binpac_fmt("invalid offset: %s: min_offset = %d, offset = %d", - location, min_offset, offset)); - } - -protected: - const char* location_; - int min_offset_, offset_; -}; - -class ExceptionStringMismatch : public Exception -{ -public: - ExceptionStringMismatch(const char* location, - const char *expected, const char *actual_data) - { - append(binpac_fmt("string mismatch at %s: \nexpected pattern: \"%s\"\nactual data: \"%s\"", - location, expected, actual_data)); - } -}; - -class ExceptionInvalidStringLength : public Exception -{ -public: - ExceptionInvalidStringLength(const char* location, int len) - { - append(binpac_fmt("invalid length string: %s: %d", - location, len)); - } -}; - -} - -#endif // binpac_exception_h diff --git a/aux/binpac/lib/binpac_regex.cc b/aux/binpac/lib/binpac_regex.cc deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/aux/binpac/lib/binpac_regex.h b/aux/binpac/lib/binpac_regex.h deleted file mode 100644 index b41e6dbb90..0000000000 --- a/aux/binpac/lib/binpac_regex.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef binpac_regex_h -#define binpac_regex_h - -#include "binpac.h" -#include "RE.h" - -class RE_Matcher; - -namespace binpac -{ - -class RegExMatcher { -public: - RegExMatcher(const char *pattern) - : pattern_(pattern) - { - re_matcher_ = 0; - } - - ~RegExMatcher() - { - delete re_matcher_; - } - - // Returns the length of longest match, or -1 on mismatch. - int MatchPrefix(const_byteptr data, int len) - { - if ( ! re_matcher_ ) - { - re_matcher_ = new RE_Matcher(pattern_.c_str()); - re_matcher_->Compile(); - } - return re_matcher_->MatchPrefix(data, len); - } - -private: - string pattern_; - RE_Matcher *re_matcher_; -}; - -} // namespace binpac - -#endif // binpac_regex_h diff --git a/aux/binpac/patches/binpac-1.patch b/aux/binpac/patches/binpac-1.patch deleted file mode 100644 index ade4e41065..0000000000 --- a/aux/binpac/patches/binpac-1.patch +++ /dev/null @@ -1,31 +0,0 @@ -diff -urN bro-1.2.1-orig/src/binpac/pac_expr.cc bro-1.2.1-ssl-binpac/src/binpac/pac_expr.cc ---- bro-1.2.1-orig/src/binpac/pac_expr.cc 2006-07-26 15:02:40.000000000 -0700 -+++ bro-1.2.1-ssl-binpac/src/binpac/pac_expr.cc 2007-05-04 14:31:11.728494000 -0700 -@@ -776,6 +776,27 @@ - } - break; - -+ case EXPR_CALLARGS: -+ { -+ mhs = 0; -+ if ( args_ ) -+ for ( uint i = 0; i < args_->size(); ++i ) -+ mhs = mhs_max(mhs, args_->at(i)->MinimalHeaderSize(env)); -+ } -+ break; -+ case EXPR_CASE: -+ { -+ mhs = operand_[0]->MinimalHeaderSize(env); -+ for ( uint i = 0; i < cases_->size(); ++i ) -+ { -+ CaseExpr * ce = cases_->at(i); -+ if ( ce->index() ) -+ for ( uint j = 0; j < ce->index()->size(); ++j ) -+ mhs = mhs_max(mhs, ce->index()->at(j)->MinimalHeaderSize(env)); -+ mhs = mhs_max(mhs, ce->value()->MinimalHeaderSize(env)); -+ } -+ } -+ break; - default: - // Evaluate every operand by default - mhs = 0; diff --git a/aux/binpac/patches/binpac-2.patch b/aux/binpac/patches/binpac-2.patch deleted file mode 100644 index 378c33027a..0000000000 --- a/aux/binpac/patches/binpac-2.patch +++ /dev/null @@ -1,97 +0,0 @@ -diff -urN bro-1.2.1-orig/src/binpac/pac_expr.cc bro-1.2.1-ssl-binpac/src/binpac/pac_expr.cc ---- bro-1.2.1-orig/src/binpac/pac_expr.cc 2006-07-26 15:02:40.000000000 -0700 -+++ bro-1.2.1-ssl-binpac/src/binpac/pac_expr.cc 2007-05-04 14:31:11.728494000 -0700 -@@ -245,6 +245,12 @@ - out_cc->println("%s %s;", - val_type->DataTypeStr().c_str(), - env->LValue(val_var)); -+ -+ // force evaluation of IDs appearing in case stmt -+ operand_[0]->ForceIDEval(out_cc, env); -+ foreach(i, CaseExprList, cases_) -+ (*i)->value()->ForceIDEval(out_cc, env); -+ - out_cc->println("switch ( %s )", operand_[0]->EvalExpr(out_cc, env)); - - out_cc->inc_indent(); -@@ -386,6 +392,49 @@ - } - } - -+void Expr::ForceIDEval(Output* out_cc, Env* env) -+ { -+ switch ( expr_type_ ) -+ { -+ case EXPR_NUM: -+ case EXPR_SIZEOF: -+ case EXPR_OFFSETOF: -+ break; -+ -+ case EXPR_ID: -+ if ( ! env->Evaluated(id_) ) -+ env->Evaluate(out_cc, id_); -+ break; -+ -+ case EXPR_MEMBER: -+ operand_[0]->ForceIDEval(out_cc, env); -+ break; -+ -+ case EXPR_CALLARGS: -+ { -+ foreach(i, ExprList, args_) -+ (*i)->ForceIDEval(out_cc, env); -+ } -+ break; -+ -+ case EXPR_CASE: -+ { -+ operand_[0]->ForceIDEval(out_cc, env); -+ foreach(i, CaseExprList, cases_) -+ (*i)->value()->ForceIDEval(out_cc, env); -+ } -+ break; -+ -+ default: -+ // Evaluate every operand by default -+ for ( int i = 0; i < 3; ++i ) -+ if ( operand_[i] ) -+ operand_[i]->ForceIDEval(out_cc, env); -+ break; -+ } -+ } -+ -+ - const char* Expr::EvalExpr(Output* out_cc, Env* env) - { - GenEval(out_cc, env); -diff -urN bro-1.2.1-orig/src/binpac/pac_expr.h bro-1.2.1-ssl-binpac/src/binpac/pac_expr.h ---- bro-1.2.1-orig/src/binpac/pac_expr.h 2006-07-26 15:02:39.000000000 -0700 -+++ bro-1.2.1-ssl-binpac/src/binpac/pac_expr.h 2007-05-04 14:16:31.624287000 -0700 -@@ -56,6 +56,11 @@ - // - const char *EvalExpr(Output *out, Env *env); - -+ // force evaulation of IDs contained in this expression; -+ // necessary with case expr and conditional let fields (&if) -+ // for correct parsing of fields -+ void ForceIDEval(Output *out_cc, Env *env); -+ - // Returns the set_* function of the expression. - // The expression must be of form ID or x.ID. - string SetFunc(Output *out, Env *env); -diff -urN bro-1.2.1-orig/src/binpac/pac_let.cc bro-1.2.1-ssl-binpac/src/binpac/pac_let.cc ---- bro-1.2.1-orig/src/binpac/pac_let.cc 2006-07-26 15:02:39.000000000 -0700 -+++ bro-1.2.1-ssl-binpac/src/binpac/pac_let.cc 2007-05-04 15:32:09.695568000 -0700 -@@ -80,7 +80,12 @@ - if ( type_->attr_if_expr() ) - { - // A conditional field -+ - env->Evaluate(out_cc, type_->has_value_var()); -+ -+ // force evaluation of IDs contained in this expr -+ expr()->ForceIDEval(out_cc, env); -+ - out_cc->println("if ( %s )", - env->RValue(type_->has_value_var())); - out_cc->inc_indent(); diff --git a/aux/binpac/patches/binpac-3.patch b/aux/binpac/patches/binpac-3.patch deleted file mode 100644 index 9832a245b6..0000000000 --- a/aux/binpac/patches/binpac-3.patch +++ /dev/null @@ -1,37 +0,0 @@ -diff -urN bro-1.2.1-orig/src/binpac/pac_let.cc bro-1.2.1-ssl-binpac/src/binpac/pac_let.cc ---- bro-1.2.1-orig/src/binpac/pac_let.cc 2006-07-26 15:02:39.000000000 -0700 -+++ bro-1.2.1-ssl-binpac/src/binpac/pac_let.cc 2007-05-04 15:32:09.695568000 -0700 -@@ -108,11 +108,6 @@ - void LetField::GenEval(Output* out_cc, Env* env) - { - GenParseCode(out_cc, env); -- if ( type_->attr_if_expr() ) -- { -- out_cc->println("BINPAC_ASSERT(%s);", -- env->RValue(type_->has_value_var())); -- } - } - - LetDecl::LetDecl(ID *id, Type *type, Expr *expr) -diff -urN bro-1.2.1-orig/src/binpac/pac_type.cc bro-1.2.1-ssl-binpac/src/binpac/pac_type.cc ---- bro-1.2.1-orig/src/binpac/pac_type.cc 2006-07-26 15:02:40.000000000 -0700 -+++ bro-1.2.1-ssl-binpac/src/binpac/pac_type.cc 2007-05-24 10:56:42.140658000 -0700 -@@ -316,9 +316,15 @@ - { - if ( DefineValueVar() ) - { -- out_h->println("%s %s const { return %s; }", -- DataTypeConstRefStr().c_str(), -- env->RValue(value_var()), lvalue()); -+ if ( attr_if_expr_ ) -+ out_h->println("%s %s const { BINPAC_ASSERT(%s); return %s; }", -+ DataTypeConstRefStr().c_str(), -+ env->RValue(value_var()), -+ env->RValue(has_value_var()), lvalue()); -+ else -+ out_h->println("%s %s const { return %s; }", -+ DataTypeConstRefStr().c_str(), -+ env->RValue(value_var()), lvalue()); - } - - foreach (i, FieldList, fields_) diff --git a/aux/binpac/patches/binpac-4.patch b/aux/binpac/patches/binpac-4.patch deleted file mode 100644 index 560fb4051b..0000000000 --- a/aux/binpac/patches/binpac-4.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff -urN bro-1.2.1-orig/src/binpac/pac_record.cc bro-1.2.1-ssl-binpac/src/binpac/pac_record.cc ---- bro-1.2.1-orig/src/binpac/pac_record.cc 2006-07-26 15:02:40.000000000 -0700 -+++ bro-1.2.1-ssl-binpac/src/binpac/pac_record.cc 2007-05-08 16:13:33.373850000 -0700 -@@ -123,7 +123,7 @@ - void RecordType::DoGenParseCode(Output* out_cc, Env* env, - const DataPtr& data, int flags) - { -- if ( StaticSize(env) >= 0 ) -+ if ( !incremental_input() && StaticSize(env) >= 0 ) - GenBoundaryCheck(out_cc, env, data); - - if ( incremental_parsing() ) diff --git a/aux/binpac/patches/binpac-5.patch b/aux/binpac/patches/binpac-5.patch deleted file mode 100644 index ae31fa1711..0000000000 --- a/aux/binpac/patches/binpac-5.patch +++ /dev/null @@ -1,66 +0,0 @@ -diff -urN bro-1.2.1-orig/src/binpac/pac_paramtype.cc bro-1.2.1-ssl-binpac/src/binpac/pac_paramtype.cc ---- bro-1.2.1-orig/src/binpac/pac_paramtype.cc 2006-07-26 15:02:40.000000000 -0700 -+++ bro-1.2.1-ssl-binpac/src/binpac/pac_paramtype.cc 2007-05-10 15:09:47.470104000 -0700 -@@ -208,7 +208,13 @@ - const char *parse_func; - string parse_params; - -- if ( ref_type->incremental_input() ) -+ if ( buffer_mode() == BUFFER_NOTHING ) -+ { -+ ASSERT(!ref_type->incremental_input()); -+ parse_func = kParseFuncWithoutBuffer; -+ parse_params = "0, 0"; -+ } -+ else if ( ref_type->incremental_input() ) - { - parse_func = kParseFuncWithBuffer; - parse_params = env->RValue(flow_buffer_id); -@@ -239,15 +245,24 @@ - - if ( incremental_input() ) - { -- ASSERT(parsing_complete_var()); -- out_cc->println("%s = %s;", -- env->LValue(parsing_complete_var()), -- call_parse_func.c_str()); -- -- // parsing_complete_var might have been already -- // evaluated when set to false -- if ( ! env->Evaluated(parsing_complete_var()) ) -- env->SetEvaluated(parsing_complete_var()); -+ if ( buffer_mode() == BUFFER_NOTHING ) -+ { -+ out_cc->println("%s;", call_parse_func.c_str()); -+ out_cc->println("%s = true;", -+ env->LValue(parsing_complete_var())); -+ } -+ else -+ { -+ ASSERT(parsing_complete_var()); -+ out_cc->println("%s = %s;", -+ env->LValue(parsing_complete_var()), -+ call_parse_func.c_str()); -+ -+ // parsing_complete_var might have been already -+ // evaluated when set to false -+ if ( ! env->Evaluated(parsing_complete_var()) ) -+ env->SetEvaluated(parsing_complete_var()); -+ } - } - else - { -diff -urN bro-1.2.1-orig/src/binpac/pac_type.cc bro-1.2.1-ssl-binpac/src/binpac/pac_type.cc ---- bro-1.2.1-orig/src/binpac/pac_type.cc 2006-07-26 15:02:40.000000000 -0700 -+++ bro-1.2.1-ssl-binpac/src/binpac/pac_type.cc 2007-05-24 10:56:42.140658000 -0700 -@@ -501,8 +501,8 @@ - - if ( buffer_mode() == BUFFER_NOTHING ) - { -- out_cc->println("%s = true;", -- env->LValue(parsing_complete_var())); -+ // this is the empty type -+ DoGenParseCode(out_cc, env, data, flags); - } - else if ( buffer_input() ) - { diff --git a/aux/binpac/patches/binpac-6.patch b/aux/binpac/patches/binpac-6.patch deleted file mode 100644 index fec16c1084..0000000000 --- a/aux/binpac/patches/binpac-6.patch +++ /dev/null @@ -1,28 +0,0 @@ -diff -urN bro-1.2.1-orig/src/binpac/lib/binpac_buffer.h bro-1.2.1-ssl-binpac/src/binpac/lib/binpac_buffer.h ---- bro-1.2.1-orig/src/binpac/lib/binpac_buffer.h 2006-07-26 15:02:38.000000000 -0700 -+++ bro-1.2.1-ssl-binpac/src/binpac/lib/binpac_buffer.h 2007-05-09 16:14:54.501656000 -0700 -@@ -59,6 +59,11 @@ - return frame_length_; - } - -+ inline bool data_available() const -+ { -+ return buffer_n_ > 0 || orig_data_end_ > orig_data_begin_; -+ } -+ - void NewLine(); - // A negative frame_length represents a frame till EOF - void NewFrame(int frame_length, bool chunked_); -diff -urN bro-1.2.1-orig/src/binpac/pac_flow.cc bro-1.2.1-ssl-binpac/src/binpac/pac_flow.cc ---- bro-1.2.1-orig/src/binpac/pac_flow.cc 2006-10-12 14:13:12.000000000 -0700 -+++ bro-1.2.1-ssl-binpac/src/binpac/pac_flow.cc 2007-05-22 16:43:55.997562000 -0700 -@@ -272,7 +272,8 @@ - env_->RValue(begin_of_data), - env_->RValue(end_of_data)); - -- out_cc->println("while ( true )"); -+ out_cc->println("while ( %s->data_available() )", -+ env_->LValue(flow_buffer_id)); - out_cc->inc_indent(); - out_cc->println("{"); - diff --git a/aux/binpac/patches/binpac-7.patch b/aux/binpac/patches/binpac-7.patch deleted file mode 100644 index 263f00bf2c..0000000000 --- a/aux/binpac/patches/binpac-7.patch +++ /dev/null @@ -1,21 +0,0 @@ -diff -urN bro-1.2.1-orig/src/binpac/pac_type.cc bro-1.2.1-ssl-binpac/src/binpac/pac_type.cc ---- bro-1.2.1-orig/src/binpac/pac_type.cc 2006-07-26 15:02:40.000000000 -0700 -+++ bro-1.2.1-ssl-binpac/src/binpac/pac_type.cc 2007-05-24 10:56:42.140658000 -0700 -@@ -393,7 +393,7 @@ - break; - - case BUFFER_BY_LENGTH: -- if ( buffering_state_var_field_ ) -+ if ( env->GetDataType(buffering_state_id) ) - { - out_cc->println("if ( %s == 0 )", - env->RValue(buffering_state_id)); -@@ -421,7 +421,7 @@ - frame_buffer_arg.c_str(), - attr_chunked() ? "true" : "false"); - -- if ( buffering_state_var_field_ ) -+ if ( env->GetDataType(buffering_state_id) ) - { - out_cc->println("%s = 1;", - env->LValue(buffering_state_id)); diff --git a/aux/binpac/patches/binpac-8.patch b/aux/binpac/patches/binpac-8.patch deleted file mode 100644 index b69a1676dd..0000000000 --- a/aux/binpac/patches/binpac-8.patch +++ /dev/null @@ -1,190 +0,0 @@ -diff -urN bro-1.2.1-orig/src/binpac/pac_analyzer.cc bro-1.2.1-ssl-binpac/src/binpac/pac_analyzer.cc ---- bro-1.2.1-orig/src/binpac/pac_analyzer.cc 2006-07-26 15:02:40.000000000 -0700 -+++ bro-1.2.1-ssl-binpac/src/binpac/pac_analyzer.cc 2007-05-22 17:00:10.091531000 -0700 -@@ -26,8 +26,9 @@ - helpers_ = new AnalyzerHelperList(); - functions_ = new FunctionList(); - -- constructor_helper_ = 0; -- destructor_helper_ = 0; -+ constructor_helpers_ = new AnalyzerHelperList(); -+ destructor_helpers_ = new AnalyzerHelperList(); -+ eof_helpers_ = new AnalyzerHelperList(); - - SetAnalyzerContext(); - -@@ -41,6 +42,9 @@ - delete_list(AnalyzerHelperList, helpers_); - delete_list(FunctionList, functions_); - delete_list(ParamList, params_); -+ delete_list(AnalyzerHelperList, constructor_helpers_); -+ delete_list(AnalyzerHelperList, destructor_helpers_); -+ delete_list(AnalyzerHelperList, eof_helpers_); - } - - void AnalyzerDecl::AddElements(AnalyzerElementList *elemlist) -@@ -75,28 +79,20 @@ - AnalyzerHelper *helper_elem = - (AnalyzerHelper *) elem; - -- if ( helper_elem->helper_type() == -- AnalyzerHelper::INIT_CODE) -- { -- if ( constructor_helper_ ) -- { -- throw Exception(elem, -- "Repeated definition of %init code"); -- } -- constructor_helper_ = helper_elem; -+ switch ( helper_elem->helper_type() ) -+ { -+ case AnalyzerHelper::INIT_CODE: -+ constructor_helpers_->push_back(helper_elem); -+ break; -+ case AnalyzerHelper::CLEANUP_CODE: -+ destructor_helpers_->push_back(helper_elem); -+ break; -+ case AnalyzerHelper::EOF_CODE: -+ eof_helpers_->push_back(helper_elem); -+ break; -+ default: -+ helpers_->push_back(helper_elem); - } -- else if ( helper_elem->helper_type() == -- AnalyzerHelper::CLEANUP_CODE) -- { -- if ( destructor_helper_ ) -- { -- throw Exception(elem, -- "Repeated definition of %cleanup code"); -- } -- destructor_helper_ = helper_elem; -- } -- else -- helpers_->push_back(helper_elem); - } - break; - case AnalyzerElement::FUNCTION: -@@ -217,15 +213,19 @@ - void AnalyzerDecl::GenInitCode(Output *out_cc) - { - TypeDecl::GenInitCode(out_cc); -- if ( constructor_helper_ ) -- constructor_helper_->GenCode(0, out_cc, this); -+ foreach(i, AnalyzerHelperList, constructor_helpers_) -+ { -+ (*i)->GenCode(0, out_cc, this); -+ } - } - - void AnalyzerDecl::GenCleanUpCode(Output *out_cc) - { - TypeDecl::GenCleanUpCode(out_cc); -- if ( destructor_helper_ ) -- destructor_helper_->GenCode(0, out_cc, this); -+ foreach(i, AnalyzerHelperList, destructor_helpers_) -+ { -+ (*i)->GenCode(0, out_cc, this); -+ } - } - - void AnalyzerDecl::GenStateVarDecls(Output *out_h) -@@ -295,6 +295,7 @@ - break; - case INIT_CODE: - case CLEANUP_CODE: -+ case EOF_CODE: - out = out_cc; - break; - } -diff -urN bro-1.2.1-orig/src/binpac/pac_analyzer.h bro-1.2.1-ssl-binpac/src/binpac/pac_analyzer.h ---- bro-1.2.1-orig/src/binpac/pac_analyzer.h 2006-07-26 15:02:39.000000000 -0700 -+++ bro-1.2.1-ssl-binpac/src/binpac/pac_analyzer.h 2007-05-22 16:32:08.397926000 -0700 -@@ -76,8 +76,9 @@ - AnalyzerHelperList *helpers_; - FunctionList *functions_; - -- AnalyzerHelper *constructor_helper_; -- AnalyzerHelper *destructor_helper_; -+ AnalyzerHelperList *constructor_helpers_; -+ AnalyzerHelperList *destructor_helpers_; -+ AnalyzerHelperList *eof_helpers_; - }; - - class AnalyzerElement : public Object -@@ -117,6 +118,7 @@ - MEMBER_DECLS, - INIT_CODE, - CLEANUP_CODE, -+ EOF_CODE, - }; - AnalyzerHelper(Type helper_type, EmbeddedCode *code) - : AnalyzerElement(HELPER), -diff -urN bro-1.2.1-orig/src/binpac/pac_conn.cc bro-1.2.1-ssl-binpac/src/binpac/pac_conn.cc ---- bro-1.2.1-orig/src/binpac/pac_conn.cc 2006-07-26 15:02:40.000000000 -0700 -+++ bro-1.2.1-ssl-binpac/src/binpac/pac_conn.cc 2007-05-22 16:42:35.406135000 -0700 -@@ -97,6 +97,12 @@ - out_cc->println("%s->%s();", - env_->LValue(downflow_id), - kFlowEOF); -+ -+ foreach(i, AnalyzerHelperList, eof_helpers_) -+ { -+ (*i)->GenCode(0, out_cc, this); -+ } -+ - out_cc->dec_indent(); - - out_cc->println("}"); -diff -urN bro-1.2.1-orig/src/binpac/pac_flow.cc bro-1.2.1-ssl-binpac/src/binpac/pac_flow.cc ---- bro-1.2.1-orig/src/binpac/pac_flow.cc 2006-10-12 14:13:12.000000000 -0700 -+++ bro-1.2.1-ssl-binpac/src/binpac/pac_flow.cc 2007-05-22 16:43:55.997562000 -0700 -@@ -151,6 +151,11 @@ - out_cc->inc_indent(); - out_cc->println("{"); - -+ foreach(i, AnalyzerHelperList, eof_helpers_) -+ { -+ (*i)->GenCode(0, out_cc, this); -+ } -+ - if ( dataunit_->type() == AnalyzerDataUnit::FLOWUNIT ) - { - out_cc->println("%s->set_eof();", -diff -urN bro-1.2.1-orig/src/binpac/pac_parse.yy bro-1.2.1-ssl-binpac/src/binpac/pac_parse.yy ---- bro-1.2.1-orig/src/binpac/pac_parse.yy 2006-10-12 14:13:12.000000000 -0700 -+++ bro-1.2.1-ssl-binpac/src/binpac/pac_parse.yy 2007-05-22 16:56:09.280526000 -0700 -@@ -22,7 +22,7 @@ - %token TOK_STATE TOK_ACTION TOK_WHEN TOK_HELPER - %token TOK_DATAUNIT TOK_FLOWDIR TOK_WITHCONTEXT - %token TOK_LPB_EXTERN TOK_LPB_HEADER TOK_LPB_CODE --%token TOK_LPB_MEMBER TOK_LPB_INIT TOK_LPB_CLEANUP -+%token TOK_LPB_MEMBER TOK_LPB_INIT TOK_LPB_CLEANUP TOK_LPB_EOF - %token TOK_LPB TOK_RPB - %token TOK_EMBEDDED_ATOM TOK_EMBEDDED_STRING - %token TOK_PAC_VAL TOK_PAC_SET TOK_PAC_TYPE TOK_PAC_TYPEOF TOK_PAC_CONST_DEF -@@ -795,6 +795,10 @@ - { - $$ = new AnalyzerHelper(AnalyzerHelper::CLEANUP_CODE, $2); - } -+ | TOK_LPB_EOF embedded_code TOK_RPB -+ { -+ $$ = new AnalyzerHelper(AnalyzerHelper::EOF_CODE, $2); -+ } - | TOK_FLOWDIR '=' tok_id optargs ';' - { - $$ = new AnalyzerFlow((AnalyzerFlow::Direction) $1, $3, $4); -diff -urN bro-1.2.1-orig/src/binpac/pac_scan.ll bro-1.2.1-ssl-binpac/src/binpac/pac_scan.ll ---- bro-1.2.1-orig/src/binpac/pac_scan.ll 2006-07-26 15:02:40.000000000 -0700 -+++ bro-1.2.1-ssl-binpac/src/binpac/pac_scan.ll 2007-05-22 16:55:19.349644000 -0700 -@@ -96,6 +96,10 @@ - BEGIN(EC); - return TOK_LPB_MEMBER; - } -+"%eof{" { -+ BEGIN(EC); -+ return TOK_LPB_EOF; -+ } - "%{" { - BEGIN(EC); - return TOK_LPB; diff --git a/aux/binpac/patches/binpac-patch-doc.txt b/aux/binpac/patches/binpac-patch-doc.txt deleted file mode 100644 index 052285eaea..0000000000 --- a/aux/binpac/patches/binpac-patch-doc.txt +++ /dev/null @@ -1,87 +0,0 @@ -binpac fixes ----------------- - -numbers of issues below correspond to the patch numbers - -(1) correct calculation of minimal header size in pac_expr.cc -- problem: EXPR_CALLARGS and EXPR_CASE not considered for the calculation - of minimal header size -- solution: added two cases in switch stmt of Expr::MinimalHeaderSize - for EXPR_CALLARGS and EXPR_CASE - - -(2) ensure parsing of fields first referenced in a case expression or - let field with an &if attribute -- problem: in cases where the if expression evaluates to false or the - proper case does not occur, fields get not parsed at all -- solution: force evaluation of all IDs referenced in a let field with - if attribute or a case expression before the body of the corresponding - switch stmt or the if stmt -- added public method Expr::ForceIDEval, properly called before - generating the code of a field with if attribute or the case expression - - -(3) properly assert the use of fields with an if attribute -- problem: the use of fields with an if attribute was not asserted in all - cases and asserted in the wrong way in some others due to the - corresponding BINPAC_ASSERT only called upon parsing the field -- solution: perform BINPAC_ASSERT upon calling the fields accessor - function -- moved BINPAC_ASSERT statement from LetField::GenEval to - Type::GenPubDecls - - -(4) incremental input with records with a non-negative StaticSize -- problem: incremental input with records with a StaticSize >= 0 - cannot be performed due to necessary length attribute, leading to - an invalid call of GenBoundaryCheck in RecordType::DoGenParseCode -- solution: added a check for incremental input in - RecordType::DoGenParseCode before calling GenBoundaryCheck - - -(5) empty type with incremental input -- problem: with an empty type and incremental input, although the - Parse function is created, it is never called, leading to problems, - if additional actions are to be performed when encountering that - empty type -- solution: generate call to Parse of empty type in Type::GenParseBuffer - - -(6) parsing loop in flow ParseBuffer (while(true)) -- problem: while(true) leads to problems after parsing of a type is - complete; at this time, it is unexpected that parsing continues, even - if no data is available in the flow buffer -- solution: check if data is available before starting a new parsing - cycle -- added a method data_available to FlowBuffer -- changed while(true) in FlowDecl::GenCodeFlowUnit to - while(flow_buffer_->data_available()) - - -(7) initialization of flow buffer in CaseType with bufferable fields - in cases -- problem: initialization of buffer occurs in every Parse call, - regardless if it was initialized before or not; initialization - is correct only on first such occurence -- solution: check to buffer_state is to be created always when - buffering_state_id is in environment in Type::GenBufferConfig -- changed condition from buffering_state_var_field_ to - env->GetDataType(buffering_state_id) - - -(8) allowing init and cleanup code to be redefined, as well as addition - of code to FlowEOF calls in analyzer and flow -- problem 1: when refining an analyzer or flow definition, additional - init and cleanup code was not allowed, if these were already defined - before; this leads to problems when adding new members, as these - cannot be initialized and destroyed properly -- solution: allow init and cleanup code to be specified more than once -- changed deifnitions and usage of constructor_helper and - destructor_helper to allow for lists of constructor and destructor - helpers (similar to member declarations) in pac_analyzer.h and - pac_analyzer.cc -- problem 2: in some cases, it is desirable to execute code when - encountering the end of the input stream, which is not possible in - binpac -- solution: added a %eof binpac primitive similar to %init, which adds - code to the FlowEOF function of an analyzer or a flow diff --git a/aux/binpac/patches/brosslbinpacanalyzerpatches.zip b/aux/binpac/patches/brosslbinpacanalyzerpatches.zip deleted file mode 100644 index 4d89326f71..0000000000 Binary files a/aux/binpac/patches/brosslbinpacanalyzerpatches.zip and /dev/null differ diff --git a/aux/binpac/patches/nadi-bittorrent.patch b/aux/binpac/patches/nadi-bittorrent.patch deleted file mode 100644 index 1ce6cc0313..0000000000 --- a/aux/binpac/patches/nadi-bittorrent.patch +++ /dev/null @@ -1,172 +0,0 @@ -Index: pac_type.h -=================================================================== ---- pac_type.h (revision 4130) -+++ pac_type.h (working copy) -@@ -78,12 +78,6 @@ - string EvalByteOrder(Output *out_cc, Env *env) const; - - virtual string EvalMember(const ID *member_id) const; --#if 0 -- // member_env() is used for finding a member of the type. -- // Thus member_env() of a ParameterizedType should return -- // ReferredDataType()->env() -- // virtual Env *member_env() const; --#endif - - // The variable defined by the type - const ID *value_var() const { return value_var_; } -@@ -223,6 +217,8 @@ - - virtual bool ByteOrderSensitive() const = 0; - -+ bool NeedsBufferingStateVar() const; -+ - void GenBufferingLoop(Output* out_cc, Env* env, int flags); - void GenParseBuffer(Output* out_cc, Env* env, int flags); - void GenParseCode2(Output* out_cc, Env* env, const DataPtr& data, int flags); -Index: lib/binpac_buffer.h -=================================================================== ---- lib/binpac_buffer.h (revision 4130) -+++ lib/binpac_buffer.h (working copy) -@@ -24,18 +24,18 @@ - void DiscardData(); - - // Whether there is enough data for the frame -- bool ready() const{ return message_complete_; } -+ bool ready() const{ return message_complete_ || mode_ == UNKNOWN_MODE; } - - inline const_byteptr begin() const - { -- BINPAC_ASSERT(message_complete_); -+ BINPAC_ASSERT(ready()); - return ( buffer_n_ == 0 ) ? - orig_data_begin_ : buffer_; - } - - inline const_byteptr end() const - { -- BINPAC_ASSERT(message_complete_); -+ BINPAC_ASSERT(ready()); - if ( buffer_n_ == 0 ) - { - BINPAC_ASSERT(frame_length_ >= 0); -Index: pac_type.cc -=================================================================== ---- pac_type.cc (revision 4130) -+++ pac_type.cc (working copy) -@@ -285,9 +285,8 @@ - parsing_complete_var, extern_type_bool->Clone()); - parsing_complete_var_field_->Prepare(env); - -- if ( ( buffer_mode() == BUFFER_BY_LENGTH || -- buffer_mode() == BUFFER_BY_LINE ) && -- ! env->GetDataType(buffering_state_id) ) -+ if ( NeedsBufferingStateVar() && -+ !env->GetDataType(buffering_state_id) ) - { - buffering_state_var_field_ = new PrivVarField( - buffering_state_id->clone(), -@@ -387,17 +386,17 @@ - break; - - case BUFFER_BY_LENGTH: -- if ( buffering_state_var_field_ ) -- { -- out_cc->println("if ( %s == 0 )", -- env->RValue(buffering_state_id)); -- out_cc->inc_indent(); -- out_cc->println("{"); -- } -+ if ( !NeedsBufferingStateVar() ) -+ break; - -+ ASSERT(env->GetDataType(buffering_state_id)); -+ out_cc->println("if ( %s == 0 )", -+ env->RValue(buffering_state_id)); -+ out_cc->inc_indent(); -+ out_cc->println("{"); -+ - if ( attr_length_expr_ ) - { -- // frame_buffer_arg = attr_length_expr_->EvalExpr(out_cc, env); - frame_buffer_arg = strfmt("%d", InitialBufferLength()); - } - else if ( attr_restofflow_ ) -@@ -407,7 +406,7 @@ - } - else - { -- frame_buffer_arg = strfmt("%d", InitialBufferLength()); -+ ASSERT(0); - } - - out_cc->println("%s->NewFrame(%s, %s);", -@@ -415,16 +414,14 @@ - frame_buffer_arg.c_str(), - attr_chunked() ? "true" : "false"); - -- if ( buffering_state_var_field_ ) -- { -- out_cc->println("%s = 1;", -- env->LValue(buffering_state_id)); -- out_cc->println("}"); -- out_cc->dec_indent(); -- } -+ out_cc->println("%s = 1;", -+ env->LValue(buffering_state_id)); -+ out_cc->println("}"); -+ out_cc->dec_indent(); - break; - - case BUFFER_BY_LINE: -+ ASSERT(env->GetDataType(buffering_state_id)); - out_cc->println("if ( %s == 0 )", - env->RValue(buffering_state_id)); - out_cc->inc_indent(); -@@ -890,6 +887,25 @@ - return ! attr_byteorder_expr() && ByteOrderSensitive(); - } - -+bool Type::NeedsBufferingStateVar() const -+ { -+ if ( !incremental_input() ) -+ return false; -+ switch ( buffer_mode() ) -+ { -+ case BUFFER_NOTHING: -+ case NOT_BUFFERABLE: -+ return false; -+ case BUFFER_BY_LINE: -+ return true; -+ case BUFFER_BY_LENGTH: -+ return ( attr_length_expr_ || attr_restofflow_ ); -+ default: -+ ASSERT(0); -+ return false; -+ } -+ } -+ - bool Type::DoTraverse(DataDepVisitor *visitor) - { - foreach (i, FieldList, fields_) -Index: pac_flow.cc -=================================================================== ---- pac_flow.cc (revision 4130) -+++ pac_flow.cc (working copy) -@@ -224,15 +224,13 @@ - out_cc->println("catch ( Exception const &e )"); - out_cc->inc_indent(); - out_cc->println("{"); -- out_cc->println("DEBUG_MSG(\"%%.6f binpac exception: %%s\\n\", network_time(), e.c_msg());"); - GenCleanUpCode(out_cc); - if ( dataunit_->type() == AnalyzerDataUnit::FLOWUNIT ) - { - out_cc->println("%s->DiscardData();", - env_->LValue(flow_buffer_id)); -- out_cc->println("BINPAC_ASSERT(!%s->ready());", -- env_->RValue(flow_buffer_id)); - } -+ out_cc->println("throw e;"); - out_cc->println("}"); - out_cc->dec_indent(); - diff --git a/aux/binpac/shtool b/aux/binpac/shtool deleted file mode 100755 index 4c1a7396fd..0000000000 --- a/aux/binpac/shtool +++ /dev/null @@ -1,716 +0,0 @@ -#!/bin/sh -## -## GNU shtool -- The GNU Portable Shell Tool -## Copyright (c) 1994-2000 Ralf S. Engelschall -## -## See http://www.gnu.org/software/shtool/ for more information. -## See ftp://ftp.gnu.org/gnu/shtool/ for latest version. -## -## Version 1.4.9 (16-Apr-2000) -## Ingredients: 3/17 available modules -## - -## -## This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. -## -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -## USA, or contact Ralf S. Engelschall . -## -## Notice: Given that you include this file verbatim into your own -## source tree, you are justified in saying that it remains separate -## from your package, and that this way you are simply just using GNU -## shtool. So, in this situation, there is no requirement that your -## package itself is licensed under the GNU General Public License in -## order to take advantage of GNU shtool. -## - -## -## Usage: shtool [] [ [] []] -## -## Available commands: -## echo Print string with optional construct expansion -## install Install a program, script or datafile -## mkdir Make one or more directories -## -## Not available commands (because module was not built-in): -## mdate Pretty-print modification time of a file or dir -## table Pretty-print a field-separated list as a table -## prop Display progress with a running propeller -## move Move files with simultaneous substitution -## mkln Make link with calculation of relative paths -## mkshadow Make a shadow tree through symbolic links -## fixperm Fix file permissions inside a source tree -## tarball Roll distribution tarballs -## guessos Simple operating system guesser -## arx Extended archive command -## slo Separate linker options by library class -## scpp Sharing C Pre-Processor -## version Generate and maintain a version information file -## path Deal with program paths -## - -if [ $# -eq 0 ]; then - echo "$0:Error: invalid command line" 1>&2 - echo "$0:Hint: run \`$0 -h' for usage" 1>&2 - exit 1 -fi -if [ ".$1" = ".-h" -o ".$1" = ".--help" ]; then - echo "This is GNU shtool, version 1.4.9 (16-Apr-2000)" - echo "Copyright (c) 1994-2000 Ralf S. Engelschall " - echo "Report bugs to " - echo '' - echo "Usage: shtool [] [ [] []]" - echo '' - echo 'Available global :' - echo ' -v, --version display shtool version information' - echo ' -h, --help display shtool usage help page (this one)' - echo ' -d, --debug display shell trace information' - echo '' - echo 'Available [] []:' - echo ' echo [-n] [-e] [ ...]' - echo ' install [-v] [-t] [-c] [-C] [-s] [-m] [-o] [-g]' - echo ' [-e] ' - echo ' mkdir [-t] [-f] [-p] [-m] [ ...]' - echo '' - echo 'Not available (because module was not built-in):' - echo ' mdate [-n] [-z] [-s] [-d] [-f] [-o] ' - echo ' table [-F] [-w] [-c] [-s] ...' - echo ' prop [-p]' - echo ' move [-v] [-t] [-e] [-p] ' - echo ' mkln [-t] [-f] [-s] [ ...] ' - echo ' mkshadow [-v] [-t] [-a] ' - echo ' fixperm [-v] [-t] [ ...]' - echo ' tarball [-t] [-v] [-o ] [-c ] [-d ] [-u' - echo ' ] [-g ] [-e ] [ ...]' - echo ' guessos ' - echo ' arx [-t] [-C] [ ...]' - echo ' slo [-p] -- -L -l [-L -l ...]' - echo ' scpp [-v] [-p] [-f] [-o] [-t] [-M]' - echo ' [-D] [-C] [ ...]' - echo ' version [-l] [-n] [-p] [-s] [-i]' - echo ' [-d] ' - echo ' path [-s] [-r] [-d] [-b] [-m] [-p] [ ...]' - echo '' - exit 0 -fi -if [ ".$1" = ".-v" -o ".$1" = ."--version" ]; then - echo "GNU shtool 1.4.9 (16-Apr-2000)" - exit 0 -fi -if [ ".$1" = ".-d" -o ".$1" = ."--debug" ]; then - shift - set -x -fi -name=`echo "$0" | sed -e 's;.*/\([^/]*\)$;\1;' -e 's;-sh$;;' -e 's;\.sh$;;'` -case "$name" in - echo|install|mkdir ) - # implicit tool command selection - tool="$name" - ;; - * ) - # explicit tool command selection - tool="$1" - shift - ;; -esac -arg_spec="" -opt_spec="" -gen_tmpfile=no - -## -## DISPATCH INTO SCRIPT PROLOG -## - -case $tool in - echo ) - str_tool="echo" - str_usage="[-n] [-e] [ ...]" - arg_spec="0+" - opt_spec="n.e." - opt_n=no - opt_e=no - ;; - install ) - str_tool="install" - str_usage="[-v] [-t] [-c] [-C] [-s] [-m] [-o] [-g] [-e] " - arg_spec="2=" - opt_spec="v.t.c.C.s.m:o:g:e:" - opt_v=no - opt_t=no - opt_c=no - opt_C=no - opt_s=no - opt_m="" - opt_o="" - opt_g="" - opt_e="" - ;; - mkdir ) - str_tool="mkdir" - str_usage="[-t] [-f] [-p] [-m] [ ...]" - arg_spec="1+" - opt_spec="t.f.p.m:" - opt_t=no - opt_f=no - opt_p=no - opt_m="" - ;; - -* ) - echo "$0:Error: unknown option \`$tool'" 2>&1 - echo "$0:Hint: run \`$0 -h' for usage" 2>&1 - exit 1 - ;; - * ) - echo "$0:Error: unknown command \`$tool'" 2>&1 - echo "$0:Hint: run \`$0 -h' for usage" 2>&1 - exit 1 - ;; -esac - -## -## COMMON UTILITY CODE -## - -# determine name of tool -if [ ".$tool" != . ]; then - # used inside shtool script - toolcmd="$0 $tool" - toolcmdhelp="shtool $tool" - msgprefix="shtool:$tool" -else - # used as standalone script - toolcmd="$0" - toolcmdhelp="sh $0" - msgprefix="$str_tool" -fi - -# parse argument specification string -eval `echo $arg_spec |\ - sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'` - -# parse option specification string -eval `echo h.$opt_spec |\ - sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'` - -# interate over argument line -opt_PREV='' -while [ $# -gt 0 ]; do - # special option stops processing - if [ ".$1" = ".--" ]; then - shift - break - fi - - # determine option and argument - opt_ARG_OK=no - if [ ".$opt_PREV" != . ]; then - # merge previous seen option with argument - opt_OPT="$opt_PREV" - opt_ARG="$1" - opt_ARG_OK=yes - opt_PREV='' - else - # split argument into option and argument - case "$1" in - -[a-zA-Z0-9]*) - eval `echo "x$1" |\ - sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \ - -e 's/";\(.*\)$/"; opt_ARG="\1"/'` - ;; - -[a-zA-Z0-9]) - opt_OPT=`echo "x$1" | cut -c3-` - opt_ARG='' - ;; - *) - break - ;; - esac - fi - - # eat up option - shift - - # determine whether option needs an argument - eval "opt_MODE=\$opt_MODE_${opt_OPT}" - if [ ".$opt_ARG" = . -a ".$opt_ARG_OK" != .yes ]; then - if [ ".$opt_MODE" = ".:" -o ".$opt_MODE" = ".+" ]; then - opt_PREV="$opt_OPT" - continue - fi - fi - - # process option - case $opt_MODE in - '.' ) - # boolean option - eval "opt_${opt_OPT}=yes" - ;; - ':' ) - # option with argument (multiple occurances override) - eval "opt_${opt_OPT}=\"\$opt_ARG\"" - ;; - '+' ) - # option with argument (multiple occurances append) - eval "opt_${opt_OPT}=\"\$opt_${opt_OPT} \$opt_ARG\"" - ;; - * ) - echo "$msgprefix:Error: unknown option: \`-$opt_OPT'" 1>&2 - echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2 - exit 1 - ;; - esac -done -if [ ".$opt_PREV" != . ]; then - echo "$msgprefix:Error: missing argument to option \`-$opt_PREV'" 1>&2 - echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2 - exit 1 -fi - -# process help option -if [ ".$opt_h" = .yes ]; then - echo "Usage: $toolcmdhelp $str_usage" - exit 0 -fi - -# complain about incorrect number of arguments -case $arg_MODE in - '=' ) - if [ $# -ne $arg_NUMS ]; then - echo "$msgprefix:Error: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2 - echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man shtool' for details" 1>&2 - exit 1 - fi - ;; - '+' ) - if [ $# -lt $arg_NUMS ]; then - echo "$msgprefix:Error: invalid number of arguments (at least $arg_NUMS expected)" 1>&2 - echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man shtool' for details" 1>&2 - exit 1 - fi - ;; -esac - -# establish a temporary file on request -if [ ".$gen_tmpfile" = .yes ]; then - if [ ".$TMPDIR" != . ]; then - tmpdir="$TMPDIR" - elif [ ".$TEMPDIR" != . ]; then - tmpdir="$TEMPDIR" - else - tmpdir="/tmp" - fi - tmpfile="$tmpdir/.shtool.$$" - rm -f $tmpfile >/dev/null 2>&1 - touch $tmpfile -fi - -## -## DISPATCH INTO SCRIPT BODY -## - -case $tool in - -echo ) - ## - ## echo -- Print string with optional construct expansion - ## Copyright (c) 1998-2000 Ralf S. Engelschall - ## Originally written for WML as buildinfo - ## - - text="$*" - - # check for broken escape sequence expansion - seo='' - bytes=`echo '\1' | wc -c | awk '{ printf("%s", $1); }'` - if [ ".$bytes" != .3 ]; then - bytes=`echo -E '\1' | wc -c | awk '{ printf("%s", $1); }'` - if [ ".$bytes" = .3 ]; then - seo='-E' - fi - fi - - # check for existing -n option (to suppress newline) - minusn='' - bytes=`echo -n 123 2>/dev/null | wc -c | awk '{ printf("%s", $1); }'` - if [ ".$bytes" = .3 ]; then - minusn='-n' - fi - - # determine terminal bold sequence - term_bold='' - term_norm='' - if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[Bb]'`" != . ]; then - case $TERM in - # for the most important terminal types we directly know the sequences - xterm|xterm*|vt220|vt220*) - term_bold=`awk 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' /dev/null` - term_norm=`awk 'BEGIN { printf("%c%c%c", 27, 91, 109); }' /dev/null` - ;; - vt100|vt100*) - term_bold=`awk 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' /dev/null` - term_norm=`awk 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' /dev/null` - ;; - # for all others, we try to use a possibly existing `tput' or `tcout' utility - * ) - paths=`echo $PATH | sed -e 's/:/ /g'` - for tool in tput tcout; do - for dir in $paths; do - if [ -r "$dir/$tool" ]; then - for seq in bold md smso; do # 'smso' is last - bold="`$dir/$tool $seq 2>/dev/null`" - if [ ".$bold" != . ]; then - term_bold="$bold" - break - fi - done - if [ ".$term_bold" != . ]; then - for seq in sgr0 me rmso reset; do # 'reset' is last - norm="`$dir/$tool $seq 2>/dev/null`" - if [ ".$norm" != . ]; then - term_norm="$norm" - break - fi - done - fi - break - fi - done - if [ ".$term_bold" != . -a ".$term_norm" != . ]; then - break; - fi - done - ;; - esac - if [ ".$term_bold" = . -o ".$term_norm" = . ]; then - echo "$msgprefix:Warning: unable to determine terminal sequence for bold mode" 1>&2 - fi - fi - - # determine user name - username='' - if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[uU]'`" != . ]; then - username="$LOGNAME" - if [ ".$username" = . ]; then - username="$USER" - if [ ".$username" = . ]; then - username="`(whoami) 2>/dev/null |\ - awk '{ printf("%s", $1); }'`" - if [ ".$username" = . ]; then - username="`(who am i) 2>/dev/null |\ - awk '{ printf("%s", $1); }'`" - if [ ".$username" = . ]; then - username='unknown' - fi - fi - fi - fi - fi - - # determine user id - userid='' - if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%U'`" != . ]; then - userid="`(id -u) 2>/dev/null`" - if [ ".$userid" = . ]; then - str="`(id) 2>/dev/null`" - if [ ".`echo $str | grep '^uid[ ]*=[ ]*[0-9]*('`" != . ]; then - userid=`echo $str | sed -e 's/^uid[ ]*=[ ]*//' -e 's/(.*//'` - fi - if [ ".$userid" = . ]; then - userid=`egrep "^${username}:" /etc/passwd 2>/dev/null | \ - sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'` - if [ ".$userid" = . ]; then - userid=`(ypcat passwd) 2>/dev/null | - egrep "^${username}:" | \ - sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'` - if [ ".$userid" = . ]; then - userid='?' - fi - fi - fi - fi - fi - - # determine host name - hostname='' - if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%h'`" != . ]; then - hostname="`(uname -n) 2>/dev/null |\ - awk '{ printf("%s", $1); }'`" - if [ ".$hostname" = . ]; then - hostname="`(hostname) 2>/dev/null |\ - awk '{ printf("%s", $1); }'`" - if [ ".$hostname" = . ]; then - hostname='unknown' - fi - fi - case $hostname in - *.* ) - domainname=".`echo $hostname | cut -d. -f2-`" - hostname="`echo $hostname | cut -d. -f1`" - ;; - esac - fi - - # determine domain name - domainname='' - if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%d'`" != . ]; then - if [ ".$domainname" = . ]; then - if [ -f /etc/resolv.conf ]; then - domainname="`egrep '^[ ]*domain' /etc/resolv.conf | head -1 |\ - sed -e 's/.*domain//' \ - -e 's/^[ ]*//' -e 's/^ *//' -e 's/^ *//' \ - -e 's/^\.//' -e 's/^/./' |\ - awk '{ printf("%s", $1); }'`" - if [ ".$domainname" = . ]; then - domainname="`egrep '^[ ]*search' /etc/resolv.conf | head -1 |\ - sed -e 's/.*search//' \ - -e 's/^[ ]*//' -e 's/^ *//' -e 's/^ *//' \ - -e 's/ .*//' -e 's/ .*//' \ - -e 's/^\.//' -e 's/^/./' |\ - awk '{ printf("%s", $1); }'`" - fi - fi - fi - fi - - # determine current time - time_day='' - time_month='' - time_year='' - time_monthname='' - if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[DMYm]'`" != . ]; then - time_day=`date '+%d'` - time_month=`date '+%m'` - time_year=`date '+%Y' 2>/dev/null` - if [ ".$time_year" = . ]; then - time_year=`date '+%y'` - case $time_year in - [5-9][0-9]) time_year="19$time_year" ;; - [0-4][0-9]) time_year="20$time_year" ;; - esac - fi - case $time_month in - 1|01) time_monthname='Jan' ;; - 2|02) time_monthname='Feb' ;; - 3|03) time_monthname='Mar' ;; - 4|04) time_monthname='Apr' ;; - 5|05) time_monthname='May' ;; - 6|06) time_monthname='Jun' ;; - 7|07) time_monthname='Jul' ;; - 8|08) time_monthname='Aug' ;; - 9|09) time_monthname='Sep' ;; - 10) time_monthname='Oct' ;; - 11) time_monthname='Nov' ;; - 12) time_monthname='Dec' ;; - esac - fi - - # expand special ``%x'' constructs - if [ ".$opt_e" = .yes ]; then - text=`echo $seo "$text" |\ - sed -e "s/%B/${term_bold}/g" \ - -e "s/%b/${term_norm}/g" \ - -e "s/%u/${username}/g" \ - -e "s/%U/${userid}/g" \ - -e "s/%h/${hostname}/g" \ - -e "s/%d/${domainname}/g" \ - -e "s/%D/${time_day}/g" \ - -e "s/%M/${time_month}/g" \ - -e "s/%Y/${time_year}/g" \ - -e "s/%m/${time_monthname}/g" 2>/dev/null` - fi - - # create output - if [ .$opt_n = .no ]; then - echo $seo "$text" - else - # the harder part: echo -n is best, because - # awk may complain about some \xx sequences. - if [ ".$minusn" != . ]; then - echo $seo $minusn "$text" - else - echo dummy | awk '{ printf("%s", TEXT); }' TEXT="$text" - fi - fi - ;; - -install ) - ## - ## install -- Install a program, script or datafile - ## Copyright (c) 1997-2000 Ralf S. Engelschall - ## Originally written for shtool - ## - - src="$1" - dst="$2" - - # If destination is a directory, append the input filename - if [ -d $dst ]; then - dst=`echo "$dst" | sed -e 's:/$::'` - dstfile=`echo "$src" | sed -e 's;.*/\([^/]*\)$;\1;'` - dst="$dst/$dstfile" - fi - - # Add a possible extension to src and dst - if [ ".$opt_e" != . ]; then - src="$src$opt_e" - dst="$dst$opt_e" - fi - - # Check for correct arguments - if [ ".$src" = ".$dst" ]; then - echo "$msgprefix:Error: source and destination are the same" 1>&2 - exit 1 - fi - - # Make a temp file name in the destination directory - dstdir=`echo $dst | sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;' -e 's;^$;.;'` - dsttmp="$dstdir/#INST@$$#" - - # Verbosity - if [ ".$opt_v" = .yes ]; then - echo "$src -> $dst" 1>&2 - fi - - # Copy or move the file name to the temp name - # (because we might be not allowed to change the source) - if [ ".$opt_C" = .yes ]; then - opt_c=yes - fi - if [ ".$opt_c" = .yes ]; then - if [ ".$opt_t" = .yes ]; then - echo "cp $src $dsttmp" 1>&2 - fi - cp $src $dsttmp || exit $? - else - if [ ".$opt_t" = .yes ]; then - echo "mv $src $dsttmp" 1>&2 - fi - mv $src $dsttmp || exit $? - fi - - # Adjust the target file - # (we do chmod last to preserve setuid bits) - if [ ".$opt_s" = .yes ]; then - if [ ".$opt_t" = .yes ]; then - echo "strip $dsttmp" 1>&2 - fi - strip $dsttmp || exit $? - fi - if [ ".$opt_o" != . ]; then - if [ ".$opt_t" = .yes ]; then - echo "chown $opt_o $dsttmp" 1>&2 - fi - chown $opt_o $dsttmp || exit $? - fi - if [ ".$opt_g" != . ]; then - if [ ".$opt_t" = .yes ]; then - echo "chgrp $opt_g $dsttmp" 1>&2 - fi - chgrp $opt_g $dsttmp || exit $? - fi - if [ ".$opt_m" != . ]; then - if [ ".$opt_t" = .yes ]; then - echo "chmod $opt_m $dsttmp" 1>&2 - fi - chmod $opt_m $dsttmp || exit $? - fi - - # Determine whether to do a quick install - # (has to be done _after_ the strip was already done) - quick=no - if [ ".$opt_C" = .yes ]; then - if [ -r $dst ]; then - if cmp -s $src $dst; then - quick=yes - fi - fi - fi - - # Finally install the file to the real destination - if [ $quick = yes ]; then - if [ ".$opt_t" = .yes ]; then - echo "rm -f $dsttmp" 1>&2 - fi - rm -f $dsttmp - else - if [ ".$opt_t" = .yes ]; then - echo "rm -f $dst && mv $dsttmp $dst" 1>&2 - fi - rm -f $dst && mv $dsttmp $dst - fi - ;; - -mkdir ) - ## - ## mkdir -- Make one or more directories - ## Copyright (c) 1996-2000 Ralf S. Engelschall - ## Originally written for public domain by Noah Friedman - ## Cleaned up and enhanced for shtool - ## - - errstatus=0 - for p in ${1+"$@"}; do - # if the directory already exists... - if [ -d "$p" ]; then - if [ ".$opt_f" = .no ] && [ ".$opt_p" = .no ]; then - echo "$msgprefix:Error: directory already exists: $p" 1>&2 - errstatus=1 - break - else - continue - fi - fi - # if the directory has to be created... - if [ ".$opt_p" = .no ]; then - if [ ".$opt_t" = .yes ]; then - echo "mkdir $p" 1>&2 - fi - mkdir $p || errstatus=$? - else - # the smart situation - set fnord `echo ":$p" |\ - sed -e 's/^:\//%/' \ - -e 's/^://' \ - -e 's/\// /g' \ - -e 's/^%/\//'` - shift - pathcomp='' - for d in ${1+"$@"}; do - pathcomp="$pathcomp$d" - case "$pathcomp" in - -* ) pathcomp="./$pathcomp" ;; - esac - if [ ! -d "$pathcomp" ]; then - if [ ".$opt_t" = .yes ]; then - echo "mkdir $pathcomp" 1>&2 - fi - mkdir $pathcomp || errstatus=$? - if [ ".$opt_m" != . ]; then - if [ ".$opt_t" = .yes ]; then - echo "chmod $opt_m $pathcomp" 1>&2 - fi - chmod $opt_m $pathcomp || errstatus=$? - fi - fi - pathcomp="$pathcomp/" - done - fi - done - exit $errstatus - ;; - -esac - -exit 0 - -##EOF## diff --git a/aux/binpac/src/Makefile.am b/aux/binpac/src/Makefile.am deleted file mode 100644 index 2dc2816c35..0000000000 --- a/aux/binpac/src/Makefile.am +++ /dev/null @@ -1,62 +0,0 @@ -## Process this file with automake to produce Makefile.in - -AM_YFLAGS = -d -t -v -AM_CPPFLAGS = -W -Wall -Wno-unused - -noinst_PROGRAMS = binpac - -binpac_SOURCES = \ - pac_scan.ll pac_parse.yy \ - pac_action.cc \ - pac_analyzer.cc \ - pac_array.cc \ - pac_attr.cc \ - pac_btype.cc \ - pac_case.cc \ - pac_conn.cc \ - pac_context.cc \ - pac_cstr.cc \ - pac_datadep.cc \ - pac_dataptr.cc \ - pac_dataunit.cc \ - pac_decl.cc \ - pac_embedded.cc \ - pac_enum.cc \ - pac_expr.cc \ - pac_exttype.cc \ - pac_field.cc \ - pac_flow.cc \ - pac_func.cc \ - pac_id.cc \ - pac_inputbuf.cc \ - pac_let.cc \ - pac_param.cc \ - pac_paramtype.cc \ - pac_primitive.cc \ - pac_record.cc \ - pac_redef.cc \ - pac_regex.cc \ - pac_state.cc \ - pac_strtype.cc \ - pac_type.cc \ - pac_typedecl.cc \ - pac_withinput.cc \ - pac_output.cc pac_utils.cc pac_exception.cc \ - pac_main.cc \ - pac_action.h pac_analyzer.h pac_array.h pac_attr.h pac_btype.h \ - pac_case.h pac_cclass.h pac_common.h pac_conn.h pac_context.h \ - pac_cstr.h pac_ctype.h pac_datadep.h pac_dataptr.h pac_dataunit.h \ - pac_dbg.h pac_decl-inl.h pac_decl.h pac_embedded.h pac_enum.h \ - pac_exception.h pac_expr.h pac_exttype.h pac_field.h pac_flow.h \ - pac_func.h pac_id.h pac_inputbuf.h pac_let.h pac_number.h \ - pac_output.h pac_param.h pac_paramtype.h pac_parse.h pac_primitive.h \ - pac_record.h pac_redef.h pac_regex.h pac_state.h pac_strtype.h \ - pac_type.h pac_typedecl.h pac_utils.h pac_varfield.h pac_withinput.h - -EXTRA_DIST = pac_expr.def pac_type.def pac_externtype.def - -DISTCLEANFILES = pac_parse.cc pac_parse.h pac_scan.cc y.output - -# Manual rules below: - -pac_scan.o: pac_parse.h diff --git a/aux/binpac/src/pac_action.cc b/aux/binpac/src/pac_action.cc deleted file mode 100644 index 0b1ac3574f..0000000000 --- a/aux/binpac/src/pac_action.cc +++ /dev/null @@ -1,119 +0,0 @@ -#include "pac_embedded.h" -#include "pac_exception.h" -#include "pac_id.h" -#include "pac_output.h" -#include "pac_type.h" -#include "pac_typedecl.h" -#include "pac_utils.h" - -#include "pac_action.h" - -AnalyzerAction::AnalyzerAction(ID *action_id, - When when, - ActionParam *param, - EmbeddedCode *code) - : AnalyzerElement(ACTION), - action_id_(action_id), - when_(when), - param_(param), - code_(code), - analyzer_(0) - { - } - -AnalyzerAction::~AnalyzerAction() - { - delete action_id_; - delete param_; - delete code_; - } - -string AnalyzerAction::action_function() const - { - return strfmt("Action_%s", action_id_->Name()); - } - -void AnalyzerAction::InstallHook(AnalyzerDecl *analyzer) - { - ASSERT(0); - analyzer_ = analyzer; - // param_->MainDataType()->InstallAction(this); - } - -void AnalyzerAction::GenCode(Output *out_h, Output *out_cc, AnalyzerDecl *decl) - { - Env action_func_env(decl->env(), this); - action_func_env.AddID(param_->id(), - TEMP_VAR, - param_->DataType()); - action_func_env.SetEvaluated(param_->id()); - - string action_func_proto = - strfmt("%s(%s)", - action_function().c_str(), - ParamDecls(&action_func_env).c_str()); - - out_h->println("void %s;", action_func_proto.c_str()); - - out_cc->println("void %s::%s", - decl->class_name().c_str(), - action_func_proto.c_str()); - out_cc->inc_indent(); - out_cc->println("{"); - - code_->GenCode(out_cc, &action_func_env); - - out_cc->println(""); - out_cc->println("}"); - out_cc->dec_indent(); - out_cc->println(""); - } - -string AnalyzerAction::ParamDecls(Env *env) const - { - return param_->DeclStr(env); - } - -Type *ActionParam::MainDataType() const - { - // Note: this is not equal to DataType() - Type *main_type = TypeDecl::LookUpType(type()->type_id()); - - if ( ! main_type ) - { - throw Exception(type()->type_id(), - "type not defined"); - } - - return main_type; - } - -Type *ActionParam::DataType() const - { - Type *main_type = MainDataType(); - - if ( ! type()->field_id() ) - { - return main_type; - } - else - { - Type *member_type = - main_type->MemberDataType(type()->field_id()); - if ( ! member_type ) - { - throw Exception(type()->field_id(), - fmt("cannot find member type for `%s.%s'", - type()->type_id()->Name(), - type()->field_id()->Name())); - } - return member_type; - } - } - -string ActionParam::DeclStr(Env *env) const - { - return strfmt("%s %s", - DataType()->DataTypeStr().c_str(), - env->LValue(id())); - } diff --git a/aux/binpac/src/pac_action.h b/aux/binpac/src/pac_action.h deleted file mode 100644 index df0828b823..0000000000 --- a/aux/binpac/src/pac_action.h +++ /dev/null @@ -1,74 +0,0 @@ -#ifndef pac_action_h -#define pac_action_h - -// Classes representing analyzer actions. - -#include "pac_common.h" -#include "pac_analyzer.h" - -class AnalyzerAction : public AnalyzerElement -{ -public: - enum When { BEFORE, AFTER }; - - AnalyzerAction(ID *action_id, - When when, - ActionParam *param, - EmbeddedCode *code); - - ~AnalyzerAction(); - - When when() const { return when_; } - ActionParam *param() const { return param_; } - AnalyzerDecl *analyzer() const { return analyzer_; } - string action_function() const; - - // Generate function prototype and code for the action - void GenCode(Output *out_h, Output *out_cc, AnalyzerDecl *decl); - - // Install the hook at the corresponding data type parsing - // function to invoke the action. - void InstallHook(AnalyzerDecl *analyzer); - -private: - string ParamDecls(Env *env) const; - - ID *action_id_; - When when_; - ActionParam *param_; - EmbeddedCode *code_; - AnalyzerDecl *analyzer_; -}; - -class ActionParam -{ -public: - ActionParam(const ID *id, ActionParamType *type) - : id_(id), type_(type) {} - - const ID *id() const { return id_; } - ActionParamType *type() const { return type_; } - - Type *MainDataType() const; - Type *DataType() const; - string DeclStr(Env *env) const; - -private: - const ID *id_; - ActionParamType *type_; -}; - -class ActionParamType -{ -public: - ActionParamType(const ID *type_id, const ID *field_id = 0) - : type_id_(type_id), field_id_(field_id) {} - - const ID *type_id() const { return type_id_; } - const ID *field_id() const { return field_id_; } - -protected: - const ID *type_id_, *field_id_; -}; - -#endif // pac_action_h diff --git a/aux/binpac/src/pac_analyzer.cc b/aux/binpac/src/pac_analyzer.cc deleted file mode 100644 index 0c01190a9d..0000000000 --- a/aux/binpac/src/pac_analyzer.cc +++ /dev/null @@ -1,358 +0,0 @@ -#include "pac_action.h" -#include "pac_context.h" -#include "pac_embedded.h" -#include "pac_exception.h" -#include "pac_expr.h" -#include "pac_flow.h" -#include "pac_func.h" -#include "pac_output.h" -#include "pac_param.h" -#include "pac_paramtype.h" -#include "pac_state.h" -#include "pac_type.h" -#include "pac_varfield.h" - -#include "pac_analyzer.h" - -AnalyzerDecl::AnalyzerDecl(ID *id, - DeclType decl_type, - ParamList *params) - : TypeDecl(id, params, new DummyType()) - { - decl_type_ = decl_type; - - statevars_ = new StateVarList(); - actions_ = new AnalyzerActionList(); - helpers_ = new AnalyzerHelperList(); - functions_ = new FunctionList(); - - constructor_helpers_ = new AnalyzerHelperList(); - destructor_helpers_ = new AnalyzerHelperList(); - eof_helpers_ = new AnalyzerHelperList(); - - SetAnalyzerContext(); - - env_ = 0; - } - -AnalyzerDecl::~AnalyzerDecl() - { - delete_list(StateVarList, statevars_); - delete_list(AnalyzerActionList, actions_); - delete_list(AnalyzerHelperList, helpers_); - delete_list(FunctionList, functions_); - delete_list(ParamList, params_); - delete_list(AnalyzerHelperList, constructor_helpers_); - delete_list(AnalyzerHelperList, destructor_helpers_); - delete_list(AnalyzerHelperList, eof_helpers_); - } - -void AnalyzerDecl::AddElements(AnalyzerElementList *elemlist) - { - ASSERT(! env_); - foreach(i, AnalyzerElementList, elemlist) - { - AnalyzerElement *elem = *i; - switch ( elem->type() ) - { - case AnalyzerElement::STATE: - { - ASSERT(0); - AnalyzerState *state_elem = - (AnalyzerState *) elem; - statevars_->insert( - statevars_->end(), - state_elem->statevars()->begin(), - state_elem->statevars()->end()); - } - break; - case AnalyzerElement::ACTION: - { - ASSERT(0); - AnalyzerAction *action_elem = - (AnalyzerAction *) elem; - actions_->push_back(action_elem); - } - break; - case AnalyzerElement::HELPER: - { - AnalyzerHelper *helper_elem = - (AnalyzerHelper *) elem; - - switch ( helper_elem->helper_type() ) - { - case AnalyzerHelper::INIT_CODE: - constructor_helpers_->push_back(helper_elem); - break; - case AnalyzerHelper::CLEANUP_CODE: - destructor_helpers_->push_back(helper_elem); - break; - case AnalyzerHelper::EOF_CODE: - eof_helpers_->push_back(helper_elem); - break; - default: - helpers_->push_back(helper_elem); - } - } - break; - case AnalyzerElement::FUNCTION: - { - AnalyzerFunction *func_elem = - (AnalyzerFunction *) elem; - Function *func = func_elem->function(); - func->set_analyzer_decl(this); - functions_->push_back(func); - } - break; - case AnalyzerElement::FLOW: - { - AnalyzerFlow *flow_elem = - (AnalyzerFlow *) elem; - ProcessFlowElement(flow_elem); - } - break; - case AnalyzerElement::DATAUNIT: - { - AnalyzerDataUnit *dataunit_elem = - (AnalyzerDataUnit *) elem; - ProcessDataUnitElement(dataunit_elem); - } - break; - } - } - } - -string AnalyzerDecl::class_name() const - { - return id_->Name(); - } - -void AnalyzerDecl::Prepare() - { - TypeDecl::Prepare(); - - ASSERT(statevars_->empty()); - ASSERT(actions_->empty()); - - foreach(i, FunctionList, functions_) - { - Function *function = *i; - function->Prepare(env_); - } - foreach(i, StateVarList, statevars_) - { - StateVar *statevar = *i; - env_->AddID(statevar->id(), STATE_VAR, statevar->type()); - } - foreach(i, AnalyzerActionList, actions_) - { - AnalyzerAction *action = *i; - action->InstallHook(this); - } - } - -void AnalyzerDecl::GenForwardDeclaration(Output* out_h) - { - out_h->println("class %s;", class_name().c_str()); - foreach(i, FunctionList, functions_) - { - Function *function = *i; - function->GenForwardDeclaration(out_h); - } - } - -void AnalyzerDecl::GenActions(Output *out_h, Output *out_cc) - { - foreach(i, AnalyzerActionList, actions_) - { - (*i)->GenCode(out_h, out_cc, this); - } - } - -void AnalyzerDecl::GenHelpers(Output *out_h, Output *out_cc) - { - foreach(i, AnalyzerHelperList, helpers_) - { - (*i)->GenCode(out_h, out_cc, this); - } - } - -void AnalyzerDecl::GenPubDecls(Output *out_h, Output *out_cc) - { - TypeDecl::GenPubDecls(out_h, out_cc); - - GenProcessFunc(out_h, out_cc); - GenGapFunc(out_h, out_cc); - GenEOFFunc(out_h, out_cc); - out_h->println(""); - - if ( ! functions_->empty() ) - { - out_h->println("// Functions"); - GenFunctions(out_h, out_cc); - out_h->println(""); - } - - // TODO: export public state variables - } - -void AnalyzerDecl::GenPrivDecls(Output *out_h, Output *out_cc) - { - TypeDecl::GenPrivDecls(out_h, out_cc); - - if ( ! helpers_->empty() ) - { - out_h->println(""); - out_h->println("// Additional members"); - GenHelpers(out_h, out_cc); - } - - // TODO: declare state variables - } - -void AnalyzerDecl::GenInitCode(Output *out_cc) - { - TypeDecl::GenInitCode(out_cc); - foreach(i, AnalyzerHelperList, constructor_helpers_) - { - (*i)->GenCode(0, out_cc, this); - } - } - -void AnalyzerDecl::GenCleanUpCode(Output *out_cc) - { - TypeDecl::GenCleanUpCode(out_cc); - foreach(i, AnalyzerHelperList, destructor_helpers_) - { - (*i)->GenCode(0, out_cc, this); - } - } - -void AnalyzerDecl::GenStateVarDecls(Output *out_h) - { - foreach(i, StateVarList, statevars_) - { - StateVar *var = *i; - var->GenDecl(out_h, env_); - } - } - -void AnalyzerDecl::GenStateVarSetFunctions(Output *out_h) - { - foreach(i, StateVarList, statevars_) - { - StateVar *var = *i; - var->GenSetFunction(out_h, env_); - } - } - -void AnalyzerDecl::GenStateVarInitCode(Output *out_cc) - { - foreach(i, StateVarList, statevars_) - { - StateVar *var = *i; - var->GenInitCode(out_cc, env_); - } - } - -void AnalyzerDecl::GenStateVarCleanUpCode(Output *out_cc) - { - foreach(i, StateVarList, statevars_) - { - StateVar *var = *i; - var->GenCleanUpCode(out_cc, env_); - } - } - -void AnalyzerDecl::GenFunctions(Output *out_h, Output *out_cc) - { - foreach(i, FunctionList, functions_) - { - Function *function = *i; - function->GenCode(out_h, out_cc); - } - } - -AnalyzerState::~AnalyzerState() - { - // Note: do not delete elements of statevars_, because they - // are referenced by the AnalyzerDecl. - delete statevars_; - } - -AnalyzerHelper::~AnalyzerHelper() - { - delete code_; - } - -void AnalyzerHelper::GenCode(Output *out_h, Output *out_cc, AnalyzerDecl *decl) - { - Output *out = 0; - switch ( helper_type_ ) - { - case MEMBER_DECLS: - out = out_h; - break; - case INIT_CODE: - case CLEANUP_CODE: - case EOF_CODE: - out = out_cc; - break; - } - ASSERT(out); - code()->GenCode(out, decl->env()); - } - -FlowField::FlowField(ID *flow_id, ParameterizedType *flow_type) - : Field(FLOW_FIELD, - TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, - flow_id, flow_type) - { - } - -void FlowField::GenInitCode(Output *out_cc, Env *env) - { - type_->GenPreParsing(out_cc, env); - } - -AnalyzerFlow::AnalyzerFlow(Direction dir, ID *type_id, ExprList *params) - : AnalyzerElement(FLOW), - dir_(dir), - type_id_(type_id) - { - if ( ! params ) - params = new ExprList(); - - // Add "this" to the list of params - params->insert(params->begin(), new Expr(this_id->clone())); - - ID *flow_id = ((dir == UP) ? upflow_id : downflow_id)->clone(); - - ParameterizedType *flow_type = new ParameterizedType(type_id_, params); - - flow_field_ = new FlowField(flow_id, flow_type); - - flow_decl_ = 0; - } - -AnalyzerFlow::~AnalyzerFlow() - { - delete flow_field_; - } - -FlowDecl *AnalyzerFlow::flow_decl() - { - DEBUG_MSG("Getting flow_decl for %s\n", type_id_->Name()); - if ( ! flow_decl_ ) - { - Decl *decl = Decl::LookUpDecl(type_id_); - if ( decl && decl->decl_type() == Decl::FLOW ) - flow_decl_ = static_cast(decl); - if ( ! flow_decl_ ) - { - throw Exception(this, - "cannot find the flow declaration"); - } - } - return flow_decl_; - } diff --git a/aux/binpac/src/pac_analyzer.h b/aux/binpac/src/pac_analyzer.h deleted file mode 100644 index a5fd5245aa..0000000000 --- a/aux/binpac/src/pac_analyzer.h +++ /dev/null @@ -1,168 +0,0 @@ -#ifndef pac_analyzer_h -#define pac_analyzer_h - -#include "pac_common.h" -#include "pac_field.h" -#include "pac_typedecl.h" - -class AnalyzerElement; -class AnalyzerState; -class AnalyzerAction; // defined in pac_action.h -class AnalyzerHelper; -class AnalyzerFlow; -class AnalyzerDataUnit; -class AnalyzerFunction; -class ConnDecl; -class FlowDecl; -typedef vector AnalyzerHelperList; -typedef vector FunctionList; - -class AnalyzerDecl : public TypeDecl -{ -public: - AnalyzerDecl(ID *id, DeclType decl_type, ParamList *params); - ~AnalyzerDecl(); - - void AddElements(AnalyzerElementList *elemlist); - - void Prepare(); - void GenForwardDeclaration(Output *out_h); - // void GenCode(Output *out_h, Output *out_cc); - - void GenInitCode(Output *out_cc); - void GenCleanUpCode(Output *out_cc); - - string class_name() const; - // string cookie_name() const; - -protected: - virtual void ProcessFlowElement(AnalyzerFlow *flow_elem) = 0; - virtual void ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem) = 0; - - // Generate public/private declarations for member functions and - // variables - void GenPubDecls(Output *out_h, Output *out_cc); - void GenPrivDecls(Output *out_h, Output *out_cc); - - // Generate the NewData() function - virtual void GenProcessFunc(Output *out_h, Output *out_cc) = 0; - - // Generate the NewGap() function - virtual void GenGapFunc(Output *out_h, Output *out_cc) = 0; - - // Generate the FlowEOF() function - virtual void GenEOFFunc(Output *out_h, Output *out_cc) = 0; - - // Generate the functions - void GenFunctions(Output *out_h, Output *out_cc); - - // Generate the action functions - void GenActions(Output *out_h, Output *out_cc); - - // Generate the helper code segments - void GenHelpers(Output *out_h, Output *out_cc); - - // Generate declarations for state variables and their set functions - void GenStateVarDecls(Output *out_h); - void GenStateVarSetFunctions(Output *out_h); - - // Generate code for initializing and cleaning up (including - // memory de-allocating) state variables - void GenStateVarInitCode(Output *out_cc); - void GenStateVarCleanUpCode(Output *out_cc); - - StateVarList *statevars_; - AnalyzerActionList *actions_; - AnalyzerHelperList *helpers_; - FunctionList *functions_; - - AnalyzerHelperList *constructor_helpers_; - AnalyzerHelperList *destructor_helpers_; - AnalyzerHelperList *eof_helpers_; -}; - -class AnalyzerElement : public Object -{ -public: - enum ElementType { STATE, ACTION, FUNCTION, HELPER, FLOW, DATAUNIT }; - AnalyzerElement(ElementType type) - : type_(type) {} - virtual ~AnalyzerElement() {} - - ElementType type() const { return type_; } - -private: - ElementType type_; -}; - -// A collection of variables representing analyzer states. -class AnalyzerState : public AnalyzerElement -{ -public: - AnalyzerState(StateVarList *statevars) - : AnalyzerElement(STATE), - statevars_(statevars) {} - ~AnalyzerState(); - - StateVarList *statevars() const { return statevars_; } - -private: - StateVarList *statevars_; -}; - -// A collection of embedded C++ code -class AnalyzerHelper : public AnalyzerElement -{ -public: - enum Type { - MEMBER_DECLS, - INIT_CODE, - CLEANUP_CODE, - EOF_CODE, - }; - AnalyzerHelper(Type helper_type, EmbeddedCode *code) - : AnalyzerElement(HELPER), - helper_type_(helper_type), - code_(code) {} - ~AnalyzerHelper(); - - Type helper_type() const { return helper_type_; } - - void GenCode(Output *out_h, Output *out_cc, AnalyzerDecl *decl); - - EmbeddedCode *code() const { return code_; } - -private: - Type helper_type_; - EmbeddedCode *code_; -}; - -// The type and parameters of (uni-directional) flows of a connection. - -class FlowField : public Field -{ -public: - FlowField(ID *flow_id, ParameterizedType *flow_type); - void GenInitCode(Output *out, Env *env); -}; - -class AnalyzerFlow : public AnalyzerElement -{ -public: - enum Direction { UP, DOWN }; - AnalyzerFlow(Direction dir, ID *type_id, ExprList *params); - ~AnalyzerFlow(); - - Direction dir() const { return dir_; } - FlowField *flow_field() const { return flow_field_; } - - FlowDecl *flow_decl(); - -private: - Direction dir_; - ID *type_id_; - FlowField *flow_field_; - FlowDecl *flow_decl_; -}; - -#endif // pac_analyzer_h diff --git a/aux/binpac/src/pac_array.cc b/aux/binpac/src/pac_array.cc deleted file mode 100644 index 7477ba050b..0000000000 --- a/aux/binpac/src/pac_array.cc +++ /dev/null @@ -1,700 +0,0 @@ -#include "pac_attr.h" -#include "pac_dataptr.h" -#include "pac_exception.h" -#include "pac_expr.h" -#include "pac_exttype.h" -#include "pac_id.h" -#include "pac_number.h" -#include "pac_output.h" -#include "pac_utils.h" -#include "pac_varfield.h" - -#include "pac_array.h" - -ArrayType::ArrayType(Type *elemtype, Expr *length) - : Type(ARRAY), elemtype_(elemtype), length_(length) - { - init(); - - switch ( elemtype_->tot() ) - { - case BUILTIN: - case PARAMETERIZED: - case STRING: - case EXTERN: - break; - - case ARRAY: - case CASE: - case DUMMY: - case EMPTY: - case RECORD: - case UNDEF: - ASSERT(0); - break; - } - } - -void ArrayType::init() - { - arraylength_var_field_ = 0; - elem_it_var_field_ = 0; - elem_var_field_ = 0; - elem_dataptr_var_field_ = 0; - elem_input_var_field_ = 0; - - elem_dataptr_until_expr_ = 0; - - end_of_array_loop_label_ = "@@@"; - - vector_str_ = strfmt("vector<%s>", elemtype_->DataTypeStr().c_str()); - - datatype_str_ = strfmt("%s *", vector_str_.c_str()); - - attr_generic_until_expr_ = 0; - attr_until_element_expr_ = 0; - attr_until_input_expr_ = 0; - } - -ArrayType::~ArrayType() - { - delete arraylength_var_field_; - delete elem_it_var_field_; - delete elem_var_field_; - delete elem_dataptr_var_field_; - delete elem_input_var_field_; - - delete elem_dataptr_until_expr_; - } - -Type *ArrayType::DoClone() const - { - Type *elemtype = elemtype_->Clone(); - if ( ! elemtype ) - return 0; - return new ArrayType(elemtype, length_); - } - -bool ArrayType::DefineValueVar() const - { - return true; - } - -string ArrayType::DataTypeStr() const - { - return datatype_str_; - } - -Type *ArrayType::ElementDataType() const - { - return elemtype_; - } - -string ArrayType::EvalElement(const string &array, const string &index) const - { - return strfmt("(*(%s))[%s]", array.c_str(), index.c_str()); - } - -const ID *ArrayType::arraylength_var() const - { - return arraylength_var_field_ ? arraylength_var_field_->id() : 0; - } - -const ID *ArrayType::elem_it_var() const - { - return elem_it_var_field_ ? elem_it_var_field_->id() : 0; - } - -const ID *ArrayType::elem_var() const - { - return elem_var_field_ ? elem_var_field_->id() : 0; - } - -const ID *ArrayType::elem_dataptr_var() const - { - return elem_dataptr_var_field_ ? elem_dataptr_var_field_->id() : 0; - } - -const ID *ArrayType::elem_input_var() const - { - return elem_input_var_field_ ? elem_input_var_field_->id() : 0; - } - -void ArrayType::ProcessAttr(Attr *a) - { - Type::ProcessAttr(a); - - switch ( a->type() ) - { - case ATTR_RESTOFDATA: - { - if ( elemtype_->StaticSize(env()) != 1 ) - { - throw Exception(elemtype_, - "&restofdata can be applied" - " to only byte arrays"); - } - if ( length_ ) - { - throw Exception(length_, - "&restofdata cannot be applied" - " to arrays with specified length"); - } - attr_restofdata_ = true; - // As the array automatically extends to the end of - // data, we do not have to check boundary. - SetBoundaryChecked(); - } - break; - - case ATTR_RESTOFFLOW: - attr_restofflow_ = true; - // TODO: handle &restofflow - break; - - case ATTR_UNTIL: - { - bool ref_element = a->expr()->HasReference(element_macro_id); - bool ref_input = a->expr()->HasReference(input_macro_id); - if ( ref_element && ref_input ) - { - throw Exception(a->expr(), - "cannot reference both $element and $input " - "in the same &until---please separate them."); - } - - if ( ref_element ) - { - if ( attr_until_element_expr_ ) - { - throw Exception(a->expr(), - "multiple &until on $element"); - } - attr_until_element_expr_ = a->expr(); - } - else if ( ref_input ) - { - if ( attr_until_input_expr_ ) - { - throw Exception(a->expr(), - "multiple &until on $input"); - } - attr_until_input_expr_ = a->expr(); - } - else - { - if ( attr_generic_until_expr_ ) - { - throw Exception(a->expr(), - "multiple &until condition"); - } - attr_generic_until_expr_ = a->expr(); - } - } - break; - - default: - break; - } - } - -void ArrayType::Prepare(Env *env, int flags) - { - if ( flags & TO_BE_PARSED ) - { - ID *arraylength_var = new ID(fmt("%s__arraylength", value_var()->Name())); - ID *elem_var = new ID(fmt("%s__elem", value_var()->Name())); - ID *elem_it_var = new ID(fmt("%s__it", elem_var->Name())); - - elem_var_field_ = - new ParseVarField(Field::CLASS_MEMBER, elem_var, elemtype_); - AddField(elem_var_field_); - - if ( incremental_parsing() ) - { - arraylength_var_field_ = - new PrivVarField(arraylength_var, extern_type_int->Clone()); - elem_it_var_field_ = - new PrivVarField(elem_it_var, extern_type_int->Clone()); - - AddField(arraylength_var_field_); - AddField(elem_it_var_field_); - } - else - { - arraylength_var_field_ = - new TempVarField(arraylength_var, extern_type_int->Clone()); - elem_it_var_field_ = - new TempVarField(elem_it_var, extern_type_int->Clone()); - - arraylength_var_field_->Prepare(env); - elem_it_var_field_->Prepare(env); - - // Add elem_dataptr_var only when not parsing incrementally - ID *elem_dataptr_var = - new ID(fmt("%s__dataptr", elem_var->Name())); - elem_dataptr_var_field_ = new TempVarField( - elem_dataptr_var, - extern_type_const_byteptr->Clone()); - elem_dataptr_var_field_->Prepare(env); - - // until(dataptr >= end_of_data) - elem_dataptr_until_expr_ = new Expr( - Expr::EXPR_GE, - new Expr(elem_dataptr_var->clone()), - new Expr(end_of_data->clone())); - } - - if ( attr_until_input_expr_ ) - { - elemtype_->SetUntilCheck(this); - } - - end_of_array_loop_label_ = strfmt("end_of_%s", value_var()->Name()); - } - - Type::Prepare(env, flags); - } - -void ArrayType::GenArrayLength(Output *out_cc, Env *env, const DataPtr& data) - { - if ( env->Evaluated(arraylength_var()) ) - return; - - if ( ! incremental_parsing() ) - { - arraylength_var_field_->GenTempDecls(out_cc, env); - arraylength_var_field_->GenInitCode(out_cc, env); - } - - if ( length_ ) - { - out_cc->println("%s = %s;", - env->LValue(arraylength_var()), - length_->EvalExpr(out_cc, env)); - - env->SetEvaluated(arraylength_var()); - - // Check for overlong array length. We cap it at the - // maximum data size as we won't store more elements. - out_cc->println("if ( t_begin_of_data + %s > t_end_of_data + 1 )", - env->LValue(arraylength_var())); - out_cc->inc_indent(); - out_cc->println("{"); - out_cc->println("%s = t_end_of_data - t_begin_of_data + 1;", - env->LValue(arraylength_var())); - out_cc->println("}"); - out_cc->dec_indent(); - - // Check negative array length - out_cc->println("if ( %s < 0 )", - env->LValue(arraylength_var())); - out_cc->inc_indent(); - out_cc->println("{"); - out_cc->println("%s = 0;", - env->LValue(arraylength_var())); - out_cc->println("}"); - out_cc->dec_indent(); - } - else if ( attr_restofdata_ ) - { - ASSERT(elemtype_->StaticSize(env) == 1); - out_cc->println("%s = (%s) - (%s);", - env->LValue(arraylength_var()), - env->RValue(end_of_data), - data.ptr_expr()); - env->SetEvaluated(arraylength_var()); - } - } - -void ArrayType::GenPubDecls(Output *out_h, Env *env) - { - Type::GenPubDecls(out_h, env); - - if ( declared_as_type() ) - { - out_h->println("int size() const { return %s ? %s->size() : 0; }", - env->RValue(value_var()), - env->RValue(value_var())); - out_h->println("%s operator[](int index) const { BINPAC_ASSERT(%s); return (*%s)[index]; }", - elemtype_->DataTypeConstRefStr().c_str(), - env->RValue(value_var()), - env->RValue(value_var())); - } - } - -void ArrayType::GenPrivDecls(Output *out_h, Env *env) - { - ASSERT(elem_var_field_->type() == elemtype_); - ASSERT(elemtype_->value_var()); - Type::GenPrivDecls(out_h, env); - } - -void ArrayType::GenInitCode(Output *out_cc, Env *env) - { - // Do not initiate the array here - // out_cc->println("%s = new %s;", lvalue(), vector_str_.c_str()); - out_cc->println("%s = 0;", lvalue()); - - Type::GenInitCode(out_cc, env); - if ( incremental_parsing() ) - { - out_cc->println("%s = -1;", - env->LValue(elem_it_var())); - } - } - -void ArrayType::GenCleanUpCode(Output *out_cc, Env *env) - { - Type::GenCleanUpCode(out_cc, env); - if ( elemtype_->NeedsCleanUp() ) - { - if ( ! elem_var_field_ ) - { - ID *elem_var = new ID(fmt("%s__elem", value_var()->Name())); - elem_var_field_ = - new ParseVarField( - Field::NOT_CLASS_MEMBER, - elem_var, - elemtype_); - elem_var_field_->Prepare(env); - } - - out_cc->println("if ( %s )", env->RValue(value_var())); - out_cc->inc_indent(); - out_cc->println("{"); - - out_cc->println("for ( int i = 0; i < (int) %s->size(); ++i )", - env->RValue(value_var())); - out_cc->inc_indent(); - out_cc->println("{"); - out_cc->println("%s %s = (*%s)[i];", - elemtype_->DataTypeStr().c_str(), - env->LValue(elem_var()), - lvalue()); - elemtype_->GenCleanUpCode(out_cc, env); - out_cc->println("}"); - out_cc->dec_indent(); - - out_cc->println("}"); - out_cc->dec_indent(); - } - out_cc->println("delete %s;", lvalue()); - } - -string ArrayType::GenArrayInit(Output *out_cc, Env *env, bool known_array_length) - { - string array_str; - - array_str = lvalue(); - if ( incremental_parsing() ) - { - out_cc->println("if ( %s < 0 )", - env->LValue(elem_it_var())); - out_cc->inc_indent(); - out_cc->println("{"); - out_cc->println("// Initialize only once"); - out_cc->println("%s = 0;", env->LValue(elem_it_var())); - } - - out_cc->println("%s = new %s;", - lvalue(), vector_str_.c_str()); - - if ( known_array_length ) - { - out_cc->println("%s->reserve(%s);", - lvalue(), env->RValue(arraylength_var())); - } - - if ( incremental_parsing() ) - { - out_cc->println("}"); - out_cc->dec_indent(); - } - - return array_str; - } - -void ArrayType::GenElementAssignment(Output *out_cc, Env *env, - string const &array_str, bool use_vector) - { - // Assign the element - if ( ! use_vector ) - { - out_cc->println("%s[%s] = %s;", - array_str.c_str(), - env->LValue(elem_it_var()), - env->LValue(elem_var())); - } - else - { - out_cc->println("%s->push_back(%s);", - array_str.c_str(), - env->LValue(elem_var())); - } - } - -void ArrayType::DoGenParseCode(Output *out_cc, Env *env, - const DataPtr& data, int flags) - { - GenArrayLength(out_cc, env, data); - - // Otherwise these variables are declared as member variables - if ( ! incremental_parsing() ) - { - // Declare and initialize temporary variables - elem_var_field_->GenInitCode(out_cc, env); - elem_it_var_field_->GenTempDecls(out_cc, env); - out_cc->println("%s = 0;", env->LValue(elem_it_var())); - env->SetEvaluated(elem_it_var()); - } - - /* - If the input length can be determined without parsing - individual elements, generate the boundary checking before - parsing (unless in the case of incremental parsing). - - There are two cases when the input length can be determined: - 1. The array has a static size; - 2. The array length can be computed before parsing and - each element is of constant size. - */ - - bool compute_size_var = false; - - if ( incremental_input() ) - { - // Do not compute size_var on incremental input - compute_size_var = false; - - if ( ! incremental_parsing() && - ( StaticSize(env) >= 0 || - ( env->Evaluated(arraylength_var()) && - elemtype_->StaticSize(env) >= 0 ) ) ) - { - GenBoundaryCheck(out_cc, env, data); - } - } - else - { - compute_size_var = AddSizeVar(out_cc, env); - } - - bool known_array_length = env->Evaluated(arraylength_var()); - string array_str = GenArrayInit(out_cc, env, known_array_length); - - bool use_vector = true; - - ASSERT(elem_it_var()); - - DataPtr elem_data(env, 0, 0); - - if ( elem_dataptr_var() ) - { - out_cc->println("const_byteptr %s = %s;", - env->LValue(elem_dataptr_var()), data.ptr_expr()); - env->SetEvaluated(elem_dataptr_var()); - - elem_data = DataPtr(env, elem_dataptr_var(), 0); - } - - string for_condition = known_array_length ? - strfmt("%s < %s", - env->LValue(elem_it_var()), - env->RValue(arraylength_var())) : - "/* forever */"; - - out_cc->println("for (; %s; ++%s)", - for_condition.c_str(), - env->LValue(elem_it_var())); - out_cc->inc_indent(); - out_cc->println("{"); - - if ( attr_generic_until_expr_ ) - GenUntilCheck(out_cc, env, attr_generic_until_expr_, true); - - if ( elem_dataptr_var() ) - GenUntilCheck(out_cc, env, elem_dataptr_until_expr_, false); - - elemtype_->GenPreParsing(out_cc, env); - elemtype_->GenParseCode(out_cc, env, elem_data, flags); - - if ( incremental_parsing() ) - { - out_cc->println("if ( ! %s )", - elemtype_->parsing_complete(env).c_str()); - out_cc->inc_indent(); - out_cc->println("goto %s;", kNeedMoreData); - out_cc->dec_indent(); - } - - GenElementAssignment(out_cc, env, array_str, use_vector); - - if ( elem_dataptr_var() ) - { - out_cc->println("%s += %s;", - env->LValue(elem_dataptr_var()), - elemtype_->DataSize(0, env, elem_data).c_str()); - out_cc->println("BINPAC_ASSERT(%s <= %s);", - env->RValue(elem_dataptr_var()), - env->RValue(end_of_data)); - } - - if ( attr_until_element_expr_ ) - GenUntilCheck(out_cc, env, attr_until_element_expr_, false); - - if ( elemtype_->IsPointerType() ) - out_cc->println("%s = 0;", env->LValue(elem_var())); - - out_cc->println("}"); - out_cc->dec_indent(); - - out_cc->dec_indent(); - out_cc->println("%s: ;", end_of_array_loop_label_.c_str()); - out_cc->inc_indent(); - - if ( compute_size_var && elem_dataptr_var() && ! env->Evaluated(size_var()) ) - { - // Compute the data size - out_cc->println("%s = %s - (%s);", - env->LValue(size_var()), - env->RValue(elem_dataptr_var()), - data.ptr_expr()); - env->SetEvaluated(size_var()); - } - } - -void ArrayType::GenUntilInputCheck(Output *out_cc, Env *env) - { - ID *elem_input_var_id = new ID( - fmt("%s__elem_input", value_var()->Name())); - elem_input_var_field_ = new TempVarField( - elem_input_var_id, extern_type_const_bytestring->Clone()); - elem_input_var_field_->Prepare(env); - - out_cc->println("%s %s(%s, %s);", - extern_type_const_bytestring->DataTypeStr().c_str(), - env->LValue(elem_input_var()), - env->RValue(begin_of_data), - env->RValue(end_of_data)); - env->SetEvaluated(elem_input_var()); - - GenUntilCheck(out_cc, env, attr_until_input_expr_, true); - } - -void ArrayType::GenUntilCheck(Output *out_cc, Env *env, - Expr *until_expr, bool delete_elem) - { - ASSERT(until_expr); - - Env check_env(env, this); - check_env.AddMacro(element_macro_id, - new Expr(elem_var()->clone())); - if ( elem_input_var() ) - { - check_env.AddMacro(input_macro_id, - new Expr(elem_input_var()->clone())); - } - - out_cc->println("// Check &until(%s)", until_expr->orig()); - out_cc->println("if ( %s )", - until_expr->EvalExpr(out_cc, &check_env)); - out_cc->inc_indent(); - out_cc->println("{"); - if ( parsing_complete_var() ) - { - out_cc->println("%s = true;", - env->LValue(parsing_complete_var())); - } - - if ( elemtype_->IsPointerType() ) - { - if ( delete_elem ) - elemtype_->GenCleanUpCode(out_cc, env); - else - out_cc->println("%s = 0;", env->LValue(elem_var())); - } - - out_cc->println("goto %s;", end_of_array_loop_label_.c_str()); - out_cc->println("}"); - out_cc->dec_indent(); - } - -void ArrayType::GenDynamicSize(Output *out_cc, Env *env, - const DataPtr& data) - { - ASSERT(! incremental_input()); - DEBUG_MSG("Generating dynamic size for array `%s'\n", - value_var()->Name()); - - int elem_w = elemtype_->StaticSize(env); - if ( elem_w >= 0 && - ! attr_until_element_expr_ && - ! attr_until_input_expr_ && - ( length_ || attr_restofdata_ ) ) - { - // If the elements have a fixed size, - // we only need to compute the number of elements - bool compute_size_var = AddSizeVar(out_cc, env); - ASSERT(compute_size_var); - GenArrayLength(out_cc, env, data); - ASSERT(env->Evaluated(arraylength_var())); - out_cc->println("%s = %d * %s;", - env->LValue(size_var()), elem_w, env->RValue(arraylength_var())); - env->SetEvaluated(size_var()); - } - else - { - // Otherwise we need parse the array dynamically - GenParseCode(out_cc, env, data, 0); - } - } - -int ArrayType::StaticSize(Env *env) const - { - int num = 0; - - if ( ! length_ || ! length_->ConstFold(env, &num) ) - return -1; - - int elem_w = elemtype_->StaticSize(env); - if ( elem_w < 0 ) - return -1; - - DEBUG_MSG("static size of %s:%s = %d * %d\n", - decl_id()->Name(), lvalue(), elem_w, num); - - return num * elem_w; - } - -void ArrayType::SetBoundaryChecked() - { - Type::SetBoundaryChecked(); - elemtype_->SetBoundaryChecked(); - } - -void ArrayType::DoMarkIncrementalInput() - { - elemtype_->MarkIncrementalInput(); - } - -bool ArrayType::RequiresAnalyzerContext() - { - return Type::RequiresAnalyzerContext() || - ( length_ && length_->RequiresAnalyzerContext() ) || - elemtype_->RequiresAnalyzerContext(); - } - -bool ArrayType::DoTraverse(DataDepVisitor *visitor) - { - if ( ! Type::DoTraverse(visitor) ) - return false; - - if ( length_ && ! length_->Traverse(visitor) ) - return false; - - if ( ! elemtype_->Traverse(visitor) ) - return false; - - return true; - } diff --git a/aux/binpac/src/pac_array.h b/aux/binpac/src/pac_array.h deleted file mode 100644 index 022ef2ea4a..0000000000 --- a/aux/binpac/src/pac_array.h +++ /dev/null @@ -1,92 +0,0 @@ -#ifndef pac_array_h -#define pac_array_h - -#include "pac_common.h" -#include "pac_type.h" - -// Fixed-length array and variable length sequence with an ending pattern - -class ArrayType : public Type -{ -public: - ArrayType(Type *arg_elemtype, Expr *arg_length = 0); - ~ArrayType(); - - bool DefineValueVar() const; - string DataTypeStr() const; - string DefaultValue() const { return "0"; } - Type *ElementDataType() const; - - string EvalElement(const string &array, const string &index) const; - - void ProcessAttr(Attr *a); - - void Prepare(Env *env, int flags); - - void GenPubDecls(Output *out, Env *env); - void GenPrivDecls(Output *out, Env *env); - - void GenInitCode(Output *out, Env *env); - void GenCleanUpCode(Output *out, Env *env); - - int StaticSize(Env *env) const; - - void SetBoundaryChecked(); - void GenUntilInputCheck(Output *out_cc, Env *env); - - bool IsPointerType() const { return true; } - -protected: - void init(); - - void DoGenParseCode(Output *out, Env *env, const DataPtr& data, int flags); - void GenDynamicSize(Output *out, Env *env, const DataPtr& data); - void GenArrayLength(Output *out_cc, Env *env, const DataPtr& data); - string GenArrayInit(Output *out_cc, Env *env, bool known_array_length); - void GenElementAssignment(Output *out_cc, Env *env, - string const &array_str, bool use_vector); - void GenUntilCheck(Output *out_cc, Env *env, - Expr *until_condition, bool delete_elem); - - bool ByteOrderSensitive() const - { - return elemtype_->RequiresByteOrder(); - } - bool RequiresAnalyzerContext(); - - Type *DoClone() const; - - void DoMarkIncrementalInput(); - - const ID *arraylength_var() const; - const ID *elem_it_var() const; - const ID *elem_var() const; - const ID *elem_dataptr_var() const; - const ID *elem_input_var() const; - -protected: - bool DoTraverse(DataDepVisitor *visitor); - -private: - Type *elemtype_; - Expr *length_; - - string vector_str_; - string datatype_str_; - string end_of_array_loop_label_; - - Field *arraylength_var_field_; - Field *elem_it_var_field_; - Field *elem_var_field_; - Field *elem_dataptr_var_field_; - Field *elem_input_var_field_; - - // This does not come from &until, but is internally generated - Expr *elem_dataptr_until_expr_; - - Expr *attr_generic_until_expr_; - Expr *attr_until_element_expr_; - Expr *attr_until_input_expr_; -}; - -#endif // pac_array_h diff --git a/aux/binpac/src/pac_attr.cc b/aux/binpac/src/pac_attr.cc deleted file mode 100644 index cfd6263be6..0000000000 --- a/aux/binpac/src/pac_attr.cc +++ /dev/null @@ -1,57 +0,0 @@ -#include "pac_attr.h" -#include "pac_expr.h" - -bool Attr::DoTraverse(DataDepVisitor *visitor) - { - if ( expr_ && ! expr_->Traverse(visitor) ) - return false; - return true; - } - -bool Attr::RequiresAnalyzerContext() const - { - return (expr_ && expr_->RequiresAnalyzerContext()); - } - -void Attr::init() - { - expr_ = 0; - seqend_ = 0; - } - -Attr::Attr(AttrType type) - : DataDepElement(DataDepElement::ATTR) - { - type_ = type; - init(); - } - -Attr::Attr(AttrType type, Expr *expr) - : DataDepElement(DataDepElement::ATTR) - { - type_ = type; - init(); - expr_ = expr; - } - -Attr::Attr(AttrType type, ExprList *exprlist) - : DataDepElement(DataDepElement::ATTR) - { - type_ = type; - init(); - expr_ = new Expr(exprlist); - } - -Attr::Attr(AttrType type, SeqEnd *seqend) - : DataDepElement(DataDepElement::ATTR) - { - type_ = type; - init(); - seqend_ = seqend; - } - -LetAttr::LetAttr(FieldList *letfields) - : Attr(ATTR_LET) - { - letfields_ = letfields; - } diff --git a/aux/binpac/src/pac_attr.h b/aux/binpac/src/pac_attr.h deleted file mode 100644 index 67bdbedc8d..0000000000 --- a/aux/binpac/src/pac_attr.h +++ /dev/null @@ -1,61 +0,0 @@ -#ifndef pac_attr_h -#define pac_attr_h - -#include "pac_common.h" -#include "pac_datadep.h" - -enum AttrType { - ATTR_BYTEORDER, - ATTR_CHECK, - ATTR_CHUNKED, - ATTR_EXPORTSOURCEDATA, - ATTR_IF, - ATTR_LENGTH, - ATTR_LET, - ATTR_LINEBREAKER, - ATTR_MULTILINE, - ATTR_ONELINE, - ATTR_REFCOUNT, - ATTR_REQUIRES, - ATTR_RESTOFDATA, - ATTR_RESTOFFLOW, - ATTR_TRANSIENT, - ATTR_UNTIL, -}; - -class Attr : public Object, public DataDepElement -{ -public: - Attr(AttrType type); - Attr(AttrType type, Expr *expr); - Attr(AttrType type, ExprList *exprlist); - Attr(AttrType type, SeqEnd *seqend); - - AttrType type() const { return type_; } - Expr *expr() const { return expr_; } - SeqEnd *seqend() const { return seqend_; } - - bool RequiresAnalyzerContext() const; - -protected: - bool DoTraverse(DataDepVisitor *visitor); - -protected: - void init(); - - AttrType type_; - Expr *expr_; - SeqEnd *seqend_; -}; - -class LetAttr : public Attr -{ -public: - LetAttr(FieldList *letfields); - FieldList *letfields() const { return letfields_; } - -private: - FieldList *letfields_; -}; - -#endif // pac_attr_h diff --git a/aux/binpac/src/pac_btype.cc b/aux/binpac/src/pac_btype.cc deleted file mode 100644 index a7df6f7bf3..0000000000 --- a/aux/binpac/src/pac_btype.cc +++ /dev/null @@ -1,144 +0,0 @@ -#include "pac_btype.h" -#include "pac_dataptr.h" -#include "pac_id.h" -#include "pac_output.h" - -Type *BuiltInType::DoClone() const - { - return new BuiltInType(bit_type()); - } - -bool BuiltInType::IsNumericType() const - { - BITType t = bit_type(); - return (t == INT8 || t == INT16 || t == INT32 || - t == UINT8 || t == UINT16 || t == UINT32); - } - -bool BuiltInType::CompatibleBuiltInTypes(BuiltInType *type1, - BuiltInType *type2) - { - return type1->IsNumericType() && type2->IsNumericType(); - } - -static const char* basic_pactype_name[] = { -# define TYPE_DEF(name, pactype, ctype, size) pactype, -# include "pac_type.def" -# undef TYPE_DEF - 0, -}; - -void BuiltInType::static_init() - { - for ( int bit_type = 0; basic_pactype_name[bit_type]; ++bit_type ) - { - Type::AddPredefinedType( - basic_pactype_name[bit_type], - new BuiltInType((BITType) bit_type)); - } - } - -int BuiltInType::LookUpByName(const char* name) - { - ASSERT(0); - for ( int i = 0; basic_pactype_name[i]; ++i ) - if ( strcmp(basic_pactype_name[i], name) == 0 ) - return i; - return -1; - } - -static const char* basic_ctype_name[] = { -# define TYPE_DEF(name, pactype, ctype, size) ctype, -# include "pac_type.def" -# undef TYPE_DEF - 0, -}; - -bool BuiltInType::DefineValueVar() const - { - return bit_type_ != EMPTY; - } - -string BuiltInType::DataTypeStr() const - { - return basic_ctype_name[bit_type_]; - } - -int BuiltInType::StaticSize(Env* /* env */) const - { - static const size_t basic_type_size[] = - { -# define TYPE_DEF(name, pactype, ctype, size) size, -# include "pac_type.def" -# undef TYPE_DEF - }; - - return basic_type_size[bit_type_]; - } - -void BuiltInType::DoMarkIncrementalInput() - { - if ( bit_type_ == EMPTY ) - return; - Type::DoMarkIncrementalInput(); - } - -void BuiltInType::GenInitCode(Output* out_cc, Env* env) - { - if ( bit_type_ != EMPTY ) - out_cc->println("%s = 0;", env->LValue(value_var())); - Type::GenInitCode(out_cc, env); - } - -void BuiltInType::GenDynamicSize(Output* out_cc, Env* env, const DataPtr& data) - { - /* should never be called */ - ASSERT(0); - } - -void BuiltInType::DoGenParseCode(Output* out_cc, Env* env, - const DataPtr& data, int flags) - { - if ( bit_type_ == EMPTY ) - return; - - // There is no need to generate the size variable - // out_cc->println("%s = sizeof(%s);", size_var(), DataTypeStr().c_str()); - - GenBoundaryCheck(out_cc, env, data); - - if ( anonymous_value_var() ) - return; - - switch ( bit_type_ ) - { - case EMPTY: - // do nothing - break; - - case INT8: - case UINT8: - out_cc->println("%s = *((%s const *) (%s));", - lvalue(), DataTypeStr().c_str(), data.ptr_expr()); - break; - case INT16: - case UINT16: - case INT32: - case UINT32: -#if 0 - out_cc->println("%s = UnMarshall<%s>(%s, %s);", - lvalue(), - DataTypeStr().c_str(), - data.ptr_expr(), - EvalByteOrder(out_cc, env).c_str()); -#else - out_cc->println("%s = FixByteOrder(%s, *((%s const *) (%s)));", - lvalue(), - EvalByteOrder(out_cc, env).c_str(), - DataTypeStr().c_str(), - data.ptr_expr()); -#endif - break; - } - } - diff --git a/aux/binpac/src/pac_btype.h b/aux/binpac/src/pac_btype.h deleted file mode 100644 index 4bdbf9390b..0000000000 --- a/aux/binpac/src/pac_btype.h +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef pac_btype_h -#define pac_btype_h - -#include "pac_type.h" - -class BuiltInType : public Type -{ -public: - enum BITType { -# define TYPE_DEF(name, pactype, ctype, size) name, -# include "pac_type.def" -# undef TYPE_DEF - }; - - static int LookUpByName(const char *name); - - BuiltInType(BITType bit_type) - : Type(bit_type == BuiltInType::EMPTY ? Type::EMPTY : BUILTIN), - bit_type_(bit_type) {} - - BITType bit_type() const { return bit_type_; } - - bool IsNumericType() const; - - bool DefineValueVar() const; - string DataTypeStr() const; - string DefaultValue() const { return "0"; } - - int StaticSize(Env *env) const; - - bool IsPointerType() const { return false; } - - bool ByteOrderSensitive() const { return StaticSize(0) >= 2; } - - void GenInitCode(Output *out_cc, Env *env); - - void DoMarkIncrementalInput(); - -protected: - void DoGenParseCode(Output *out, Env *env, const DataPtr& data, int flags); - void GenDynamicSize(Output *out, Env *env, const DataPtr& data); - Type *DoClone() const; - - BITType bit_type_; - -public: - static void static_init(); - static bool CompatibleBuiltInTypes(BuiltInType *type1, - BuiltInType *type2); -}; - -#endif // pac_btype_h diff --git a/aux/binpac/src/pac_case.cc b/aux/binpac/src/pac_case.cc deleted file mode 100644 index b809d61b6e..0000000000 --- a/aux/binpac/src/pac_case.cc +++ /dev/null @@ -1,391 +0,0 @@ -#include "pac_exception.h" -#include "pac_expr.h" -#include "pac_exttype.h" -#include "pac_id.h" -#include "pac_output.h" -#include "pac_typedecl.h" -#include "pac_utils.h" - -#include "pac_case.h" - -CaseType::CaseType(Expr* index_expr, CaseFieldList* cases) - : Type(CASE), index_expr_(index_expr), cases_(cases) - { - index_var_ = 0; - foreach(i, CaseFieldList, cases_) - AddField(*i); - } - -CaseType::~CaseType() - { - delete index_var_; - delete index_expr_; - delete cases_; - } - -void CaseType::AddCaseField(CaseField *f) - { - // All fields must be added before Prepare() - ASSERT(!env()); - - AddField(f); - cases_->push_back(f); - } - -bool CaseType::DefineValueVar() const - { - return false; - } - -string CaseType::DataTypeStr() const - { - ASSERT(type_decl()); - return strfmt("%s *", type_decl()->class_name().c_str()); - } - -Type *CaseType::ValueType() const - { - foreach (i, CaseFieldList, cases_) - { - CaseField *c = *i; - return c->type(); - } - ASSERT(0); - return 0; - } - -string CaseType::DefaultValue() const - { - return ValueType()->DefaultValue(); - } - -void CaseType::Prepare(Env* env, int flags) - { - ASSERT(flags & TO_BE_PARSED); - - index_var_ = new ID(fmt("%s_case_index", value_var()->Name())); - env->AddID(index_var_, MEMBER_VAR, extern_type_int); - - // Sort the cases_ to put the default case at the end of the list - CaseFieldList::iterator default_case_it = - cases_->end(); // to avoid warning - CaseField *default_case = 0; - - foreach (i, CaseFieldList, cases_) - { - CaseField *c = *i; - if ( ! c->index() ) - { - if ( default_case ) - throw Exception(c, "duplicate default case"); - default_case_it = i; - default_case = c; - } - } - if ( default_case ) - { - cases_->erase(default_case_it); - cases_->push_back(default_case); - } - - foreach (i, CaseFieldList, cases_) - { - CaseField *c = *i; - c->set_index_var(index_var_); - c->set_case_type(this); - } - - Type::Prepare(env, flags); - } - -void CaseType::GenPrivDecls(Output* out_h, Env* env) - { - out_h->println("int %s;", env->LValue(index_var_)); - Type::GenPrivDecls(out_h, env); - } - -void CaseType::GenPubDecls(Output* out_h, Env* env) - { - out_h->println("int %s const { return %s; }", - env->RValue(index_var_), env->LValue(index_var_)); - Type::GenPubDecls(out_h, env); - } - -void CaseType::GenInitCode(Output* out_cc, Env* env) - { - out_cc->println("%s = -1;", env->LValue(index_var_)); - Type::GenInitCode(out_cc, env); - } - -void CaseType::GenCleanUpCode(Output* out_cc, Env* env) - { - Type::GenCleanUpCode(out_cc, env); - - env->set_in_branch(true); - out_cc->println("switch ( %s )", env->RValue(index_var_)); - out_cc->inc_indent(); - out_cc->println("{"); - foreach (i, CaseFieldList, cases_) - { - CaseField *c = *i; - c->GenCleanUpCode(out_cc, env); - } - out_cc->println("}"); - out_cc->dec_indent(); - env->set_in_branch(false); - } - -void CaseType::DoGenParseCode(Output* out_cc, Env* env, - const DataPtr& data, int flags) - { - if ( StaticSize(env) >= 0 ) - GenBoundaryCheck(out_cc, env, data); - - bool compute_size_var = false; - - if ( ! incremental_input() ) - compute_size_var = AddSizeVar(out_cc, env); - - out_cc->println("%s = %s;", - env->LValue(index_var_), index_expr_->EvalExpr(out_cc, env)); - env->SetEvaluated(index_var_); - - env->set_in_branch(true); - out_cc->println("switch ( %s )", env->RValue(index_var_)); - out_cc->inc_indent(); - out_cc->println("{"); - bool has_default_case = false; - foreach (i, CaseFieldList, cases_) - { - CaseField *c = *i; - c->GenParseCode(out_cc, env, data, - compute_size_var ? size_var() : 0); - if ( c->IsDefaultCase() ) - has_default_case = true; - } - - if ( ! has_default_case ) - { - out_cc->println("default:"); - out_cc->inc_indent(); - out_cc->println("throw ExceptionInvalidCaseIndex(\"%s\", %s);", - decl_id()->Name(), env->RValue(index_var_)); - out_cc->println("break;"); - out_cc->dec_indent(); - } - out_cc->println("}"); - out_cc->dec_indent(); - env->set_in_branch(false); - - if ( compute_size_var ) - env->SetEvaluated(size_var()); - } - -void CaseType::GenDynamicSize(Output* out_cc, Env* env, - const DataPtr& data) - { - GenParseCode(out_cc, env, data, 0); - } - -int CaseType::StaticSize(Env* env) const - { - int static_w = -1; - foreach (i, CaseFieldList, cases_) - { - CaseField *c = *i; - int w = c->StaticSize(env); - if ( w < 0 || ( static_w >= 0 && w != static_w ) ) - return -1; - static_w = w; - } - return static_w; - } - -void CaseType::SetBoundaryChecked() - { - Type::SetBoundaryChecked(); - foreach (i, CaseFieldList, cases_) - { - CaseField *c = *i; - c->SetBoundaryChecked(); - } - } - -void CaseType::DoMarkIncrementalInput() - { - foreach (i, CaseFieldList, cases_) - { - CaseField *c = *i; - c->type()->MarkIncrementalInput(); - } - } - -bool CaseType::ByteOrderSensitive() const - { - foreach (i, CaseFieldList, cases_) - { - CaseField *c = *i; - if ( c->RequiresByteOrder() ) - return true; - } - return false; - } - -CaseField::CaseField(ExprList* index, ID* id, Type* type) - : Field(CASE_FIELD, - TYPE_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, - id, type), - index_(index) - { - ASSERT(type_); - type_->set_value_var(id, MEMBER_VAR); - case_type_ = 0; - } - -CaseField::~CaseField() - { - delete_list(ExprList, index_); - } - -void GenCaseStr(ExprList *index_list, Output *out_cc, Env *env) - { - if ( index_list ) - { - foreach(i, ExprList, index_list) - { - Expr *index_expr = *i; - int index_const; - - if ( ! index_expr->ConstFold(env, &index_const) ) - throw ExceptionNonConstExpr(index_expr); - out_cc->println("case %d:", index_const); - } - } - else - { - out_cc->println("default:"); - } - } - -void CaseField::Prepare(Env* env) - { - ASSERT(index_var_); - Field::Prepare(env); - } - -void CaseField::GenPubDecls(Output* out_h, Env* env) - { - if ( ! ((flags_ & PUBLIC_READABLE) && (flags_ & CLASS_MEMBER)) ) - return; - - // Skip type "empty" - if ( type_->DataTypeStr().empty() ) - return; - - out_h->println("%s %s const", - type_->DataTypeConstRefStr().c_str(), env->RValue(id_)); - - out_h->inc_indent(); - out_h->println("{"); - - if ( ! index_ ) - out_h->println("return %s;", lvalue()); - else - { - out_h->println("switch ( %s )", env->RValue(index_var_)); - out_h->inc_indent(); - out_h->println("{"); - GenCaseStr(index_, out_h, env); - out_h->inc_indent(); - out_h->println("break; // OK"); - out_h->dec_indent(); - - out_h->println("default:"); - out_h->inc_indent(); - out_h->println("throw ExceptionInvalidCase(\"%s\", %s, \"%s\");", - id_->LocName(), - env->RValue(index_var_), - OrigExprList(index_).c_str()); - out_h->println("break;"); - out_h->dec_indent(); - - out_h->println("}"); - out_h->dec_indent(); - - out_h->println("return %s;", lvalue()); - } - - out_h->println("}"); - out_h->dec_indent(); - } - -void CaseField::GenInitCode(Output* out_cc, Env* env) - { - // GenCaseStr(index_, out_cc, env); - // out_cc->inc_indent(); - // out_cc->println("{"); - // out_cc->println("// Initialize \"%s\"", id_->Name()); - type_->GenInitCode(out_cc, env); - // out_cc->println("}"); - // out_cc->println("break;"); - // out_cc->dec_indent(); - } - -void CaseField::GenCleanUpCode(Output* out_cc, Env* env) - { - GenCaseStr(index_, out_cc, env); - out_cc->inc_indent(); - out_cc->println("// Clean up \"%s\"", id_->Name()); - out_cc->println("{"); - if ( ! anonymous_field() ) - type_->GenCleanUpCode(out_cc, env); - out_cc->println("}"); - out_cc->println("break;"); - out_cc->dec_indent(); - } - -void CaseField::GenParseCode(Output* out_cc, Env* env, - const DataPtr& data, const ID* size_var) - { - GenCaseStr(index_, out_cc, env); - out_cc->inc_indent(); - out_cc->println("// Parse \"%s\"", id_->Name()); - out_cc->println("{"); - - { - Env case_env(env, this); - Env *env = &case_env; - - type_->GenPreParsing(out_cc, env); - type_->GenParseCode(out_cc, env, data, 0); - if ( size_var ) - { - out_cc->println("%s = %s;", - env->LValue(size_var), - type_->DataSize(out_cc, env, data).c_str()); - } - if ( type_->incremental_input() ) - { - ASSERT(case_type()->parsing_complete_var()); - out_cc->println("%s = %s;", - env->LValue(case_type()->parsing_complete_var()), - env->RValue(type_->parsing_complete_var())); - } - out_cc->println("}"); - } - - out_cc->println("break;"); - out_cc->dec_indent(); - } - -bool CaseField::DoTraverse(DataDepVisitor *visitor) - { - return Field::DoTraverse(visitor) && - type()->Traverse(visitor); - } - -bool CaseField::RequiresAnalyzerContext() const - { - return Field::RequiresAnalyzerContext() || - type()->RequiresAnalyzerContext(); - } diff --git a/aux/binpac/src/pac_case.h b/aux/binpac/src/pac_case.h deleted file mode 100644 index c9e416cfe1..0000000000 --- a/aux/binpac/src/pac_case.h +++ /dev/null @@ -1,99 +0,0 @@ -#ifndef pac_case_h -#define pac_case_h - -#include "pac_common.h" -#include "pac_field.h" -#include "pac_id.h" -#include "pac_type.h" - -class CaseType : public Type -{ -public: - CaseType(Expr *index, CaseFieldList *cases); - ~CaseType(); - - void AddCaseField(CaseField *f); - - bool DefineValueVar() const; - string DataTypeStr() const; - string DefaultValue() const; - - void Prepare(Env *env, int flags); - - void GenPubDecls(Output *out, Env *env); - void GenPrivDecls(Output *out, Env *env); - - void GenInitCode(Output *out, Env *env); - void GenCleanUpCode(Output *out, Env *env); - - int StaticSize(Env *env) const; - - void SetBoundaryChecked(); - - Type *ValueType() const; - - bool IsPointerType() const { return ValueType()->IsPointerType(); } - -protected: - void DoGenParseCode(Output *out, Env *env, const DataPtr& data, int flags); - void GenDynamicSize(Output *out, Env *env, const DataPtr& data); - Type *DoClone() const { return 0; } - void DoMarkIncrementalInput(); - - bool ByteOrderSensitive() const; - - Expr *index_expr_; - ID *index_var_; - CaseFieldList *cases_; - - typedef map member_map_t; - member_map_t member_map_; -}; - -class CaseField : public Field -{ -public: - CaseField(ExprList *index, ID *id, Type *type); - ~CaseField(); - - CaseType *case_type() const { return case_type_; } - void set_case_type(CaseType *t) { case_type_ = t; } - - ExprList *index() const { return index_; } - - const char *lvalue() const { return type_->lvalue(); } - - const char *CaseStr(Env *env); - void set_index_var(const ID *var) { index_var_ = var; } - - void Prepare(Env *env); - - void GenPubDecls(Output *out, Env *env); - - void GenInitCode(Output *out, Env *env); - void GenCleanUpCode(Output *out, Env *env); - void GenParseCode(Output *out, Env *env, - const DataPtr& data, const ID *size_var); - - int StaticSize(Env *env) const { return type_->StaticSize(env); } - - bool IsDefaultCase() const { return ! index_; } - void SetBoundaryChecked() { type_->SetBoundaryChecked(); } - - bool RequiresByteOrder() const { return type_->RequiresByteOrder(); } - bool RequiresAnalyzerContext() const; - -protected: - bool DoTraverse(DataDepVisitor *visitor); - -protected: - CaseType *case_type_; - ExprList *index_; - const ID *index_var_; -}; - -// Generate a list of "case X:" lines from index_list. Each index -// expression must be constant foldable. -void GenCaseStr(ExprList *index_list, Output *out_cc, Env *env); - -#endif // pac_case_h diff --git a/aux/binpac/src/pac_cclass.h b/aux/binpac/src/pac_cclass.h deleted file mode 100644 index 87a7595996..0000000000 --- a/aux/binpac/src/pac_cclass.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef pac_cclass_h -#define pac_cclass_h - -class CClass; -class CClassMember; -class CClassMethod; -class CType; -class CVariable; - -typedef vector CClassMemberList; -typedef vector CClassMethodList; -typedef vector CVariableList; - -#include "pac_common.h" - -// Represents a C++ class. -// -// For now we adopt a simple model: -// -// 1. All members have a protected member variable "name_" and a -// public constant access method "name()". -// -// 2. All methods are public. -// -// 3. We do not check repeated names. - -class CClass -{ -public: - CClass(const string &class_name); - - void AddMember(CClassMember *member); - void AddMethod(CClassMember *method); - - void GenForwardDeclaration(Output *out_h); - void GenCode(Output *out_h, Output *out_cc); - -protected: - string class_name_; - CClassMemberList *members_; - CClassMethodList *methods_; -}; - -class CVariable -{ -public: - CClassMember(const string &name, CType *type); - - string name() const { return name_; } - CType *type() const { return type_; } - -protected: - string name_; - CType *type_; -}; - -class CClassMember -{ -public: - CClassMember(CVariable *var); - void GenCode(Output *out_h, Output *out_cc); - - string decl() const; - -protected: - CVariable *var_; -}; - -class CClassMethod -{ -public: - CClassMethod(CVariable *var, CVariableList *params); - - string decl() const; - -protected: - CVariable *var_; - CVariableList *params_; -}; - -#endif // pac_cclass_h diff --git a/aux/binpac/src/pac_common.h b/aux/binpac/src/pac_common.h deleted file mode 100644 index 81e59c184e..0000000000 --- a/aux/binpac/src/pac_common.h +++ /dev/null @@ -1,134 +0,0 @@ -#ifndef pac_common_h -#define pac_common_h - -#include "pac_utils.h" - -#include - -#include -#include -#include - -using namespace std; - -extern bool FLAGS_pac_debug; -extern vector FLAGS_include_directories; -extern string input_filename; -extern int line_number; - -// Definition of class Object, which is the base class for all objects -// representing language elements -- identifiers, types, expressions, -// etc. - -class Object -{ -public: - Object() - { - filename = input_filename; - line_num = line_number; - location = strfmt("%s:%d", filename.c_str(), line_number); - } - - ~Object() - { - } - - const char* Location() const { return location.c_str(); } - -protected: - string filename; - int line_num; - string location; -}; - -class ActionParam; -class ActionParamType; -class AnalyzerAction; -class AnalyzerContextDecl; -class AnalyzerDecl; -class AnalyzerElement; -class ArrayType; -class Attr; -class CClass; -class CType; -class ConstString; -class CaseExpr; -class CaseField; -class ContextField; -class DataPtr; -class Decl; -class EmbeddedCode; -class Enum; -class Env; -class ExternType; -class Expr; -class Field; -class Function; -class InputBuffer; -class LetDef; -class LetField; -class ID; -class Number; -class Output; -class PacPrimitive; -class Param; -class ParameterizedType; -class RecordType; -class RecordField; -class RecordDataField; -class RecordPaddingField; -class RegEx; -class SeqEnd; -class StateVar; -class Type; -class TypeDecl; -class WithInputField; - -// The ID of the current declaration. -extern const ID* current_decl_id; - -typedef vector ActionParamList; -typedef vector AnalyzerActionList; -typedef vector AnalyzerElementList; -typedef vector AttrList; -typedef vector CaseExprList; -typedef vector CaseFieldList; -typedef vector ContextFieldList; -typedef vector DeclList; -typedef vector EnumList; -typedef vector ExprList; -typedef vector FieldList; -typedef vector LetFieldList; -typedef vector NumList; -typedef vector ParamList; -typedef vector RecordFieldList; -typedef vector StateVarList; - -#define foreach(i, ct, pc) \ - if ( pc ) \ - for ( ct::iterator i = (pc)->begin(); i != (pc)->end(); ++i ) - -#define delete_list(ct, pc) \ - { \ - foreach(delete_list_i, ct, pc) \ - delete *delete_list_i; \ - delete pc; \ - pc = 0; \ - } - -// Constants -const char * const kComputeFrameLength = "compute_frame_length"; -const char * const kFlowBufferClass = "FlowBuffer"; -const char * const kFlowBufferVar = "flow_buffer"; -const char * const kFlowEOF = "FlowEOF"; -const char * const kFlowGap = "NewGap"; -const char * const kInitialBufferLengthFunc = "initial_buffer_length"; -const char * const kNeedMoreData = "need_more_data"; -const char * const kNewData = "NewData"; -const char * const kParseFuncWithBuffer = "ParseBuffer"; -const char * const kParseFuncWithoutBuffer = "Parse"; -const char * const kRefCountClass = "binpac::RefCount"; -const char * const kTypeWithLengthClass = "binpac::TypeWithLength"; - -#endif // pac_common_h diff --git a/aux/binpac/src/pac_conn.cc b/aux/binpac/src/pac_conn.cc deleted file mode 100644 index d9159cae5a..0000000000 --- a/aux/binpac/src/pac_conn.cc +++ /dev/null @@ -1,169 +0,0 @@ -#include "pac_analyzer.h" -#include "pac_dataunit.h" -#include "pac_embedded.h" -#include "pac_exception.h" -#include "pac_expr.h" -#include "pac_flow.h" -#include "pac_output.h" -#include "pac_paramtype.h" -#include "pac_type.h" - -#include "pac_conn.h" - -ConnDecl::ConnDecl(ID *conn_id, - ParamList *params, - AnalyzerElementList *elemlist) - : AnalyzerDecl(conn_id, CONN, params) - { - flows_[0] = flows_[1] = 0; - AddElements(elemlist); - data_type_ = new ParameterizedType(conn_id->clone(), 0); - } - -ConnDecl::~ConnDecl() - { - delete flows_[0]; - delete flows_[1]; - } - -void ConnDecl::AddBaseClass(vector *base_classes) const - { - base_classes->push_back("binpac::ConnectionAnalyzer"); - } - -void ConnDecl::ProcessFlowElement(AnalyzerFlow *flow_elem) - { - int flow_index; - - if ( flow_elem->dir() == AnalyzerFlow::UP ) - flow_index = 0; - else - flow_index = 1; - - if ( flows_[flow_index] ) - { - throw Exception(flow_elem, - fmt("%sflow already defined", - flow_index == 0 ? "up" : "down")); - } - - flows_[flow_index] = flow_elem; - type_->AddField(flow_elem->flow_field()); - } - -void ConnDecl::ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem) - { - throw Exception( - dataunit_elem, - "dataunit should be defined in only a flow declaration"); - } - -void ConnDecl::Prepare() - { - AnalyzerDecl::Prepare(); - - flows_[0]->flow_decl()->set_conn_decl(this); - flows_[1]->flow_decl()->set_conn_decl(this); - } - -void ConnDecl::GenPubDecls(Output *out_h, Output *out_cc) - { - AnalyzerDecl::GenPubDecls(out_h, out_cc); - } - -void ConnDecl::GenPrivDecls(Output *out_h, Output *out_cc) - { - AnalyzerDecl::GenPrivDecls(out_h, out_cc); - } - -void ConnDecl::GenEOFFunc(Output *out_h, Output *out_cc) - { - string proto = strfmt("%s(bool is_orig)", kFlowEOF); - - out_h->println("void %s;", proto.c_str()); - - out_cc->println("void %s::%s", class_name().c_str(), proto.c_str()); - out_cc->inc_indent(); - out_cc->println("{"); - - out_cc->println("if ( is_orig )"); - out_cc->inc_indent(); - out_cc->println("%s->%s();", - env_->LValue(upflow_id), - kFlowEOF); - out_cc->dec_indent(); - out_cc->println("else"); - out_cc->inc_indent(); - out_cc->println("%s->%s();", - env_->LValue(downflow_id), - kFlowEOF); - - foreach(i, AnalyzerHelperList, eof_helpers_) - { - (*i)->GenCode(0, out_cc, this); - } - - out_cc->dec_indent(); - - out_cc->println("}"); - out_cc->dec_indent(); - out_cc->println(""); - } - -void ConnDecl::GenGapFunc(Output *out_h, Output *out_cc) - { - string proto = strfmt("%s(bool is_orig, int gap_length)", kFlowGap); - - out_h->println("void %s;", proto.c_str()); - - out_cc->println("void %s::%s", class_name().c_str(), proto.c_str()); - out_cc->inc_indent(); - out_cc->println("{"); - - out_cc->println("if ( is_orig )"); - out_cc->inc_indent(); - out_cc->println("%s->%s(gap_length);", - env_->LValue(upflow_id), - kFlowGap); - out_cc->dec_indent(); - out_cc->println("else"); - out_cc->inc_indent(); - out_cc->println("%s->%s(gap_length);", - env_->LValue(downflow_id), - kFlowGap); - out_cc->dec_indent(); - - out_cc->println("}"); - out_cc->dec_indent(); - out_cc->println(""); - } - -void ConnDecl::GenProcessFunc(Output *out_h, Output *out_cc) - { - string proto = - strfmt("%s(bool is_orig, const_byteptr begin, const_byteptr end)", - kNewData); - - out_h->println("void %s;", proto.c_str()); - - out_cc->println("void %s::%s", class_name().c_str(), proto.c_str()); - out_cc->inc_indent(); - out_cc->println("{"); - - out_cc->println("if ( is_orig )"); - out_cc->inc_indent(); - out_cc->println("%s->%s(begin, end);", - env_->LValue(upflow_id), - kNewData); - out_cc->dec_indent(); - out_cc->println("else"); - out_cc->inc_indent(); - out_cc->println("%s->%s(begin, end);", - env_->LValue(downflow_id), - kNewData); - out_cc->dec_indent(); - - out_cc->println("}"); - out_cc->dec_indent(); - out_cc->println(""); - } diff --git a/aux/binpac/src/pac_conn.h b/aux/binpac/src/pac_conn.h deleted file mode 100644 index 0247bf7f7b..0000000000 --- a/aux/binpac/src/pac_conn.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef pac_conn_h -#define pac_conn_h - -#include "pac_decl.h" -#include "pac_analyzer.h" - -class ConnDecl : public AnalyzerDecl -{ -public: - ConnDecl(ID *conn_id, ParamList *params, AnalyzerElementList *elemlist); - ~ConnDecl(); - - void Prepare(); - - Type* DataType() const { return data_type_; } - -protected: - void AddBaseClass(vector *base_classes) const; - - void GenProcessFunc(Output *out_h, Output *out_cc); - void GenGapFunc(Output *out_h, Output *out_cc); - void GenEOFFunc(Output *out_h, Output *out_cc); - - void GenPubDecls(Output *out_h, Output *out_cc); - void GenPrivDecls(Output *out_h, Output *out_cc); - - void ProcessFlowElement(AnalyzerFlow *flow_elem); - void ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem); - - AnalyzerFlow *flows_[2]; - Type *data_type_; -}; - -#endif // pac_conn_h diff --git a/aux/binpac/src/pac_context.cc b/aux/binpac/src/pac_context.cc deleted file mode 100644 index 94e4c4ce47..0000000000 --- a/aux/binpac/src/pac_context.cc +++ /dev/null @@ -1,120 +0,0 @@ -#include "pac_analyzer.h" -#include "pac_exception.h" -#include "pac_exttype.h" -#include "pac_flow.h" -#include "pac_id.h" -#include "pac_output.h" -#include "pac_param.h" -#include "pac_paramtype.h" -#include "pac_type.h" -#include "pac_utils.h" - -#include "pac_context.h" - -ContextField::ContextField(ID *id, Type *type) - : Field(CONTEXT_FIELD, - TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, - id, type) - { - } - -AnalyzerContextDecl *AnalyzerContextDecl::current_analyzer_context_ = 0; - -namespace { - ParamList *ContextFieldsToParams(ContextFieldList *context_fields) - { - // Convert context fields to parameters - ParamList *params = new ParamList(); - foreach(i, ContextFieldList, context_fields) - { - ContextField *f = *i; - params->push_back( - new Param(f->id()->clone(), - f->type())); - } - return params; - } -} // namespace private - -AnalyzerContextDecl::AnalyzerContextDecl( - ID *id, - ContextFieldList *context_fields) - : TypeDecl(new ID(fmt("Context%s", id->Name())), - ContextFieldsToParams(context_fields), - new DummyType()) - { - context_name_id_ = id; - if ( current_analyzer_context_ != 0 ) - { - throw Exception(this, - fmt("multiple declaration of analyzer context; " - "the previous one is `%s'", - current_analyzer_context_->id()->Name())); - } - else - current_analyzer_context_ = this; - - context_fields_ = context_fields; - - param_type_ = new ParameterizedType(id_->clone(), 0); - - flow_buffer_added_ = false; - - DEBUG_MSG("Context type: %s\n", param_type()->class_name().c_str()); - } - -AnalyzerContextDecl::~AnalyzerContextDecl() - { - delete context_name_id_; - delete_list(ContextFieldList, context_fields_); - } - -void AnalyzerContextDecl::GenForwardDeclaration(Output *out_h) - { - GenNamespaceBegin(out_h); - TypeDecl::GenForwardDeclaration(out_h); - } - -void AnalyzerContextDecl::GenCode(Output *out_h, Output *out_cc) - { - GenNamespaceBegin(out_h); - GenNamespaceBegin(out_cc); - TypeDecl::GenCode(out_h, out_cc); - } - -void AnalyzerContextDecl::GenNamespaceBegin(Output *out) const - { - out->println("namespace %s {", context_name_id()->Name()); - } - -void AnalyzerContextDecl::GenNamespaceEnd(Output *out) const - { - out->println("} // namespace %s", context_name_id()->Name()); - } - -void AnalyzerContextDecl::AddFlowBuffer() - { - if ( flow_buffer_added_ ) - return; - - AddParam(new Param( - new ID(kFlowBufferVar), - FlowDecl::flow_buffer_type()->Clone())); - - flow_buffer_added_ = true; - } - -string AnalyzerContextDecl::mb_buffer(Env *env) - { - // A hack. The orthodox way would be to build an Expr of - // context.flow_buffer_var, and then EvalExpr. - return fmt("%s->%s()", - env->RValue(analyzer_context_id), - kFlowBufferVar); - } - -Type *DummyType::DoClone() const - { - // Fields will be copied in Type::Clone(). - return new DummyType(); - } diff --git a/aux/binpac/src/pac_context.h b/aux/binpac/src/pac_context.h deleted file mode 100644 index 29704e0b8d..0000000000 --- a/aux/binpac/src/pac_context.h +++ /dev/null @@ -1,97 +0,0 @@ -#ifndef pac_context_h -#define pac_context_h - -#include "pac_common.h" -#include "pac_field.h" -#include "pac_type.h" -#include "pac_typedecl.h" - -// AnalyzerContext represents a cookie that an analyzer gives to -// parse functions of various message types. The cookie is parsed -// to every parse function (if necessary) as parameter 'binpac_context'. -// -// The members of the cookie is declared through 'analyzer' declarations, -// such as in: -// -// analyzer SunRPC withcontext { -// connection: RPC_Conn; -// flow: RPC_Flow; -// }; -// -// The cookie usually contains the connection and flow in which -// the message appears, and the context information can be -// accessed as members of the cookie, such as -// ``binpac_context.connection''. - -class ContextField : public Field -{ -public: - ContextField(ID *id, Type *type); -}; - -class AnalyzerContextDecl : public TypeDecl -{ -public: - AnalyzerContextDecl(ID *id, ContextFieldList *context_fields); - ~AnalyzerContextDecl(); - - void AddFlowBuffer(); - - const ID *context_name_id() const { return context_name_id_; } - - // The type of analyzer context as a parameter - ParameterizedType *param_type() const { return param_type_; } - - void GenForwardDeclaration(Output *out_h); - void GenCode(Output *out_h, Output *out_cc); - - void GenNamespaceBegin(Output *out) const; - void GenNamespaceEnd(Output *out) const; - -private: - ID *context_name_id_; - ContextFieldList *context_fields_; - ParameterizedType *param_type_; - bool flow_buffer_added_; - -// static members -public: - static AnalyzerContextDecl *current_analyzer_context() - { - return current_analyzer_context_; - } - - static string mb_buffer(Env *env); - -private: - static AnalyzerContextDecl *current_analyzer_context_; -}; - -class DummyType : public Type -{ -public: - DummyType() : Type(DUMMY) {} - - bool DefineValueVar() const { return false; } - string DataTypeStr() const { ASSERT(0); return ""; } - - int StaticSize(Env* env) const { ASSERT(0); return -1; } - - bool ByteOrderSensitive() const { return false; } - - bool IsPointerType() const { ASSERT(0); return false; } - - void DoGenParseCode(Output* out, Env* env, - const DataPtr& data, int flags) - { ASSERT(0); } - - // Generate code for computing the dynamic size of the type - void GenDynamicSize(Output* out, Env* env, const DataPtr& data) - { ASSERT(0); } - -protected: - Type *DoClone() const; - void DoMarkIncrementalInput() { ASSERT(0); } -}; - -#endif // pac_context_h diff --git a/aux/binpac/src/pac_cstr.cc b/aux/binpac/src/pac_cstr.cc deleted file mode 100644 index 2d41bf7d1b..0000000000 --- a/aux/binpac/src/pac_cstr.cc +++ /dev/null @@ -1,127 +0,0 @@ -#include "pac_cstr.h" -#include "pac_dbg.h" -#include "pac_exception.h" - -namespace { - -class EscapeException -{ -public: - explicit EscapeException(const string &s) - { - msg_ = s; - } - - const string &msg() const { return msg_; } - -private: - string msg_; -}; - -// Copied from util.cc of Bro -int expand_escape(const char*& s) - { - switch ( *(s++) ) { - case 'b': return '\b'; - case 'f': return '\f'; - case 'n': return '\n'; - case 'r': return '\r'; - case 't': return '\t'; - case 'a': return '\a'; - case 'v': return '\v'; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': - { // \{1,3} - --s; // put back the first octal digit - const char* start = s; - - // Don't increment inside loop control - // because if isdigit() is a macro it might - // expand into multiple increments ... - - // Here we define a maximum length for escape sequence - // to allow easy handling of string like: "^H0" as - // "\0100". - - for ( int len = 0; len < 3 && isascii(*s) && isdigit(*s); ++s, ++len) - ; - - int result; - if ( sscanf(start, "%3o", &result) != 1 ) - { - throw EscapeException(fmt("bad octal escape: \"%s", start)); - result = 0; - } - - return result; - } - - case 'x': - { /* \x */ - const char* start = s; - - // Look at most 2 characters, so that "\x0ddir" -> "^Mdir". - for ( int len = 0; len < 2 && isascii(*s) && isxdigit(*s); - ++s, ++len) - ; - - int result; - if ( sscanf(start, "%2x", &result) != 1 ) - { - throw EscapeException(fmt("bad hexadecimal escape: \"%s", start)); - result = 0; - } - - return result; - } - - default: - return s[-1]; - } - } - -} // private namespace - -ConstString::ConstString(const string &s) - : str_(s) - { - // Copied from scan.l of Bro - try - { - const char* text = str_.c_str(); - int len = strlen(text) + 1; - int i = 0; - - char* s = new char[len]; - - // Skip leading quote. - for ( ++text; *text; ++text ) - { - if ( *text == '\\' ) - { - ++text; // skip '\' - s[i++] = expand_escape(text); - --text; // point to end of sequence - } - else - { - s[i++] = *text; - } - } - ASSERT(i < len); - - // Get rid of trailing quote. - ASSERT(s[i-1] == '"'); - s[i-1] = '\0'; - - unescaped_ = s; - delete [] s; - } - catch(EscapeException const &e) - { - // Throw again with the object - throw Exception(this, e.msg().c_str()); - } - } - diff --git a/aux/binpac/src/pac_cstr.h b/aux/binpac/src/pac_cstr.h deleted file mode 100644 index d1faaf7604..0000000000 --- a/aux/binpac/src/pac_cstr.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef pac_cstr_h -#define pac_cstr_h - -#include "pac_common.h" - -class ConstString : public Object -{ -public: - ConstString(const string &s); - - // The string in its escaped form, with surrounding '"'s - const string &str() const { return str_; } - const char *c_str() const { return str_.c_str(); } - - // The unescaped string, without surrounding '"'s - const string &unescaped() const { return unescaped_; } - -private: - string str_; - string unescaped_; -}; - -#endif // pac_cstr_h diff --git a/aux/binpac/src/pac_ctype.cc b/aux/binpac/src/pac_ctype.cc deleted file mode 100644 index cfde2f461b..0000000000 --- a/aux/binpac/src/pac_ctype.cc +++ /dev/null @@ -1,21 +0,0 @@ -#include "pac_ctype.h" - -string CType::DeclareInstance(const string &var) const - { - return strfmt("%s %s", name().c_str(), var.c_str()); - } - -string CType::DeclareConstReference(const string &var) const - { - return strfmt("%s const &%s", name().c_str(), var.c_str()); - } - -string CType::DeclareConstPointer(const string &var) const - { - return strfmt("%s const *%s", name().c_str(), var.c_str()); - } - -string CType::DeclarePointer(const string &var) const - { - return strfmt("%s *%s", name().c_str(), var.c_str()); - } diff --git a/aux/binpac/src/pac_ctype.h b/aux/binpac/src/pac_ctype.h deleted file mode 100644 index aebbc34d6a..0000000000 --- a/aux/binpac/src/pac_ctype.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef pac_ctype_h -#define pac_ctype_h - -#include "pac_common.h" - -// Represents a C++ type -class CType -{ -public: - CType(const string &name); - - string name() const { return name_; } - - string DeclareInstance(const string &var) const; - string DeclareConstReference(const string &var) const; - string DeclareConstPointer(const string &var) const; - string DeclarePointer(const string &var) const; - -protected: - string name_; -}; - -#endif // pac_ctype_h diff --git a/aux/binpac/src/pac_datadep.cc b/aux/binpac/src/pac_datadep.cc deleted file mode 100644 index 8c43e0e106..0000000000 --- a/aux/binpac/src/pac_datadep.cc +++ /dev/null @@ -1,76 +0,0 @@ -#include "pac_datadep.h" -#include "pac_expr.h" -#include "pac_id.h" -#include "pac_type.h" - -DataDepElement::DataDepElement(DDE_Type type) - : dde_type_(type), in_traversal(false) - { - } - -bool DataDepElement::Traverse(DataDepVisitor *visitor) - { - // Avoid infinite loop - if ( in_traversal ) - return true; - if ( ! visitor->PreProcess(this) ) - return false; - - in_traversal = true; - bool cont = DoTraverse(visitor); - in_traversal = false; - - if ( ! cont ) - return false; - if ( ! visitor->PostProcess(this) ) - return false; - return true; - } - -Expr *DataDepElement::expr() - { - return static_cast(this); - } - -Type *DataDepElement::type() - { - return static_cast(this); - } - -bool RequiresAnalyzerContext::PreProcess(DataDepElement *element) - { - switch ( element->dde_type() ) - { - case DataDepElement::EXPR: - ProcessExpr(element->expr()); - break; - default: - break; - } - - // Continue traversal until we know the answer is 'yes' - return ! requires_analyzer_context_; - } - -bool RequiresAnalyzerContext::PostProcess(DataDepElement *element) - { - return ! requires_analyzer_context_; - } - -void RequiresAnalyzerContext::ProcessExpr(Expr *expr) - { - if ( expr->expr_type() == Expr::EXPR_ID ) - { - requires_analyzer_context_ = - (requires_analyzer_context_ || - *expr->id() == *analyzer_context_id || - *expr->id() == *context_macro_id); - } - } - -bool RequiresAnalyzerContext::compute(DataDepElement *element) - { - RequiresAnalyzerContext visitor; - element->Traverse(&visitor); - return visitor.requires_analyzer_context_; - } diff --git a/aux/binpac/src/pac_datadep.h b/aux/binpac/src/pac_datadep.h deleted file mode 100644 index a45053fb01..0000000000 --- a/aux/binpac/src/pac_datadep.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef pac_datadep_h -#define pac_datadep_h - -// To provide a way to traverse through the data dependency graph. -// That is, to evaluate X, what must be evaluated. - -#include "pac_common.h" -#include "pac_dbg.h" - -class DataDepVisitor; - -class DataDepElement { -public: - enum DDE_Type { - ATTR, - CASEEXPR, - EXPR, - FIELD, - INPUT_BUFFER, - PARAM, - TYPE, - }; - - DataDepElement(DDE_Type type); - virtual ~DataDepElement() {} - - // Returns whether to continue traversal - bool Traverse(DataDepVisitor *visitor); - - // Returns whether to continue traversal - virtual bool DoTraverse(DataDepVisitor *visitor) = 0; - - DDE_Type dde_type() const { return dde_type_; } - Expr *expr(); - Type *type(); - -protected: - DDE_Type dde_type_; - bool in_traversal; -}; - -class DataDepVisitor { -public: - virtual ~DataDepVisitor() {} - // Returns whether to continue traversal - virtual bool PreProcess(DataDepElement *element) = 0; - virtual bool PostProcess(DataDepElement *element) = 0; -}; - -class RequiresAnalyzerContext : public DataDepVisitor { -public: - RequiresAnalyzerContext() : requires_analyzer_context_(false) {} - - // Returns whether to continue traversal - bool PreProcess(DataDepElement *element); - bool PostProcess(DataDepElement *element); - - bool requires_analyzer_context() const - { - return requires_analyzer_context_; - } - - static bool compute(DataDepElement *element); - -protected: - void ProcessExpr(Expr *expr); - - bool requires_analyzer_context_; -}; - -#endif // pac_datadep_h diff --git a/aux/binpac/src/pac_dataptr.cc b/aux/binpac/src/pac_dataptr.cc deleted file mode 100644 index beac6997cb..0000000000 --- a/aux/binpac/src/pac_dataptr.cc +++ /dev/null @@ -1,66 +0,0 @@ -#include "pac_exception.h" -#include "pac_id.h" -#include "pac_output.h" -#include "pac_utils.h" - -#include "pac_dataptr.h" - -DataPtr::DataPtr(Env* env, const ID* id, const int offset) - : id_(id), offset_(offset) - { - if ( id_ ) - { - if ( ! env->Evaluated(id_) ) - throw ExceptionIDNotEvaluated(id_); - - if ( offset_ == 0 ) - ptr_expr_ = strfmt("%s", env->RValue(id_)); - else - ptr_expr_ = strfmt("(%s + %d)", env->RValue(id_), offset_); - } - else - ptr_expr_ = "(null id)"; - } - -int DataPtr::AbsOffset(const ID* base_ptr) const - { - return ( id() == base_ptr ) ? offset() : -1; - } - -char* DataPtr::AbsOffsetExpr(Env* env, const ID* base_ptr) const - { - if ( AbsOffset(base_ptr) >= 0 ) - return nfmt("%d", offset()); - else - return nfmt("(%s - %s)", ptr_expr(), env->RValue(base_ptr)); - } - -void DataPtr::GenBoundaryCheck(Output* out_cc, Env* env, - const char* data_size, const char* data_name) const - { - ASSERT(id_); - - out_cc->println("// Checking out-of-bound for \"%s\"", data_name); - out_cc->println("if ( %s + (%s) > %s )", - ptr_expr(), - data_size, - env->RValue(end_of_data)); - - out_cc->inc_indent(); - out_cc->println("{"); - - char* data_offset = AbsOffsetExpr(env, begin_of_data); - - out_cc->println("// Handle out-of-bound condition"); - out_cc->println("throw ExceptionOutOfBound(\"%s\",", data_name); - out_cc->println(" (%s) + (%s), ", - data_offset, data_size); - out_cc->println(" (%s) - (%s));", - env->RValue(end_of_data), env->RValue(begin_of_data)); - - delete [] data_offset; - - out_cc->println("}"); - out_cc->dec_indent(); - } - diff --git a/aux/binpac/src/pac_dataptr.h b/aux/binpac/src/pac_dataptr.h deleted file mode 100644 index 602843ff56..0000000000 --- a/aux/binpac/src/pac_dataptr.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef pac_dataptr_h -#define pac_dataptr_h - -#include -#include "pac_common.h" - -// A data pointer is represented by an data pointer variable -// plus a constant offset. - -class DataPtr -{ -public: - DataPtr(Env* env, const ID* arg_id, const int arg_off); - - DataPtr const &operator=(DataPtr const &x) - { - id_ = x.id(); - offset_ = x.offset(); - ptr_expr_ = x.ptr_expr(); - - return *this; - } - - const ID* id() const { return id_; } - int offset() const { return offset_; } - - const char* ptr_expr() const - { - ASSERT(id_); - return ptr_expr_.c_str(); - } - - int AbsOffset(const ID* base_ptr) const; - char* AbsOffsetExpr(Env* env, const ID* base_ptr) const; - - void GenBoundaryCheck(Output* out, - Env* env, - const char* data_size, - const char* data_name) const; - -protected: - const ID* id_; - int offset_; - string ptr_expr_; -}; - -#endif // pac_dataptr_h diff --git a/aux/binpac/src/pac_dataunit.cc b/aux/binpac/src/pac_dataunit.cc deleted file mode 100644 index 2b7218963d..0000000000 --- a/aux/binpac/src/pac_dataunit.cc +++ /dev/null @@ -1,60 +0,0 @@ -#include "pac_context.h" -#include "pac_dataunit.h" -#include "pac_output.h" -#include "pac_paramtype.h" -#include "pac_varfield.h" - -AnalyzerDataUnit::AnalyzerDataUnit( - DataUnitType type, - ID *id, - ExprList *type_params, - ExprList *context_params) - : AnalyzerElement(DATAUNIT), - type_(type), - id_(id), - type_params_(type_params), - context_params_(context_params) - { - data_type_ = new ParameterizedType(id_, type_params_); - context_type_ = new ParameterizedType( - AnalyzerContextDecl::current_analyzer_context()->id()->clone(), - context_params_); - - dataunit_var_field_ = new ParseVarField( - Field::CLASS_MEMBER, - dataunit_id->clone(), - data_type()); - context_var_field_ = new PrivVarField( - analyzer_context_id->clone(), - context_type()); - } - -AnalyzerDataUnit::~AnalyzerDataUnit() - { - delete dataunit_var_field_; - delete context_var_field_; - } - -void AnalyzerDataUnit::Prepare(Env *env) - { - dataunit_var_field_->Prepare(env); - context_var_field_->Prepare(env); - } - -void AnalyzerDataUnit::GenNewDataUnit(Output *out_cc, Env *env) - { - out_cc->println("%s = new %s(%s);", - env->LValue(dataunit_id), - data_type()->class_name().c_str(), - data_type()->EvalParameters(out_cc, env).c_str()); - } - -void AnalyzerDataUnit::GenNewContext(Output *out_cc, Env *env) - { - out_cc->println("%s = new %s(%s);", - env->LValue(analyzer_context_id), - context_type()->class_name().c_str(), - context_type()->EvalParameters(out_cc, env).c_str()); - env->SetEvaluated(analyzer_context_id); - } - diff --git a/aux/binpac/src/pac_dataunit.h b/aux/binpac/src/pac_dataunit.h deleted file mode 100644 index eb76378afa..0000000000 --- a/aux/binpac/src/pac_dataunit.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef pac_dataunit_h -#define pac_dataunit_h - -#include "pac_analyzer.h" - -// The type and parameters of input data unit of a flow. For instance, the -// data unit of a DCE/RPC flow is DCE_RPC_PDU. - -class AnalyzerDataUnit : public AnalyzerElement -{ -public: - enum DataUnitType { DATAGRAM, FLOWUNIT }; - AnalyzerDataUnit( - DataUnitType type, - ID *id, - ExprList *type_params, - ExprList *context_params); - ~AnalyzerDataUnit(); - - void Prepare(Env *env); - - // Initializes dataunit_id - void GenNewDataUnit(Output *out_cc, Env *env); - // Initializes analyzer_context_id - void GenNewContext(Output *out_cc, Env *env); - - DataUnitType type() const { return type_; } - const ID *id() const { return id_; } - ExprList *type_params() const { return type_params_; } - ExprList *context_params() const { return context_params_; } - - ParameterizedType *data_type() const { return data_type_; } - ParameterizedType *context_type() const { return context_type_; } - - Field *dataunit_var_field() const { return dataunit_var_field_; } - Field *context_var_field() const { return context_var_field_; } - -private: - DataUnitType type_; - ID *id_; - ExprList *type_params_; - ExprList *context_params_; - ParameterizedType *data_type_; - ParameterizedType *context_type_; - Field *dataunit_var_field_; - Field *context_var_field_; -}; - -#endif // pac_dataunit_h diff --git a/aux/binpac/src/pac_dbg.h b/aux/binpac/src/pac_dbg.h deleted file mode 100644 index bcd87639fb..0000000000 --- a/aux/binpac/src/pac_dbg.h +++ /dev/null @@ -1,14 +0,0 @@ -/* $Id: pac_dbg.h 3265 2006-06-09 21:16:12Z rpang $ */ - -#ifndef pac_dbg_h -#define pac_dbg_h - -#include -#include - -extern bool FLAGS_pac_debug; - -#define ASSERT(x) assert(x) -#define DEBUG_MSG(x...) if ( FLAGS_pac_debug ) fprintf(stderr, x) - -#endif /* pac_dbg_h */ diff --git a/aux/binpac/src/pac_decl-inl.h b/aux/binpac/src/pac_decl-inl.h deleted file mode 100644 index 97c369fa9f..0000000000 --- a/aux/binpac/src/pac_decl-inl.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef pac_decl_inl_h -#define pac_decl_inl_h - -#include "pac_id.h" - -#endif // pac_decl_inl_h diff --git a/aux/binpac/src/pac_decl.cc b/aux/binpac/src/pac_decl.cc deleted file mode 100644 index 3c3ae95aa9..0000000000 --- a/aux/binpac/src/pac_decl.cc +++ /dev/null @@ -1,191 +0,0 @@ -#include "pac_attr.h" -#include "pac_context.h" -#include "pac_dataptr.h" -#include "pac_embedded.h" -#include "pac_exception.h" -#include "pac_expr.h" -#include "pac_exttype.h" -#include "pac_id.h" -#include "pac_output.h" -#include "pac_param.h" -#include "pac_record.h" -#include "pac_type.h" -#include "pac_utils.h" - -#include "pac_decl.h" - -DeclList *Decl::decl_list_ = 0; -Decl::DeclMap Decl::decl_map_; - -Decl::Decl(ID* id, DeclType decl_type) - : id_(id), decl_type_(decl_type), attrlist_(0) - { - decl_map_[id_] = this; - if ( ! decl_list_ ) - decl_list_ = new DeclList(); - decl_list_->push_back(this); - - DEBUG_MSG("Finished Decl %s\n", id_->Name()); - - analyzer_context_ = 0; - } - -Decl::~Decl() - { - delete id_; - delete_list(AttrList, attrlist_); - } - -void Decl::AddAttrs(AttrList* attrs) - { - if ( ! attrs ) - return; - if ( ! attrlist_ ) - attrlist_ = new AttrList(); - foreach ( i, AttrList, attrs ) - { - attrlist_->push_back(*i); - ProcessAttr(*i); - } - } - -void Decl::ProcessAttr(Attr *attr) - { - throw Exception(attr, "unhandled attribute"); - } - -void Decl::SetAnalyzerContext() - { - analyzer_context_ = - AnalyzerContextDecl::current_analyzer_context(); - if ( ! analyzer_context_ ) - { - throw Exception(this, - "analyzer context not defined"); - } - } - -void Decl::ProcessDecls(Output *out_h, Output *out_cc) - { - if ( ! decl_list_ ) - return; - - foreach(i, DeclList, decl_list_) - { - Decl *decl = *i; - current_decl_id = decl->id(); - decl->Prepare(); - } - - foreach(i, DeclList, decl_list_) - { - Decl *decl = *i; - current_decl_id = decl->id(); - decl->GenExternDeclaration(out_h); - } - - out_h->println("namespace binpac {\n"); - out_cc->println("namespace binpac {\n"); - - AnalyzerContextDecl *analyzer_context = - AnalyzerContextDecl::current_analyzer_context(); - - foreach(i, DeclList, decl_list_) - { - Decl *decl = *i; - current_decl_id = decl->id(); - decl->GenForwardDeclaration(out_h); - } - - if ( analyzer_context ) - analyzer_context->GenNamespaceEnd(out_h); - - out_h->println(""); - - foreach(i, DeclList, decl_list_) - { - Decl *decl = *i; - current_decl_id = decl->id(); - decl->GenCode(out_h, out_cc); - } - - if ( analyzer_context ) - { - analyzer_context->GenNamespaceEnd(out_h); - analyzer_context->GenNamespaceEnd(out_cc); - } - - out_h->println("} // namespace binpac"); - out_cc->println("} // namespace binpac"); - } - -Decl* Decl::LookUpDecl(const ID* id) - { - DeclMap::iterator it = decl_map_.find(id); - if ( it == decl_map_.end() ) - return 0; - return it->second; - } - -int HelperDecl::helper_id_seq = 0; - -HelperDecl::HelperDecl(HelperType helper_type, - ID* context_id, - EmbeddedCode* code) - : Decl(new ID(fmt("helper_%d", ++helper_id_seq)), HELPER), - helper_type_(helper_type), - context_id_(context_id), - code_(code) - { - } - -HelperDecl::~HelperDecl() - { - delete context_id_; - delete code_; - } - -void HelperDecl::Prepare() - { - // Do nothing - } - -void HelperDecl::GenExternDeclaration(Output *out_h) - { - if ( helper_type_ == EXTERN ) - code_->GenCode(out_h, global_env()); - } - -void HelperDecl::GenCode(Output *out_h, Output *out_cc) - { - Env *env = global_env(); - -#if 0 - if ( context_id_ ) - { - Decl *decl = Decl::LookUpDecl(context_id_); - if ( ! decl ) - { - throw Exception(context_id_, - fmt("cannot find declaration for %s", - context_id_->Name())); - } - env = decl->env(); - if ( ! env ) - { - throw Exception(context_id_, - fmt("not a type or analyzer: %s", - context_id_->Name())); - } - } -#endif - - if ( helper_type_ == HEADER ) - code_->GenCode(out_h, env); - else if ( helper_type_ == CODE ) - code_->GenCode(out_cc, env); - else if ( helper_type_ == EXTERN ) - ; // do nothing - else - ASSERT(0); - } diff --git a/aux/binpac/src/pac_decl.h b/aux/binpac/src/pac_decl.h deleted file mode 100644 index 6151022d20..0000000000 --- a/aux/binpac/src/pac_decl.h +++ /dev/null @@ -1,81 +0,0 @@ -#ifndef pac_decl_h -#define pac_decl_h - -#include "pac_common.h" -#include "pac_id.h" - -class Decl : public Object -{ -public: - // Note: ANALYZER is not for AnalyzerDecl (which is an - // abstract class) , but for AnalyzerContextDecl. - enum DeclType { ENUM, LET, TYPE, FUNC, CONN, FLOW, ANALYZER, HELPER, REGEX }; - - Decl(ID *id, DeclType decl_type); - virtual ~Decl(); - - const ID *id() const { return id_; } - DeclType decl_type() const { return decl_type_; } - AnalyzerContextDecl *analyzer_context() const - { return analyzer_context_; } - - // NULL except for TypeDecl or AnalyzerDecl - virtual Env *env() const { return 0; } - - virtual void Prepare() = 0; - - // Generate declarations out of the "binpac" namespace - virtual void GenExternDeclaration(Output *out_h) { /* do nothing */ } - - // Generate declarations before definition of classes - virtual void GenForwardDeclaration(Output *out_h) = 0; - - virtual void GenCode(Output *out_h, Output *out_cc) = 0; - - void TakeExprList(); - void AddAttrs(AttrList *attrlist); - void SetAnalyzerContext(); - -protected: - virtual void ProcessAttr(Attr *a); - - ID *id_; - DeclType decl_type_; - AttrList *attrlist_; - ExprList *expr_list_; - AnalyzerContextDecl *analyzer_context_; - -public: - static void ProcessDecls(Output *out_h, Output *out_cc); - static Decl *LookUpDecl(const ID *id); - -private: - static DeclList *decl_list_; - typedef map DeclMap; - static DeclMap decl_map_; -}; - -class HelperDecl : public Decl -{ -public: - enum HelperType { - HEADER, CODE, EXTERN, - }; - HelperDecl(HelperType type, ID *context_id, EmbeddedCode *code); - ~HelperDecl(); - - void Prepare(); - void GenExternDeclaration(Output *out_h); - void GenForwardDeclaration(Output *out_h) { /* do nothing */ } - void GenCode(Output *out_h, Output *out_cc); - -private: - HelperType helper_type_; - ID *context_id_; - ID *helper_id_; - EmbeddedCode *code_; - - static int helper_id_seq; -}; - -#endif // pac_decl_h diff --git a/aux/binpac/src/pac_embedded.cc b/aux/binpac/src/pac_embedded.cc deleted file mode 100644 index aca2d03a19..0000000000 --- a/aux/binpac/src/pac_embedded.cc +++ /dev/null @@ -1,82 +0,0 @@ -#include "pac_id.h" -#include "pac_primitive.h" -#include "pac_output.h" - -#include "pac_embedded.h" - -EmbeddedCodeSegment::EmbeddedCodeSegment(const string &s) - : s_(s), primitive_(0) - { - } - -EmbeddedCodeSegment::EmbeddedCodeSegment(PacPrimitive *primitive) - : s_(""), primitive_(primitive) - { - } - -EmbeddedCodeSegment::~EmbeddedCodeSegment() - { - delete primitive_; - } - -string EmbeddedCodeSegment::ToCode(Env *env) - { - if ( primitive_ && s_.empty() ) - s_ = primitive_->ToCode(env); - return s_; - } - -EmbeddedCode::EmbeddedCode() - { - segments_ = new EmbeddedCodeSegmentList(); - } - -EmbeddedCode::~EmbeddedCode() - { - delete_list(EmbeddedCodeSegmentList, segments_); - } - -void EmbeddedCode::Append(int atom) - { - current_segment_ += static_cast(atom); - } - -void EmbeddedCode::Append(const char *str) - { - current_segment_ += str; - } - -void EmbeddedCode::Append(PacPrimitive *primitive) - { - if ( ! current_segment_.empty() ) - { - segments_->push_back(new EmbeddedCodeSegment(current_segment_)); - current_segment_ = ""; - } - segments_->push_back(new EmbeddedCodeSegment(primitive)); - } - -void EmbeddedCode::GenCode(Output *out, Env *env) - { - if ( ! current_segment_.empty() ) - { - segments_->push_back(new EmbeddedCodeSegment(current_segment_)); - current_segment_ = ""; - } - - // TODO: return to the generated file after embedded code - // out->print("#line %d \"%s\"\n", line_num, filename.c_str()); - - // Allow use of RValue for undefined ID, in which case the - // ID's name is used as its RValue - env->set_allow_undefined_id(true); - - foreach(i, EmbeddedCodeSegmentList, segments_) - { - EmbeddedCodeSegment *segment = *i; - out->print("%s", segment->ToCode(env).c_str()); - } - - env->set_allow_undefined_id(false); - out->print("\n"); - } diff --git a/aux/binpac/src/pac_embedded.h b/aux/binpac/src/pac_embedded.h deleted file mode 100644 index b84de746e1..0000000000 --- a/aux/binpac/src/pac_embedded.h +++ /dev/null @@ -1,42 +0,0 @@ -#ifndef pac_embedded_h -#define pac_embedded_h - -#include "pac_common.h" - -class EmbeddedCodeSegment -{ -public: - explicit EmbeddedCodeSegment(const string &s); - explicit EmbeddedCodeSegment(PacPrimitive *primitive); - ~EmbeddedCodeSegment(); - - string ToCode(Env *env); - -private: - string s_; - PacPrimitive *primitive_; -}; - -typedef vector EmbeddedCodeSegmentList; - -class EmbeddedCode : public Object -{ -public: - EmbeddedCode(); - ~EmbeddedCode(); - - // Append a character - void Append(int atom); - void Append(const char *str); - - // Append a PAC primitive - void Append(PacPrimitive *primitive); - - void GenCode(Output *out, Env *env); - -private: - string current_segment_; - EmbeddedCodeSegmentList *segments_; -}; - -#endif // pac_embedded_h diff --git a/aux/binpac/src/pac_enum.cc b/aux/binpac/src/pac_enum.cc deleted file mode 100644 index deb1711bc6..0000000000 --- a/aux/binpac/src/pac_enum.cc +++ /dev/null @@ -1,70 +0,0 @@ -#include "pac_exception.h" -#include "pac_enum.h" -#include "pac_expr.h" -#include "pac_exttype.h" -#include "pac_output.h" -#include "pac_typedecl.h" - -Enum::Enum(ID* id, Expr* expr) - : id_(id), expr_(expr) - { - } - -Enum::~Enum() - { - delete id_; - delete expr_; - } - -void Enum::GenHeader(Output* out_h, int *pval) - { - ASSERT(pval); - if ( expr_ ) - { - if ( ! expr_->ConstFold(global_env(), pval) ) - throw ExceptionNonConstExpr(expr_); - out_h->println("%s = %d,", id_->Name(), *pval); - } - else - out_h->println("%s,", id_->Name()); - global_env()->AddConstID(id_, *pval); - } - -EnumDecl::EnumDecl(ID *id, EnumList *enumlist) - : Decl(id, ENUM), enumlist_(enumlist) - { - ID *type_id = id->clone(); - datatype_ = new ExternType(type_id, ExternType::NUMBER); - extern_typedecl_ = new TypeDecl(type_id, 0, datatype_); - } - -EnumDecl::~EnumDecl() - { - delete_list(EnumList, enumlist_); - delete extern_typedecl_; - } - -void EnumDecl::Prepare() - { - // Do nothing - } - -void EnumDecl::GenForwardDeclaration(Output *out_h) - { - out_h->println("enum %s {", id_->Name()); - out_h->inc_indent(); - int c = 0; - foreach(i, EnumList, enumlist_) - { - (*i)->GenHeader(out_h, &c); - ++c; - } - out_h->dec_indent(); - out_h->println("};"); - } - -void EnumDecl::GenCode(Output* out_h, Output* /* out_cc */) - { - // Do nothing - } - diff --git a/aux/binpac/src/pac_enum.h b/aux/binpac/src/pac_enum.h deleted file mode 100644 index 6b255912b6..0000000000 --- a/aux/binpac/src/pac_enum.h +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef pac_enum_h -#define pac_enum_h - -#include "pac_decl.h" - -class Enum -{ -public: - Enum(ID *id, Expr *expr = 0); - ~Enum(); - - void GenHeader(Output *out_h, int *pval); - -private: - ID *id_; - Expr *expr_; -}; - -class EnumDecl : public Decl -{ -public: - EnumDecl(ID *id, EnumList *enumlist); - ~EnumDecl(); - - Type *DataType() const { return datatype_; } - - void Prepare(); - void GenForwardDeclaration(Output *out_h); - void GenCode(Output *out_h, Output *out_cc); - -private: - EnumList *enumlist_; - Type *datatype_; - TypeDecl *extern_typedecl_; -}; - -#endif // pac_enum_h diff --git a/aux/binpac/src/pac_exception.cc b/aux/binpac/src/pac_exception.cc deleted file mode 100644 index 462ef8e18f..0000000000 --- a/aux/binpac/src/pac_exception.cc +++ /dev/null @@ -1,70 +0,0 @@ -#include "pac_exception.h" -#include "pac_expr.h" -#include "pac_id.h" -#include "pac_utils.h" - -Exception::Exception(const Object* o, const char* msg) - { - if ( o ) - { - msg_ = o->Location(); - msg_ += ": error : "; - } - if ( msg ) - msg_ += msg; - if ( FLAGS_pac_debug ) - { - DEBUG_MSG("Exception: %s\n", msg_.c_str()); - abort(); - } - } - -ExceptionIDNotFound::ExceptionIDNotFound(const ID* id) - : Exception(id), id_(id) - { - append(fmt("`%s' undeclared", id_->Name())); - } - -ExceptionIDRedefinition::ExceptionIDRedefinition(const ID* id) - : Exception(id), id_(id) - { - append(fmt("`%s' redefined", id_->Name())); - } - -ExceptionIDNotEvaluated::ExceptionIDNotEvaluated(const ID* id) - : Exception(id), id_(id) - { - append(fmt("ID `%s' not evaluated before used", id->Name())); - } - -ExceptionIDNotField::ExceptionIDNotField(const ID* id) - : Exception(id), id_(id) - { - append(fmt("ID `%s' is not a field", id_->Name())); - } - -ExceptionMemberNotFound::ExceptionMemberNotFound(const ID* type_id, - const ID *member_id) - : Exception(member_id), type_id_(type_id), member_id_(member_id) - { - append(fmt("type %s does not have member `%s'", - type_id_->Name(), member_id_->Name())); - } - -ExceptionCyclicDependence::ExceptionCyclicDependence(const ID* id) - : Exception(id), id_(id) - { - append(fmt("cyclic dependence through `%s'", id_->Name())); - } - -ExceptionPaddingError::ExceptionPaddingError(const Object* o, const char* msg) - : Exception(o) - { - append(msg); - } - -ExceptionNonConstExpr::ExceptionNonConstExpr(const Expr* expr) - : Exception(expr) - { - append(fmt("Expression `%s' is not constant", expr->orig())); - } diff --git a/aux/binpac/src/pac_exception.h b/aux/binpac/src/pac_exception.h deleted file mode 100644 index 7653ffeacc..0000000000 --- a/aux/binpac/src/pac_exception.h +++ /dev/null @@ -1,97 +0,0 @@ -// $Id: pac_exception.h 3225 2006-06-08 00:00:01Z vern $ - -#ifndef pac_exception_h -#define pac_exception_h - -#include -using namespace std; - -#include "pac_common.h" - -class Exception -{ -public: - Exception(const Object* o, const char* msg = 0); - - const char* msg() const { return msg_.c_str(); } - void append(const char* s) { msg_ += s; } - -private: - string msg_; -}; - -class ExceptionIDNotFound : public Exception -{ -public: - ExceptionIDNotFound(const ID* id); - const ID* id() const { return id_; } - -private: - const ID* id_; -}; - -class ExceptionIDRedefinition : public Exception -{ -public: - ExceptionIDRedefinition(const ID* id); - const ID* id() const { return id_; } - -private: - const ID* id_; -}; - -class ExceptionIDNotEvaluated : public Exception -{ -public: - ExceptionIDNotEvaluated(const ID* id); - const ID* id() const { return id_; } - -private: - const ID* id_; -}; - -class ExceptionCyclicDependence : public Exception -{ -public: - ExceptionCyclicDependence(const ID* id); - const ID* id() const { return id_; } - -private: - const ID* id_; -}; - -class ExceptionPaddingError : public Exception -{ -public: - ExceptionPaddingError(const Object* o, const char* msg); -}; - -class ExceptionIDNotField : public Exception -{ -public: - ExceptionIDNotField(const ID* id); - const ID* id() const { return id_; } - -private: - const ID* id_; -}; - -class ExceptionMemberNotFound : public Exception -{ -public: - ExceptionMemberNotFound(const ID* type_id, const ID *member_id); - -private: - const ID *type_id_, *member_id_; -}; - -class ExceptionNonConstExpr : public Exception -{ -public: - ExceptionNonConstExpr(const Expr* expr); - -private: - const Expr *expr; -}; - -#endif /* pac_exception_h */ diff --git a/aux/binpac/src/pac_expr.cc b/aux/binpac/src/pac_expr.cc deleted file mode 100644 index 02303bc953..0000000000 --- a/aux/binpac/src/pac_expr.cc +++ /dev/null @@ -1,1041 +0,0 @@ -#include "pac_case.h" -#include "pac_cstr.h" -#include "pac_exception.h" -#include "pac_expr.h" -#include "pac_exttype.h" -#include "pac_id.h" -#include "pac_number.h" -#include "pac_output.h" -#include "pac_record.h" -#include "pac_regex.h" -#include "pac_strtype.h" -#include "pac_typedecl.h" -#include "pac_utils.h" - -string OrigExprList(ExprList *list) - { - bool first = true; - string str; - foreach(i, ExprList, list) - { - Expr *expr = *i; - if ( first ) - first = false; - else - str += ", "; - str += expr->orig(); - } - return str; - } - -string EvalExprList(ExprList *exprlist, Output *out, Env *env) - { - string val_list(""); - bool first = true; - - foreach(i, ExprList, exprlist) - { - if ( ! first ) - val_list += ", "; - val_list += (*i)->EvalExpr(out, env); - first = false; - } - - return val_list; - } - -static const char* expr_fmt[] = -{ -# define EXPR_DEF(type, num_op, fmt) fmt, -# include "pac_expr.def" -# undef EXPR_DEF -}; - -void Expr::init() - { - id_ = 0; - num_ = 0; - cstr_ = 0; - regex_ = 0; - num_operands_ = 0; - operand_[0] = 0; - operand_[1] = 0; - operand_[2] = 0; - args_ = 0; - cases_ = 0; - } - -Expr::Expr(ID* arg_id) - : DataDepElement(EXPR) - { - init(); - expr_type_ = EXPR_ID; - id_ = arg_id; - num_operands_ = 0; - orig_ = fmt("%s", id_->Name()); - } - -Expr::Expr(Number* arg_num) - : DataDepElement(EXPR) - { - init(); - expr_type_ = EXPR_NUM; - num_ = arg_num; - num_operands_ = 0; - orig_ = fmt("((int) %s)", num_->Str()); - } - -Expr::Expr(ConstString *cstr) - : DataDepElement(EXPR) - { - init(); - expr_type_ = EXPR_CSTR; - cstr_ = cstr; - num_operands_ = 0; - orig_ = cstr_->str(); - } - -Expr::Expr(RegEx *regex) - : DataDepElement(EXPR) - { - init(); - expr_type_ = EXPR_REGEX; - regex_ = regex; - num_operands_ = 0; - orig_ = fmt("/%s/", regex_->str().c_str()); - } - -Expr::Expr(ExprType arg_type, Expr* op1) - : DataDepElement(EXPR) - { - init(); - expr_type_ = arg_type; - num_operands_ = 1; - operand_[0] = op1; - orig_ = fmt(expr_fmt[expr_type_], op1->orig()); - } - -Expr::Expr(ExprType arg_type, Expr* op1, Expr* op2) - : DataDepElement(EXPR) - { - init(); - expr_type_ = arg_type; - num_operands_ = 2; - operand_[0] = op1; - operand_[1] = op2; - operand_[2] = 0; - orig_ = fmt(expr_fmt[expr_type_], op1->orig(), op2->orig()); - } - -Expr::Expr(ExprType arg_type, Expr* op1, Expr* op2, Expr* op3) - : DataDepElement(EXPR) - { - init(); - expr_type_ = arg_type; - num_operands_ = 3; - operand_[0] = op1; - operand_[1] = op2; - operand_[2] = op3; - orig_ = fmt(expr_fmt[expr_type_], op1->orig(), op2->orig(), op3->orig()); - } - -Expr::Expr(ExprList *args) - : DataDepElement(EXPR) - { - init(); - expr_type_ = EXPR_CALLARGS; - num_operands_ = -1; - args_ = args; - - orig_ = OrigExprList(args_); - } - -Expr::Expr(Expr *index, CaseExprList *cases) - : DataDepElement(EXPR) - { - init(); - expr_type_ = EXPR_CASE; - num_operands_ = -1; - operand_[0] = index; - cases_ = cases; - - orig_ = strfmt("case %s of { ", index->orig()); - foreach(i, CaseExprList, cases_) - { - CaseExpr *c = *i; - orig_ += strfmt("%s => %s; ", - OrigExprList(c->index()).c_str(), - c->value()->orig()); - } - orig_ += "}"; - } - -Expr::~Expr() - { - delete id_; - delete operand_[0]; - delete operand_[1]; - delete operand_[2]; - delete_list(ExprList, args_); - delete_list(CaseExprList, cases_); - } - -void Expr::AddCaseExpr(CaseExpr *case_expr) - { - ASSERT(str_.empty()); - ASSERT(expr_type_ == EXPR_CASE); - ASSERT(cases_); - cases_->push_back(case_expr); - } - -void Expr::GenStrFromFormat(Env *env) - { - // The format != "@custom@" - ASSERT(*expr_fmt[expr_type_] != '@'); - - switch ( num_operands_ ) - { - case 1: - str_ = fmt(expr_fmt[expr_type_], - operand_[0]->str()); - break; - case 2: - str_ = fmt(expr_fmt[expr_type_], - operand_[0]->str(), - operand_[1]->str()); - break; - case 3: - str_ = fmt(expr_fmt[expr_type_], - operand_[0]->str(), - operand_[1]->str(), - operand_[2]->str()); - break; - default: - DEBUG_MSG("num_operands_ = %d, orig = %s\n", num_operands_, orig()); - ASSERT(0); - break; - } - } - -namespace { - - RecordField *GetRecordField(const ID *id, Env *env) - { - Field* field = env->GetField(id); - ASSERT(field); - if ( field->tof() != RECORD_FIELD && - field->tof() != PADDING_FIELD ) - throw Exception(id, "not a record field"); - RecordField *r = static_cast(field); - ASSERT(r); - return r; - } - -} // private namespace - -void Expr::GenCaseEval(Output *out_cc, Env *env) - { - ASSERT(expr_type_ == EXPR_CASE); - ASSERT(operand_[0]); - ASSERT(cases_); - - Type *val_type = DataType(env); - ID *val_var = env->AddTempID(val_type); - - out_cc->println("%s %s;", - val_type->DataTypeStr().c_str(), - env->LValue(val_var)); - - // force evaluation of IDs appearing in case stmt - operand_[0]->ForceIDEval(out_cc, env); - foreach(i, CaseExprList, cases_) - (*i)->value()->ForceIDEval(out_cc, env); - - out_cc->println("switch ( %s )", operand_[0]->EvalExpr(out_cc, env)); - - out_cc->inc_indent(); - out_cc->println("{"); - - CaseExpr *default_case = 0; - foreach(i, CaseExprList, cases_) - { - CaseExpr *c = *i; - ExprList *index = c->index(); - if ( ! index ) - { - if ( default_case ) - throw Exception(c, "duplicate default cases"); - default_case = c; - } - else - { - GenCaseStr(index, out_cc, env); - out_cc->inc_indent(); - out_cc->println("%s = %s;", - env->LValue(val_var), - c->value()->EvalExpr(out_cc, env)); - out_cc->println("break;"); - out_cc->dec_indent(); - } - } - - // Generate the default case after all other cases - GenCaseStr(0, out_cc, env); - out_cc->inc_indent(); - if ( default_case ) - { - out_cc->println("%s = %s;", - env->LValue(val_var), - default_case->value()->EvalExpr(out_cc, env)); - } - else - { - out_cc->println("throw ExceptionInvalidCaseIndex(\"%s\", %s);", - Location(), operand_[0]->EvalExpr(out_cc, env)); - } - out_cc->println("break;"); - out_cc->dec_indent(); - - out_cc->println("}"); - out_cc->dec_indent(); - - env->SetEvaluated(val_var); - str_ = env->RValue(val_var); - } - -void Expr::GenEval(Output* out_cc, Env* env) - { - switch ( expr_type_ ) - { - case EXPR_NUM: - str_ = num_->Str(); - break; - - case EXPR_ID: - if ( ! env->Evaluated(id_) ) - env->Evaluate(out_cc, id_); - str_ = env->RValue(id_); - break; - - case EXPR_MEMBER: - { - /* - For member expressions such X.Y, evaluating - X only is sufficient. (Actually trying to - evaluate Y will lead to error because Y is - not defined in the current environment.) - */ - operand_[0]->GenEval(out_cc, env); - - Type *ty0 = operand_[0]->DataType(env); - - str_ = fmt("%s%s", - operand_[0]->EvalExpr(out_cc, env), - ty0 ? - ty0->EvalMember(operand_[1]->id()).c_str() : - fmt("->%s()", operand_[1]->id()->Name())); - } - break; - - case EXPR_SUBSCRIPT: - { - operand_[0]->GenEval(out_cc, env); - operand_[1]->GenEval(out_cc, env); - - string v0 = operand_[0]->EvalExpr(out_cc, env); - string v1 = operand_[1]->EvalExpr(out_cc, env); - - Type *ty0 = operand_[0]->DataType(env); - if ( ty0 ) - str_ = ty0->EvalElement(v0, v1); - else - str_ = fmt("%s[%s]", v0.c_str(), v1.c_str()); - } - break; - - case EXPR_SIZEOF: - { - const ID *id = operand_[0]->id(); - RecordField *rf; - Type *ty; - - try - { - if ( (rf = GetRecordField(id, env)) != 0 ) - { - str_ = fmt("%s", rf->FieldSize(out_cc, env)); - } - } - catch ( ExceptionIDNotFound &e ) - { - if ( (ty = TypeDecl::LookUpType(id)) != 0 ) - { - int ty_size = ty->StaticSize(global_env()); - if ( ty_size >= 0 ) - str_ = fmt("%d", ty_size); - else - throw Exception(id, "unknown size"); - } - else - throw Exception(id, "not a record field or type"); - } - } - break; - - case EXPR_OFFSETOF: - { - const ID *id = operand_[0]->id(); - RecordField *rf = GetRecordField(id, env); - str_ = fmt("%s", rf->FieldOffset(out_cc, env)); - } - break; - - case EXPR_CALLARGS: - str_ = EvalExprList(args_, out_cc, env); - break; - - case EXPR_CASE: - GenCaseEval(out_cc, env); - break; - - default: - // Evaluate every operand by default - for ( int i = 0; i < 3; ++i ) - if ( operand_[i] ) - operand_[i]->GenEval(out_cc, env); - GenStrFromFormat(env); - break; - } - } - -void Expr::ForceIDEval(Output* out_cc, Env* env) - { - switch ( expr_type_ ) - { - case EXPR_NUM: - case EXPR_SIZEOF: - case EXPR_OFFSETOF: - break; - - case EXPR_ID: - if ( ! env->Evaluated(id_) ) - env->Evaluate(out_cc, id_); - break; - - case EXPR_MEMBER: - operand_[0]->ForceIDEval(out_cc, env); - break; - - case EXPR_CALLARGS: - { - foreach(i, ExprList, args_) - (*i)->ForceIDEval(out_cc, env); - } - break; - - case EXPR_CASE: - { - operand_[0]->ForceIDEval(out_cc, env); - foreach(i, CaseExprList, cases_) - (*i)->value()->ForceIDEval(out_cc, env); - } - break; - - default: - // Evaluate every operand by default - for ( int i = 0; i < 3; ++i ) - if ( operand_[i] ) - operand_[i]->ForceIDEval(out_cc, env); - break; - } - } - - -const char* Expr::EvalExpr(Output* out_cc, Env* env) - { - GenEval(out_cc, env); - return str(); - } - -Type *Expr::DataType(Env *env) const - { - Type *data_type; - - switch ( expr_type_ ) - { - case EXPR_ID: - data_type = env->GetDataType(id_); - break; - - case EXPR_MEMBER: - { - // Get type of the parent - Type *parent_type = operand_[0]->DataType(env); - if ( ! parent_type ) - return 0; - data_type = parent_type->MemberDataType(operand_[1]->id()); - } - break; - - case EXPR_SUBSCRIPT: - { - // Get type of the parent - Type *parent_type = operand_[0]->DataType(env); - data_type = parent_type->ElementDataType(); - } - break; - - case EXPR_PAREN: - data_type = operand_[0]->DataType(env); - break; - - case EXPR_COND: - { - Type *type1 = operand_[1]->DataType(env); - Type *type2 = operand_[2]->DataType(env); - if ( ! Type::CompatibleTypes(type1, type2) ) - { - throw Exception(this, - fmt("type mismatch: %s vs %s", - type1->DataTypeStr().c_str(), - type2->DataTypeStr().c_str())); - } - data_type = type1; - } - break; - - case EXPR_CALL: - data_type = operand_[0]->DataType(env); - break; - - case EXPR_CASE: - { - if ( cases_ && ! cases_->empty() ) - { - Type *type1 = - cases_->front()->value()->DataType(env); - foreach(i, CaseExprList, cases_) - { - Type *type2 = - (*i)->value()->DataType(env); - if ( ! Type::CompatibleTypes(type1, type2) ) - { - throw Exception(this, - fmt("type mismatch: %s vs %s", - type1->DataTypeStr().c_str(), - type2->DataTypeStr().c_str())); - } - if ( type1 == extern_type_nullptr ) - type1 = type2; - } - data_type = type1; - } - else - data_type = 0; - } - break; - - case EXPR_NUM: - case EXPR_SIZEOF: - case EXPR_OFFSETOF: - case EXPR_NEG: - case EXPR_PLUS: - case EXPR_MINUS: - case EXPR_TIMES: - case EXPR_DIV: - case EXPR_MOD: - case EXPR_BITNOT: - case EXPR_BITAND: - case EXPR_BITOR: - case EXPR_BITXOR: - case EXPR_LSHIFT: - case EXPR_RSHIFT: - case EXPR_EQUAL: - case EXPR_GE: - case EXPR_LE: - case EXPR_GT: - case EXPR_LT: - case EXPR_NOT: - case EXPR_AND: - case EXPR_OR: - data_type = extern_type_int; - break; - - default: - data_type = 0; - break; - } - - return data_type; - } - -string Expr::DataTypeStr(Env *env) const - { - Type *type = DataType(env); - - if ( ! type ) - { - throw Exception(this, - fmt("cannot find data type for expression `%s'", - orig())); - } - - return type->DataTypeStr(); - } - -string Expr::SetFunc(Output *out, Env *env) - { - switch ( expr_type_ ) - { - case EXPR_ID: - return set_function(id_); - case EXPR_MEMBER: - { - // Evaluate the parent - string parent_val(operand_[0]->EvalExpr(out, env)); - return parent_val - + "->" - + set_function(operand_[1]->id()); - } - break; - default: - throw Exception(this, - fmt("cannot generate set function " - "for expression `%s'", orig())); - break; - } - } - -bool Expr::ConstFold(Env* env, int* pn) const - { - switch ( expr_type_ ) - { - case EXPR_NUM: - *pn = num_->Num(); - return true; - case EXPR_ID: - return env->GetConstant(id_, pn); - default: - // ### FIXME: folding consts - return false; - } - } - -// TODO: build a generic data dependency extraction process -namespace { - - // Maximum of two minimal header sizes - int mhs_max(int h1, int h2) - { - if ( h1 < 0 || h2 < 0 ) - return -1; - else - { - // return max(h1, h2); - return h1 > h2 ? h1 : h2; - } - } - - // MHS required to evaluate the field - int mhs_letfield(Env* env, LetField* field) - { - return field->expr()->MinimalHeaderSize(env); - } - - int mhs_recordfield(Env* env, RecordField* field) - { - int offset = field->static_offset(); - if ( offset < 0 ) // offset cannot be statically determined - return -1; - int size = field->StaticSize(env, offset); - if ( size < 0 ) // size cannot be statically determined - return -1; - return offset + size; - } - - int mhs_casefield(Env* env, CaseField* field) - { - // TODO: deal with the index - int size = field->StaticSize(env); - if ( size < 0 ) // size cannot be statically determined - return -1; - return size; - } - - int mhs_field(Env* env, Field* field) - { - int mhs = -1; - switch ( field->tof() ) - { - case LET_FIELD: - { - LetField *f = - static_cast(field); - ASSERT(f); - mhs = mhs_letfield(env, f); - } - break; - - case CONTEXT_FIELD: - case FLOW_FIELD: - ASSERT(0); - break; - - case PARAM_FIELD: - mhs = 0; - break; - - case RECORD_FIELD: - case PADDING_FIELD: - { - RecordField *f = - static_cast(field); - ASSERT(f); - mhs = mhs_recordfield(env, f); - } - break; - - case CASE_FIELD: - { - CaseField *f = - static_cast(field); - ASSERT(f); - mhs = mhs_casefield(env, f); - } - break; - - case PARSE_VAR_FIELD: - case PRIV_VAR_FIELD: - case PUB_VAR_FIELD: - case TEMP_VAR_FIELD: - mhs = 0; - break; - - case WITHINPUT_FIELD: - { - // ### TODO: fix this - mhs = -1; - } - break; - } - return mhs; - } - - int mhs_id(Env *env, const ID *id) - { - int mhs = -1; - switch ( env->GetIDType(id) ) - { - case CONST: - case GLOBAL_VAR: - case TEMP_VAR: - case STATE_VAR: - case FUNC_ID: - case FUNC_PARAM: - mhs = 0; - break; - case MEMBER_VAR: - case PRIV_MEMBER_VAR: - { - Field* field = env->GetField(id); - if ( ! field ) - throw ExceptionIDNotField(id); - mhs = mhs_field(env, field); - } - break; - case UNION_VAR: - // TODO: deal with UNION_VAR - mhs = -1; - break; - case MACRO: - { - Expr *e = env->GetMacro(id); - mhs = e->MinimalHeaderSize(env); - } - break; - } - return mhs; - } -} - -int Expr::MinimalHeaderSize(Env *env) - { - int mhs; - - switch ( expr_type_ ) - { - case EXPR_NUM: - // Zero byte is required - mhs = 0; - break; - - case EXPR_ID: - mhs = mhs_id(env, id_); - break; - - case EXPR_MEMBER: - // TODO: this is not a tight bound because - // one actually does not have to parse the - // whole record to compute one particular - // field. - mhs = operand_[0]->MinimalHeaderSize(env); - break; - - case EXPR_SUBSCRIPT: - { - int index; - Type *array_type = operand_[0]->DataType(env); - Type *elem_type = array_type->ElementDataType(); - int elem_size = elem_type->StaticSize(env); - if ( elem_size >= 0 && - operand_[1]->ConstFold(env, &index) ) - { - mhs = elem_size * index; - } - else - { - mhs = -1; - } - } - - case EXPR_SIZEOF: - { - const ID* id = operand_[0]->id(); - ASSERT(id); - RecordField *rf; - Type *ty; - - if ( (rf = GetRecordField(id, env)) != 0 ) - { - if ( rf->StaticSize(env, -1) >= 0 ) - mhs = 0; - else - mhs = mhs_recordfield(env, rf); - } - - else if ( (ty = TypeDecl::LookUpType(id)) != 0 ) - { - mhs = 0; - } - - else - throw Exception(id, "not a record field or type"); - } - break; - - case EXPR_OFFSETOF: - { - const ID* id = operand_[0]->id(); - ASSERT(id); - RecordField *field = GetRecordField(id, env); - - mhs = field->static_offset(); - if ( mhs < 0 ) - { - mhs = 0; - // Take the MHS of the preceding (non-let) field - RecordField* prev_field = field->prev(); - ASSERT(prev_field); - mhs = mhs_recordfield(env, prev_field); - } - } - break; - - case EXPR_CALLARGS: - { - mhs = 0; - if ( args_ ) - for ( unsigned int i = 0; i < args_->size(); ++i ) - mhs = mhs_max(mhs, (*args_)[i]->MinimalHeaderSize(env)); - } - break; - case EXPR_CASE: - { - mhs = operand_[0]->MinimalHeaderSize(env); - for ( unsigned int i = 0; i < cases_->size(); ++i ) - { - CaseExpr * ce = (*cases_)[i]; - if ( ce->index() ) - for ( unsigned int j = 0; j < ce->index()->size(); ++j ) - mhs = mhs_max(mhs, (*ce->index())[j]->MinimalHeaderSize(env)); - mhs = mhs_max(mhs, ce->value()->MinimalHeaderSize(env)); - } - } - break; - default: - // Evaluate every operand by default - mhs = 0; - for ( int i = 0; i < 3; ++i ) - if ( operand_[i] ) - mhs = mhs_max(mhs, operand_[i]->MinimalHeaderSize(env)); - break; - } - - return mhs; - } - -bool Expr::HasReference(const ID *id) const - { - switch ( expr_type_ ) - { - case EXPR_ID: - return *id == *id_; - - case EXPR_MEMBER: - return operand_[0]->HasReference(id); - - case EXPR_CALLARGS: - { - foreach(i, ExprList, args_) - if ( (*i)->HasReference(id) ) - return true; - } - return false; - - case EXPR_CASE: - { - foreach(i, CaseExprList, cases_) - if ( (*i)->HasReference(id) ) - return true; - } - return false; - - default: - // Evaluate every operand by default - for ( int i = 0; i < 3; ++i ) - { - if ( operand_[i] && - operand_[i]->HasReference(id) ) - { - return true; - } - } - return false; - } - } - -bool Expr::DoTraverse(DataDepVisitor *visitor) - { - switch ( expr_type_ ) - { - case EXPR_ID: - break; - - case EXPR_MEMBER: - /* - For member expressions such X.Y, evaluating - X only is sufficient. (Actually trying to - evaluate Y will lead to error because Y is - not defined in the current environment.) - */ - if ( ! operand_[0]->Traverse(visitor) ) - return false; - break; - - case EXPR_CALLARGS: - { - foreach(i, ExprList, args_) - if ( ! (*i)->Traverse(visitor) ) - return false; - } - break; - - case EXPR_CASE: - { - foreach(i, CaseExprList, cases_) - if ( ! (*i)->Traverse(visitor) ) - return false; - } - break; - - default: - // Evaluate every operand by default - for ( int i = 0; i < 3; ++i ) - { - if ( operand_[i] && - ! operand_[i]->Traverse(visitor) ) - { - return false; - } - } - break; - } - - return true; - } - -bool Expr::RequiresAnalyzerContext() const - { - switch ( expr_type_ ) - { - case EXPR_ID: - return *id_ == *analyzer_context_id; - - case EXPR_MEMBER: - /* - For member expressions such X.Y, evaluating - X only is sufficient. (Actually trying to - evaluate Y will lead to error because Y is - not defined in the current environment.) - */ - return operand_[0]->RequiresAnalyzerContext(); - - case EXPR_CALLARGS: - { - foreach(i, ExprList, args_) - if ( (*i)->RequiresAnalyzerContext() ) - return true; - } - return false; - - case EXPR_CASE: - { - foreach(i, CaseExprList, cases_) - if ( (*i)->RequiresAnalyzerContext() ) - return true; - } - return false; - - default: - // Evaluate every operand by default - for ( int i = 0; i < 3; ++i ) - if ( operand_[i] && - operand_[i]->RequiresAnalyzerContext() ) - { - DEBUG_MSG("'%s' requires analyzer context\n", operand_[i]->orig()); - return true; - } - return false; - } - } - -CaseExpr::CaseExpr(ExprList *index, Expr *value) - : DataDepElement(DataDepElement::CASEEXPR), - index_(index), value_(value) - { - } - -CaseExpr::~CaseExpr() - { - delete_list(ExprList, index_); - delete value_; - } - -bool CaseExpr::DoTraverse(DataDepVisitor *visitor) - { - foreach(i, ExprList, index_) - if ( ! (*i)->Traverse(visitor) ) - return false; - return value_->Traverse(visitor); - } - -bool CaseExpr::HasReference(const ID *id) const - { - return value_->HasReference(id); - } - -bool CaseExpr::RequiresAnalyzerContext() const - { - // index_ should evaluate to constants - return value_->RequiresAnalyzerContext(); - } diff --git a/aux/binpac/src/pac_expr.def b/aux/binpac/src/pac_expr.def deleted file mode 100644 index d7c0319522..0000000000 --- a/aux/binpac/src/pac_expr.def +++ /dev/null @@ -1,34 +0,0 @@ -EXPR_DEF(EXPR_ID, 0, "%s") -EXPR_DEF(EXPR_NUM, 0, "%s") -EXPR_DEF(EXPR_CSTR, 0, "%s") -EXPR_DEF(EXPR_REGEX, 0, "REGEX(%s)") -EXPR_DEF(EXPR_SUBSCRIPT, 2, "@element@(%s[%s])") -EXPR_DEF(EXPR_MEMBER, 2, "@%s->%s@") -EXPR_DEF(EXPR_PAREN, 1, " ( %s ) ") -EXPR_DEF(EXPR_CALL, 1, "%s(%s)") -EXPR_DEF(EXPR_CALLARGS, -1, "@custom@") -EXPR_DEF(EXPR_SIZEOF, 1, "@sizeof(%s)@") -EXPR_DEF(EXPR_OFFSETOF, 1, "@offsetof(%s)@") -EXPR_DEF(EXPR_NEG, 1, "-%s") -EXPR_DEF(EXPR_PLUS, 2, "%s + %s") -EXPR_DEF(EXPR_MINUS, 2, "%s - %s") -EXPR_DEF(EXPR_TIMES, 2, "%s * %s") -EXPR_DEF(EXPR_DIV, 2, "%s / %s") -EXPR_DEF(EXPR_MOD, 2, "%s %% %s") -EXPR_DEF(EXPR_BITNOT, 1, "~%s") -EXPR_DEF(EXPR_BITAND, 2, "%s & %s") -EXPR_DEF(EXPR_BITOR, 2, "%s | %s") -EXPR_DEF(EXPR_BITXOR, 2, "%s ^ %s") -EXPR_DEF(EXPR_LSHIFT, 2, "%s << %s") -EXPR_DEF(EXPR_RSHIFT, 2, "%s >> %s") -EXPR_DEF(EXPR_EQUAL, 2, "%s == %s") -EXPR_DEF(EXPR_NEQ, 2, "%s != %s") -EXPR_DEF(EXPR_GE, 2, "%s >= %s") -EXPR_DEF(EXPR_LE, 2, "%s <= %s") -EXPR_DEF(EXPR_GT, 2, "%s > %s") -EXPR_DEF(EXPR_LT, 2, "%s < %s") -EXPR_DEF(EXPR_NOT, 1, "! %s") -EXPR_DEF(EXPR_AND, 2, "%s && %s") -EXPR_DEF(EXPR_OR, 2, "%s || %s") -EXPR_DEF(EXPR_COND, 3, "%s ? %s : %s") -EXPR_DEF(EXPR_CASE, -1, "@custom@") diff --git a/aux/binpac/src/pac_expr.h b/aux/binpac/src/pac_expr.h deleted file mode 100644 index be1e70c6ea..0000000000 --- a/aux/binpac/src/pac_expr.h +++ /dev/null @@ -1,139 +0,0 @@ -#ifndef pac_expr_h -#define pac_expr_h - -#include "pac_common.h" -#include "pac_datadep.h" - -class CaseExpr; - -class Expr : public Object, public DataDepElement -{ -public: - enum ExprType { -# define EXPR_DEF(type, x, y) type, -# include "pac_expr.def" -# undef EXPR_DEF - }; - - void init(); - - Expr(ID *id); - Expr(Number *num); - Expr(ConstString *s); - Expr(RegEx *regex); - Expr(ExprList *args); // for EXPR_CALLARGS - Expr(Expr *index, CaseExprList *cases); - - Expr(ExprType type, Expr *op1); - Expr(ExprType type, Expr *op1, Expr *op2); - Expr(ExprType type, Expr *op1, Expr *op2, Expr *op3); - - virtual ~Expr(); - - const char *orig() const { return orig_.c_str(); } - const ID *id() const { return id_; } - const char *str() const { return str_.c_str(); } - ExprType expr_type() const { return expr_type_; } - - void AddCaseExpr(CaseExpr *case_expr); - - // Returns the data "type" of the expression. Here we only - // do a serious job for the EXPR_MEMBER and EXPR_SUBSCRIPT - // operators. For arithmetic operations, we fall back - // to "int". - Type *DataType(Env *env) const; - string DataTypeStr(Env *env) const; - - // Note: EvalExpr() may generate C++ statements in order to evaluate - // variables in the expression, so the following is wrong: - // - // out->print("int x = "); - // out->println("%s", expr->EvalExpr(out, env)); - // - // While putting them together is right: - // - // out->println("int x = %s", expr->EvalExpr(out, env)); - // - const char *EvalExpr(Output *out, Env *env); - - // force evaulation of IDs contained in this expression; - // necessary with case expr and conditional let fields (&if) - // for correct parsing of fields - void ForceIDEval(Output *out_cc, Env *env); - - // Returns the set_* function of the expression. - // The expression must be of form ID or x.ID. - string SetFunc(Output *out, Env *env); - - // Returns true if the expression folds to an integer - // constant with env, and puts the constant in *pn. - // - bool ConstFold(Env *env, int *pn) const; - - // Whether id is referenced in the expression - bool HasReference(const ID *id) const; - - // Suppose the data for type might be incomplete, what is - // the minimal number of bytes from data head required to - // compute the expression? For example, how many bytes of frame - // header do we need to determine the length of the frame? - // - // The parameter points to the Env of a type. - // - // Returns -1 if the number is not a constant. - // - int MinimalHeaderSize(Env *env); - - // Whether evaluation of the expression requires the analyzer context - bool RequiresAnalyzerContext() const; - -protected: - bool DoTraverse(DataDepVisitor *visitor); - -private: - ExprType expr_type_; - - int num_operands_; - Expr *operand_[3]; - - ID *id_; // EXPR_ID - Number *num_; // EXPR_NUM - ConstString *cstr_; // EXPR_CSTR - RegEx *regex_; // EXPR_REGEX - ExprList *args_; // EXPR_CALLARGS - CaseExprList *cases_; // EXPR_CASE - - string str_; // value string - string orig_; // original string for debugging info - - void GenStrFromFormat(Env *env); - void GenEval(Output *out, Env *env); - void GenCaseEval(Output *out_cc, Env *env); -}; - -string OrigExprList(ExprList *exprlist); -string EvalExprList(ExprList *exprlist, Output *out, Env *env); - -// An entry of the case expression, consisting of one or more constant -// expressions for the case index and a value expression. -class CaseExpr : public Object, public DataDepElement -{ -public: - CaseExpr(ExprList *index, Expr *value); - virtual ~CaseExpr(); - - ExprList *index() const { return index_; } - Expr *value() const { return value_; } - - bool HasReference(const ID *id) const; - bool RequiresAnalyzerContext() const; - -protected: - bool DoTraverse(DataDepVisitor *visitor); - -private: - ExprList *index_; - Expr *value_; -}; - -#endif // pac_expr_h diff --git a/aux/binpac/src/pac_externtype.def b/aux/binpac/src/pac_externtype.def deleted file mode 100644 index aeac5a51b0..0000000000 --- a/aux/binpac/src/pac_externtype.def +++ /dev/null @@ -1,15 +0,0 @@ -EXTERNTYPE(bool, bool, NUMBER) -EXTERNTYPE(int, int, NUMBER) -EXTERNTYPE(double, double, NUMBER) -EXTERNTYPE(string, string, PLAIN) -EXTERNTYPE(void, void, PLAIN) -EXTERNTYPE(voidptr, void, POINTER) -EXTERNTYPE(nullptr, nullptr, PLAIN) -EXTERNTYPE(bytearray, bytearray, PLAIN) -EXTERNTYPE(const_charptr, const_charptr, PLAIN) -EXTERNTYPE(const_byteptr, const_byteptr, PLAIN) -// EXTERNTYPE(const_byteseg, const_byteseg, PLAIN) -EXTERNTYPE(const_bytestring, const_bytestring, PLAIN) -// EXTERNTYPE(bytestring, bytestring, PLAIN) -EXTERNTYPE(re_matcher, re_matcher, PLAIN) -EXTERNTYPE(flowbuffer, FlowBuffer, POINTER) diff --git a/aux/binpac/src/pac_exttype.cc b/aux/binpac/src/pac_exttype.cc deleted file mode 100644 index 659d4cdc5e..0000000000 --- a/aux/binpac/src/pac_exttype.cc +++ /dev/null @@ -1,76 +0,0 @@ -#include "pac_exttype.h" -#include "pac_id.h" -#include "pac_decl.h" - -bool ExternType::DefineValueVar() const - { - return true; - } - -string ExternType::DataTypeStr() const - { - switch ( ext_type_ ) - { - case PLAIN: - case NUMBER: - return id_->Name(); - case POINTER: - return string(id_->Name()) + " *"; - default: - ASSERT(0); - return ""; - } - } - -int ExternType::StaticSize(Env* env) const - { - ASSERT(0); - return -1; - } - -bool ExternType::ByteOrderSensitive() const - { - return false; - } - -string ExternType::EvalMember(const ID *member_id) const - { - return strfmt("%s%s", - ext_type_ == POINTER ? "->" : ".", - member_id->Name()); - } - -void ExternType::DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags) - { - ASSERT(0); - } - -void ExternType::GenDynamicSize(Output* out, Env* env, const DataPtr& data) - { - ASSERT(0); - } - -Type *ExternType::DoClone() const - { - return new ExternType(id_->clone(), ext_type_); - } - -// Definitions of pre-defined external types - -#define EXTERNTYPE(name, ctype, exttype) ExternType *extern_type_##name = 0; -#include "pac_externtype.def" -#undef EXTERNTYPE - -void ExternType::static_init() - { - ID *id; - // TypeDecl *decl; - // decl = new TypeDecl(id, 0, extern_type_##name); - -#define EXTERNTYPE(name, ctype, exttype) \ - id = new ID(#ctype); \ - extern_type_##name = new ExternType(id, ExternType::exttype); \ - Type::AddPredefinedType(#name, extern_type_##name); -#include "pac_externtype.def" -#undef EXTERNTYPE - } diff --git a/aux/binpac/src/pac_exttype.h b/aux/binpac/src/pac_exttype.h deleted file mode 100644 index 6d81608195..0000000000 --- a/aux/binpac/src/pac_exttype.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef pac_exttype_h -#define pac_exttype_h - -#include "pac_type.h" - -// ExternType represent external C++ types that are not defined in -// PAC specification (therefore they cannot appear in data layout -// spefication, e.g., in a record field). The type name is copied -// literally to the compiled code. - -class ExternType : public Type -{ -public: - enum EXTType { PLAIN, NUMBER, POINTER }; - ExternType(const ID *id, EXTType ext_type) - : Type(EXTERN), - id_(id), - ext_type_(ext_type) {} - - bool DefineValueVar() const; - string DataTypeStr() const; - int StaticSize(Env *env) const; - bool ByteOrderSensitive() const; - - string EvalMember(const ID *member_id) const; - bool IsNumericType() const { return ext_type_ == NUMBER; } - bool IsPointerType() const { return ext_type_ == POINTER; } - -protected: - void DoGenParseCode(Output *out, Env *env, const DataPtr& data, int flags); - void GenDynamicSize(Output *out, Env *env, const DataPtr& data); - - Type *DoClone() const; - -private: - const ID *id_; - EXTType ext_type_; - -public: - static void static_init(); -}; - -#define EXTERNTYPE(name, ctype, exttype) extern ExternType *extern_type_##name; -#include "pac_externtype.def" -#undef EXTERNTYPE - -#endif // pac_exttype_h diff --git a/aux/binpac/src/pac_field.cc b/aux/binpac/src/pac_field.cc deleted file mode 100644 index 0ee70e4b28..0000000000 --- a/aux/binpac/src/pac_field.cc +++ /dev/null @@ -1,143 +0,0 @@ -#include "pac_attr.h" -#include "pac_common.h" -#include "pac_exception.h" -#include "pac_field.h" -#include "pac_id.h" -#include "pac_type.h" - -Field::Field(FieldType tof, int flags, ID *id, Type *type) - : DataDepElement(DataDepElement::FIELD), - tof_(tof), flags_(flags), id_(id), type_(type) - { - decl_id_ = current_decl_id; - field_id_str_ = strfmt("%s:%s", decl_id()->Name(), id_->Name()); - attrs_ = 0; - } - -Field::~Field() - { - delete id_; - delete type_; - delete_list(AttrList, attrs_); - } - -void Field::AddAttr(AttrList* attrs) - { - if ( ! attrs_ ) - { - attrs_ = attrs; - } - else - { - attrs_->insert(attrs_->end(), attrs->begin(), attrs->end()); - delete attrs; - } - - foreach(i, AttrList, attrs) - ProcessAttr(*i); - } - -void Field::ProcessAttr(Attr *a) - { - switch ( a->type() ) - { - case ATTR_IF: - if ( tof() != LET_FIELD && - tof() != WITHINPUT_FIELD ) - { - throw Exception(a, - "&if can only be applied to a " - "let field"); - } - break; - default: - break; - } - - if ( type_ ) - type_->ProcessAttr(a); - } - -bool Field::anonymous_field() const - { - return type_ && type_->anonymous_value_var(); - } - -int Field::ValueVarType() const - { - if ( flags_ & CLASS_MEMBER ) - return (flags_ & PUBLIC_READABLE) ? MEMBER_VAR : PRIV_MEMBER_VAR; - else - return TEMP_VAR; - } - -void Field::Prepare(Env *env) - { - if ( type_ ) - { - if ( anonymous_field() ) - flags_ &= ~(CLASS_MEMBER | PUBLIC_READABLE); - if ( ! type_->persistent() ) - flags_ &= (~PUBLIC_READABLE); - - type_->set_value_var(id(), ValueVarType()); - type_->Prepare(env, - flags_ & TYPE_TO_BE_PARSED ? - Type::TO_BE_PARSED : 0); - env->SetField(id(), this); - } - } - -void Field::GenPubDecls(Output* out_h, Env* env) - { - if ( type_ && (flags_ & PUBLIC_READABLE) && (flags_ & CLASS_MEMBER) ) - type_->GenPubDecls(out_h, env); - } - -void Field::GenPrivDecls(Output* out_h, Env* env) - { - // Generate private declaration only if it is a class member - if ( type_ && (flags_ & CLASS_MEMBER) ) - type_->GenPrivDecls(out_h, env); - } - -void Field::GenTempDecls(Output* out_h, Env* env) - { - // Generate temp field - if ( type_ && !(flags_ & CLASS_MEMBER) ) - type_->GenPrivDecls(out_h, env); - } - -void Field::GenInitCode(Output* out_cc, Env* env) - { - if ( type_ && ! anonymous_field() ) - type_->GenInitCode(out_cc, env); - } - -void Field::GenCleanUpCode(Output* out_cc, Env* env) - { - if ( type_ && ! anonymous_field() ) - type_->GenCleanUpCode(out_cc, env); - } - -bool Field::DoTraverse(DataDepVisitor *visitor) - { - // Check parameterized type - if ( type_ && ! type_->Traverse(visitor) ) - return false; - foreach(i, AttrList, attrs_) - if ( ! (*i)->Traverse(visitor) ) - return false; - return true; - } - -bool Field::RequiresAnalyzerContext() const - { - // Check parameterized type - if ( type_ && type_->RequiresAnalyzerContext() ) - return true; - foreach(i, AttrList, attrs_) - if ( (*i)->RequiresAnalyzerContext() ) - return true; - return false; - } diff --git a/aux/binpac/src/pac_field.h b/aux/binpac/src/pac_field.h deleted file mode 100644 index 169c8110ec..0000000000 --- a/aux/binpac/src/pac_field.h +++ /dev/null @@ -1,84 +0,0 @@ -#ifndef pac_field_h -#define pac_field_h - -#include "pac_common.h" -#include "pac_datadep.h" - -// A "field" is a member of class. - -enum FieldType { - CASE_FIELD, - CONTEXT_FIELD, - FLOW_FIELD, - LET_FIELD, - PADDING_FIELD, - PARAM_FIELD, - RECORD_FIELD, - PARSE_VAR_FIELD, - PRIV_VAR_FIELD, - PUB_VAR_FIELD, - TEMP_VAR_FIELD, - WITHINPUT_FIELD, -}; - -class Field : public Object, public DataDepElement -{ -public: - Field(FieldType tof, int flags, ID *id, Type *type); - // Field flags - - // Whether the field will be evaluated by calling the Parse() - // function of the type - static const int TYPE_TO_BE_PARSED = 1; - static const int TYPE_NOT_TO_BE_PARSED = 0; - - // Whether the field is a member of the class or a temp - // variable - static const int CLASS_MEMBER = 2; - static const int NOT_CLASS_MEMBER = 0; - - // Whether the field is public readable - static const int PUBLIC_READABLE = 4; - static const int NOT_PUBLIC_READABLE = 0; - - virtual ~Field(); - - FieldType tof() const { return tof_; } - const ID* id() const { return id_; } - Type *type() const { return type_; } - const ID* decl_id() const { return decl_id_; } - - bool anonymous_field() const; - - void AddAttr(AttrList* attrs); - - // The field interface - virtual void ProcessAttr(Attr *attr); - virtual void Prepare(Env* env); - - virtual void GenPubDecls(Output* out, Env* env); - virtual void GenPrivDecls(Output* out, Env* env); - virtual void GenTempDecls(Output* out, Env* env); - - virtual void GenInitCode(Output* out, Env* env); - virtual void GenCleanUpCode(Output* out, Env* env); - - virtual bool RequiresAnalyzerContext() const; - -protected: - int ValueVarType() const; - bool ToBeParsed() const; - - bool DoTraverse(DataDepVisitor *visitor); - -protected: - FieldType tof_; - int flags_; - ID* id_; - Type *type_; - const ID* decl_id_; - string field_id_str_; - AttrList* attrs_; -}; - -#endif // pac_field_h diff --git a/aux/binpac/src/pac_flow.cc b/aux/binpac/src/pac_flow.cc deleted file mode 100644 index adf574e879..0000000000 --- a/aux/binpac/src/pac_flow.cc +++ /dev/null @@ -1,340 +0,0 @@ -#include "pac_analyzer.h" -#include "pac_conn.h" -#include "pac_context.h" -#include "pac_dataptr.h" -#include "pac_dataunit.h" -#include "pac_embedded.h" -#include "pac_exception.h" -#include "pac_expr.h" -#include "pac_exttype.h" -#include "pac_flow.h" -#include "pac_output.h" -#include "pac_param.h" -#include "pac_paramtype.h" -#include "pac_type.h" -#include "pac_varfield.h" - - -FlowDecl::FlowDecl(ID *id, - ParamList *params, - AnalyzerElementList *elemlist) - : AnalyzerDecl(id, FLOW, params) - { - dataunit_ = 0; - conn_decl_ = 0; - flow_buffer_var_field_ = 0; - AddElements(elemlist); - } - -FlowDecl::~FlowDecl() - { - delete flow_buffer_var_field_; - delete dataunit_; - } - -ParameterizedType *FlowDecl::flow_buffer_type_ = 0; - -ParameterizedType *FlowDecl::flow_buffer_type() - { - if ( ! flow_buffer_type_ ) - { - flow_buffer_type_ = new ParameterizedType(new ID(kFlowBufferClass), 0); - } - return flow_buffer_type_; - } - -void FlowDecl::AddBaseClass(vector *base_classes) const - { - base_classes->push_back("binpac::FlowAnalyzer"); - } - -void FlowDecl::ProcessFlowElement(AnalyzerFlow *flow_elem) - { - throw Exception( - flow_elem, - "flow should be defined in only a connection declaration"); - } - -void FlowDecl::ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem) - { - if ( dataunit_ ) - { - throw Exception(dataunit_elem, - "dataunit already defined"); - } - dataunit_ = dataunit_elem; - - if ( dataunit_->type() == AnalyzerDataUnit::FLOWUNIT ) - { - dataunit_->data_type()->MarkIncrementalInput(); - - flow_buffer_var_field_ = new PrivVarField( - flow_buffer_id->clone(), - FlowDecl::flow_buffer_type()->Clone()); - type_->AddField(flow_buffer_var_field_); - - ASSERT(AnalyzerContextDecl::current_analyzer_context()); - AnalyzerContextDecl::current_analyzer_context()->AddFlowBuffer(); - - // Add an argument to the context initiation - dataunit_->context_type()->AddParamArg( - new Expr(flow_buffer_var_field_->id()->clone())); - } - } - -void FlowDecl::Prepare() - { - // Add the connection parameter - if ( ! conn_decl_ ) - { - throw Exception(this, - "no connection is not declared for the flow"); - } - - if ( ! params_ ) - params_ = new ParamList(); - - params_->insert(params_->begin(), - new Param(connection_id->clone(), - conn_decl_->DataType())); - - AnalyzerDecl::Prepare(); - - dataunit_->Prepare(env_); - } - -void FlowDecl::GenPubDecls(Output *out_h, Output *out_cc) - { - AnalyzerDecl::GenPubDecls(out_h, out_cc); - } - -void FlowDecl::GenPrivDecls(Output *out_h, Output *out_cc) - { - // Declare the data unit - dataunit_->dataunit_var_field()->GenPrivDecls(out_h, env_); - - // Declare the analyzer context - dataunit_->context_var_field()->GenPrivDecls(out_h, env_); - - AnalyzerDecl::GenPrivDecls(out_h, out_cc); - } - -void FlowDecl::GenInitCode(Output *out_cc) - { - AnalyzerDecl::GenInitCode(out_cc); - - out_cc->println("%s = 0;", - env_->LValue(dataunit_id)); - out_cc->println("%s = 0;", - env_->LValue(analyzer_context_id)); - - if ( dataunit_->type() == AnalyzerDataUnit::FLOWUNIT ) - { - flow_buffer_var_field_->type()->GenPreParsing(out_cc, env_); - env_->SetEvaluated(flow_buffer_var_field_->id()); - } - } - -void FlowDecl::GenCleanUpCode(Output *out_cc) - { - GenDeleteDataUnit(out_cc); - AnalyzerDecl::GenCleanUpCode(out_cc); - } - -void FlowDecl::GenEOFFunc(Output *out_h, Output *out_cc) - { - string proto = strfmt("%s()", kFlowEOF); - - out_h->println("void %s;", proto.c_str()); - - out_cc->println("void %s::%s", class_name().c_str(), proto.c_str()); - out_cc->inc_indent(); - out_cc->println("{"); - - foreach(i, AnalyzerHelperList, eof_helpers_) - { - (*i)->GenCode(0, out_cc, this); - } - - if ( dataunit_->type() == AnalyzerDataUnit::FLOWUNIT ) - { - out_cc->println("%s->set_eof();", - env_->LValue(flow_buffer_id)); - out_cc->println("%s(0, 0);", kNewData); - } - - out_cc->println("}"); - out_cc->dec_indent(); - } - -void FlowDecl::GenGapFunc(Output *out_h, Output *out_cc) - { - string proto = strfmt("%s(int gap_length)", kFlowGap); - - out_h->println("void %s;", proto.c_str()); - - out_cc->println("void %s::%s", class_name().c_str(), proto.c_str()); - out_cc->inc_indent(); - out_cc->println("{"); - - if ( dataunit_->type() == AnalyzerDataUnit::FLOWUNIT ) - { - out_cc->println("%s->NewGap(gap_length);", - env_->LValue(flow_buffer_id)); - } - - out_cc->println("}"); - out_cc->dec_indent(); - } - -void FlowDecl::GenProcessFunc(Output *out_h, Output *out_cc) - { - env_->AddID(begin_of_data, TEMP_VAR, extern_type_const_byteptr); - env_->AddID(end_of_data, TEMP_VAR, extern_type_const_byteptr); - - string proto = - strfmt("%s(const_byteptr %s, const_byteptr %s)", - kNewData, - env_->LValue(begin_of_data), - env_->LValue(end_of_data)); - - out_h->println("void %s;", proto.c_str()); - - out_cc->println("void %s::%s", class_name().c_str(), proto.c_str()); - out_cc->inc_indent(); - out_cc->println("{"); - - out_cc->println("try"); - out_cc->inc_indent(); - out_cc->println("{"); - - env_->SetEvaluated(begin_of_data); - env_->SetEvaluated(end_of_data); - - switch ( dataunit_->type() ) - { - case AnalyzerDataUnit::DATAGRAM: - GenCodeDatagram(out_cc); - break; - case AnalyzerDataUnit::FLOWUNIT: - GenCodeFlowUnit(out_cc); - break; - default: - ASSERT(0); - } - - out_cc->println("}"); - out_cc->dec_indent(); - - out_cc->println("catch ( Exception const &e )"); - out_cc->inc_indent(); - out_cc->println("{"); - GenCleanUpCode(out_cc); - if ( dataunit_->type() == AnalyzerDataUnit::FLOWUNIT ) - { - out_cc->println("%s->DiscardData();", - env_->LValue(flow_buffer_id)); - } - out_cc->println("throw e;"); - out_cc->println("}"); - out_cc->dec_indent(); - - out_cc->println("}"); - out_cc->dec_indent(); - out_cc->println(""); - } - -void FlowDecl::GenNewDataUnit(Output *out_cc) - { - Type *unit_datatype = dataunit_->data_type(); - // dataunit_->data_type()->GenPreParsing(out_cc, env_); - dataunit_->GenNewDataUnit(out_cc, env_); - if ( unit_datatype->buffer_input() && - unit_datatype->buffer_mode() == Type::BUFFER_BY_LENGTH ) - { - out_cc->println("%s->NewFrame(0, false);", - env_->LValue(flow_buffer_id)); - } - dataunit_->GenNewContext(out_cc, env_); - } - -void FlowDecl::GenDeleteDataUnit(Output *out_cc) - { - // Do not just delete dataunit, because we may just want to Unref it. - // out_cc->println("delete %s;", env_->LValue(dataunit_id)); - dataunit_->data_type()->GenCleanUpCode(out_cc, env_); - dataunit_->context_type()->GenCleanUpCode(out_cc, env_); - } - -void FlowDecl::GenCodeFlowUnit(Output *out_cc) - { - Type *unit_datatype = dataunit_->data_type(); - - out_cc->println("%s->NewData(%s, %s);", - env_->LValue(flow_buffer_id), - env_->RValue(begin_of_data), - env_->RValue(end_of_data)); - - out_cc->println("while ( %s->data_available() && ", - env_->LValue(flow_buffer_id)); - out_cc->inc_indent(); - out_cc->println("( !%s->have_pending_request() || %s->ready() ) )", - env_->LValue(flow_buffer_id), env_->LValue(flow_buffer_id)); - out_cc->println("{"); - - // Generate a new dataunit if necessary - out_cc->println("if ( ! %s )", env_->LValue(dataunit_id)); - out_cc->inc_indent(); - out_cc->println("{"); - out_cc->println("BINPAC_ASSERT(!%s);", - env_->LValue(analyzer_context_id)); - GenNewDataUnit(out_cc); - out_cc->println("}"); - out_cc->dec_indent(); - - DataPtr data(env_, 0, 0); - unit_datatype->GenParseCode(out_cc, env_, data, 0); - - out_cc->println("if ( %s )", - unit_datatype->parsing_complete(env_).c_str()); - out_cc->inc_indent(); - out_cc->println("{"); - out_cc->println("// Clean up the flow unit after parsing"); - GenDeleteDataUnit(out_cc); - // out_cc->println("BINPAC_ASSERT(%s == 0);", env_->LValue(dataunit_id)); - out_cc->println("}"); - out_cc->dec_indent(); - out_cc->println("else"); - out_cc->inc_indent(); - out_cc->println("{"); - out_cc->println("// Resume upon next input segment"); - out_cc->println("BINPAC_ASSERT(!%s->ready());", - env_->RValue(flow_buffer_id)); - out_cc->println("break;"); - out_cc->println("}"); - out_cc->dec_indent(); - - out_cc->println("}"); - out_cc->dec_indent(); - } - -void FlowDecl::GenCodeDatagram(Output *out_cc) - { - Type *unit_datatype = dataunit_->data_type(); - GenNewDataUnit(out_cc); - - string parse_params = strfmt("%s, %s", - env_->RValue(begin_of_data), - env_->RValue(end_of_data)); - - if ( RequiresAnalyzerContext::compute(unit_datatype) ) - { - parse_params += ", "; - parse_params += env_->RValue(analyzer_context_id); - } - - DataPtr dataptr(env_, begin_of_data, 0); - unit_datatype->GenParseCode(out_cc, env_, dataptr, 0); - - GenDeleteDataUnit(out_cc); - } diff --git a/aux/binpac/src/pac_flow.h b/aux/binpac/src/pac_flow.h deleted file mode 100644 index 652f206992..0000000000 --- a/aux/binpac/src/pac_flow.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef pac_flow_h -#define pac_flow_h - -#include "pac_analyzer.h" - -class FlowDecl : public AnalyzerDecl -{ -public: - FlowDecl(ID *flow_id, ParamList *params, AnalyzerElementList *elemlist); - ~FlowDecl(); - - void Prepare(); - - void set_conn_decl(ConnDecl *c) { conn_decl_ = c; } - - static ParameterizedType *flow_buffer_type(); - -protected: - void AddBaseClass(vector *base_classes) const; - - void GenInitCode(Output *out_cc); - void GenCleanUpCode(Output *out_cc); - void GenProcessFunc(Output *out_h, Output *out_cc); - void GenEOFFunc(Output *out_h, Output *out_cc); - void GenGapFunc(Output *out_h, Output *out_cc); - - void GenPubDecls(Output *out_h, Output *out_cc); - void GenPrivDecls(Output *out_h, Output *out_cc); - - void ProcessFlowElement(AnalyzerFlow *flow_elem); - void ProcessDataUnitElement(AnalyzerDataUnit *dataunit_elem); - -private: - void GenNewDataUnit(Output *out_cc); - void GenDeleteDataUnit(Output *out_cc); - void GenCodeFlowUnit(Output *out_cc); - void GenCodeDatagram(Output *out_cc); - - AnalyzerDataUnit *dataunit_; - ConnDecl *conn_decl_; - - Field *flow_buffer_var_field_; - - static ParameterizedType *flow_buffer_type_; -}; - -#endif // pac_flow_h diff --git a/aux/binpac/src/pac_func.cc b/aux/binpac/src/pac_func.cc deleted file mode 100644 index 8bde6e10f6..0000000000 --- a/aux/binpac/src/pac_func.cc +++ /dev/null @@ -1,123 +0,0 @@ -#include "pac_embedded.h" -#include "pac_expr.h" -#include "pac_func.h" -#include "pac_output.h" -#include "pac_param.h" -#include "pac_type.h" - -Function::Function(ID *id, Type *type, ParamList *params) - : id_(id), type_(type), params_(params), expr_(0), code_(0) - { - analyzer_decl_ = 0; - env_ = 0; - } - -Function::~Function() - { - delete id_; - delete type_; - delete_list(ParamList, params_); - delete env_; - delete expr_; - delete code_; - } - -void Function::Prepare(Env *env) - { - env->AddID(id_, FUNC_ID, type_); - env->SetEvaluated(id_); - - env_ = new Env(env, this); - - foreach(i, ParamList, params_) - { - Param *p = *i; - env_->AddID(p->id(), FUNC_PARAM, p->type()); - env_->SetEvaluated(p->id()); - } - } - -void Function::GenForwardDeclaration(Output* out_h) - { - // Do nothing - } - -void Function::GenCode(Output* out_h, Output* out_cc) - { - out_h->println("%s %s(%s);", - type_->DataTypeStr().c_str(), - id_->Name(), - ParamDecls(params_).c_str()); - - string class_str = ""; - if ( analyzer_decl_ ) - class_str = strfmt("%s::", analyzer_decl_->id()->Name()); - - string proto_str = strfmt("%s %s%s(%s)", - type_->DataTypeStr().c_str(), - class_str.c_str(), - id_->Name(), - ParamDecls(params_).c_str()); - - ASSERT(!(expr_ && code_)); - - if ( expr_ ) - { - out_cc->println("%s", proto_str.c_str()); - - out_cc->inc_indent(); - out_cc->println("{"); - - out_cc->println("return static_cast<%s>(%s);", - type_->DataTypeStr().c_str(), - expr_->EvalExpr(out_cc, env_)); - - out_cc->println("}"); - out_cc->dec_indent(); - } - - else if ( code_ ) - { - out_cc->println("%s", proto_str.c_str()); - - out_cc->inc_indent(); - out_cc->println("{"); - - code_->GenCode(out_cc, env_); - - out_cc->println("}"); - out_cc->dec_indent(); - } - - out_cc->println(""); - } - -FuncDecl::FuncDecl(Function *function) - : Decl(function->id()->clone(), FUNC), function_(function) - { - function_->Prepare(global_env()); - } - -FuncDecl::~FuncDecl() - { - delete function_; - } - -void FuncDecl::Prepare() - { - } - -void FuncDecl::GenForwardDeclaration(Output *out_h) - { - function_->GenForwardDeclaration(out_h); - } - -void FuncDecl::GenCode(Output *out_h, Output *out_cc) - { - function_->GenCode(out_h, out_cc); - } - -AnalyzerFunction::AnalyzerFunction(Function *function) - : AnalyzerElement(FUNCTION), function_(function) - { - } diff --git a/aux/binpac/src/pac_func.h b/aux/binpac/src/pac_func.h deleted file mode 100644 index df862323bb..0000000000 --- a/aux/binpac/src/pac_func.h +++ /dev/null @@ -1,68 +0,0 @@ -#ifndef pac_func_h -#define pac_func_h - -#include "pac_decl.h" -#include "pac_analyzer.h" - -class Function : public Object -{ -public: - Function(ID *id, Type *type, ParamList *params); - ~Function(); - - ID *id() const { return id_; } - - AnalyzerDecl *analyzer_decl() const { return analyzer_decl_; } - void set_analyzer_decl(AnalyzerDecl *decl) { analyzer_decl_ = decl; } - - Expr *expr() const { return expr_; } - void set_expr(Expr *expr) { expr_ = expr; } - - EmbeddedCode *code() const { return code_; } - void set_code(EmbeddedCode *code) { code_ = code; } - - void Prepare(Env *env); - void GenForwardDeclaration(Output *out_h); - void GenCode(Output *out_h, Output *out_cc); - -private: - Env *env_; - - ID *id_; - Type *type_; - ParamList *params_; - - AnalyzerDecl *analyzer_decl_; - - Expr *expr_; - EmbeddedCode *code_; -}; - -class FuncDecl : public Decl -{ -public: - FuncDecl(Function *function); - ~FuncDecl(); - - Function *function() const { return function_; } - - void Prepare(); - void GenForwardDeclaration(Output *out_h); - void GenCode(Output *out_h, Output *out_cc); - -private: - Function *function_; -}; - -class AnalyzerFunction : public AnalyzerElement -{ -public: - AnalyzerFunction(Function *function); - - Function *function() const { return function_; } - -private: - Function *function_; -}; - -#endif // pac_func_h diff --git a/aux/binpac/src/pac_id.cc b/aux/binpac/src/pac_id.cc deleted file mode 100644 index 5eb7a0d985..0000000000 --- a/aux/binpac/src/pac_id.cc +++ /dev/null @@ -1,440 +0,0 @@ -#include "pac_exception.h" -#include "pac_expr.h" -#include "pac_exttype.h" -#include "pac_field.h" -#include "pac_id.h" -#include "pac_type.h" -#include "pac_utils.h" - -const ID *default_value_var = 0; -const ID *null_id = 0; -const ID *null_byteseg_id = 0; -const ID *null_decl_id = 0; -const ID *begin_of_data = 0; -const ID *end_of_data = 0; -const ID *len_of_data = 0; -const ID *byteorder_id = 0; -const ID *bigendian_id = 0; -const ID *littleendian_id = 0; -const ID *unspecified_byteorder_id = 0; -const ID *const_true_id = 0; -const ID *const_false_id = 0; -const ID *analyzer_context_id = 0; -const ID *context_macro_id = 0; -const ID *this_id = 0; -const ID *sourcedata_id = 0; -const ID *connection_id = 0; -const ID *upflow_id = 0; -const ID *downflow_id = 0; -const ID *dataunit_id = 0; -const ID *flow_buffer_id = 0; -const ID *element_macro_id = 0; -const ID *input_macro_id = 0; -const ID *cxt_connection_id = 0; -const ID *cxt_flow_id = 0; -const ID *parsing_state_id = 0; -const ID *buffering_state_id = 0; - -int ID::anonymous_id_seq = 0; - -ID *ID::NewAnonymousID(const string &prefix) - { - ID *id = new ID(fmt("%s%03d", prefix.c_str(), ++anonymous_id_seq)); - id->anonymous_id_ = true; - return id; - } - -IDRecord::IDRecord(Env *arg_env, const ID* arg_id, IDType arg_id_type) - : env(arg_env), id(arg_id), id_type(arg_id_type) - { - eval = 0; - evaluated = in_evaluation = false; - setfunc = ""; // except for STATE_VAR - switch (id_type) - { - case MEMBER_VAR: - rvalue = strfmt("%s()", id->Name()); - lvalue = strfmt("%s_", id->Name()); - break; - case PRIV_MEMBER_VAR: - rvalue = strfmt("%s_", id->Name()); - lvalue = strfmt("%s_", id->Name()); - break; - case UNION_VAR: - rvalue = strfmt("%s()", id->Name()); - lvalue = strfmt("%s_", id->Name()); - break; - case CONST: - case GLOBAL_VAR: - rvalue = strfmt("%s", id->Name()); - lvalue = strfmt("%s", id->Name()); - break; - case TEMP_VAR: - rvalue = strfmt("t_%s", id->Name()); - lvalue = strfmt("t_%s", id->Name()); - break; - case STATE_VAR: - rvalue = strfmt("%s()", id->Name()); - lvalue = strfmt("%s_", id->Name()); - break; - case MACRO: - rvalue = "@MACRO@"; - lvalue = "@MACRO@"; - break; - case FUNC_ID: - rvalue = strfmt("%s", id->Name()); - lvalue = "@FUNC_ID@"; - break; - case FUNC_PARAM: - rvalue = strfmt("%s", id->Name()); - lvalue = "@FUNC_PARAM@"; - break; - } - field = 0; - constant_set = false; - } - -IDRecord::~IDRecord() - { - } - -void IDRecord::SetConstant(int c) - { - ASSERT(id_type == CONST); - constant_set = true; - constant = c; - } - -bool IDRecord::GetConstant(int *pc) const - { - if ( constant_set ) - *pc = constant; - return constant_set; - } - -void IDRecord::SetMacro(Expr *e) - { - ASSERT(id_type == MACRO); - macro = e; - } - -Expr *IDRecord::GetMacro() const - { - ASSERT(id_type == MACRO); - return macro; - } - -void IDRecord::SetEvaluated(bool v) - { - if ( v ) - ASSERT(! evaluated); - evaluated = v; - } - -void IDRecord::Evaluate(Output* out, Env* env) - { - if ( evaluated ) - return; - - if ( ! out ) - throw ExceptionIDNotEvaluated(id); - - if ( ! eval ) - throw Exception(id, "no evaluation method"); - - if ( in_evaluation ) - throw ExceptionCyclicDependence(id); - - in_evaluation = true; - eval->GenEval(out, env); - in_evaluation = false; - - evaluated = true; - } - -const char* IDRecord::RValue() const - { - if ( id_type == MACRO ) - return macro->EvalExpr(0, env); - - if ( id_type == TEMP_VAR && ! evaluated ) - throw ExceptionIDNotEvaluated(id); - - return rvalue.c_str(); - } - -const char* IDRecord::LValue() const - { - ASSERT(id_type != MACRO && id_type != FUNC_ID); - return lvalue.c_str(); - } - -Env::Env(Env* parent_env, Object* context_object) - : parent(parent_env), context_object_(context_object) - { - allow_undefined_id_ = false; - in_branch_ = false; - } - -Env::~Env() - { - for ( id_map_t::iterator it = id_map.begin(); it != id_map.end(); ++it ) - { - delete it->second; - it->second = 0; - } - } - -void Env::AddID(const ID* id, IDType id_type, Type *data_type) - { - DEBUG_MSG("To add ID `%s'...\n", id->Name()); - id_map_t::iterator it = id_map.find(id); - if ( it != id_map.end() ) - { - DEBUG_MSG("Duplicate definition: `%s'\n", it->first->Name()); - throw ExceptionIDRedefinition(id); - } - id_map[id] = new IDRecord(this, id, id_type); - // TODO: figure out when data_type must be non-NULL - // ASSERT(data_type); - SetDataType(id, data_type); - } - -void Env::AddConstID(const ID* id, const int c, Type *type) - { - if ( ! type ) - type = extern_type_int; - AddID(id, CONST, type); - SetConstant(id, c); - SetEvaluated(id); // a constant is always evaluated - } - -void Env::AddMacro(const ID *id, Expr *macro) - { - AddID(id, MACRO, macro->DataType(this)); - SetMacro(id, macro); - SetEvaluated(id); - } - -ID *Env::AddTempID(Type *type) - { - ID *id = ID::NewAnonymousID("t_var_"); - AddID(id, TEMP_VAR, type); - return id; - } - -IDRecord* Env::lookup(const ID* id, bool recursive, bool raise_exception) const - { - ASSERT(id); - - id_map_t::const_iterator it = id_map.find(id); - if ( it != id_map.end() ) - return it->second; - - if ( recursive && parent ) - return parent->lookup(id, recursive, raise_exception); - - if ( raise_exception ) - throw ExceptionIDNotFound(id); - else - return 0; - } - -IDType Env::GetIDType(const ID* id) const - { - return lookup(id, true, true)->GetType(); - } - -const char* Env::RValue(const ID* id) const - { - IDRecord *r = lookup(id, true, false); - if ( r ) - return r->RValue(); - else - { - if ( allow_undefined_id() ) - return id->Name(); - else - throw ExceptionIDNotFound(id); - } - } - -const char* Env::LValue(const ID* id) const - { - return lookup(id, true, true)->LValue(); - } - -void Env::SetEvalMethod(const ID* id, Evaluatable* eval) - { - lookup(id, true, true)->SetEvalMethod(eval); - } - -void Env::Evaluate(Output* out, const ID* id) - { - IDRecord *r = lookup(id, true, !allow_undefined_id()); - if ( r ) - r->Evaluate(out, this); - } - -bool Env::Evaluated(const ID* id) const - { - IDRecord *r = lookup(id, true, !allow_undefined_id()); - if ( r ) - return r->Evaluated(); - else - // Assume undefined variables are already evaluated - return true; - } - -void Env::SetEvaluated(const ID* id, bool v) - { - if ( in_branch() ) - { - Field *f = GetField(id); - if (f && f->tof() == LET_FIELD) - { - throw Exception( - context_object_, - fmt("INTERNAL ERROR: " - "evaluating let field '%s' in a branch! " - "To work around this problem, " - "add '&requires(%s)' to the case type. " - "Sorry for the inconvenience.\n", - id->Name(), - id->Name())); - ASSERT(0); - } - } - - IDRecord *r = lookup(id, false, false); - if ( r ) - r->SetEvaluated(v); - else if ( parent ) - parent->SetEvaluated(id, v); - else - throw ExceptionIDNotFound(id); - } - -void Env::SetField(const ID* id, Field* field) - { - lookup(id, false, true)->SetField(field); - } - -Field* Env::GetField(const ID* id) const - { - return lookup(id, true, true)->GetField(); - } - -void Env::SetDataType(const ID* id, Type* type) - { - lookup(id, true, true)->SetDataType(type); - } - -Type* Env::GetDataType(const ID* id) const - { - IDRecord *r = lookup(id, true, false); - if ( r ) - return r->GetDataType(); - else - return 0; - } - -string Env::DataTypeStr(const ID *id) const - { - Type *type = GetDataType(id); - if ( ! type ) - throw Exception(id, "data type not defined"); - return type->DataTypeStr(); - } - -void Env::SetConstant(const ID* id, int constant) - { - lookup(id, false, true)->SetConstant(constant); - } - -bool Env::GetConstant(const ID* id, int* pc) const - { - ASSERT(pc); - // lookup without raising exception - IDRecord* r = lookup(id, true, false); - if ( r ) - return r->GetConstant(pc); - else - return false; - } - -void Env::SetMacro(const ID* id, Expr *macro) - { - lookup(id, true, true)->SetMacro(macro); - } - -Expr* Env::GetMacro(const ID* id) const - { - return lookup(id, true, true)->GetMacro(); - } - -void init_builtin_identifiers() - { - default_value_var = new ID("val"); - null_id = new ID("NULL"); - null_byteseg_id = new ID("null_byteseg"); - begin_of_data = new ID("begin_of_data"); - end_of_data = new ID("end_of_data"); - len_of_data = new ID("length_of_data"); - byteorder_id = new ID("byteorder"); - bigendian_id = new ID("bigendian"); - littleendian_id = new ID("littleendian"); - unspecified_byteorder_id = new ID("unspecified_byteorder"); - const_true_id = new ID("true"); - const_false_id = new ID("false"); - analyzer_context_id = new ID("context"); - this_id = new ID("this"); - sourcedata_id = new ID("sourcedata"); - connection_id = new ID("connection"); - upflow_id = new ID("upflow"); - downflow_id = new ID("downflow"); - dataunit_id = new ID("dataunit"); - flow_buffer_id = new ID("flow_buffer"); - element_macro_id = new ID("$element"); - input_macro_id = new ID("$input"); - context_macro_id = new ID("$context"); - parsing_state_id = new ID("parsing_state"); - buffering_state_id = new ID("buffering_state"); - - null_decl_id = new ID(""); - current_decl_id = null_decl_id; - } - -Env* global_env() - { - static Env *the_global_env = 0; - - if ( ! the_global_env ) - { - the_global_env = new Env(0, 0); - - // These two are defined in binpac.h, so we do not need to - // generate code for them. - the_global_env->AddConstID(bigendian_id, 0); - the_global_env->AddConstID(littleendian_id, 1); - the_global_env->AddConstID(unspecified_byteorder_id, -1); - the_global_env->AddConstID(const_false_id, 0); - the_global_env->AddConstID(const_true_id, 1); - // A hack for ID "this" - the_global_env->AddConstID(this_id, 0); - the_global_env->AddConstID(null_id, 0, extern_type_nullptr); - -#if 0 - the_global_env->AddID(null_byteseg_id, - GLOBAL_VAR, - extern_type_const_byteseg); -#endif - } - - return the_global_env; - } - -string set_function(const ID *id) - { - return strfmt("set_%s", id->Name()); - } diff --git a/aux/binpac/src/pac_id.h b/aux/binpac/src/pac_id.h deleted file mode 100644 index 6ac89687d4..0000000000 --- a/aux/binpac/src/pac_id.h +++ /dev/null @@ -1,246 +0,0 @@ -#ifndef pac_id_h -#define pac_id_h - -#include -#include -using namespace std; - -#include "pac_common.h" -#include "pac_dbg.h" -#include "pac_utils.h" - -// Classes handling identifiers. -// -// ID -- name and location of definition of an ID -// -// IDRecord -- association of an ID, its definition type (const, global, temp, -// member, or union member), and its evaluation method. -// -// Evaluatable -- interface for a variable or a field that needs be evaluated -// before referenced. -// -// Env -- a mapping from ID names to their L/R-value expressions and evaluation -// methods. - -enum IDType { - CONST, - GLOBAL_VAR, - TEMP_VAR, - MEMBER_VAR, - PRIV_MEMBER_VAR, - UNION_VAR, - STATE_VAR, - MACRO, - FUNC_ID, - FUNC_PARAM, -}; - -class ID; -class IDRecord; -class Env; -class Evaluatable; - -class ID : public Object -{ -public: - ID(const char *arg_name) - : name(arg_name), anonymous_id_(false) - { - locname = nfmt("%s:%s", Location(), Name()); - } - ~ID() - { - delete locname; - } - - bool operator==(ID const &x) const { return name == x.Name(); } - - const char *Name() const { return name.c_str(); } - const char *LocName() const { return locname; } - bool is_anonymous() const { return anonymous_id_; } - - ID *clone() const { return new ID(Name()); } - -protected: - string name; - bool anonymous_id_; - char *locname; - friend class ID_ptr_cmp; - -public: - static ID *NewAnonymousID(const string &prefix); -private: - static int anonymous_id_seq; -}; - -// A comparison operator for pointers to ID's. -class ID_ptr_cmp -{ -public: - bool operator()(const ID *const & id1, const ID *const & id2) const - { - ASSERT(id1); - ASSERT(id2); - return id1->name < id2->name; - } -}; - -class IDRecord -{ -public: - IDRecord(Env *env, const ID *id, IDType id_type); - ~IDRecord(); - - IDType GetType() const { return id_type; } - - void SetDataType(Type *type) { data_type = type; } - Type *GetDataType() const { return data_type; } - - void SetEvalMethod(Evaluatable *arg_eval) { eval = arg_eval; } - void Evaluate(Output *out, Env *env); - void SetEvaluated(bool v); - bool Evaluated() const { return evaluated; } - - void SetField(Field *f) { field = f; } - Field *GetField() const { return field; } - - void SetConstant(int c); - bool GetConstant(int *pc) const; - - void SetMacro(Expr *expr); - Expr *GetMacro() const; - - const char * RValue() const; - const char * LValue() const; - -protected: - Env *env; - const ID *id; - IDType id_type; - - string rvalue; - string lvalue; - string setfunc; - - Type *data_type; - - Field *field; - - int constant; - bool constant_set; - - Expr *macro; - - bool evaluated; - bool in_evaluation; // to detect cyclic dependence - Evaluatable *eval; -}; - -class Evaluatable -{ -public: - virtual ~Evaluatable() {} - virtual void GenEval(Output *out, Env *env) = 0; -}; - -class Env -{ -public: - Env(Env *parent_env, Object *context_object); - ~Env(); - - bool allow_undefined_id() const { return allow_undefined_id_; } - void set_allow_undefined_id(bool x) { allow_undefined_id_ = x; } - - bool in_branch() const { return in_branch_; } - void set_in_branch(bool x) { in_branch_ = x; } - - void AddID(const ID *id, IDType id_type, Type *type); - void AddConstID(const ID *id, const int c, Type *type = 0); - void AddMacro(const ID *id, Expr *expr); - - // Generate a temp ID with a unique name - ID *AddTempID(Type *type); - - IDType GetIDType(const ID *id) const; - const char * RValue(const ID *id) const; - const char * LValue(const ID *id) const; - // const char *SetFunc(const ID *id) const; - - // Set evaluation method for the ID - void SetEvalMethod(const ID *id, Evaluatable *eval); - - // Evaluate the ID according to the evaluation method. It - // assumes the ID has an evaluation emthod. It does nothing - // if the ID has already been evaluated. - void Evaluate(Output *out, const ID *id); - - // Whether the ID has already been evaluated. - bool Evaluated(const ID *id) const; - - // Set the ID as evaluated (or not). - void SetEvaluated(const ID *id, bool v = true); - - void SetField(const ID *id, Field *field); - Field *GetField(const ID *id) const; - - bool GetConstant(const ID *id, int *pc) const; - - Expr *GetMacro(const ID *id) const; - - Type *GetDataType(const ID *id) const; - - string DataTypeStr(const ID *id) const; - -protected: - IDRecord *lookup(const ID *id, - bool recursive, - bool raise_exception) const; - - void SetDataType(const ID *id, Type *type); - void SetConstant(const ID *id, int constant); - void SetMacro(const ID *id, Expr *macro); - -private: - Env *parent; - Object *context_object_; - typedef map id_map_t; - id_map_t id_map; - bool allow_undefined_id_; - bool in_branch_; -}; - -extern const ID *default_value_var; -extern const ID *null_id; -extern const ID *null_byteseg_id; -extern const ID *begin_of_data; -extern const ID *end_of_data; -extern const ID *len_of_data; -extern const ID *byteorder_id; -extern const ID *bigendian_id; -extern const ID *littleendian_id; -extern const ID *unspecified_byteorder_id; -extern const ID *analyzer_context_id; -extern const ID *context_macro_id; -extern const ID *this_id; -extern const ID *sourcedata_id; -// extern const ID *sourcedata_begin_id; -// extern const ID *sourcedata_end_id; -extern const ID *connection_id; -extern const ID *upflow_id; -extern const ID *downflow_id; -extern const ID *dataunit_id; -extern const ID *flow_buffer_id; -extern const ID *element_macro_id; -extern const ID *cxt_connection_id; -extern const ID *cxt_flow_id; -extern const ID *input_macro_id; -extern const ID *parsing_state_id; -extern const ID *buffering_state_id; - -extern void init_builtin_identifiers(); -extern Env *global_env(); - -extern string set_function(const ID *id); - -#endif // pac_id_h diff --git a/aux/binpac/src/pac_inputbuf.cc b/aux/binpac/src/pac_inputbuf.cc deleted file mode 100644 index 1974860693..0000000000 --- a/aux/binpac/src/pac_inputbuf.cc +++ /dev/null @@ -1,44 +0,0 @@ -#include "pac_expr.h" -#include "pac_exttype.h" -#include "pac_id.h" -#include "pac_inputbuf.h" -#include "pac_output.h" -#include "pac_type.h" - -InputBuffer::InputBuffer(Expr *expr) - : DataDepElement(INPUT_BUFFER), expr_(expr) - { - } - -bool InputBuffer::DoTraverse(DataDepVisitor *visitor) - { - if ( expr_ && ! expr_->Traverse(visitor) ) - return false; - return true; - } - -bool InputBuffer::RequiresAnalyzerContext() const - { - return expr_->RequiresAnalyzerContext(); - } - -DataPtr InputBuffer::GenDataBeginEnd(Output *out_cc, Env *env) - { - env->AddID(begin_of_data, TEMP_VAR, extern_type_const_byteptr); - env->AddID(end_of_data, TEMP_VAR, extern_type_const_byteptr); - - out_cc->println("%s %s, %s;", - extern_type_const_byteptr->DataTypeStr().c_str(), - env->LValue(begin_of_data), - env->LValue(end_of_data)); - - out_cc->println("get_pointers(%s, &%s, &%s);", - expr_->EvalExpr(out_cc, env), - env->LValue(begin_of_data), - env->LValue(end_of_data)); - - env->SetEvaluated(begin_of_data); - env->SetEvaluated(end_of_data); - - return DataPtr(env, begin_of_data, 0); - } diff --git a/aux/binpac/src/pac_inputbuf.h b/aux/binpac/src/pac_inputbuf.h deleted file mode 100644 index f03a5193ab..0000000000 --- a/aux/binpac/src/pac_inputbuf.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef pac_inputbuf_h -#define pac_inputbuf_h - -#include "pac_datadep.h" -#include "pac_dataptr.h" - -class Expr; - -class InputBuffer : public Object, public DataDepElement -{ -public: - InputBuffer(Expr *expr); - - bool RequiresAnalyzerContext() const; - DataPtr GenDataBeginEnd(Output *out_cc, Env *env); - -protected: - bool DoTraverse(DataDepVisitor *visitor); - -private: - Expr *expr_; -}; - -#endif // pac_inputbuf_h diff --git a/aux/binpac/src/pac_let.cc b/aux/binpac/src/pac_let.cc deleted file mode 100644 index ebd7caef90..0000000000 --- a/aux/binpac/src/pac_let.cc +++ /dev/null @@ -1,167 +0,0 @@ -#include "pac_expr.h" -#include "pac_exttype.h" -#include "pac_let.h" -#include "pac_output.h" -#include "pac_type.h" - -namespace { - -void GenLetEval(const ID *id, Expr *expr, string prefix, Output* out, Env* env) - { - if ( expr ) - { - } - } - -} // private namespace - -LetField::LetField(ID* id, Type *type, Expr* expr) - : Field(LET_FIELD, - TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, - id, type), - expr_(expr) - { - ASSERT(expr_); - } - -LetField::~LetField() - { - delete expr_; - } - -bool LetField::DoTraverse(DataDepVisitor *visitor) - { - return Field::DoTraverse(visitor) && - expr()->Traverse(visitor); - } - -bool LetField::RequiresAnalyzerContext() const - { - return Field::RequiresAnalyzerContext() || - (expr() && expr()->RequiresAnalyzerContext()); - } - -void LetField::Prepare(Env* env) - { - if ( ! type_ ) - { - ASSERT(expr_); - type_ = expr_->DataType(env); - if ( type_ ) - type_ = type_->Clone(); - else - type_ = extern_type_int->Clone(); - - foreach(i, AttrList, attrs_) - ProcessAttr(*i); - } - - Field::Prepare(env); - env->SetEvalMethod(id_, this); - } - -void LetField::GenInitCode(Output* out_cc, Env* env) - { - int v; - if ( expr_ && expr_->ConstFold(env, &v) ) - { - DEBUG_MSG("Folding const for `%s'\n", id_->Name()); - GenEval(out_cc, env); - } - else - type_->GenInitCode(out_cc, env); - } - -void LetField::GenParseCode(Output* out_cc, Env* env) - { - if ( env->Evaluated(id_) ) - return; - - if ( type_->attr_if_expr() ) - { - // A conditional field - - env->Evaluate(out_cc, type_->has_value_var()); - - // force evaluation of IDs contained in this expr - expr()->ForceIDEval(out_cc, env); - - out_cc->println("if ( %s )", - env->RValue(type_->has_value_var())); - out_cc->inc_indent(); - out_cc->println("{"); - } - - out_cc->println("%s = %s;", - env->LValue(id_), - expr()->EvalExpr(out_cc, env)); - if ( ! env->Evaluated(id_) ) - env->SetEvaluated(id_); - - if ( type_->attr_if_expr() ) - { - out_cc->println("}"); - out_cc->dec_indent(); - } - } - -void LetField::GenEval(Output* out_cc, Env* env) - { - GenParseCode(out_cc, env); - } - -LetDecl::LetDecl(ID *id, Type *type, Expr *expr) - : Decl(id, LET), type_(type), expr_(expr) - { - if ( ! type_ ) - { - ASSERT(expr_); - type_ = expr_->DataType(global_env()); - if ( type_ ) - type_ = type_->Clone(); - else - type_ = extern_type_int->Clone(); - } - - Env *env = global_env(); - int c; - if ( expr_ && expr_->ConstFold(env, &c) ) - env->AddConstID(id_, c); - else - env->AddID(id_, GLOBAL_VAR, type_); - } - -LetDecl::~LetDecl() - { - delete id_; - delete type_; - delete expr_; - } - -void LetDecl::Prepare() - { - } - -void LetDecl::GenForwardDeclaration(Output* out_h) - { - } - -void LetDecl::GenCode(Output * out_h, Output *out_cc) - { - out_h->println("extern %s const %s;", - type_->DataTypeStr().c_str(), - global_env()->RValue(id_)); - GenEval(out_cc, global_env()); - } - -void LetDecl::GenEval(Output *out_cc, Env * /* env */) - { - Env *env = global_env(); - out_cc->println("%s %s = %s;", - fmt("%s const", type_->DataTypeStr().c_str()), - env->LValue(id_), - expr_->EvalExpr(out_cc, env)); - - if ( ! env->Evaluated(id_) ) - env->SetEvaluated(id_); - } diff --git a/aux/binpac/src/pac_let.h b/aux/binpac/src/pac_let.h deleted file mode 100644 index aba8128511..0000000000 --- a/aux/binpac/src/pac_let.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef pac_let_h -#define pac_let_h - -#include "pac_decl.h" -#include "pac_field.h" - -class LetField : public Field, Evaluatable -{ -public: - LetField(ID* arg_id, Type *type, Expr* arg_expr); - ~LetField(); - - Expr *expr() const { return expr_; } - - void Prepare(Env* env); - - void GenInitCode(Output* out, Env* env); - void GenParseCode(Output* out, Env* env); - void GenEval(Output* out, Env* env); - - bool RequiresAnalyzerContext() const; - -protected: - bool DoTraverse(DataDepVisitor *visitor); - -protected: - Expr* expr_; -}; - -class LetDecl : public Decl, Evaluatable -{ -public: - LetDecl(ID *id, Type *type, Expr *expr); - ~LetDecl(); - - Expr *expr() const { return expr_; } - - void Prepare(); - void GenForwardDeclaration(Output *out_h); - void GenCode(Output *out_h, Output *out_cc); - void GenEval(Output* out, Env* env); - -private: - Type *type_; - Expr *expr_; -}; - -#endif // pac_let_h diff --git a/aux/binpac/src/pac_main.cc b/aux/binpac/src/pac_main.cc deleted file mode 100644 index 7c98e526fa..0000000000 --- a/aux/binpac/src/pac_main.cc +++ /dev/null @@ -1,259 +0,0 @@ -// $Id: pac_main.cc 3320 2006-06-20 21:19:33Z rpang $ - -#include -#include - -#include "pac_common.h" -#include "pac_decl.h" -#include "pac_exttype.h" -#include "pac_id.h" -#include "pac_output.h" -#include "pac_parse.h" -#include "pac_type.h" -#include "pac_utils.h" -#include "pac_exception.h" - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -extern int yydebug; -extern int yyparse(); -extern void switch_to_file(FILE* fp_input); -string input_filename; - -bool FLAGS_pac_debug = false; -string FLAGS_output_directory; -vector FLAGS_include_directories; - -Output* header_output = 0; -Output* source_output = 0; - -void add_to_include_directories(string dirs) - { - unsigned int dir_begin = 0, dir_end; - while ( dir_begin < dirs.length() ) - { - for ( dir_end = dir_begin; dir_end < dirs.length(); ++dir_end) - if ( dirs[dir_end] == ':' ) - break; - - string dir = dirs.substr(dir_begin, dir_end - dir_begin); - - // Add a trailing '/' if necessary - if ( dir.length() > 0 && *(dir.end() - 1) != '/' ) - dir += '/'; - - FLAGS_include_directories.push_back(dir); - dir_begin = dir_end + 1; - } - } - -void pac_init() - { - init_builtin_identifiers(); - Type::init(); - } - -void insert_comments(Output* out, const char* source_filename) - { - out->println("// This file is automatically generated from %s.\n", - source_filename); - } - -void insert_basictype_defs(Output* out) - { - out->println("#ifndef pac_type_defs"); - out->println("#define pac_type_defs"); - out->println(""); - out->println("typedef char int8;"); - out->println("typedef short int16;"); - out->println("typedef long int32;"); - out->println("typedef unsigned char uint8;"); - out->println("typedef unsigned short uint16;"); - out->println("typedef unsigned long uint32;"); - out->println(""); - out->println("#endif /* pac_type_defs */"); - out->println(""); - } - -void insert_byteorder_macros(Output* out) - { - out->println("#define FixByteOrder16(x) (byteorder == HOST_BYTEORDER ? (x) : pac_swap16(x))"); - out->println("#define FixByteOrder32(x) (byteorder == HOST_BYTEORDER ? (x) : pac_swap32(x))"); - out->println(""); - } - -const char* to_id(const char* s) - { - static char t[1024]; - int i; - for ( i = 0; s[i] && i < (int) sizeof(t) - 1; ++i ) - t[i] = isalnum(s[i]) ? s[i] : '_'; - if ( isdigit(t[0]) ) - t[0] = '_'; - t[i] = '\0'; - return t; - } - -int compile(const char* filename) - { - FILE* fp_input = fopen(filename, "r"); - if ( ! fp_input ) - { - perror(fmt("Error in opening %s", filename)); - return -1; - } - input_filename = filename; - - string basename; - - if ( ! FLAGS_output_directory.empty() ) - { - // Strip leading directories of filename - const char *last_slash = strrchr(filename, '/'); - if ( last_slash ) - basename = last_slash + 1; - else - basename = filename; - basename = FLAGS_output_directory + "/" + basename; - } - else - basename = filename; - - // If the file name ends with ".pac" - if ( basename.length() > 4 && - basename.substr(basename.length() - 4) == ".pac" ) - { - basename = basename.substr(0, basename.length() - 4); - } - - basename += "_pac"; - - DEBUG_MSG("Output file: %s.{h,cc}\n", basename.c_str()); - - int ret = 0; - - try - { - switch_to_file(fp_input); - if ( yyparse() ) - return 1; - - Output out_h(fmt("%s.h", basename.c_str())); - Output out_cc(fmt("%s.cc", basename.c_str())); - - header_output = &out_h; - source_output = &out_cc; - - insert_comments(&out_h, filename); - insert_comments(&out_cc, filename); - - const char* filename_id = to_id(filename); - - out_h.println("#ifndef %s_h", filename_id); - out_h.println("#define %s_h", filename_id); - out_h.println(""); - out_h.println("#include "); - out_h.println(""); - out_h.println("#include \"binpac.h\""); - out_h.println(""); - - out_cc.println("#include \"%s.h\"\n", basename.c_str()); - - Decl::ProcessDecls(&out_h, &out_cc); - - out_h.println("#endif /* %s_h */", filename_id); - } - catch ( OutputException& e ) - { - fprintf(stderr, "Error in compiling %s: %s\n", - filename, e.errmsg()); - ret = 1; - } - catch ( Exception& e ) - { - fprintf(stderr, "%s\n", e.msg()); - exit(1); - } - - header_output = 0; - source_output = 0; - input_filename = ""; - fclose(fp_input); - - return ret; - } - -void usage() - { -#ifdef VERSION - fprintf(stderr, "binpac version %s\n", VERSION); -#endif - fprintf(stderr, "usage: binpac [options] \n"); - fprintf(stderr, " | pac-language input files\n"); - fprintf(stderr, " -d | use given directory for compiler output\n"); - fprintf(stderr, " -D | enable debugging output\n"); - fprintf(stderr, " -h | show command line help\n"); - fprintf(stderr, " -I | include in input file search path\n"); - exit(1); - } - -int main(int argc, char* argv[]) - { -#ifdef HAVE_MALLOC_OPTIONS - extern char *malloc_options; -#endif - int o; - while ( (o = getopt(argc, argv, "DI:d:h")) != -1 ) - { - switch(o) - { - case 'D': - yydebug = 1; - FLAGS_pac_debug = true; -#ifdef HAVE_MALLOC_OPTIONS - malloc_options = "A"; -#endif - break; - - case 'I': - // Add to FLAGS_include_directories - add_to_include_directories(optarg); - break; - - case 'd': - FLAGS_output_directory = optarg; - break; - - case 'h': - usage(); - break; - } - } - - // Strip the trailing '/'s - while ( ! FLAGS_output_directory.empty() && - *(FLAGS_output_directory.end() - 1) == '/' ) - { - FLAGS_output_directory.erase(FLAGS_output_directory.end()-1); - } - - // Add the current directory to FLAGS_include_directories - add_to_include_directories("."); - - pac_init(); - - argc -= optind; - argv += optind; - if ( argc == 0 ) - compile("-"); - - int ret = 0; - for ( int i = 0; i < argc; ++i ) - if ( compile(argv[i]) ) - ret = 1; - - return ret; - } - diff --git a/aux/binpac/src/pac_number.h b/aux/binpac/src/pac_number.h deleted file mode 100644 index f923068700..0000000000 --- a/aux/binpac/src/pac_number.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef pac_number_h -#define pac_number_h - -#include "pac_common.h" - -class Number : public Object -{ -public: - Number(int arg_n) - : s(fmt("%d", arg_n)), n(arg_n) {} - Number(const char* arg_s, int arg_n) - : s(arg_s), n(arg_n) {} - const char* Str() const { return s.c_str(); } - int Num() const { return n; } - -protected: - const string s; - const int n; -}; - -#endif // pac_number_h diff --git a/aux/binpac/src/pac_output.cc b/aux/binpac/src/pac_output.cc deleted file mode 100644 index 404b4422cc..0000000000 --- a/aux/binpac/src/pac_output.cc +++ /dev/null @@ -1,61 +0,0 @@ -// $Id: pac_output.cc 3225 2006-06-08 00:00:01Z vern $ - -#include -#include -#include -#include - -#include "pac_utils.h" -#include "pac_output.h" - -OutputException::OutputException(const char* arg_msg) - { - msg = arg_msg; - } - -OutputException::~OutputException() - { - } - -Output::Output(const char* filename) - { - fp = fopen(filename, "w"); - if ( ! fp ) - throw OutputException(strerror(errno)); - indent_ = 0; - } - -Output::~Output() - { - if ( fp ) - fclose(fp); - } - -int Output::print(const char* fmt, va_list ap) - { - int r = vfprintf(fp, fmt, ap); - if ( r == -1 ) - throw OutputException(strerror(errno)); - return r; - } - -int Output::print(const char* fmt, ...) - { - va_list ap; - va_start(ap, fmt); - return print(fmt, ap); - } - -int Output::println(const char* fmt, ...) - { - for ( int i = 0; i < indent(); ++i ) - fprintf(fp, "\t"); - - int r; - va_list ap; - va_start(ap, fmt); - r = print(fmt, ap); - - fprintf(fp, "\n"); - return r; - } diff --git a/aux/binpac/src/pac_output.h b/aux/binpac/src/pac_output.h deleted file mode 100644 index 9911f3a2b4..0000000000 --- a/aux/binpac/src/pac_output.h +++ /dev/null @@ -1,42 +0,0 @@ -// $Id: pac_output.h 3225 2006-06-08 00:00:01Z vern $ - -#ifndef pac_output_h -#define pac_output_h - -#include -#include -#include - -using namespace std; - -class OutputException { -public: - OutputException(const char* arg_msg); - ~OutputException(); - const char* errmsg() const { return msg.c_str(); } - -protected: - string msg; -}; - -class Output { -public: - Output(const char *filename); - ~Output(); - - int println(const char* fmt, ...); - int print(const char* fmt, ...); - - int indent() const { return indent_; } - - void inc_indent() { ++indent_; } - void dec_indent() { --indent_; } - -protected: - int print(const char* fmt, va_list ap); - - FILE* fp; - int indent_; -}; - -#endif /* pac_output_h */ diff --git a/aux/binpac/src/pac_param.cc b/aux/binpac/src/pac_param.cc deleted file mode 100644 index 21e452ee05..0000000000 --- a/aux/binpac/src/pac_param.cc +++ /dev/null @@ -1,70 +0,0 @@ -#include "pac_decl.h" -#include "pac_exttype.h" -#include "pac_field.h" -#include "pac_id.h" -#include "pac_output.h" -#include "pac_type.h" -#include "pac_utils.h" - -#include "pac_param.h" - -Param::Param(ID* id, Type *type) - : id_(id), type_(type) - { - if ( ! type_ ) - type_ = extern_type_int->Clone(); - - decl_str_ = strfmt("%s %s", - type_->DataTypeConstRefStr().c_str(), - id_->Name()); - - param_field_ = new ParamField(this); - } - -Param::~Param() - { - } - -const string &Param::decl_str() const - { - ASSERT(!decl_str_.empty()); - return decl_str_; - } - -string ParamDecls(ParamList *params) - { - string param_decls; - - int first = 1; - foreach (i, ParamList, params) - { - Param* p = *i; - const char* decl_str = p->decl_str().c_str(); - if ( first ) - first = 0; - else - param_decls += ", "; - param_decls += decl_str; - } - return param_decls; - } - -ParamField::ParamField(const Param *param) - : Field(PARAM_FIELD, - TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, - param->id(), - param->type()) - { - } - -void ParamField::GenInitCode(Output *out_cc, Env *env) - { - out_cc->println("%s = %s;", - env->LValue(id()), id()->Name()); - env->SetEvaluated(id()); - } - -void ParamField::GenCleanUpCode(Output* out_cc, Env* env) - { - // Do nothing - } diff --git a/aux/binpac/src/pac_param.h b/aux/binpac/src/pac_param.h deleted file mode 100644 index 5efc60fd3a..0000000000 --- a/aux/binpac/src/pac_param.h +++ /dev/null @@ -1,48 +0,0 @@ -#ifndef pac_param_h -#define pac_param_h - -#include "pac_common.h" -#include "pac_field.h" - -class Param : public Object -{ -public: - Param(ID* id, Type* type); - ~Param(); - - ID *id() const { return id_; } - Type *type() const { return type_; } - const string & decl_str() const; - Field *param_field() const { return param_field_; } - -private: - ID* id_; - Type* type_; - string decl_str_; - Field *param_field_; -}; - -class ParamField : public Field -{ -public: - ParamField(const Param *param); - - void GenInitCode(Output *out, Env *env); - void GenCleanUpCode(Output* out, Env* env); -}; - -// Returns the string with a list of param declarations separated by ','. -string ParamDecls(ParamList *params); - -#if 0 -// Generate assignments to parameters, in the form of "%s_ = %s;" % (id, id). -void GenParamAssignments(ParamList *params, Output *out_cc, Env *env); - -// Generate public access methods to parameter members. -void GenParamPubDecls(ParamList *params, Output *out_h, Env *env); - -// Generate private definitions of parameter members. -void GenParamPrivDecls(ParamList *params, Output *out_h, Env *env); -#endif - -#endif // pac_param_h diff --git a/aux/binpac/src/pac_paramtype.cc b/aux/binpac/src/pac_paramtype.cc deleted file mode 100644 index 96e79735a3..0000000000 --- a/aux/binpac/src/pac_paramtype.cc +++ /dev/null @@ -1,289 +0,0 @@ -#include "pac_context.h" -#include "pac_dataptr.h" -#include "pac_exception.h" -#include "pac_expr.h" -#include "pac_output.h" -#include "pac_paramtype.h" -#include "pac_typedecl.h" - -ParameterizedType::ParameterizedType(ID* type_id, ExprList* args) - : Type(PARAMETERIZED), type_id_(type_id), args_(args) - { - checking_requires_analyzer_context_ = false; - } - -ParameterizedType::~ParameterizedType() - { - } - -string ParameterizedType::EvalMember(const ID *member_id) const - { - Type *ty = ReferredDataType(true); - return strfmt("->%s", ty->env()->RValue(member_id)); - } - -string ParameterizedType::class_name() const - { - return type_id_->Name(); - } - -Type *ParameterizedType::DoClone() const - { - return new ParameterizedType(type_id_->clone(), args_); - } - -void ParameterizedType::AddParamArg(Expr *arg) - { - args_->push_back(arg); - } - -bool ParameterizedType::DefineValueVar() const - { - return true; - } - -string ParameterizedType::DataTypeStr() const - { - return strfmt("%s *", type_id_->Name()); - } - -Type *ParameterizedType::MemberDataType(const ID *member_id) const - { - Type *ref_type = TypeDecl::LookUpType(type_id_); - if ( ! ref_type ) - return 0; - return ref_type->MemberDataType(member_id); - } - -Type *ParameterizedType::ReferredDataType(bool throw_exception) const - { - Type* type = TypeDecl::LookUpType(type_id_); - if ( ! type ) - { - DEBUG_MSG("WARNING: cannot find referenced type for %s\n", - type_id_->Name()); - if ( throw_exception ) - throw ExceptionIDNotFound(type_id_); - } - return type; - } - -int ParameterizedType::StaticSize(Env* env) const - { - return ReferredDataType(true)->StaticSize(env); - } - -void ParameterizedType::DoMarkIncrementalInput() - { - Type *ty = ReferredDataType(true); - - ty->MarkIncrementalInput(); - - buffer_input_ = ty->buffer_input(); - incremental_parsing_ = ty->incremental_parsing(); - } - -Type::BufferMode ParameterizedType::buffer_mode() const - { - // Note that the precedence is on attributes (&oneline or &length) - // specified on the parameterized type directly than on the type - // declaration. - // - // If both &oneline and &length are specified at the same place, - // use &length. - // - BufferMode mode = Type::buffer_mode(); - Type *ty = ReferredDataType(true); - - if ( mode != NOT_BUFFERABLE ) - return mode; - else if ( ty->BufferableByLength() ) - return BUFFER_BY_LENGTH; - else if ( ty->BufferableByLine() ) - return BUFFER_BY_LINE; - - return NOT_BUFFERABLE; - } - -bool ParameterizedType::ByteOrderSensitive() const - { - return ReferredDataType(true)->RequiresByteOrder(); - } - -bool ParameterizedType::DoTraverse(DataDepVisitor *visitor) - { - if ( ! Type::DoTraverse(visitor) ) - return false; - - foreach(i, ExprList, args_) - if ( ! (*i)->Traverse(visitor) ) - return false; - - Type *ty = ReferredDataType(false); - if ( ty && ! ty->Traverse(visitor) ) - return false; - - return true; - } - -bool ParameterizedType::RequiresAnalyzerContext() - { - if ( checking_requires_analyzer_context_ ) - return false; - checking_requires_analyzer_context_ = true; - - bool ret = false; - // If any argument expression refers to analyzer context - foreach(i, ExprList, args_) - if ( (*i)->RequiresAnalyzerContext() ) - { - ret = true; - break; - } - ret = ret || - Type::RequiresAnalyzerContext(); - - if ( ! ret ) - { - Type *ty = ReferredDataType(false); - if ( ty ) - ret = ty->RequiresAnalyzerContext(); - } - - checking_requires_analyzer_context_ = false; - return ret; - } - -void ParameterizedType::GenInitCode(Output* out_cc, Env* env) - { - ASSERT(persistent()); - out_cc->println("%s = 0;", env->LValue(value_var())); - Type::GenInitCode(out_cc, env); - } - -void ParameterizedType::GenCleanUpCode(Output* out_cc, Env* env) - { - Type *ty = ReferredDataType(false); - if ( ty && ty->attr_refcount() ) - out_cc->println("Unref(%s);", lvalue()); - else - out_cc->println("delete %s;", lvalue()); - out_cc->println("%s = 0;", lvalue()); - Type::GenCleanUpCode(out_cc, env); - } - -string ParameterizedType::EvalParameters(Output* out_cc, Env *env) const - { - string arg_str; - - int first = 1; - foreach (i, ExprList, args_) - { - Expr* e = *i; - if ( first ) - first = 0; - else - arg_str += ", "; - arg_str += e->EvalExpr(out_cc, env); - } - - return arg_str; - } - -void ParameterizedType::GenNewInstance(Output *out_cc, Env *env) - { - out_cc->println("%s = new %s(%s);", - lvalue(), - type_id_->Name(), - EvalParameters(out_cc, env).c_str()); - } - -void ParameterizedType::DoGenParseCode(Output* out_cc, Env* env, - const DataPtr& data, int flags) - { - DEBUG_MSG("DoGenParseCode for %s\n", type_id_->Name()); - - Type *ref_type = ReferredDataType(true); - - const char *parse_func; - string parse_params; - - if ( buffer_mode() == BUFFER_NOTHING ) - { - ASSERT(!ref_type->incremental_input()); - parse_func = kParseFuncWithoutBuffer; - parse_params = "0, 0"; - } - else if ( ref_type->incremental_input() ) - { - parse_func = kParseFuncWithBuffer; - parse_params = env->RValue(flow_buffer_id); - } - else - { - parse_func = kParseFuncWithoutBuffer; - parse_params = strfmt("%s, %s", - data.ptr_expr(), - env->RValue(end_of_data)); - } - - if ( RequiresAnalyzerContext::compute(ref_type) ) - { - parse_params += strfmt(", %s", env->RValue(analyzer_context_id)); - } - - if ( ref_type->RequiresByteOrder() ) - { - env->Evaluate(out_cc, byteorder_id); - parse_params += strfmt(", %s", env->RValue(byteorder_id)); - } - - string call_parse_func = strfmt("%s->%s(%s)", - lvalue(), // parse() needs an LValue - parse_func, - parse_params.c_str()); - - if ( incremental_input() ) - { - if ( buffer_mode() == BUFFER_NOTHING ) - { - out_cc->println("%s;", call_parse_func.c_str()); - out_cc->println("%s = true;", - env->LValue(parsing_complete_var())); - } - else - { - ASSERT(parsing_complete_var()); - out_cc->println("%s = %s;", - env->LValue(parsing_complete_var()), - call_parse_func.c_str()); - - // parsing_complete_var might have been already - // evaluated when set to false - if ( ! env->Evaluated(parsing_complete_var()) ) - env->SetEvaluated(parsing_complete_var()); - } - } - else - { - if ( AddSizeVar(out_cc, env) ) - { - out_cc->println("%s = %s;", - env->LValue(size_var()), - call_parse_func.c_str()); - env->SetEvaluated(size_var()); - } - else - { - out_cc->println("%s;", - call_parse_func.c_str()); - } - } - } - -void ParameterizedType::GenDynamicSize(Output* out_cc, Env* env, - const DataPtr& data) - { - GenParseCode(out_cc, env, data, 0); - } - diff --git a/aux/binpac/src/pac_paramtype.h b/aux/binpac/src/pac_paramtype.h deleted file mode 100644 index 4a2ef4e1d7..0000000000 --- a/aux/binpac/src/pac_paramtype.h +++ /dev/null @@ -1,62 +0,0 @@ -#ifndef pac_paramtype_h -#define pac_paramtype_h - -#include "pac_type.h" - -// An instantiated type: ID + expression list -class ParameterizedType : public Type -{ -public: - ParameterizedType(ID *type_id, ExprList *args); - ~ParameterizedType(); - - Type *clone() const; - - string EvalMember(const ID *member_id) const; - // Env *member_env() const; - - void AddParamArg(Expr *arg); - - bool DefineValueVar() const; - string DataTypeStr() const; - string DefaultValue() const { return "0"; } - Type *MemberDataType(const ID *member_id) const; - - // "throw_exception" specifies whether to throw an exception - // if the referred data type is not found - Type *ReferredDataType(bool throw_exception) const; - - void GenCleanUpCode(Output *out, Env *env); - - int StaticSize(Env *env) const; - - bool IsPointerType() const { return true; } - - bool ByteOrderSensitive() const; - bool RequiresAnalyzerContext(); - - void GenInitCode(Output *out_cc, Env *env); - - string class_name() const; - string EvalParameters(Output *out_cc, Env *env) const; - - BufferMode buffer_mode() const; - -protected: - void GenNewInstance(Output *out, Env *env); - - bool DoTraverse(DataDepVisitor *visitor); - Type *DoClone() const; - void DoMarkIncrementalInput(); - -private: - ID *type_id_; - ExprList *args_; - char *data_type_; - bool checking_requires_analyzer_context_; - - void DoGenParseCode(Output *out, Env *env, const DataPtr& data, int flags); - void GenDynamicSize(Output *out, Env *env, const DataPtr& data); -}; - -#endif // pac_paramtype_h diff --git a/aux/binpac/src/pac_parse.yy b/aux/binpac/src/pac_parse.yy deleted file mode 100644 index 3d7f9a328f..0000000000 --- a/aux/binpac/src/pac_parse.yy +++ /dev/null @@ -1,1095 +0,0 @@ -/* $Id: pac_parse.yy 3225 2006-06-08 00:00:01Z vern $ */ - -%token TOK_TYPE TOK_RECORD TOK_CASE TOK_ENUM TOK_LET TOK_FUNCTION -%token TOK_REFINE TOK_CASEFUNC TOK_CASETYPE TOK_TYPEATTR -%token TOK_HELPERHEADER TOK_HELPERCODE -%token TOK_RIGHTARROW TOK_DEFAULT TOK_OF -%token TOK_PADDING TOK_TO TOK_ALIGN -%token TOK_WITHINPUT -%token TOK_INT8 TOK_INT16 TOK_INT32 -%token TOK_UINT8 TOK_UINT16 TOK_UINT32 -%token TOK_ID TOK_NUMBER TOK_REGEX TOK_STRING -%token TOK_BEGIN_RE TOK_END_RE -%token TOK_ATTR_ALSO -%token TOK_ATTR_BYTEORDER TOK_ATTR_CHECK TOK_ATTR_CHUNKED -%token TOK_ATTR_EXPORTSOURCEDATA TOK_ATTR_IF -%token TOK_ATTR_LENGTH TOK_ATTR_LET -%token TOK_ATTR_LINEBREAKER TOK_ATTR_MULTILINE TOK_ATTR_ONELINE -%token TOK_ATTR_REFCOUNT TOK_ATTR_REQUIRES -%token TOK_ATTR_RESTOFDATA TOK_ATTR_RESTOFFLOW -%token TOK_ATTR_TRANSIENT TOK_ATTR_UNTIL -%token TOK_ANALYZER TOK_CONNECTION TOK_FLOW -%token TOK_STATE TOK_ACTION TOK_WHEN TOK_HELPER -%token TOK_DATAUNIT TOK_FLOWDIR TOK_WITHCONTEXT -%token TOK_LPB_EXTERN TOK_LPB_HEADER TOK_LPB_CODE -%token TOK_LPB_MEMBER TOK_LPB_INIT TOK_LPB_CLEANUP TOK_LPB_EOF -%token TOK_LPB TOK_RPB -%token TOK_EMBEDDED_ATOM TOK_EMBEDDED_STRING -%token TOK_PAC_VAL TOK_PAC_SET TOK_PAC_TYPE TOK_PAC_TYPEOF TOK_PAC_CONST_DEF -%token TOK_END_PAC -%token TOK_EXTERN - -%nonassoc '=' TOK_PLUSEQ -%left ';' -%left ',' -%left '?' ':' -%left TOK_OR -%left TOK_AND -%nonassoc TOK_EQUAL TOK_NEQ TOK_LE TOK_GE '<' '>' -%left '&' '|' '^' -%left TOK_LSHIFT TOK_RSHIFT -%left '+' '-' -%left '*' '/' '%' -%right '~' '!' -%right TOK_SIZEOF TOK_OFFSETOF -%right '(' ')' '[' ']' -%left '.' - -%type actionparam -%type actionparamtype -%type sah -%type sahlist conn flow -%type attr -%type optattrs attrlist -%type caseexpr -%type caseexprlist -%type casefield casefield0 -%type casefieldlist -%type contextfield -%type analyzercontext contextfieldlist -%type decl decl_with_attr decl_without_attr -%type embedded_code -%type enumlist enumlist1 -%type enumitem -%type expr caseindex optinit optlinebreaker -%type exprlist optexprlist optargs -%type withinputfield letfield -%type letfieldlist -%type funcproto function -%type TOK_ID tok_id optfieldid -%type input -%type TOK_NUMBER -%type embedded_pac_primitive -%type param -%type optparams paramlist -%type recordfield recordfield0 padding -%type recordfieldlist -%type regex -%type statevar -%type statevarlist -%type TOK_EMBEDDED_STRING TOK_STRING TOK_REGEX -%type cstr -%type type type3 type2 type1 opttype -%type TOK_EMBEDDED_ATOM TOK_WHEN TOK_FLOWDIR TOK_DATAUNIT - -%{ - -#include "pac_action.h" -#include "pac_analyzer.h" -#include "pac_array.h" -#include "pac_attr.h" -#include "pac_case.h" -#include "pac_common.h" -#include "pac_conn.h" -#include "pac_context.h" -#include "pac_cstr.h" -#include "pac_dataptr.h" -#include "pac_dataunit.h" -#include "pac_dbg.h" -#include "pac_decl.h" -#include "pac_embedded.h" -#include "pac_enum.h" -#include "pac_exception.h" -#include "pac_expr.h" -#include "pac_exttype.h" -#include "pac_flow.h" -#include "pac_func.h" -#include "pac_id.h" -#include "pac_inputbuf.h" -#include "pac_let.h" -#include "pac_output.h" -#include "pac_param.h" -#include "pac_paramtype.h" -#include "pac_primitive.h" -#include "pac_record.h" -#include "pac_redef.h" -#include "pac_regex.h" -#include "pac_state.h" -#include "pac_strtype.h" -#include "pac_type.h" -#include "pac_utils.h" -#include "pac_withinput.h" - -extern int yyerror(const char msg[]); -extern int yylex(); -extern int yychar; -extern char* yytext; -extern int yyleng; -extern void begin_RE(); -extern void end_RE(); - -extern string input_filename; -extern int line_number; -extern Output* header_output; -extern Output* source_output; - -%} - -%union { - ActionParam *actionparam; - ActionParamType *actionparamtype; - AnalyzerElement *aelem; - AnalyzerElementList *aelemlist; - Attr *attr; - AttrList *attrlist; - ConstString *cstr; - CaseExpr *caseexpr; - CaseExprList *caseexprlist; - CaseField *casefield; - CaseFieldList *casefieldlist; - ContextField *contextfield; - ContextFieldList *contextfieldlist; - Decl *decl; - EmbeddedCode *embedded_code; - Enum *enumitem; - EnumList *enumlist; - Expr *expr; - ExprList *exprlist; - Field *field; - FieldList *fieldlist; - Function *function; - ID *id; - InputBuffer *input; - LetFieldList *letfieldlist; - LetField *letfield; - Number *num; - PacPrimitive *pacprimitive; - Param *param; - ParamList *paramlist; - RecordFieldList *recordfieldlist; - RecordField *recordfield; - RegEx *regex; - StateVar *statevar; - StateVarList *statevarlist; - const char *str; - Type *type; - int val; -} - -%% - -decls : /* empty */ - { - // Put initialization here - } - | decls decl optsemicolon - { - } - ; - -decl : decl_with_attr optattrs - { - $$ = $1; - $1->AddAttrs($2); - } - | decl_without_attr - { - $$ = $1; - } - ; - -decl_with_attr : TOK_TYPE tok_id { current_decl_id = $2; } optparams '=' type - { - TypeDecl* decl = new TypeDecl($2, $4, $6); - $$ = decl; - } - | TOK_LET tok_id { current_decl_id = $2; } opttype optinit - { - $$ = new LetDecl($2, $4, $5); - } - | TOK_FUNCTION function - { - current_decl_id = $2->id(); - $$ = new FuncDecl($2); - } - | TOK_ENUM tok_id { current_decl_id = $2; } '{' enumlist '}' - { - $$ = new EnumDecl($2, $5); - } - | TOK_EXTERN TOK_TYPE tok_id { current_decl_id = $3; } - { - Type *extern_type = new ExternType($3, ExternType::PLAIN); - $$ = new TypeDecl($3, 0, extern_type); - } - | TOK_ANALYZER tok_id { current_decl_id = $2; } TOK_WITHCONTEXT analyzercontext - { - $$ = new AnalyzerContextDecl($2, $5); - } - | TOK_ANALYZER tok_id { current_decl_id = $2; } optparams '{' conn '}' - { - $$ = new ConnDecl($2, $4, $6); - } - | TOK_CONNECTION tok_id { current_decl_id = $2; } optparams '{' conn '}' - { - $$ = new ConnDecl($2, $4, $6); - } - | TOK_FLOW tok_id { current_decl_id = $2; } optparams '{' flow '}' - { - $$ = new FlowDecl($2, $4, $6); - } - | TOK_REFINE TOK_CASETYPE tok_id TOK_PLUSEQ '{' casefieldlist '}' - { - $$ = ProcessCaseTypeRedef($3, $6); - } - | TOK_REFINE TOK_CASEFUNC tok_id TOK_PLUSEQ '{' caseexprlist '}' - { - $$ = ProcessCaseExprRedef($3, $6); - } - | TOK_REFINE TOK_ANALYZER tok_id TOK_PLUSEQ '{' sahlist '}' - { - $$ = ProcessAnalyzerRedef($3, Decl::CONN, $6); - } - | TOK_REFINE TOK_CONNECTION tok_id TOK_PLUSEQ '{' sahlist '}' - { - $$ = ProcessAnalyzerRedef($3, Decl::CONN, $6); - } - | TOK_REFINE TOK_FLOW tok_id TOK_PLUSEQ '{' sahlist '}' - { - $$ = ProcessAnalyzerRedef($3, Decl::FLOW, $6); - } - ; - -decl_without_attr: TOK_LPB_HEADER embedded_code TOK_RPB - { - $$ = new HelperDecl(HelperDecl::HEADER, 0, $2); - } - | TOK_LPB_CODE embedded_code TOK_RPB - { - $$ = new HelperDecl(HelperDecl::CODE, 0, $2); - } - | TOK_LPB_EXTERN embedded_code TOK_RPB - { - $$ = new HelperDecl(HelperDecl::EXTERN, 0, $2); - } - | TOK_REFINE TOK_TYPEATTR tok_id TOK_PLUSEQ attrlist - { - $$ = ProcessTypeAttrRedef($3, $5); - } - ; - -optsemicolon : /* nothing */ - | ';' - ; - -tok_id : TOK_ID - { - $$ = $1; - } - | TOK_CONNECTION - { - $$ = new ID("connection"); - } - | TOK_ANALYZER - { - $$ = new ID("analyzer"); - } - | TOK_FLOW - { - $$ = new ID("flow"); - } - | TOK_FUNCTION - { - $$ = new ID("function"); - } - | TOK_TYPE - { - $$ = new ID("type"); - } - ; - -analyzercontext : '{' contextfieldlist '}' - { - $$ = $2; - } - ; - -contextfieldlist: contextfieldlist contextfield ';' - { - $1->push_back($2); - $$ = $1; - } - | /* nothing */ - { - $$ = new ContextFieldList(); - } - ; - -contextfield : tok_id ':' type1 - { - $$ = new ContextField($1, $3); - } - ; - -funcproto : tok_id '(' paramlist ')' ':' type2 - { - $$ = new Function($1, $6, $3); - } - ; - -function : funcproto '=' expr - { - $1->set_expr($3); - $$ = $1; - } - | funcproto TOK_LPB embedded_code TOK_RPB - { - $1->set_code($3); - $$ = $1; - } - | funcproto ';' - { - $$ = $1; - } - ; - -optparams : '(' paramlist ')' - { - $$ = $2; - } - | /* empty */ - { - $$ = 0; - } - ; - -paramlist : paramlist ',' param - { - $1->push_back($3); - $$ = $1; - } - | param - { - $$ = new ParamList(); - $$->push_back($1); - } - | /* empty */ - { - $$ = new ParamList(); - } - ; - -param : tok_id ':' type2 - { - $$ = new Param($1, $3); - } - ; - -optinit : /* nothing */ - { - $$ = 0; - } - | '=' expr - { - $$ = $2; - } - ; - -opttype : /* nothing */ - { - $$ = 0; - } - | ':' type2 - { - $$ = $2; - } - ; - -type : type3 - { - $$ = $1; - } - ; - -/* type3 is for record or type2 */ -type3 : type2 - { - $$ = $1; - } - | TOK_RECORD '{' recordfieldlist '}' - { - $$ = new RecordType($3); - } - ; - -/* type2 is for array or case or type1 */ -type2 : type1 - { - $$ = $1; - } - | type1 '[' expr ']' - { - $$ = new ArrayType($1, $3); - } - | type1 '[' ']' - { - $$ = new ArrayType($1); - } - | TOK_CASE caseindex TOK_OF '{' casefieldlist '}' - { - $$ = new CaseType($2, $5); - } - ; - -/* type1 is for built-in, parameterized, or string types */ -type1 : tok_id - { - $$ = Type::LookUpByID($1); - } - | tok_id '(' exprlist ')' - { - $$ = new ParameterizedType($1, $3); - } - | regex - { - $$ = new StringType($1); - } - | cstr - { - $$ = new StringType($1); - } - ; - -recordfieldlist : recordfieldlist recordfield ';' - { - $1->push_back($2); - $$ = $1; - } - | /* empty */ - { - $$ = new RecordFieldList(); - } - ; - -recordfield : recordfield0 optattrs - { - $1->AddAttr($2); - $$ = $1; - } - ; - -recordfield0 : optfieldid type2 - { - $$ = new RecordDataField($1, $2); - } - | padding - { - $$ = $1; - } - ; - -padding : optfieldid TOK_PADDING '[' expr ']' - { - $$ = new RecordPaddingField( - $1, PAD_BY_LENGTH, $4); - } - | optfieldid TOK_PADDING TOK_TO expr - { - $$ = new RecordPaddingField( - $1, PAD_TO_OFFSET, $4); - } - | optfieldid TOK_PADDING TOK_ALIGN expr - { - $$ = new RecordPaddingField( - $1, PAD_TO_NEXT_WORD, $4); - } - ; - -optfieldid : tok_id ':' - { - $$ = $1; - } - | ':' - { - $$ = ID::NewAnonymousID("anonymous_field_"); - } - ; - -caseindex : expr - { - $$ = $1; - } - ; - -casefieldlist : casefieldlist casefield ';' - { - $1->push_back($2); - $$ = $1; - } - | /* empty */ - { - $$ = new CaseFieldList(); - } - ; - -casefield : casefield0 optattrs - { - $1->AddAttr($2); - $$ = $1; - } - ; - -casefield0 : exprlist TOK_RIGHTARROW tok_id ':' type2 - { - $$ = new CaseField($1, $3, $5); - } - | TOK_DEFAULT TOK_RIGHTARROW tok_id ':' type2 - { - $$ = new CaseField(0, $3, $5); - } - ; - -optexprlist : /* nothing */ - { - $$ = 0; - } - | exprlist - { - $$ = $1; - } - ; - -exprlist : exprlist ',' expr - { - $1->push_back($3); - $$ = $1; - } - | expr - { - $$ = new ExprList(); - $$->push_back($1); - } - ; - -expr : tok_id - { - $$ = new Expr($1); - } - | TOK_NUMBER - { - $$ = new Expr($1); - } - | expr '[' expr ']' - { - $$ = new Expr(Expr::EXPR_SUBSCRIPT, $1, $3); - } - | expr '.' tok_id - { - $$ = new Expr(Expr::EXPR_MEMBER, $1, new Expr($3)); - } - | TOK_SIZEOF '(' tok_id ')' - { - $$ = new Expr(Expr::EXPR_SIZEOF, new Expr($3)); - } - | TOK_OFFSETOF '(' tok_id ')' - { - $$ = new Expr(Expr::EXPR_OFFSETOF, new Expr($3)); - } - | '(' expr ')' - { - $$ = new Expr(Expr::EXPR_PAREN, $2); - } - | expr '(' optexprlist ')' - { - $$ = new Expr(Expr::EXPR_CALL, - $1, - new Expr($3)); - } - | '-' expr - { - $$ = new Expr(Expr::EXPR_NEG, $2); - } - | expr '+' expr - { - $$ = new Expr(Expr::EXPR_PLUS, $1, $3); - } - | expr '-' expr - { - $$ = new Expr(Expr::EXPR_MINUS, $1, $3); - } - | expr '*' expr - { - $$ = new Expr(Expr::EXPR_TIMES, $1, $3); - } - | expr '/' expr - { - $$ = new Expr(Expr::EXPR_DIV, $1, $3); - } - | expr '%' expr - { - $$ = new Expr(Expr::EXPR_MOD, $1, $3); - } - | '~' expr - { - $$ = new Expr(Expr::EXPR_BITNOT, $2); - } - | expr '&' expr - { - $$ = new Expr(Expr::EXPR_BITAND, $1, $3); - } - | expr '|' expr - { - $$ = new Expr(Expr::EXPR_BITOR, $1, $3); - } - | expr '^' expr - { - $$ = new Expr(Expr::EXPR_BITXOR, $1, $3); - } - | expr TOK_LSHIFT expr - { - $$ = new Expr(Expr::EXPR_LSHIFT, $1, $3); - } - | expr TOK_RSHIFT expr - { - $$ = new Expr(Expr::EXPR_RSHIFT, $1, $3); - } - | expr TOK_EQUAL expr - { - $$ = new Expr(Expr::EXPR_EQUAL, $1, $3); - } - | expr TOK_NEQ expr - { - $$ = new Expr(Expr::EXPR_NEQ, $1, $3); - } - | expr TOK_GE expr - { - $$ = new Expr(Expr::EXPR_GE, $1, $3); - } - | expr TOK_LE expr - { - $$ = new Expr(Expr::EXPR_LE, $1, $3); - } - | expr '>' expr - { - $$ = new Expr(Expr::EXPR_GT, $1, $3); - } - | expr '<' expr - { - $$ = new Expr(Expr::EXPR_LT, $1, $3); - } - | '!' expr - { - $$ = new Expr(Expr::EXPR_NOT, $2); - } - | expr TOK_AND expr - { - $$ = new Expr(Expr::EXPR_AND, $1, $3); - } - | expr TOK_OR expr - { - $$ = new Expr(Expr::EXPR_OR, $1, $3); - } - | expr '?' expr ':' expr - { - $$ = new Expr(Expr::EXPR_COND, $1, $3, $5); - } - | TOK_CASE expr TOK_OF '{' caseexprlist '}' - { - $$ = new Expr($2, $5); - } - | cstr - { - $$ = new Expr($1); - } - | regex - { - $$ = new Expr($1); - } - ; - -cstr : TOK_STRING - { - $$ = new ConstString($1); - } - ; - -regex : TOK_BEGIN_RE TOK_REGEX TOK_END_RE - { - $$ = new RegEx($2); - } - ; - -caseexprlist : /* nothing */ - { - $$ = new CaseExprList(); - } - | caseexprlist caseexpr ';' - { - $1->push_back($2); - $$ = $1; - } - ; - -caseexpr : exprlist TOK_RIGHTARROW expr - { - $$ = new CaseExpr($1, $3); - } - | TOK_DEFAULT TOK_RIGHTARROW expr - { - $$ = new CaseExpr(0, $3); - } - ; - -enumlist : enumlist1 - { - $$ = $1; - } - | enumlist1 ',' - { - $$ = $1; - } - ; - -enumlist1 : enumlist1 ',' enumitem - { - $1->push_back($3); - $$ = $1; - } - | enumitem - { - $$ = new EnumList(); - $$->push_back($1); - } - ; - -enumitem : tok_id - { - $$ = new Enum($1); - } - | tok_id '=' expr - { - $$ = new Enum($1, $3); - } - ; - -conn : sahlist - { - $$ = $1; - } - ; - -flow : sahlist - { - $$ = $1; - } - ; - -/* State-Action-Helper List */ -sahlist : /* empty */ - { - $$ = new AnalyzerElementList(); - } - | sahlist sah - { - $1->push_back($2); - $$ = $1; - } - ; - -sah : TOK_LPB_MEMBER embedded_code TOK_RPB - { - $$ = new AnalyzerHelper(AnalyzerHelper::MEMBER_DECLS, $2); - } - | TOK_LPB_INIT embedded_code TOK_RPB - { - $$ = new AnalyzerHelper(AnalyzerHelper::INIT_CODE, $2); - } - | TOK_LPB_CLEANUP embedded_code TOK_RPB - { - $$ = new AnalyzerHelper(AnalyzerHelper::CLEANUP_CODE, $2); - } - | TOK_LPB_EOF embedded_code TOK_RPB - { - $$ = new AnalyzerHelper(AnalyzerHelper::EOF_CODE, $2); - } - | TOK_FLOWDIR '=' tok_id optargs ';' - { - $$ = new AnalyzerFlow((AnalyzerFlow::Direction) $1, $3, $4); - } - | TOK_DATAUNIT '=' tok_id optargs TOK_WITHCONTEXT '(' optexprlist ')' ';' - { - $$ = new AnalyzerDataUnit( - (AnalyzerDataUnit::DataUnitType) $1, - $3, - $4, - $7); - } - | TOK_FUNCTION function - { - $$ = new AnalyzerFunction($2); - } - | TOK_STATE '{' statevarlist '}' - { - $$ = new AnalyzerState($3); - } - | TOK_ACTION tok_id TOK_WHEN '(' actionparam ')' TOK_LPB embedded_code TOK_RPB - { - $$ = new AnalyzerAction($2, (AnalyzerAction::When) $3, $5, $8); - } - ; - -statevarlist : /* empty */ - { - $$ = new StateVarList(); - } - | statevarlist statevar ';' - { - $1->push_back($2); - $$ = $1; - } - ; - -statevar : tok_id ':' type1 - { - $$ = new StateVar($1, $3); - } - ; - -actionparam : tok_id TOK_LE actionparamtype - { - $$ = new ActionParam($1, $3); - } - ; - -actionparamtype : tok_id - { - $$ = new ActionParamType($1); - } - | tok_id '.' tok_id - { - $$ = new ActionParamType($1, $3); - } - ; - -embedded_code : /* empty */ - { - $$ = new EmbeddedCode(); - } - | embedded_code TOK_EMBEDDED_ATOM - { - $1->Append($2); - $$ = $1; - } - | embedded_code TOK_EMBEDDED_STRING - { - $1->Append($2); - $$ = $1; - } - | embedded_code embedded_pac_primitive - { - $1->Append($2); - $$ = $1; - } - ; - -embedded_pac_primitive: TOK_PAC_VAL expr TOK_END_PAC - { - $$ = new PPVal($2); - } - | TOK_PAC_SET expr TOK_END_PAC - { - $$ = new PPSet($2); - } - | TOK_PAC_TYPE expr TOK_END_PAC - { - $$ = new PPType($2); - } - | TOK_PAC_CONST_DEF tok_id '=' expr TOK_END_PAC - { - $$ = new PPConstDef($2, $4); - } - ; - -optargs : /* empty */ - { - $$ = 0; - } - | '(' optexprlist ')' - { - $$ = $2; - } - ; - -letfieldlist : letfieldlist letfield ';' - { - $1->push_back($2); - $$ = $1; - } - | letfieldlist withinputfield ';' - { - $1->push_back($2); - $$ = $1; - } - | /* empty */ - { - $$ = new FieldList(); - } - ; - -letfield : tok_id opttype optinit optattrs - { - $$ = new LetField($1, $2, $3); - $$->AddAttr($4); - } - ; - -withinputfield : tok_id ':' type1 TOK_WITHINPUT input optattrs - { - $$ = new WithInputField($1, $3, $5); - $$->AddAttr($6); - } - ; - -/* There can be other forms of input */ -input : expr - { - $$ = new InputBuffer($1); - } - ; - -optattrs : /* empty */ - { - $$ = 0; - } - | attrlist - { - $$ = $1; - } - ; - -attrlist : attrlist optcomma attr - { - if ( $3 ) - $1->push_back($3); - $$ = $1; - } - | attr - { - $$ = new AttrList(); - if ( $1 ) - $$->push_back($1); - } - ; - -optcomma : /* nothing */ - | ',' - ; - -attr : TOK_ATTR_BYTEORDER '=' expr - { - $$ = new Attr(ATTR_BYTEORDER, $3); - } - | TOK_ATTR_CHECK expr - { - $$ = new Attr(ATTR_CHECK, $2); - } - | TOK_ATTR_CHUNKED - { - $$ = new Attr(ATTR_CHUNKED); - } - | TOK_ATTR_EXPORTSOURCEDATA - { - $$ = new Attr(ATTR_EXPORTSOURCEDATA); - } - | TOK_ATTR_IF expr - { - $$ = new Attr(ATTR_IF, $2); - } - | TOK_ATTR_LENGTH '=' expr - { - $$ = new Attr(ATTR_LENGTH, $3); - } - | TOK_ATTR_LET '{' letfieldlist '}' - { - $$ = new LetAttr($3); - } - | TOK_ATTR_LINEBREAKER '=' expr - { - $$ = new Attr(ATTR_LINEBREAKER, $3); - } - | TOK_ATTR_MULTILINE '(' expr ')' - { - $$ = new Attr(ATTR_MULTILINE, $3); - } - | TOK_ATTR_ONELINE optlinebreaker - { - $$ = new Attr(ATTR_ONELINE, $2); - } - | TOK_ATTR_REFCOUNT - { - $$ = new Attr(ATTR_REFCOUNT); - } - | TOK_ATTR_REQUIRES '(' optexprlist ')' - { - $$ = new Attr(ATTR_REQUIRES, $3); - } - | TOK_ATTR_RESTOFDATA - { - $$ = new Attr(ATTR_RESTOFDATA); - } - | TOK_ATTR_RESTOFFLOW - { - $$ = new Attr(ATTR_RESTOFFLOW); - } - | TOK_ATTR_TRANSIENT - { - $$ = new Attr(ATTR_TRANSIENT); - } - | TOK_ATTR_UNTIL expr - { - $$ = new Attr(ATTR_UNTIL, $2); - } - ; - -optlinebreaker : /* nothing */ - { - $$ = 0; - } - | '(' expr ')' - { - $$ = $2; - } - ; - -%% - -const ID* current_decl_id = 0; - -int yyerror(const char msg[]) - { - char* msgbuf = - new char[strlen(msg) + yyleng + 64]; - - if ( ! yychar || ! yytext || yytext[0] == '\0' ) - sprintf(msgbuf, "%s, at end of file", msg); - - else if ( yytext[0] == '\n' ) - sprintf(msgbuf, "%s, on previous line", msg); - - else - sprintf(msgbuf, "%s, at or near \"%s\"", msg, yytext); - - /* - extern int column; - sprintf(msgbuf, "%*s\n%*s\n", column, "^", column, msg); - */ - - if ( ! input_filename.empty() ) - fprintf(stderr, "%s:%d: ", input_filename.c_str(), line_number); - else - fprintf(stderr, "line %d: ", line_number); - fprintf(stderr, "%s", msgbuf); - fprintf(stderr, " (yychar=%d)", yychar); - fprintf(stderr, "\n"); - - return 0; - } diff --git a/aux/binpac/src/pac_primitive.cc b/aux/binpac/src/pac_primitive.cc deleted file mode 100644 index c4893a63ed..0000000000 --- a/aux/binpac/src/pac_primitive.cc +++ /dev/null @@ -1,39 +0,0 @@ -#include "pac_dbg.h" -#include "pac_expr.h" -#include "pac_id.h" -#include "pac_primitive.h" -#include "pac_type.h" - -string PPVal::ToCode(Env *env) - { - ASSERT(expr_); - return string(expr_->EvalExpr(0, env)); - } - -string PPSet::ToCode(Env *env) - { - ASSERT(expr_); - return expr_->SetFunc(0, env); - } - -string PPType::ToCode(Env *env) - { - Type *type = expr_->DataType(env); - if ( ! type ) - { - } - return type->DataTypeStr(); - } - -string PPConstDef::ToCode(Env *env) - { - Type *type = expr_->DataType(env); - env->AddID(id_, TEMP_VAR, type); - env->SetEvaluated(id_); - - string type_str = type->DataTypeStr(); - return strfmt("%s %s = %s", - type_str.c_str(), - env->LValue(id_), - expr_->EvalExpr(0, env)); - } diff --git a/aux/binpac/src/pac_primitive.h b/aux/binpac/src/pac_primitive.h deleted file mode 100644 index 47d06a1e72..0000000000 --- a/aux/binpac/src/pac_primitive.h +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef pac_primitive_h -#define pac_primitive_h - -#include "pac_common.h" - -class PacPrimitive -{ -public: - enum PrimitiveType { VAL, SET, TYPE, CONST_DEF }; - - explicit PacPrimitive(PrimitiveType type) : type_(type) {} - virtual ~PacPrimitive() {} - - PrimitiveType type() const { return type(); } - - virtual string ToCode(Env *env) = 0; - -private: - PrimitiveType type_; -}; - -class PPVal : public PacPrimitive -{ -public: - PPVal(Expr *expr) : PacPrimitive(VAL), expr_(expr) {} - Expr *expr() const { return expr_; } - - string ToCode(Env *env); - -private: - Expr *expr_; -}; - -class PPSet : public PacPrimitive -{ -public: - PPSet(Expr *expr) : PacPrimitive(SET), expr_(expr) {} - Expr *expr() const { return expr_; } - - string ToCode(Env *env); - -private: - Expr *expr_; -}; - -class PPType : public PacPrimitive -{ -public: - PPType(Expr *expr) : PacPrimitive(TYPE), expr_(expr) {} - Expr *expr() const { return expr_; } - - string ToCode(Env *env); - -private: - Expr *expr_; -}; - -class PPConstDef : public PacPrimitive -{ -public: - PPConstDef(const ID *id, Expr *expr) - : PacPrimitive(CONST_DEF), - id_(id), - expr_(expr) {} - const ID *id() const { return id_; } - Expr *expr() const { return expr_; } - - string ToCode(Env *env); - -private: - const ID *id_; - Expr *expr_; -}; - -#endif // pac_primitive_h diff --git a/aux/binpac/src/pac_record.cc b/aux/binpac/src/pac_record.cc deleted file mode 100644 index 9875195033..0000000000 --- a/aux/binpac/src/pac_record.cc +++ /dev/null @@ -1,680 +0,0 @@ -#include "pac_attr.h" -#include "pac_dataptr.h" -#include "pac_exception.h" -#include "pac_expr.h" -#include "pac_exttype.h" -#include "pac_field.h" -#include "pac_output.h" -#include "pac_record.h" -#include "pac_type.h" -#include "pac_typedecl.h" -#include "pac_utils.h" -#include "pac_varfield.h" - - -RecordType::RecordType(RecordFieldList* record_fields) - : Type(RECORD) - { - // Here we assume that the type is a standalone type. - value_var_ = 0; - - // Put all fields in fields_ - foreach (i, RecordFieldList, record_fields) - AddField(*i); - - // Put RecordField's in record_fields_ - record_fields_ = record_fields; - - parsing_dataptr_var_field_ = 0; - } - -RecordType::~RecordType() - { - // Do not delete_list(RecordFieldList, record_fields_) - // because the fields are also in fields_. - delete record_fields_; - delete parsing_dataptr_var_field_; - } - -const ID *RecordType::parsing_dataptr_var() const - { - return parsing_dataptr_var_field_ ? - parsing_dataptr_var_field_->id() : 0; - } - -bool RecordType::DefineValueVar() const - { - return false; - } - -string RecordType::DataTypeStr() const - { - ASSERT(type_decl()); - return strfmt("%s *", type_decl()->class_name().c_str()); - } - -void RecordType::Prepare(Env* env, int flags) - { - ASSERT(flags & TO_BE_PARSED); - - RecordField *prev = 0; - int offset = 0; - int seq = 0; - foreach (i, RecordFieldList, record_fields_) - { - RecordField *f = *i; - f->set_record_type(this); - f->set_prev(prev); - if ( prev ) - prev->set_next(f); - prev = f; - if ( offset >= 0 ) - { - f->set_static_offset(offset); - int w = f->StaticSize(env, offset); - if ( w < 0 ) - offset = -1; - else - offset += w; - } - ++seq; - f->set_parsing_state_seq(seq); - } - - if ( incremental_parsing() ) - { -#if 0 - ASSERT(! parsing_state_var_field_); - ID *parsing_state_var_id = new ID("parsing_state"); - parsing_state_var_field_ = new PrivVarField( - parsing_state_var_id, extern_type_int->Clone()); - AddField(parsing_state_var_field_); - - ID *parsing_dataptr_var_id = new ID("parsing_dataptr"); - parsing_dataptr_var_field_ = new TempVarField( - parsing_dataptr_var_id, extern_type_const_byteptr->Clone()); - parsing_dataptr_var_field_->Prepare(env); -#endif - } - - Type::Prepare(env, flags); - } - -void RecordType::GenPubDecls(Output* out_h, Env* env) - { - Type::GenPubDecls(out_h, env); - } - -void RecordType::GenPrivDecls(Output* out_h, Env* env) - { - Type::GenPrivDecls(out_h, env); - } - -void RecordType::GenInitCode(Output* out_cc, Env* env) - { - Type::GenInitCode(out_cc, env); - } - -void RecordType::GenCleanUpCode(Output* out_cc, Env* env) - { - Type::GenCleanUpCode(out_cc, env); - } - -void RecordType::DoGenParseCode(Output* out_cc, Env* env, - const DataPtr& data, int flags) - { - if ( !incremental_input() && StaticSize(env) >= 0 ) - GenBoundaryCheck(out_cc, env, data); - - if ( incremental_parsing() ) - { - out_cc->println("switch ( %s ) {", - env->LValue(parsing_state_id)); - - out_cc->println("case 0:"); - out_cc->inc_indent(); - foreach (i, RecordFieldList, record_fields_) - { - RecordField *f = *i; - f->GenParseCode(out_cc, env); - out_cc->println(""); - } - out_cc->println(""); - out_cc->println("%s = true;", - env->LValue(parsing_complete_var())); - out_cc->dec_indent(); - out_cc->println("}"); - } - else - { - ASSERT( data.id() == begin_of_data && - data.offset() == 0 ); - foreach (i, RecordFieldList, record_fields_) - { - RecordField *f = *i; - f->GenParseCode(out_cc, env); - out_cc->println(""); - } - if ( incremental_input() ) - { - ASSERT(parsing_complete_var()); - out_cc->println("%s = true;", - env->LValue(parsing_complete_var())); - } - } - - if ( ! incremental_input() && AddSizeVar(out_cc, env) ) - { - const DataPtr& end_of_record_dataptr = - record_fields_->back()->getFieldEnd(out_cc, env); - - out_cc->println("%s = %s - %s;", - env->LValue(size_var()), - end_of_record_dataptr.ptr_expr(), - env->RValue(begin_of_data)); - env->SetEvaluated(size_var()); - } - - if ( ! boundary_checked() ) - { - RecordField *last_field = record_fields_->back(); - if ( ! last_field->BoundaryChecked() ) - GenBoundaryCheck(out_cc, env, data); - } - } - -void RecordType::GenDynamicSize(Output* out_cc, Env* env, - const DataPtr& data) - { - GenParseCode(out_cc, env, data, 0); - } - -int RecordType::StaticSize(Env* env) const - { - int tot_w = 0; - foreach (i, RecordFieldList, record_fields_) - { - RecordField *f = *i; - int w = f->StaticSize(env, tot_w); - if ( w < 0 ) - return -1; - tot_w += w; - } - return tot_w; - } - -void RecordType::SetBoundaryChecked() - { - Type::SetBoundaryChecked(); - foreach (i, RecordFieldList, record_fields_) - { - RecordField *f = *i; - f->SetBoundaryChecked(); - } - } - -void RecordType::DoMarkIncrementalInput() - { - foreach (i, RecordFieldList, record_fields_) - { - RecordField *f = *i; - f->type()->MarkIncrementalInput(); - } - } - -bool RecordType::DoTraverse(DataDepVisitor *visitor) - { - return Type::DoTraverse(visitor); - } - -bool RecordType::ByteOrderSensitive() const - { - foreach (i, RecordFieldList, record_fields_) - { - RecordField *f = *i; - if ( f->RequiresByteOrder() ) - return true; - } - return false; - } - -RecordField::RecordField(FieldType tof, ID *id, Type *type) - : Field(tof, - TYPE_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, - id, type) - { - begin_of_field_dataptr = 0; - end_of_field_dataptr = 0; - field_size_expr = 0; - field_offset_expr = 0; - end_of_field_dataptr_var = 0; - record_type_ = 0; - prev_ = 0; - next_ = 0; - static_offset_ = -1; - boundary_checked_ = false; - } - -RecordField::~RecordField() - { - delete begin_of_field_dataptr; - delete end_of_field_dataptr; - delete [] field_size_expr; - delete [] field_offset_expr; - delete end_of_field_dataptr_var; - } - -const DataPtr& RecordField::getFieldBegin(Output* out_cc, Env* env) - { - if ( prev() ) - return prev()->getFieldEnd(out_cc, env); - else - { - // The first field - if ( ! begin_of_field_dataptr ) - { - begin_of_field_dataptr = - new DataPtr(env, begin_of_data, 0); - } - return *begin_of_field_dataptr; - } - } - -const DataPtr& RecordField::getFieldEnd(Output* out_cc, Env* env) - { - if ( end_of_field_dataptr ) - return *end_of_field_dataptr; - - const DataPtr& begin_ptr = getFieldBegin(out_cc, env); - - if ( record_type()->incremental_parsing() ) - { - ASSERT(0); - if ( ! end_of_field_dataptr ) - { - const ID *dataptr_var = - record_type()->parsing_dataptr_var(); - ASSERT(dataptr_var); - - end_of_field_dataptr = - new DataPtr(env, dataptr_var, 0); - } - } - else - { - int field_offset; - if ( begin_ptr.id() == begin_of_data ) - field_offset = begin_ptr.offset(); - else - field_offset = -1; // unknown - - int field_size = StaticSize(env, field_offset); - if ( field_size >= 0 ) // can be statically determinted - { - end_of_field_dataptr = new DataPtr( - env, - begin_ptr.id(), - begin_ptr.offset() + field_size); - } - else - { - // If not, we add a variable for the offset after the field - end_of_field_dataptr_var = new ID( - fmt("dataptr_after_%s", id()->Name())); - env->AddID(end_of_field_dataptr_var, - TEMP_VAR, - extern_type_const_byteptr); - - GenFieldEnd(out_cc, env, begin_ptr); - - end_of_field_dataptr = new DataPtr( - env, - end_of_field_dataptr_var, - 0); - } - } - - return *end_of_field_dataptr; - } - -const char* RecordField::FieldSize(Output* out_cc, Env* env) - { - if ( field_size_expr ) - return field_size_expr; - - const DataPtr& begin = getFieldBegin(out_cc, env); - const DataPtr& end = getFieldEnd(out_cc, env); - if ( begin.id() == end.id() ) - field_size_expr = nfmt("%d", end.offset() - begin.offset()); - else - field_size_expr = nfmt("(%s - %s)", end.ptr_expr(), begin.ptr_expr()); - return field_size_expr; - } - -const char* RecordField::FieldOffset(Output* out_cc, Env* env) - { - if ( field_offset_expr ) - return field_offset_expr; - - const DataPtr& begin = getFieldBegin(out_cc, env); - if ( begin.id() == begin_of_data ) - field_offset_expr = nfmt("%d", begin.offset()); - else - field_offset_expr = nfmt("(%s - %s)", - begin.ptr_expr(), env->RValue(begin_of_data)); - return field_offset_expr; - } - -// The reasoning behind AttemptBoundaryCheck is: "If my next field -// can check its boundary, then I don't have to check mine, and it -// will save me a boundary-check." -bool RecordField::AttemptBoundaryCheck(Output* out_cc, Env* env) - { - if ( boundary_checked_ ) - return true; - - // If I do not even know my size till I parse the data, my - // next field won't be able to check its boundary now. - - const DataPtr& begin = getFieldBegin(out_cc, env); - if ( StaticSize(env, begin.AbsOffset(begin_of_data)) < 0 ) - return false; - - // Now we ask the next field to check its boundary. - if ( next() && next()->AttemptBoundaryCheck(out_cc, env) ) - { - // If it works, we are all set - SetBoundaryChecked(); - return true; - } - else - // If it fails, then I can still try to do it by myself - return GenBoundaryCheck(out_cc, env); - } - -RecordDataField::RecordDataField(ID* id, Type* type) - : RecordField(RECORD_FIELD, id, type) - { - ASSERT(type_); - } - -RecordDataField::~RecordDataField() - { - } - -void RecordDataField::Prepare(Env* env) - { - Field::Prepare(env); - env->SetEvalMethod(id_, this); - env->SetField(id_, this); - } - -void RecordDataField::GenParseCode(Output* out_cc, Env* env) - { - if ( env->Evaluated(id()) ) - return; - - // Always evaluate record fields in order if parsing - // is incremental. - if ( record_type()->incremental_parsing() && prev() ) - prev()->GenParseCode(out_cc, env); - - DataPtr data(env, 0, 0); - if ( ! record_type()->incremental_parsing() ) - { - data = getFieldBegin(out_cc, env); - AttemptBoundaryCheck(out_cc, env); - } - - out_cc->println("// Parse \"%s\"", id_->Name()); -#if 0 - out_cc->println("DEBUG_MSG(\"%%.6f Parse %s\\n\", network_time());", - id_->Name()); -#endif - type_->GenPreParsing(out_cc, env); - if ( type_->incremental_input() ) - { - // The enclosing record type must be incrementally parsed - out_cc->println("%s = %d;", - env->LValue(parsing_state_id), - parsing_state_seq()); - out_cc->dec_indent(); - out_cc->println("case %d:", parsing_state_seq()); - out_cc->inc_indent(); - out_cc->println("{"); - } - - type_->GenParseCode(out_cc, env, data, 0); - - if ( record_type()->incremental_parsing() ) - { - ASSERT(type_->incremental_input()); - - out_cc->println("if ( ! (%s) )", - type_->parsing_complete(env).c_str()); - out_cc->inc_indent(); - out_cc->println("goto %s;", kNeedMoreData); - out_cc->dec_indent(); - } - - if ( record_type()->incremental_parsing() ) - { -#if 0 - const ID *dataptr_var = - record_type()->parsing_dataptr_var(); - ASSERT(dataptr_var); - out_cc->println("%s += (%s);", - env->LValue(dataptr_var), - type_->DataSize(out_cc, env, data).c_str()); -#endif - out_cc->println("}"); - } - - SetBoundaryChecked(); - } - -void RecordDataField::GenEval(Output* out_cc, Env* env) - { - GenParseCode(out_cc, env); - } - -void RecordDataField::GenFieldEnd(Output* out_cc, Env* env, - const DataPtr& field_begin) - { - out_cc->println("const_byteptr const %s = %s + (%s);", - env->LValue(end_of_field_dataptr_var), - field_begin.ptr_expr(), - type_->DataSize(out_cc, env, field_begin).c_str()); - env->SetEvaluated(end_of_field_dataptr_var); - - out_cc->println("BINPAC_ASSERT(%s <= %s);", - env->RValue(end_of_field_dataptr_var), - env->RValue(end_of_data)); - } - -void RecordDataField::SetBoundaryChecked() - { - RecordField::SetBoundaryChecked(); - type_->SetBoundaryChecked(); - } - -bool RecordDataField::GenBoundaryCheck(Output* out_cc, Env* env) - { - if ( boundary_checked_ ) - return true; - - type_->GenBoundaryCheck(out_cc, env, getFieldBegin(out_cc, env)); - - SetBoundaryChecked(); - return true; - } - -bool RecordDataField::DoTraverse(DataDepVisitor *visitor) - { - return Field::DoTraverse(visitor); - } - -bool RecordDataField::RequiresAnalyzerContext() const - { - return Field::RequiresAnalyzerContext() || - type()->RequiresAnalyzerContext(); - } - -RecordPaddingField::RecordPaddingField(ID* id, PaddingType ptype, Expr* expr) - : RecordField(PADDING_FIELD, id, 0), ptype_(ptype), expr_(expr) - { - wordsize_ = -1; - } - -RecordPaddingField::~RecordPaddingField() - { - } - -void RecordPaddingField::Prepare(Env* env) - { - Field::Prepare(env); - if ( ptype_ == PAD_TO_NEXT_WORD ) - { - if ( ! expr_->ConstFold(env, &wordsize_) ) - throw ExceptionPaddingError(this, - fmt("padding word size not a constant")); - } - } - -void RecordPaddingField::GenParseCode(Output* out_cc, Env* env) - { - // Always evaluate record fields in order if parsing - // is incremental. - if ( record_type()->incremental_parsing() && prev() ) - prev()->GenParseCode(out_cc, env); - } - -int RecordPaddingField::StaticSize(Env* env, int offset) const - { - int length; - int target_offset; - int offset_in_word; - - switch ( ptype_ ) - { - case PAD_BY_LENGTH: - return expr_->ConstFold(env, &length) ? length : -1; - - case PAD_TO_OFFSET: - // If the current offset cannot be statically - // determined, we need to Generate code to - // check the offset - if ( offset == -1 ) - return -1; - - if ( ! expr_->ConstFold(env, &target_offset) ) - return -1; - - // If both the current and target offsets - // can be statically computed, we can get its - // static size - if ( offset > target_offset ) - throw ExceptionPaddingError( - this, - fmt("current offset = %d, " - "target offset = %d", - offset, target_offset)); - return target_offset - offset; - - case PAD_TO_NEXT_WORD: - if ( offset == -1 || wordsize_ == -1 ) - return -1; - - offset_in_word = offset % wordsize_; - return ( offset_in_word == 0 ) ? - 0 : wordsize_ - offset_in_word; - } - - return -1; - } - -void RecordPaddingField::GenFieldEnd(Output* out_cc, Env* env, const DataPtr& field_begin) - { - ASSERT(! env->Evaluated(end_of_field_dataptr_var)); - - char* padding_var; - switch ( ptype_ ) - { - case PAD_BY_LENGTH: - out_cc->println("const_byteptr const %s = %s + (%s);", - env->LValue(end_of_field_dataptr_var), - field_begin.ptr_expr(), - expr_->EvalExpr(out_cc, env)); - break; - - case PAD_TO_OFFSET: - out_cc->println("const_byteptr %s = %s + (%s);", - env->LValue(end_of_field_dataptr_var), - env->RValue(begin_of_data), - expr_->EvalExpr(out_cc, env)); - out_cc->println("if ( %s < %s )", - env->LValue(end_of_field_dataptr_var), - field_begin.ptr_expr()); - out_cc->inc_indent(); - out_cc->println("{"); - out_cc->println("// throw ExceptionInvalidOffset(\"%s\", %s - %s, %s);", - id_->LocName(), - field_begin.ptr_expr(), - env->RValue(begin_of_data), - expr_->EvalExpr(out_cc, env)); - out_cc->println("%s = %s;", - env->LValue(end_of_field_dataptr_var), - field_begin.ptr_expr()); - out_cc->println("}"); - out_cc->dec_indent(); - break; - - case PAD_TO_NEXT_WORD: - padding_var = nfmt("%s__size", id()->Name()); - out_cc->println("int %s = (%s - %s) %% %d;", - padding_var, - field_begin.ptr_expr(), - env->RValue(begin_of_data), - wordsize_); - out_cc->println("%s = (%s == 0) ? 0 : %d - %s;", - padding_var, - padding_var, - wordsize_, - padding_var); - out_cc->println("const_byteptr const %s = %s + %s;", - env->LValue(end_of_field_dataptr_var), - field_begin.ptr_expr(), - padding_var); - delete [] padding_var; - break; - } - - env->SetEvaluated(end_of_field_dataptr_var); - } - -bool RecordPaddingField::GenBoundaryCheck(Output* out_cc, Env* env) - { - if ( boundary_checked_ ) - return true; - - const DataPtr& begin = getFieldBegin(out_cc, env); - - char* size; - int ss = StaticSize(env, begin.AbsOffset(begin_of_data)); - ASSERT ( ss >= 0 ); - size = nfmt("%d", ss); - - begin.GenBoundaryCheck(out_cc, env, size, field_id_str_.c_str()); - - delete [] size; - - SetBoundaryChecked(); - return true; - } - -bool RecordPaddingField::DoTraverse(DataDepVisitor *visitor) - { - return Field::DoTraverse(visitor) && - (! expr_ || expr_->Traverse(visitor)); - } - diff --git a/aux/binpac/src/pac_record.h b/aux/binpac/src/pac_record.h deleted file mode 100644 index 04daa3a9f4..0000000000 --- a/aux/binpac/src/pac_record.h +++ /dev/null @@ -1,169 +0,0 @@ -#ifndef pac_record_h -#define pac_record_h - -#include "pac_common.h" -#include "pac_field.h" -#include "pac_id.h" -#include "pac_let.h" -#include "pac_type.h" - -class RecordType : public Type -{ -public: - RecordType(RecordFieldList* fields); - ~RecordType(); - - bool DefineValueVar() const; - string DataTypeStr() const; - - void Prepare(Env* env, int flags); - - void GenPubDecls(Output* out, Env* env); - void GenPrivDecls(Output* out, Env* env); - - void GenInitCode(Output* out, Env* env); - void GenCleanUpCode(Output* out, Env* env); - - int StaticSize(Env* env) const; - - void SetBoundaryChecked(); - - const ID *parsing_dataptr_var() const; - - bool IsPointerType() const { ASSERT(0); return false; } - -protected: - void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags); - void GenDynamicSize(Output* out, Env* env, const DataPtr& data); - - Type *DoClone() const { return 0; } - - void DoMarkIncrementalInput(); - - bool DoTraverse(DataDepVisitor *visitor); - bool ByteOrderSensitive() const; - -private: - Field *parsing_dataptr_var_field_; - RecordFieldList* record_fields_; -}; - -// A data field of a record type. A RecordField corresponds to a -// segment of input data, and therefore RecordField's are ordered---each -// of them has a known previous and next field. - -class RecordField : public Field -{ -public: - RecordField(FieldType tof, ID* id, Type *type); - ~RecordField(); - - RecordType *record_type() const { return record_type_; } - void set_record_type(RecordType* ty) { record_type_ = ty; } - - virtual void GenParseCode(Output* out, Env* env) = 0; - - RecordField* prev() const { return prev_; } - RecordField* next() const { return next_; } - void set_prev(RecordField* f) { prev_ = f; } - void set_next(RecordField* f) { next_ = f; } - - int static_offset() const { return static_offset_; } - void set_static_offset(int offset) { static_offset_ = offset; } - - int parsing_state_seq() const { return parsing_state_seq_; } - void set_parsing_state_seq(int x) { parsing_state_seq_ = x; } - - virtual int StaticSize(Env* env, int offset) const = 0; - const char* FieldSize(Output* out, Env* env); - const char* FieldOffset(Output* out, Env* env); - - virtual bool BoundaryChecked() const { return boundary_checked_; } - virtual void SetBoundaryChecked() { boundary_checked_ = true; } - - virtual bool RequiresByteOrder() const = 0; - - friend class RecordType; - -protected: - RecordType* record_type_; - RecordField* prev_; - RecordField* next_; - bool boundary_checked_; - int static_offset_; - int parsing_state_seq_; - - DataPtr* begin_of_field_dataptr; - DataPtr* end_of_field_dataptr; - char* field_size_expr; - char* field_offset_expr; - ID* end_of_field_dataptr_var; - - const DataPtr& getFieldBegin(Output* out_cc, Env* env); - const DataPtr& getFieldEnd(Output* out_cc, Env* env); - virtual void GenFieldEnd(Output* out, Env* env, const DataPtr& begin) = 0; - - bool AttemptBoundaryCheck(Output* out_cc, Env* env); - virtual bool GenBoundaryCheck(Output* out_cc, Env* env) = 0; -}; - -class RecordDataField : public RecordField, public Evaluatable -{ -public: - RecordDataField(ID* arg_id, Type* arg_type); - ~RecordDataField(); - - // Instantiates abstract class Field - void Prepare(Env* env); - void GenParseCode(Output* out, Env* env); - - // Instantiates abstract class Evaluatable - void GenEval(Output* out, Env* env); - - int StaticSize(Env* env, int) const { return type()->StaticSize(env); } - - void SetBoundaryChecked(); - - bool RequiresByteOrder() const - { return type()->RequiresByteOrder(); } - bool RequiresAnalyzerContext() const; - -protected: - void GenFieldEnd(Output* out, Env* env, const DataPtr& begin); - bool GenBoundaryCheck(Output* out_cc, Env* env); - bool DoTraverse(DataDepVisitor *visitor); -}; - -enum PaddingType { PAD_BY_LENGTH, PAD_TO_OFFSET, PAD_TO_NEXT_WORD }; - -class RecordPaddingField : public RecordField -{ -public: - RecordPaddingField(ID* id, PaddingType ptype, Expr* expr); - ~RecordPaddingField(); - - void Prepare(Env* env); - - void GenPubDecls(Output* out, Env* env) { /* nothing */ } - void GenPrivDecls(Output* out, Env* env) { /* nothing */ } - - void GenInitCode(Output* out, Env* env) { /* nothing */ } - void GenCleanUpCode(Output* out, Env* env) { /* nothing */ } - void GenParseCode(Output* out, Env* env); - - int StaticSize(Env* env, int offset) const; - - bool RequiresByteOrder() const { return false; } - -protected: - void GenFieldEnd(Output* out, Env* env, const DataPtr& begin); - bool GenBoundaryCheck(Output* out_cc, Env* env); - bool DoTraverse(DataDepVisitor *visitor); - -private: - PaddingType ptype_; - Expr* expr_; - int wordsize_; -}; - -#endif // pac_record_h diff --git a/aux/binpac/src/pac_redef.cc b/aux/binpac/src/pac_redef.cc deleted file mode 100644 index 9f09b457bd..0000000000 --- a/aux/binpac/src/pac_redef.cc +++ /dev/null @@ -1,173 +0,0 @@ -#include "pac_analyzer.h" -#include "pac_case.h" -#include "pac_exception.h" -#include "pac_expr.h" -#include "pac_func.h" -#include "pac_record.h" -#include "pac_redef.h" -#include "pac_type.h" -#include "pac_typedecl.h" - -namespace { - -Decl *find_decl(const ID *id) - { - Decl *decl = Decl::LookUpDecl(id); - if ( ! decl ) - { - throw Exception(id, - fmt("cannot find declaration for %s", - id->Name())); - } - - return decl; - } - -} - -Decl *ProcessTypeRedef(const ID *id, FieldList *fieldlist) - { - Decl *decl = find_decl(id); - - if ( decl->decl_type() != Decl::TYPE ) - { - throw Exception(id, - fmt("not a type declaration: %s", - id->Name())); - } - - TypeDecl *type_decl = static_cast(decl); - ASSERT(type_decl); - Type *type = type_decl->type(); - - foreach(i, FieldList, fieldlist) - { - Field *f = *i; - - // One cannot change data layout in 'redef'. - // Only 'let' or 'action' can be added - if ( f->tof() == LET_FIELD || - f->tof() == WITHINPUT_FIELD ) - { - type->AddField(f); - } - else if ( f->tof() == RECORD_FIELD || - f->tof() == PADDING_FIELD ) - { - throw Exception(f, - "cannot change data layout in redef"); - } - else if ( f->tof() == CASE_FIELD ) - { - throw Exception(f, - "use 'redef case' adding cases"); - } - } - - return decl; - } - -Decl *ProcessCaseTypeRedef(const ID *id, CaseFieldList *casefieldlist) - { - Decl *decl = find_decl(id); - - if ( decl->decl_type() != Decl::TYPE ) - { - throw Exception(id, - fmt("not a type declaration: %s", - id->Name())); - } - - TypeDecl *type_decl = static_cast(decl); - ASSERT(type_decl); - - Type *type = type_decl->type(); - if ( type->tot() != Type::CASE ) - { - throw Exception(id, - fmt("not a case type: %s", - id->Name())); - } - - CaseType *casetype = static_cast(type); - ASSERT(casetype); - - foreach(i, CaseFieldList, casefieldlist) - { - CaseField *f = *i; - casetype->AddCaseField(f); - } - - return decl; - } - -Decl *ProcessCaseExprRedef(const ID *id, CaseExprList *caseexprlist) - { - Decl *decl = find_decl(id); - - if ( decl->decl_type() != Decl::FUNC ) - { - throw Exception(id, - fmt("not a function declaration: %s", - id->Name())); - } - - FuncDecl *func_decl = static_cast(decl); - ASSERT(func_decl); - - Expr *expr = func_decl->function()->expr(); - if ( ! expr ||expr->expr_type() != Expr::EXPR_CASE ) - { - throw Exception(id, - fmt("function not defined by a case expression: %s", - id->Name())); - } - - foreach(i, CaseExprList, caseexprlist) - { - CaseExpr *e = *i; - expr->AddCaseExpr(e); - } - - return decl; - } - -Decl *ProcessAnalyzerRedef(const ID *id, - Decl::DeclType decl_type, - AnalyzerElementList *elements) - { - Decl *decl = find_decl(id); - - if ( decl->decl_type() != decl_type ) - { - throw Exception(id, - fmt("not a connection/flow declaration: %s", - id->Name())); - } - - AnalyzerDecl *analyzer_decl = static_cast(decl); - ASSERT(analyzer_decl); - - analyzer_decl->AddElements(elements); - - return decl; - } - -Decl *ProcessTypeAttrRedef(const ID *id, AttrList *attrlist) - { - Decl *decl = find_decl(id); - - if ( decl->decl_type() != Decl::TYPE ) - { - throw Exception(id, - fmt("not a type declaration: %s", - id->Name())); - } - - TypeDecl *type_decl = static_cast(decl); - ASSERT(type_decl); - - type_decl->AddAttrs(attrlist); - - return decl; - } diff --git a/aux/binpac/src/pac_redef.h b/aux/binpac/src/pac_redef.h deleted file mode 100644 index 9a9c3030c4..0000000000 --- a/aux/binpac/src/pac_redef.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef pac_redef_h -#define pac_redef_h - -#include "pac_decl.h" - -Decl *ProcessCaseTypeRedef(const ID *id, CaseFieldList *casefieldlist); -Decl *ProcessCaseExprRedef(const ID *id, CaseExprList *caseexprlist); -Decl *ProcessAnalyzerRedef(const ID *id, - Decl::DeclType decl_type, - AnalyzerElementList *elements); -Decl *ProcessTypeAttrRedef(const ID *id, AttrList *attrlist); - -#endif // pac_redef_h diff --git a/aux/binpac/src/pac_regex.cc b/aux/binpac/src/pac_regex.cc deleted file mode 100644 index 6265c02876..0000000000 --- a/aux/binpac/src/pac_regex.cc +++ /dev/null @@ -1,82 +0,0 @@ -#include "pac_exttype.h" -#include "pac_id.h" -#include "pac_output.h" -#include "pac_regex.h" -#include "pac_type.h" - -// Depends on the regular expression library we are using -const char *RegEx::kREMatcherType = "RegExMatcher"; -const char *RegEx::kMatchPrefix = "MatchPrefix"; - -string escape_char(const string &s) - { - char buf[s.length() * 2 + 1]; - int j = 0; - for ( int i = 0; i < (int) s.length(); ++i ) - { - if ( s[i] == '\\' ) - { - if ( i + 1 < (int) s.length() ) - { - buf[j++] = '\\'; - if ( s[i+1] == '/' ) - buf[j-1] = s[++i]; - else if ( s[i+1] == '/' || s[i+1] == '\\' || s[i+1] == '"' ) - buf[j++] = s[++i]; - else - buf[j++] = '\\'; - } - } - else if ( s[i] == '"' ) - { - buf[j++] = '\\'; - buf[j++] = '"'; - } - else - { - buf[j++] = s[i]; - } - } - - buf[j++] = '\0'; - - return string(buf); - } - -RegEx::RegEx(const string &s) - { - str_ = escape_char(s); - string prefix = strfmt("%s_re_", current_decl_id->Name()); - matcher_id_ = ID::NewAnonymousID(prefix); - decl_ = new RegExDecl(this); - } - -RegEx::~RegEx() - { - } - -RegExDecl::RegExDecl(RegEx *regex) - : Decl(regex->matcher_id(), REGEX) - { - regex_ = regex; - } - -void RegExDecl::Prepare() - { - global_env()->AddID(id(), GLOBAL_VAR, extern_type_re_matcher); - } - -void RegExDecl::GenForwardDeclaration(Output *out_h) - { - out_h->println("extern %s %s;\n", - RegEx::kREMatcherType, - global_env()->LValue(regex_->matcher_id())); - } - -void RegExDecl::GenCode(Output *out_h, Output *out_cc) - { - out_cc->println("%s %s(\"%s\");\n", - RegEx::kREMatcherType, - global_env()->LValue(regex_->matcher_id()), - regex_->str().c_str()); - } diff --git a/aux/binpac/src/pac_regex.h b/aux/binpac/src/pac_regex.h deleted file mode 100644 index 47c601b729..0000000000 --- a/aux/binpac/src/pac_regex.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef pac_regex_h -#define pac_regex_h - -#include "pac_common.h" -#include "pac_decl.h" - -class RegExDecl; - -class RegEx : public Object -{ -public: - RegEx(const string &str); - ~RegEx(); - - const string &str() const { return str_; } - ID *matcher_id() const { return matcher_id_; } - -private: - string str_; - ID *matcher_id_; - RegExDecl *decl_; - -public: - static const char *kREMatcherType; - static const char *kMatchPrefix; -}; - -class RegExDecl : public Decl -{ -public: - RegExDecl(RegEx *regex); - - void Prepare(); - void GenForwardDeclaration(Output *out_h); - void GenCode(Output *out_h, Output *out_cc); - -private: - RegEx *regex_; -}; - -#endif // pac_regex_h diff --git a/aux/binpac/src/pac_scan.ll b/aux/binpac/src/pac_scan.ll deleted file mode 100644 index ec435ea4ea..0000000000 --- a/aux/binpac/src/pac_scan.ll +++ /dev/null @@ -1,356 +0,0 @@ -%{ -// $Id: pac_scan.ll 3361 2006-07-06 18:06:49Z rpang $ - -#include "pac_action.h" -#include "pac_array.h" -#include "pac_attr.h" -#include "pac_case.h" -#include "pac_common.h" -#include "pac_conn.h" -#include "pac_dataptr.h" -#include "pac_dataunit.h" -#include "pac_dbg.h" -#include "pac_decl.h" -#include "pac_exception.h" -#include "pac_expr.h" -#include "pac_flow.h" -#include "pac_id.h" -#include "pac_number.h" -#include "pac_output.h" -#include "pac_param.h" -#include "pac_parse.h" -#include "pac_record.h" -#include "pac_type.h" -#include "pac_utils.h" - -int line_number = 1; - -int begin_pac_primitive(int tok); -int end_pac_primitive(); - -int string_token(int tok) - { - yylval.str = copy_string(yytext); - return tok; - } - -int char_token(int tok) - { - yylval.val = yytext[0]; - return tok; - } - -void include_file(const char *filename); - -%} - -/* EC -- embedded code state */ -/* PP -- PAC primitive state */ -/* INCL -- @include line */ - -%s EC INCL PP RE - -WS [ \t]+ -ID [A-Za-z_][A-Za-z_0-9]* -D [0-9]+ -HEX [0-9a-fA-F]+ -FILE [A-Za-z._0-9\-]+ -ESCSEQ (\\([^\n]|[0-7]{3}|x[[:xdigit:]]{2})) - -%option nounput - -%% - -"%include" { - BEGIN(INCL); - } - -{WS} /* skip whitespace */ - -{FILE} { - BEGIN(INITIAL); - include_file(yytext); - } - -"%extern{" { - BEGIN(EC); - return TOK_LPB_EXTERN; - } -"%header{" { - BEGIN(EC); - return TOK_LPB_HEADER; - } -"%code{" { - BEGIN(EC); - return TOK_LPB_CODE; - } -"%init{" { - BEGIN(EC); - return TOK_LPB_INIT; - } -"%cleanup{" { - BEGIN(EC); - return TOK_LPB_CLEANUP; - } -"%member{" { - BEGIN(EC); - return TOK_LPB_MEMBER; - } -"%eof{" { - BEGIN(EC); - return TOK_LPB_EOF; - } -"%{" { - BEGIN(EC); - return TOK_LPB; - } -"%}" { - BEGIN(INITIAL); - return TOK_RPB; - } - -"${" return begin_pac_primitive(TOK_PAC_VAL); -"$set{" return begin_pac_primitive(TOK_PAC_SET); -"$type{" return begin_pac_primitive(TOK_PAC_TYPE); -"$typeof{" return begin_pac_primitive(TOK_PAC_TYPEOF); -"$const_def{" return begin_pac_primitive(TOK_PAC_CONST_DEF); - -"//".* return string_token(TOK_EMBEDDED_STRING); -. return char_token(TOK_EMBEDDED_ATOM); -\n { ++line_number; return char_token(TOK_EMBEDDED_ATOM); } - -"}" return end_pac_primitive(); - -\n ++line_number; -#.* /* eat comments */ -{WS} /* eat whitespace */ - -"RE/" { - BEGIN(RE); - return TOK_BEGIN_RE; - } - -([^/\\\n]|{ESCSEQ})+ return string_token(TOK_REGEX); - -"/" { - BEGIN(INITIAL); - return TOK_END_RE; - } - -[\\\n] return yytext[0]; - -analyzer return TOK_ANALYZER; -enum return TOK_ENUM; -extern return TOK_EXTERN; -flow return TOK_FLOW; -function return TOK_FUNCTION; -let return TOK_LET; -refine return TOK_REFINE; -type return TOK_TYPE; - -align return TOK_ALIGN; -case return TOK_CASE; -casefunc return TOK_CASEFUNC; -casetype return TOK_CASETYPE; -connection return TOK_CONNECTION; -datagram { - yylval.val = AnalyzerDataUnit::DATAGRAM; - return TOK_DATAUNIT; - } -default return TOK_DEFAULT; -downflow { - yylval.val = AnalyzerFlow::DOWN; - return TOK_FLOWDIR; - } -flowunit { - yylval.val = AnalyzerDataUnit::FLOWUNIT; - return TOK_DATAUNIT; - } -of return TOK_OF; -offsetof return TOK_OFFSETOF; -padding return TOK_PADDING; -record return TOK_RECORD; -sizeof return TOK_SIZEOF; -to return TOK_TO; -typeattr return TOK_TYPEATTR; -upflow { - yylval.val = AnalyzerFlow::UP; - return TOK_FLOWDIR; - } -withcontext return TOK_WITHCONTEXT; -withinput return TOK_WITHINPUT; - -&also return TOK_ATTR_ALSO; -&byteorder return TOK_ATTR_BYTEORDER; -&check return TOK_ATTR_CHECK; -&chunked return TOK_ATTR_CHUNKED; -&exportsourcedata return TOK_ATTR_EXPORTSOURCEDATA; -&if return TOK_ATTR_IF; -&length return TOK_ATTR_LENGTH; -&let return TOK_ATTR_LET; -&linebreaker return TOK_ATTR_LINEBREAKER; -&oneline return TOK_ATTR_ONELINE; -&refcount return TOK_ATTR_REFCOUNT; -&requires return TOK_ATTR_REQUIRES; -&restofdata return TOK_ATTR_RESTOFDATA; -&restofflow return TOK_ATTR_RESTOFFLOW; -&transient return TOK_ATTR_TRANSIENT; -&until return TOK_ATTR_UNTIL; - -"0x"{HEX} { - int n; - sscanf(yytext + 2, "%x", &n); - yylval.num = new Number(yytext, n); - return TOK_NUMBER; - } - -{D} { - int n; - sscanf(yytext, "%d", &n); - yylval.num = new Number(yytext, n); - return TOK_NUMBER; - } - -{ID} { - yylval.id = new ID(yytext); - return TOK_ID; - } - -"$"{ID} { - yylval.id = new ID(yytext); - return TOK_ID; - } - -\"([^\\\n\"]|{ESCSEQ})*\" return string_token(TOK_STRING); - -"==" return TOK_EQUAL; -"!=" return TOK_NEQ; -">=" return TOK_GE; -"<=" return TOK_LE; -"<<" return TOK_LSHIFT; -">>" return TOK_RSHIFT; -"&&" return TOK_AND; -"||" return TOK_OR; -"+=" return TOK_PLUSEQ; -"->" return TOK_RIGHTARROW; - -[\.!%*/+\-&|\^,:;<=>?()\[\]{}~] return yytext[0]; - -%% - -void begin_RE() - { - BEGIN(RE); - } - -void end_RE() - { - BEGIN(INITIAL); - } - -// The DECL state is deprecated -void begin_decl() - { - // BEGIN(DECL); - } - -void end_decl() - { - // BEGIN(INITIAL); - } - -int begin_pac_primitive(int tok) - { - BEGIN(PP); - return tok; - } - -int end_pac_primitive() - { - BEGIN(EC); - return TOK_END_PAC; - } - -const int MAX_INCLUDE_DEPTH = 100; - -struct IncludeState { - YY_BUFFER_STATE yystate; - string input_filename; - int line_number; -}; - -IncludeState include_stack[MAX_INCLUDE_DEPTH]; -int include_stack_ptr = 0; - -void switch_to_file(FILE *fp) - { - yy_switch_to_buffer(yy_create_buffer(fp, YY_BUF_SIZE)); - } - -void switch_to_file(const char *filename) - { - if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) - { - fprintf( stderr, "Includes nested too deeply" ); - exit( 1 ); - } - - IncludeState state = - { YY_CURRENT_BUFFER, input_filename, line_number }; - include_stack[include_stack_ptr++] = state; - - FILE *fp = fopen(filename, "r"); - - if ( ! fp ) - { - fprintf(stderr, "%s:%d: error: cannot include file \"%s\"\n", - input_filename.c_str(), line_number,filename); - --include_stack_ptr; - return; - } - - yyin = fp; - input_filename = string(filename); - line_number = 1; - switch_to_file(yyin); - fprintf(stderr, "switching to file %s\n", input_filename.c_str()); - } - -void include_file(const char *filename) - { - ASSERT(filename); - - string full_filename; - if ( filename[0] == '/' || filename[0] == '.' ) - full_filename = filename; - else - { - int i; - for ( i = 0; i < (int) FLAGS_include_directories.size(); ++i ) - { - full_filename = FLAGS_include_directories[i] + filename; - DEBUG_MSG("Try include file: \"%s\"\n", - full_filename.c_str()); - if ( access(full_filename.c_str(), R_OK) == 0 ) - break; - } - if ( i >= (int) FLAGS_include_directories.size() ) - full_filename = filename; - } - - switch_to_file(full_filename.c_str()); - } - -int yywrap() - { - yy_delete_buffer(YY_CURRENT_BUFFER); - --include_stack_ptr; - if ( include_stack_ptr < 0 ) - return 1; - - IncludeState state = include_stack[include_stack_ptr]; - yy_switch_to_buffer(state.yystate); - input_filename = state.input_filename; - line_number = state.line_number; - return 0; - } diff --git a/aux/binpac/src/pac_state.cc b/aux/binpac/src/pac_state.cc deleted file mode 100644 index 83ee974391..0000000000 --- a/aux/binpac/src/pac_state.cc +++ /dev/null @@ -1,36 +0,0 @@ -#include "pac_id.h" -#include "pac_output.h" -#include "pac_type.h" - -#include "pac_state.h" - -void StateVar::GenDecl(Output *out_h, Env *env) - { - out_h->println("%s %s;", - type_->DataTypeStr().c_str(), - env->LValue(id_)); - } - -void StateVar::GenAccessFunction(Output *out_h, Env *env) - { - out_h->println("%s %s const { return %s; }", - type_->DataTypeConstRefStr().c_str(), - env->RValue(id_), - env->LValue(id_)); - } - -void StateVar::GenSetFunction(Output *out_h, Env *env) - { - out_h->println("void %s(%s x) { %s = x; }", - set_function(id_).c_str(), - type_->DataTypeConstRefStr().c_str(), - env->LValue(id_)); - } - -void StateVar::GenInitCode(Output *out_cc, Env *env) - { - } - -void StateVar::GenCleanUpCode(Output *out_cc, Env *env) - { - } diff --git a/aux/binpac/src/pac_state.h b/aux/binpac/src/pac_state.h deleted file mode 100644 index 82bb580f47..0000000000 --- a/aux/binpac/src/pac_state.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef pac_state_h -#define pac_state_h - -// Classes representing analyzer states. - -#include "pac_common.h" - -class StateVar -{ -public: - StateVar(ID *id, Type *type) - : id_(id), type_(type) {} - - const ID *id() const { return id_; } - Type *type() const { return type_; } - - void GenDecl(Output *out_h, Env *env); - void GenAccessFunction(Output *out_h, Env *env); - void GenSetFunction(Output *out_h, Env *env); - void GenInitCode(Output *out_cc, Env *env); - void GenCleanUpCode(Output *out_cc, Env *env); - -private: - ID *id_; - Type *type_; -}; - -#endif // pac_state_h diff --git a/aux/binpac/src/pac_strtype.cc b/aux/binpac/src/pac_strtype.cc deleted file mode 100644 index 48e1eb5ad0..0000000000 --- a/aux/binpac/src/pac_strtype.cc +++ /dev/null @@ -1,425 +0,0 @@ -#include "pac_attr.h" -#include "pac_btype.h" -#include "pac_cstr.h" -#include "pac_dataptr.h" -#include "pac_exception.h" -#include "pac_expr.h" -#include "pac_exttype.h" -#include "pac_id.h" -#include "pac_output.h" -#include "pac_regex.h" -#include "pac_strtype.h" -#include "pac_varfield.h" - -const char *StringType::kStringTypeName = "bytestring"; -const char *StringType::kConstStringTypeName = "const_bytestring"; - -StringType::StringType(StringTypeEnum anystr) - : Type(STRING), type_(ANYSTR), str_(0), regex_(0) - { - ASSERT(anystr == ANYSTR); - init(); - } - -StringType::StringType(ConstString *str) - : Type(STRING), type_(CSTR), str_(str), regex_(0) - { - init(); - } - -StringType::StringType(RegEx *regex) - : Type(STRING), type_(REGEX), str_(0), regex_(regex) - { - ASSERT(regex_); - init(); - } - -void StringType::init() - { - string_length_var_field_ = 0; - elem_datatype_ = new BuiltInType(BuiltInType::UINT8); - } - -StringType::~StringType() - { - // TODO: Unref for Objects - // Question: why Unref? - // - // Unref(str_); - // Unref(regex_); - - delete string_length_var_field_; - delete elem_datatype_; - } - -Type *StringType::DoClone() const - { - StringType *clone; - - switch ( type_ ) - { - case ANYSTR: - clone = new StringType(ANYSTR); - break; - case CSTR: - clone = new StringType(str_); - break; - case REGEX: - clone = new StringType(regex_); - break; - default: - ASSERT(0); - return 0; - } - - return clone; - } - -bool StringType::DefineValueVar() const - { - return true; - } - -string StringType::DataTypeStr() const - { - return strfmt("%s", - persistent() ? kStringTypeName : kConstStringTypeName); - } - -Type *StringType::ElementDataType() const - { - return elem_datatype_; - } - -void StringType::ProcessAttr(Attr *a) - { - Type::ProcessAttr(a); - - switch ( a->type() ) - { - case ATTR_CHUNKED: - { - if ( type_ != ANYSTR ) - { - throw Exception(a, - "&chunked can be applied" - " to only type bytestring"); - } - attr_chunked_ = true; - SetBoundaryChecked(); - } - break; - - case ATTR_RESTOFDATA: - { - if ( type_ != ANYSTR ) - { - throw Exception(a, - "&restofdata can be applied" - " to only type bytestring"); - } - attr_restofdata_ = true; - // As the string automatically extends to the end of - // data, we do not have to check boundary. - SetBoundaryChecked(); - } - break; - - case ATTR_RESTOFFLOW: - { - if ( type_ != ANYSTR ) - { - throw Exception(a, - "&restofflow can be applied" - " to only type bytestring"); - } - attr_restofflow_ = true; - // As the string automatically extends to the end of - // flow, we do not have to check boundary. - SetBoundaryChecked(); - } - break; - - default: - break; - } - } - -void StringType::Prepare(Env* env, int flags) - { - if ( (flags & TO_BE_PARSED) && StaticSize(env) < 0 ) - { - ID *string_length_var = new ID(fmt("%s_string_length", - value_var() ? value_var()->Name() : "val")); - string_length_var_field_ = new TempVarField( - string_length_var, extern_type_int->Clone()); - string_length_var_field_->Prepare(env); - } - Type::Prepare(env, flags); - } - -void StringType::GenPubDecls(Output* out_h, Env* env) - { - Type::GenPubDecls(out_h, env); - } - -void StringType::GenPrivDecls(Output* out_h, Env* env) - { - Type::GenPrivDecls(out_h, env); - } - -void StringType::GenInitCode(Output* out_cc, Env* env) - { - Type::GenInitCode(out_cc, env); - } - -void StringType::GenCleanUpCode(Output* out_cc, Env* env) - { - Type::GenCleanUpCode(out_cc, env); - if ( persistent() ) - out_cc->println("%s.free();", env->LValue(value_var())); - } - -void StringType::DoMarkIncrementalInput() - { - if ( attr_restofflow_ ) - { - // Do nothing - ASSERT(type_ == ANYSTR); - } - else - { - Type::DoMarkIncrementalInput(); - } - } - -int StringType::StaticSize(Env* env) const - { - switch ( type_ ) - { - case CSTR: - // Use length of the unescaped string - return str_->unescaped().length(); - case REGEX: - // TODO: static size for a regular expression? - case ANYSTR: - return -1; - - default: - ASSERT(0); - return -1; - } - } - -const ID *StringType::string_length_var() const - { - return string_length_var_field_ ? string_length_var_field_->id() : 0; - } - -void StringType::GenDynamicSize(Output* out_cc, Env* env, - const DataPtr& data) - { - ASSERT(StaticSize(env) < 0); - DEBUG_MSG("Generating dynamic size for string `%s'\n", - value_var()->Name()); - - if ( env->Evaluated(string_length_var()) ) - return; - - string_length_var_field_->GenTempDecls(out_cc, env); - - switch ( type_ ) - { - case ANYSTR: - GenDynamicSizeAnyStr(out_cc, env, data); - break; - case CSTR: - ASSERT(0); - break; - case REGEX: - // TODO: static size for a regular expression? - GenDynamicSizeRegEx(out_cc, env, data); - break; - } - - if ( ! incremental_input() && AddSizeVar(out_cc, env) ) - { - out_cc->println("%s = %s;", - env->LValue(size_var()), - env->RValue(string_length_var())); - env->SetEvaluated(size_var()); - } - } - -string StringType::GenStringSize(Output* out_cc, Env* env, - const DataPtr& data) - { - int static_size = StaticSize(env); - if ( static_size >= 0 ) - return strfmt("%d", static_size); - GenDynamicSize(out_cc, env, data); - return env->RValue(string_length_var()); - } - -void StringType::DoGenParseCode(Output* out_cc, Env* env, - const DataPtr& data, int flags) - { - string str_size = GenStringSize(out_cc, env, data); - - // Generate additional checking - switch ( type_ ) - { - case CSTR: - GenCheckingCStr(out_cc, env, data, str_size); - break; - case REGEX: - case ANYSTR: - break; - } - - if ( ! anonymous_value_var() ) - { - // Set the value variable - out_cc->println("// check for negative sizes"); - out_cc->println("if ( %s < 0 )", - str_size.c_str()); - out_cc->println("throw ExceptionInvalidStringLength(\"%s\", %s);", - Location(), str_size.c_str()); - out_cc->println("%s.init(%s, %s);", - env->LValue(value_var()), - data.ptr_expr(), - str_size.c_str()); - } - - if ( parsing_complete_var() ) - { - out_cc->println("%s = true;", - env->LValue(parsing_complete_var())); - } - } - -void StringType::GenStringMismatch(Output* out_cc, Env* env, - const DataPtr& data, const char *pattern) - { - out_cc->println("throw ExceptionStringMismatch(\"%s\", %s, %s);", - Location(), - pattern, - fmt("string((const char *) (%s), (const char *) %s).c_str()", - data.ptr_expr(), - env->RValue(end_of_data))); - } - -void StringType::GenCheckingCStr(Output* out_cc, Env* env, - const DataPtr& data, const string &str_size) - { - // TODO: extend it for dynamic strings - ASSERT(type_ == CSTR); - - GenBoundaryCheck(out_cc, env, data); - - string str_val = str_->str(); - - // Compare the string and report error on mismatch - out_cc->println("if ( memcmp(%s, %s, %s) != 0 )", - data.ptr_expr(), - str_val.c_str(), - str_size.c_str()); - out_cc->inc_indent(); - out_cc->println("{"); - GenStringMismatch(out_cc, env, data, str_val.c_str()); - out_cc->println("}"); - out_cc->dec_indent(); - } - -void StringType::GenDynamicSizeRegEx(Output* out_cc, Env* env, - const DataPtr& data) - { - // string_length_var = - // matcher.match_prefix( - // begin, - // end); - - out_cc->println("%s = ", - env->LValue(string_length_var())); - out_cc->inc_indent(); - - out_cc->println("%s.%s(", - env->RValue(regex_->matcher_id()), - RegEx::kMatchPrefix); - - out_cc->inc_indent(); - out_cc->println("%s,", - data.ptr_expr()); - out_cc->println("%s - %s);", - env->RValue(end_of_data), - data.ptr_expr()); - - out_cc->dec_indent(); - out_cc->dec_indent(); - - env->SetEvaluated(string_length_var()); - - out_cc->println("if ( %s < 0 )", - env->RValue(string_length_var())); - out_cc->inc_indent(); - out_cc->println("{"); - GenStringMismatch(out_cc, env, data, - fmt("\"%s\"", regex_->str().c_str())); - out_cc->println("}"); - out_cc->dec_indent(); - } - -void StringType::GenDynamicSizeAnyStr(Output* out_cc, Env* env, - const DataPtr& data) - { - ASSERT(type_ == ANYSTR); - - if ( attr_restofdata_ || attr_oneline_ ) - { - out_cc->println("%s = (%s) - (%s);", - env->LValue(string_length_var()), - env->RValue(end_of_data), - data.ptr_expr()); - } - else if ( attr_restofflow_ ) - { - out_cc->println("%s = (%s) - (%s);", - env->LValue(string_length_var()), - env->RValue(end_of_data), - data.ptr_expr()); - } - else if ( attr_length_expr_ ) - { - out_cc->println("%s = %s;", - env->LValue(string_length_var()), - attr_length_expr_->EvalExpr(out_cc, env)); - } - else - { - throw Exception(this, - "cannot determine length of bytestring"); - } - - env->SetEvaluated(string_length_var()); - } - -bool StringType::DoTraverse(DataDepVisitor *visitor) - { - if ( ! Type::DoTraverse(visitor) ) - return false; - - switch ( type_ ) - { - case ANYSTR: - case CSTR: - case REGEX: - break; - } - - return true; - } - -void StringType::static_init() - { - Type::AddPredefinedType("bytestring", new StringType(ANYSTR)); - } diff --git a/aux/binpac/src/pac_strtype.h b/aux/binpac/src/pac_strtype.h deleted file mode 100644 index 55b35e54ab..0000000000 --- a/aux/binpac/src/pac_strtype.h +++ /dev/null @@ -1,82 +0,0 @@ -#ifndef pac_strtype_h -#define pac_strtype_h - -#include "pac_type.h" - -// TODO: question: shall we merge it with ArrayType? -class StringType : public Type -{ -public: - enum StringTypeEnum { CSTR, REGEX, ANYSTR }; - - explicit StringType(StringTypeEnum anystr); - explicit StringType(ConstString *str); - explicit StringType(RegEx *regex); - ~StringType(); - - bool DefineValueVar() const; - string DataTypeStr() const; - string DefaultValue() const { return "0"; } - Type *ElementDataType() const; - - void Prepare(Env* env, int flags); - - void GenPubDecls(Output* out, Env* env); - void GenPrivDecls(Output* out, Env* env); - - void GenInitCode(Output* out, Env* env); - void GenCleanUpCode(Output* out, Env* env); - - void DoMarkIncrementalInput(); - - int StaticSize(Env* env) const; - - bool IsPointerType() const { return false; } - - void ProcessAttr(Attr *a); - -protected: - void init(); - - // Generate computation of size of the string and returns the string - // representing a constant integer or name of the length variable. - string GenStringSize(Output* out_cc, Env* env, const DataPtr& data); - - // Generate a string mismatch exception - void GenStringMismatch(Output* out_cc, Env* env, - const DataPtr& data, const char *pattern); - - void DoGenParseCode(Output* out, Env* env, const DataPtr& data, int flags); - - void GenCheckingCStr(Output* out, Env* env, - const DataPtr& data, const string &str_size); - - void GenDynamicSize(Output* out, Env* env, const DataPtr& data); - void GenDynamicSizeAnyStr(Output* out_cc, Env* env, const DataPtr& data); - void GenDynamicSizeRegEx(Output* out_cc, Env* env, const DataPtr& data); - - Type *DoClone() const; - - // TODO: insensitive towards byte order till we support unicode - bool ByteOrderSensitive() const { return false; } - -protected: - bool DoTraverse(DataDepVisitor *visitor); - -private: - const ID *string_length_var() const; - - StringTypeEnum type_; - ConstString *str_; - RegEx *regex_; - Field *string_length_var_field_; - Type *elem_datatype_; - -public: - static void static_init(); -private: - static const char *kStringTypeName; - static const char *kConstStringTypeName; -}; - -#endif // pac_strtype_h diff --git a/aux/binpac/src/pac_type.cc b/aux/binpac/src/pac_type.cc deleted file mode 100644 index a30295aa0e..0000000000 --- a/aux/binpac/src/pac_type.cc +++ /dev/null @@ -1,1137 +0,0 @@ -#include "pac_action.h" -#include "pac_array.h" -#include "pac_attr.h" -#include "pac_btype.h" -#include "pac_context.h" -#include "pac_dataptr.h" -#include "pac_decl.h" -#include "pac_exception.h" -#include "pac_expr.h" -#include "pac_exttype.h" -#include "pac_field.h" -#include "pac_id.h" -#include "pac_let.h" -#include "pac_output.h" -#include "pac_paramtype.h" -#include "pac_strtype.h" -#include "pac_type.h" -#include "pac_utils.h" -#include "pac_varfield.h" -#include "pac_withinput.h" - - -Type::type_map_t Type::type_map_; - -Type::Type(TypeType tot) - : DataDepElement(DataDepElement::TYPE), tot_(tot) - { - type_decl_ = 0; - type_decl_id_ = current_decl_id; - declared_as_type_ = false; - env_ = 0; - value_var_ = default_value_var; - ASSERT(value_var_); - value_var_type_ = MEMBER_VAR; - anonymous_value_var_ = false; - size_var_field_ = 0; - size_expr_ = 0; - boundary_checked_ = false; - parsing_complete_var_field_ = 0; - parsing_state_var_field_ = 0; - buffering_state_var_field_ = 0; - has_value_field_ = 0; - - array_until_input_ = 0; - - incremental_input_ = false; - buffer_input_ = false; - incremental_parsing_ = false; - - fields_ = new FieldList(); - - attrs_ = new AttrList(); - attr_byteorder_expr_ = 0; - attr_checks_ = new ExprList(); - attr_chunked_ = false; - attr_exportsourcedata_ = false; - attr_if_expr_ = 0; - attr_length_expr_ = 0; - attr_letfields_ = 0; - attr_multiline_end_ = 0; - attr_oneline_ = false; - attr_refcount_ = false; - attr_requires_ = 0; - attr_restofdata_ = false; - attr_restofflow_ = false; - attr_transient_ = false; - } - -Type::~Type() - { - delete size_var_field_; - delete parsing_complete_var_field_; - delete parsing_state_var_field_; - delete buffering_state_var_field_; - delete has_value_field_; - delete [] size_expr_; - delete_list(FieldList, fields_); - delete attrs_; - delete attr_byteorder_expr_; - delete attr_if_expr_; - delete attr_length_expr_; - delete_list(ExprList, attr_checks_); - delete attr_requires_; - } - -Type *Type::Clone() const - { - Type *clone = DoClone(); - if ( clone ) - { - foreach(i, FieldList, fields_) - { - Field *f = *i; - clone->AddField(f); - } - - foreach(i, AttrList, attrs_) - { - Attr *a = *i; - clone->ProcessAttr(a); - } - } - return clone; - } - -string Type::EvalMember(const ID *member_id) const - { - ASSERT(0); - return "@@@"; - } - -string Type::EvalElement(const string &array, const string &index) const - { - return strfmt("%s[%s]", array.c_str(), index.c_str()); - } - -const ID *Type::decl_id() const - { - return type_decl_id_; - } - -void Type::set_type_decl(const TypeDecl *decl, bool declared_as_type) - { - type_decl_ = decl; - type_decl_id_ = decl->id(); - declared_as_type_ = declared_as_type; - } - -void Type::set_value_var(const ID* arg_id, int arg_id_type) - { - value_var_ = arg_id; - value_var_type_ = arg_id_type; - - if ( value_var_ ) - anonymous_value_var_ = value_var_->is_anonymous(); - } - -const ID *Type::size_var() const - { - return size_var_field_ ? size_var_field_->id() : 0; - } - -void Type::AddField(Field *f) - { - ASSERT(f); - fields_->push_back(f); - } - -void Type::ProcessAttr(Attr* a) - { - switch ( a->type() ) - { - case ATTR_BYTEORDER: - attr_byteorder_expr_ = a->expr(); - break; - - case ATTR_CHECK: - attr_checks_->push_back(a->expr()); - break; - - case ATTR_EXPORTSOURCEDATA: - attr_exportsourcedata_ = true; - break; - - case ATTR_LENGTH: - attr_length_expr_ = a->expr(); - break; - - case ATTR_IF: - attr_if_expr_ = a->expr(); - break; - - case ATTR_LET: - { - LetAttr *letattr = static_cast(a); - if ( ! attr_letfields_ ) - attr_letfields_ = letattr->letfields(); - else - { - // Append to attr_letfields_ - attr_letfields_->insert( - attr_letfields_->end(), - letattr->letfields()->begin(), - letattr->letfields()->end()); - } - } - break; - - case ATTR_LINEBREAKER: - ASSERT(0); - break; - - case ATTR_MULTILINE: - attr_multiline_end_ = a->expr(); - break; - - case ATTR_ONELINE: - attr_oneline_ = true; - break; - - case ATTR_REFCOUNT: - attr_refcount_ = true; - break; - - case ATTR_REQUIRES: - attr_requires_ = a->expr(); - break; - - case ATTR_TRANSIENT: - attr_transient_ = true; - break; - - case ATTR_CHUNKED: - case ATTR_UNTIL: - case ATTR_RESTOFDATA: - case ATTR_RESTOFFLOW: - // Ignore - // ... these are processed by { - // {ArrayType, StringType}::ProcessAttr - break; - } - - attrs_->push_back(a); - } - -string Type::EvalByteOrder(Output *out_cc, Env *env) const - { - // If &byteorder is specified for a field, rather - // than a type declaration, we do not add a byteorder variable - // to the class, but instead evaluate it directly. - if ( attr_byteorder_expr() && ! declared_as_type() ) - return attr_byteorder_expr()->EvalExpr(out_cc, global_env()); - env->Evaluate(out_cc, byteorder_id); - return env->RValue(byteorder_id); - } - -void Type::Prepare(Env* env, int flags) - { - env_ = env; - ASSERT(env_); - - // The name of the value variable - if ( value_var() ) - { - data_id_str_ = strfmt("%s:%s", - decl_id()->Name(), value_var()->Name()); - } - else - { - data_id_str_ = strfmt("%s", decl_id()->Name()); - } - - if ( value_var() ) - { - env_->AddID(value_var(), - static_cast(value_var_type_), - this); - lvalue_ = strfmt("%s", env_->LValue(value_var())); - } - - foreach(i, FieldList, attr_letfields_) - { - AddField(*i); - } - - if ( attr_exportsourcedata_ ) - { - ASSERT(flags & TO_BE_PARSED); - AddField(new PubVarField(sourcedata_id->clone(), - extern_type_const_bytestring->Clone())); - } - - // An optional field - if ( attr_if_expr() ) - { - ASSERT(value_var()); - ID *has_value_id = new ID(fmt("has_%s", value_var()->Name())); - has_value_field_ = new LetField(has_value_id, - extern_type_bool->Clone(), - attr_if_expr()); - AddField(has_value_field_); - } - - if ( incremental_input() ) - { - ASSERT(flags & TO_BE_PARSED); - ID *parsing_complete_var = - new ID(fmt("%s_parsing_complete", - value_var() ? value_var()->Name() : "val")); - DEBUG_MSG("Adding parsing complete var: %s\n", - parsing_complete_var->Name()); - parsing_complete_var_field_ = new TempVarField( - parsing_complete_var, extern_type_bool->Clone()); - parsing_complete_var_field_->Prepare(env); - - if ( NeedsBufferingStateVar() && - ! env->GetDataType(buffering_state_id) ) - { - buffering_state_var_field_ = new PrivVarField( - buffering_state_id->clone(), - extern_type_int->Clone()); - AddField(buffering_state_var_field_); - } - - if ( incremental_parsing() && tot_ == RECORD ) - { - ASSERT(! parsing_state_var_field_); - parsing_state_var_field_ = new PrivVarField( - parsing_state_id->clone(), - extern_type_int->Clone()); - AddField(parsing_state_var_field_); - } - } - - foreach (i, FieldList, fields_) - { - Field *f = *i; - f->Prepare(env); - } - } - -void Type::GenPubDecls(Output* out_h, Env* env) - { - if ( DefineValueVar() ) - { - if ( attr_if_expr_ ) - out_h->println("%s %s const { BINPAC_ASSERT(%s); return %s; }", - DataTypeConstRefStr().c_str(), - env->RValue(value_var()), - env->RValue(has_value_var()), lvalue()); - else - out_h->println("%s %s const { return %s; }", - DataTypeConstRefStr().c_str(), - env->RValue(value_var()), lvalue()); - } - - foreach (i, FieldList, fields_) - { - Field *f = *i; - f->GenPubDecls(out_h, env); - } - } - -void Type::GenPrivDecls(Output* out_h, Env* env) - { - if ( DefineValueVar() ) - { - out_h->println("%s %s;", - DataTypeStr().c_str(), - env->LValue(value_var())); - } - - foreach (i, FieldList, fields_) - { - Field *f = *i; - f->GenPrivDecls(out_h, env); - } - } - -void Type::GenInitCode(Output* out_cc, Env* env) - { - foreach (i, FieldList, fields_) - { - Field *f = *i; - f->GenInitCode(out_cc, env); - } - - if ( parsing_state_var_field_ ) - { - out_cc->println("%s = 0;", - env->LValue(parsing_state_var_field_->id())); - } - - if ( buffering_state_var_field_ ) - { - out_cc->println("%s = 0;", - env->LValue(buffering_state_var_field_->id())); - } - } - -void Type::GenCleanUpCode(Output* out_cc, Env* env) - { - foreach (i, FieldList, fields_) - { - Field *f = *i; - if ( f->tof() != CASE_FIELD ) - f->GenCleanUpCode(out_cc, env); - } - } - -void Type::GenBufferConfiguration(Output *out_cc, Env *env) - { - ASSERT(buffer_input()); - - string frame_buffer_arg; - - switch ( buffer_mode() ) - { - case BUFFER_NOTHING: - break; - - case BUFFER_BY_LENGTH: - if ( ! NeedsBufferingStateVar() ) - break; - - if ( buffering_state_var_field_ ) - { - out_cc->println("if ( %s == 0 )", - env->RValue(buffering_state_id)); - out_cc->inc_indent(); - out_cc->println("{"); - } - - if ( attr_length_expr_ ) - { - // frame_buffer_arg = attr_length_expr_->EvalExpr(out_cc, env); - frame_buffer_arg = strfmt("%d", InitialBufferLength()); - } - else if ( attr_restofflow_ ) - { - ASSERT(attr_chunked()); - frame_buffer_arg = "-1"; - } - else - { - ASSERT(0); - } - - out_cc->println("%s->NewFrame(%s, %s);", - env->LValue(flow_buffer_id), - frame_buffer_arg.c_str(), - attr_chunked() ? "true" : "false"); - - if ( buffering_state_var_field_ ) - { - out_cc->println("%s = 1;", - env->LValue(buffering_state_id)); - out_cc->println("}"); - out_cc->dec_indent(); - } - break; - - case BUFFER_BY_LINE: - out_cc->println("if ( %s == 0 )", - env->RValue(buffering_state_id)); - out_cc->inc_indent(); - out_cc->println("{"); - - out_cc->println("%s->NewLine();", - env->LValue(flow_buffer_id)); - - out_cc->println("%s = 1;", - env->LValue(buffering_state_id)); - out_cc->println("}"); - out_cc->dec_indent(); - break; - - default: - ASSERT(0); - break; - } - } - -void Type::GenPreParsing(Output *out_cc, Env *env) - { - if ( incremental_input() && IsPointerType() ) - { - out_cc->println("if ( ! %s )", env->LValue(value_var())); - out_cc->inc_indent(); - out_cc->println("{"); - GenNewInstance(out_cc, env); - out_cc->println("}"); - out_cc->dec_indent(); - } - else - GenNewInstance(out_cc, env); - - if ( buffer_input() ) - { - GenBufferConfiguration(out_cc, env); - } - } - -// Wrappers around DoGenParseCode, which does the real job -void Type::GenParseCode(Output* out_cc, Env* env, const DataPtr& data, int flags) - { - if ( value_var() && env->Evaluated(value_var()) ) - return; - - DEBUG_MSG("GenParseCode for %s\n", data_id_str_.c_str()); - - if ( attr_if_expr() ) - { - ASSERT(has_value_var()); - ASSERT(env->Evaluated(has_value_var())); - } - - if ( value_var() && anonymous_value_var() ) - { - GenPrivDecls(out_cc, env); - GenInitCode(out_cc, env); - } - - if ( incremental_input() ) - { - parsing_complete_var_field_->GenTempDecls(out_cc, env); - - out_cc->println("%s = false;", - env->LValue(parsing_complete_var())); - env->SetEvaluated(parsing_complete_var()); - - if ( buffer_mode() == BUFFER_NOTHING ) - { - out_cc->println("%s = true;", - env->LValue(parsing_complete_var())); - } - else if ( buffer_input() ) - { - if ( declared_as_type() ) - GenParseBuffer(out_cc, env, flags); - else - GenBufferingLoop(out_cc, env, flags); - } - else - GenParseCode2(out_cc, env, data, flags); - } - else - { - if ( attr_length_expr_) - { - EvalLengthExpr(out_cc, env); - - GenBoundaryCheck(out_cc, env, data); - - out_cc->println("{"); - out_cc->println("// Setting %s with &length", - env->RValue(end_of_data)); - out_cc->println("%s %s = %s + %s;", - extern_type_const_byteptr->DataTypeStr().c_str(), - env->LValue(end_of_data), - data.ptr_expr(), - EvalLengthExpr(out_cc, env).c_str()); - - GenParseCode2(out_cc, env, data, flags); - - out_cc->println("}"); - } - else - { - GenParseCode2(out_cc, env, data, flags); - } - } - } - -void Type::GenBufferingLoop(Output* out_cc, Env* env, int flags) - { - out_cc->println("while ( ! %s && %s->ready() )", - env->LValue(parsing_complete_var()), - env->LValue(flow_buffer_id)); - - out_cc->inc_indent(); - out_cc->println("{"); - - Env buffer_env(env, this); - GenParseBuffer(out_cc, &buffer_env, flags); - - out_cc->println("}"); - out_cc->dec_indent(); - } - -void Type::GenParseBuffer(Output* out_cc, Env* env, int flags) - { - ASSERT(incremental_input()); - - const ID *data_begin; - - if ( ! incremental_parsing() ) - { - env->AddID(begin_of_data, TEMP_VAR, extern_type_const_byteptr); - env->AddID(end_of_data, TEMP_VAR, extern_type_const_byteptr); - - out_cc->println("%s %s = %s->begin();", - env->DataTypeStr(begin_of_data).c_str(), - env->LValue(begin_of_data), - env->RValue(flow_buffer_id)); - - out_cc->println("%s %s = %s->end();", - env->DataTypeStr(end_of_data).c_str(), - env->LValue(end_of_data), - env->RValue(flow_buffer_id)); - - env->SetEvaluated(begin_of_data); - env->SetEvaluated(end_of_data); - - data_begin = begin_of_data; - } - else - data_begin = 0; - - if ( array_until_input_ ) - { - if ( incremental_parsing() ) - { - throw Exception(this, - "cannot handle &until($input...) " - "for incrementally parsed type"); - } - array_until_input_->GenUntilInputCheck(out_cc, env); - } - - DataPtr data(env, data_begin, 0); - - if ( attr_length_expr() ) - { - ASSERT(buffer_mode() == BUFFER_BY_LENGTH); - out_cc->println("switch ( %s )", - env->LValue(buffering_state_id)); - out_cc->inc_indent(); - out_cc->println("{"); - out_cc->println("case 0:"); - out_cc->inc_indent(); - GenBufferConfiguration(out_cc, env); - out_cc->println("%s = 1;", env->LValue(buffering_state_id)); - out_cc->println("break;"); - out_cc->dec_indent(); - - out_cc->println("case 1:"); - out_cc->inc_indent(); - - out_cc->println("{"); - - out_cc->println("%s = 2;", env->LValue(buffering_state_id)); - - Env frame_length_env(env, this); - out_cc->println("%s->GrowFrame(%s);", - env->LValue(flow_buffer_id), - attr_length_expr_->EvalExpr(out_cc, &frame_length_env)); - out_cc->println("}"); - out_cc->println("break;"); - - out_cc->dec_indent(); - out_cc->println("case 2:"); - out_cc->inc_indent(); - - out_cc->println("BINPAC_ASSERT(%s->ready());", - env->RValue(flow_buffer_id)); - out_cc->println("if ( %s->ready() )", - env->RValue(flow_buffer_id)); - out_cc->inc_indent(); - out_cc->println("{"); - - Env parse_env(env, this); - GenParseCode2(out_cc, &parse_env, data, 0); - - out_cc->println("BINPAC_ASSERT(%s);", - parsing_complete(env).c_str()); - out_cc->println("%s = 0;", - env->LValue(buffering_state_id)); - out_cc->println("}"); - out_cc->dec_indent(); - - out_cc->println("break;"); - - out_cc->dec_indent(); - out_cc->println("default:"); - out_cc->inc_indent(); - - out_cc->println("BINPAC_ASSERT(%s <= 2);", - env->LValue(buffering_state_id)); - out_cc->println("break;"); - - out_cc->dec_indent(); - out_cc->println("}"); - out_cc->dec_indent(); - } - else if ( attr_restofflow_ ) - { - out_cc->println("BINPAC_ASSERT(%s->eof());", - env->RValue(flow_buffer_id)); - GenParseCode2(out_cc, env, data, 0); - } - else if ( buffer_mode() == BUFFER_BY_LINE ) - { - GenParseCode2(out_cc, env, data, 0); - out_cc->println("%s = 0;", env->LValue(buffering_state_id)); - } - else - GenParseCode2(out_cc, env, data, 0); - } - -void Type::GenParseCode2(Output* out_cc, Env* env, - const DataPtr& data, int flags) - { - DEBUG_MSG("GenParseCode2 for %s\n", data_id_str_.c_str()); - - if ( attr_exportsourcedata_ ) - { - if ( incremental_parsing() ) - { - throw Exception(this, - "cannot export raw data for incrementally parsed types"); - } - - out_cc->println("%s = const_bytestring(%s, %s);", - env->LValue(sourcedata_id), - data.ptr_expr(), - env->RValue(end_of_data)); - env->SetEvaluated(sourcedata_id); - - GenParseCode3(out_cc, env, data, flags); - - string datasize_str = DataSize(out_cc, env, data); - out_cc->println("%s.set_end(%s + %s);", - env->LValue(sourcedata_id), - data.ptr_expr(), - datasize_str.c_str()); - } - else - { - GenParseCode3(out_cc, env, data, flags); - } - } - -void Type::GenParseCode3(Output* out_cc, Env* env, const DataPtr& data, int flags) - { - if ( attr_requires_ ) - attr_requires_->EvalExpr(out_cc, env); - - foreach(i, FieldList, fields_) - { - Field *f = *i; - f->GenTempDecls(out_cc, env); - } - - DoGenParseCode(out_cc, env, data, flags); - - if ( incremental_input() ) - { - out_cc->println("if ( %s )", parsing_complete(env).c_str()); - out_cc->inc_indent(); - out_cc->println("{"); - } - - out_cc->println("// Evaluate 'let' and 'withinput' fields"); - foreach(i, FieldList, fields_) - { - Field *f = *i; - if ( f->tof() == LET_FIELD ) - { - LetField *lf = static_cast(f); - lf->GenParseCode(out_cc, env); - } - else if ( f->tof() == WITHINPUT_FIELD ) - { - WithInputField *af = static_cast(f); - af->GenParseCode(out_cc, env); - } - } - - if ( value_var() && anonymous_value_var() ) - { - GenCleanUpCode(out_cc, env); - } - - if ( incremental_input() ) - { - out_cc->println("}"); - out_cc->dec_indent(); - } - - if ( value_var() ) - env->SetEvaluated(value_var()); - - if ( size_var() ) - ASSERT(env->Evaluated(size_var())); - } - -Type *Type::MemberDataType(const ID *member_id) const - { - DEBUG_MSG("MemberDataType: %s::%s\n", type_decl_id_->Name(), member_id->Name()); - ASSERT(env_); - env_->set_allow_undefined_id(true); - Type *t = env_->GetDataType(member_id); - env_->set_allow_undefined_id(false); - return t; - } - -Type *Type::ElementDataType() const - { - return 0; - } - -// Returns false if it is not necessary to add size_var -// (it is already added or the type has a fixed size). -bool Type::AddSizeVar(Output* out_cc, Env* env) - { - if ( size_var() ) - { - DEBUG_MSG("size var `%s' already added\n", size_var()->Name()); - ASSERT(env->Evaluated(size_var())); - return false; - } - - if ( StaticSize(env) >= 0 ) - return false; - - ASSERT(! incremental_input()); - - ID *size_var_id = new ID(fmt("%s__size", - value_var() ? value_var()->Name() : decl_id()->Name())); - - DEBUG_MSG("adding size var `%s' to env %p\n", size_var_id->Name(), env); - - size_var_field_ = new TempVarField( - size_var_id, extern_type_int->Clone()); - size_var_field_->Prepare(env); - size_var_field_->GenTempDecls(out_cc, env); - - return true; - } - -string Type::EvalLengthExpr(Output* out_cc, Env* env) - { - ASSERT(!incremental_input()); - ASSERT(attr_length_expr_); - int static_length; - if ( attr_length_expr_->ConstFold(env, &static_length) ) - return strfmt("%d", static_length); - // How do we make sure size_var is evaluated with attr_length_expr_? - if ( AddSizeVar(out_cc, env) ) - { - out_cc->println("%s = %s;", - env->LValue(size_var()), - attr_length_expr_->EvalExpr(out_cc, env)); - env->SetEvaluated(size_var()); - } - return env->RValue(size_var()); - } - -string Type::DataSize(Output* out_cc, Env* env, const DataPtr& data) - { - if ( attr_length_expr_ ) - return EvalLengthExpr(out_cc, env); - - int ss = StaticSize(env); - if ( ss >= 0 ) - { - return strfmt("%d", ss); - } - else - { - if ( ! size_var() || ! env->Evaluated(size_var()) ) - { - ASSERT(out_cc != 0); - GenDynamicSize(out_cc, env, data); - ASSERT(size_var()); - } - return env->RValue(size_var()); - } - } - -void Type::GenBoundaryCheck(Output* out_cc, Env* env, - const DataPtr& data) - { - if ( boundary_checked() ) - return; - - data.GenBoundaryCheck(out_cc, env, - DataSize(out_cc, env, data).c_str(), - data_id_str_.c_str()); - - SetBoundaryChecked(); - } - -bool Type::NeedsCleanUp() const - { - switch ( tot_ ) - { - case EMPTY: - case BUILTIN: - return false; - case ARRAY: - case PARAMETERIZED: - case STRING: - return true; - default: - ASSERT(0); - return true; - } - return true; - } - -bool Type::RequiresByteOrder() const - { - return ! attr_byteorder_expr() && ByteOrderSensitive(); - } - -bool Type::NeedsBufferingStateVar() const - { - if ( !incremental_input() ) - return false; - switch ( buffer_mode() ) - { - case BUFFER_NOTHING: - case NOT_BUFFERABLE: - return false; - case BUFFER_BY_LINE: - return true; - case BUFFER_BY_LENGTH: - return ( attr_length_expr_ || attr_restofflow_ ); - default: - ASSERT(0); - return false; - } - } - -bool Type::DoTraverse(DataDepVisitor *visitor) - { - foreach (i, FieldList, fields_) - { - if ( ! (*i)->Traverse(visitor) ) - return false; - } - - foreach(i, AttrList, attrs_) - { - if ( ! (*i)->Traverse(visitor) ) - return false; - } - - return true; - } - -bool Type::RequiresAnalyzerContext() - { - ASSERT(0); - - if ( buffer_input() ) - return true; - - foreach (i, FieldList, fields_) - { - Field *f = *i; - if ( f->RequiresAnalyzerContext() ) - return true; - } - - foreach(i, AttrList, attrs_) - if ( (*i)->RequiresAnalyzerContext() ) - return true; - - return false; - } - -bool Type::IsEmptyType() const - { - return ( StaticSize(global_env()) == 0 ); - } - -void Type::MarkIncrementalInput() - { - DEBUG_MSG("Handle incremental input for %s.%s\n", - decl_id()->Name(), - value_var() ? value_var()->Name() : "*"); - - incremental_input_ = true; - if ( Bufferable() ) - buffer_input_ = true; - else - { - incremental_parsing_ = true; - DoMarkIncrementalInput(); - } - } - -void Type::DoMarkIncrementalInput() - { - throw Exception(this, "cannot handle incremental input"); - } - -bool Type::BufferableByLength() const - { - // If the input is an "frame buffer" with specified length - return attr_length_expr_ || attr_restofflow_; - } - -bool Type::BufferableByLine() const - { - // If the input is an ASCII line; - return attr_oneline_; - } - -bool Type::Bufferable() const - { - // If the input is an ASCII line or an "frame buffer" - return IsEmptyType() || BufferableByLength() || BufferableByLine(); - } - -Type::BufferMode Type::buffer_mode() const - { - if ( IsEmptyType() ) - return BUFFER_NOTHING; - else if ( BufferableByLength() ) - return BUFFER_BY_LENGTH; - else if ( BufferableByLine() ) - return BUFFER_BY_LINE; - return NOT_BUFFERABLE; - } - -const ID *Type::parsing_complete_var() const - { - if ( parsing_complete_var_field_ ) - return parsing_complete_var_field_->id(); - else - return 0; - } - -string Type::parsing_complete(Env *env) const - { - ASSERT(parsing_complete_var()); - return env->RValue(parsing_complete_var()); - } - -const ID *Type::has_value_var() const - { - if ( has_value_field_ ) - return has_value_field_->id(); - else - return 0; - } - -int Type::InitialBufferLength() const - { - if ( ! attr_length_expr_ ) - return 0; - return attr_length_expr_->MinimalHeaderSize(env()); - } - -bool Type::CompatibleTypes(Type *type1, Type *type2) - { - // If we cannot deduce one of the data types, assume that - // they are compatible. - if ( ! type1 || ! type2 ) - return true; - - // We do not have enough information about extern types - if ( type1->tot() == EXTERN || type2->tot() == EXTERN ) - return true; - - if ( type1->tot() != type2->tot() ) - { - if ( type1->IsNumericType() && type2->IsNumericType() ) - return true; - else - return false; - } - - switch( type1->tot() ) - { - case UNDEF: - case EMPTY: - return true; - case BUILTIN: - { - BuiltInType *t1 = - static_cast(type1); - BuiltInType *t2 = - static_cast(type2); - return BuiltInType::CompatibleBuiltInTypes(t1, t2); - } - - case PARAMETERIZED: - case RECORD: - case CASE: - case EXTERN: - return type1->DataTypeStr() == type2->DataTypeStr(); - break; - - case ARRAY: - { - ArrayType *t1 = - static_cast(type1); - ArrayType *t2 = - static_cast(type2); - return CompatibleTypes(t1->ElementDataType(), - t2->ElementDataType()); - } - - default: - ASSERT(0); - return false; - } - } - -Type *Type::LookUpByID(ID *id) - { - // 1. Is it a pre-defined type? - string name = id->Name(); - if ( type_map_.find(name) != type_map_.end() ) - { - return type_map_[name]->Clone(); - } - - // 2. Is it a simple declared type? - Type *type = TypeDecl::LookUpType(id); - if ( type ) - { - // Note: as a Type is always associated with a variable, - // return a clone. - switch ( type->tot() ) - { - case Type::BUILTIN: - case Type::EXTERN: - case Type::STRING: - return type->Clone(); - - case Type::ARRAY: - default: - break; - } - } - - return new ParameterizedType(id, 0); - } - -void Type::AddPredefinedType(const string &type_name, Type *type) - { - ASSERT(type_map_.find(type_name) == type_map_.end()); - type_map_[type_name] = type; - } - -void Type::init() - { - BuiltInType::static_init(); - ExternType::static_init(); - StringType::static_init(); - } diff --git a/aux/binpac/src/pac_type.def b/aux/binpac/src/pac_type.def deleted file mode 100644 index 62939ec671..0000000000 --- a/aux/binpac/src/pac_type.def +++ /dev/null @@ -1,8 +0,0 @@ -// TYPEDEF(type_id, pac_type, c_type, size) -TYPE_DEF(INT8, "int8", "int8", 1) -TYPE_DEF(INT16, "int16", "int16", 2) -TYPE_DEF(INT32, "int32", "int32", 4) -TYPE_DEF(UINT8, "uint8", "uint8", 1) -TYPE_DEF(UINT16, "uint16", "uint16", 2) -TYPE_DEF(UINT32, "uint32", "uint32", 4) -TYPE_DEF(EMPTY, "empty", "", 0) diff --git a/aux/binpac/src/pac_type.h b/aux/binpac/src/pac_type.h deleted file mode 100644 index 08252cf637..0000000000 --- a/aux/binpac/src/pac_type.h +++ /dev/null @@ -1,309 +0,0 @@ -#ifndef pac_type_h -#define pac_type_h - -#include -using namespace std; - -#include "pac_common.h" -#include "pac_datadep.h" -#include "pac_dbg.h" - -class Type : public Object, public DataDepElement -{ -public: - enum TypeType { - UNDEF = -1, - EMPTY, - BUILTIN, - PARAMETERIZED, - RECORD, - CASE, - ARRAY, - STRING, - EXTERN, - DUMMY, - }; - - explicit Type(TypeType tot); - virtual ~Type(); - - Type *Clone() const; - - // Type of type - TypeType tot() const { return tot_; } - - //////////////////////////////////////// - // Code generation - virtual void Prepare(Env *env, int flags); - - // Flag(s) for Prepare() - static const int TO_BE_PARSED = 1; - - virtual void GenPubDecls(Output *out, Env *env); - virtual void GenPrivDecls(Output *out, Env *env); - - virtual void GenInitCode(Output *out, Env *env); - virtual void GenCleanUpCode(Output *out, Env *env); - - void GenPreParsing(Output *out, Env *env); - void GenParseCode(Output *out, Env *env, const DataPtr& data, int flags); - - //////////////////////////////////////// - // TODO: organize the various methods below - - // The LValue string of the variable defined by the type. - // For example, if the type defines a record field, the - // lvalue is the member variable corresponding to the field; - // if the type appears in a type decl, then the lvalue is the - // default value var. - // - const char *lvalue() const { return lvalue_.c_str(); } - - // The TypeDecl that defined the type. - // - const TypeDecl *type_decl() const { return type_decl_; } - void set_type_decl(const TypeDecl *decl, bool declared_as_type); - - // Returns whether the type appears in a type declaration - // (true) or as type specification of a field (false). - // - bool declared_as_type() const { return declared_as_type_; } - - // The ID of the decl in which the type appear. - // - const ID *decl_id() const; - - Env *env() const { return env_; } - - string EvalByteOrder(Output *out_cc, Env *env) const; - - virtual string EvalMember(const ID *member_id) const; - virtual string EvalElement(const string &array, - const string &index) const; - - // The variable defined by the type - const ID *value_var() const { return value_var_; } - void set_value_var(const ID *arg_id, int arg_id_type); - - bool anonymous_value_var() const { return anonymous_value_var_; } - - const ID *size_var() const; - - // Adds a variable to env to represent the size of this type. - // Returns false if we do not need a size variable (because - // the type has a static size) or the size variable is already added. - bool AddSizeVar(Output *out, Env *env); - - const ID *parsing_state_var() const; - - const ID *has_value_var() const; - - void AddField(Field *f); - - void AddCheck(Expr *expr) { /* TODO */ } - - virtual bool DefineValueVar() const = 0; - - // Returns C++ datatype string - virtual string DataTypeStr() const = 0; - - // Returns const reference of the C++ data type (unless the type - // is numeric or pointer) - string DataTypeConstRefStr() const - { - string data_type = DataTypeStr(); - if ( ! IsPointerType() && ! IsNumericType() ) - data_type += " const &"; - return data_type; - } - - // Returns a default value for the type - virtual string DefaultValue() const - { - ASSERT(0); return "@@@"; - } - - // Returns the data type of the member field/case - virtual Type *MemberDataType(const ID *member_id) const; - - // Returns the data type of the element type of an array - virtual Type *ElementDataType() const; - - // Whether the type needs clean-up at deallocation. - bool NeedsCleanUp() const; - - // Whether byte order must be determined before parsing the type. - bool RequiresByteOrder() const; - - // Whether class of the type requires a parameter of analyzer context. - virtual bool RequiresAnalyzerContext(); - - virtual bool IsPointerType() const = 0; - virtual bool IsNumericType() const { return false; } - bool IsEmptyType() const; - - //////////////////////////////////////// - // Attributes - virtual void ProcessAttr(Attr *a); - - bool attr_chunked() const { return attr_chunked_; } - Expr *attr_byteorder_expr() const { return attr_byteorder_expr_; } - Expr *attr_if_expr() const { return attr_if_expr_; } - // TODO: generate the length expression automatically. - Expr *attr_length_expr() const { return attr_length_expr_; } - bool attr_refcount() const { return attr_refcount_; } - bool attr_transient() const { return attr_transient_; } - - // Whether the value remains valid outside the parse function - bool persistent() const - { - return ! attr_transient() && ! attr_chunked(); - } - - void SetUntilCheck(ArrayType *t) { array_until_input_ = t; } - - //////////////////////////////////////// - // Size and boundary checking - virtual int StaticSize(Env *env) const = 0; - string DataSize(Output *out, Env *env, const DataPtr& data); - - bool boundary_checked() const { return boundary_checked_; } - virtual void SetBoundaryChecked() { boundary_checked_ = true; } - void GenBoundaryCheck(Output *out, Env *env, const DataPtr& data); - - //////////////////////////////////////// - // Handling incremental input - // - // There are two ways to handle incremental input: (1) to - // buffer the input before parsing; (2) to parse incrementally. - // - // The type must be "bufferable" for (1). While for (2), - // each member of the type must be able to handle incremental - // input. - - void MarkIncrementalInput(); - virtual void DoMarkIncrementalInput(); - - // Whether the type may receive incremental input - bool incremental_input() const { return incremental_input_; } - - // Whether parsing should also be incremental - bool incremental_parsing() const { return incremental_parsing_; } - - // Whether we should buffer the input - bool buffer_input() const { return buffer_input_; } - - // Whether parsing of the type is completed - const ID *parsing_complete_var() const; - string parsing_complete(Env *env) const; - - // Whether the input is bufferable - bool Bufferable() const; - bool BufferableByLength() const; - bool BufferableByLine() const; - - enum BufferMode { - NOT_BUFFERABLE, - BUFFER_NOTHING, // for type "empty" - BUFFER_BY_LENGTH, - BUFFER_BY_LINE, - }; - virtual BufferMode buffer_mode() const; - - void GenBufferConfiguration(Output *out, Env *env); - - int InitialBufferLength() const; - -protected: - virtual void GenNewInstance(Output *out, Env *env) {} - - virtual bool ByteOrderSensitive() const = 0; - - bool NeedsBufferingStateVar() const; - - void GenBufferingLoop(Output* out_cc, Env* env, int flags); - void GenParseBuffer(Output* out_cc, Env* env, int flags); - void GenParseCode2(Output* out_cc, Env* env, const DataPtr& data, int flags); - void GenParseCode3(Output* out_cc, Env* env, const DataPtr& data, int flags); - - virtual void DoGenParseCode(Output *out, Env *env, - const DataPtr& data, - int flags) = 0; - - string EvalLengthExpr(Output* out_cc, Env* env); - - // Generate code for computing the dynamic size of the type - virtual void GenDynamicSize(Output *out, Env *env, - const DataPtr& data) = 0; - - bool DoTraverse(DataDepVisitor *visitor); - - virtual Type *DoClone() const = 0; - -protected: - TypeType tot_; - const TypeDecl *type_decl_; - bool declared_as_type_; - const ID *type_decl_id_; - Env *env_; - - const ID *value_var_; - bool anonymous_value_var_; // whether the ID is anonymous - - string data_id_str_; - int value_var_type_; - Field *size_var_field_; - char *size_expr_; - bool boundary_checked_; - string lvalue_; - FieldList *fields_; - - bool incremental_input_; - bool incremental_parsing_; - bool buffer_input_; - - // A boolean variable on whether parsing of the type is completed - Field *parsing_complete_var_field_; - - // An integer variable holding the parsing state - Field *parsing_state_var_field_; - - Field *buffering_state_var_field_; - - // The array type with &until($input...) condition, if - // "this" is the element type - ArrayType *array_until_input_; - - // A "has_*" member var for fields with &if - LetField *has_value_field_; - - // Attributes - AttrList *attrs_; - - Expr *attr_byteorder_expr_; - ExprList *attr_checks_; - bool attr_chunked_; - bool attr_exportsourcedata_; - Expr *attr_if_expr_; - Expr *attr_length_expr_; - FieldList *attr_letfields_; - Expr *attr_multiline_end_; - bool attr_oneline_; - bool attr_refcount_; - Expr *attr_requires_; - bool attr_restofdata_; - bool attr_restofflow_; - bool attr_transient_; - -public: - static void init(); - static bool CompatibleTypes(Type *type1, Type *type2); - static void AddPredefinedType(const string &type_name, Type *type); - static Type *LookUpByID(ID *id); - -protected: - typedef map type_map_t; - static type_map_t type_map_; -}; - -#endif // pac_type_h diff --git a/aux/binpac/src/pac_typedecl.cc b/aux/binpac/src/pac_typedecl.cc deleted file mode 100644 index c989869d20..0000000000 --- a/aux/binpac/src/pac_typedecl.cc +++ /dev/null @@ -1,409 +0,0 @@ -#include "pac_attr.h" -#include "pac_context.h" -#include "pac_dataptr.h" -#include "pac_embedded.h" -#include "pac_enum.h" -#include "pac_exception.h" -#include "pac_expr.h" -#include "pac_exttype.h" -#include "pac_id.h" -#include "pac_output.h" -#include "pac_param.h" -#include "pac_paramtype.h" -#include "pac_record.h" -#include "pac_type.h" -#include "pac_typedecl.h" -#include "pac_utils.h" - -TypeDecl::TypeDecl(ID* id, ParamList* params, Type* type) - : Decl(id, TYPE), params_(params), type_(type) - { - env_ = 0; - type_->set_type_decl(this, true); - } - -TypeDecl::~TypeDecl() - { - delete env_; - delete type_; - - delete_list(ParamList, params_); - } - -void TypeDecl::ProcessAttr(Attr* a) - { - type_->ProcessAttr(a); - } - -void TypeDecl::AddParam(Param *param) - { - // Cannot work after Prepare() - ASSERT(! env_); - params_->push_back(param); - } - -void TypeDecl::Prepare() - { - DEBUG_MSG("Preparing type %s\n", id()->Name()); - - if ( type_->tot() != Type::EXTERN && type_->tot() != Type::DUMMY ) - SetAnalyzerContext(); - - // As a type ID can be used in the same way function is, add the - // id as a FUNC_ID and set it as evaluated. - global_env()->AddID(id(), FUNC_ID, type_); - global_env()->SetEvaluated(id()); - - env_ = new Env(global_env(), this); - - foreach (i, ParamList, params_) - { - Param* p = *i; - // p->Prepare(env_); - type_->AddField(p->param_field()); - } - - if ( type_->attr_byteorder_expr() ) - { - DEBUG_MSG("Adding byteorder field to %s\n", - id()->Name()); - type_->AddField(new LetField(byteorder_id->clone(), - extern_type_int, - type_->attr_byteorder_expr())); - } - - type_->Prepare(env_, Type::TO_BE_PARSED); - } - -string TypeDecl::class_name() const - { - return id_->Name(); - } - -void TypeDecl::GenForwardDeclaration(Output* out_h) - { - // Do not generate declaration for external types - if ( type_->tot() == Type::EXTERN ) - return; - out_h->println("class %s;", class_name().c_str()); - } - -void TypeDecl::GenCode(Output* out_h, Output* out_cc) - { - // Do not generate code for external types - if ( type_->tot() == Type::EXTERN || type_->tot() == Type::STRING ) - return; - - fprintf(stderr, "Generating code for %s\n", class_name().c_str()); - - if ( RequiresAnalyzerContext::compute(type_) ) - { - DEBUG_MSG("%s requires analyzer context\n", - id()->Name()); - Type *param_type = analyzer_context()->param_type(); - env_->AddID(analyzer_context_id, TEMP_VAR, param_type); - env_->SetEvaluated(analyzer_context_id); - env_->AddMacro(context_macro_id, - new Expr(analyzer_context_id->clone())); - } - - // Add parameter "byteorder" - if ( type_->RequiresByteOrder() && ! type_->attr_byteorder_expr() ) - { - env_->AddID(byteorder_id, TEMP_VAR, extern_type_int); - env_->SetEvaluated(byteorder_id); - } - - vector base_classes; - - AddBaseClass(&base_classes); - - if ( type_->attr_refcount() ) - base_classes.push_back(kRefCountClass); - - // The first line of class definition - out_h->println(""); - out_h->print("class %s", class_name().c_str()); - bool first = true; - foreach(i, vector, &base_classes) - { - if ( first ) - { - out_h->print(" : public %s", i->c_str()); - first = false; - } - else - out_h->print(", public %s", i->c_str()); - } - out_h->print("\n"); - - // Public members - out_h->println("{"); - out_h->println("public:"); - out_h->inc_indent(); - - GenConstructorFunc(out_h, out_cc); - GenDestructorFunc(out_h, out_cc); - - if ( type_->attr_length_expr() ) - GenInitialBufferLengthFunc(out_h, out_cc); - - GenParseFunc(out_h, out_cc); - - out_h->println(""); - out_h->println("// Member access functions"); - type_->GenPubDecls(out_h, env_); - out_h->println(""); - - GenPubDecls(out_h, out_cc); - - out_h->dec_indent(); - out_h->println("protected:"); - out_h->inc_indent(); - - GenPrivDecls(out_h, out_cc); - type_->GenPrivDecls(out_h, env_); - - out_h->dec_indent(); - out_h->println("};\n"); - } - -void TypeDecl::GenPubDecls(Output* out_h, Output *out_cc) - { - // GenParamPubDecls(params_, out_h, env_); - } - -void TypeDecl::GenPrivDecls(Output* out_h, Output *out_cc) - { - // GenParamPrivDecls(params_, out_h, env_); - } - -void TypeDecl::GenInitCode(Output *out_cc) - { - } - -void TypeDecl::GenCleanUpCode(Output *out_cc) - { - } - -void TypeDecl::GenConstructorFunc(Output* out_h, Output* out_cc) - { - string params_str = ParamDecls(params_); - - string proto = - strfmt("%s(%s)", class_name().c_str(), params_str.c_str()); - - out_h->println("%s;", proto.c_str()); - - out_cc->println("%s::%s", class_name().c_str(), proto.c_str()); - out_cc->inc_indent(); - - out_cc->println("{"); - - // GenParamAssignments(params_, out_cc, env_); - - type_->GenInitCode(out_cc, env_); - GenInitCode(out_cc); - - out_cc->println("}\n"); - out_cc->dec_indent(); - } - -void TypeDecl::GenDestructorFunc(Output* out_h, Output* out_cc) - { - string proto = strfmt("~%s()", class_name().c_str()); - - out_h->println("%s;", proto.c_str()); - - out_cc->println("%s::%s", class_name().c_str(), proto.c_str()); - out_cc->inc_indent(); - out_cc->println("{"); - - GenCleanUpCode(out_cc); - type_->GenCleanUpCode(out_cc, env_); - - out_cc->println("}\n"); - out_cc->dec_indent(); - } - -string TypeDecl::ParseFuncPrototype(Env* env) - { - const char *func_name = 0; - const char *return_type = 0; - string params; - - if ( type_->incremental_input() ) - { - func_name = kParseFuncWithBuffer; - return_type = "bool"; - params = strfmt("flow_buffer_t %s", - env->LValue(flow_buffer_id)); - } - else - { - func_name = kParseFuncWithoutBuffer; - return_type = "int"; - params = strfmt("const_byteptr const %s, const_byteptr const %s", - env->LValue(begin_of_data), - env->LValue(end_of_data)); - } - - if ( RequiresAnalyzerContext::compute(type_) ) - { - Type *param_type = analyzer_context()->param_type(); - params += fmt(", %s %s", - param_type->DataTypeConstRefStr().c_str(), - env->LValue(analyzer_context_id)); - } - - // Add parameter "byteorder" - if ( type_->RequiresByteOrder() && ! type_->attr_byteorder_expr() ) - { - params += fmt(", int %s", env->LValue(byteorder_id)); - } - - // Returns " %s()%s". - return strfmt("%s %%s%s(%s)%%s", - return_type, func_name, params.c_str()); - } - -void TypeDecl::GenParsingEnd(Output *out_cc, Env *env, const DataPtr &data) - { - string ret_val_0, ret_val_1; - - if ( type_->incremental_input() ) - { - ret_val_0 = type_->parsing_complete(env).c_str(); - ret_val_1 = "false"; - } - else - { - ret_val_0 = type_->DataSize(0, env, data).c_str(); - ret_val_1 = "@@@"; - - out_cc->println("BINPAC_ASSERT(%s + (%s) <= %s);", - env->RValue(begin_of_data), - ret_val_0.c_str(), - env->RValue(end_of_data)); - } - - if ( type_->incremental_parsing() && - ( type_->tot() == Type::RECORD || type_->tot() == Type::ARRAY ) ) - { - // In which case parsing may jump to label - // "need_more_data" ... - out_cc->println("BINPAC_ASSERT(%s);", - type_->parsing_complete(env).c_str()); - out_cc->println("return %s;", ret_val_0.c_str()); - - out_cc->println(""); - out_cc->dec_indent(); - out_cc->println("%s:", kNeedMoreData); - out_cc->inc_indent(); - out_cc->println("BINPAC_ASSERT(!(%s));", - type_->parsing_complete(env).c_str()); - out_cc->println("return %s;", ret_val_1.c_str()); - } - else if ( type_->incremental_input() ) - { - out_cc->println("return %s;", ret_val_0.c_str()); - } - else - { - out_cc->println("return %s;", ret_val_0.c_str()); - } - } - -void TypeDecl::GenParseFunc(Output* out_h, Output* out_cc) - { - if ( type_->tot() == Type::DUMMY ) - return; - - // Env within the parse function - Env p_func_env(env_, this); - Env *env = &p_func_env; - - if ( type_->incremental_input() ) - { - env->AddID(flow_buffer_id, TEMP_VAR, extern_type_flowbuffer); - env->SetEvaluated(flow_buffer_id); - } - else - { - env->AddID(begin_of_data, TEMP_VAR, extern_type_const_byteptr); - env->AddID(end_of_data, TEMP_VAR, extern_type_const_byteptr); - - env->SetEvaluated(begin_of_data); - env->SetEvaluated(end_of_data); - } - - string proto; - proto = ParseFuncPrototype(env); - -#if 0 - if ( func_type == PARSE ) - { - out_h->println("// 1. If the message is completely parsed, returns number of"); - out_h->println("// input bytes parsed."); - out_h->println("// 2. If the input is not complete but the type supports"); - out_h->println("// incremental input, returns number of input bytes + 1"); - out_h->println("// (%s - %s + 1).", - env->LValue(end_of_data), - env->LValue(begin_of_data)); - out_h->println("// 3. An exception will be thrown on error."); - } -#endif - - out_h->println(proto.c_str(), "", ";"); - - out_cc->println(proto.c_str(), fmt("%s::", class_name().c_str()), ""); - out_cc->inc_indent(); - out_cc->println("{"); - - DataPtr data(env, 0, 0); - - if ( ! type_->incremental_input() ) - data = DataPtr(env, begin_of_data, 0); - type_->GenParseCode(out_cc, env, data, 0); - GenParsingEnd(out_cc, env, data); - - out_cc->println("}\n"); - out_cc->dec_indent(); - } - -void TypeDecl::GenInitialBufferLengthFunc(Output* out_h, Output* out_cc) - { - string func(kInitialBufferLengthFunc); - - int init_buffer_length = type_->InitialBufferLength(); - - if ( init_buffer_length < 0 ) // cannot be statically determined - { - throw Exception(type()->attr_length_expr(), - fmt("cannot determine initial buffer length" - " for type %s", id_->Name())); - } - - out_h->println("int %s() const { return %d; }", - func.c_str(), - init_buffer_length); - } - -Type* TypeDecl::LookUpType(const ID *id) - { - Decl *decl = LookUpDecl(id); - if ( ! decl ) - return 0; - switch ( decl->decl_type() ) - { - case TYPE: - case CONN: - case FLOW: - return static_cast(decl)->type(); - case ENUM: - return static_cast(decl)->DataType(); - default: - return 0; - } - } - diff --git a/aux/binpac/src/pac_typedecl.h b/aux/binpac/src/pac_typedecl.h deleted file mode 100644 index 37631af18e..0000000000 --- a/aux/binpac/src/pac_typedecl.h +++ /dev/null @@ -1,49 +0,0 @@ -#ifndef pac_typedecl_h -#define pac_typedecl_h - -#include "pac_decl.h" - -class TypeDecl : public Decl -{ -public: - TypeDecl(ID *arg_id, ParamList *arg_params, Type *arg_type); - ~TypeDecl(); - void Prepare(); - void GenForwardDeclaration(Output *out_h); - void GenCode(Output *out_h, Output *out_cc); - - Env *env() const { return env_; } - Type *type() const { return type_; } - string class_name() const; - static Type *LookUpType(const ID *id); - -protected: - void AddParam(Param *param); - virtual void AddBaseClass(vector *base_classes) const {} - void ProcessAttr(Attr *a); - - virtual void GenPubDecls(Output *out_h, Output *out_cc); - virtual void GenPrivDecls(Output *out_h, Output *out_cc); - virtual void GenInitCode(Output *out_cc); - virtual void GenCleanUpCode(Output *out_cc); - - void GenConstructorFunc(Output *out_h, Output *out_cc); - void GenDestructorFunc(Output *out_h, Output *out_cc); - - string ParseFuncPrototype(Env* env); - void GenParseFunc(Output *out_h, Output *out_cc); - - void GenParsingEnd(Output *out_cc, Env *env, const DataPtr &data); - - void GenInitialBufferLengthFunc(Output *out_h, Output *out_cc); - -protected: - Env *env_; - - ParamList *params_; - Type *type_; - - bool inherits_frame_buffer_; -}; - -#endif // pac_typedecl_h diff --git a/aux/binpac/src/pac_utils.cc b/aux/binpac/src/pac_utils.cc deleted file mode 100644 index a9118fc256..0000000000 --- a/aux/binpac/src/pac_utils.cc +++ /dev/null @@ -1,43 +0,0 @@ -// $Id: pac_utils.cc 3225 2006-06-08 00:00:01Z vern $ - -#include -#include -#include - -#include "pac_utils.h" - -char* copy_string(const char* s) - { - char* c = new char[strlen(s)+1]; - strcpy(c, s); - return c; - } - -namespace { - -const char* do_fmt(const char* format, va_list ap) - { - static char buf[1024]; - vsnprintf(buf, sizeof(buf), format, ap); - return buf; - } - -} - -string strfmt(const char* format, ...) - { - va_list ap; - va_start(ap, format); - const char* r = do_fmt(format, ap); - va_end(ap); - return string(r); - } - -char* nfmt(const char* format, ...) - { - va_list ap; - va_start(ap, format); - const char* r = do_fmt(format, ap); - va_end(ap); - return copy_string(r); - } diff --git a/aux/binpac/src/pac_utils.h b/aux/binpac/src/pac_utils.h deleted file mode 100644 index deef850245..0000000000 --- a/aux/binpac/src/pac_utils.h +++ /dev/null @@ -1,17 +0,0 @@ -// $Id: pac_utils.h 3225 2006-06-08 00:00:01Z vern $ - -#ifndef pac_utils_h -#define pac_utils_h - -#include -#include -using namespace std; - -char* copy_string(const char* s); -string strfmt(const char* fmt, ...); -char* nfmt(const char* fmt, ...); - -// const char* fmt(const char* fmt, ...); -#define fmt(x...) strfmt(x).c_str() - -#endif /* pac_utils_h */ diff --git a/aux/binpac/src/pac_varfield.cc b/aux/binpac/src/pac_varfield.cc deleted file mode 100644 index 76f36910f6..0000000000 --- a/aux/binpac/src/pac_varfield.cc +++ /dev/null @@ -1,6 +0,0 @@ -#include "pac_varfield.h" - -void PrivVarField::Prepare(Env *env) - { - Field::Prepare(env); - } diff --git a/aux/binpac/src/pac_varfield.h b/aux/binpac/src/pac_varfield.h deleted file mode 100644 index 8fea8879f9..0000000000 --- a/aux/binpac/src/pac_varfield.h +++ /dev/null @@ -1,51 +0,0 @@ -#ifndef pac_varfield_h -#define pac_varfield_h - -#include "pac_field.h" - -// A private variable evaluated with parsing -class ParseVarField : public Field -{ -public: - ParseVarField(int is_class_member, ID* id, Type *type) - : Field(PARSE_VAR_FIELD, - TYPE_TO_BE_PARSED | is_class_member | NOT_PUBLIC_READABLE, - id, type) {} - void GenPubDecls(Output* out, Env* env) { /* do nothing */ } -}; - -// A public variable -class PubVarField : public Field -{ -public: - PubVarField(ID* id, Type *type) - : Field(PUB_VAR_FIELD, - TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, - id, type) {} - ~PubVarField() {} -}; - -// A private variable -class PrivVarField : public Field -{ -public: - PrivVarField(ID* id, Type *type) - : Field(PRIV_VAR_FIELD, - TYPE_NOT_TO_BE_PARSED | CLASS_MEMBER | NOT_PUBLIC_READABLE, - id, type) {} - ~PrivVarField() {} - - void GenPubDecls(Output* out, Env* env) { /* do nothing */ } -}; - -class TempVarField : public Field -{ -public: - TempVarField(ID* id, Type *type) - : Field(TEMP_VAR_FIELD, - TYPE_NOT_TO_BE_PARSED | NOT_CLASS_MEMBER, - id, type) {} - ~TempVarField() {} -}; - -#endif // pac_varfield_h diff --git a/aux/binpac/src/pac_withinput.cc b/aux/binpac/src/pac_withinput.cc deleted file mode 100644 index 8c39053046..0000000000 --- a/aux/binpac/src/pac_withinput.cc +++ /dev/null @@ -1,80 +0,0 @@ -#include "pac_withinput.h" -#include "pac_dataptr.h" -#include "pac_expr.h" -#include "pac_inputbuf.h" -#include "pac_output.h" -#include "pac_type.h" - -WithInputField::WithInputField(ID* id, Type *type, InputBuffer* input) - : Field(WITHINPUT_FIELD, - TYPE_TO_BE_PARSED | CLASS_MEMBER | PUBLIC_READABLE, - id, type), - input_(input) - { - ASSERT(type_); - ASSERT(input_); - } - -WithInputField::~WithInputField() - { - delete input_; - } - -bool WithInputField::DoTraverse(DataDepVisitor *visitor) - { - return Field::DoTraverse(visitor) && - input()->Traverse(visitor); - } - -bool WithInputField::RequiresAnalyzerContext() const - { - return Field::RequiresAnalyzerContext() || - (input() && input()->RequiresAnalyzerContext()); - } - -void WithInputField::Prepare(Env* env) - { - Field::Prepare(env); - env->SetEvalMethod(id_, this); - } - -void WithInputField::GenEval(Output* out_cc, Env* env) - { - GenParseCode(out_cc, env); - if ( type_->attr_if_expr() ) - { - out_cc->println("BINPAC_ASSERT(%s);", - env->RValue(type_->has_value_var())); - } - } - -void WithInputField::GenParseCode(Output* out_cc, Env* env) - { - out_cc->println("// Parse \"%s\"", id_->Name()); - if ( type_->attr_if_expr() ) - { - // A conditional field - env->Evaluate(out_cc, type_->has_value_var()); - out_cc->println("if ( %s )", - env->RValue(type_->has_value_var())); - out_cc->inc_indent(); - out_cc->println("{"); - } - else - out_cc->println("{"); - - Env field_env(env, this); - ASSERT(! type_->incremental_input()); - type_->GenPreParsing(out_cc, &field_env); - type_->GenParseCode(out_cc, &field_env, - input()->GenDataBeginEnd(out_cc, &field_env), - 0); - - if ( type_->attr_if_expr() ) - { - out_cc->println("}"); - out_cc->dec_indent(); - } - else - out_cc->println("}"); - } diff --git a/aux/binpac/src/pac_withinput.h b/aux/binpac/src/pac_withinput.h deleted file mode 100644 index 18b086d61a..0000000000 --- a/aux/binpac/src/pac_withinput.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef pac_withinput_h -#define pac_withinput_h - -#include "pac_datadep.h" -#include "pac_decl.h" -#include "pac_field.h" - -class WithInputField : public Field, public Evaluatable -{ -public: - WithInputField(ID* id, Type *type, InputBuffer* input); - virtual ~WithInputField(); - - InputBuffer *input() const { return input_; } - - void Prepare(Env* env); - - // void GenPubDecls(Output* out, Env* env); - // void GenPrivDecls(Output* out, Env* env); - - // void GenInitCode(Output* out, Env* env); - // void GenCleanUpCode(Output* out, Env* env); - - void GenParseCode(Output* out, Env* env); - - // Instantiate the Evaluatable interface - void GenEval(Output* out, Env* env); - - bool RequiresAnalyzerContext() const; - -protected: - bool DoTraverse(DataDepVisitor *visitor); - -protected: - InputBuffer *input_; -}; - -#endif // pac_withinput_h diff --git a/aux/broccoli/AUTHORS b/aux/broccoli/AUTHORS deleted file mode 100644 index 7167bfcffc..0000000000 --- a/aux/broccoli/AUTHORS +++ /dev/null @@ -1,3 +0,0 @@ -Christian Kreibich and various contributors, -see ChangeLog for details. - diff --git a/aux/broccoli/COPYING b/aux/broccoli/COPYING deleted file mode 100644 index 265fcf14d4..0000000000 --- a/aux/broccoli/COPYING +++ /dev/null @@ -1,21 +0,0 @@ - -Broccoli is copyright (C) 2000-2009 Christian Kreibich . - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/aux/broccoli/ChangeLog b/aux/broccoli/ChangeLog deleted file mode 100644 index 8d5c52cf88..0000000000 --- a/aux/broccoli/ChangeLog +++ /dev/null @@ -1,1547 +0,0 @@ -Broccoli Changelog -======================================================================== - -Tue Jan 12 12:32:12 PST 2010 Christian - -- Build warning fixes (Kevin Lo). - ------------------------------------------------------------------------- - -Fri Oct 9 18:42:05 PDT 2009 Christian - -- Version bump to 1.5. - ------------------------------------------------------------------------- - -Fri Sep 25 10:09:03 PDT 2009 Christian - -- Bropipe fixes: set a connection class for robustness reasons; - removes some C/C++ confusion (Seth Hall). - ------------------------------------------------------------------------- - -Mon Jun 29 17:56:00 PDT 2009 Christian - -- SWIG bindings update. - ------------------------------------------------------------------------- - -Mon Jun 29 15:29:35 PDT 2009 Christian - -- Support for sending raw serialized events via the new API function - bro_event_send_raw(), with much help from Matthias Vallentin. - ------------------------------------------------------------------------- - -Mon Jun 29 15:20:58 PDT 2009 Christian - -- Fix for buffered data remaining in transmit buffer when calling - for_event_queue_flush(). - -- Added bro_conn_get_connstats() which reports statistical information - about a connection in a new dedicated structure BroConnStats. For now - this is only the amount of data buffered in the rx/tx buffers. - ------------------------------------------------------------------------- - -Mon Jun 29 15:18:10 PDT 2009 Christian - -- All multiprocess/-threading synchronization code has been removed. - ------------------------------------------------------------------------- - -Mon Jun 29 15:10:59 PDT 2009 Christian - -- Broccoli now requires initialization before any connections may be - created. The reason is twofold: (i) it provides a clean method for - initializing relevant parts of Broccoli in multithreaded environments, - and (ii) it allows configuration of parts of Broccoli where the - normal approach via configuration files is insufficient. - - For details on the initialization process, refer to the manual, but - generally speaking, a call to - - bro_init(NULL); - - at the beginning of your application is all that is required. For the - time being, a number of high-level API calls double-check whether you - have called bro_init() previously. - -- Broccoli now supports the callback functions OpenSSL requires for - thread-safe operation. Implement those callbacks as required by your - threading library, hook them into a BroCtx structure previously - initialized using bro_ctx_init(), and pass the structure to - bro_init(). This will hook the callbacks into OpenSSL for you. - - O'Reilly's book "Network Security with OpenSSL" provides an example - of how to implement the callbacks. - ------------------------------------------------------------------------- - -Thu Jun 25 16:46:37 PDT 2009 Christian - -- Fix to Python bindings: added required bro_init() call (Matthias - Vallentin). - ------------------------------------------------------------------------- - -Thu May 28 10:27:30 PDT 2009 Christian - -- The BroEvMeta structure used in compact event callbacks now allows - access to the timestamp of event creation. - ------------------------------------------------------------------------- - -Fri Mar 27 23:39:10 CET 2009 Christian - -- Fixed a memory leak triggered by bro_event_send() but actually caused - by lack of cleanup after an underlying string duplication. Thanks to - Steve Chan and Matthias Vallentin for helpful feedback. - ------------------------------------------------------------------------- - -Wed Mar 25 11:26:16 CET 2009 Christian - -Formatting robustness fixes to bropipe (Steve Chan). - ------------------------------------------------------------------------- - -Thu Feb 12 19:28:24 PST 2009 Christian - -- Updates to contributed bropipe command (Steve Chan): - - Proper parsing of default host/port. - - Support for "urlstring" type, which urlencodes spaces in strings - and other special characters. - ------------------------------------------------------------------------- - -Thu Dec 11 09:37:12 PST 2008 Christian - -- Optimization: the internal slots vector of hashtables is now lazily - allocated when the first actual insertion happens. Since hashtables - are used in various places in the BroVal structures but frequently - remain empty, the savings are substantial. Thanks to Matthias - Vallentin for pointing this out. - ------------------------------------------------------------------------- - -Mon Nov 3 11:07:49 PST 2008 Christian - -- Fixes for I/O deadlocking problems: - - - A bug in the implementation of BRO_CFLAG_YIELD has been - fixed. Input processing now only yields after the - handshake is complete on *both* endpoints. - - - When events arrive during bro_conn_connect(), it could happen - that deadlock ensues if no additional data are sent and - __bro_io_process_input() can not read new input data. It no - longer returns immediately in that case, and instead attempts - to process any available input data. - ------------------------------------------------------------------------- - -Sat Oct 4 15:05:07 CEST 2008 Christian - -- Added bro_record_get_nth_name() to the API (Seth Hall). -- make install no longer worked for documentation, apparently as part - of Bro's make install cleanup. This isn't quite right since gtk-doc - documentation is normally installed in a well-known place and - Broccoli will normally need to be installed via "make install", but - for now I'm leaving it uninstalled and instead provide a specific - "install-docs" target for people who want documentation installed. -- Documentation updated where missing, and rebuilt. -- Copyright years updated. - ------------------------------------------------------------------------- - -Mon Sep 22 21:34:13 CEST 2008 Christian - -- Updated broping.bro (and broping-record.bro, slightly) to explicitly - declare the used event types ahead of their use. - ------------------------------------------------------------------------- - -Mon Sep 8 11:30:35 CEST 2008 Christian - -- Use of caching on received objects is now disabled by default, but can - be enabled using the new connection flag BRO_CFLAG_CACHE. The old - BRO_CFLAG_DONTCACHE is kept for backward compatibility but no longer - does anything. Keeping the caches between Bro instances and Broccoli - synchronized still needs to be implemented completely, and in the - meantime no caching is the safer default. Thanks to Stephen Chan for - helping track this down. - ------------------------------------------------------------------------- - -Wed Jul 16 01:47:16 PDT 2008 Christian - -- Python bindings for Broccoli are now provided in the bindings/python - subdirectory (Robin Sommer). They are not built automatically. See - the instructions in bindings/python/README for details. -- Minor documentation setup tweaks. - ------------------------------------------------------------------------- - -Thu May 15 14:05:10 PDT 2008 Christian - -Event callbacks of the "compact" type are now able to obtain start- and -end pointers of the currently processed event in serialized form, from -the receive buffer stored with the connection handle. - ------------------------------------------------------------------------- - -Wed Feb 20 13:53:51 PST 2008 Christian - -- Fix to __bro_openssl_read(), which handled some error cases - reported by BIO_read() incorrectly. (Robin Sommer) -- Clarifications to documentation of bro_conn_active() and - bro_conn_process_input(). -- Version bump to 1.4.0. - ------------------------------------------------------------------------- - -Thu Sep 13 13:56:58 PDT 2007 Christian - -- autogen.sh now uses --force when running libtoolize, which at least - in some setups seems to be necessary to avoid bizarre build issues. - (In the particular case encountered, these looked like run-together - ar and runlib invocations). Thanks to Po-Ching Lin for helping nail - this down. - ------------------------------------------------------------------------- - -Mon Sep 10 18:17:29 PDT 2007 Christian - -- Broccoli now supports table and set container types. Have a look at - the bro_table_...() and bro_set_...() families of functions in - broccoli.h, the updated manual, and the updated broconn and brotable - examples in the test/ directory. - ------------------------------------------------------------------------- - -Tue Sep 4 15:53:27 PDT 2007 Christian - -- Major bugfix for capabilities exchange during handshake: Broccoli did - not convert into NBO, causing successful event exchange to fail. :( - Amazingly, this means disabling cache usage per Broccoli's request - never worked... - ------------------------------------------------------------------------- - -Tue Sep 4 12:36:53 PDT 2007 Christian - -- Changed the way compact argument passing to event callbacks works. - All event metadata is now represented by a single argument, a pointer - to a BroEvMeta structure. It contains the name of the event, the - number of arguments, and the arguments along with their types. - - Updated documentation and broping demo accordingly. - - NOTE: This introduces an API incompatibility. If you were previously - using the compact callback API, you will need to update your - code! I bumped up the library version info to 2:0:0 to signal - this. - -- Fixed a bug in the implementation of BRO_CFLAG_YIELD and some SGML- - violating documentation of same. - ------------------------------------------------------------------------- - -Thu Aug 16 15:24:51 CEST 2007 Christian - -- Include autogen.sh in the distribution. - ------------------------------------------------------------------------- - -Sat Aug 11 04:59:35 PDT 2007 Robin - -- New flag for Broccoli's connections: with BRO_CFLAG_YIELD, - bro_conn_process_input() processes at most one event at a time and then - returns (Robin Sommer). - -- The new Broccoli function bro_conn_new_socket() creates a connection - from an existing socket, which can then be used with listen()/accept() - to have Broccoli listen for incoming connections (Robin Sommer). - ------------------------------------------------------------------------- - -Fri Jul 6 18:18:05 PDT 2007 Christian - -- Bumped up the version number to 1.3. Now that Broccoli is bundled - with Bro, it makes sense to keep Broccoli's release version number - in synch with Bro's. -- Added the automake-provided ylwrap wrapper script to the distribution. - This is for compatibility reasons: some automakes believe that - Broccoli requires ylwrap, others don't. The distcheck target however - needs ylwrap when it *is* required, so it's easiest to just provide - one. It can always be overwritten locally, should the need arise. - ------------------------------------------------------------------------- - -Wed Mar 7 10:49:25 PST 2007 Christian - -- Data format version number bumped up, in sync with Bro again. - ------------------------------------------------------------------------- - -Mon Dec 4 12:07:12 PST 2006 Christian - -- Updated broconn.c to new bro_record_get_named_val(). - ------------------------------------------------------------------------- - -Tue Nov 28 11:16:04 PST 2006 Christian - -- Run-time type information is now also available for the values stored - in records (previously there was only type-checking, but no way to - obtain the type of the vals). See the manual and API documentation of - the functions bro_record_get_nth_val() and bro_record_get_named_val() - for details. - ------------------------------------------------------------------------- - -Mon Nov 27 18:38:06 PST 2006 Christian - -- Compact argument passing for event callbacks: as an alternative to the - argument passing style used so far for event callbacks (dubbed "expan- - ded"), one can now request "compressed" passing by using the - bro_event_registry_add_compact() variant. Instead of passing every - event argument as a separate pointer, compact passing provides only - the number of arguments, and a pointer to an array of BroEvArgs. - The elements of this array then provide pointers to the actual argu- - ments as well as pointers to the new BroValMeta metadata structure, - which currently contains type information about the argument. - - This style is better suited for applications that don't know the type - of events they will have to handle at compile time, for example when - writing language bindings. - - broping.c features example code, also see the manual for detailed - explanation. - ------------------------------------------------------------------------- - -Mon Nov 27 16:32:52 PST 2006 Christian - -- Bumped up version to 0.9 -- I'm starting to use shared library version numbers to indicate API - changes. Their correspondence to the release version number will be - listed in VERSION. -- Fixed a warning in bro_packet.c - ------------------------------------------------------------------------- - -Mon Nov 27 16:23:46 PST 2006 Christian - -- Renamed cvs.pl to svn.pl -- Bumped up BRO_DATA_FORMAT_VERSION to 13, to match that of Bro trunk. - ------------------------------------------------------------------------- - -Mon Nov 27 16:21:28 PST 2006 Christian - -- Updating my commit script to SVN -- let's see if this works... - ------------------------------------------------------------------------- - -Mon May 15 19:21:30 BST 2006 Christian - -- Correction to the explanation of bro_event_registry_add(), pointed - out by Robin Sommer. - ------------------------------------------------------------------------- - -Mon May 8 08:14:31 PDT 2006 Christian - -- Added config.sub and config.guess versions that seem to work well with - MacOS X to the tree, to remove the dependency on the libtool/automake - versions installed on the machine where tarballs are built. - -- Removed -f from libtoolize invocation in autogen.sh, so we don't - overwrite the above. - -- Fixed COPYING, which wasn't actually referring to Broccoli. :) - ------------------------------------------------------------------------- - -Sat May 6 20:17:32 BST 2006 Christian - -- Last-minute tweaks bring last-minute brokenness, especially when - configuring without --enable-debug... :( - ------------------------------------------------------------------------- - -Tue May 2 13:25:31 BST 2006 Christian - -- Added generated HTML documentation to CVS, so it is guaranteed to be - included in tarballs generated via dist/distcheck, regardless of - whether GtkDoc support exists on the build system or not. - ------------------------------------------------------------------------- - -Tue May 2 02:31:39 BST 2006 Christian - -- Changed connection setup debugging output to state more clearly - whether an SSL or cleartext connection is attempted, as suggested - by Brian Tierney. -- New configuration item /broccoli/use_ssl to enable/disable SSL - connections, as suggested by Jason Lee. Documentation and sample - configuration in broccoli.conf updated accordingly, look at the latter - for a quick explanation. -- A bunch of small tweaks to get distcheck to work properly when invoked - from the Bro tree. -- Other doc/Makefile.am cleanups. - ------------------------------------------------------------------------- - -Sat Apr 29 19:12:07 PDT 2006 Christian - -- Fixed bogusness in docs/Makefile.am's dist-hook target. Should now - work much better in general, and in particular not bomb out with - non-GNU make. - ------------------------------------------------------------------------- - -Fri Apr 7 23:52:20 BST 2006 Christian - -- Bumped up BRO_DATA_FORMAT_VERSION to 12, to match the one in Bro's - CVS HEAD again. - ------------------------------------------------------------------------- - -Mon Mar 27 22:59:04 BST 2006 Christian - -- This should fix a memleak detected by Jim Mellander and reported with - a test case by Mark Dedlow. - ------------------------------------------------------------------------- - -Fri Mar 3 16:40:56 GMT 2006 Christian - -- Warning for invalid permissions on ~/.broccoli.conf has been upgraded - from debugging output to stderr, per request from Mark Dedlow. -- Only check validity of config file name assembled via getenv("HOME") - if it yields a filename different from the one assembled via the - passwd entry. - ------------------------------------------------------------------------- - -Thu Mar 2 17:57:49 GMT 2006 Christian - -- Reintroducing file needed for distcheck. - ------------------------------------------------------------------------- - -Thu Mar 2 16:27:55 GMT 2006 Christian - -- Debugging fixlet. - ------------------------------------------------------------------------- - -Fri Feb 3 20:31:08 GMT 2006 Christian - -- Embarrassing debugging output fixes. - ------------------------------------------------------------------------- - -Fri Jan 27 23:40:23 GMT 2006 Christian - -- Only do lock operations when there's any need for them. - ------------------------------------------------------------------------- - -Fri Jan 27 18:30:06 GMT 2006 Christian - -I am *so* fired. Overlooked a very clear warning that bro_io.c:lock() -wasn't returning a value. - ------------------------------------------------------------------------- - -Wed Jan 18 10:45:33 GMT 2006 Christian - -- Fixed call trace debugging inconsistencies, this will hopefully fix a - case of runaway call trace indentation depth that Robin + Stefan have - bumped into. - ------------------------------------------------------------------------- - -Wed Jan 4 16:21:07 GMT 2006 Christian - -- Documentation fixlet, pointed out by Stefan Kornexl. - ------------------------------------------------------------------------- - -Thu Dec 22 00:48:20 GMT 2005 Christian - -- Attempt at a more portable detecting of [g]libtoolize. Let me know if - this works any better. - ------------------------------------------------------------------------- - -Mon Dec 19 17:48:19 PST 2005 Christian - -- Moved brosendpkts.c and rcvpackets.bro from test/ to contrib/, i.e., - out of the default build process. brosendpkts.c defines variables in - the middle of main(), which some compilers tolerate while others - don't. This should fix build issues reported by Brian Tierney. - ------------------------------------------------------------------------- - -Thu Dec 15 18:38:18 GMT 2005 Christian - -Configuration tweaks to run smoothly when invoked from a Bro build. - -- Added AC_CONFIG_AUX_DIR(.) to make sure things are exclusively run - out of our tree. -- Added flags to autogen.sh and configure.in to indicate that we're - part of a Bro build. - ------------------------------------------------------------------------- - -Fri Dec 2 14:04:05 GMT 2005 Christian - -- Removed EXTRA_DIST for the test app policies, since they are included - in the tarball and installed anyway via pkgdata_DATA. - ------------------------------------------------------------------------- - -Fri Dec 2 13:59:27 GMT 2005 Christian - -- Added "brosendpkts", a test program for sending pcap packets to a Bro, - plus the accompanying Bro policy. Contributed by Stefan Kornexl and - Robin Sommer, with a tiny tweak to build only when pcap support is - available. - ------------------------------------------------------------------------- - -Wed Nov 23 11:59:03 PST 2005 Christian - -- Avoided the keyword "class" to prevent problems with using broccoli.h - in a C++ context. Pointed out by Stefan Kornexl. - ------------------------------------------------------------------------- - -Tue Nov 8 14:10:23 PST 2005 Christian - -- Added support for connection classes, updated documentation. - ------------------------------------------------------------------------- - -Mon Oct 31 19:37:55 PST 2005 Christian - -- Support for specifying type names along with values. This is done -through a new and optional argument to bro_event_add_val(), bro_ -record_add_val(), and friends. See manual for details. - -- Added a test program "broenum" for demonstrating this. When running -Bro with the provided broenum.bro policy, it sends a single event with -an enum val to the remote Bro, which will print both numerical and -string representations of the value. For example, broenum.bro defines -an enum type - - type enumtype: enum { ENUM1, ENUM2, ENUM3, ENUM4 }; - -Given this, - - $ broenum -n 0 yields Received enum val 0/ENUM1 - $ broenum -n 1 yields Received enum val 1/ENUM2 - $ broenum -n 4 yields Received enum val 4/ - -You can also test predefined enums: - - $ broenum -t transport_proto -n 1 - -yields - - Received enum val 1/tcp - ------------------------------------------------------------------------- - -Mon Oct 31 17:07:15 PST 2005 Christian - -Changed commit script to pass the commit message through the generated -file via -F, instead of via -m and the command line. D'oh. - ------------------------------------------------------------------------- - -Mon Oct 31 17:03:47 PST 2005 Christian - -- Support for the new abbreviated serialization format for types. Need -to come up with a decent API for actually using this feature now. - ------------------------------------------------------------------------- - -Mon Oct 31 11:25:22 PST 2005 Christian - -Several changes to handshake implementation and API(!). - -- Refactored the handshake code to make the multiple phases of the -connection's initialization phase more explicit. Our own and the peer's -handshake state are now tracked separately. conn_init_configure() takes -care of our state machine with a separate function per phase, and -__bro_io_process_input() handles the peer's state. - -- Added support for capabilities. The only capability Broccoli currently -supports is a non-capability: it can ask the remote Bro not to use the -serialization cache. In order to do so, pass BRO_CONN_DONTCACHE as -a connection flag when obtaining the connection handle. Needs more -testing. - -- Several API changes. Given the more complex handshake procedure that -is in place now, the old approach of only completing the handshake half- -way in bro_connect() so the user can requests before calling -bro_conn_await_handshake() (or alternatively, passing -BRO_CONN_COMPLETE_HANDSHAKE as a connection flag) is just too messy now. -The two steps of obtaining a connection handle and establishing a -connection have been split into separate functions, so the user can -register event handlers in between. - -What was - - BroConn *bc = bro_connect(..., BRO_CFLAGS_NONE); - - bro_event_registry_add(bc,...); - bro_event_registry_add(bc,...); - bro_event_registry_request(bc); - - bro_conn_await_handshake(bc); - /* ... */ - bro_disconnect(bc); - -is now - - BroConn *bc = bro_conn_new(..., BRO_CFLAGS_NONE); - - bro_event_registry_add(bc,...); - bro_event_registry_add(bc,...); - - bro_conn_connect(bc); - /* ... */ - bro_conn_delete(bc); - -Note that the explicit call to bro_event_registry_request() is gone as -bro_conn_connect() will automatically request event types for which -handlers have been installed via bro_event_registry_add(). What was - - BroConn *bc = bro_connect(..., BRO_CFLAGS_COMPLETE_HANDSHAKE); - bro_disconnect(bc); - -is now - - BroConn *bc = bro_conn_new(..., BRO_CFLAGS_NONE); - bro_conn_connect(bc); - /* ... */ - bro_conn_delete(bc); - -I might add bro_conn_disconnect() in the near future. It'd allow us -to keep a completely configured connection handle around and use it -repeatedly for establishing connections. - -Sorry for the inconvenience but I really think this is a lot nicer than -the old API. The examples and documentation have been updated accor- -dingly. - ------------------------------------------------------------------------- - -Sat Oct 29 15:43:18 PDT 2005 Christian - -Added an optional age list to the hash table implementation. We'll -need this to duplicate Bro's object serialization caching strategy. - ------------------------------------------------------------------------- - -Fri Oct 28 15:26:55 PDT 2005 Christian - -Brothers and sisters, hallelujah! On the 27th day Christian looked at -record vals in the Broccoli, and he saw that it was leaking like a -sieve. So Christian ran the valgrind. On the 28th day Christian still -looked at Broccoli, with tired eyes, ground the vals[1] a bit more, -and he saw that it was plugged[2]. - -Amen. :) - -[1] Really really bad pun. Sorry. -[2] I get zero memleaks on broping -r -c 100 now. :) - ------------------------------------------------------------------------- - -Thu Oct 27 20:02:39 PDT 2005 Christian - -First crack at reference-counted sobjects. I need reference counting -in order to get rid of objects in the serialization cache (since they -can contain nested objects etc -- it's nasty), which I had ignored so -far. There are still leaks in the event transmission code, dammit. :( - ------------------------------------------------------------------------- - -Thu Oct 27 15:06:10 PDT 2005 Christian - -Added my own list implementation due to suckiness of the TAILQ_xxx -macro stuff which I never liked anyway. The problem is that elements -of lists built using these macros can only have each member exactly -once as the prev/next pointers are part of the structs. - -A few uses of TAILQ_xxx remain, these will go in the near future. - ------------------------------------------------------------------------- - -Tue Oct 25 19:57:42 PDT 2005 Christian - -Partial support for enum vals, per request from Weidong. Sending enum -vals should work, though the underlying enum types aren't fully handled -yet. - ------------------------------------------------------------------------- - -Mon Oct 24 16:31:56 PDT 2005 Christian - -TODO item: clean up generated parser/lexer files when we know we can -regenerate them. make clean currently does not erase them, which caused -Weidong some trouble. - ------------------------------------------------------------------------- - -Fri Oct 21 17:48:51 PDT 2005 Christian - -Clarification to the manual, after a question from Weidong. - ------------------------------------------------------------------------- - -Fri Oct 14 18:05:39 PDT 2005 Christian - -Transparent reconnects should work again (took all *day*, argh -- I -totally broke it with the connection sharing stuff). Try broping while -occasionally stopping and restarting the Bro side. - -Fixed a number of memleaks -- broping is now leak-free according to -valgrind. - -Clarifications in the debugging output. - ------------------------------------------------------------------------- - -Fri Oct 14 12:07:10 PDT 2005 Christian - -Added documentation for the new user data argument to -bro_event_registry_add(). - ------------------------------------------------------------------------- - -Fri Oct 14 11:48:00 PDT 2005 Christian - -Added user data to event handler callbacks. This is necessary for -example when using class members in C++ as callbacks since the object -needs to be provided at the time of dereferencing. It's also easier to -use than the existing bro_conn_{set,get}_data() mechanism. - -Updated documentation with more details on the broccoli-config script. - ------------------------------------------------------------------------- - -Thu Oct 13 15:08:56 PDT 2005 Christian - -When supporting packets (the default), check whether pcap.h actually -exists. This has thus far just been assumed. We don't actually use -the library, so there's no need to test for it. - ------------------------------------------------------------------------- - -Mon Oct 10 20:37:15 PDT 2005 Christian - -Changed bro_record_get_named_val() and bro_record_get_nth_val() to -return a pointer to the queried value directly, instead of through -a pointer argument. These arguments' type used to be void* though it -should really be void**, but switching to void** causes lots of warnings -with current GCCs ('dereferencing type-punned pointer will break -strict-aliasing rules'). NULL is perfectly usable as an error indicator -here, and thus used from now on. Updated manual, broping, and broconn -accordingly. - ------------------------------------------------------------------------- - -Tue Sep 20 17:19:58 PDT 2005 Christian - -Fixed a varargs buglet that is tolerated on Linux but not BSD. Pointed -out by Scott Campbell. - ------------------------------------------------------------------------- - -Fri Sep 9 18:48:54 PDT 2005 Christian - -Support for textual tags on packets, also an upgrade to more complex -handshake procedure that allows for synchronization of state (Robin -Sommer). - -Note: as of this change, at least Bro 1.0a2 is required. - ------------------------------------------------------------------------- - -Wed Aug 10 01:36:47 BST 2005 Christian - -Fixed my insecure usage of snprintf. - ------------------------------------------------------------------------- - -Tue Jul 19 10:11:49 PDT 2005 Christian - -Forgot to include broconn's policy file in the distribution. - ------------------------------------------------------------------------- - -Mon Jul 18 16:34:22 PDT 2005 Christian - -Fixed a bug that caused the lookup of record fields by name to fail. - ------------------------------------------------------------------------- - -Fri Jul 1 00:44:49 BST 2005 Christian - -The sequence of tests determining which config file to read from -failed to fall back properly to the global config file in case of -incorrect user permissions. Fixed. - ------------------------------------------------------------------------- - -Mon Jun 27 19:34:56 PDT 2005 Christian - -Added bro_buf_reset() to the user-visible API. - ------------------------------------------------------------------------- - -Mon Jun 27 17:58:53 PDT 2005 Christian - -When a configuration item cannot be found in the current config file -section, a lookup is also attempted in the default section (the one -at the top of the file, before any sections are defined). This allows -the sections to override the default section, which is what one would -expect. - ------------------------------------------------------------------------- - -Mon Jun 27 14:43:56 PDT 2005 Christian - -Debugging output tweak. When providing the SSL cert passphrase via -the config file, do no longer report it in the debugging output. - ------------------------------------------------------------------------- - -Mon Jun 27 12:33:52 PDT 2005 Christian - -Cosmetics in the debugging output of __bro_openssl_write(). - ------------------------------------------------------------------------- - -Fri Jun 24 18:13:49 PDT 2005 Christian - -Added --build flag to broccoli-config. It reports various details -about the build, for example whether debugging support was compiled in. - ------------------------------------------------------------------------- - -Fri Jun 24 10:37:23 PDT 2005 Christian - -I'm adding a little test app that subscribes to a few connection -events and prints out the fields of the received connection records, -both for testing and code demonstration purposes. So far it has -highlighted a bug in Bro that occurs when a remote app is a pure -requester of events and not sending anything. Fix pending. - ------------------------------------------------------------------------- - -Mon Jun 20 18:21:24 PDT 2005 Christian - -Show the names of requested events in the debugging output -- it -had to be deciphered from the hex string which isn't that much fun. - ------------------------------------------------------------------------- - -Thu Jun 16 14:02:59 PDT 2005 Christian - -Better documentation of how to extract record fields. - ------------------------------------------------------------------------- - -Thu Jun 16 11:51:02 PDT 2005 Christian - -- Added bro_string_get_data() and bro_string_get_length() to avoid -making people access BroString's internal fields directly. - -- Moved BroString's internal storage format to uchar*. - ------------------------------------------------------------------------- - -Sun Jun 12 19:17:31 PDT 2005 Christian - -Debugging output now shows the correct function and line numbers again. -I had accidentially moved __FUNCTION__ and __LINE__ into bro_debug.c :( - ------------------------------------------------------------------------- - -Fri Jun 3 15:00:48 PDT 2005 Christian - -I broke the sanity checks for semaphore initialization when I moved -the semaphore structures to shared memory. Fixed. - ------------------------------------------------------------------------- - -Mon May 16 22:25:41 PDT 2005 Christian - -- Debugging output now goes to stderr instead of stdout. That keeps it -out of the way if an instrumented app dups() stdout to another file -descriptor. -- Debugging output is now disabled by default (even when compiled in), -so it needs to be enabled explicitly in the code or in the config file. - ------------------------------------------------------------------------- - -Fri May 13 18:24:23 PDT 2005 Christian - -Synchronization fixes and minor cleanups. - -- Unsuccessful connection attempts to remote Bros in combination with -connection sharing caused the caller to hang indefinitely. This should -now be fixed, but required some fairly intricate tweaks to the locking -constructs. Still needs more testing. - -- Bumped version to 0.8. - ------------------------------------------------------------------------- - -Fri May 6 23:09:29 BST 2005 Christian - -This is the 0.7.1 release. - ------------------------------------------------------------------------- - -Fri May 6 14:44:53 PDT 2005 Christian - -Documentation for shareable connection handles. - ------------------------------------------------------------------------- - -Fri May 6 12:11:17 PDT 2005 Christian - -Build fixlets. - -- Don't only test for the first of the documentation extraction tools, -but also for those used later on. - -- Few more signedness warnings fixed. - ------------------------------------------------------------------------- - -Wed May 4 18:33:40 PDT 2005 Christian - -Fixed a whole bunch of signedness warnings reported by gcc 4 on MacOS -10.4. Thanks to Roger for the quick reply. - ------------------------------------------------------------------------- - -Wed May 4 17:41:40 PDT 2005 Christian - -Fix for a little-endian bug that I managed to introduce when testing on -Solaris ... *sigh* :( - ------------------------------------------------------------------------- - -Wed May 4 17:30:07 PDT 2005 Christian - -A number of portability fixes after testing the build on Linux, FreeBSD -and Solaris. - ------------------------------------------------------------------------- - -Mon May 2 20:17:04 PDT 2005 Christian - -Fixed an obvious bug the config file parser. I'm baffled as to how it -could go unnoticed for so long. - ------------------------------------------------------------------------- - -Mon May 2 20:11:25 PDT 2005 Christian - -Portability fixes. - -- Use -pthread (not -lpthread) in both the --cflags and --libs options -to broccoli-config, if required. -lpthread does not work on BSDs, where --pthread has different effects on the linker. - -- s/System V/SYSV/ in configure script output for consistency. - -- Bumped version to 0.7.1. - -It should build correctly on BSDs and Linux now. Still need to check -whether synchronization actually works on the BSDs. - ------------------------------------------------------------------------- - -Fri Apr 29 23:12:01 BST 2005 Christian - -If the configure script determines we need -lpthread, it's a good idea -to actually reflect that in broccoli-config. - ------------------------------------------------------------------------- - -Fri Apr 29 22:36:26 BST 2005 Christian - -Fix for SYSV semaphores pointed out by Craig Leres -- I completely -forgot to test the SYSV stuff before the release. *sigh*. - ------------------------------------------------------------------------- - -Thu Apr 28 13:46:57 BST 2005 Christian - -- This is the 0.7 release. - ------------------------------------------------------------------------- - -Thu Apr 28 13:43:44 BST 2005 Christian - -RPM spec file fixlet. - ------------------------------------------------------------------------- - -Wed Apr 27 18:04:57 BST 2005 Christian - -Preparations for the 0.7 release. - ------------------------------------------------------------------------- - -Wed Mar 16 18:34:27 GMT 2005 Christian - -I think shared connections w/ SSL work. :) They key aspects are - -- We want to be able to use a single connection handle in arbitrary -process/thread scenarios: in sshd, a single handle created in the -listening process should work in all forked children (right now I'm -created separate ones in each child, yuck), in Apache it should work -in all servicing threads (creating a separate connection in each -servicing thread would be far too costly), etc. - -- However, all SSL I/O on a single BIO must happen in the same *thread* -according to openssl-users -- same process seems intuitive because of -cipher streams etc; why it's per thread I don't know. - -The approach is now as follows: when a connection handle is marked as -shareable, an I/O handler process is forked off during handle setup -that processes all I/O for a single connection handle exclusively. -Data are processed through separate tx/rx buffers that live in shared -memory and are protected by semaphores. Additionally, a number of -fields in the connection handle also live in shared memory so can be -used to send back and forth messages etc. By using global semaphores as -condition variables, rx/tx requests are dispatched to the I/O handler -process. Therefore this should work for all multi-process/thread -scenarios in which processes/threads are created after the connection -handle is set up. - -This all is transparent when a connection is not marked shareable. The -main optimization left to do now is to make the locking more fine- -grained -- a throughput comparison is going to be interesting... - -I haven't tried transparent reconnects again; I'd presume I managed -to break them in the process. - ------------------------------------------------------------------------- - -Mon Mar 14 17:31:17 GMT 2005 Christian - -- Lots of work on shared connection handles. This is going to take a -while to work robustly. For now steer clear of BRO_CFLAG_SHAREABLE. - -- Fixed wrong ordering of semaphore locks in __bro_io_msg_queue_flush(). - -- The connection hack to work around OpenSSL's 'temporary unavailable' -beliefs is now only used when the problem occurs, namely during -reconnects. - -- Fixed a bug in the Posix version of __bro_sem_new() that prevented -processes from creating more than one different semaphores. Doh. - -- Bumped BRO_DATA_FORMAT_VERSION to 9, to sync up with Bro tree. - -- Added __bro_sem_get(), returning the current value of a sempahore, -with implementations for Posix + SYSV. - -- Lots of calltracing added. - ------------------------------------------------------------------------- - -Mon Mar 14 10:24:54 GMT 2005 Christian - -Code for shared connection handles with SSL enabled. Pretty much done, -but needs a lot of testing now. - ------------------------------------------------------------------------- - -Sat Mar 12 18:13:58 GMT 2005 Christian - -Beginning of support for sharing connection handles for SSL-enabled -connections. Since supporting this is complex, it will be optional, -and enabled by using the new BRO_CFLAG_SHAREABLE connection flag. - ------------------------------------------------------------------------- - -Fri Mar 11 14:50:23 GMT 2005 Christian - -Move to AC_PROG_LIBTOOL. - ------------------------------------------------------------------------- - -Fri Mar 11 14:33:57 GMT 2005 Christian - -Portability and robustness fixes. - -- auto* calls in autgen.sh are now checked for success and cause the -script to abort on error. -- Instead of trying to figure out what libraries the various OSs need -in order to be able to use Posix semaphors, I'm now attempting to use -the -pthread flag directly. If that fails, we just fall back to SYSV -semaphores. -- All semaphore + shmem implementations are now included in the tarball, -the point is to include them selectively in the *build*. -- Stevens' ifdef magic for union semun doesn't work on at least OpenBSD -so I'm using the BSD_HOST macro from config.h now. -- Apparently AM_PROG_LIBTOOL causes some people trouble so we need to -check how to get that working realiably :( - ------------------------------------------------------------------------- - -Mon Feb 21 14:45:51 GMT 2005 Christian - -- Partial-write bugfix. When we succeed only partially in writing out -a message, report success, not failure. Failure is handled by queuing -the message for later transmission, but we have already sent it -partially and the rest is still stuck in the output buffer, so if we -queue it again, it'll get sent at least twice. - -I had noticed that out of 100000 events sent by 100 processes in -parallel, typically around 100020 arrived :) - ------------------------------------------------------------------------- - -Sat Feb 19 21:04:46 GMT 2005 Christian - -- Lots of synchronization work. This generally seems to work now! :) It -required one major addition: support for shared memory. The problem is -that if multiple threads/processes attempt to write at the same time -and one write succeeds only partially, then *whichever* thread/process -gets to write next needs to write out the rest before writing any new -messages. The only alternative is to have write operations block until -entire messages are sent, which seems dangerous from an instrumentation -point of view. To share the remaining message data, shared memory is -required: both the tx and rx buffers now operate in shared memory and -are protected by semaphores. The current implementation uses SYSV shared -memory. - -I think shared memory is a good idea in general; for example it could be -used during instrumentation to get information from one corner of an app -to another without changing the application's structure. I don't think -we'll need this right away, but it's nice to have a possible technique -for it. - -- bro_disconnect() is now more tricky to use than before: if you use -it in a parallel setting, you *must* call it from the same process that -called bro_connect() and you must do so *after* all the other processes -have finished using the connection (typically this is not hard to do, so -I think we can live with that). - -The reason is that semaphores + shared memory need to be uninstalled -specifically and I haven't yet figured out a way to automate reference -counting so that the last thread/process using a connection could do -this automatically. It would be very cool if the functions that are -used for deinstallation could be asked to fail while the IPC objects are -still in use, but that's not the case. - -- You can still build the whole thing without semaphores or shared mem -and it'll work for single-threaded apps. The configure script now issues -a warning if not all tools required for stable parallel operation can be -found. - -- Added bro_event_queue_length_max() to allow applications to find out -the maximum queue length before messages will get dropped. brohose uses -this to wait until the queue gets half full before insisting on a flush. - ------------------------------------------------------------------------- - -Fri Feb 18 17:14:40 GMT 2005 Christian - -- SYSV semaphore implementation. Configure checks are included -and work as follows: if both Posix + SYSV semaphores are found, -Posix are preferred, however the user can override this by passing ---disable-posix-semaphores. Semaphores are still not actually used. - - ------------------------------------------------------------------------- - -Thu Feb 17 22:24:12 GMT 2005 Christian - -- First shot at semaphore support. Checking for Posix named semaphores -and making sure they actually work at configure time was the hardest -part; actual semaphore code untested and still unused. No ifdefs -anywhere :) - ------------------------------------------------------------------------- - -Thu Feb 17 20:06:00 GMT 2005 Christian - -- Incompletely sent chunks are now recognized and remaining parts are -shipped as soon as possible: repeated brohose -n 1 -e 1000 runs do not -take out Bro any more. :) - ------------------------------------------------------------------------- - -Thu Feb 17 19:21:15 GMT 2005 Christian - -- Added "brohose", which lets you hose a Bro with events by forking a -configurable number of processes, and having each process pump out an -event a configurable number of times as fast as possible. This is meant -as both a stress-testing tool for the protocol as well as obviously for -the synchronization stuff that'll go into Broccoli soon. - ------------------------------------------------------------------------- - -Wed Feb 16 17:40:47 GMT 2005 Christian - -- Documentation for the configuration options for debugging output. - ------------------------------------------------------------------------- - -Thu Feb 10 11:39:57 GMT 2005 Christian - -- Changed bro_event_queue_empty() to bro_event_queue_length(), -which is more useful in general and can be used to find out -whether the queue is empty, too. - ------------------------------------------------------------------------- - -Tue Feb 8 14:45:58 GMT 2005 Christian - -- This is release 0.6. - ------------------------------------------------------------------------- - -Mon Feb 7 14:54:15 GMT 2005 Christian - -- Additional byte swaps for IP addresses + subnets for compatibility -with Bro. - ------------------------------------------------------------------------- - -Sun Feb 6 23:55:07 GMT 2005 Christian - -- Debugging output can now be configured from the config file, -using the /broccoli/debug_messages and /broccoli/debug_calltrace -config items. - ------------------------------------------------------------------------- - -Tue Feb 1 21:34:17 GMT 2005 Christian - -- During handshake, data format compatibility is now confirmed as well -as matching protocol version. - ------------------------------------------------------------------------- - -Tue Feb 1 21:04:43 GMT 2005 Christian - -- Initial commit of support for sending/receiving libpcap packets. -Totally untested, and not documented yet. More on this once support -for packets is committed into the Bro tree. - ------------------------------------------------------------------------- - -Tue Feb 1 18:39:02 GMT 2005 Christian - -- Transparent reconnects now also work for non-SSL connections. I was -just lucky that the SSL handshake prevented the same problem from -occurring in the SSL-enabled case. Two fixes were necessary: - - 1) a separate attempt to connect to the peer that I have full control - over, and - 2) a fixlet in queue management that caused the event that - triggers the reconnect to be sent before any handshake information - for the new connection, thus causing a connection teardown by the - Bro end because the version number was not seen at the right time. - - ------------------------------------------------------------------------- - -Mon Jan 31 19:38:36 GMT 2005 Christian - -- Fixed a few spots where D_ENTER was not balanced with D_RETURN -- Added an int-to-string table for message types, for debugging -- Added a flag to the connection structure that prevents reconnect -attempts while one is already in progress -- Made io_msg_queue() private to bro_io.c because it was only called -from there. - ------------------------------------------------------------------------- - -Fri Jan 28 12:35:03 GMT 2005 Christian - -- Changed the error semantics of in __bro_io_msg_queue() so that queuing -a message after failure to send is not a failure. This fixes an issue -with handshake completion that I have observed with broping across -different machines, where events could still get lost despite explicit -request to complete the handshake. - ------------------------------------------------------------------------- - -Sun Jan 16 20:45:42 GMT 2005 Christian - -- Serialization/Unserialization for ports fixed, support for ICMP ports. - ------------------------------------------------------------------------- - -Sat Jan 15 13:58:16 GMT 2005 Christian - -- Sending and receiving IP addresses and subnets was broken, fixed now. -- Fixed a small memleak when first-time connection setup fails. - ------------------------------------------------------------------------- - -Thu Jan 13 21:03:45 GMT 2005 Christian - -- When using reconnects, Broccoli will now not attempt to reconnect -more than once every 5s. - ------------------------------------------------------------------------- - -Thu Jan 13 20:43:13 GMT 2005 Christian - -- Added connection flag BRO_CFLAG_ALWAYS_QUEUE that causes events -always to be queued in the connection's event queue regardless of -whether the peer is currently dead or not. - -- Moved the test of whether the peer requested an event that is -about to be sent or not to the point where the event actually is -about to be sent, from the point where it is requested to be sent. -The difference is that now an event will get silently dropped on -the floor if after a connection outage and a reconnect, a change -in the events requested from the peer will prevent the old queued -events to be sent anyway, even if they are no longer requested. - ------------------------------------------------------------------------- - -Wed Jan 12 20:46:10 GMT 2005 Christian - -- Added support for transparent reconnects for broken connections. -When using BRO_CFLAG_RECONNECT, Broccoli now attempts to reconnect -whenever a peer died and the user tries to read from or write to -the peer. This can aways be triggered manually using -bro_reconnect(). - -- Added bro_conn_alive() to determine if a connection is currently -alive or not. - ------------------------------------------------------------------------- - -Tue Jan 11 17:33:51 GMT 2005 Christian - -- Added connection flags parameter to bro_connect() and -bro_connect_str(): BRO_CFLAG_COMPLETE_HANDSHAKE completes -the handshake right away before returning from bro_connect()/ -bro_connect_str(), and BRO_CFLAG_RECONNECT still needs to be -implemented. Documentation updated accordingly. - ------------------------------------------------------------------------- - -Sat Jan 8 21:07:30 CET 2005 Christian - -- Allow empty (or comments-only) configuration files. - ------------------------------------------------------------------------- - -Sat Jan 8 20:52:56 CET 2005 Christian - -- Fixed the home directory lookup via getpwent() -- now correctly looks -up the entry of the current effective user. Doh. - -- Beginning of code for connection flags to use when creating a -connection, for example for handshake behaviour, automatic reconnection -attempts, etc. - ------------------------------------------------------------------------- - -Tue Jan 4 23:28:59 CET 2005 Christian - -- constness fixes for functions that accept values for events and -record fields. - ------------------------------------------------------------------------- - -Tue Jan 4 22:07:35 CET 2005 Christian - -- Encrpyted connections now extract as much data as possible from -the underlying buffer by calling BIO_read() optimistically. - -- For encrypted connections, the passphrase for the certificate's -private key can now be specified in the configuration file using key -"/broccoli/host_pass". - -- Added support for the handshake message in the Bro protocol. - -- If the ca_cert or host_cert keys are found in the config file, but -there is a problem loading the crypto files, don't attempt to connect. - -- Completed documentation on encrypted communication, explaining the -use of ca-create and ca-issue. - -- Fixed several bugs in the handling of sections in config files. -Matching of domain names is now case-insensitive. - -- The ~/.broccoli.conf file is now only used when it is readable only -by the user owning it. - -- More robustness for corner cases of buffer sizes. - -- Fixed a bug in sending messages that consist of only a single chunk -(like the handshake message). - -- The library now attempts to initialize the random number generator -in OpenSSL from /dev/random if possible. - ------------------------------------------------------------------------- - -Fri Dec 24 11:58:08 CET 2004 Christian - -- If the ca_cert or host_cert keys are found in the config file, but -there is a problem loading the crypto files, don't attempt to connect. - -- Completed documentation on encrypted communication, explaining the -use of ca-create and ca-issue. - -- Fixed several bugs in the handling of sections in config files. - ------------------------------------------------------------------------- - -Thu Dec 23 14:33:56 GMT 2004 Christian - -- Added sections support for configuration files. Sections can be -declared at arbitrary points in the config file, using the same syntax -as in OpenSSL config files. There can be a global section at the -beginning of the file, before the first declared sections. Sections are -selected using bro_conf_set_domain(). - -- Support for a per-user config file in ~/.broccoli.conf. This does -not override settings in the global config file but completely replaces -it, i.e., when the user-specific file is found, the global one is -ignored. - -- Added bro_conn_await_handshake() that blocks for limitable amount of -time, waiting for the handshake of a new Bro connection to complete. -This still needs some fixing, but is definitely necessary to prevent -weird races from occurring when a client tries to use a new connection -that has not yet been established completely. - -- Test applications are now linked to static libraries. This will -hopefully keep the build more portable. - -- Use of LFLAGS and YFLAGS moved to AM_LFLAGS and AM_YFLAGS, given the -warnings issued when using automake 1.9. - -- First shot at fixing the buffer flushing issues I see when using -encrypted connections. - ------------------------------------------------------------------------- - -Fri Dec 10 16:31:26 GMT 2004 Christian - -- Added + fixed OpenSSL code to support encrypted communication. -- Added OpenSSL as requirement to spec file. -- Changed broping policies to always use the same port -- Updated broccoli.conf: added keys for the CA's and the host's cert. - ------------------------------------------------------------------------- - -Thu Dec 9 14:59:24 GMT 2004 Christian - -- Build fixes in case documentation tools are not found -- Documentation polishing -- only SSL setup section todo still. - ------------------------------------------------------------------------- - -Thu Dec 9 00:48:05 GMT 2004 Christian - -- Final documentation passes for the 0.6 release. - ------------------------------------------------------------------------- - -Mon Dec 6 17:18:55 GMT 2004 Christian - -- More documentation, explaining the data types, records, Bro policy -configuration, started section on SSL setup (copied from Robin right -now), and minor fixes. - ------------------------------------------------------------------------- - -Mon Dec 6 15:17:05 GMT 2004 Christian - -- Added spec file for building RPMs -- seems to work -- Aest policies are now installed in $prefix/share/broccoli - ------------------------------------------------------------------------- - -Mon Dec 6 00:22:02 GMT 2004 Christian - -- Dropped the ..._raw() functions for records. These won't be used -internally ever. Their implementation moved to bro.c, and only the high- -level code remained in bro_record.c. - -- Added bro_event_set_val() to replace a val in an existing event. -There's not much use in resending an existing event unless it is -identical, which is not that useful. High-level code is in -__bro_event_set_val(). - -- Made it more clear in the comments explaining the -bro_record_get_..._val() functions that the "result" argument must -actually be the address of a pointer. (void * as argument type means -that the compiler does not issue a warning when passing in, say, a -double * -- but it would do so if we would use void **.) - ------------------------------------------------------------------------- - -Sun Dec 5 22:05:53 GMT 2004 Christian - -- Updates to the cvs wrapper script: surround with date and name -only in the ChangeLog, not in the commit message itself. - ------------------------------------------------------------------------- - -Sun Dec 5 02:15:29 GMT 2004 Christian - -- Fixed a bug in __bro_val_clone(): forgot to handle BRO_INTTYPE_OTHER. - -- Changed --enable-debugging flag to --enable-debug, for consistency -with the Bro tree. - -- Fixed bugs in several cloning implementations that didn't call the -parent's implementation. - ------------------------------------------------------------------------- - -Sun Dec 5 01:40:52 GMT 2004 Christian - -- Added __bro_event_copy() to clone events internally. - -- Events are now duplicated in __bro_io_event_queue() before they're -sent so the user's event remains unaffected (and thus could be sent -repeatedly etc). - -- Extensive pass over the documentation; still a good deal to do. - ------------------------------------------------------------------------- - -Sat Dec 4 03:09:05 GMT 2004 Christian - -More work on documentation, much is outdated now. - ------------------------------------------------------------------------- - -Sat Dec 4 02:05:30 GMT 2004 Christian - -- Started a ChangeLog. No detailed ChangeLog information was kept -previous to this commit. - ------------------------------------------------------------------------- diff --git a/aux/broccoli/INSTALL b/aux/broccoli/INSTALL deleted file mode 100644 index b42a17ac46..0000000000 --- a/aux/broccoli/INSTALL +++ /dev/null @@ -1,182 +0,0 @@ -Basic Installation -================== - - These are generic installation instructions. - - The `configure' shell script attempts to guess correct values for -various system-dependent variables used during compilation. It uses -those values to create a `Makefile' in each directory of the package. -It may also create one or more `.h' files containing system-dependent -definitions. Finally, it creates a shell script `config.status' that -you can run in the future to recreate the current configuration, a file -`config.cache' that saves the results of its tests to speed up -reconfiguring, and a file `config.log' containing compiler output -(useful mainly for debugging `configure'). - - If you need to do unusual things to compile the package, please try -to figure out how `configure' could check whether to do them, and mail -diffs or instructions to the address given in the `README' so they can -be considered for the next release. If at some point `config.cache' -contains results you don't want to keep, you may remove or edit it. - - The file `configure.in' is used to create `configure' by a program -called `autoconf'. You only need `configure.in' if you want to change -it or regenerate `configure' using a newer version of `autoconf'. - -The simplest way to compile this package is: - - 1. `cd' to the directory containing the package's source code and type - `./configure' to configure the package for your system. If you're - using `csh' on an old version of System V, you might need to type - `sh ./configure' instead to prevent `csh' from trying to execute - `configure' itself. - - Running `configure' takes awhile. While running, it prints some - messages telling which features it is checking for. - - 2. Type `make' to compile the package. - - 3. Optionally, type `make check' to run any self-tests that come with - the package. - - 4. Type `make install' to install the programs and any data files and - documentation. - - 5. You can remove the program binaries and object files from the - source code directory by typing `make clean'. To also remove the - files that `configure' created (so you can compile the package for - a different kind of computer), type `make distclean'. There is - also a `make maintainer-clean' target, but that is intended mainly - for the package's developers. If you use it, you may have to get - all sorts of other programs in order to regenerate files that came - with the distribution. - -Compilers and Options -===================== - - Some systems require unusual options for compilation or linking that -the `configure' script does not know about. You can give `configure' -initial values for variables by setting them in the environment. Using -a Bourne-compatible shell, you can do that on the command line like -this: - CC=c89 CFLAGS=-O2 LIBS=-lposix ./configure - -Or on systems that have the `env' program, you can do it like this: - env CPPFLAGS=-I/usr/local/include LDFLAGS=-s ./configure - -Compiling For Multiple Architectures -==================================== - - You can compile the package for more than one kind of computer at the -same time, by placing the object files for each architecture in their -own directory. To do this, you must use a version of `make' that -supports the `VPATH' variable, such as GNU `make'. `cd' to the -directory where you want the object files and executables to go and run -the `configure' script. `configure' automatically checks for the -source code in the directory that `configure' is in and in `..'. - - If you have to use a `make' that does not supports the `VPATH' -variable, you have to compile the package for one architecture at a time -in the source code directory. After you have installed the package for -one architecture, use `make distclean' before reconfiguring for another -architecture. - -Installation Names -================== - - By default, `make install' will install the package's files in -`/usr/local/bin', `/usr/local/man', etc. You can specify an -installation prefix other than `/usr/local' by giving `configure' the -option `--prefix=PATH'. - - You can specify separate installation prefixes for -architecture-specific files and architecture-independent files. If you -give `configure' the option `--exec-prefix=PATH', the package will use -PATH as the prefix for installing programs and libraries. -Documentation and other data files will still use the regular prefix. - - In addition, if you use an unusual directory layout you can give -options like `--bindir=PATH' to specify different values for particular -kinds of files. Run `configure --help' for a list of the directories -you can set and what kinds of files go in them. - - If the package supports it, you can cause programs to be installed -with an extra prefix or suffix on their names by giving `configure' the -option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. - -Optional Features -================= - - Some packages pay attention to `--enable-FEATURE' options to -`configure', where FEATURE indicates an optional part of the package. -They may also pay attention to `--with-PACKAGE' options, where PACKAGE -is something like `gnu-as' or `x' (for the X Window System). The -`README' should mention any `--enable-' and `--with-' options that the -package recognizes. - - For packages that use the X Window System, `configure' can usually -find the X include and library files automatically, but if it doesn't, -you can use the `configure' options `--x-includes=DIR' and -`--x-libraries=DIR' to specify their locations. - -Specifying the System Type -========================== - - There may be some features `configure' can not figure out -automatically, but needs to determine by the type of host the package -will run on. Usually `configure' can figure that out, but if it prints -a message saying it can not guess the host type, give it the -`--host=TYPE' option. TYPE can either be a short name for the system -type, such as `sun4', or a canonical name with three fields: - CPU-COMPANY-SYSTEM - -See the file `config.sub' for the possible values of each field. If -`config.sub' isn't included in this package, then this package doesn't -need to know the host type. - - If you are building compiler tools for cross-compiling, you can also -use the `--target=TYPE' option to select the type of system they will -produce code for and the `--build=TYPE' option to select the type of -system on which you are compiling the package. - -Sharing Defaults -================ - - If you want to set default values for `configure' scripts to share, -you can create a site shell script called `config.site' that gives -default values for variables like `CC', `cache_file', and `prefix'. -`configure' looks for `PREFIX/share/config.site' if it exists, then -`PREFIX/etc/config.site' if it exists. Or, you can set the -`CONFIG_SITE' environment variable to the location of the site script. -A warning: not all `configure' scripts look for a site script. - -Operation Controls -================== - - `configure' recognizes the following options to control how it -operates. - -`--cache-file=FILE' - Use and save the results of the tests in FILE instead of - `./config.cache'. Set FILE to `/dev/null' to disable caching, for - debugging `configure'. - -`--help' - Print a summary of the options to `configure', and exit. - -`--quiet' -`--silent' -`-q' - Do not print messages saying which checks are being made. To - suppress all normal output, redirect it to `/dev/null' (any error - messages will still be shown). - -`--srcdir=DIR' - Look for the package's source code in directory DIR. Usually - `configure' can determine that directory automatically. - -`--version' - Print the version of Autoconf used to generate the `configure' - script, and exit. - -`configure' also accepts some other, not widely useful, options. diff --git a/aux/broccoli/Makefile.am b/aux/broccoli/Makefile.am deleted file mode 100644 index 0a3046a11b..0000000000 --- a/aux/broccoli/Makefile.am +++ /dev/null @@ -1,20 +0,0 @@ -## Process this file with automake to produce Makefile.in - -SUBDIRS = src test docs bindings - -# When running distcheck, make sure we skip building documentation. -# -DISTCHECK_CONFIGURE_FLAGS = --disable-gtk-doc - -MAINTAINERCLEANFILES = Makefile.in aclocal.m4 config.guess \ - config.h.in config.sub configure install-sh \ - ltconfig ltmain.sh missing mkinstalldirs \ - stamp-h.in - -bin_SCRIPTS = broccoli-config -dist_sysconf_DATA = broccoli.conf - -EXTRA_DIST = README AUTHORS COPYING depcomp ylwrap shtool \ - compat/sys/queue.h broccoli.spec contrib \ - autogen.sh - diff --git a/aux/broccoli/NEWS b/aux/broccoli/NEWS deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/aux/broccoli/README b/aux/broccoli/README deleted file mode 100644 index d34833c367..0000000000 --- a/aux/broccoli/README +++ /dev/null @@ -1,66 +0,0 @@ - - B R O C C O L I - - The Bro Client Communications Library - - http://www.bro-ids.org - -________________________________________________________________________ - -This package contains Broccoli, the Bro client communications library. -It allows you to create client sensors for the Bro intrusion detection -system. Broccoli can speak a good subset of the Bro communication -protocol, in particular, it can receive Bro IDs, send and receive Bro -events, and send and receive event requests to/from peering Bros. You -can currently create and receive values of pure types like integers, -counters, timestamps, IP addresses, port numbers, booleans, and strings. - -The library uses OpenSSL for encrypted communication. Other than that, -the library has no other dependencies and has been tested on Linux, the -BSDs, and Solaris. A Windows build has not currently been tried but -is part of our future plans. If you succeed in building Broccoli on -other platforms, let us know! - -To build, do the usual ./configure; make; make install routine. Here's -a list of the current configure options: - - --enable-debug - - This one enables lots of debugging output. Be sure to disable this - when using the library in a production environment! The output could - easily end up in undersired places when the stdout of the program - you've instrumented is used in other ways. - - --with-configfile=FILE - - Broccoli can read key/value pairs from a config file. By default it - is located in the etc directory of the installation root (exception: - when using --prefix=/usr, /etc is used instead of /usr/etc). The - default config file name is broccoli.conf. Using --with-configfile, - you can override the location and name of the config file. - -To use the library in other programs & configure scripts, use the -broccoli-config script. It gives you the necessary configuration flags -and linker flags for your system, see --cflags and --libs. - -The API is contained in broccoli.h and pretty well documented. A few -usage examples can be found in the test directory, in particular, the -broping tool can be used to test event transmission and reception. Have -a look at the policy file broping.bro for the events that need to be -defined at the peering Bro. Try broping -h for a look at the available -options. - -Broccoli knows two kinds of version numbers: the release version number -(as in "broccoli-x.y.tar.gz", or as shipped with Bro) and the shared -library API version number. The former relates to changes in the tree, -the latter to compatibility changes in the API. You can see their -correspondence in VERSION. - -Comments, feedback and patches are appreciated, please send them to -the Bro mailing list at bro(at)bro-ids.org or directly to the author at -christian (at) icir.org. - - Enjoy! - --Christian. -________________________________________________________________________ -$Id: README 4043 2007-03-01 23:15:14Z kreibich $ diff --git a/aux/broccoli/TODO b/aux/broccoli/TODO deleted file mode 100644 index 10d875aac6..0000000000 --- a/aux/broccoli/TODO +++ /dev/null @@ -1,27 +0,0 @@ -- Separate method pointers (i.e., the vtable) in the various classes into - separate "class" structs (think klass in Gtk). Right now these waste - space because they're allocated with every instance, but since they're - not used extensively it hasn't really been worth it so far. - -- The init methods must be allowed to fail. Currently allocations in that - method can fail but this failure can not be signaled to the caller. - -- Add an error variable so the user has a way to figure out what happened - when things go wrong. - -- Add support for at least a small number of expressions -- needed in - bro_attr.[ch]. - -- Add support for tables/sets. - -- Add a server-suitable API, i.e., how can one write an application that - listens on a given port, using Broccoli. - -- When configure determined that lex+yacc exist, make clean doesn't clean - up the generated lexer/parser C files. I presume this is because I keep - them all in EXTRA_DIST. Ensure make clean removes the generated files - when we know we can regenerate them. - -- There's a segfault lurking in __bro_record_get_nth_val() with records - that don't have all members assigned to. Investigate whether dummy - val approach really works or whether it's a design flaw. diff --git a/aux/broccoli/autogen.sh b/aux/broccoli/autogen.sh deleted file mode 100755 index ef3e9188f5..0000000000 --- a/aux/broccoli/autogen.sh +++ /dev/null @@ -1,131 +0,0 @@ -#!/bin/sh - -# Initialization script to set up the initial configuration files etc. -# shtool usage inspired by the autogen script of the ferite scripting -# language -- cheers Chris :) - -BLD_ON=`./shtool echo -n -e %B` -BLD_OFF=`./shtool echo -n -e %b` - -LT=libtoolize -DIE=0 -NAME=broccoli - -echo -echo " "${BLD_ON}"Broccoli Build Tools Setup"${BLD_OFF} -echo "====================================================" -echo -echo "Checking whether we have all tools available ..." - -(autoconf --version) < /dev/null > /dev/null 2>&1 || { - echo - echo ${BLD_ON}"Error"${BLD_OFF}": You must have \`autoconf' installed to." - echo "Download the appropriate package for your distribution," - echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" - DIE=1 -} - -($LT --version) < /dev/null > /dev/null 2>&1 || { - LT=glibtoolize - - ($LT --version) < /dev/null > /dev/null 2>&1 || { - echo - echo ${BLD_ON}"Error"${BLD_OFF}": You must have \`libtool' installed." - echo "Download the appropriate package for your distribution," - echo "or get the source tarball at ftp://ftp.gnu.org/pub/gnu/" - DIE=1 - } -} - -(automake --version) < /dev/null > /dev/null 2>&1 || { - echo - echo ${BLD_ON}"Error"${BLD_OFF}": You must have \`automake' installed." - echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz" - echo "(or a newer version if it is available)" - DIE=1 - NO_AUTOMAKE=yes -} - - -# if no automake, don't bother testing for aclocal -test -n "$NO_AUTOMAKE" || (aclocal --version) < /dev/null > /dev/null 2>&1 || { - echo - echo ${BLD_ON}"Error"${BLD_OFF}": Missing \`aclocal'. The version of \`automake'" - echo "installed doesn't appear recent enough." - echo "Get ftp://ftp.gnu.org/pub/gnu/automake-1.3.tar.gz" - echo "(or a newer version if it is available)" - DIE=1 -} - -if test "$DIE" -eq 1; then - exit 1 -fi - -echo "All necessary tools found." -echo - -if [ -d autom4te.cache ] ; then - echo "Removing autom4te.cache ..." - rm -rf autom4te.cache -fi - -echo -echo "running "${BLD_ON}$LT${BLD_OFF} -echo "----------------------------------------------------" -$LT -c -f -if [ $? -ne 0 ]; then - echo "*** ERROR($NAME), aborting." - exit 1 -fi - -echo -echo "running "${BLD_ON}"aclocal"${BLD_OFF} -echo "----------------------------------------------------" -aclocal -I . $ACLOCAL_FLAGS -if [ $? -ne 0 ]; then - echo "*** ERROR($NAME), aborting." - exit 1 -fi - -echo -echo "running "${BLD_ON}"autoheader"${BLD_OFF} -echo "----------------------------------------------------" -autoheader -if [ $? -ne 0 ]; then - echo "*** ERROR($NAME), aborting." - exit 1 -fi - -echo -echo "running "${BLD_ON}"automake"${BLD_OFF} -echo "----------------------------------------------------" -automake -a -c -if [ $? -ne 0 ]; then - echo "*** ERROR($NAME), aborting." - exit 1 -fi - -echo -echo "running "${BLD_ON}"autoconf"${BLD_OFF} -echo "----------------------------------------------------" -autoconf -if [ $? -ne 0 ]; then - echo "*** ERROR($NAME), aborting." - exit 1 -fi - -if ! test "x$BROBUILD" = xyes; then -echo -echo -echo "Setup finished. Now run:" -echo -echo " $ "${BLD_ON}"./configure"${BLD_OFF}" (with options as needed, try --help)" -echo -echo "and then" -echo -echo " $ "${BLD_ON}"make"${BLD_OFF} -echo " # "${BLD_ON}"make install"${BLD_OFF} -echo -echo " (or use "${BLD_ON}"gmake"${BLD_OFF}" when make on your platform isn't GNU make)" -echo -fi diff --git a/aux/broccoli/bindings/Makefile.am b/aux/broccoli/bindings/Makefile.am deleted file mode 100644 index dfc9c49f30..0000000000 --- a/aux/broccoli/bindings/Makefile.am +++ /dev/null @@ -1,18 +0,0 @@ -# While recursive inclusion is possible, this would include -# *anything* found in there, which is not what we want. --cpk -# -EXTRA_DIST = \ -./python/README \ -./python/README.html \ -./python/TODO \ -./python/broccoli_intern.i \ -./python/broccoli_intern.py \ -./python/broccoli_intern_wrap.c \ -./python/broccoli.py \ -./python/Makefile \ -./python/setup.py \ -./python/tests \ -./python/tests/broping.py \ -./python/tests/broping-record.py \ -./python/tests/test.bro \ -./python/tests/test.py diff --git a/aux/broccoli/bindings/python/Makefile b/aux/broccoli/bindings/python/Makefile deleted file mode 100644 index 35bfa53b1b..0000000000 --- a/aux/broccoli/bindings/python/Makefile +++ /dev/null @@ -1,18 +0,0 @@ -# $Id$ -# -# Makefile not need to build module. Use "python setup.py install" instead. - -CLEAN=build broccoli_intern_wrap.c broccoli_intern.py README.html *.pyc - -all : doc broccoli_intern_wrap.c - -broccoli_intern_wrap.c : broccoli_intern.i - swig -python -I../../src -o broccoli_intern_wrap.c broccoli_intern.i - -doc : README.html - -clean: - rm -rf $(CLEAN) - -README.html : README - -asciidoc -a toc -b xhtml11-custom README diff --git a/aux/broccoli/bindings/python/README b/aux/broccoli/bindings/python/README deleted file mode 100644 index d8b0b2f466..0000000000 --- a/aux/broccoli/bindings/python/README +++ /dev/null @@ -1,240 +0,0 @@ -// -*- AsciiDoc -*- -Python Bindings for Broccoli -============================ - -Overview --------- - -This Python module provides bindings for -http://www.icir.org/christian/broccoli/index.html[Broccoli], Bro's -client communication library. In general, the bindings provide the -same functionality as Broccoli's C API. - -Download --------- - -Since Bro 1.4, a stable version of the Python module ships as part -of the Bro distribution in +aux/broccoli/bindings/python+. - -The most current development version is part of the Bro Subversion -repository. To get it, use: - - > svn checkout http://svn.icir.org/bro/trunk/bro/aux/broccoli/bindings/python - -Installation ------------- - -Installation of the Python module is pretty straight-forward. After -Broccoli itself has been -http://www.icir.org/christian/broccoli/manual/c55.html[installed], -it follows the standard installation process for Python modules: - - > python setup.py install - -Try the following to test the installation. If you do not see any -error message, everything should be fine: - - > python -c "import broccoli" - > - -Usage ------ - -The following examples demonstrate how to send and receive Bro -events in Python. - -The main challenge when using Broccoli from Python is dealing with -the data types of Bro event parameters as there is no one-to-one -mapping between Bro's types and Python's types. The Python modules -automatically maps between those types which both systems provide -(such as strings) and provides a set of wrapper classes for Bro -types which do not have a direct Python equivalent (such as IP -addresses). - -Connecting to Bro -~~~~~~~~~~~~~~~~~ - -The following code sets up a connection from Python to a remote Bro -instance (or another Broccoli) and provides a connection handle for -further communication: - - from broccoli import * - bc = Connection("127.0.0.1:47758") - -An +IOError+ will be raised if the connection cannot be established. - -Sending Events -~~~~~~~~~~~~~~ - -Once you have a connection handle +bc+ set up as shown above, you can -start sending events: - - bc.send("foo", 5, "attack!") - -This sends an event called +foo+ with two parameters, +5+ and -+attack!+. Broccoli operates asynchronously, i.e., events scheduled -with +send()+ are not always sent out immediately but might be -queued for later transmission. To ensure that all events get out -(and incoming events are processed, see below), you need to call -+bc.processInput()+ regularly. - -Data Types -~~~~~~~~~~ - -In the example above, the types of the event parameters are -automatically derived from the corresponding Python types: the first -parameter (+5+) has the Bro type +int+ and the second one -(+attack!+) has Bro type +string+. - -For types which do not have a Python equivalent, the +broccoli+ -module provides wrapper classes which have the same names as the -corresponding Bro types. For example, to send an event called +bar+ -with one +addr+ argument and one +count+ argument, you can write: - - bc.send("bar", addr("192.168.1.1"), count(42)) - -The following table summarizes the available atomic types and their -usage. - -.Bro vs. Python types -[grid="all"] -.---------.-----------.-------------------------- -Bro Type Python Type Example -------------------------------------------------- -addr +addr("192.168.1.1")+ -bool bool +True+ -count +count(42)+ -double float +3.14+ -enum _Type currently not supported_ -int int +5+ -interval +interval(60)+ -net _Type currently not supported_ -port +port("80/tcp")+ -string string +"attack!"+ -subnet +subnet("192.168.1.0/24")+ -time +time(1111111111.0)+ -------------------------------------------------- - -The +broccoli+ module also supports sending Bro records as event -parameters. To send a record, you first define a record type. For -example, a Bro record type - - type my_record: record { - a: int; - b: addr; - c: subnet; - }; - -turns into Python as - - my_record = record_type("a", "b", "c") - -As the example shows, Python only needs to know the attribute names -but not their types. The types are derived automatically in the same -way as discussed above for atomic event parameters. - -Now you can instantiate a record instance of the newly defined type -and send it out: - - rec = record(my_record) - rec.a = 5 - rec.b = addr("192.168.1.1") - rec.c = subnet("192.168.1.0/24") - bc.send("my_event", rec) - -NOTE: The Python module does not support nested records at this -time. - -Receiving Events -~~~~~~~~~~~~~~~~ - -To receive events, you define a callback function having the same -name as the event and mark it with the +event+ decorator: - - @event - def foo(arg1, arg2): - print arg1, arg2 - -Once you start calling +bc.processInput()+ regularly (see above), -each received +foo+ event will trigger the callback function. - -By default, the event's arguments are always passed in with built-in -Python types. For Bro types which do not have a direct Python -equivalent (see table above), a substitute built-in type is used -which corresponds to the type the wrapper class' constructor expects -(see the examples in the table). For example, Bro type +addr+ is -passed in as a string and Bro type +time+ is passed in as a float. - -Alternatively, you can define a _typed_ prototype for the event. If you -do so, arguments will first be type-checked and then passed to the -call-back with the specified type (which means instances of the -wrapper classes for non-Python types). Example: - - @event(count, addr) - def bar(arg1, arg2): - print arg1, arg2 - -Here, +arg1+ will be an instance of the +count+ wrapper class and -+arg2+ will be an instance of the +addr+ wrapper class. - -Protoyping works similarly with built-in Python types: - - @event(int, string): - def foo(arg1, arg2): - print arg1, arg2 - -In general, the prototype specifies the types in which the callback -wants to receive the arguments. This actually provides support for -simple type casts as some types support conversion to into something -different. If for instance the event source sends an event with a -single port argument, +@event(port)+ will pass the port as an -instance of the +port+ wrapper class; +@event(string)+ will pass it -as a string (e.g., +"80/tcp"+); and +@event(int)+ will pass it as an -integer without protocol information (e.g., just +80+). If an -argument cannot be converted into the specified type, a +TypeError+ -will be raised. - -To receive an event with a record parameter, the record type first -needs to be defined, as described above. Then the type can be used -with the +@event+ decorator in the same way as atomic types: - - my_record = record_type("a", "b", "c") - @event(my_record) - def my_event(rec): - print rec.a, rec.b, rec.c - -Helper Functions ----------------- - -The +broccoli+ module provides one helper function: +current_time()+ -returns the current time as a float which, if necessary, can be -wrapped into a +time+ parameter (i.e., +time(current_time()+) - -Examples --------- - -There are some example scripts in -http://svn.icir.org/bro/branches/robin/work/aux/broccoli/bindings/python/tests/[+aux/broccoli/bindings/python/tests+]: - - - http://svn.icir.org/bro/branches/robin/work/aux/broccoli/bindings/python/tests/broping.py[+broping.py+] - is a (simplified) Python version of Broccoli's test program - +broping+. Start Bro with - http://svn.icir.org/bro/branches/robin/work/aux/broccoli/test/broping.bro[+aux/broccoli/test/broping.bro+]. - - - Similarly, - http://svn.icir.org/bro/branches/robin/work/aux/broccoli/bindings/python/tests/broping-record.py[+broping-record.py+] - is a Python version of Broccoli's +broping+ for records. Start - Bro with - http://svn.icir.org/bro/branches/robin/work/aux/broccoli/test/broping-record.bro[+aux/broccoli/test/broping-record.bro+]. - - - http://svn.icir.org/bro/branches/robin/work/aux/broccoli/bindings/python/tests/test.py[+test.py+] - is a very ugly but comprehensive regression test and part of the - communication test-suite. Start Bro with - http://svn.icir.org/bro/branches/robin/work/aux/broccoli/bindings/python/tests/test.bro[+test.bro+]. - - - - - - - diff --git a/aux/broccoli/bindings/python/README.html b/aux/broccoli/bindings/python/README.html deleted file mode 100644 index d8792f8485..0000000000 --- a/aux/broccoli/bindings/python/README.html +++ /dev/null @@ -1,800 +0,0 @@ - - - - - - - -Python Bindings for Broccoli - - - -

Overview

-

-

This Python module provides bindings for -Broccoli, Bro's -client communication library. In general, the bindings provide the -same functionality as Broccoli's C API.

-
-

Download

-

-

Since Bro 1.4, a stable version of the Python module ships as part -of the Bro distribution in aux/broccoli/bindings/python.

-

The most current development version is part of the Bro Subversion -repository. To get it, use:

-
-
-
> svn checkout http://svn.icir.org/bro/trunk/bro/aux/broccoli/bindings/python
-
-
-

Installation

-

-

Installation of the Python module is pretty straight-forward. After -Broccoli itself has been -installed, -it follows the standard installation process for Python modules:

-
-
-
> python setup.py install
-
-

Try the following to test the installation. If you do not see any -error message, everything should be fine:

-
-
-
> python -c "import broccoli"
->
-
-
-

Usage

-

-

The following examples demonstrate how to send and receive Bro -events in Python.

-

The main challenge when using Broccoli from Python is dealing with -the data types of Bro event parameters as there is no one-to-one -mapping between Bro's types and Python's types. The Python modules -automatically maps between those types which both systems provide -(such as strings) and provides a set of wrapper classes for Bro -types which do not have a direct Python equivalent (such as IP -addresses).

-

Connecting to Bro

-

The following code sets up a connection from Python to a remote Bro -instance (or another Broccoli) and provides a connection handle for -further communication:

-
-
-
from broccoli import *
-bc = Connection("127.0.0.1:47758")
-
-

An IOError will be raised if the connection cannot be established.

-

Sending Events

-

Once you have a connection handle bc set up as shown above, you can -start sending events:

-
-
-
bc.send("foo", 5, "attack!")
-
-

This sends an event called foo with two parameters, 5 and -attack!. Broccoli operates asynchronously, i.e., events scheduled -with send() are not always sent out immediately but might be -queued for later transmission. To ensure that all events get out -(and incoming events are processed, see below), you need to call -bc.processInput() regularly.

-

Data Types

-

In the example above, the types of the event parameters are -automatically derived from the corresponding Python types: the first -parameter (5) has the Bro type int and the second one -(attack!) has Bro type string.

-

For types which do not have a Python equivalent, the broccoli -module provides wrapper classes which have the same names as the -corresponding Bro types. For example, to send an event called bar -with one addr argument and one count argument, you can write:

-
-
-
bc.send("bar", addr("192.168.1.1"), count(42))
-
-

The following table summarizes the available atomic types and their -usage.

-
- - ---- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Table: Bro vs. Python types
- Bro Type - - Python Type - - Example -
- addr - - - - addr("192.168.1.1") -
- bool - - bool - - True -
- count - - - - count(42) -
- double - - float - - 3.14 -
- enum - - - - Type currently not supported -
- int - - int - - 5 -
- interval - - - - interval(60) -
- net - - - - Type currently not supported -
- port - - - - port("80/tcp") -
- string - - string - - "attack!" -
- subnet - - - - subnet("192.168.1.0/24") -
- time - - - - time(1111111111.0) -
-
-

The broccoli module also supports sending Bro records as event -parameters. To send a record, you first define a record type. For -example, a Bro record type

-
-
-
type my_record: record {
-    a: int;
-    b: addr;
-    c: subnet;
-};
-
-

turns into Python as

-
-
-
my_record = record_type("a", "b", "c")
-
-

As the example shows, Python only needs to know the attribute names -but not their types. The types are derived automatically in the same -way as discussed above for atomic event parameters.

-

Now you can instantiate a record instance of the newly defined type -and send it out:

-
-
-
rec = record(my_record)
-rec.a = 5
-rec.b = addr("192.168.1.1")
-rec.c = subnet("192.168.1.0/24")
-bc.send("my_event", rec)
-
-
- - - -
-
Note
-
The Python module does not support nested records at this -time.
-
-

Receiving Events

-

To receive events, you define a callback function having the same -name as the event and mark it with the event decorator:

-
-
-
@event
-def foo(arg1, arg2):
-    print arg1, arg2
-
-

Once you start calling bc.processInput() regularly (see above), -each received foo event will trigger the callback function.

-

By default, the event's arguments are always passed in with built-in -Python types. For Bro types which do not have a direct Python -equivalent (see table above), a substitute built-in type is used -which corresponds to the type the wrapper class' constructor expects -(see the examples in the table). For example, Bro type addr is -passed in as a string and Bro type time is passed in as a float.

-

Alternatively, you can define a typed prototype for the event. If you -do so, arguments will first be type-checked and then passed to the -call-back with the specified type (which means instances of the -wrapper classes for non-Python types). Example:

-
-
-
@event(count, addr)
-def bar(arg1, arg2):
-    print arg1, arg2
-
-

Here, arg1 will be an instance of the count wrapper class and -arg2 will be an instance of the addr wrapper class.

-

Protoyping works similarly with built-in Python types:

-
-
-
@event(int, string):
-def foo(arg1, arg2):
-    print arg1, arg2
-
-

In general, the prototype specifies the types in which the callback -wants to receive the arguments. This actually provides support for -simple type casts as some types support conversion to into something -different. If for instance the event source sends an event with a -single port argument, @event(port) will pass the port as an -instance of the port wrapper class; @event(string) will pass it -as a string (e.g., "80/tcp"); and @event(int) will pass it as an -integer without protocol information (e.g., just 80). If an -argument cannot be converted into the specified type, a TypeError -will be raised.

-

To receive an event with a record parameter, the record type first -needs to be defined, as described above. Then the type can be used -with the @event decorator in the same way as atomic types:

-
-
-
my_record = record_type("a", "b", "c")
-@event(my_record)
-def my_event(rec):
-    print rec.a, rec.b, rec.c
-
-
-

Helper Functions

-

-

The broccoli module provides one helper function: current_time() -returns the current time as a float which, if necessary, can be -wrapped into a time parameter (i.e., time(current_time())

-
-

Examples

-

-

There are some example scripts in -aux/broccoli/bindings/python/tests:

- -
- - - diff --git a/aux/broccoli/bindings/python/TODO b/aux/broccoli/bindings/python/TODO deleted file mode 100644 index 0bfc98af3e..0000000000 --- a/aux/broccoli/bindings/python/TODO +++ /dev/null @@ -1,7 +0,0 @@ - -- nested records are not support. -- type net does not work because I'm too lazy to implement the parsing ... -- type enum disabled because there seems to be some Broccoli problem with them. -- would be nice to have some more standard operations (+,-, etc.) - defined for the wrapper classes. -- listen() not available in Python diff --git a/aux/broccoli/bindings/python/broccoli.py b/aux/broccoli/bindings/python/broccoli.py deleted file mode 100644 index e8992eed32..0000000000 --- a/aux/broccoli/bindings/python/broccoli.py +++ /dev/null @@ -1,425 +0,0 @@ - -import socket -import struct -from types import FunctionType - -from _broccoli_intern import * - -bro_init(None) - -##### Connection class which capsulates a Broccoli connection. -class Connection: - # Connection to destination given as string "host:port" - def __init__(self, destination, broclass="", flags=BRO_CFLAG_RECONNECT | BRO_CFLAG_ALWAYS_QUEUE, connect=True): - self.bc = bro_conn_new_str(destination, flags) - self.destination = destination - if not self.bc: - raise IOError("cannot init Broccoli connection handle") - - self._registerHandlers() - - if broclass: - bro_conn_set_class(self.bc, broclass) - - if connect: - self.connect(); - - # If the instance was created with connect=False, this will trigger the connect. - def connect(self): - if not bro_conn_connect(self.bc): - raise IOError("cannot connect to %s" % self.destination) - - # Hand control to Broccoli's I/O loop. - # Returns true if the send queue is non-empty. - def processInput(self): - bro_conn_process_input(self.bc); - return bro_event_queue_length(self.bc) > 0 - - # Send an event of name with args. - def send(self, name, *args): - ev = bro_event_new(name) - for arg in args: - bro_event_add_val(ev, _getInternalVal(arg)); - - bro_event_send(self.bc, ev); - bro_event_free(ev); - self.processInput() - - # Explicit subscribe - def subscribe(self, event_name, callback): - ev = event(callback) - bro_event_registry_add_compact(self.bc, event_name, ev); - - # Register all decorated event callbacks. - def _registerHandlers(self): - for ev in _Events: - bro_event_registry_add_compact(self.bc, ev.__name__, ev); - - -##### Wrapped helper functions. -def current_time(): - return bro_util_current_time() - -##### Decorator @event(val-type1, val-type2, val-type3, ...) - -# List of all functions declared with the @event decorator -# (more precisely, list of all of their wrappers; see below). -_Events = [] - -def event(*types): - - # We wrap the event callback into a function which turns the 2-tuples (type,val) - # that we get from the C layer into the corresponding Python object. - def make_wrapper(func): - - def wrapped_f(*args): - - new_args = [] - - ptypes = types - if not ptypes: - # Allow omitting types. - ptypes = [None] *len(args) - - for (arg, type) in zip(args, ptypes): - # Split the 2-tuples passed to us by the C layer. - (btype, val) = arg - # Create an instance of the corresponding Python type. - new_args += [instantiate(btype, val, type)] - - # Finally call the callback. - return func(*new_args); - - # Pretend the wrapper has the name of the actual callback (rather than "wrapped_f" ...) - wrapped_f.func_name = func.func_name - - # Add the wrapped function to the list of events handlers. - global _Events - _Events += [wrapped_f] - - return wrapped_f - - # Allow @event instead of @event() - if len(types) == 1 and type(types[0]) == FunctionType: - func = types[0] - types = () - return make_wrapper(func) - - else: - return make_wrapper - -##### Data types - -# For those Bro types which do not direcly correspond to Python type, we create -# wrapper classes. For those which do (int, float), we use the Python type directly. - -# Base class for our wrapper classes. -# For atomic types, the classes here act as both type and instances. For non-atomic -# types (i.e., records) we define separate type and instance classes below. -class Val: - # Type is the Bro type BRO_TYPE_*. - # Val is representation of the Val in a standard Python type. - def __init__(self, type, val): - self.type = type - self.val = val - - self.__class__._bro_type = type # Doing it once would be sufficient. - - def __str__(self): - return str(self.val) - - # Convert value into a 2-tuple (type, val) as expected by the C layer. - def internalVal(self): - return (self.type, self.val) - -class count(Val): - def __init__(self, val): - Val.__init__(self, BRO_TYPE_COUNT, int(val)) - - @staticmethod - def _factory(val, dst_type): - v = count(val) - if dst_type == int or not dst_type: - return v.val - _typeCheck(dst_type, count) - return v - -class interval(Val): - def __init__(self, val): - Val.__init__(self, BRO_TYPE_INTERVAL, float(val)) - - @staticmethod - def _factory(val, dst_type): - v = interval(val) - if dst_type == float or not dst_type: - return v.val - _typeCheck(dst_type, interval) - return v - -class time(Val): - def __init__(self, val): - Val.__init__(self, BRO_TYPE_TIME, float(val)) - - @staticmethod - def _factory(val, dst_type): - v = time(val) - if dst_type == float or not dst_type: - return v.val - _typeCheck(dst_type, time) - return v - -class port(Val): - - protos_by_name = { "tcp": 6, "udp": 17, "icmp": 1 } - protos_by_num = { 6: "tcp", 17: "udp", 1: "icmp" } - - def __init__(self, str=None, internal=None): - v = internal and internal or self._parse(str) - Val.__init__(self, BRO_TYPE_PORT, v) - - def __str__(self): - (port, proto) = self.val - try: - return "%d/%s" % (port, self.protos_by_num[proto]) - except IndexError: - return "%s/unknown" % port - - @staticmethod - def _factory(val, dst_type): - v = port(internal=val) - if dst_type == str or not dst_type: - return str(v) - if dst_type == int: - return v[0] - _typeCheck(dst_type, port) - return v - - def _parse(self, str): - (port, proto) = str.split("/") - try: - return (int(port), self.protos_by_name[proto.lower()]) - except (IndexError, ValueError): - return (0, 0) - -class addr(Val): - def __init__(self, str=None, internal=None): - v = internal and internal or self._parse(str) - Val.__init__(self, BRO_TYPE_IPADDR, v) - - def __str__(self): - return socket.inet_ntoa(struct.pack('=l', self.val)) - - @staticmethod - def _factory(val, dst_type): - v = addr(internal=val) - if dst_type == str or not dst_type: - return str(v) - _typeCheck(dst_type, addr) - return v - - def _parse(self, str): - return struct.unpack('=l',socket.inet_aton(str))[0] - -# Not supported at this point. Need to write a parse function. -class net(Val): - def __init__(self, str=None, internal=None): - v = internal and internal or self._parse(str) - Val.__init__(self, BRO_TYPE_NET, v) - - def __str__(self): - return "X.X.X" # FIXME - - @staticmethod - def _factory(val, dst_type): - v = net(internal=val) - if dst_type == str or not dst_type: - return str(v) - _typeCheck(dst_type, net) - return v - - def _parse(self, str): - return 0 # FIXME - -class subnet(Val): - def __init__(self, str=None, internal=None): - v = internal and internal or self._parse(str) - Val.__init__(self, BRO_TYPE_SUBNET, v) - - def __str__(self): - (net, mask) = self.val - return "%s/%d" % (socket.inet_ntoa(struct.pack('=l', net)), mask) - - @staticmethod - def _factory(val, dst_type): - v = subnet(internal=val) - if dst_type == str or not dst_type: - return str(v) - _typeCheck(dst_type, subnet) - return v - - def _parse(self, str): - (net, mask) = str.split("/") - return (struct.unpack('=l',socket.inet_aton(net))[0], int(mask)) - -# Not supported at this point since Broccoli seems to have problems with -# enums. Also need to write parse functions. -class enum(Val): - def __init__(self, str=None, internal=None): - v = internal and internal or self._parse(str) - Val.__init__(self, BRO_TYPE_ENUM, v) - - def __str__(self): - return "XXXX" # FIXME - - @staticmethod - def _factory(val, dst_type): - v = enum(internal=val) - _typeCheck(dst_type, enum) - return v - - def _parse(self, str): - return 0 # FIXME - -# Helper class for unset values. -class unknown(Val): - def __init__(self): - Val.__init__(self, BRO_TYPE_UNKNOWN, None) - -# Dictionary of all defined record types. -RecTypes = {} - -# Type class for records, which maps field names to indices. -# E.g., conn_id = record_type("orig_h", "orig_p", "resp_h", "resp_p") -class record_type: - def __init__(self, *fields): - self.fields = fields - - global RecTypes - # Remember this type by its name. - RecTypes[self.__class__.__name__] = self - - @classmethod - def _factory(self, vals, dst_type): - # FIXME: Add _typeCheck(), - # FIXME: For recursive records we'd need to pass the right record type - # here instead of none, which we don't have. How to do that? - - # Get the type. - rec_type = RecTypes[dst_type.__class__.__name__] - - # Init the field values. - vals = [instantiate(btype, val, None) for (btype, val) in vals] - - return record(rec_type, vals) - -# Class for record instances. -class record(Val): - def __init__(self, type, vals = None): - Val.__init__(self, BRO_TYPE_RECORD, {}) - - # Save the record's type. - self._type = type - - if not vals: - # Use Nones if we didn't get any values. - vals = [None] * len(type.fields) - - # Initialize record fields. - for (key, val) in zip(type.fields, vals): - self.val[key] = val - - def internalVal(self): - vals = [_getInternalVal(self.val.get(f, unknown())) for f in self._type.fields] - return (BRO_TYPE_RECORD, vals) - - # Provide attribute access via "val.attr". - def __getattr__(self, key): - if "_type" in self.__dict__ and key in self._type.fields: - return self.val[key] - raise AttributeError - - def __setattr__(self, key, val): - try: - if key in self._type.fields: - self.val[key] = val - return - except AttributeError: - pass - - # FIXME: Check that key is defined in type. - self.__dict__[key] = val - -# Helper to check whether two Python types match. -def _typeCheck(type1, type2): - def typeToBro(type): - # Do the Python types manually. - if type == int: - return BRO_TYPE_INT; - if type == bool: - return BRO_TYPE_BOOL; - if type == float: - return BRO_TYPE_DOUBLE; - if type == str: - return BRO_TYPE_STRING; - return type._bro_type - - if type1 and type2 and typeToBro(type1) != typeToBro(type2): - raise TypeError - -# Helper to create the 2-tuple val. -def _getInternalVal(arg): - - if arg == None: - raise ValueError("uninitialized event argument") - - if type(arg) == int: - return (BRO_TYPE_INT, arg) - elif type(arg) == bool: - return (BRO_TYPE_BOOL, arg) - elif type(arg) == str: - return(BRO_TYPE_STRING, arg) - elif type(arg) == float: - return(BRO_TYPE_DOUBLE, arg) - else: - return arg.internalVal() - -# Factories for Python internal types. -def _int_factory(val, dst_type): - return int(val) - -def _bool_factory(val, dst_type): - return bool(val) - -def _string_factory(val, dst_type): - return str(val) - -def _float_factory(val, dst_type): - return float(val) - -string = str -double = float - -# Table of factories for all supported types so that we can dynamically -# instantiate them. -_Factories = { - BRO_TYPE_INT: _int_factory, - BRO_TYPE_BOOL: _bool_factory, - BRO_TYPE_COUNT: count._factory, - BRO_TYPE_TIME: time._factory, - BRO_TYPE_INTERVAL: interval._factory, - BRO_TYPE_DOUBLE: _float_factory, - BRO_TYPE_STRING: _string_factory, - BRO_TYPE_PORT: port._factory, - BRO_TYPE_IPADDR: addr._factory, - BRO_TYPE_NET: net._factory, - BRO_TYPE_SUBNET: subnet._factory, - BRO_TYPE_ENUM: enum._factory, - BRO_TYPE_RECORD: record_type._factory, -} - -def instantiate(src_type, val, dst_type): - return _Factories[src_type](val, dst_type) - - - - diff --git a/aux/broccoli/bindings/python/broccoli_intern.i b/aux/broccoli/bindings/python/broccoli_intern.i deleted file mode 100644 index 95e7757f37..0000000000 --- a/aux/broccoli/bindings/python/broccoli_intern.i +++ /dev/null @@ -1,392 +0,0 @@ -// $Id$ - -%module broccoli_intern -%{ -// Include the header in the wrapper code. -#include - -// Broccoli internal struct. Easier to copy that here than to include a bunch -// of Broccoli's internal headers. -struct bro_record { - void *val_list; - int val_len; -}; - -typedef BroRecord bro_record ; - -// Builds a 2-tuple (type, object). -PyObject* makeTypeTuple(int type, PyObject *val) -{ - PyObject *tuple = PyTuple_New(2); - PyTuple_SetItem(tuple, 0, PyInt_FromLong(type)); - PyTuple_SetItem(tuple, 1, val); - return tuple; -} - -// Parses a 2-tuple (type, object). Return 1 on success. -// Borrows input's reference to object. -int parseTypeTuple(PyObject* input, int *type, PyObject **val) -{ - if ( ! (PyTuple_Check(input) && PyTuple_Size(input) == 2) ) { - PyErr_SetString(PyExc_RuntimeError, "argument must be 2-tuple"); - return 0; - } - - PyObject *ptype = PyTuple_GetItem(input, 0); - PyObject *pval = PyTuple_GetItem(input, 1); - - if ( ! PyInt_Check(ptype) ) { - PyErr_SetString(PyExc_RuntimeError, "first tuple element must be integer"); - return 0; - } - - *type = PyInt_AsLong(ptype); - - if ( *type < 0 || *type > BRO_TYPE_MAX ) { - PyErr_SetString(PyExc_RuntimeError, "unknown type in tuple"); - return 0; - } - - *val = pval; - return 1; -} - -// Release the memory associated with the Broccoli value. -void freeBroccoliVal(int type, void* data) -{ - if ( ! data ) - return; - - switch ( type ) { - case BRO_TYPE_STRING: - free(((BroString *)data)->str_val); - free(data); - break; - - case BRO_TYPE_RECORD: - bro_record_free((BroRecord *)data); - break; - - default: - free(data); - } - -} - -// Converts a Broccoli value into a Python object. -PyObject* valToPyObj(int type, void* data) -{ - PyObject* val = 0; - - switch (type) { - case BRO_TYPE_BOOL: - val = PyBool_FromLong(*((int *)data)); - break; - - case BRO_TYPE_INT: - case BRO_TYPE_COUNT: - case BRO_TYPE_COUNTER: - case BRO_TYPE_IPADDR: - case BRO_TYPE_NET: { - val = PyInt_FromLong(*((long *)data)); - break; - } - - case BRO_TYPE_DOUBLE: - case BRO_TYPE_TIME: - case BRO_TYPE_INTERVAL: { - val = PyFloat_FromDouble(*((double *)data)); - break; - } - - case BRO_TYPE_STRING: { - BroString *str = (BroString*)data; - val = PyString_FromStringAndSize(str->str_val, str->str_len); - break; - } - - case BRO_TYPE_ENUM: { - val = PyTuple_New(2); - PyTuple_SetItem(val, 0, PyBool_FromLong(*((int *)data))); - PyTuple_SetItem(val, 1, PyString_FromString("broccoli-doesnt-give-use-the-enum-type! :-(")); - break; - } - - - case BRO_TYPE_PORT: { - BroPort *port = (BroPort*)data; - val = PyTuple_New(2); - PyTuple_SetItem(val, 0, PyInt_FromLong(port->port_num)); - PyTuple_SetItem(val, 1, PyInt_FromLong(port->port_proto)); - break; - } - - case BRO_TYPE_SUBNET: { - BroSubnet *subnet = (BroSubnet*)data; - val = PyTuple_New(2); - PyTuple_SetItem(val, 0, PyInt_FromLong(subnet->sn_net)); - PyTuple_SetItem(val, 1, PyInt_FromLong(subnet->sn_width)); - break; - } - - case BRO_TYPE_RECORD: { - BroRecord *rec = (BroRecord*)data; - PyObject *fields = PyList_New(rec->val_len); - int i; - for ( i = 0; i < rec->val_len; i++ ) { - int type = BRO_TYPE_UNKNOWN; - void *data = bro_record_get_nth_val(rec, i, &type); - PyList_SetItem(fields, i, valToPyObj(type, data)); - } - val = fields; - break; - } - - default: - PyErr_SetString(PyExc_RuntimeError, "unknown type"); - return 0; - - } - - return makeTypeTuple(type, val); -} - -// Converts a Python object into Broccoli value. -int pyObjToVal(PyObject *val, int type, const char **type_name, void** data) -{ - *type_name = 0; - *data = 0; - - switch (type) { - case BRO_TYPE_BOOL: - case BRO_TYPE_INT: - case BRO_TYPE_COUNT: - case BRO_TYPE_COUNTER: - case BRO_TYPE_IPADDR: - case BRO_TYPE_NET: { - int* tmp = (int *)malloc(sizeof(int)); - *tmp = PyInt_AsLong(val); - *data = tmp; - break; - } - - case BRO_TYPE_DOUBLE: - case BRO_TYPE_TIME: - case BRO_TYPE_INTERVAL: { - double* tmp = (double *)malloc(sizeof(double)); - *tmp = PyFloat_AsDouble(val); - *data = tmp; - break; - } - - case BRO_TYPE_STRING: { - BroString* str = (BroString *)malloc(sizeof(BroString)); - - const char* tmp = PyString_AsString(val); - if ( ! tmp ) - return 0; - - str->str_len = strlen(tmp); - str->str_val = strdup(tmp); - *data = str; - break; - } - - case BRO_TYPE_ENUM: { - if ( ! (PyTuple_Check(val) && PyTuple_Size(val) == 2) ) { - PyErr_SetString(PyExc_RuntimeError, "enum must be 2-tuple"); - return 0; - } - - int* tmp = (int *)malloc(sizeof(int)); - *tmp = PyInt_AsLong(PyTuple_GetItem(val, 0)); - *data = tmp; - - const char* enum_type = PyString_AsString(PyTuple_GetItem(val, 1)); - if ( ! enum_type ) - return 0; - - *type_name = strdup(enum_type); - break; - } - - case BRO_TYPE_PORT: { - if ( ! (PyTuple_Check(val) && PyTuple_Size(val) == 2) ) { - PyErr_SetString(PyExc_RuntimeError, "port must be 2-tuple"); - return 0; - } - - BroPort* port = (BroPort *)malloc(sizeof(BroPort)); - port->port_num = PyInt_AsLong(PyTuple_GetItem(val, 0)); - port->port_proto = PyInt_AsLong(PyTuple_GetItem(val, 1)); - *data = port; - break; - } - - case BRO_TYPE_SUBNET: { - if ( ! (PyTuple_Check(val) && PyTuple_Size(val) == 2) ) { - PyErr_SetString(PyExc_RuntimeError, "subnet must be 2-tuple"); - return 0; - } - - BroSubnet* subnet = (BroSubnet *)malloc(sizeof(BroSubnet)); - subnet->sn_net = PyInt_AsLong(PyTuple_GetItem(val, 0)); - subnet->sn_width = PyInt_AsLong(PyTuple_GetItem(val, 1)); - *data = subnet; - break; - } - - case BRO_TYPE_RECORD: { - BroRecord *rec = bro_record_new(); - int i; - for ( i = 0; i < PyList_Size(val); i++ ) { - int ftype; - PyObject *fval; - if ( ! parseTypeTuple(PyList_GetItem(val, i), &ftype, &fval) ) - return 0; - - const char *ftype_name; - void *fdata; - if ( ! pyObjToVal(fval, ftype, &ftype_name, &fdata) ) - return 0; - - bro_record_add_val(rec, "", ftype, 0, fdata); - freeBroccoliVal(ftype, fdata); - } - - *data = rec; - break; - } - - default: - PyErr_SetString(PyExc_RuntimeError, "unknown type"); - return 0; - } - - return 1; -} - -// C-level event handler for events. We register all events with this callback, -// passing the target Python function in via data. -void event_callback(BroConn *bc, void *data, BroEvMeta *meta) -{ - PyObject *func = (PyObject*)data; - - int i; - PyObject *pyargs = PyTuple_New(meta->ev_numargs); - for ( i = 0; i < meta->ev_numargs; i++ ) - PyTuple_SetItem(pyargs, i, valToPyObj(meta->ev_args[i].arg_type, meta->ev_args[i].arg_data)); - - PyObject *result = PyObject_Call(func, pyargs, 0); - - Py_DECREF(pyargs); - - if ( result ) - Py_DECREF(result); -} - -%} - -// For bro_event_registry_add_compact(). -%typemap(in) (BroCompactEventFunc func, void *user_data) -{ - if ( ! PyFunction_Check($input) ) { - PyErr_SetString(PyExc_RuntimeError, "callback must be a function"); - return NULL; - } - - $1 = event_callback; - $2 = $input; - Py_INCREF($input); -} - -// For bro_event_add_val() and bro_record_add_val(). -%typemap(in) (int type, const char *type_name, const void *val) -{ - int type; - const char* type_name; - void *data; - - PyObject *val; - -//bro_debug_messages = 1; -//bro_debug_calltrace = 1; - - - if ( ! parseTypeTuple($input, &type, &val) ) - return NULL; - - if ( ! pyObjToVal(val, type, &type_name, &data) ) - return NULL; - - $1 = type; - $2 = type_name; - $3 = data; -} - -%typemap(freearg) (int type, const char *type_name, const void *val) -{ - // Broccoli makes copies of the passed data so we need to clean up. - freeBroccoliVal($1, $3); - - if ( $2 ) - free($2); -} - -///// The following is a subset of broccoli.h for which we provide wrappers. - -#define BRO_TYPE_UNKNOWN 0 -#define BRO_TYPE_BOOL 1 -#define BRO_TYPE_INT 2 -#define BRO_TYPE_COUNT 3 -#define BRO_TYPE_COUNTER 4 -#define BRO_TYPE_DOUBLE 5 -#define BRO_TYPE_TIME 6 -#define BRO_TYPE_INTERVAL 7 -#define BRO_TYPE_STRING 8 -#define BRO_TYPE_PATTERN 9 -#define BRO_TYPE_ENUM 10 -#define BRO_TYPE_TIMER 11 -#define BRO_TYPE_PORT 12 -#define BRO_TYPE_IPADDR 13 -#define BRO_TYPE_NET 14 -#define BRO_TYPE_SUBNET 15 -#define BRO_TYPE_ANY 16 -#define BRO_TYPE_TABLE 17 -#define BRO_TYPE_UNION 18 -#define BRO_TYPE_RECORD 19 -#define BRO_TYPE_LIST 20 -#define BRO_TYPE_FUNC 21 -#define BRO_TYPE_FILE 22 -#define BRO_TYPE_VECTOR 23 -#define BRO_TYPE_ERROR 24 -#define BRO_TYPE_PACKET 25 -#define BRO_TYPE_SET 26 -#define BRO_TYPE_MAX 27 -#define BRO_CFLAG_NONE 0 -#define BRO_CFLAG_RECONNECT (1 << 0) -#define BRO_CFLAG_ALWAYS_QUEUE (1 << 1) -#define BRO_CFLAG_SHAREABLE (1 << 2) -#define BRO_CFLAG_DONTCACHE (1 << 3) -#define BRO_CFLAG_YIELD (1 << 4) -#define BRO_CFLAG_CACHE (1 << 5) - -// The exact types of these don't really matter as we're only -// passing pointers around. -typedef void BroCtx; -typedef void BroConn; -typedef void BroEvent; - -int bro_init(const BroCtx *ctx); -BroConn *bro_conn_new_str(const char *hostname, int flags); -void bro_conn_set_class(BroConn *bc, const char *classname); -int bro_conn_connect(BroConn *bc); -int bro_conn_process_input(BroConn *bc); -int bro_event_queue_length(BroConn *bc); -BroEvent *bro_event_new(const char *event_name); -void bro_event_free(BroEvent *be); -int bro_event_add_val(BroEvent *be, int type, const char *type_name,const void *val); -int bro_event_send(BroConn *bc, BroEvent *be); -void bro_event_registry_add_compact(BroConn *bc, const char *event_name, BroCompactEventFunc func, void *user_data); -double bro_util_current_time(void); - diff --git a/aux/broccoli/bindings/python/broccoli_intern.py b/aux/broccoli/bindings/python/broccoli_intern.py deleted file mode 100644 index 0acd03f869..0000000000 --- a/aux/broccoli/bindings/python/broccoli_intern.py +++ /dev/null @@ -1,99 +0,0 @@ -# This file was automatically generated by SWIG (http://www.swig.org). -# Version 1.3.31 -# -# Don't modify this file, modify the SWIG interface instead. -# This file is compatible with both classic and new-style classes. - -import _broccoli_intern -import new -new_instancemethod = new.instancemethod -try: - _swig_property = property -except NameError: - pass # Python < 2.2 doesn't have 'property'. -def _swig_setattr_nondynamic(self,class_type,name,value,static=1): - if (name == "thisown"): return self.this.own(value) - if (name == "this"): - if type(value).__name__ == 'PySwigObject': - self.__dict__[name] = value - return - method = class_type.__swig_setmethods__.get(name,None) - if method: return method(self,value) - if (not static) or hasattr(self,name): - self.__dict__[name] = value - else: - raise AttributeError("You cannot add attributes to %s" % self) - -def _swig_setattr(self,class_type,name,value): - return _swig_setattr_nondynamic(self,class_type,name,value,0) - -def _swig_getattr(self,class_type,name): - if (name == "thisown"): return self.this.own() - method = class_type.__swig_getmethods__.get(name,None) - if method: return method(self) - raise AttributeError,name - -def _swig_repr(self): - try: strthis = "proxy of " + self.this.__repr__() - except: strthis = "" - return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,) - -import types -try: - _object = types.ObjectType - _newclass = 1 -except AttributeError: - class _object : pass - _newclass = 0 -del types - - -BRO_TYPE_UNKNOWN = _broccoli_intern.BRO_TYPE_UNKNOWN -BRO_TYPE_BOOL = _broccoli_intern.BRO_TYPE_BOOL -BRO_TYPE_INT = _broccoli_intern.BRO_TYPE_INT -BRO_TYPE_COUNT = _broccoli_intern.BRO_TYPE_COUNT -BRO_TYPE_COUNTER = _broccoli_intern.BRO_TYPE_COUNTER -BRO_TYPE_DOUBLE = _broccoli_intern.BRO_TYPE_DOUBLE -BRO_TYPE_TIME = _broccoli_intern.BRO_TYPE_TIME -BRO_TYPE_INTERVAL = _broccoli_intern.BRO_TYPE_INTERVAL -BRO_TYPE_STRING = _broccoli_intern.BRO_TYPE_STRING -BRO_TYPE_PATTERN = _broccoli_intern.BRO_TYPE_PATTERN -BRO_TYPE_ENUM = _broccoli_intern.BRO_TYPE_ENUM -BRO_TYPE_TIMER = _broccoli_intern.BRO_TYPE_TIMER -BRO_TYPE_PORT = _broccoli_intern.BRO_TYPE_PORT -BRO_TYPE_IPADDR = _broccoli_intern.BRO_TYPE_IPADDR -BRO_TYPE_NET = _broccoli_intern.BRO_TYPE_NET -BRO_TYPE_SUBNET = _broccoli_intern.BRO_TYPE_SUBNET -BRO_TYPE_ANY = _broccoli_intern.BRO_TYPE_ANY -BRO_TYPE_TABLE = _broccoli_intern.BRO_TYPE_TABLE -BRO_TYPE_UNION = _broccoli_intern.BRO_TYPE_UNION -BRO_TYPE_RECORD = _broccoli_intern.BRO_TYPE_RECORD -BRO_TYPE_LIST = _broccoli_intern.BRO_TYPE_LIST -BRO_TYPE_FUNC = _broccoli_intern.BRO_TYPE_FUNC -BRO_TYPE_FILE = _broccoli_intern.BRO_TYPE_FILE -BRO_TYPE_VECTOR = _broccoli_intern.BRO_TYPE_VECTOR -BRO_TYPE_ERROR = _broccoli_intern.BRO_TYPE_ERROR -BRO_TYPE_PACKET = _broccoli_intern.BRO_TYPE_PACKET -BRO_TYPE_SET = _broccoli_intern.BRO_TYPE_SET -BRO_TYPE_MAX = _broccoli_intern.BRO_TYPE_MAX -BRO_CFLAG_NONE = _broccoli_intern.BRO_CFLAG_NONE -BRO_CFLAG_RECONNECT = _broccoli_intern.BRO_CFLAG_RECONNECT -BRO_CFLAG_ALWAYS_QUEUE = _broccoli_intern.BRO_CFLAG_ALWAYS_QUEUE -BRO_CFLAG_SHAREABLE = _broccoli_intern.BRO_CFLAG_SHAREABLE -BRO_CFLAG_DONTCACHE = _broccoli_intern.BRO_CFLAG_DONTCACHE -BRO_CFLAG_YIELD = _broccoli_intern.BRO_CFLAG_YIELD -BRO_CFLAG_CACHE = _broccoli_intern.BRO_CFLAG_CACHE -bro_init = _broccoli_intern.bro_init -bro_conn_new_str = _broccoli_intern.bro_conn_new_str -bro_conn_set_class = _broccoli_intern.bro_conn_set_class -bro_conn_connect = _broccoli_intern.bro_conn_connect -bro_conn_process_input = _broccoli_intern.bro_conn_process_input -bro_event_queue_length = _broccoli_intern.bro_event_queue_length -bro_event_new = _broccoli_intern.bro_event_new -bro_event_free = _broccoli_intern.bro_event_free -bro_event_add_val = _broccoli_intern.bro_event_add_val -bro_event_send = _broccoli_intern.bro_event_send -bro_event_registry_add_compact = _broccoli_intern.bro_event_registry_add_compact -bro_util_current_time = _broccoli_intern.bro_util_current_time - - diff --git a/aux/broccoli/bindings/python/broccoli_intern_wrap.c b/aux/broccoli/bindings/python/broccoli_intern_wrap.c deleted file mode 100644 index fdae51ce8c..0000000000 --- a/aux/broccoli/bindings/python/broccoli_intern_wrap.c +++ /dev/null @@ -1,3922 +0,0 @@ -/* ---------------------------------------------------------------------------- - * This file was automatically generated by SWIG (http://www.swig.org). - * Version 1.3.31 - * - * This file is not intended to be easily readable and contains a number of - * coding conventions designed to improve portability and efficiency. Do not make - * changes to this file unless you know what you are doing--modify the SWIG - * interface file instead. - * ----------------------------------------------------------------------------- */ - -#define SWIGPYTHON -#define SWIG_PYTHON_DIRECTOR_NO_VTABLE -/* ----------------------------------------------------------------------------- - * This section contains generic SWIG labels for method/variable - * declarations/attributes, and other compiler dependent labels. - * ----------------------------------------------------------------------------- */ - -/* template workaround for compilers that cannot correctly implement the C++ standard */ -#ifndef SWIGTEMPLATEDISAMBIGUATOR -# if defined(__SUNPRO_CC) -# if (__SUNPRO_CC <= 0x560) -# define SWIGTEMPLATEDISAMBIGUATOR template -# else -# define SWIGTEMPLATEDISAMBIGUATOR -# endif -# else -# define SWIGTEMPLATEDISAMBIGUATOR -# endif -#endif - -/* inline attribute */ -#ifndef SWIGINLINE -# if defined(__cplusplus) || (defined(__GNUC__) && !defined(__STRICT_ANSI__)) -# define SWIGINLINE inline -# else -# define SWIGINLINE -# endif -#endif - -/* attribute recognised by some compilers to avoid 'unused' warnings */ -#ifndef SWIGUNUSED -# if defined(__GNUC__) -# if !(defined(__cplusplus)) || (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -# elif defined(__ICC) -# define SWIGUNUSED __attribute__ ((__unused__)) -# else -# define SWIGUNUSED -# endif -#endif - -#ifndef SWIGUNUSEDPARM -# ifdef __cplusplus -# define SWIGUNUSEDPARM(p) -# else -# define SWIGUNUSEDPARM(p) p SWIGUNUSED -# endif -#endif - -/* internal SWIG method */ -#ifndef SWIGINTERN -# define SWIGINTERN static SWIGUNUSED -#endif - -/* internal inline SWIG method */ -#ifndef SWIGINTERNINLINE -# define SWIGINTERNINLINE SWIGINTERN SWIGINLINE -#endif - -/* exporting methods */ -#if (__GNUC__ >= 4) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) -# ifndef GCC_HASCLASSVISIBILITY -# define GCC_HASCLASSVISIBILITY -# endif -#endif - -#ifndef SWIGEXPORT -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# if defined(STATIC_LINKED) -# define SWIGEXPORT -# else -# define SWIGEXPORT __declspec(dllexport) -# endif -# else -# if defined(__GNUC__) && defined(GCC_HASCLASSVISIBILITY) -# define SWIGEXPORT __attribute__ ((visibility("default"))) -# else -# define SWIGEXPORT -# endif -# endif -#endif - -/* calling conventions for Windows */ -#ifndef SWIGSTDCALL -# if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# define SWIGSTDCALL __stdcall -# else -# define SWIGSTDCALL -# endif -#endif - -/* Deal with Microsoft's attempt at deprecating C standard runtime functions */ -#if !defined(SWIG_NO_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) && !defined(_CRT_SECURE_NO_DEPRECATE) -# define _CRT_SECURE_NO_DEPRECATE -#endif - - -/* Python.h has to appear first */ -#include - -/* ----------------------------------------------------------------------------- - * swigrun.swg - * - * This file contains generic CAPI SWIG runtime support for pointer - * type checking. - * ----------------------------------------------------------------------------- */ - -/* This should only be incremented when either the layout of swig_type_info changes, - or for whatever reason, the runtime changes incompatibly */ -#define SWIG_RUNTIME_VERSION "3" - -/* define SWIG_TYPE_TABLE_NAME as "SWIG_TYPE_TABLE" */ -#ifdef SWIG_TYPE_TABLE -# define SWIG_QUOTE_STRING(x) #x -# define SWIG_EXPAND_AND_QUOTE_STRING(x) SWIG_QUOTE_STRING(x) -# define SWIG_TYPE_TABLE_NAME SWIG_EXPAND_AND_QUOTE_STRING(SWIG_TYPE_TABLE) -#else -# define SWIG_TYPE_TABLE_NAME -#endif - -/* - You can use the SWIGRUNTIME and SWIGRUNTIMEINLINE macros for - creating a static or dynamic library from the swig runtime code. - In 99.9% of the cases, swig just needs to declare them as 'static'. - - But only do this if is strictly necessary, ie, if you have problems - with your compiler or so. -*/ - -#ifndef SWIGRUNTIME -# define SWIGRUNTIME SWIGINTERN -#endif - -#ifndef SWIGRUNTIMEINLINE -# define SWIGRUNTIMEINLINE SWIGRUNTIME SWIGINLINE -#endif - -/* Generic buffer size */ -#ifndef SWIG_BUFFER_SIZE -# define SWIG_BUFFER_SIZE 1024 -#endif - -/* Flags for pointer conversions */ -#define SWIG_POINTER_DISOWN 0x1 - -/* Flags for new pointer objects */ -#define SWIG_POINTER_OWN 0x1 - - -/* - Flags/methods for returning states. - - The swig conversion methods, as ConvertPtr, return and integer - that tells if the conversion was successful or not. And if not, - an error code can be returned (see swigerrors.swg for the codes). - - Use the following macros/flags to set or process the returning - states. - - In old swig versions, you usually write code as: - - if (SWIG_ConvertPtr(obj,vptr,ty.flags) != -1) { - // success code - } else { - //fail code - } - - Now you can be more explicit as: - - int res = SWIG_ConvertPtr(obj,vptr,ty.flags); - if (SWIG_IsOK(res)) { - // success code - } else { - // fail code - } - - that seems to be the same, but now you can also do - - Type *ptr; - int res = SWIG_ConvertPtr(obj,(void **)(&ptr),ty.flags); - if (SWIG_IsOK(res)) { - // success code - if (SWIG_IsNewObj(res) { - ... - delete *ptr; - } else { - ... - } - } else { - // fail code - } - - I.e., now SWIG_ConvertPtr can return new objects and you can - identify the case and take care of the deallocation. Of course that - requires also to SWIG_ConvertPtr to return new result values, as - - int SWIG_ConvertPtr(obj, ptr,...) { - if () { - if () { - *ptr = ; - return SWIG_NEWOBJ; - } else { - *ptr = ; - return SWIG_OLDOBJ; - } - } else { - return SWIG_BADOBJ; - } - } - - Of course, returning the plain '0(success)/-1(fail)' still works, but you can be - more explicit by returning SWIG_BADOBJ, SWIG_ERROR or any of the - swig errors code. - - Finally, if the SWIG_CASTRANK_MODE is enabled, the result code - allows to return the 'cast rank', for example, if you have this - - int food(double) - int fooi(int); - - and you call - - food(1) // cast rank '1' (1 -> 1.0) - fooi(1) // cast rank '0' - - just use the SWIG_AddCast()/SWIG_CheckState() - - - */ -#define SWIG_OK (0) -#define SWIG_ERROR (-1) -#define SWIG_IsOK(r) (r >= 0) -#define SWIG_ArgError(r) ((r != SWIG_ERROR) ? r : SWIG_TypeError) - -/* The CastRankLimit says how many bits are used for the cast rank */ -#define SWIG_CASTRANKLIMIT (1 << 8) -/* The NewMask denotes the object was created (using new/malloc) */ -#define SWIG_NEWOBJMASK (SWIG_CASTRANKLIMIT << 1) -/* The TmpMask is for in/out typemaps that use temporal objects */ -#define SWIG_TMPOBJMASK (SWIG_NEWOBJMASK << 1) -/* Simple returning values */ -#define SWIG_BADOBJ (SWIG_ERROR) -#define SWIG_OLDOBJ (SWIG_OK) -#define SWIG_NEWOBJ (SWIG_OK | SWIG_NEWOBJMASK) -#define SWIG_TMPOBJ (SWIG_OK | SWIG_TMPOBJMASK) -/* Check, add and del mask methods */ -#define SWIG_AddNewMask(r) (SWIG_IsOK(r) ? (r | SWIG_NEWOBJMASK) : r) -#define SWIG_DelNewMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_NEWOBJMASK) : r) -#define SWIG_IsNewObj(r) (SWIG_IsOK(r) && (r & SWIG_NEWOBJMASK)) -#define SWIG_AddTmpMask(r) (SWIG_IsOK(r) ? (r | SWIG_TMPOBJMASK) : r) -#define SWIG_DelTmpMask(r) (SWIG_IsOK(r) ? (r & ~SWIG_TMPOBJMASK) : r) -#define SWIG_IsTmpObj(r) (SWIG_IsOK(r) && (r & SWIG_TMPOBJMASK)) - - -/* Cast-Rank Mode */ -#if defined(SWIG_CASTRANK_MODE) -# ifndef SWIG_TypeRank -# define SWIG_TypeRank unsigned long -# endif -# ifndef SWIG_MAXCASTRANK /* Default cast allowed */ -# define SWIG_MAXCASTRANK (2) -# endif -# define SWIG_CASTRANKMASK ((SWIG_CASTRANKLIMIT) -1) -# define SWIG_CastRank(r) (r & SWIG_CASTRANKMASK) -SWIGINTERNINLINE int SWIG_AddCast(int r) { - return SWIG_IsOK(r) ? ((SWIG_CastRank(r) < SWIG_MAXCASTRANK) ? (r + 1) : SWIG_ERROR) : r; -} -SWIGINTERNINLINE int SWIG_CheckState(int r) { - return SWIG_IsOK(r) ? SWIG_CastRank(r) + 1 : 0; -} -#else /* no cast-rank mode */ -# define SWIG_AddCast -# define SWIG_CheckState(r) (SWIG_IsOK(r) ? 1 : 0) -#endif - - - - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void *(*swig_converter_func)(void *); -typedef struct swig_type_info *(*swig_dycast_func)(void **); - -/* Structure to store inforomation on one type */ -typedef struct swig_type_info { - const char *name; /* mangled name of this type */ - const char *str; /* human readable name of this type */ - swig_dycast_func dcast; /* dynamic cast function down a hierarchy */ - struct swig_cast_info *cast; /* linked list of types that can cast into this type */ - void *clientdata; /* language specific type data */ - int owndata; /* flag if the structure owns the clientdata */ -} swig_type_info; - -/* Structure to store a type and conversion function used for casting */ -typedef struct swig_cast_info { - swig_type_info *type; /* pointer to type that is equivalent to this type */ - swig_converter_func converter; /* function to cast the void pointers */ - struct swig_cast_info *next; /* pointer to next cast in linked list */ - struct swig_cast_info *prev; /* pointer to the previous cast */ -} swig_cast_info; - -/* Structure used to store module information - * Each module generates one structure like this, and the runtime collects - * all of these structures and stores them in a circularly linked list.*/ -typedef struct swig_module_info { - swig_type_info **types; /* Array of pointers to swig_type_info structures that are in this module */ - size_t size; /* Number of types in this module */ - struct swig_module_info *next; /* Pointer to next element in circularly linked list */ - swig_type_info **type_initial; /* Array of initially generated type structures */ - swig_cast_info **cast_initial; /* Array of initially generated casting structures */ - void *clientdata; /* Language specific module data */ -} swig_module_info; - -/* - Compare two type names skipping the space characters, therefore - "char*" == "char *" and "Class" == "Class", etc. - - Return 0 when the two name types are equivalent, as in - strncmp, but skipping ' '. -*/ -SWIGRUNTIME int -SWIG_TypeNameComp(const char *f1, const char *l1, - const char *f2, const char *l2) { - for (;(f1 != l1) && (f2 != l2); ++f1, ++f2) { - while ((*f1 == ' ') && (f1 != l1)) ++f1; - while ((*f2 == ' ') && (f2 != l2)) ++f2; - if (*f1 != *f2) return (*f1 > *f2) ? 1 : -1; - } - return (l1 - f1) - (l2 - f2); -} - -/* - Check type equivalence in a name list like ||... - Return 0 if not equal, 1 if equal -*/ -SWIGRUNTIME int -SWIG_TypeEquiv(const char *nb, const char *tb) { - int equiv = 0; - const char* te = tb + strlen(tb); - const char* ne = nb; - while (!equiv && *ne) { - for (nb = ne; *ne; ++ne) { - if (*ne == '|') break; - } - equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; - if (*ne) ++ne; - } - return equiv; -} - -/* - Check type equivalence in a name list like ||... - Return 0 if equal, -1 if nb < tb, 1 if nb > tb -*/ -SWIGRUNTIME int -SWIG_TypeCompare(const char *nb, const char *tb) { - int equiv = 0; - const char* te = tb + strlen(tb); - const char* ne = nb; - while (!equiv && *ne) { - for (nb = ne; *ne; ++ne) { - if (*ne == '|') break; - } - equiv = (SWIG_TypeNameComp(nb, ne, tb, te) == 0) ? 1 : 0; - if (*ne) ++ne; - } - return equiv; -} - - -/* think of this as a c++ template<> or a scheme macro */ -#define SWIG_TypeCheck_Template(comparison, ty) \ - if (ty) { \ - swig_cast_info *iter = ty->cast; \ - while (iter) { \ - if (comparison) { \ - if (iter == ty->cast) return iter; \ - /* Move iter to the top of the linked list */ \ - iter->prev->next = iter->next; \ - if (iter->next) \ - iter->next->prev = iter->prev; \ - iter->next = ty->cast; \ - iter->prev = 0; \ - if (ty->cast) ty->cast->prev = iter; \ - ty->cast = iter; \ - return iter; \ - } \ - iter = iter->next; \ - } \ - } \ - return 0 - -/* - Check the typename -*/ -SWIGRUNTIME swig_cast_info * -SWIG_TypeCheck(const char *c, swig_type_info *ty) { - SWIG_TypeCheck_Template(strcmp(iter->type->name, c) == 0, ty); -} - -/* Same as previous function, except strcmp is replaced with a pointer comparison */ -SWIGRUNTIME swig_cast_info * -SWIG_TypeCheckStruct(swig_type_info *from, swig_type_info *into) { - SWIG_TypeCheck_Template(iter->type == from, into); -} - -/* - Cast a pointer up an inheritance hierarchy -*/ -SWIGRUNTIMEINLINE void * -SWIG_TypeCast(swig_cast_info *ty, void *ptr) { - return ((!ty) || (!ty->converter)) ? ptr : (*ty->converter)(ptr); -} - -/* - Dynamic pointer casting. Down an inheritance hierarchy -*/ -SWIGRUNTIME swig_type_info * -SWIG_TypeDynamicCast(swig_type_info *ty, void **ptr) { - swig_type_info *lastty = ty; - if (!ty || !ty->dcast) return ty; - while (ty && (ty->dcast)) { - ty = (*ty->dcast)(ptr); - if (ty) lastty = ty; - } - return lastty; -} - -/* - Return the name associated with this type -*/ -SWIGRUNTIMEINLINE const char * -SWIG_TypeName(const swig_type_info *ty) { - return ty->name; -} - -/* - Return the pretty name associated with this type, - that is an unmangled type name in a form presentable to the user. -*/ -SWIGRUNTIME const char * -SWIG_TypePrettyName(const swig_type_info *type) { - /* The "str" field contains the equivalent pretty names of the - type, separated by vertical-bar characters. We choose - to print the last name, as it is often (?) the most - specific. */ - if (!type) return NULL; - if (type->str != NULL) { - const char *last_name = type->str; - const char *s; - for (s = type->str; *s; s++) - if (*s == '|') last_name = s+1; - return last_name; - } - else - return type->name; -} - -/* - Set the clientdata field for a type -*/ -SWIGRUNTIME void -SWIG_TypeClientData(swig_type_info *ti, void *clientdata) { - swig_cast_info *cast = ti->cast; - /* if (ti->clientdata == clientdata) return; */ - ti->clientdata = clientdata; - - while (cast) { - if (!cast->converter) { - swig_type_info *tc = cast->type; - if (!tc->clientdata) { - SWIG_TypeClientData(tc, clientdata); - } - } - cast = cast->next; - } -} -SWIGRUNTIME void -SWIG_TypeNewClientData(swig_type_info *ti, void *clientdata) { - SWIG_TypeClientData(ti, clientdata); - ti->owndata = 1; -} - -/* - Search for a swig_type_info structure only by mangled name - Search is a O(log #types) - - We start searching at module start, and finish searching when start == end. - Note: if start == end at the beginning of the function, we go all the way around - the circular list. -*/ -SWIGRUNTIME swig_type_info * -SWIG_MangledTypeQueryModule(swig_module_info *start, - swig_module_info *end, - const char *name) { - swig_module_info *iter = start; - do { - if (iter->size) { - register size_t l = 0; - register size_t r = iter->size - 1; - do { - /* since l+r >= 0, we can (>> 1) instead (/ 2) */ - register size_t i = (l + r) >> 1; - const char *iname = iter->types[i]->name; - if (iname) { - register int compare = strcmp(name, iname); - if (compare == 0) { - return iter->types[i]; - } else if (compare < 0) { - if (i) { - r = i - 1; - } else { - break; - } - } else if (compare > 0) { - l = i + 1; - } - } else { - break; /* should never happen */ - } - } while (l <= r); - } - iter = iter->next; - } while (iter != end); - return 0; -} - -/* - Search for a swig_type_info structure for either a mangled name or a human readable name. - It first searches the mangled names of the types, which is a O(log #types) - If a type is not found it then searches the human readable names, which is O(#types). - - We start searching at module start, and finish searching when start == end. - Note: if start == end at the beginning of the function, we go all the way around - the circular list. -*/ -SWIGRUNTIME swig_type_info * -SWIG_TypeQueryModule(swig_module_info *start, - swig_module_info *end, - const char *name) { - /* STEP 1: Search the name field using binary search */ - swig_type_info *ret = SWIG_MangledTypeQueryModule(start, end, name); - if (ret) { - return ret; - } else { - /* STEP 2: If the type hasn't been found, do a complete search - of the str field (the human readable name) */ - swig_module_info *iter = start; - do { - register size_t i = 0; - for (; i < iter->size; ++i) { - if (iter->types[i]->str && (SWIG_TypeEquiv(iter->types[i]->str, name))) - return iter->types[i]; - } - iter = iter->next; - } while (iter != end); - } - - /* neither found a match */ - return 0; -} - -/* - Pack binary data into a string -*/ -SWIGRUNTIME char * -SWIG_PackData(char *c, void *ptr, size_t sz) { - static const char hex[17] = "0123456789abcdef"; - register const unsigned char *u = (unsigned char *) ptr; - register const unsigned char *eu = u + sz; - for (; u != eu; ++u) { - register unsigned char uu = *u; - *(c++) = hex[(uu & 0xf0) >> 4]; - *(c++) = hex[uu & 0xf]; - } - return c; -} - -/* - Unpack binary data from a string -*/ -SWIGRUNTIME const char * -SWIG_UnpackData(const char *c, void *ptr, size_t sz) { - register unsigned char *u = (unsigned char *) ptr; - register const unsigned char *eu = u + sz; - for (; u != eu; ++u) { - register char d = *(c++); - register unsigned char uu; - if ((d >= '0') && (d <= '9')) - uu = ((d - '0') << 4); - else if ((d >= 'a') && (d <= 'f')) - uu = ((d - ('a'-10)) << 4); - else - return (char *) 0; - d = *(c++); - if ((d >= '0') && (d <= '9')) - uu |= (d - '0'); - else if ((d >= 'a') && (d <= 'f')) - uu |= (d - ('a'-10)); - else - return (char *) 0; - *u = uu; - } - return c; -} - -/* - Pack 'void *' into a string buffer. -*/ -SWIGRUNTIME char * -SWIG_PackVoidPtr(char *buff, void *ptr, const char *name, size_t bsz) { - char *r = buff; - if ((2*sizeof(void *) + 2) > bsz) return 0; - *(r++) = '_'; - r = SWIG_PackData(r,&ptr,sizeof(void *)); - if (strlen(name) + 1 > (bsz - (r - buff))) return 0; - strcpy(r,name); - return buff; -} - -SWIGRUNTIME const char * -SWIG_UnpackVoidPtr(const char *c, void **ptr, const char *name) { - if (*c != '_') { - if (strcmp(c,"NULL") == 0) { - *ptr = (void *) 0; - return name; - } else { - return 0; - } - } - return SWIG_UnpackData(++c,ptr,sizeof(void *)); -} - -SWIGRUNTIME char * -SWIG_PackDataName(char *buff, void *ptr, size_t sz, const char *name, size_t bsz) { - char *r = buff; - size_t lname = (name ? strlen(name) : 0); - if ((2*sz + 2 + lname) > bsz) return 0; - *(r++) = '_'; - r = SWIG_PackData(r,ptr,sz); - if (lname) { - strncpy(r,name,lname+1); - } else { - *r = 0; - } - return buff; -} - -SWIGRUNTIME const char * -SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) { - if (*c != '_') { - if (strcmp(c,"NULL") == 0) { - memset(ptr,0,sz); - return name; - } else { - return 0; - } - } - return SWIG_UnpackData(++c,ptr,sz); -} - -#ifdef __cplusplus -} -#endif - -/* Errors in SWIG */ -#define SWIG_UnknownError -1 -#define SWIG_IOError -2 -#define SWIG_RuntimeError -3 -#define SWIG_IndexError -4 -#define SWIG_TypeError -5 -#define SWIG_DivisionByZero -6 -#define SWIG_OverflowError -7 -#define SWIG_SyntaxError -8 -#define SWIG_ValueError -9 -#define SWIG_SystemError -10 -#define SWIG_AttributeError -11 -#define SWIG_MemoryError -12 -#define SWIG_NullReferenceError -13 - - - - -/* Add PyOS_snprintf for old Pythons */ -#if PY_VERSION_HEX < 0x02020000 -# if defined(_MSC_VER) || defined(__BORLANDC__) || defined(_WATCOM) -# define PyOS_snprintf _snprintf -# else -# define PyOS_snprintf snprintf -# endif -#endif - -/* A crude PyString_FromFormat implementation for old Pythons */ -#if PY_VERSION_HEX < 0x02020000 - -#ifndef SWIG_PYBUFFER_SIZE -# define SWIG_PYBUFFER_SIZE 1024 -#endif - -static PyObject * -PyString_FromFormat(const char *fmt, ...) { - va_list ap; - char buf[SWIG_PYBUFFER_SIZE * 2]; - int res; - va_start(ap, fmt); - res = vsnprintf(buf, sizeof(buf), fmt, ap); - va_end(ap); - return (res < 0 || res >= (int)sizeof(buf)) ? 0 : PyString_FromString(buf); -} -#endif - -/* Add PyObject_Del for old Pythons */ -#if PY_VERSION_HEX < 0x01060000 -# define PyObject_Del(op) PyMem_DEL((op)) -#endif -#ifndef PyObject_DEL -# define PyObject_DEL PyObject_Del -#endif - -/* A crude PyExc_StopIteration exception for old Pythons */ -#if PY_VERSION_HEX < 0x02020000 -# ifndef PyExc_StopIteration -# define PyExc_StopIteration PyExc_RuntimeError -# endif -# ifndef PyObject_GenericGetAttr -# define PyObject_GenericGetAttr 0 -# endif -#endif -/* Py_NotImplemented is defined in 2.1 and up. */ -#if PY_VERSION_HEX < 0x02010000 -# ifndef Py_NotImplemented -# define Py_NotImplemented PyExc_RuntimeError -# endif -#endif - - -/* A crude PyString_AsStringAndSize implementation for old Pythons */ -#if PY_VERSION_HEX < 0x02010000 -# ifndef PyString_AsStringAndSize -# define PyString_AsStringAndSize(obj, s, len) {*s = PyString_AsString(obj); *len = *s ? strlen(*s) : 0;} -# endif -#endif - -/* PySequence_Size for old Pythons */ -#if PY_VERSION_HEX < 0x02000000 -# ifndef PySequence_Size -# define PySequence_Size PySequence_Length -# endif -#endif - - -/* PyBool_FromLong for old Pythons */ -#if PY_VERSION_HEX < 0x02030000 -static -PyObject *PyBool_FromLong(long ok) -{ - PyObject *result = ok ? Py_True : Py_False; - Py_INCREF(result); - return result; -} -#endif - -/* Py_ssize_t for old Pythons */ -/* This code is as recommended by: */ -/* http://www.python.org/dev/peps/pep-0353/#conversion-guidelines */ -#if PY_VERSION_HEX < 0x02050000 && !defined(PY_SSIZE_T_MIN) -typedef int Py_ssize_t; -# define PY_SSIZE_T_MAX INT_MAX -# define PY_SSIZE_T_MIN INT_MIN -#endif - -/* ----------------------------------------------------------------------------- - * error manipulation - * ----------------------------------------------------------------------------- */ - -SWIGRUNTIME PyObject* -SWIG_Python_ErrorType(int code) { - PyObject* type = 0; - switch(code) { - case SWIG_MemoryError: - type = PyExc_MemoryError; - break; - case SWIG_IOError: - type = PyExc_IOError; - break; - case SWIG_RuntimeError: - type = PyExc_RuntimeError; - break; - case SWIG_IndexError: - type = PyExc_IndexError; - break; - case SWIG_TypeError: - type = PyExc_TypeError; - break; - case SWIG_DivisionByZero: - type = PyExc_ZeroDivisionError; - break; - case SWIG_OverflowError: - type = PyExc_OverflowError; - break; - case SWIG_SyntaxError: - type = PyExc_SyntaxError; - break; - case SWIG_ValueError: - type = PyExc_ValueError; - break; - case SWIG_SystemError: - type = PyExc_SystemError; - break; - case SWIG_AttributeError: - type = PyExc_AttributeError; - break; - default: - type = PyExc_RuntimeError; - } - return type; -} - - -SWIGRUNTIME void -SWIG_Python_AddErrorMsg(const char* mesg) -{ - PyObject *type = 0; - PyObject *value = 0; - PyObject *traceback = 0; - - if (PyErr_Occurred()) PyErr_Fetch(&type, &value, &traceback); - if (value) { - PyObject *old_str = PyObject_Str(value); - PyErr_Clear(); - Py_XINCREF(type); - PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg); - Py_DECREF(old_str); - Py_DECREF(value); - } else { - PyErr_Format(PyExc_RuntimeError, mesg); - } -} - - - -#if defined(SWIG_PYTHON_NO_THREADS) -# if defined(SWIG_PYTHON_THREADS) -# undef SWIG_PYTHON_THREADS -# endif -#endif -#if defined(SWIG_PYTHON_THREADS) /* Threading support is enabled */ -# if !defined(SWIG_PYTHON_USE_GIL) && !defined(SWIG_PYTHON_NO_USE_GIL) -# if (PY_VERSION_HEX >= 0x02030000) /* For 2.3 or later, use the PyGILState calls */ -# define SWIG_PYTHON_USE_GIL -# endif -# endif -# if defined(SWIG_PYTHON_USE_GIL) /* Use PyGILState threads calls */ -# ifndef SWIG_PYTHON_INITIALIZE_THREADS -# define SWIG_PYTHON_INITIALIZE_THREADS PyEval_InitThreads() -# endif -# ifdef __cplusplus /* C++ code */ - class SWIG_Python_Thread_Block { - bool status; - PyGILState_STATE state; - public: - void end() { if (status) { PyGILState_Release(state); status = false;} } - SWIG_Python_Thread_Block() : status(true), state(PyGILState_Ensure()) {} - ~SWIG_Python_Thread_Block() { end(); } - }; - class SWIG_Python_Thread_Allow { - bool status; - PyThreadState *save; - public: - void end() { if (status) { PyEval_RestoreThread(save); status = false; }} - SWIG_Python_Thread_Allow() : status(true), save(PyEval_SaveThread()) {} - ~SWIG_Python_Thread_Allow() { end(); } - }; -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK SWIG_Python_Thread_Block _swig_thread_block -# define SWIG_PYTHON_THREAD_END_BLOCK _swig_thread_block.end() -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW SWIG_Python_Thread_Allow _swig_thread_allow -# define SWIG_PYTHON_THREAD_END_ALLOW _swig_thread_allow.end() -# else /* C code */ -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK PyGILState_STATE _swig_thread_block = PyGILState_Ensure() -# define SWIG_PYTHON_THREAD_END_BLOCK PyGILState_Release(_swig_thread_block) -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW PyThreadState *_swig_thread_allow = PyEval_SaveThread() -# define SWIG_PYTHON_THREAD_END_ALLOW PyEval_RestoreThread(_swig_thread_allow) -# endif -# else /* Old thread way, not implemented, user must provide it */ -# if !defined(SWIG_PYTHON_INITIALIZE_THREADS) -# define SWIG_PYTHON_INITIALIZE_THREADS -# endif -# if !defined(SWIG_PYTHON_THREAD_BEGIN_BLOCK) -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK -# endif -# if !defined(SWIG_PYTHON_THREAD_END_BLOCK) -# define SWIG_PYTHON_THREAD_END_BLOCK -# endif -# if !defined(SWIG_PYTHON_THREAD_BEGIN_ALLOW) -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW -# endif -# if !defined(SWIG_PYTHON_THREAD_END_ALLOW) -# define SWIG_PYTHON_THREAD_END_ALLOW -# endif -# endif -#else /* No thread support */ -# define SWIG_PYTHON_INITIALIZE_THREADS -# define SWIG_PYTHON_THREAD_BEGIN_BLOCK -# define SWIG_PYTHON_THREAD_END_BLOCK -# define SWIG_PYTHON_THREAD_BEGIN_ALLOW -# define SWIG_PYTHON_THREAD_END_ALLOW -#endif - -/* ----------------------------------------------------------------------------- - * Python API portion that goes into the runtime - * ----------------------------------------------------------------------------- */ - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* cc-mode */ -#endif -#endif - -/* ----------------------------------------------------------------------------- - * Constant declarations - * ----------------------------------------------------------------------------- */ - -/* Constant Types */ -#define SWIG_PY_POINTER 4 -#define SWIG_PY_BINARY 5 - -/* Constant information structure */ -typedef struct swig_const_info { - int type; - char *name; - long lvalue; - double dvalue; - void *pvalue; - swig_type_info **ptype; -} swig_const_info; - -#ifdef __cplusplus -#if 0 -{ /* cc-mode */ -#endif -} -#endif - - -/* ----------------------------------------------------------------------------- - * See the LICENSE file for information on copyright, usage and redistribution - * of SWIG, and the README file for authors - http://www.swig.org/release.html. - * - * pyrun.swg - * - * This file contains the runtime support for Python modules - * and includes code for managing global variables and pointer - * type checking. - * - * ----------------------------------------------------------------------------- */ - -/* Common SWIG API */ - -/* for raw pointers */ -#define SWIG_Python_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, 0) -#define SWIG_ConvertPtr(obj, pptr, type, flags) SWIG_Python_ConvertPtr(obj, pptr, type, flags) -#define SWIG_ConvertPtrAndOwn(obj,pptr,type,flags,own) SWIG_Python_ConvertPtrAndOwn(obj, pptr, type, flags, own) -#define SWIG_NewPointerObj(ptr, type, flags) SWIG_Python_NewPointerObj(ptr, type, flags) -#define SWIG_CheckImplicit(ty) SWIG_Python_CheckImplicit(ty) -#define SWIG_AcquirePtr(ptr, src) SWIG_Python_AcquirePtr(ptr, src) -#define swig_owntype int - -/* for raw packed data */ -#define SWIG_ConvertPacked(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) -#define SWIG_NewPackedObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) - -/* for class or struct pointers */ -#define SWIG_ConvertInstance(obj, pptr, type, flags) SWIG_ConvertPtr(obj, pptr, type, flags) -#define SWIG_NewInstanceObj(ptr, type, flags) SWIG_NewPointerObj(ptr, type, flags) - -/* for C or C++ function pointers */ -#define SWIG_ConvertFunctionPtr(obj, pptr, type) SWIG_Python_ConvertFunctionPtr(obj, pptr, type) -#define SWIG_NewFunctionPtrObj(ptr, type) SWIG_Python_NewPointerObj(ptr, type, 0) - -/* for C++ member pointers, ie, member methods */ -#define SWIG_ConvertMember(obj, ptr, sz, ty) SWIG_Python_ConvertPacked(obj, ptr, sz, ty) -#define SWIG_NewMemberObj(ptr, sz, type) SWIG_Python_NewPackedObj(ptr, sz, type) - - -/* Runtime API */ - -#define SWIG_GetModule(clientdata) SWIG_Python_GetModule() -#define SWIG_SetModule(clientdata, pointer) SWIG_Python_SetModule(pointer) -#define SWIG_NewClientData(obj) PySwigClientData_New(obj) - -#define SWIG_SetErrorObj SWIG_Python_SetErrorObj -#define SWIG_SetErrorMsg SWIG_Python_SetErrorMsg -#define SWIG_ErrorType(code) SWIG_Python_ErrorType(code) -#define SWIG_Error(code, msg) SWIG_Python_SetErrorMsg(SWIG_ErrorType(code), msg) -#define SWIG_fail goto fail - - -/* Runtime API implementation */ - -/* Error manipulation */ - -SWIGINTERN void -SWIG_Python_SetErrorObj(PyObject *errtype, PyObject *obj) { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - PyErr_SetObject(errtype, obj); - Py_DECREF(obj); - SWIG_PYTHON_THREAD_END_BLOCK; -} - -SWIGINTERN void -SWIG_Python_SetErrorMsg(PyObject *errtype, const char *msg) { - SWIG_PYTHON_THREAD_BEGIN_BLOCK; - PyErr_SetString(errtype, (char *) msg); - SWIG_PYTHON_THREAD_END_BLOCK; -} - -#define SWIG_Python_Raise(obj, type, desc) SWIG_Python_SetErrorObj(SWIG_Python_ExceptionType(desc), obj) - -/* Set a constant value */ - -SWIGINTERN void -SWIG_Python_SetConstant(PyObject *d, const char *name, PyObject *obj) { - PyDict_SetItemString(d, (char*) name, obj); - Py_DECREF(obj); -} - -/* Append a value to the result obj */ - -SWIGINTERN PyObject* -SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) { -#if !defined(SWIG_PYTHON_OUTPUT_TUPLE) - if (!result) { - result = obj; - } else if (result == Py_None) { - Py_DECREF(result); - result = obj; - } else { - if (!PyList_Check(result)) { - PyObject *o2 = result; - result = PyList_New(1); - PyList_SetItem(result, 0, o2); - } - PyList_Append(result,obj); - Py_DECREF(obj); - } - return result; -#else - PyObject* o2; - PyObject* o3; - if (!result) { - result = obj; - } else if (result == Py_None) { - Py_DECREF(result); - result = obj; - } else { - if (!PyTuple_Check(result)) { - o2 = result; - result = PyTuple_New(1); - PyTuple_SET_ITEM(result, 0, o2); - } - o3 = PyTuple_New(1); - PyTuple_SET_ITEM(o3, 0, obj); - o2 = result; - result = PySequence_Concat(o2, o3); - Py_DECREF(o2); - Py_DECREF(o3); - } - return result; -#endif -} - -/* Unpack the argument tuple */ - -SWIGINTERN int -SWIG_Python_UnpackTuple(PyObject *args, const char *name, int min, int max, PyObject **objs) -{ - if (!args) { - if (!min && !max) { - return 1; - } else { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got none", - name, (min == max ? "" : "at least "), min); - return 0; - } - } - if (!PyTuple_Check(args)) { - PyErr_SetString(PyExc_SystemError, "UnpackTuple() argument list is not a tuple"); - return 0; - } else { - register int l = PyTuple_GET_SIZE(args); - if (l < min) { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", - name, (min == max ? "" : "at least "), min, l); - return 0; - } else if (l > max) { - PyErr_Format(PyExc_TypeError, "%s expected %s%d arguments, got %d", - name, (min == max ? "" : "at most "), max, l); - return 0; - } else { - register int i; - for (i = 0; i < l; ++i) { - objs[i] = PyTuple_GET_ITEM(args, i); - } - for (; l < max; ++l) { - objs[l] = 0; - } - return i + 1; - } - } -} - -/* A functor is a function object with one single object argument */ -#if PY_VERSION_HEX >= 0x02020000 -#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunctionObjArgs(functor, obj, NULL); -#else -#define SWIG_Python_CallFunctor(functor, obj) PyObject_CallFunction(functor, "O", obj); -#endif - -/* - Helper for static pointer initialization for both C and C++ code, for example - static PyObject *SWIG_STATIC_POINTER(MyVar) = NewSomething(...); -*/ -#ifdef __cplusplus -#define SWIG_STATIC_POINTER(var) var -#else -#define SWIG_STATIC_POINTER(var) var = 0; if (!var) var -#endif - -/* ----------------------------------------------------------------------------- - * Pointer declarations - * ----------------------------------------------------------------------------- */ - -/* Flags for new pointer objects */ -#define SWIG_POINTER_NOSHADOW (SWIG_POINTER_OWN << 1) -#define SWIG_POINTER_NEW (SWIG_POINTER_NOSHADOW | SWIG_POINTER_OWN) - -#define SWIG_POINTER_IMPLICIT_CONV (SWIG_POINTER_DISOWN << 1) - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* cc-mode */ -#endif -#endif - -/* How to access Py_None */ -#if defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) -# ifndef SWIG_PYTHON_NO_BUILD_NONE -# ifndef SWIG_PYTHON_BUILD_NONE -# define SWIG_PYTHON_BUILD_NONE -# endif -# endif -#endif - -#ifdef SWIG_PYTHON_BUILD_NONE -# ifdef Py_None -# undef Py_None -# define Py_None SWIG_Py_None() -# endif -SWIGRUNTIMEINLINE PyObject * -_SWIG_Py_None(void) -{ - PyObject *none = Py_BuildValue((char*)""); - Py_DECREF(none); - return none; -} -SWIGRUNTIME PyObject * -SWIG_Py_None(void) -{ - static PyObject *SWIG_STATIC_POINTER(none) = _SWIG_Py_None(); - return none; -} -#endif - -/* The python void return value */ - -SWIGRUNTIMEINLINE PyObject * -SWIG_Py_Void(void) -{ - PyObject *none = Py_None; - Py_INCREF(none); - return none; -} - -/* PySwigClientData */ - -typedef struct { - PyObject *klass; - PyObject *newraw; - PyObject *newargs; - PyObject *destroy; - int delargs; - int implicitconv; -} PySwigClientData; - -SWIGRUNTIMEINLINE int -SWIG_Python_CheckImplicit(swig_type_info *ty) -{ - PySwigClientData *data = (PySwigClientData *)ty->clientdata; - return data ? data->implicitconv : 0; -} - -SWIGRUNTIMEINLINE PyObject * -SWIG_Python_ExceptionType(swig_type_info *desc) { - PySwigClientData *data = desc ? (PySwigClientData *) desc->clientdata : 0; - PyObject *klass = data ? data->klass : 0; - return (klass ? klass : PyExc_RuntimeError); -} - - -SWIGRUNTIME PySwigClientData * -PySwigClientData_New(PyObject* obj) -{ - if (!obj) { - return 0; - } else { - PySwigClientData *data = (PySwigClientData *)malloc(sizeof(PySwigClientData)); - /* the klass element */ - data->klass = obj; - Py_INCREF(data->klass); - /* the newraw method and newargs arguments used to create a new raw instance */ - if (PyClass_Check(obj)) { - data->newraw = 0; - data->newargs = obj; - Py_INCREF(obj); - } else { -#if (PY_VERSION_HEX < 0x02020000) - data->newraw = 0; -#else - data->newraw = PyObject_GetAttrString(data->klass, (char *)"__new__"); -#endif - if (data->newraw) { - Py_INCREF(data->newraw); - data->newargs = PyTuple_New(1); - PyTuple_SetItem(data->newargs, 0, obj); - } else { - data->newargs = obj; - } - Py_INCREF(data->newargs); - } - /* the destroy method, aka as the C++ delete method */ - data->destroy = PyObject_GetAttrString(data->klass, (char *)"__swig_destroy__"); - if (PyErr_Occurred()) { - PyErr_Clear(); - data->destroy = 0; - } - if (data->destroy) { - int flags; - Py_INCREF(data->destroy); - flags = PyCFunction_GET_FLAGS(data->destroy); -#ifdef METH_O - data->delargs = !(flags & (METH_O)); -#else - data->delargs = 0; -#endif - } else { - data->delargs = 0; - } - data->implicitconv = 0; - return data; - } -} - -SWIGRUNTIME void -PySwigClientData_Del(PySwigClientData* data) -{ - Py_XDECREF(data->newraw); - Py_XDECREF(data->newargs); - Py_XDECREF(data->destroy); -} - -/* =============== PySwigObject =====================*/ - -typedef struct { - PyObject_HEAD - void *ptr; - swig_type_info *ty; - int own; - PyObject *next; -} PySwigObject; - -SWIGRUNTIME PyObject * -PySwigObject_long(PySwigObject *v) -{ - return PyLong_FromVoidPtr(v->ptr); -} - -SWIGRUNTIME PyObject * -PySwigObject_format(const char* fmt, PySwigObject *v) -{ - PyObject *res = NULL; - PyObject *args = PyTuple_New(1); - if (args) { - if (PyTuple_SetItem(args, 0, PySwigObject_long(v)) == 0) { - PyObject *ofmt = PyString_FromString(fmt); - if (ofmt) { - res = PyString_Format(ofmt,args); - Py_DECREF(ofmt); - } - Py_DECREF(args); - } - } - return res; -} - -SWIGRUNTIME PyObject * -PySwigObject_oct(PySwigObject *v) -{ - return PySwigObject_format("%o",v); -} - -SWIGRUNTIME PyObject * -PySwigObject_hex(PySwigObject *v) -{ - return PySwigObject_format("%x",v); -} - -SWIGRUNTIME PyObject * -#ifdef METH_NOARGS -PySwigObject_repr(PySwigObject *v) -#else -PySwigObject_repr(PySwigObject *v, PyObject *args) -#endif -{ - const char *name = SWIG_TypePrettyName(v->ty); - PyObject *hex = PySwigObject_hex(v); - PyObject *repr = PyString_FromFormat("", name, PyString_AsString(hex)); - Py_DECREF(hex); - if (v->next) { -#ifdef METH_NOARGS - PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next); -#else - PyObject *nrep = PySwigObject_repr((PySwigObject *)v->next, args); -#endif - PyString_ConcatAndDel(&repr,nrep); - } - return repr; -} - -SWIGRUNTIME int -PySwigObject_print(PySwigObject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) -{ -#ifdef METH_NOARGS - PyObject *repr = PySwigObject_repr(v); -#else - PyObject *repr = PySwigObject_repr(v, NULL); -#endif - if (repr) { - fputs(PyString_AsString(repr), fp); - Py_DECREF(repr); - return 0; - } else { - return 1; - } -} - -SWIGRUNTIME PyObject * -PySwigObject_str(PySwigObject *v) -{ - char result[SWIG_BUFFER_SIZE]; - return SWIG_PackVoidPtr(result, v->ptr, v->ty->name, sizeof(result)) ? - PyString_FromString(result) : 0; -} - -SWIGRUNTIME int -PySwigObject_compare(PySwigObject *v, PySwigObject *w) -{ - void *i = v->ptr; - void *j = w->ptr; - return (i < j) ? -1 : ((i > j) ? 1 : 0); -} - -SWIGRUNTIME PyTypeObject* _PySwigObject_type(void); - -SWIGRUNTIME PyTypeObject* -PySwigObject_type(void) { - static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigObject_type(); - return type; -} - -SWIGRUNTIMEINLINE int -PySwigObject_Check(PyObject *op) { - return ((op)->ob_type == PySwigObject_type()) - || (strcmp((op)->ob_type->tp_name,"PySwigObject") == 0); -} - -SWIGRUNTIME PyObject * -PySwigObject_New(void *ptr, swig_type_info *ty, int own); - -SWIGRUNTIME void -PySwigObject_dealloc(PyObject *v) -{ - PySwigObject *sobj = (PySwigObject *) v; - PyObject *next = sobj->next; - if (sobj->own) { - swig_type_info *ty = sobj->ty; - PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; - PyObject *destroy = data ? data->destroy : 0; - if (destroy) { - /* destroy is always a VARARGS method */ - PyObject *res; - if (data->delargs) { - /* we need to create a temporal object to carry the destroy operation */ - PyObject *tmp = PySwigObject_New(sobj->ptr, ty, 0); - res = SWIG_Python_CallFunctor(destroy, tmp); - Py_DECREF(tmp); - } else { - PyCFunction meth = PyCFunction_GET_FUNCTION(destroy); - PyObject *mself = PyCFunction_GET_SELF(destroy); - res = ((*meth)(mself, v)); - } - Py_XDECREF(res); - } else { - const char *name = SWIG_TypePrettyName(ty); -#if !defined(SWIG_PYTHON_SILENT_MEMLEAK) - printf("swig/python detected a memory leak of type '%s', no destructor found.\n", name); -#endif - } - } - Py_XDECREF(next); - PyObject_DEL(v); -} - -SWIGRUNTIME PyObject* -PySwigObject_append(PyObject* v, PyObject* next) -{ - PySwigObject *sobj = (PySwigObject *) v; -#ifndef METH_O - PyObject *tmp = 0; - if (!PyArg_ParseTuple(next,(char *)"O:append", &tmp)) return NULL; - next = tmp; -#endif - if (!PySwigObject_Check(next)) { - return NULL; - } - sobj->next = next; - Py_INCREF(next); - return SWIG_Py_Void(); -} - -SWIGRUNTIME PyObject* -#ifdef METH_NOARGS -PySwigObject_next(PyObject* v) -#else -PySwigObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -#endif -{ - PySwigObject *sobj = (PySwigObject *) v; - if (sobj->next) { - Py_INCREF(sobj->next); - return sobj->next; - } else { - return SWIG_Py_Void(); - } -} - -SWIGINTERN PyObject* -#ifdef METH_NOARGS -PySwigObject_disown(PyObject *v) -#else -PySwigObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -#endif -{ - PySwigObject *sobj = (PySwigObject *)v; - sobj->own = 0; - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject* -#ifdef METH_NOARGS -PySwigObject_acquire(PyObject *v) -#else -PySwigObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args)) -#endif -{ - PySwigObject *sobj = (PySwigObject *)v; - sobj->own = SWIG_POINTER_OWN; - return SWIG_Py_Void(); -} - -SWIGINTERN PyObject* -PySwigObject_own(PyObject *v, PyObject *args) -{ - PyObject *val = 0; -#if (PY_VERSION_HEX < 0x02020000) - if (!PyArg_ParseTuple(args,(char *)"|O:own",&val)) -#else - if (!PyArg_UnpackTuple(args, (char *)"own", 0, 1, &val)) -#endif - { - return NULL; - } - else - { - PySwigObject *sobj = (PySwigObject *)v; - PyObject *obj = PyBool_FromLong(sobj->own); - if (val) { -#ifdef METH_NOARGS - if (PyObject_IsTrue(val)) { - PySwigObject_acquire(v); - } else { - PySwigObject_disown(v); - } -#else - if (PyObject_IsTrue(val)) { - PySwigObject_acquire(v,args); - } else { - PySwigObject_disown(v,args); - } -#endif - } - return obj; - } -} - -#ifdef METH_O -static PyMethodDef -swigobject_methods[] = { - {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_NOARGS, (char *)"releases ownership of the pointer"}, - {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_NOARGS, (char *)"aquires ownership of the pointer"}, - {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, - {(char *)"append", (PyCFunction)PySwigObject_append, METH_O, (char *)"appends another 'this' object"}, - {(char *)"next", (PyCFunction)PySwigObject_next, METH_NOARGS, (char *)"returns the next 'this' object"}, - {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_NOARGS, (char *)"returns object representation"}, - {0, 0, 0, 0} -}; -#else -static PyMethodDef -swigobject_methods[] = { - {(char *)"disown", (PyCFunction)PySwigObject_disown, METH_VARARGS, (char *)"releases ownership of the pointer"}, - {(char *)"acquire", (PyCFunction)PySwigObject_acquire, METH_VARARGS, (char *)"aquires ownership of the pointer"}, - {(char *)"own", (PyCFunction)PySwigObject_own, METH_VARARGS, (char *)"returns/sets ownership of the pointer"}, - {(char *)"append", (PyCFunction)PySwigObject_append, METH_VARARGS, (char *)"appends another 'this' object"}, - {(char *)"next", (PyCFunction)PySwigObject_next, METH_VARARGS, (char *)"returns the next 'this' object"}, - {(char *)"__repr__",(PyCFunction)PySwigObject_repr, METH_VARARGS, (char *)"returns object representation"}, - {0, 0, 0, 0} -}; -#endif - -#if PY_VERSION_HEX < 0x02020000 -SWIGINTERN PyObject * -PySwigObject_getattr(PySwigObject *sobj,char *name) -{ - return Py_FindMethod(swigobject_methods, (PyObject *)sobj, name); -} -#endif - -SWIGRUNTIME PyTypeObject* -_PySwigObject_type(void) { - static char swigobject_doc[] = "Swig object carries a C/C++ instance pointer"; - - static PyNumberMethods PySwigObject_as_number = { - (binaryfunc)0, /*nb_add*/ - (binaryfunc)0, /*nb_subtract*/ - (binaryfunc)0, /*nb_multiply*/ - (binaryfunc)0, /*nb_divide*/ - (binaryfunc)0, /*nb_remainder*/ - (binaryfunc)0, /*nb_divmod*/ - (ternaryfunc)0,/*nb_power*/ - (unaryfunc)0, /*nb_negative*/ - (unaryfunc)0, /*nb_positive*/ - (unaryfunc)0, /*nb_absolute*/ - (inquiry)0, /*nb_nonzero*/ - 0, /*nb_invert*/ - 0, /*nb_lshift*/ - 0, /*nb_rshift*/ - 0, /*nb_and*/ - 0, /*nb_xor*/ - 0, /*nb_or*/ - (coercion)0, /*nb_coerce*/ - (unaryfunc)PySwigObject_long, /*nb_int*/ - (unaryfunc)PySwigObject_long, /*nb_long*/ - (unaryfunc)0, /*nb_float*/ - (unaryfunc)PySwigObject_oct, /*nb_oct*/ - (unaryfunc)PySwigObject_hex, /*nb_hex*/ -#if PY_VERSION_HEX >= 0x02020000 - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_true_divide */ -#elif PY_VERSION_HEX >= 0x02000000 - 0,0,0,0,0,0,0,0,0,0,0 /* nb_inplace_add -> nb_inplace_or */ -#endif - }; - - static PyTypeObject pyswigobject_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp - = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - (char *)"PySwigObject", /* tp_name */ - sizeof(PySwigObject), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)PySwigObject_dealloc, /* tp_dealloc */ - (printfunc)PySwigObject_print, /* tp_print */ -#if PY_VERSION_HEX < 0x02020000 - (getattrfunc)PySwigObject_getattr, /* tp_getattr */ -#else - (getattrfunc)0, /* tp_getattr */ -#endif - (setattrfunc)0, /* tp_setattr */ - (cmpfunc)PySwigObject_compare, /* tp_compare */ - (reprfunc)PySwigObject_repr, /* tp_repr */ - &PySwigObject_as_number, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)0, /* tp_hash */ - (ternaryfunc)0, /* tp_call */ - (reprfunc)PySwigObject_str, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - swigobject_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ -#if PY_VERSION_HEX >= 0x02020000 - 0, /* tp_iter */ - 0, /* tp_iternext */ - swigobject_methods, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#ifdef COUNT_ALLOCS - 0,0,0,0 /* tp_alloc -> tp_next */ -#endif - }; - pyswigobject_type = tmp; - pyswigobject_type.ob_type = &PyType_Type; - type_init = 1; - } - return &pyswigobject_type; -} - -SWIGRUNTIME PyObject * -PySwigObject_New(void *ptr, swig_type_info *ty, int own) -{ - PySwigObject *sobj = PyObject_NEW(PySwigObject, PySwigObject_type()); - if (sobj) { - sobj->ptr = ptr; - sobj->ty = ty; - sobj->own = own; - sobj->next = 0; - } - return (PyObject *)sobj; -} - -/* ----------------------------------------------------------------------------- - * Implements a simple Swig Packed type, and use it instead of string - * ----------------------------------------------------------------------------- */ - -typedef struct { - PyObject_HEAD - void *pack; - swig_type_info *ty; - size_t size; -} PySwigPacked; - -SWIGRUNTIME int -PySwigPacked_print(PySwigPacked *v, FILE *fp, int SWIGUNUSEDPARM(flags)) -{ - char result[SWIG_BUFFER_SIZE]; - fputs("pack, v->size, 0, sizeof(result))) { - fputs("at ", fp); - fputs(result, fp); - } - fputs(v->ty->name,fp); - fputs(">", fp); - return 0; -} - -SWIGRUNTIME PyObject * -PySwigPacked_repr(PySwigPacked *v) -{ - char result[SWIG_BUFFER_SIZE]; - if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) { - return PyString_FromFormat("", result, v->ty->name); - } else { - return PyString_FromFormat("", v->ty->name); - } -} - -SWIGRUNTIME PyObject * -PySwigPacked_str(PySwigPacked *v) -{ - char result[SWIG_BUFFER_SIZE]; - if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))){ - return PyString_FromFormat("%s%s", result, v->ty->name); - } else { - return PyString_FromString(v->ty->name); - } -} - -SWIGRUNTIME int -PySwigPacked_compare(PySwigPacked *v, PySwigPacked *w) -{ - size_t i = v->size; - size_t j = w->size; - int s = (i < j) ? -1 : ((i > j) ? 1 : 0); - return s ? s : strncmp((char *)v->pack, (char *)w->pack, 2*v->size); -} - -SWIGRUNTIME PyTypeObject* _PySwigPacked_type(void); - -SWIGRUNTIME PyTypeObject* -PySwigPacked_type(void) { - static PyTypeObject *SWIG_STATIC_POINTER(type) = _PySwigPacked_type(); - return type; -} - -SWIGRUNTIMEINLINE int -PySwigPacked_Check(PyObject *op) { - return ((op)->ob_type == _PySwigPacked_type()) - || (strcmp((op)->ob_type->tp_name,"PySwigPacked") == 0); -} - -SWIGRUNTIME void -PySwigPacked_dealloc(PyObject *v) -{ - if (PySwigPacked_Check(v)) { - PySwigPacked *sobj = (PySwigPacked *) v; - free(sobj->pack); - } - PyObject_DEL(v); -} - -SWIGRUNTIME PyTypeObject* -_PySwigPacked_type(void) { - static char swigpacked_doc[] = "Swig object carries a C/C++ instance pointer"; - static PyTypeObject pyswigpacked_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp - = { - PyObject_HEAD_INIT(NULL) - 0, /* ob_size */ - (char *)"PySwigPacked", /* tp_name */ - sizeof(PySwigPacked), /* tp_basicsize */ - 0, /* tp_itemsize */ - (destructor)PySwigPacked_dealloc, /* tp_dealloc */ - (printfunc)PySwigPacked_print, /* tp_print */ - (getattrfunc)0, /* tp_getattr */ - (setattrfunc)0, /* tp_setattr */ - (cmpfunc)PySwigPacked_compare, /* tp_compare */ - (reprfunc)PySwigPacked_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - (hashfunc)0, /* tp_hash */ - (ternaryfunc)0, /* tp_call */ - (reprfunc)PySwigPacked_str, /* tp_str */ - PyObject_GenericGetAttr, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - Py_TPFLAGS_DEFAULT, /* tp_flags */ - swigpacked_doc, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ -#if PY_VERSION_HEX >= 0x02020000 - 0, /* tp_iter */ - 0, /* tp_iternext */ - 0, /* tp_methods */ - 0, /* tp_members */ - 0, /* tp_getset */ - 0, /* tp_base */ - 0, /* tp_dict */ - 0, /* tp_descr_get */ - 0, /* tp_descr_set */ - 0, /* tp_dictoffset */ - 0, /* tp_init */ - 0, /* tp_alloc */ - 0, /* tp_new */ - 0, /* tp_free */ - 0, /* tp_is_gc */ - 0, /* tp_bases */ - 0, /* tp_mro */ - 0, /* tp_cache */ - 0, /* tp_subclasses */ - 0, /* tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#ifdef COUNT_ALLOCS - 0,0,0,0 /* tp_alloc -> tp_next */ -#endif - }; - pyswigpacked_type = tmp; - pyswigpacked_type.ob_type = &PyType_Type; - type_init = 1; - } - return &pyswigpacked_type; -} - -SWIGRUNTIME PyObject * -PySwigPacked_New(void *ptr, size_t size, swig_type_info *ty) -{ - PySwigPacked *sobj = PyObject_NEW(PySwigPacked, PySwigPacked_type()); - if (sobj) { - void *pack = malloc(size); - if (pack) { - memcpy(pack, ptr, size); - sobj->pack = pack; - sobj->ty = ty; - sobj->size = size; - } else { - PyObject_DEL((PyObject *) sobj); - sobj = 0; - } - } - return (PyObject *) sobj; -} - -SWIGRUNTIME swig_type_info * -PySwigPacked_UnpackData(PyObject *obj, void *ptr, size_t size) -{ - if (PySwigPacked_Check(obj)) { - PySwigPacked *sobj = (PySwigPacked *)obj; - if (sobj->size != size) return 0; - memcpy(ptr, sobj->pack, size); - return sobj->ty; - } else { - return 0; - } -} - -/* ----------------------------------------------------------------------------- - * pointers/data manipulation - * ----------------------------------------------------------------------------- */ - -SWIGRUNTIMEINLINE PyObject * -_SWIG_This(void) -{ - return PyString_FromString("this"); -} - -SWIGRUNTIME PyObject * -SWIG_This(void) -{ - static PyObject *SWIG_STATIC_POINTER(swig_this) = _SWIG_This(); - return swig_this; -} - -/* #define SWIG_PYTHON_SLOW_GETSET_THIS */ - -SWIGRUNTIME PySwigObject * -SWIG_Python_GetSwigThis(PyObject *pyobj) -{ - if (PySwigObject_Check(pyobj)) { - return (PySwigObject *) pyobj; - } else { - PyObject *obj = 0; -#if (!defined(SWIG_PYTHON_SLOW_GETSET_THIS) && (PY_VERSION_HEX >= 0x02030000)) - if (PyInstance_Check(pyobj)) { - obj = _PyInstance_Lookup(pyobj, SWIG_This()); - } else { - PyObject **dictptr = _PyObject_GetDictPtr(pyobj); - if (dictptr != NULL) { - PyObject *dict = *dictptr; - obj = dict ? PyDict_GetItem(dict, SWIG_This()) : 0; - } else { -#ifdef PyWeakref_CheckProxy - if (PyWeakref_CheckProxy(pyobj)) { - PyObject *wobj = PyWeakref_GET_OBJECT(pyobj); - return wobj ? SWIG_Python_GetSwigThis(wobj) : 0; - } -#endif - obj = PyObject_GetAttr(pyobj,SWIG_This()); - if (obj) { - Py_DECREF(obj); - } else { - if (PyErr_Occurred()) PyErr_Clear(); - return 0; - } - } - } -#else - obj = PyObject_GetAttr(pyobj,SWIG_This()); - if (obj) { - Py_DECREF(obj); - } else { - if (PyErr_Occurred()) PyErr_Clear(); - return 0; - } -#endif - if (obj && !PySwigObject_Check(obj)) { - /* a PyObject is called 'this', try to get the 'real this' - PySwigObject from it */ - return SWIG_Python_GetSwigThis(obj); - } - return (PySwigObject *)obj; - } -} - -/* Acquire a pointer value */ - -SWIGRUNTIME int -SWIG_Python_AcquirePtr(PyObject *obj, int own) { - if (own) { - PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); - if (sobj) { - int oldown = sobj->own; - sobj->own = own; - return oldown; - } - } - return 0; -} - -/* Convert a pointer value */ - -SWIGRUNTIME int -SWIG_Python_ConvertPtrAndOwn(PyObject *obj, void **ptr, swig_type_info *ty, int flags, int *own) { - if (!obj) return SWIG_ERROR; - if (obj == Py_None) { - if (ptr) *ptr = 0; - return SWIG_OK; - } else { - PySwigObject *sobj = SWIG_Python_GetSwigThis(obj); - while (sobj) { - void *vptr = sobj->ptr; - if (ty) { - swig_type_info *to = sobj->ty; - if (to == ty) { - /* no type cast needed */ - if (ptr) *ptr = vptr; - break; - } else { - swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); - if (!tc) { - sobj = (PySwigObject *)sobj->next; - } else { - if (ptr) *ptr = SWIG_TypeCast(tc,vptr); - break; - } - } - } else { - if (ptr) *ptr = vptr; - break; - } - } - if (sobj) { - if (own) *own = sobj->own; - if (flags & SWIG_POINTER_DISOWN) { - sobj->own = 0; - } - return SWIG_OK; - } else { - int res = SWIG_ERROR; - if (flags & SWIG_POINTER_IMPLICIT_CONV) { - PySwigClientData *data = ty ? (PySwigClientData *) ty->clientdata : 0; - if (data && !data->implicitconv) { - PyObject *klass = data->klass; - if (klass) { - PyObject *impconv; - data->implicitconv = 1; /* avoid recursion and call 'explicit' constructors*/ - impconv = SWIG_Python_CallFunctor(klass, obj); - data->implicitconv = 0; - if (PyErr_Occurred()) { - PyErr_Clear(); - impconv = 0; - } - if (impconv) { - PySwigObject *iobj = SWIG_Python_GetSwigThis(impconv); - if (iobj) { - void *vptr; - res = SWIG_Python_ConvertPtrAndOwn((PyObject*)iobj, &vptr, ty, 0, 0); - if (SWIG_IsOK(res)) { - if (ptr) { - *ptr = vptr; - /* transfer the ownership to 'ptr' */ - iobj->own = 0; - res = SWIG_AddCast(res); - res = SWIG_AddNewMask(res); - } else { - res = SWIG_AddCast(res); - } - } - } - Py_DECREF(impconv); - } - } - } - } - return res; - } - } -} - -/* Convert a function ptr value */ - -SWIGRUNTIME int -SWIG_Python_ConvertFunctionPtr(PyObject *obj, void **ptr, swig_type_info *ty) { - if (!PyCFunction_Check(obj)) { - return SWIG_ConvertPtr(obj, ptr, ty, 0); - } else { - void *vptr = 0; - - /* here we get the method pointer for callbacks */ - const char *doc = (((PyCFunctionObject *)obj) -> m_ml -> ml_doc); - const char *desc = doc ? strstr(doc, "swig_ptr: ") : 0; - if (desc) { - desc = ty ? SWIG_UnpackVoidPtr(desc + 10, &vptr, ty->name) : 0; - if (!desc) return SWIG_ERROR; - } - if (ty) { - swig_cast_info *tc = SWIG_TypeCheck(desc,ty); - if (!tc) return SWIG_ERROR; - *ptr = SWIG_TypeCast(tc,vptr); - } else { - *ptr = vptr; - } - return SWIG_OK; - } -} - -/* Convert a packed value value */ - -SWIGRUNTIME int -SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *ty) { - swig_type_info *to = PySwigPacked_UnpackData(obj, ptr, sz); - if (!to) return SWIG_ERROR; - if (ty) { - if (to != ty) { - /* check type cast? */ - swig_cast_info *tc = SWIG_TypeCheck(to->name,ty); - if (!tc) return SWIG_ERROR; - } - } - return SWIG_OK; -} - -/* ----------------------------------------------------------------------------- - * Create a new pointer object - * ----------------------------------------------------------------------------- */ - -/* - Create a new instance object, whitout calling __init__, and set the - 'this' attribute. -*/ - -SWIGRUNTIME PyObject* -SWIG_Python_NewShadowInstance(PySwigClientData *data, PyObject *swig_this) -{ -#if (PY_VERSION_HEX >= 0x02020000) - PyObject *inst = 0; - PyObject *newraw = data->newraw; - if (newraw) { - inst = PyObject_Call(newraw, data->newargs, NULL); - if (inst) { -#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS) - PyObject **dictptr = _PyObject_GetDictPtr(inst); - if (dictptr != NULL) { - PyObject *dict = *dictptr; - if (dict == NULL) { - dict = PyDict_New(); - *dictptr = dict; - PyDict_SetItem(dict, SWIG_This(), swig_this); - } - } -#else - PyObject *key = SWIG_This(); - PyObject_SetAttr(inst, key, swig_this); -#endif - } - } else { - PyObject *dict = PyDict_New(); - PyDict_SetItem(dict, SWIG_This(), swig_this); - inst = PyInstance_NewRaw(data->newargs, dict); - Py_DECREF(dict); - } - return inst; -#else -#if (PY_VERSION_HEX >= 0x02010000) - PyObject *inst; - PyObject *dict = PyDict_New(); - PyDict_SetItem(dict, SWIG_This(), swig_this); - inst = PyInstance_NewRaw(data->newargs, dict); - Py_DECREF(dict); - return (PyObject *) inst; -#else - PyInstanceObject *inst = PyObject_NEW(PyInstanceObject, &PyInstance_Type); - if (inst == NULL) { - return NULL; - } - inst->in_class = (PyClassObject *)data->newargs; - Py_INCREF(inst->in_class); - inst->in_dict = PyDict_New(); - if (inst->in_dict == NULL) { - Py_DECREF(inst); - return NULL; - } -#ifdef Py_TPFLAGS_HAVE_WEAKREFS - inst->in_weakreflist = NULL; -#endif -#ifdef Py_TPFLAGS_GC - PyObject_GC_Init(inst); -#endif - PyDict_SetItem(inst->in_dict, SWIG_This(), swig_this); - return (PyObject *) inst; -#endif -#endif -} - -SWIGRUNTIME void -SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this) -{ - PyObject *dict; -#if (PY_VERSION_HEX >= 0x02020000) && !defined(SWIG_PYTHON_SLOW_GETSET_THIS) - PyObject **dictptr = _PyObject_GetDictPtr(inst); - if (dictptr != NULL) { - dict = *dictptr; - if (dict == NULL) { - dict = PyDict_New(); - *dictptr = dict; - } - PyDict_SetItem(dict, SWIG_This(), swig_this); - return; - } -#endif - dict = PyObject_GetAttrString(inst, (char*)"__dict__"); - PyDict_SetItem(dict, SWIG_This(), swig_this); - Py_DECREF(dict); -} - - -SWIGINTERN PyObject * -SWIG_Python_InitShadowInstance(PyObject *args) { - PyObject *obj[2]; - if (!SWIG_Python_UnpackTuple(args,(char*)"swiginit", 2, 2, obj)) { - return NULL; - } else { - PySwigObject *sthis = SWIG_Python_GetSwigThis(obj[0]); - if (sthis) { - PySwigObject_append((PyObject*) sthis, obj[1]); - } else { - SWIG_Python_SetSwigThis(obj[0], obj[1]); - } - return SWIG_Py_Void(); - } -} - -/* Create a new pointer object */ - -SWIGRUNTIME PyObject * -SWIG_Python_NewPointerObj(void *ptr, swig_type_info *type, int flags) { - if (!ptr) { - return SWIG_Py_Void(); - } else { - int own = (flags & SWIG_POINTER_OWN) ? SWIG_POINTER_OWN : 0; - PyObject *robj = PySwigObject_New(ptr, type, own); - PySwigClientData *clientdata = type ? (PySwigClientData *)(type->clientdata) : 0; - if (clientdata && !(flags & SWIG_POINTER_NOSHADOW)) { - PyObject *inst = SWIG_Python_NewShadowInstance(clientdata, robj); - if (inst) { - Py_DECREF(robj); - robj = inst; - } - } - return robj; - } -} - -/* Create a new packed object */ - -SWIGRUNTIMEINLINE PyObject * -SWIG_Python_NewPackedObj(void *ptr, size_t sz, swig_type_info *type) { - return ptr ? PySwigPacked_New((void *) ptr, sz, type) : SWIG_Py_Void(); -} - -/* -----------------------------------------------------------------------------* - * Get type list - * -----------------------------------------------------------------------------*/ - -#ifdef SWIG_LINK_RUNTIME -void *SWIG_ReturnGlobalTypeList(void *); -#endif - -SWIGRUNTIME swig_module_info * -SWIG_Python_GetModule(void) { - static void *type_pointer = (void *)0; - /* first check if module already created */ - if (!type_pointer) { -#ifdef SWIG_LINK_RUNTIME - type_pointer = SWIG_ReturnGlobalTypeList((void *)0); -#else - type_pointer = PyCObject_Import((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, - (char*)"type_pointer" SWIG_TYPE_TABLE_NAME); - if (PyErr_Occurred()) { - PyErr_Clear(); - type_pointer = (void *)0; - } -#endif - } - return (swig_module_info *) type_pointer; -} - -#if PY_MAJOR_VERSION < 2 -/* PyModule_AddObject function was introduced in Python 2.0. The following function - is copied out of Python/modsupport.c in python version 2.3.4 */ -SWIGINTERN int -PyModule_AddObject(PyObject *m, char *name, PyObject *o) -{ - PyObject *dict; - if (!PyModule_Check(m)) { - PyErr_SetString(PyExc_TypeError, - "PyModule_AddObject() needs module as first arg"); - return SWIG_ERROR; - } - if (!o) { - PyErr_SetString(PyExc_TypeError, - "PyModule_AddObject() needs non-NULL value"); - return SWIG_ERROR; - } - - dict = PyModule_GetDict(m); - if (dict == NULL) { - /* Internal error -- modules must have a dict! */ - PyErr_Format(PyExc_SystemError, "module '%s' has no __dict__", - PyModule_GetName(m)); - return SWIG_ERROR; - } - if (PyDict_SetItemString(dict, name, o)) - return SWIG_ERROR; - Py_DECREF(o); - return SWIG_OK; -} -#endif - -SWIGRUNTIME void -SWIG_Python_DestroyModule(void *vptr) -{ - swig_module_info *swig_module = (swig_module_info *) vptr; - swig_type_info **types = swig_module->types; - size_t i; - for (i =0; i < swig_module->size; ++i) { - swig_type_info *ty = types[i]; - if (ty->owndata) { - PySwigClientData *data = (PySwigClientData *) ty->clientdata; - if (data) PySwigClientData_Del(data); - } - } - Py_DECREF(SWIG_This()); -} - -SWIGRUNTIME void -SWIG_Python_SetModule(swig_module_info *swig_module) { - static PyMethodDef swig_empty_runtime_method_table[] = { {NULL, NULL, 0, NULL} };/* Sentinel */ - - PyObject *module = Py_InitModule((char*)"swig_runtime_data" SWIG_RUNTIME_VERSION, - swig_empty_runtime_method_table); - PyObject *pointer = PyCObject_FromVoidPtr((void *) swig_module, SWIG_Python_DestroyModule); - if (pointer && module) { - PyModule_AddObject(module, (char*)"type_pointer" SWIG_TYPE_TABLE_NAME, pointer); - } else { - Py_XDECREF(pointer); - } -} - -/* The python cached type query */ -SWIGRUNTIME PyObject * -SWIG_Python_TypeCache(void) { - static PyObject *SWIG_STATIC_POINTER(cache) = PyDict_New(); - return cache; -} - -SWIGRUNTIME swig_type_info * -SWIG_Python_TypeQuery(const char *type) -{ - PyObject *cache = SWIG_Python_TypeCache(); - PyObject *key = PyString_FromString(type); - PyObject *obj = PyDict_GetItem(cache, key); - swig_type_info *descriptor; - if (obj) { - descriptor = (swig_type_info *) PyCObject_AsVoidPtr(obj); - } else { - swig_module_info *swig_module = SWIG_Python_GetModule(); - descriptor = SWIG_TypeQueryModule(swig_module, swig_module, type); - if (descriptor) { - obj = PyCObject_FromVoidPtr(descriptor, NULL); - PyDict_SetItem(cache, key, obj); - Py_DECREF(obj); - } - } - Py_DECREF(key); - return descriptor; -} - -/* - For backward compatibility only -*/ -#define SWIG_POINTER_EXCEPTION 0 -#define SWIG_arg_fail(arg) SWIG_Python_ArgFail(arg) -#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags) - -SWIGRUNTIME int -SWIG_Python_AddErrMesg(const char* mesg, int infront) -{ - if (PyErr_Occurred()) { - PyObject *type = 0; - PyObject *value = 0; - PyObject *traceback = 0; - PyErr_Fetch(&type, &value, &traceback); - if (value) { - PyObject *old_str = PyObject_Str(value); - Py_XINCREF(type); - PyErr_Clear(); - if (infront) { - PyErr_Format(type, "%s %s", mesg, PyString_AsString(old_str)); - } else { - PyErr_Format(type, "%s %s", PyString_AsString(old_str), mesg); - } - Py_DECREF(old_str); - } - return 1; - } else { - return 0; - } -} - -SWIGRUNTIME int -SWIG_Python_ArgFail(int argnum) -{ - if (PyErr_Occurred()) { - /* add information about failing argument */ - char mesg[256]; - PyOS_snprintf(mesg, sizeof(mesg), "argument number %d:", argnum); - return SWIG_Python_AddErrMesg(mesg, 1); - } else { - return 0; - } -} - -SWIGRUNTIMEINLINE const char * -PySwigObject_GetDesc(PyObject *self) -{ - PySwigObject *v = (PySwigObject *)self; - swig_type_info *ty = v ? v->ty : 0; - return ty ? ty->str : (char*)""; -} - -SWIGRUNTIME void -SWIG_Python_TypeError(const char *type, PyObject *obj) -{ - if (type) { -#if defined(SWIG_COBJECT_TYPES) - if (obj && PySwigObject_Check(obj)) { - const char *otype = (const char *) PySwigObject_GetDesc(obj); - if (otype) { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, 'PySwigObject(%s)' is received", - type, otype); - return; - } - } else -#endif - { - const char *otype = (obj ? obj->ob_type->tp_name : 0); - if (otype) { - PyObject *str = PyObject_Str(obj); - const char *cstr = str ? PyString_AsString(str) : 0; - if (cstr) { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s(%s)' is received", - type, otype, cstr); - } else { - PyErr_Format(PyExc_TypeError, "a '%s' is expected, '%s' is received", - type, otype); - } - Py_XDECREF(str); - return; - } - } - PyErr_Format(PyExc_TypeError, "a '%s' is expected", type); - } else { - PyErr_Format(PyExc_TypeError, "unexpected type is received"); - } -} - - -/* Convert a pointer value, signal an exception on a type mismatch */ -SWIGRUNTIME void * -SWIG_Python_MustGetPtr(PyObject *obj, swig_type_info *ty, int argnum, int flags) { - void *result; - if (SWIG_Python_ConvertPtr(obj, &result, ty, flags) == -1) { - PyErr_Clear(); - if (flags & SWIG_POINTER_EXCEPTION) { - SWIG_Python_TypeError(SWIG_TypePrettyName(ty), obj); - SWIG_Python_ArgFail(argnum); - } - } - return result; -} - - -#ifdef __cplusplus -#if 0 -{ /* cc-mode */ -#endif -} -#endif - - - -#define SWIG_exception_fail(code, msg) do { SWIG_Error(code, msg); SWIG_fail; } while(0) - -#define SWIG_contract_assert(expr, msg) if (!(expr)) { SWIG_Error(SWIG_RuntimeError, msg); SWIG_fail; } else - - - -/* -------- TYPES TABLE (BEGIN) -------- */ - -#define SWIGTYPE_p_BroCompactEventFunc swig_types[0] -#define SWIGTYPE_p_char swig_types[1] -#define SWIGTYPE_p_void swig_types[2] -static swig_type_info *swig_types[4]; -static swig_module_info swig_module = {swig_types, 3, 0, 0, 0, 0}; -#define SWIG_TypeQuery(name) SWIG_TypeQueryModule(&swig_module, &swig_module, name) -#define SWIG_MangledTypeQuery(name) SWIG_MangledTypeQueryModule(&swig_module, &swig_module, name) - -/* -------- TYPES TABLE (END) -------- */ - -#if (PY_VERSION_HEX <= 0x02000000) -# if !defined(SWIG_PYTHON_CLASSIC) -# error "This python version requires swig to be run with the '-classic' option" -# endif -#endif - -/*----------------------------------------------- - @(target):= _broccoli_intern.so - ------------------------------------------------*/ -#define SWIG_init init_broccoli_intern - -#define SWIG_name "_broccoli_intern" - -#define SWIGVERSION 0x010331 -#define SWIG_VERSION SWIGVERSION - - -#define SWIG_as_voidptr(a) (void *)((const void *)(a)) -#define SWIG_as_voidptrptr(a) ((void)SWIG_as_voidptr(*a),(void**)(a)) - - -// Include the header in the wrapper code. -#include - -// Broccoli internal struct. Easier to copy that here than to include a bunch -// of Broccoli's internal headers. -struct bro_record { - void *val_list; - int val_len; -}; - -typedef BroRecord bro_record ; - -// Builds a 2-tuple (type, object). -PyObject* makeTypeTuple(int type, PyObject *val) -{ - PyObject *tuple = PyTuple_New(2); - PyTuple_SetItem(tuple, 0, PyInt_FromLong(type)); - PyTuple_SetItem(tuple, 1, val); - return tuple; -} - -// Parses a 2-tuple (type, object). Return 1 on success. -// Borrows input's reference to object. -int parseTypeTuple(PyObject* input, int *type, PyObject **val) -{ - if ( ! (PyTuple_Check(input) && PyTuple_Size(input) == 2) ) { - PyErr_SetString(PyExc_RuntimeError, "argument must be 2-tuple"); - return 0; - } - - PyObject *ptype = PyTuple_GetItem(input, 0); - PyObject *pval = PyTuple_GetItem(input, 1); - - if ( ! PyInt_Check(ptype) ) { - PyErr_SetString(PyExc_RuntimeError, "first tuple element must be integer"); - return 0; - } - - *type = PyInt_AsLong(ptype); - - if ( *type < 0 || *type > BRO_TYPE_MAX ) { - PyErr_SetString(PyExc_RuntimeError, "unknown type in tuple"); - return 0; - } - - *val = pval; - return 1; -} - -// Release the memory associated with the Broccoli value. -void freeBroccoliVal(int type, void* data) -{ - if ( ! data ) - return; - - switch ( type ) { - case BRO_TYPE_STRING: - free(((BroString *)data)->str_val); - free(data); - break; - - case BRO_TYPE_RECORD: - bro_record_free((BroRecord *)data); - break; - - default: - free(data); - } - -} - -// Converts a Broccoli value into a Python object. -PyObject* valToPyObj(int type, void* data) -{ - PyObject* val = 0; - - switch (type) { - case BRO_TYPE_BOOL: - val = PyBool_FromLong(*((int *)data)); - break; - - case BRO_TYPE_INT: - case BRO_TYPE_COUNT: - case BRO_TYPE_COUNTER: - case BRO_TYPE_IPADDR: - case BRO_TYPE_NET: { - val = PyInt_FromLong(*((long *)data)); - break; - } - - case BRO_TYPE_DOUBLE: - case BRO_TYPE_TIME: - case BRO_TYPE_INTERVAL: { - val = PyFloat_FromDouble(*((double *)data)); - break; - } - - case BRO_TYPE_STRING: { - BroString *str = (BroString*)data; - val = PyString_FromStringAndSize(str->str_val, str->str_len); - break; - } - - case BRO_TYPE_ENUM: { - val = PyTuple_New(2); - PyTuple_SetItem(val, 0, PyBool_FromLong(*((int *)data))); - PyTuple_SetItem(val, 1, PyString_FromString("broccoli-doesnt-give-use-the-enum-type! :-(")); - break; - } - - - case BRO_TYPE_PORT: { - BroPort *port = (BroPort*)data; - val = PyTuple_New(2); - PyTuple_SetItem(val, 0, PyInt_FromLong(port->port_num)); - PyTuple_SetItem(val, 1, PyInt_FromLong(port->port_proto)); - break; - } - - case BRO_TYPE_SUBNET: { - BroSubnet *subnet = (BroSubnet*)data; - val = PyTuple_New(2); - PyTuple_SetItem(val, 0, PyInt_FromLong(subnet->sn_net)); - PyTuple_SetItem(val, 1, PyInt_FromLong(subnet->sn_width)); - break; - } - - case BRO_TYPE_RECORD: { - BroRecord *rec = (BroRecord*)data; - PyObject *fields = PyList_New(rec->val_len); - int i; - for ( i = 0; i < rec->val_len; i++ ) { - int type = BRO_TYPE_UNKNOWN; - void *data = bro_record_get_nth_val(rec, i, &type); - PyList_SetItem(fields, i, valToPyObj(type, data)); - } - val = fields; - break; - } - - default: - PyErr_SetString(PyExc_RuntimeError, "unknown type"); - return 0; - - } - - return makeTypeTuple(type, val); -} - -// Converts a Python object into Broccoli value. -int pyObjToVal(PyObject *val, int type, const char **type_name, void** data) -{ - *type_name = 0; - *data = 0; - - switch (type) { - case BRO_TYPE_BOOL: - case BRO_TYPE_INT: - case BRO_TYPE_COUNT: - case BRO_TYPE_COUNTER: - case BRO_TYPE_IPADDR: - case BRO_TYPE_NET: { - int* tmp = (int *)malloc(sizeof(int)); - *tmp = PyInt_AsLong(val); - *data = tmp; - break; - } - - case BRO_TYPE_DOUBLE: - case BRO_TYPE_TIME: - case BRO_TYPE_INTERVAL: { - double* tmp = (double *)malloc(sizeof(double)); - *tmp = PyFloat_AsDouble(val); - *data = tmp; - break; - } - - case BRO_TYPE_STRING: { - BroString* str = (BroString *)malloc(sizeof(BroString)); - - const char* tmp = PyString_AsString(val); - if ( ! tmp ) - return 0; - - str->str_len = strlen(tmp); - str->str_val = strdup(tmp); - *data = str; - break; - } - - case BRO_TYPE_ENUM: { - if ( ! (PyTuple_Check(val) && PyTuple_Size(val) == 2) ) { - PyErr_SetString(PyExc_RuntimeError, "enum must be 2-tuple"); - return 0; - } - - int* tmp = (int *)malloc(sizeof(int)); - *tmp = PyInt_AsLong(PyTuple_GetItem(val, 0)); - *data = tmp; - - const char* enum_type = PyString_AsString(PyTuple_GetItem(val, 1)); - if ( ! enum_type ) - return 0; - - *type_name = strdup(enum_type); - break; - } - - case BRO_TYPE_PORT: { - if ( ! (PyTuple_Check(val) && PyTuple_Size(val) == 2) ) { - PyErr_SetString(PyExc_RuntimeError, "port must be 2-tuple"); - return 0; - } - - BroPort* port = (BroPort *)malloc(sizeof(BroPort)); - port->port_num = PyInt_AsLong(PyTuple_GetItem(val, 0)); - port->port_proto = PyInt_AsLong(PyTuple_GetItem(val, 1)); - *data = port; - break; - } - - case BRO_TYPE_SUBNET: { - if ( ! (PyTuple_Check(val) && PyTuple_Size(val) == 2) ) { - PyErr_SetString(PyExc_RuntimeError, "subnet must be 2-tuple"); - return 0; - } - - BroSubnet* subnet = (BroSubnet *)malloc(sizeof(BroSubnet)); - subnet->sn_net = PyInt_AsLong(PyTuple_GetItem(val, 0)); - subnet->sn_width = PyInt_AsLong(PyTuple_GetItem(val, 1)); - *data = subnet; - break; - } - - case BRO_TYPE_RECORD: { - BroRecord *rec = bro_record_new(); - int i; - for ( i = 0; i < PyList_Size(val); i++ ) { - int ftype; - PyObject *fval; - if ( ! parseTypeTuple(PyList_GetItem(val, i), &ftype, &fval) ) - return 0; - - const char *ftype_name; - void *fdata; - if ( ! pyObjToVal(fval, ftype, &ftype_name, &fdata) ) - return 0; - - bro_record_add_val(rec, "", ftype, 0, fdata); - freeBroccoliVal(ftype, fdata); - } - - *data = rec; - break; - } - - default: - PyErr_SetString(PyExc_RuntimeError, "unknown type"); - return 0; - } - - return 1; -} - -// C-level event handler for events. We register all events with this callback, -// passing the target Python function in via data. -void event_callback(BroConn *bc, void *data, BroEvMeta *meta) -{ - PyObject *func = (PyObject*)data; - - int i; - PyObject *pyargs = PyTuple_New(meta->ev_numargs); - for ( i = 0; i < meta->ev_numargs; i++ ) - PyTuple_SetItem(pyargs, i, valToPyObj(meta->ev_args[i].arg_type, meta->ev_args[i].arg_data)); - - PyObject *result = PyObject_Call(func, pyargs, 0); - - Py_DECREF(pyargs); - - if ( result ) - Py_DECREF(result); -} - - - - #define SWIG_From_long PyInt_FromLong - - -SWIGINTERNINLINE PyObject * -SWIG_From_int (int value) -{ - return SWIG_From_long (value); -} - - -SWIGINTERN swig_type_info* -SWIG_pchar_descriptor(void) -{ - static int init = 0; - static swig_type_info* info = 0; - if (!init) { - info = SWIG_TypeQuery("_p_char"); - init = 1; - } - return info; -} - - -SWIGINTERN int -SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc) -{ - if (PyString_Check(obj)) { - char *cstr; Py_ssize_t len; - PyString_AsStringAndSize(obj, &cstr, &len); - if (cptr) { - if (alloc) { - /* - In python the user should not be able to modify the inner - string representation. To warranty that, if you define - SWIG_PYTHON_SAFE_CSTRINGS, a new/copy of the python string - buffer is always returned. - - The default behavior is just to return the pointer value, - so, be careful. - */ -#if defined(SWIG_PYTHON_SAFE_CSTRINGS) - if (*alloc != SWIG_OLDOBJ) -#else - if (*alloc == SWIG_NEWOBJ) -#endif - { - *cptr = (char *)memcpy((char *)malloc((len + 1)*sizeof(char)), cstr, sizeof(char)*(len + 1)); - *alloc = SWIG_NEWOBJ; - } - else { - *cptr = cstr; - *alloc = SWIG_OLDOBJ; - } - } else { - *cptr = PyString_AsString(obj); - } - } - if (psize) *psize = len + 1; - return SWIG_OK; - } else { - swig_type_info* pchar_descriptor = SWIG_pchar_descriptor(); - if (pchar_descriptor) { - void* vptr = 0; - if (SWIG_ConvertPtr(obj, &vptr, pchar_descriptor, 0) == SWIG_OK) { - if (cptr) *cptr = (char *) vptr; - if (psize) *psize = vptr ? (strlen((char *)vptr) + 1) : 0; - if (alloc) *alloc = SWIG_OLDOBJ; - return SWIG_OK; - } - } - } - return SWIG_TypeError; -} - - - - - -#include -#ifndef LLONG_MIN -# define LLONG_MIN LONG_LONG_MIN -#endif -#ifndef LLONG_MAX -# define LLONG_MAX LONG_LONG_MAX -#endif -#ifndef ULLONG_MAX -# define ULLONG_MAX ULONG_LONG_MAX -#endif - - -SWIGINTERN int -SWIG_AsVal_double (PyObject *obj, double *val) -{ - int res = SWIG_TypeError; - if (PyFloat_Check(obj)) { - if (val) *val = PyFloat_AsDouble(obj); - return SWIG_OK; - } else if (PyInt_Check(obj)) { - if (val) *val = PyInt_AsLong(obj); - return SWIG_OK; - } else if (PyLong_Check(obj)) { - double v = PyLong_AsDouble(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - } - } -#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - double d = PyFloat_AsDouble(obj); - if (!PyErr_Occurred()) { - if (val) *val = d; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - long v = PyLong_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_AddCast(SWIG_OK)); - } else { - PyErr_Clear(); - } - } - } -#endif - return res; -} - - -#include - - -#include - - -SWIGINTERNINLINE int -SWIG_CanCastAsInteger(double *d, double min, double max) { - double x = *d; - if ((min <= x && x <= max)) { - double fx = floor(x); - double cx = ceil(x); - double rd = ((x - fx) < 0.5) ? fx : cx; /* simple rint */ - if ((errno == EDOM) || (errno == ERANGE)) { - errno = 0; - } else { - double summ, reps, diff; - if (rd < x) { - diff = x - rd; - } else if (rd > x) { - diff = rd - x; - } else { - return 1; - } - summ = rd + x; - reps = diff/summ; - if (reps < 8*DBL_EPSILON) { - *d = rd; - return 1; - } - } - } - return 0; -} - - -SWIGINTERN int -SWIG_AsVal_long (PyObject *obj, long* val) -{ - if (PyInt_Check(obj)) { - if (val) *val = PyInt_AsLong(obj); - return SWIG_OK; - } else if (PyLong_Check(obj)) { - long v = PyLong_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_OK; - } else { - PyErr_Clear(); - } - } -#ifdef SWIG_PYTHON_CAST_MODE - { - int dispatch = 0; - long v = PyInt_AsLong(obj); - if (!PyErr_Occurred()) { - if (val) *val = v; - return SWIG_AddCast(SWIG_OK); - } else { - PyErr_Clear(); - } - if (!dispatch) { - double d; - int res = SWIG_AddCast(SWIG_AsVal_double (obj,&d)); - if (SWIG_IsOK(res) && SWIG_CanCastAsInteger(&d, LONG_MIN, LONG_MAX)) { - if (val) *val = (long)(d); - return res; - } - } - } -#endif - return SWIG_TypeError; -} - - -SWIGINTERN int -SWIG_AsVal_int (PyObject * obj, int *val) -{ - long v; - int res = SWIG_AsVal_long (obj, &v); - if (SWIG_IsOK(res)) { - if ((v < INT_MIN || v > INT_MAX)) { - return SWIG_OverflowError; - } else { - if (val) *val = (int)(v); - } - } - return res; -} - - - #define SWIG_From_double PyFloat_FromDouble - -#ifdef __cplusplus -extern "C" { -#endif -SWIGINTERN PyObject *_wrap_bro_init(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - BroCtx *arg1 = (BroCtx *) 0 ; - int result; - int res1 ; - PyObject * obj0 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"O:bro_init",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0,SWIG_as_voidptrptr(&arg1), 0, 0); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bro_init" "', argument " "1"" of type '" "BroCtx const *""'"); - } - result = (int)bro_init((void const *)arg1); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_bro_conn_new_str(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - char *arg1 = (char *) 0 ; - int arg2 ; - BroConn *result = 0 ; - int res1 ; - char *buf1 = 0 ; - int alloc1 = 0 ; - int val2 ; - int ecode2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"OO:bro_conn_new_str",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bro_conn_new_str" "', argument " "1"" of type '" "char const *""'"); - } - arg1 = (char *)(buf1); - ecode2 = SWIG_AsVal_int(obj1, &val2); - if (!SWIG_IsOK(ecode2)) { - SWIG_exception_fail(SWIG_ArgError(ecode2), "in method '" "bro_conn_new_str" "', argument " "2"" of type '" "int""'"); - } - arg2 = (int)(val2); - result = (BroConn *)bro_conn_new_str((char const *)arg1,arg2); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_void, 0 | 0 ); - if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); - return resultobj; -fail: - if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_bro_conn_set_class(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - BroConn *arg1 = (BroConn *) 0 ; - char *arg2 = (char *) 0 ; - int res1 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"OO:bro_conn_set_class",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0,SWIG_as_voidptrptr(&arg1), 0, 0); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bro_conn_set_class" "', argument " "1"" of type '" "BroConn *""'"); - } - res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "bro_conn_set_class" "', argument " "2"" of type '" "char const *""'"); - } - arg2 = (char *)(buf2); - bro_conn_set_class(arg1,(char const *)arg2); - resultobj = SWIG_Py_Void(); - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_bro_conn_connect(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - BroConn *arg1 = (BroConn *) 0 ; - int result; - int res1 ; - PyObject * obj0 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"O:bro_conn_connect",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0,SWIG_as_voidptrptr(&arg1), 0, 0); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bro_conn_connect" "', argument " "1"" of type '" "BroConn *""'"); - } - result = (int)bro_conn_connect(arg1); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_bro_conn_process_input(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - BroConn *arg1 = (BroConn *) 0 ; - int result; - int res1 ; - PyObject * obj0 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"O:bro_conn_process_input",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0,SWIG_as_voidptrptr(&arg1), 0, 0); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bro_conn_process_input" "', argument " "1"" of type '" "BroConn *""'"); - } - result = (int)bro_conn_process_input(arg1); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_bro_event_queue_length(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - BroConn *arg1 = (BroConn *) 0 ; - int result; - int res1 ; - PyObject * obj0 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"O:bro_event_queue_length",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0,SWIG_as_voidptrptr(&arg1), 0, 0); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bro_event_queue_length" "', argument " "1"" of type '" "BroConn *""'"); - } - result = (int)bro_event_queue_length(arg1); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_bro_event_new(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - char *arg1 = (char *) 0 ; - BroEvent *result = 0 ; - int res1 ; - char *buf1 = 0 ; - int alloc1 = 0 ; - PyObject * obj0 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"O:bro_event_new",&obj0)) SWIG_fail; - res1 = SWIG_AsCharPtrAndSize(obj0, &buf1, NULL, &alloc1); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bro_event_new" "', argument " "1"" of type '" "char const *""'"); - } - arg1 = (char *)(buf1); - result = (BroEvent *)bro_event_new((char const *)arg1); - resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_void, 0 | 0 ); - if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); - return resultobj; -fail: - if (alloc1 == SWIG_NEWOBJ) free((char*)buf1); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_bro_event_free(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - BroEvent *arg1 = (BroEvent *) 0 ; - int res1 ; - PyObject * obj0 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"O:bro_event_free",&obj0)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0,SWIG_as_voidptrptr(&arg1), 0, 0); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bro_event_free" "', argument " "1"" of type '" "BroEvent *""'"); - } - bro_event_free(arg1); - resultobj = SWIG_Py_Void(); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_bro_event_add_val(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - BroEvent *arg1 = (BroEvent *) 0 ; - int arg2 ; - char *arg3 = (char *) 0 ; - void *arg4 = (void *) 0 ; - int result; - int res1 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"OO:bro_event_add_val",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0,SWIG_as_voidptrptr(&arg1), 0, 0); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bro_event_add_val" "', argument " "1"" of type '" "BroEvent *""'"); - } - { - int type; - const char* type_name; - void *data; - - PyObject *val; - - //bro_debug_messages = 1; - //bro_debug_calltrace = 1; - - - if ( ! parseTypeTuple(obj1, &type, &val) ) - return NULL; - - if ( ! pyObjToVal(val, type, &type_name, &data) ) - return NULL; - - arg2 = type; - arg3 = type_name; - arg4 = data; - } - result = (int)bro_event_add_val(arg1,arg2,(char const *)arg3,(void const *)arg4); - resultobj = SWIG_From_int((int)(result)); - { - // Broccoli makes copies of the passed data so we need to clean up. - freeBroccoliVal(arg2, arg4); - - if ( arg3 ) - free(arg3); - } - return resultobj; -fail: - { - // Broccoli makes copies of the passed data so we need to clean up. - freeBroccoliVal(arg2, arg4); - - if ( arg3 ) - free(arg3); - } - return NULL; -} - - -SWIGINTERN PyObject *_wrap_bro_event_send(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - BroConn *arg1 = (BroConn *) 0 ; - BroEvent *arg2 = (BroEvent *) 0 ; - int result; - int res1 ; - int res2 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"OO:bro_event_send",&obj0,&obj1)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0,SWIG_as_voidptrptr(&arg1), 0, 0); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bro_event_send" "', argument " "1"" of type '" "BroConn *""'"); - } - res2 = SWIG_ConvertPtr(obj1,SWIG_as_voidptrptr(&arg2), 0, 0); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "bro_event_send" "', argument " "2"" of type '" "BroEvent *""'"); - } - result = (int)bro_event_send(arg1,arg2); - resultobj = SWIG_From_int((int)(result)); - return resultobj; -fail: - return NULL; -} - - -SWIGINTERN PyObject *_wrap_bro_event_registry_add_compact(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - BroConn *arg1 = (BroConn *) 0 ; - char *arg2 = (char *) 0 ; - BroCompactEventFunc arg3 ; - void *arg4 = (void *) 0 ; - int res1 ; - int res2 ; - char *buf2 = 0 ; - int alloc2 = 0 ; - PyObject * obj0 = 0 ; - PyObject * obj1 = 0 ; - PyObject * obj2 = 0 ; - - if (!PyArg_ParseTuple(args,(char *)"OOO:bro_event_registry_add_compact",&obj0,&obj1,&obj2)) SWIG_fail; - res1 = SWIG_ConvertPtr(obj0,SWIG_as_voidptrptr(&arg1), 0, 0); - if (!SWIG_IsOK(res1)) { - SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "bro_event_registry_add_compact" "', argument " "1"" of type '" "BroConn *""'"); - } - res2 = SWIG_AsCharPtrAndSize(obj1, &buf2, NULL, &alloc2); - if (!SWIG_IsOK(res2)) { - SWIG_exception_fail(SWIG_ArgError(res2), "in method '" "bro_event_registry_add_compact" "', argument " "2"" of type '" "char const *""'"); - } - arg2 = (char *)(buf2); - { - if ( ! PyFunction_Check(obj2) ) { - PyErr_SetString(PyExc_RuntimeError, "callback must be a function"); - return NULL; - } - - arg3 = event_callback; - arg4 = obj2; - Py_INCREF(obj2); - } - bro_event_registry_add_compact(arg1,(char const *)arg2,arg3,arg4); - resultobj = SWIG_Py_Void(); - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return resultobj; -fail: - if (alloc2 == SWIG_NEWOBJ) free((char*)buf2); - return NULL; -} - - -SWIGINTERN PyObject *_wrap_bro_util_current_time(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { - PyObject *resultobj = 0; - double result; - - if (!PyArg_ParseTuple(args,(char *)":bro_util_current_time")) SWIG_fail; - result = (double)bro_util_current_time(); - resultobj = SWIG_From_double((double)(result)); - return resultobj; -fail: - return NULL; -} - - -static PyMethodDef SwigMethods[] = { - { (char *)"bro_init", _wrap_bro_init, METH_VARARGS, NULL}, - { (char *)"bro_conn_new_str", _wrap_bro_conn_new_str, METH_VARARGS, NULL}, - { (char *)"bro_conn_set_class", _wrap_bro_conn_set_class, METH_VARARGS, NULL}, - { (char *)"bro_conn_connect", _wrap_bro_conn_connect, METH_VARARGS, NULL}, - { (char *)"bro_conn_process_input", _wrap_bro_conn_process_input, METH_VARARGS, NULL}, - { (char *)"bro_event_queue_length", _wrap_bro_event_queue_length, METH_VARARGS, NULL}, - { (char *)"bro_event_new", _wrap_bro_event_new, METH_VARARGS, NULL}, - { (char *)"bro_event_free", _wrap_bro_event_free, METH_VARARGS, NULL}, - { (char *)"bro_event_add_val", _wrap_bro_event_add_val, METH_VARARGS, NULL}, - { (char *)"bro_event_send", _wrap_bro_event_send, METH_VARARGS, NULL}, - { (char *)"bro_event_registry_add_compact", _wrap_bro_event_registry_add_compact, METH_VARARGS, NULL}, - { (char *)"bro_util_current_time", _wrap_bro_util_current_time, METH_VARARGS, NULL}, - { NULL, NULL, 0, NULL } -}; - - -/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (BEGIN) -------- */ - -static swig_type_info _swigt__p_BroCompactEventFunc = {"_p_BroCompactEventFunc", "BroCompactEventFunc *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_char = {"_p_char", "char *", 0, 0, (void*)0, 0}; -static swig_type_info _swigt__p_void = {"_p_void", "void *|BroEvent *", 0, 0, (void*)0, 0}; - -static swig_type_info *swig_type_initial[] = { - &_swigt__p_BroCompactEventFunc, - &_swigt__p_char, - &_swigt__p_void, -}; - -static swig_cast_info _swigc__p_BroCompactEventFunc[] = { {&_swigt__p_BroCompactEventFunc, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_char[] = { {&_swigt__p_char, 0, 0, 0},{0, 0, 0, 0}}; -static swig_cast_info _swigc__p_void[] = { {&_swigt__p_void, 0, 0, 0},{0, 0, 0, 0}}; - -static swig_cast_info *swig_cast_initial[] = { - _swigc__p_BroCompactEventFunc, - _swigc__p_char, - _swigc__p_void, -}; - - -/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */ - -static swig_const_info swig_const_table[] = { -{0, 0, 0, 0.0, 0, 0}}; - -#ifdef __cplusplus -} -#endif -/* ----------------------------------------------------------------------------- - * Type initialization: - * This problem is tough by the requirement that no dynamic - * memory is used. Also, since swig_type_info structures store pointers to - * swig_cast_info structures and swig_cast_info structures store pointers back - * to swig_type_info structures, we need some lookup code at initialization. - * The idea is that swig generates all the structures that are needed. - * The runtime then collects these partially filled structures. - * The SWIG_InitializeModule function takes these initial arrays out of - * swig_module, and does all the lookup, filling in the swig_module.types - * array with the correct data and linking the correct swig_cast_info - * structures together. - * - * The generated swig_type_info structures are assigned staticly to an initial - * array. We just loop through that array, and handle each type individually. - * First we lookup if this type has been already loaded, and if so, use the - * loaded structure instead of the generated one. Then we have to fill in the - * cast linked list. The cast data is initially stored in something like a - * two-dimensional array. Each row corresponds to a type (there are the same - * number of rows as there are in the swig_type_initial array). Each entry in - * a column is one of the swig_cast_info structures for that type. - * The cast_initial array is actually an array of arrays, because each row has - * a variable number of columns. So to actually build the cast linked list, - * we find the array of casts associated with the type, and loop through it - * adding the casts to the list. The one last trick we need to do is making - * sure the type pointer in the swig_cast_info struct is correct. - * - * First off, we lookup the cast->type name to see if it is already loaded. - * There are three cases to handle: - * 1) If the cast->type has already been loaded AND the type we are adding - * casting info to has not been loaded (it is in this module), THEN we - * replace the cast->type pointer with the type pointer that has already - * been loaded. - * 2) If BOTH types (the one we are adding casting info to, and the - * cast->type) are loaded, THEN the cast info has already been loaded by - * the previous module so we just ignore it. - * 3) Finally, if cast->type has not already been loaded, then we add that - * swig_cast_info to the linked list (because the cast->type) pointer will - * be correct. - * ----------------------------------------------------------------------------- */ - -#ifdef __cplusplus -extern "C" { -#if 0 -} /* c-mode */ -#endif -#endif - -#if 0 -#define SWIGRUNTIME_DEBUG -#endif - - -SWIGRUNTIME void -SWIG_InitializeModule(void *clientdata) { - size_t i; - swig_module_info *module_head, *iter; - int found; - - clientdata = clientdata; - - /* check to see if the circular list has been setup, if not, set it up */ - if (swig_module.next==0) { - /* Initialize the swig_module */ - swig_module.type_initial = swig_type_initial; - swig_module.cast_initial = swig_cast_initial; - swig_module.next = &swig_module; - } - - /* Try and load any already created modules */ - module_head = SWIG_GetModule(clientdata); - if (!module_head) { - /* This is the first module loaded for this interpreter */ - /* so set the swig module into the interpreter */ - SWIG_SetModule(clientdata, &swig_module); - module_head = &swig_module; - } else { - /* the interpreter has loaded a SWIG module, but has it loaded this one? */ - found=0; - iter=module_head; - do { - if (iter==&swig_module) { - found=1; - break; - } - iter=iter->next; - } while (iter!= module_head); - - /* if the is found in the list, then all is done and we may leave */ - if (found) return; - /* otherwise we must add out module into the list */ - swig_module.next = module_head->next; - module_head->next = &swig_module; - } - - /* Now work on filling in swig_module.types */ -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: size %d\n", swig_module.size); -#endif - for (i = 0; i < swig_module.size; ++i) { - swig_type_info *type = 0; - swig_type_info *ret; - swig_cast_info *cast; - -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); -#endif - - /* if there is another module already loaded */ - if (swig_module.next != &swig_module) { - type = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, swig_module.type_initial[i]->name); - } - if (type) { - /* Overwrite clientdata field */ -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: found type %s\n", type->name); -#endif - if (swig_module.type_initial[i]->clientdata) { - type->clientdata = swig_module.type_initial[i]->clientdata; -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: found and overwrite type %s \n", type->name); -#endif - } - } else { - type = swig_module.type_initial[i]; - } - - /* Insert casting types */ - cast = swig_module.cast_initial[i]; - while (cast->type) { - /* Don't need to add information already in the list */ - ret = 0; -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: look cast %s\n", cast->type->name); -#endif - if (swig_module.next != &swig_module) { - ret = SWIG_MangledTypeQueryModule(swig_module.next, &swig_module, cast->type->name); -#ifdef SWIGRUNTIME_DEBUG - if (ret) printf("SWIG_InitializeModule: found cast %s\n", ret->name); -#endif - } - if (ret) { - if (type == swig_module.type_initial[i]) { -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: skip old type %s\n", ret->name); -#endif - cast->type = ret; - ret = 0; - } else { - /* Check for casting already in the list */ - swig_cast_info *ocast = SWIG_TypeCheck(ret->name, type); -#ifdef SWIGRUNTIME_DEBUG - if (ocast) printf("SWIG_InitializeModule: skip old cast %s\n", ret->name); -#endif - if (!ocast) ret = 0; - } - } - - if (!ret) { -#ifdef SWIGRUNTIME_DEBUG - printf("SWIG_InitializeModule: adding cast %s\n", cast->type->name); -#endif - if (type->cast) { - type->cast->prev = cast; - cast->next = type->cast; - } - type->cast = cast; - } - cast++; - } - /* Set entry in modules->types array equal to the type */ - swig_module.types[i] = type; - } - swig_module.types[i] = 0; - -#ifdef SWIGRUNTIME_DEBUG - printf("**** SWIG_InitializeModule: Cast List ******\n"); - for (i = 0; i < swig_module.size; ++i) { - int j = 0; - swig_cast_info *cast = swig_module.cast_initial[i]; - printf("SWIG_InitializeModule: type %d %s\n", i, swig_module.type_initial[i]->name); - while (cast->type) { - printf("SWIG_InitializeModule: cast type %s\n", cast->type->name); - cast++; - ++j; - } - printf("---- Total casts: %d\n",j); - } - printf("**** SWIG_InitializeModule: Cast List ******\n"); -#endif -} - -/* This function will propagate the clientdata field of type to -* any new swig_type_info structures that have been added into the list -* of equivalent types. It is like calling -* SWIG_TypeClientData(type, clientdata) a second time. -*/ -SWIGRUNTIME void -SWIG_PropagateClientData(void) { - size_t i; - swig_cast_info *equiv; - static int init_run = 0; - - if (init_run) return; - init_run = 1; - - for (i = 0; i < swig_module.size; i++) { - if (swig_module.types[i]->clientdata) { - equiv = swig_module.types[i]->cast; - while (equiv) { - if (!equiv->converter) { - if (equiv->type && !equiv->type->clientdata) - SWIG_TypeClientData(equiv->type, swig_module.types[i]->clientdata); - } - equiv = equiv->next; - } - } - } -} - -#ifdef __cplusplus -#if 0 -{ - /* c-mode */ -#endif -} -#endif - - - -#ifdef __cplusplus -extern "C" { -#endif - - /* Python-specific SWIG API */ -#define SWIG_newvarlink() SWIG_Python_newvarlink() -#define SWIG_addvarlink(p, name, get_attr, set_attr) SWIG_Python_addvarlink(p, name, get_attr, set_attr) -#define SWIG_InstallConstants(d, constants) SWIG_Python_InstallConstants(d, constants) - - /* ----------------------------------------------------------------------------- - * global variable support code. - * ----------------------------------------------------------------------------- */ - - typedef struct swig_globalvar { - char *name; /* Name of global variable */ - PyObject *(*get_attr)(void); /* Return the current value */ - int (*set_attr)(PyObject *); /* Set the value */ - struct swig_globalvar *next; - } swig_globalvar; - - typedef struct swig_varlinkobject { - PyObject_HEAD - swig_globalvar *vars; - } swig_varlinkobject; - - SWIGINTERN PyObject * - swig_varlink_repr(swig_varlinkobject *SWIGUNUSEDPARM(v)) { - return PyString_FromString(""); - } - - SWIGINTERN PyObject * - swig_varlink_str(swig_varlinkobject *v) { - PyObject *str = PyString_FromString("("); - swig_globalvar *var; - for (var = v->vars; var; var=var->next) { - PyString_ConcatAndDel(&str,PyString_FromString(var->name)); - if (var->next) PyString_ConcatAndDel(&str,PyString_FromString(", ")); - } - PyString_ConcatAndDel(&str,PyString_FromString(")")); - return str; - } - - SWIGINTERN int - swig_varlink_print(swig_varlinkobject *v, FILE *fp, int SWIGUNUSEDPARM(flags)) { - PyObject *str = swig_varlink_str(v); - fprintf(fp,"Swig global variables "); - fprintf(fp,"%s\n", PyString_AsString(str)); - Py_DECREF(str); - return 0; - } - - SWIGINTERN void - swig_varlink_dealloc(swig_varlinkobject *v) { - swig_globalvar *var = v->vars; - while (var) { - swig_globalvar *n = var->next; - free(var->name); - free(var); - var = n; - } - } - - SWIGINTERN PyObject * - swig_varlink_getattr(swig_varlinkobject *v, char *n) { - PyObject *res = NULL; - swig_globalvar *var = v->vars; - while (var) { - if (strcmp(var->name,n) == 0) { - res = (*var->get_attr)(); - break; - } - var = var->next; - } - if (res == NULL && !PyErr_Occurred()) { - PyErr_SetString(PyExc_NameError,"Unknown C global variable"); - } - return res; - } - - SWIGINTERN int - swig_varlink_setattr(swig_varlinkobject *v, char *n, PyObject *p) { - int res = 1; - swig_globalvar *var = v->vars; - while (var) { - if (strcmp(var->name,n) == 0) { - res = (*var->set_attr)(p); - break; - } - var = var->next; - } - if (res == 1 && !PyErr_Occurred()) { - PyErr_SetString(PyExc_NameError,"Unknown C global variable"); - } - return res; - } - - SWIGINTERN PyTypeObject* - swig_varlink_type(void) { - static char varlink__doc__[] = "Swig var link object"; - static PyTypeObject varlink_type; - static int type_init = 0; - if (!type_init) { - const PyTypeObject tmp - = { - PyObject_HEAD_INIT(NULL) - 0, /* Number of items in variable part (ob_size) */ - (char *)"swigvarlink", /* Type name (tp_name) */ - sizeof(swig_varlinkobject), /* Basic size (tp_basicsize) */ - 0, /* Itemsize (tp_itemsize) */ - (destructor) swig_varlink_dealloc, /* Deallocator (tp_dealloc) */ - (printfunc) swig_varlink_print, /* Print (tp_print) */ - (getattrfunc) swig_varlink_getattr, /* get attr (tp_getattr) */ - (setattrfunc) swig_varlink_setattr, /* Set attr (tp_setattr) */ - 0, /* tp_compare */ - (reprfunc) swig_varlink_repr, /* tp_repr */ - 0, /* tp_as_number */ - 0, /* tp_as_sequence */ - 0, /* tp_as_mapping */ - 0, /* tp_hash */ - 0, /* tp_call */ - (reprfunc)swig_varlink_str, /* tp_str */ - 0, /* tp_getattro */ - 0, /* tp_setattro */ - 0, /* tp_as_buffer */ - 0, /* tp_flags */ - varlink__doc__, /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ -#if PY_VERSION_HEX >= 0x02020000 - 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_iter -> tp_weaklist */ -#endif -#if PY_VERSION_HEX >= 0x02030000 - 0, /* tp_del */ -#endif -#ifdef COUNT_ALLOCS - 0,0,0,0 /* tp_alloc -> tp_next */ -#endif - }; - varlink_type = tmp; - varlink_type.ob_type = &PyType_Type; - type_init = 1; - } - return &varlink_type; - } - - /* Create a variable linking object for use later */ - SWIGINTERN PyObject * - SWIG_Python_newvarlink(void) { - swig_varlinkobject *result = PyObject_NEW(swig_varlinkobject, swig_varlink_type()); - if (result) { - result->vars = 0; - } - return ((PyObject*) result); - } - - SWIGINTERN void - SWIG_Python_addvarlink(PyObject *p, char *name, PyObject *(*get_attr)(void), int (*set_attr)(PyObject *p)) { - swig_varlinkobject *v = (swig_varlinkobject *) p; - swig_globalvar *gv = (swig_globalvar *) malloc(sizeof(swig_globalvar)); - if (gv) { - size_t size = strlen(name)+1; - gv->name = (char *)malloc(size); - if (gv->name) { - strncpy(gv->name,name,size); - gv->get_attr = get_attr; - gv->set_attr = set_attr; - gv->next = v->vars; - } - } - v->vars = gv; - } - - SWIGINTERN PyObject * - SWIG_globals(void) { - static PyObject *_SWIG_globals = 0; - if (!_SWIG_globals) _SWIG_globals = SWIG_newvarlink(); - return _SWIG_globals; - } - - /* ----------------------------------------------------------------------------- - * constants/methods manipulation - * ----------------------------------------------------------------------------- */ - - /* Install Constants */ - SWIGINTERN void - SWIG_Python_InstallConstants(PyObject *d, swig_const_info constants[]) { - PyObject *obj = 0; - size_t i; - for (i = 0; constants[i].type; ++i) { - switch(constants[i].type) { - case SWIG_PY_POINTER: - obj = SWIG_NewPointerObj(constants[i].pvalue, *(constants[i]).ptype,0); - break; - case SWIG_PY_BINARY: - obj = SWIG_NewPackedObj(constants[i].pvalue, constants[i].lvalue, *(constants[i].ptype)); - break; - default: - obj = 0; - break; - } - if (obj) { - PyDict_SetItemString(d, constants[i].name, obj); - Py_DECREF(obj); - } - } - } - - /* -----------------------------------------------------------------------------*/ - /* Fix SwigMethods to carry the callback ptrs when needed */ - /* -----------------------------------------------------------------------------*/ - - SWIGINTERN void - SWIG_Python_FixMethods(PyMethodDef *methods, - swig_const_info *const_table, - swig_type_info **types, - swig_type_info **types_initial) { - size_t i; - for (i = 0; methods[i].ml_name; ++i) { - const char *c = methods[i].ml_doc; - if (c && (c = strstr(c, "swig_ptr: "))) { - int j; - swig_const_info *ci = 0; - const char *name = c + 10; - for (j = 0; const_table[j].type; ++j) { - if (strncmp(const_table[j].name, name, - strlen(const_table[j].name)) == 0) { - ci = &(const_table[j]); - break; - } - } - if (ci) { - size_t shift = (ci->ptype) - types; - swig_type_info *ty = types_initial[shift]; - size_t ldoc = (c - methods[i].ml_doc); - size_t lptr = strlen(ty->name)+2*sizeof(void*)+2; - char *ndoc = (char*)malloc(ldoc + lptr + 10); - if (ndoc) { - char *buff = ndoc; - void *ptr = (ci->type == SWIG_PY_POINTER) ? ci->pvalue : 0; - if (ptr) { - strncpy(buff, methods[i].ml_doc, ldoc); - buff += ldoc; - strncpy(buff, "swig_ptr: ", 10); - buff += 10; - SWIG_PackVoidPtr(buff, ptr, ty->name, lptr); - methods[i].ml_doc = ndoc; - } - } - } - } - } - } - -#ifdef __cplusplus -} -#endif - -/* -----------------------------------------------------------------------------* - * Partial Init method - * -----------------------------------------------------------------------------*/ - -#ifdef __cplusplus -extern "C" -#endif -SWIGEXPORT void SWIG_init(void) { - PyObject *m, *d; - - /* Fix SwigMethods to carry the callback ptrs when needed */ - SWIG_Python_FixMethods(SwigMethods, swig_const_table, swig_types, swig_type_initial); - - m = Py_InitModule((char *) SWIG_name, SwigMethods); - d = PyModule_GetDict(m); - - SWIG_InitializeModule(0); - SWIG_InstallConstants(d,swig_const_table); - - - SWIG_Python_SetConstant(d, "BRO_TYPE_UNKNOWN",SWIG_From_int((int)(0))); - SWIG_Python_SetConstant(d, "BRO_TYPE_BOOL",SWIG_From_int((int)(1))); - SWIG_Python_SetConstant(d, "BRO_TYPE_INT",SWIG_From_int((int)(2))); - SWIG_Python_SetConstant(d, "BRO_TYPE_COUNT",SWIG_From_int((int)(3))); - SWIG_Python_SetConstant(d, "BRO_TYPE_COUNTER",SWIG_From_int((int)(4))); - SWIG_Python_SetConstant(d, "BRO_TYPE_DOUBLE",SWIG_From_int((int)(5))); - SWIG_Python_SetConstant(d, "BRO_TYPE_TIME",SWIG_From_int((int)(6))); - SWIG_Python_SetConstant(d, "BRO_TYPE_INTERVAL",SWIG_From_int((int)(7))); - SWIG_Python_SetConstant(d, "BRO_TYPE_STRING",SWIG_From_int((int)(8))); - SWIG_Python_SetConstant(d, "BRO_TYPE_PATTERN",SWIG_From_int((int)(9))); - SWIG_Python_SetConstant(d, "BRO_TYPE_ENUM",SWIG_From_int((int)(10))); - SWIG_Python_SetConstant(d, "BRO_TYPE_TIMER",SWIG_From_int((int)(11))); - SWIG_Python_SetConstant(d, "BRO_TYPE_PORT",SWIG_From_int((int)(12))); - SWIG_Python_SetConstant(d, "BRO_TYPE_IPADDR",SWIG_From_int((int)(13))); - SWIG_Python_SetConstant(d, "BRO_TYPE_NET",SWIG_From_int((int)(14))); - SWIG_Python_SetConstant(d, "BRO_TYPE_SUBNET",SWIG_From_int((int)(15))); - SWIG_Python_SetConstant(d, "BRO_TYPE_ANY",SWIG_From_int((int)(16))); - SWIG_Python_SetConstant(d, "BRO_TYPE_TABLE",SWIG_From_int((int)(17))); - SWIG_Python_SetConstant(d, "BRO_TYPE_UNION",SWIG_From_int((int)(18))); - SWIG_Python_SetConstant(d, "BRO_TYPE_RECORD",SWIG_From_int((int)(19))); - SWIG_Python_SetConstant(d, "BRO_TYPE_LIST",SWIG_From_int((int)(20))); - SWIG_Python_SetConstant(d, "BRO_TYPE_FUNC",SWIG_From_int((int)(21))); - SWIG_Python_SetConstant(d, "BRO_TYPE_FILE",SWIG_From_int((int)(22))); - SWIG_Python_SetConstant(d, "BRO_TYPE_VECTOR",SWIG_From_int((int)(23))); - SWIG_Python_SetConstant(d, "BRO_TYPE_ERROR",SWIG_From_int((int)(24))); - SWIG_Python_SetConstant(d, "BRO_TYPE_PACKET",SWIG_From_int((int)(25))); - SWIG_Python_SetConstant(d, "BRO_TYPE_SET",SWIG_From_int((int)(26))); - SWIG_Python_SetConstant(d, "BRO_TYPE_MAX",SWIG_From_int((int)(27))); - SWIG_Python_SetConstant(d, "BRO_CFLAG_NONE",SWIG_From_int((int)(0))); - SWIG_Python_SetConstant(d, "BRO_CFLAG_RECONNECT",SWIG_From_int((int)((1 << 0)))); - SWIG_Python_SetConstant(d, "BRO_CFLAG_ALWAYS_QUEUE",SWIG_From_int((int)((1 << 1)))); - SWIG_Python_SetConstant(d, "BRO_CFLAG_SHAREABLE",SWIG_From_int((int)((1 << 2)))); - SWIG_Python_SetConstant(d, "BRO_CFLAG_DONTCACHE",SWIG_From_int((int)((1 << 3)))); - SWIG_Python_SetConstant(d, "BRO_CFLAG_YIELD",SWIG_From_int((int)((1 << 4)))); - SWIG_Python_SetConstant(d, "BRO_CFLAG_CACHE",SWIG_From_int((int)((1 << 5)))); -} - diff --git a/aux/broccoli/bindings/python/setup.py b/aux/broccoli/bindings/python/setup.py deleted file mode 100755 index 1960f22203..0000000000 --- a/aux/broccoli/bindings/python/setup.py +++ /dev/null @@ -1,21 +0,0 @@ -#! /usr/bin/env python - -import os -import sys - -from distutils.core import setup, Extension - -setup(name="pybroccoli", - version="0.1", - author="Robin Sommer", - author_email="robin@icir.org", - license="GPL", - url="http://www.icir.org/robin/pybroccoli", - py_modules=['broccoli'], - ext_modules = [ - Extension("_broccoli_intern", ["broccoli_intern_wrap.c"], - include_dirs=["../../src"], - library_dirs=["../../src/.libs"], - libraries=["broccoli"])] -) - diff --git a/aux/broccoli/bindings/python/tests/broping-record.py b/aux/broccoli/bindings/python/tests/broping-record.py deleted file mode 100755 index 305e5821ec..0000000000 --- a/aux/broccoli/bindings/python/tests/broping-record.py +++ /dev/null @@ -1,30 +0,0 @@ -#! /usr/bin/env python -# -# Use with broccoli/test/broping-record.bro. - -from time import sleep -from broccoli import * - -ping_data = record_type("seq", "src_time") -pong_data = record_type("seq", "src_time", "dst_time") - -@event(pong_data) -def pong(data): - print "pong event: seq=%i, time=%f/%f s" % (data.seq, - data.dst_time - data.src_time, current_time() - data.src_time) - -bc = Connection("127.0.0.1:47758") - -seq = 1 - -while True: - data = record(ping_data) - data.seq = count(seq) - data.src_time = time(current_time()) - bc.send("ping", data) - - seq += 1 - sleep(1) - - - diff --git a/aux/broccoli/bindings/python/tests/broping.py b/aux/broccoli/bindings/python/tests/broping.py deleted file mode 100755 index eec1d9efb3..0000000000 --- a/aux/broccoli/bindings/python/tests/broping.py +++ /dev/null @@ -1,24 +0,0 @@ -#! /usr/bin/env python -# -# Use with broccoli/test/broping.bro. - -from time import sleep -from broccoli import * - -@event -def pong(src_time, dst_time, seq): - print "pong event: seq=%i, time=%f/%f s" % (seq, - dst_time - src_time, current_time() - src_time) - -bc = Connection("127.0.0.1:47758") - -seq = 1 - -while True: - bc.send("ping", time(current_time()), count(seq)) - - seq += 1 - sleep(1) - - - diff --git a/aux/broccoli/bindings/python/tests/test.bro b/aux/broccoli/bindings/python/tests/test.bro deleted file mode 100644 index 0bb72722b3..0000000000 --- a/aux/broccoli/bindings/python/tests/test.bro +++ /dev/null @@ -1,57 +0,0 @@ - -@load listen-clear -redef listen_port_clear = 47758/tcp; - -redef Remote::destinations += { - ["broping"] = [$host = 127.0.0.1, $events = /test1|test3/, $connect=F, $ssl=F] -}; - - -### Testing atomic types. - -type foo: enum { CONST1, CONST2, CONST3 }; - -# No enum currently as Broccoli has trouble receiving them. -global test2: event(a: int, b: count, c: time, d: interval, e: bool, f: double, g: string, h: port, i: addr, j: net, k: subnet); -global test2b: event(a: int, b: count, c: time, d: interval, e: bool, f: double, g: string, h: port, i: addr, j: net, k: subnet); - -event test1(a: int, b: count, c: time, d: interval, e: bool, f: double, g: string, h: port, i: addr, j: net, k: subnet) -{ - print "==== atomic"; - print a; - print b; - print c; - print d; - print e; - print f; - print g; - print h; - print i; - print j; - print k; - - event test2(-4, 42, current_time(), 1min, T, 3.14, "Hurz", 12345/udp, 1.2.3.4, 10.0., 22.33.44.0/24); - event test2(a,b,c,d,e,f,g,h,i,j,k); - event test2b(a,b,c,d,e,f,g,h,i,j,k); -} - -### Testing record types. - -type rec: record { - a: int; - b: addr; -}; - -global test4: event(r: rec); - -event test3(r: rec) -{ - print "==== record"; - print r$a, r$b; - event test4(r); - - local r2 : rec; - r2$a = 99; - r2$b = 3.4.5.1; - event test4(r2); -} diff --git a/aux/broccoli/bindings/python/tests/test.py b/aux/broccoli/bindings/python/tests/test.py deleted file mode 100755 index 95143708f8..0000000000 --- a/aux/broccoli/bindings/python/tests/test.py +++ /dev/null @@ -1,89 +0,0 @@ -#! /usr/bin/env python - -import time as Time - -from broccoli import * - -@event -def test2(a,b,c,d,e,f,g,h,i,j,k): - global recv - recv += 1 - print "==== atomic a %d ====" % recv - print repr(a), a - print repr(b), b - print repr(c), c - print repr(d), d - print repr(e), e - print repr(f), f - print repr(g), g - print repr(h), h - print repr(i), i - print repr(j), j - print repr(j), k - -# Same except with typing this time. -@event(int,count,time,interval,bool,double,addr,port,addr,net,subnet) -def test2b(a,b,c,d,e,f,g,h,i,j,k): - print "==== atomic b %d ====" % recv - print repr(a), a - print repr(b), b - print repr(c), c - print repr(d), d - print repr(e), e - print repr(f), f - print repr(g), g - print repr(h), h - print repr(i), i - print repr(j), j - print repr(j), k - -rec = record_type("a", "b") - -@event(rec) -def test4(r): - global recv - recv += 1 - print "==== record %d ====" % recv - print repr(r) - print repr(r.a), r.a - print repr(r.b), r.b - -bc = Connection("127.0.0.1:47758") - -bc.send("test1", - int(-10), - count(2), - time(current_time()), - interval(120), - bool(False), - double(1.5), - string("Servus"), - port("5555/tcp"), - addr("6.7.6.5"), - net("20.0."), - subnet("192.168.0.0/16") - ) - -recv = 0 -while True: - bc.processInput(); - if recv == 2: - break - Time.sleep(1) - - -r = record(rec) -r.a = 42; -r.b = addr("6.6.7.7") - -bc.send("test3", r) - -recv = 0 -while True: - bc.processInput(); - if recv == 2: - break - Time.sleep(1) - - - diff --git a/aux/broccoli/broccoli-config.in b/aux/broccoli/broccoli-config.in deleted file mode 100644 index 952bc82cb3..0000000000 --- a/aux/broccoli/broccoli-config.in +++ /dev/null @@ -1,66 +0,0 @@ -#!/bin/sh - -buildinfo=@BUILDINFO@ -prefix=@prefix@ -exec_prefix=@exec_prefix@ -exec_prefix_set=no - -usage="\ -Usage: broccoli-config [--build] [--prefix[=DIR]] [--exec-prefix[=DIR]] [--version] [--libs] [--cflags] [--config]" - -if test $# -eq 0; then - echo "${usage}" 1>&2 - exit 1 -fi - -while test $# -gt 0; do - case "$1" in - -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;; - *) optarg= ;; - esac - - case $1 in - --build) - echo $buildinfo - ;; - --prefix=*) - prefix=$optarg - if test $exec_prefix_set = no ; then - exec_prefix=$optarg - fi - ;; - --prefix) - echo $prefix - ;; - --exec-prefix=*) - exec_prefix=$optarg - exec_prefix_set=yes - ;; - --exec-prefix) - echo $exec_prefix - ;; - --version) - echo @VERSION@ - ;; - --cflags) - if test @includedir@ != /usr/include ; then - includes=-I@includedir@ - fi - echo $includes -I$prefix/include @BRO_CFLAGSADD@ -DBROCCOLI - ;; - --libs) - libdirs=-L@libdir@ - echo $libdirs -lbroccoli @BRO_LIBADD@ - ;; - --config) - echo @BRO_SYSCONF_FILE@ - ;; - *) - echo "${usage}" 1>&2 - exit 1 - ;; - esac - shift -done - -exit 0 diff --git a/aux/broccoli/broccoli.conf b/aux/broccoli/broccoli.conf deleted file mode 100644 index c067d01f49..0000000000 --- a/aux/broccoli/broccoli.conf +++ /dev/null @@ -1,61 +0,0 @@ -# This is the Broccoli system-wide configuration file. -# -# The config file is structured into sections. The settings in each -# section are called a domain. Each domain is identified as follows: -# -# [ name ] -# -# where "name" is a single word consisting of alphanumeric letters -# without whitespace. The beginning of the document can contain -# additional settings, these comprise the default domain. It will be -# used when bro_conf_set_domain() is never used. -# -# Entries are of the form , where the identifier -# is a sequence of letters, and value can be a string (including -# whitespace), and floating point or integer numbers. Comments start -# with a "#" and go to the end of the line. For boolean values, you -# may also use "yes", "on", "true", "no", "off", or "false". -# Strings may contain whitespace, but need to be surrounded by -# double quotes '"'. -# -# You can name identifiers any way you like, but to keep things -# organized we recommend a hierarchical structure. Case matters. -# -# Examples: -# -# Foo/PeerName mybro.securesite.com -# Foo/PortNum 123 -# Bar/SomeFloat 1.23443543 -# Bar/SomeLongStr "Hello World" -# - -# Debugging output -# ---------------- -#/broccoli/debug_messages yes -#/broccoli/debug_calltrace yes - -# Encryption setup -# ---------------- -# -# In order to configure encrypted communications, you have to point -# these two entries to this agent's certificate + private key and -# the trusted CA's certificate, respectively. You can optionally -# store the passphrase for this agent's private key in the config -# file as well, but you should obviously only do so when the config -# file has appropriate access restrictions. Check the manual for -# details. -# -# use_ssl is the main switch to control whether the SSL settings -# are used (yes/on/1) or not (no/false/0). When use_ssl is not -# present, SSL is attempted if certificates are configured, other- -# wise cleartext connections are used. When it is present and enabled, -# then setup is aborted if certificates are not found. In no case -# does an SSL setup ever fall back to a cleartext one. -# -#/broccoli/use_ssl yes -#/broccoli/ca_cert /ca_cert.pem -#/broccoli/host_cert /bro_cert.pem -#/broccoli/host_pass foo - -# Your settings below -# ------------------- diff --git a/aux/broccoli/broccoli.spec b/aux/broccoli/broccoli.spec deleted file mode 100644 index 74a09e4ca8..0000000000 --- a/aux/broccoli/broccoli.spec +++ /dev/null @@ -1,69 +0,0 @@ -# This spec file creates a single relocatable RPM. -# -%define prefix /usr - -Summary: The Bro Client Communications Library -Name: broccoli -Version: 0.9 -Release: 1 -License: BSD -Group: Development/Libraries -URL: http://www.bro-ids.org -Source: http://www.icir.org/christian/downloads/%{name}-%{version}.tar.gz -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot -Packager: Christian Kreibich -Requires: openssl >= 0.9.7a -Requires: openssl-devel >= 0.9.7a -Prefix: %{prefix} - -%description -Broccoli enables your applications to speak the Bro communication protocol, -allowing you to compose, send, request, and receive events. You can register -your own event handlers. You can talk to other Broccoli applications or Bro -agents -- Bro agents cannot tell whether they are talking to another -Bro or a Broccoli application. Communications can be SSL-encrypted. Broccoli -turns Bro into a distributed policy-controlled event management system. - -%prep -%setup -q -# Needed for snapshot releases. -if [ ! -f configure ]; then - CFLAGS="$RPM_OPT_FLAGS" ./autogen.sh --prefix=%prefix -else - CFLAGS="$RPM_OPT_FLAGS" ./configure --prefix=%prefix -fi - -%build - -if [ "$SMP" != "" ]; then - (make "MAKE=make -k -j $SMP"; exit 0) - make -else - make -fi - -%install -rm -rf $RPM_BUILD_ROOT -make prefix=$RPM_BUILD_ROOT%{prefix} sysconfdir=$RPM_BUILD_ROOT/etc install - -%clean -rm -rf $RPM_BUILD_ROOT - -%post -p /sbin/ldconfig - -%postun -p /sbin/ldconfig - -%files -%defattr(-,root,root,-) -%doc AUTHORS COPYING ChangeLog NEWS README TODO -%doc %{prefix}/share/gtk-doc/html/broccoli -%{prefix}/lib/lib*.so.* -%{prefix}/lib/lib*a -%{prefix}/include/broccoli.h -%{prefix}/bin/bro* -%{prefix}/share/broccoli/*.bro -/etc/broccoli.conf - -%changelog -* Tue Dec 6 2004 Christian Kreibich -- Added spec file to tree. diff --git a/aux/broccoli/compat/sys/queue.h b/aux/broccoli/compat/sys/queue.h deleted file mode 100644 index 5b6e2a0a23..0000000000 --- a/aux/broccoli/compat/sys/queue.h +++ /dev/null @@ -1,241 +0,0 @@ -/* - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)queue.h 8.3 (Berkeley) 12/13/93 - */ - -#ifndef _SYS_QUEUE_H -#define _SYS_QUEUE_H 1 - -/* - * This file defines three types of data structures: lists, tail queues, - * and circular queues. - * - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list after - * an existing element or at the head of the list. A list may only be - * traversed in the forward direction. - * - * A tail queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list after - * an existing element, at the head of the list, or at the end of the - * list. A tail queue may only be traversed in the forward direction. - * - * A circle queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or after - * an existing element, at the head of the list, or at the end of the list. - * A circle queue may be traversed in either direction, but has a more - * complex end of list detection. - * - * For details on the use of these macros, see the queue(3) manual page. - */ - -/* - * List definitions. - */ -#define LIST_HEAD(name, type) \ -struct name { \ - struct type *lh_first; /* first element */ \ -} - -#define LIST_ENTRY(type) \ -struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ -} - -/* - * List functions. - */ -#define LIST_INIT(head) { \ - (head)->lh_first = NULL; \ -} - -#define LIST_INSERT_AFTER(listelm, elm, field) { \ - if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ - (listelm)->field.le_next->field.le_prev = \ - &(elm)->field.le_next; \ - (listelm)->field.le_next = (elm); \ - (elm)->field.le_prev = &(listelm)->field.le_next; \ -} - -#define LIST_INSERT_HEAD(head, elm, field) { \ - if (((elm)->field.le_next = (head)->lh_first) != NULL) \ - (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ - (head)->lh_first = (elm); \ - (elm)->field.le_prev = &(head)->lh_first; \ -} - -#define LIST_REMOVE(elm, field) { \ - if ((elm)->field.le_next != NULL) \ - (elm)->field.le_next->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = (elm)->field.le_next; \ -} - -/* - * Tail queue definitions. - */ -#define TAILQ_HEAD(name, type) \ -struct name { \ - struct type *tqh_first; /* first element */ \ - struct type **tqh_last; /* addr of last next element */ \ -} - -#define TAILQ_ENTRY(type) \ -struct { \ - struct type *tqe_next; /* next element */ \ - struct type **tqe_prev; /* address of previous next element */ \ -} - -/* - * Tail queue functions. - */ -#define TAILQ_INIT(head) { \ - (head)->tqh_first = NULL; \ - (head)->tqh_last = &(head)->tqh_first; \ -} - -#define TAILQ_INSERT_HEAD(head, elm, field) { \ - if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ - (elm)->field.tqe_next->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (head)->tqh_first = (elm); \ - (elm)->field.tqe_prev = &(head)->tqh_first; \ -} - -#define TAILQ_INSERT_TAIL(head, elm, field) { \ - (elm)->field.tqe_next = NULL; \ - (elm)->field.tqe_prev = (head)->tqh_last; \ - *(head)->tqh_last = (elm); \ - (head)->tqh_last = &(elm)->field.tqe_next; \ -} - -#define TAILQ_INSERT_AFTER(head, listelm, elm, field) { \ - if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ - (elm)->field.tqe_next->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (listelm)->field.tqe_next = (elm); \ - (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ -} - -#define TAILQ_REMOVE(head, elm, field) { \ - if (((elm)->field.tqe_next) != NULL) \ - (elm)->field.tqe_next->field.tqe_prev = \ - (elm)->field.tqe_prev; \ - else \ - (head)->tqh_last = (elm)->field.tqe_prev; \ - *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ -} - -/* - * Circular queue definitions. - */ -#define CIRCLEQ_HEAD(name, type) \ -struct name { \ - struct type *cqh_first; /* first element */ \ - struct type *cqh_last; /* last element */ \ -} - -#define CIRCLEQ_ENTRY(type) \ -struct { \ - struct type *cqe_next; /* next element */ \ - struct type *cqe_prev; /* previous element */ \ -} - -/* - * Circular queue functions. - */ -#define CIRCLEQ_INIT(head) { \ - (head)->cqh_first = (void *)(head); \ - (head)->cqh_last = (void *)(head); \ -} - -#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) { \ - (elm)->field.cqe_next = (listelm)->field.cqe_next; \ - (elm)->field.cqe_prev = (listelm); \ - if ((listelm)->field.cqe_next == (void *)(head)) \ - (head)->cqh_last = (elm); \ - else \ - (listelm)->field.cqe_next->field.cqe_prev = (elm); \ - (listelm)->field.cqe_next = (elm); \ -} - -#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) { \ - (elm)->field.cqe_next = (listelm); \ - (elm)->field.cqe_prev = (listelm)->field.cqe_prev; \ - if ((listelm)->field.cqe_prev == (void *)(head)) \ - (head)->cqh_first = (elm); \ - else \ - (listelm)->field.cqe_prev->field.cqe_next = (elm); \ - (listelm)->field.cqe_prev = (elm); \ -} - -#define CIRCLEQ_INSERT_HEAD(head, elm, field) { \ - (elm)->field.cqe_next = (head)->cqh_first; \ - (elm)->field.cqe_prev = (void *)(head); \ - if ((head)->cqh_last == (void *)(head)) \ - (head)->cqh_last = (elm); \ - else \ - (head)->cqh_first->field.cqe_prev = (elm); \ - (head)->cqh_first = (elm); \ -} - -#define CIRCLEQ_INSERT_TAIL(head, elm, field) { \ - (elm)->field.cqe_next = (void *)(head); \ - (elm)->field.cqe_prev = (head)->cqh_last; \ - if ((head)->cqh_first == (void *)(head)) \ - (head)->cqh_first = (elm); \ - else \ - (head)->cqh_last->field.cqe_next = (elm); \ - (head)->cqh_last = (elm); \ -} - -#define CIRCLEQ_REMOVE(head, elm, field) { \ - if ((elm)->field.cqe_next == (void *)(head)) \ - (head)->cqh_last = (elm)->field.cqe_prev; \ - else \ - (elm)->field.cqe_next->field.cqe_prev = \ - (elm)->field.cqe_prev; \ - if ((elm)->field.cqe_prev == (void *)(head)) \ - (head)->cqh_first = (elm)->field.cqe_next; \ - else \ - (elm)->field.cqe_prev->field.cqe_next = \ - (elm)->field.cqe_next; \ -} -#endif /* sys/queue.h */ diff --git a/aux/broccoli/configure.in b/aux/broccoli/configure.in deleted file mode 100644 index 61e07de967..0000000000 --- a/aux/broccoli/configure.in +++ /dev/null @@ -1,297 +0,0 @@ -dnl Process this file with autoconf to produce a configure script. - -AC_INIT -AC_CONFIG_SRCDIR([src/broccoli.h.in]) - -AC_CANONICAL_TARGET -AC_CANONICAL_HOST - -AC_CONFIG_AUX_DIR(.) -AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(broccoli, 1.5.0) - -dnl Commands for funkier shell output: -BLD_ON=`./shtool echo -n -e %B` -BLD_OFF=`./shtool echo -n -e %b` - -AC_PROG_CC -AM_PROG_CC_STDC -AC_HEADER_STDC -AC_PROG_INSTALL -AM_PROG_LEX -AC_PROG_YACC - -dnl According to the autobook, we need to add this extra directive -dnl before AM_PROG_LIBTOOL to make libtool work on Windows: -AC_LIBTOOL_WIN32_DLL -AC_PROG_LIBTOOL - - -dnl Okay, the lex and yacc checks suck big time because they -dnl just fall back to assgning "yacc" to YACC and "lex" to LEX -dnl (in the best case -- I even just get ":" sometimes) as a -dnl fallback, without checking if those actually exist. -dnl (Someone correct me if this is wrong, though I doubt it) -dnl So in those cases, run an extra AC_PROG_CHECK to see if we -dnl actually have them. Argh. -have_lex=true -have_yacc=true - -if test "x$YACC" = "xyacc"; then - AC_PATH_PROG(have_yacc, yacc, no) -fi - -if test ! "x$LEX" = "xflex"; then - AC_PATH_PROG(have_lex, lex, no) -fi - -AM_CONDITIONAL(HAVE_LEX_AND_YACC, test "x$have_yacc" != "xno" && test "x$have_lex" != "xno") - -AC_C_BIGENDIAN - -AM_CONDITIONAL(SOLARIS_HOST, false) -AM_CONDITIONAL(LINUX_HOST, false) -AM_CONDITIONAL(BSD_HOST, false) -AM_CONDITIONAL(APPLE_HOST, false) -AM_CONDITIONAL(WINDOWS_HOST, false) - -bro_libcrypto=crypto -bro_libssl=ssl - -case "$host" in - *-solaris*) - AC_DEFINE(SOLARIS_HOST, 1, [Whether this is a Solaris host]) - AM_CONDITIONAL(SOLARIS_HOST, true) - BRO_LIBADD="-lsocket -lnsl" - ;; - *-linux*) - AC_DEFINE(LINUX_HOST, 1, [Whether this is a Linux host]) - AM_CONDITIONAL(LINUX_HOST, true) - ;; - *bsd*) - AC_DEFINE(BSD_HOST, 1, [Whether this is a BSD host]) - AM_CONDITIONAL(BSD_HOST, true) - ;; - *apple*) - AC_DEFINE(APPLE_HOST, 1, [Whether this is a APPLE host]) - AM_CONDITIONAL(APPLE_HOST, true) - ;; - *-mingw32*) - AC_DEFINE(WINDOWS_HOST, 1, [Whether this run on Windows in a MinGW environment]) - AM_CONDITIONAL(WINDOWS_HOST, true) - bro_libcrypto=eay32 - bro_libssl=ssleay32 - BRO_LIBADD="-lwsock32" - ;; -esac - -AC_SUBST(BRO_LIBADD) -AC_SUBST(BRO_CFLAGSADD) - -dnl ################################################## -dnl # Check for getuid() and getpwuid(). -dnl ################################################## -AC_CHECK_FUNCS([geteuid getpwuid]) - -dnl ################################################## -dnl # Check for type uint in sys/types.h -dnl ################################################## -AC_CHECK_TYPE([uint],, - [TYPEDEF_UINT="typedef unsigned int uint;" - AC_SUBST(TYPEDEF_UINT)]) - -dnl ################################################## -dnl # Config directory and config file: -dnl # Define BRO_SYSCONF_DIR and BRO_SYSCONF_FILE. -dnl ################################################## - -dnl Unless --disable-etc-tweak is given, we check if -dnl the prefix is /usr, and in that case tweak sysconfdir -dnl to /etc (nobody cares about /usr/etc really). -dnl Otherwise we use what's given. -dnl -AC_ARG_ENABLE(etc-tweak, - AC_HELP_STRING([--disable-etc-tweak], [Do not tweak config file location to /etc if prefix is /usr]), - etc_tweak="no", - etc_tweak="yes") - -BRO_SYSCONF_DIR=`eval eval eval eval "echo $sysconfdir"` - -if test x$etc_tweak = xyes; then - if test "x${sysconfdir}" = 'x${prefix}/etc'; then - if test "x${prefix}" = "x/usr"; then - sysconfdir="/etc" - BRO_SYSCONF_DIR="$sysconfdir" - elif test "x${prefix}" = "xNONE"; then - BRO_SYSCONF_DIR="${ac_default_prefix}/etc" - fi - fi -fi - -AC_DEFINE_UNQUOTED(BRO_SYSCONF_DIR, "$BRO_SYSCONF_DIR", [Configuration directory]) -AC_SUBST(BRO_SYSCONF_DIR) - -dnl Now derive config file name from that, or use the -dnl requested one if provided. - -AC_ARG_WITH(configfile, - AC_HELP_STRING([--with-configfile=FILE], [Use config file at location ]), - [BRO_SYSCONF_FILE="$withval"], - [BRO_SYSCONF_FILE="$BRO_SYSCONF_DIR/broccoli.conf"]) - -AC_DEFINE_UNQUOTED(BRO_SYSCONF_FILE, "$BRO_SYSCONF_FILE", [Location of config file]) -AC_SUBST(BRO_SYSCONF_FILE) - -dnl ################################################## -dnl # Packet support enable/disable switch -dnl ################################################## -AC_ARG_WITH(pcap-headers, - [ --with-pcap-headers=PATH Add PATH to include path searched for pcap.h], - CPPFLAGS="$CPPFLAGS -I$withval") - -AC_ARG_ENABLE(packets, - AC_HELP_STRING([--disable-packets], [Do not support tx/rx of pcap packets]), - packet_support="no", - packet_support="yes") - -if test "$packet_support" = "yes"; then - AC_CHECK_HEADERS(pcap.h, , packet_support="no") - if test "$packet_support" = "yes"; then - BRO_PCAP_SUPPORT="#define BRO_PCAP_SUPPORT" - fi -fi - -AM_CONDITIONAL(BRO_PCAP_SUPPORT, test "$packet_support" = "yes") -AC_SUBST(BRO_PCAP_SUPPORT) - -dnl ################################################## -dnl # Debugging enable/disable switch -dnl ################################################## -AC_ARG_ENABLE(debug, - AC_HELP_STRING([--enable-debug], [Use debugging macros to produce helpful output (disabled by default)]), - debug="yes", - debug="no") - -if test x$debug = xyes; then - - - AC_DEFINE_UNQUOTED(BRO_DEBUG, 1, [Enable debugging output]) -fi - - -dnl ################################################## -dnl # Check for OpenSSL. -dnl ################################################## -dnl -dnl This is mostly easy, with one exception: in the MinGW -dnl environment, instead of libcrypto we need to look for -dnl libeay32.a, and instead of libssl we need to look for -dnl ssleay32.a. This is with the OpenSSL for Windows package -dnl from http://www.slproweb.com/products/Win32OpenSSL.html. -dnl -AC_ARG_WITH(openssl, - [ --with-openssl=DIR Use OpenSSL installation in DIR], - [CPPFLAGS="-I$withval/include $CPPFLAGS" - LIBS="-L$withval/lib $LIBS"]) -AC_ARG_WITH(kerberos, - [ --with-kerberos=DIR Use Kerberos installation in DIR], - [CPPFLAGS="$CPPFLAGS -I$withval/include" ], - [if test -d "/usr/kerberos"; then CPPFLAGS="$CPPFLAGS -I/usr/kerberos/include"; fi]) - -AC_CHECK_HEADERS([openssl/ssl.h],, - [AC_MSG_ERROR([cannot find openssl/ssl.h, sorry])]) -AC_CHECK_LIB($bro_libcrypto, OPENSSL_add_all_algorithms_conf,, - [AC_MSG_ERROR([cannot find libcrypto, sorry])], $BRO_LIBADD) -AC_CHECK_LIB($bro_libssl, SSL_new,, - [AC_MSG_ERROR([cannot find libssl, sorry])], $BRO_LIBADD) - - -dnl ################################################## -dnl # Check for gtk-doc. -dnl ################################################## - -AC_ARG_WITH(html-dir, [ --with-html-dir=PATH path to installed docs ]) - -if test "x$with_html_dir" = "x" ; then - HTML_DIR='${datadir}/gtk-doc/html' -else - HTML_DIR=$with_html_dir -fi - -AC_SUBST(HTML_DIR) - -AC_CHECK_PROG(GTKDOC, gtkdoc-mkdb, true, false) -AC_PATH_PROG(OPENJADE, openjade, no) - -gtk_doc_min_version_maj=0 -gtk_doc_min_version_min=6 - -if test x$GTKDOC = xtrue -a x$OPENJADE != xno; then - gtk_doc_version=`gtkdoc-mkdb --version` - AC_MSG_CHECKING([gtk-doc version ($gtk_doc_version) >= $gtk_doc_min_version_maj.$gtk_doc_min_version_min]) - if perl < "$gtk_doc_min_version_maj") || - (("\$1" == "$gtk_doc_min_version_maj") && - ("\$2" >= "$gtk_doc_min_version_min")))) ? 0 : 1); -EOF - AC_MSG_RESULT(yes) - else - AC_MSG_RESULT(no) - GTKDOC=false - fi -fi - -dnl Let people disable the gtk-doc stuff. -AC_ARG_ENABLE(gtk-doc, [ --enable-gtk-doc Use gtk-doc to build documentation [default=auto]], enable_gtk_doc="$enableval", enable_gtk_doc=auto) -if test x$enable_gtk_doc = xauto ; then - if test x$GTKDOC = xtrue ; then - enable_gtk_doc=yes - else - enable_gtk_doc=no - fi -fi - -AM_CONDITIONAL(ENABLE_GTK_DOC, test x$enable_gtk_doc = xyes) - -dnl ################################################## -dnl # Fix build info output string for broccoli-config -dnl ################################################## -broc_buildinfo=`uname -n` -broc_builddate=`date` -broc_builddebug="Debugging support: $debug" -BUILDINFO="\"$broc_buildinfo, $broc_builddate, $broc_builddebug\"" -AC_SUBST(BUILDINFO) - -AC_CONFIG_FILES([ -Makefile -broccoli-config -src/Makefile -src/broccoli.h -test/Makefile -docs/Makefile -docs/mkhtml -bindings/Makefile -]) -AC_CONFIG_COMMANDS([default],[[ -chmod +x broccoli-config -chmod +x docs/mkhtml -]],[[]]) -AC_OUTPUT - -echo -echo " "${BLD_ON}"Broccoli Configuration Summary"${BLD_OFF} -echo "==========================================================" -echo -echo " - Debugging enabled: "${BLD_ON}$debug${BLD_OFF} -echo " - Pcap packet support: "${BLD_ON}$packet_support${BLD_OFF} -echo -if test "x$bro_build" = xno; then -echo " Now run:" -echo -echo " $ "${BLD_ON}"make"${BLD_OFF} -echo " # "${BLD_ON}"make install"${BLD_OFF} -echo -echo " (or use "${BLD_ON}"gmake"${BLD_OFF}" when make on your platform isn't GNU make)" -echo -fi diff --git a/aux/broccoli/contrib/README b/aux/broccoli/contrib/README deleted file mode 100644 index 28e72b8d06..0000000000 --- a/aux/broccoli/contrib/README +++ /dev/null @@ -1,12 +0,0 @@ -This directory contains code contributed by others, until it's clear -where's the best place to put it. - -Note: given broccoli-config, the generic build command for a Broccoli -application is - - $ -o output `broccoli-config --cflags` \ - `broccoli-config --libs` - - --Christian. -________________________________________________________________________ -$Id: README 2035 2005-12-20 04:16:11Z vern $ diff --git a/aux/broccoli/contrib/broclient.cc b/aux/broccoli/contrib/broclient.cc deleted file mode 100644 index 21693b8052..0000000000 --- a/aux/broccoli/contrib/broclient.cc +++ /dev/null @@ -1,339 +0,0 @@ -#include -#include -#include -#include -#include - -#include -#include -#include -#include - - -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -using std::string; -using std::vector; -using std::cout; -using std::cin; -using std::cerr; - -string default_host = "127.0.0.1"; -string default_port = "47757"; -string host; -string port; - -int count = -1; -int seq; - -void -usage(void) - { - cout << "broclient - sends events with string arguments from stdin to a running Bro\n" - "USAGE: broclient [-p port=47757] [host=127.0.0.1]\n" - "Input format (each line): event_name type=arg1 type=arg2...\n"; - exit(0); - } - -void -showtypes(void) - { - cout << "Legitimate event types are:\n" - "string, int, count, double, bool, time, \n" - "interval, port, addr, net, subnet\n\n" - "eamples: string=foo, port=23/tcp, addr=10.10.10.10, \n" - "net=10.10.10.0 and subnet=10.0.0.0/8\n"; - exit(0); - } - - -void tokenize(const string& str, vector& tokens) - { - int num_tokens = 0; - char delim = '\0'; - - for ( unsigned int i = 0; i < str.length(); ++i ) - { - while ( isspace(str[i]) ) - ++i; - - string next_arg; - - if (str[i] == '"' || str[i] == '\'') - { - delim = str[i]; - ++i; - } - else - delim = '\0'; - - - for ( ; str[i]; ++i ) - { - if ( delim && str[i] == '\\' && - i < str.length() && str[i+1] == delim ) - { - ++i; - next_arg.push_back(str[i]); - } - - else if ( delim && str[i] == delim ) - { - ++i; - break; - } - - else if ( ! delim && isspace(str[i]) ) - break; - else - next_arg.push_back(str[i]); - } - - tokens.push_back(next_arg); - } - } - - - -int -main(int argc, char **argv) - { - int opt, use_record = 0, debugging = 0; - BroConn *bc; - extern char *optarg; - extern int optind; - - bro_init(NULL); - - bro_debug_calltrace = 0; - bro_debug_messages = 0; - - host = default_host; - port = default_port; - - while ( (opt = getopt(argc, argv, "p:dh?")) != -1) - { - switch (opt) - { - case 'd': - debugging++; - - if (debugging == 1) - bro_debug_messages = 1; - - if (debugging > 1) - bro_debug_calltrace = 1; - break; - - case 'h': - case '?': - usage(); - - case 'p': - port = optarg; - break; - - default: - usage(); - } - } - - argc -= optind; - argv += optind; - - if (argc > 0) - host = argv[0]; - - /* Connect to Bro */ - if (! (bc = bro_conn_new_str( (host + ":" + port).c_str(), BRO_CFLAG_NONE ))) - { - cerr << "Could not obtain connection handle for Bro at " << - host.c_str() << ":" << port.c_str() << "\n"; - exit(-1); - } - - cout << "Connecting... \n"; - if (! bro_conn_connect(bc)) - { - cout << "Could not connect to Bro.\n"; - exit(-1); - } - - cout << "Handshake Complete \n"; - /* Enter pinging loop */ - while ( ! cin.eof() ) - { - string inp; - vector tokens; - cout << "Calling getline .. \n"; - std::getline(cin, inp); - - tokenize(inp, tokens); - if ( tokens.size() == 0 ) - continue; - - BroEvent *ev; - - cout << "Calling bro_conn_process_input .. \n"; - bro_conn_process_input(bc); - - cout << "Generating Bro event \n"; - if ( (ev = bro_event_new(tokens[0].c_str())) ) - { - - for ( unsigned int i = 1; i < tokens.size(); ++i ) - { - // this is something of a nasty hack, but it does work - - string tkn,tkn_type,tkn_data; - char delim = '='; - - tkn=tokens[i].c_str(); - string::size_type position = tkn.find_first_of("=",0); - - tkn_type = tkn.substr(0,position); - tkn_data = tkn.substr(position+1,tkn.length()); - - if ( tkn_type == "string" ) - { - BroString arg; - bro_string_init(&arg); - bro_string_set(&arg, tkn_data.c_str()); - bro_event_add_val(ev, BRO_TYPE_STRING, NULL, &arg); - bro_string_cleanup(&arg); - } - else if ( tkn_type == "int" ) - { - int bint; - bint = atoi(tkn_data.c_str()); - bro_event_add_val(ev, BRO_TYPE_INT, NULL, (int*)bint); - } - else if ( tkn_type == "count" ) - { - uint32 buint; - buint = atoi(tkn_data.c_str()); - bro_event_add_val(ev, BRO_TYPE_COUNT, NULL, (uint32*)buint); - } - else if ( tkn_type == "double" ) - { - double bdouble; - char* end_s; - bdouble = strtod(tkn_data.c_str(),&end_s); - bro_event_add_val(ev, BRO_TYPE_DOUBLE, NULL, &bdouble); - } - else if ( tkn_type == "bool" ) - { - int bbool=0; - - if ( tkn_data == "T" || - tkn_data == "TRUE" || - tkn_data == "1" ) - bbool = 1; - - bro_event_add_val(ev, BRO_TYPE_BOOL, NULL, &bbool); - } - else if ( tkn_type == "time" ) - { - double btime; - char* end_s; - btime = strtod(tkn_data.c_str(),&end_s); - bro_event_add_val(ev, BRO_TYPE_TIME, NULL, &btime); - } - else if ( tkn_type == "interval" ) - { - double binterval; - char* end_s; - binterval = strtod(tkn_data.c_str(),&end_s); - bro_event_add_val(ev, BRO_TYPE_INTERVAL, NULL, &binterval); - } - else if ( tkn_type == "port" ) - { - BroPort BP; - string port_value; - string::size_type port_offset; - int broport; - - //determine protocol type, start with tcp/udp do icmp - // later since the 'ports' are not as simple... - if ( tkn_data.find("tcp",0) < tkn_data.length() ) - BP.port_proto = IPPROTO_TCP; - else BP.port_proto = IPPROTO_UDP; - - // parse out the numeric values - port_offset = tkn_data.find_first_of("/",0); - port_value = tkn_data.substr(0,port_offset); - - broport = atoi(port_value.c_str()); - BP.port_num = broport; - - bro_event_add_val(ev, BRO_TYPE_PORT, NULL, &BP); - - } - else if ( tkn_type == "addr" ) - { - uint32 badd; - // badd=htonl((uint32)inet_addr(tkn_data.c_str())); - badd=(uint32)inet_addr(tkn_data.c_str()); - - bro_event_add_val(ev, BRO_TYPE_IPADDR, NULL, &badd); - } - else if ( tkn_type == "net" ) - { - uint32 bnet; - // bnet=htonl((uint32)inet_addr(tkn_data.c_str())); - bnet=(uint32)inet_addr(tkn_data.c_str()); - - bro_event_add_val(ev, BRO_TYPE_NET, NULL, &bnet); - } - else if ( tkn_type == "subnet" ) - { - // this is assuming a string that looks like - // "subnet=10.0.0.0/8" - BroSubnet BS; - string subnet_value; - string subnet_width; - string::size_type mask_offset; - uint32 sn_net, sn_width; - - //parse out numeric values - mask_offset = tkn_data.find_first_of("/",0); - subnet_value = tkn_data.substr(0,mask_offset); - subnet_width = tkn_data.substr(mask_offset+1,tkn_data.length()); - - sn_net = (uint32)inet_addr(subnet_value.c_str()); - sn_width = (uint32)atol(subnet_width.c_str()); - - BS.sn_net = sn_net; - BS.sn_width = sn_width; - - bro_event_add_val(ev, BRO_TYPE_SUBNET, NULL, &BS); - } - else - { - // there is something wrong here - cerr << "unknown data type: " << tkn_type << "\n\n"; - bro_event_free(ev); - showtypes(); - } - - } - - /* Ship it -- sends it if possible, queues it otherwise */ - cout << "Sending event to Bro \n"; - if ( ! bro_event_send(bc, ev) ) - cerr << "event could not be sent right away\n"; - - bro_event_free(ev); - } - } - - - /* Disconnect from Bro */ - bro_conn_delete(bc); - - return 0; - } diff --git a/aux/broccoli/contrib/bropipe.cc b/aux/broccoli/contrib/bropipe.cc deleted file mode 100644 index e1b059f372..0000000000 --- a/aux/broccoli/contrib/bropipe.cc +++ /dev/null @@ -1,657 +0,0 @@ -// $Id: bropipe.cc 6940 2009-11-14 00:38:53Z robin $ -// bropipe.cc: pipe version of generic client -// 02/04/05 -// -// to compile: g++ `broccoli-config --cflags` `broccoli-config --libs` -o bropipe bropipe.cc -// - - -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include "broccoli.h" - -using std::string; -using std::vector; -using std::cout; -using std::cin; -using std::cerr; - -string default_host = "127.0.0.1"; -string default_port = "47757"; -string default_input_file = "brocsock"; -string default_log_file = "/tmp/bropipe.log"; - -string conn_str; -string host; -string port; -string input_file; -string log_file; -int debug; -BroConn *bc; - -// The following are declarations needed for the modp_burl string decoding -// functions. They were cribbed from the stringencoders-v3.7.0 source tree. -// syc 1/20/09 - -/** - * \file - *
- * BFASTURL.c High performance URL encoder/decoder
- * http://code.google.com/p/stringencoders/
- *
- * Copyright © 2006,2007  Nick Galbreath -- nickg [at] modp [dot] com
- * 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 name of the modp.com 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 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
- * OWNER 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 is the standard "new" BSD license:
- * http://www.opensource.org/licenses/bsd-license.php
- * 
- */ - -static const uint32_t gsHexDecodeMap[256] = { -256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, -256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, -256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, -256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 256, 256, -256, 256, 256, 256, 256, 10, 11, 12, 13, 14, 15, 256, -256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, -256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, -256, 10, 11, 12, 13, 14, 15, 256, 256, 256, 256, 256, -256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, -256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, - 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, -256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, -256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, -256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, -256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, -256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, -256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, -256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, -256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, -256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, 256, -256, 256, 256, 256 -}; - - -int modp_burl_decode(char* dest, const char* s, int len) -{ - uint32_t d = 0; // used for decoding %XX - const uint8_t* src = (const uint8_t*) s; - const char* deststart = dest; - const uint8_t* srcend = (const uint8_t*)(src + len); - const uint8_t* srcendloop = (const uint8_t*)(srcend - 2); - - while (src < srcendloop) { - switch (*src) { - case '+': - *dest++ = ' '; - src++; - break; - case '%': - d = (gsHexDecodeMap[(uint32_t)(*(src + 1))] << 4) | - gsHexDecodeMap[(uint32_t)(*(src + 2))]; - if (d < 256) { // if one of the hex chars is bad, d >= 256 - *dest = (char) d; - dest++; - src += 3; - } else { - *dest++ = '%'; - src++; - } - break; - default: - *dest++ = *src++; - } - } - - // handle last two chars - // dont decode "%XX" - while (src < srcend) { - switch (*src) { - case '+': - *dest++ = ' '; - src++; - break; - default: - *dest++ = *src++; - } - } - - *dest = '\0'; - return dest - deststart; // compute "strlen" of dest. -} - -void usage(void) - { - cout << "bropipe - sends events with string arguments from file to a\n" - " running Bro\n" - "USAGE: bropipe [-p port=47757] [-f input] [host=127.0.0.1[:port]] [-d]\n" - "Input format (each line): event_name type=arg1 type=arg2...\n"; - exit(0); - } - -void showtypes(void) - { - cout << "Legitimate event types are:\n" - " string, urlstring, int, count, double, bool, time, \n" - " interval, port, addr, net, subnet\n\n" - " examples: string=foo, port=23/tcp, addr=10.10.10.10, \n" - " net=10.10.10.0, subnet=10.0.0.0/8\n" - " urlstring is a url encoded string type - use this when\n" - " whitespace can be found in the strings\n"; - exit(0); - } - -void tokenize(const string& str, vector& tokens) - { - int num_tokens = 0; - char delim = '\0'; - - for ( unsigned int i = 0; i < str.length(); ++i ) { - while ( isspace(str[i]) ) - ++i; - - string next_arg; - - if (str[i] == '"' || str[i] == '\'') - { - delim = str[i]; - ++i; - } - else - delim = '\0'; - - for ( ; str[i]; ++i ) - { - if ( delim && str[i] == '\\' && - i < str.length() && str[i+1] == delim ) - { - ++i; - next_arg.push_back(str[i]); - } - - else if ( delim && str[i] == delim ) - { - ++i; - break; - } - - else if ( ! delim && isspace(str[i]) ) - break; - else - next_arg.push_back(str[i]); - } - - tokens.push_back(next_arg); - } - } - -void ntokenize(const string& str, vector& inText) - { - int num_tokens = 0; - char delim = '\n'; - - for ( unsigned int i = 0; i < str.length(); ++i ) - { - while ( isspace(str[i]) ) - ++i; - - string next_arg; - - if (str[i] == '"' || str[i] == '\'') - { - delim = str[i]; - ++i; - } - else - delim = '\n'; - - for ( ; str[i]; ++i ) - { - if ( delim && str[i] == '\\' && - i < str.length() && str[i+1] == delim ) - { - next_arg.push_back(str[i]); - ++i; - } - - else if ( delim && str[i] == delim ) - { - break; - } - - else if ( ! delim && isspace(str[i]) ) - break; - else - next_arg.push_back(str[i]); - } - - inText.push_back(next_arg); - } - } - - -FILE * open_input_stream() - { - FILE *fp; - - if (input_file == "-") - { - fp = stdin; - if (debug) - fprintf(stderr, "DEBUG: input is STDIN.\n"); - } - else - { - if (debug) - fprintf(stderr, "DEBUG: try opening `%s' as input\n", input_file.c_str()); - fp = fopen(input_file.c_str(),"r"); - if (fp == NULL) - { - if (debug) - fprintf(stderr, "DEBUG: can't open, so creating pipe %s\n", input_file.c_str()); - - mkfifo(input_file.c_str(), S_IRUSR | S_IRGRP | S_IROTH ); - fp = fopen(input_file.c_str(),"r"); - - if (fp==NULL) - fprintf(stderr, "Failed to create pipe %s\n", input_file.c_str()); - else - if (debug) - fprintf(stderr, "DEBUG: created and opened pipe `%s'\n", input_file.c_str()); - - } - } - - return(fp); - } - - -int make_connection() - { - // now connect to the bro host - on failure, try again three times - // the flags here are telling us to block on connect, reconnect in the - // event of a connection failure, and queue up events in the event of a - // failure to the bro host - // - // the flags have been modified to allow for connect back and event queuing - - if ((bc = bro_conn_new_str(conn_str.c_str(), BRO_CFLAG_RECONNECT | BRO_CFLAG_ALWAYS_QUEUE))) - { - if (debug) - fprintf(stderr, "DEBUG: got BroConn handle\n"); - } - else - { - fprintf(stderr, "fatal: could not get BroConn handle.\n"); - exit(-1); - } - - if (debug) - fprintf(stderr, "DEBUG: attempt to connect to %s...", conn_str.c_str()); - - bro_conn_set_class(bc, "bropipe"); - - while (!bro_conn_connect (bc)) { - fprintf (stderr, "could not connect to Bro at %s:%s.\n", - host.c_str (), port.c_str ()); - fprintf (stderr, "Will try again in 5 seconds \n"); - sleep (5); - } - - if (debug) - fprintf(stderr, "DEBUG: connected\n"); - - return(0); - } - -int main(int argc, char **argv) - { - int fd,rc,n; - int j; - int ecount=0; - fd_set readfds; - char buf[1024]; - char *urlstr = NULL; - int urlstrsz = 0; - - struct timeval tv; - FILE *fp; - - int opt, use_record = 0; - extern char *optarg; - extern int optind; - - bro_init(NULL); - - host = default_host + ":" + default_port; - input_file = default_input_file; - - while ( (opt = getopt(argc, argv, "l:f:p:dDh?")) != -1) - { - switch (opt) - { - case 'l': - log_file = optarg; - break; - - case 'f': - input_file = optarg; - break; - - case 'd': - debug++; - break; - - case 'D': - debug++; - debug++; - break; - - case 'h': - case '?': - usage(); - break; - - case 'p': - port = optarg; - break; - - default: - usage(); - break; - } - } - - argc -= optind; - argv += optind; - - if (argc == 1) { - host = argv[0]; - if (host.find(':') == string::npos) - host += ":" + default_port; - } - - - if (argc > 1) - usage(); - - // config destination connection string - conn_str = host; - if (port != "") - { - conn_str += ":"; - conn_str += port; - } - - // open input - fp = open_input_stream(); - if (fp == NULL) { - fprintf(stderr, "fatal: failed to get input stream\n"); - return(1); - } - - if (!debug || debug < 2) - make_connection(); - else - if (debug) - fprintf(stderr, "DEBUG: not connecting to Bro (debug level >1)\n"); - - - - // socket and pipe are set up, now start processing - if(debug) - fprintf(stderr, "DEBUG: waiting for data on input stream...\n"); - - while(fgets(buf, sizeof(buf), fp)) - { - ecount++; - string inp; - vector inText; //text inputts within the pipe - vector tokens; - - if (debug) - fprintf(stderr, "DEBUG: read event #%d: %s", ecount, buf); - - if(debug >1) - continue; - - - inp = buf; - ntokenize(inp, inText); - - BroEvent *ev; - bro_conn_process_input(bc); - - for(j=0;j urlstrsz) { - if (urlstr) - free( urlstr); - urlstr = (char *)malloc( sz); - if (urlstr == NULL) { - fprintf( stderr,"Could not allocate %d bytes for url conversion buffer\n",sz); - return(1); - } - urlstrsz = sz; - } - modp_burl_decode(urlstr,tkn_data.c_str(),strlen(tkn_data.c_str())); - bro_string_set(&arg,urlstr); - bro_event_add_val(ev, BRO_TYPE_STRING, NULL, &arg); - bro_string_cleanup(&arg); - } - - else if ( tkn_type == "int" ) - { - int bint; - bint = atoi(tkn_data.c_str()); - bro_event_add_val(ev, BRO_TYPE_INT, NULL, &bint); - } - else if ( tkn_type == "count" ) - { - uint32 buint; - buint = atoi(tkn_data.c_str()); - bro_event_add_val(ev, BRO_TYPE_COUNT, NULL, &buint); - } - else if ( tkn_type == "double" ) - { - double bdouble; - char* end_s; - bdouble = strtod(tkn_data.c_str(),&end_s); - bro_event_add_val(ev, BRO_TYPE_DOUBLE, NULL, &bdouble); - } - else if ( tkn_type == "bool" ) - { - int bbool=0; - - if ( tkn_data == "T" || - tkn_data == "TRUE" || - tkn_data == "1" ) - bbool = 1; - - bro_event_add_val(ev, BRO_TYPE_BOOL, NULL, &bbool); - } - else if ( tkn_type == "time" ) - { - double btime; - char* end_s; - btime = strtod(tkn_data.c_str(),&end_s); - bro_event_add_val(ev, BRO_TYPE_TIME, NULL, &btime); - } - else if ( tkn_type == "interval" ) - { - double binterval; - char* end_s; - binterval = strtod(tkn_data.c_str(),&end_s); - bro_event_add_val(ev, BRO_TYPE_INTERVAL, NULL, &binterval); - } - else if ( tkn_type == "port" ) - { - BroPort BP; - string port_value; - string::size_type port_offset; - int broport; - - //determine protocol type, start with tcp/udp do icmp - // later since the 'ports' are not as simple... - if ( tkn_data.find("tcp",0) -#include -#include - -void usage() { - fprintf(stderr, "usage: brosendpkts -r file -b host:port [-t tag]\n"); - exit(1); -} - - -int main(int argc, char** argv) { - char* filename=NULL; - char* bro_connection=NULL; - char* tag=""; - - bro_init(NULL); - - int opt; - while ((opt=getopt(argc, argv, "r:b:t:h?")) != -1) { - switch(opt) { - case 'r': - filename=strdup(optarg); - break; - case 'b': - bro_connection=strdup(optarg); - break; - case 't': - tag=strdup(optarg); - break; - case 'h': - case '?': - default: - usage(); - } - } - argc -= optind; - argv += optind; - - - if (filename==NULL || bro_connection==NULL) usage(); - - BroConn *broccoli_p=bro_conn_new_str(bro_connection, BRO_CFLAG_NONE); - if (!broccoli_p) - { - fprintf(stderr, "can't instantiate connection object\n"); - exit(1); - } - - if (! bro_conn_connect(broccoli_p)) { - fprintf(stderr, "Bro connection to %s failed\n", - bro_connection); - exit(1); - } - printf("connected to Bro %s\n", bro_connection); - - char pcap_errbuf[PCAP_ERRBUF_SIZE]=""; - pcap_t* pcap_p=pcap_open_offline(filename, pcap_errbuf); - - if (!pcap_p) { - fprintf(stderr, "pcap eror: %s\n", pcap_errbuf); - exit(1); - } - - bro_conn_set_packet_ctxt(broccoli_p, pcap_datalink(pcap_p)); - - const uchar* packet_p=NULL; - struct pcap_pkthdr pkthdr; - - int pkt_cnt=0; - while ((packet_p=pcap_next(pcap_p, &pkthdr))) { - pkt_cnt++; - BroPacket* broccoli_packet_p=bro_packet_new(&pkthdr, packet_p, tag); - bro_packet_send(broccoli_p, broccoli_packet_p); - bro_packet_free(broccoli_packet_p); - } - - printf("sent %d packets\n",pkt_cnt); - - bro_conn_delete(broccoli_p); - printf("connection to Bro %s closed\n", bro_connection); - - return 0; -} diff --git a/aux/broccoli/contrib/rcvpackets.bro b/aux/broccoli/contrib/rcvpackets.bro deleted file mode 100644 index 339bf815b8..0000000000 --- a/aux/broccoli/contrib/rcvpackets.bro +++ /dev/null @@ -1,11 +0,0 @@ - -@load listen-clear - -redef Remote::destinations += { - ["broccoli"] = [$host=127.0.0.1, $accept_state=T, $sync=F] -}; - - - - - diff --git a/aux/broccoli/docs/Makefile.am b/aux/broccoli/docs/Makefile.am deleted file mode 100644 index 9828f010e0..0000000000 --- a/aux/broccoli/docs/Makefile.am +++ /dev/null @@ -1,205 +0,0 @@ -## Process this file with automake to produce Makefile.in - -# This is a blank Makefile.am for using gtk-doc. -# Copy this to your project's API docs directory and modify the variables to -# suit your project. See the GTK+ Makefiles in gtk+/docs/reference for examples -# of using the various options. - -# The name of the module, e.g. 'glib'. -DOC_MODULE=broccoli - -# The top-level SGML file. Change it if you want. -DOC_MAIN_SGML_FILE=$(DOC_MODULE)-manual.sgml - -# The directory containing the source code. Relative to $(srcdir). -# CAUTION: this will usually be the current directory. -# gtk-doc will search all .c & .h files beneath here for inline comments -# documenting functions and macros. -DOC_SOURCE_DIR=$(top_srcdir)/src - -# Extra options to pass to gtkdoc-scanobj or gtkdoc-scangobj. -SCANOBJ_OPTIONS= - -# Extra options to supply to gtkdoc-scan. -SCAN_OPTIONS= - -# Extra options to supply to gtkdoc-mkdb. -MKDB_OPTIONS=--ignore-files=bro_lexer.c - -# Extra options to supply to gtkdoc-fixref. -FIXXREF_OPTIONS= - -# Used for dependencies. -HFILE_GLOB= -CFILE_GLOB= - -# Header files to ignore when scanning. -IGNORE_HFILES= - -# Images to copy into HTML directory. -HTML_IMAGES = \ - images/caution.gif \ - images/note.gif \ - images/warning.gif \ - images/logo.jpg - -# Other HTML stuff that needs installing -HTML_MISC = \ - stylesheet.css - -# Extra SGML files that are included by $(DOC_MAIN_SGML_FILE). -content_files = - -# Other files to distribute. -extra_files = broccoli.types - -# CFLAGS and LDFLAGS for compiling scan program. Only needed if your app/lib -# contains GtkObjects/GObjects and you want to document signals and properties. -GTKDOC_CFLAGS = -GTKDOC_LIBS = - -GTKDOC_CC=$(LIBTOOL) --mode=compile $(CC) -GTKDOC_LD=$(LIBTOOL) --mode=link $(CC) - -# If you need to override some of the declarations, place them in the -# $(DOC_MODULE)-overrides.txt file and uncomment the second line here. -DOC_OVERRIDES = -#DOC_OVERRIDES = $(DOC_MODULE)-overrides.txt - -# You can pass in a different stylesheet (or none, for the default look). -STYLESHEET=stylesheet.dsl - -########################################################################### -# Everything below here is generic and you shouldn't need to change it. -########################################################################### - -TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE) - -EXTRA_DIST = \ - $(content_files) \ - $(extra_files) \ - $(HTML_IMAGES) \ - $(HTML_MISC) \ - $(DOC_MAIN_SGML_FILE) \ - $(DOC_MODULE).types \ - $(DOC_MODULE)-sections.txt \ - $(DOC_OVERRIDES) \ - broccoli.types \ - mkhtml \ - stylesheet.dsl - -DOC_STAMPS=scan-build.stamp tmpl-build.stamp sgml-build.stamp html-build.stamp \ - $(srcdir)/tmpl.stamp $(srcdir)/sgml.stamp $(srcdir)/html.stamp - -SCANOBJ_FILES = \ - $(DOC_MODULE).args \ - $(DOC_MODULE).hierarchy \ - $(DOC_MODULE).interfaces \ - $(DOC_MODULE).prerequisites \ - $(DOC_MODULE).signals - -if ENABLE_GTK_DOC -all-local: html-build.stamp - -#### scan #### - -scan-build.stamp: $(HFILE_GLOB) - @echo '*** Scanning header files ***' - if grep -l '^..*$$' $(srcdir)/$(DOC_MODULE).types > /dev/null ; then \ - CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" CFLAGS="$(GTKDOC_CFLAGS)" LDFLAGS="$(GTKDOC_LIBS)" gtkdoc-scanobj $(SCANOBJ_OPTIONS) --module=$(DOC_MODULE) --output-dir=$(srcdir) ; \ - else \ - cd $(srcdir) ; \ - for i in $(SCANOBJ_FILES) ; do \ - test -f $(srcdir)/$$i || touch $(srcdir)/$$i ; \ - done \ - fi - cd $(srcdir) && \ - gtkdoc-scan --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --ignore-headers="$(IGNORE_HFILES)" $(SCAN_OPTIONS) $(EXTRA_HFILES) - touch scan-build.stamp - -$(DOC_MODULE)-decl.txt $(SCANOBJ_FILES): scan-build.stamp - @true - -#### templates #### - -tmpl-build.stamp: $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_OVERRIDES) - @echo '*** Rebuilding template files ***' - cd $(srcdir) && gtkdoc-mktmpl --module=$(DOC_MODULE) - touch tmpl-build.stamp - -tmpl.stamp: tmpl-build.stamp - @true - -#### sgml #### - -sgml-build.stamp: tmpl.stamp $(CFILE_GLOB) - @echo '*** Building SGML ***' - cd $(srcdir) && \ - gtkdoc-mkdb --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --main-sgml-file=$(DOC_MAIN_SGML_FILE) $(MKDB_OPTIONS) - touch sgml-build.stamp - -sgml.stamp: sgml-build.stamp - @true - -#### html #### - -html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files) - @echo '*** Building HTML ***' - test -d $(srcdir)/html || mkdir $(srcdir)/html - mkhtmldir=`cd $(srcdir) && pwd` && \ - cd $(srcdir)/html && $$mkhtmldir/mkhtml $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE) $$mkhtmldir/$(STYLESHEET) - test "x$(HTML_MISC)" = "x" || ( cd $(srcdir) && cp $(HTML_MISC) html ) - @echo '-- Fixing Crossreferences' - cd $(srcdir) && gtkdoc-fixxref --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS) - touch html-build.stamp -else -all-local: -endif - -############## - -clean-local: - rm -f *~ *.bak $(SCANOBJ_FILES) *-unused.txt $(DOC_STAMPS) - -maintainer-clean-local: clean - cd $(srcdir) && rm -rf sgml html $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt - -# Manual rule here, global install was removed as part of Bro's "make -# install" cleanup for the 1.4 release. --cpk -# -install-docs: - $(mkinstalldirs) $(DESTDIR)$(TARGET_DIR)/images - (installfiles=`echo $(srcdir)/html/*.html`; \ - if test "$$installfiles" = '$(srcdir)/html/*.html'; \ - then echo '-- Nothing to install'; \ - else \ - for i in $$installfiles; do \ - echo '-- Installing '$$i; \ - $(INSTALL_DATA) $$i $(DESTDIR)$(TARGET_DIR); \ - done; \ - echo '-- Installing $(srcdir)/images/'; \ - for i in $(HTML_IMAGES); do \ - $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(TARGET_DIR)/images; \ - done; \ - echo '-- Installing additional files'; \ - for i in $(HTML_MISC); do \ - $(INSTALL_DATA) $(srcdir)/$$i $(DESTDIR)$(TARGET_DIR); \ - done; \ - fi) - -uninstall-local: - rm -rf $(DESTDIR)$(TARGET_DIR) - -dist-hook: - mkdir -p $(distdir)/tmpl - mkdir -p $(distdir)/sgml - mkdir -p $(distdir)/html/images - -cp $(srcdir)/tmpl/*.sgml $(distdir)/tmpl - -cp $(srcdir)/sgml/*.sgml $(distdir)/sgml - -cp $(srcdir)/html/*.html $(distdir)/html - for i in $(HTML_MISC); do \ - cp $(srcdir)/$$i $(distdir)/html; \ - done - for i in $(HTML_IMAGES); do \ - cp $(srcdir)/$$i $(distdir)/html/images ; \ - done diff --git a/aux/broccoli/docs/broccoli-manual.sgml b/aux/broccoli/docs/broccoli-manual.sgml deleted file mode 100644 index e4c20ff491..0000000000 --- a/aux/broccoli/docs/broccoli-manual.sgml +++ /dev/null @@ -1,1822 +0,0 @@ -broccoli
"> -broccoli-config"> - - -broping"> -]> - - Broccoli: The Bro Client Communications Library - - - - - - - Broccoli Logo - - - - - This is documentation for release &bc-latest-rel; - of Broccoli, compatible with Bro IDS releases of 1.4 - or newer. Broccoli is free software under terms of the BSD license as given - in the License - section. This documentation is always available on the web for download - and online browsing at - http://www.icir.org/christian/broccoli. - - Feedback, patches and bug reports are all welcome, please - join the Bro mailing list. - - - Yet Another SRG/ICIR Production — - http://www.cl.cam.ac.uk/Research/SRG — - http://www.icir.org - - - - - - Introduction - - Welcome! You're looking at the Broccoli manual. Thanks for reading this. - - - What is Broccoli? - - Broccoli is the BRO Client - COmmunications LIbrary. It allows - you to write applications that speak the communication protocol of the - Bro intrusion detection system. - In this document, we assume that you are familiar with the basic concepts - of Bro. If you need a refresher, please have a look at the - original paper, - the user manual, - and the material on bro-ids.org in general. - - - - Why do I care? - - Having a single IDS on your network is good, but things become a lot more interesting - when you can communicate information among multiple vantage points in your network. - Bro agents can communicate with other Bro agents, sending and receiving events and - other state information. In the Bro context this is particularly interesting because - it means that you can build sophisticated policy-controlled distributed event - management systems. - - - Broccoli enters the picture when it comes to integrating components that are not - Bro agents themselves. Broccoli lets you create applications that can speak the Bro - communication protocol. You can compose, send, request, and receive events. - You can register your own event handlers. You can talk to other Broccoli - applications or Bro agents — Bro agents cannot tell whether they are talking - to another Bro or a Broccoli application. Broccoli allows you to integrate applications - of your choosing into a distributed policy-controlled event management system. - Broccoli is intended - to be portable: it should build on Linux, the BSDs, Solaris, and Windows - (in the MinGW environment). - - - Unlike other distributed IDSs, Bro does not assume a strict sensor–manager - hierarchy in the information flow. Instead, Bro agents can request delivery of - arbitrary events - from other instances. When an event is triggered in a Bro agent, it checks - whether any connected agents have requested notification of this event, - and send a copy of the event, including the event arguments. - Recall that in Bro, an event handler is essentially a function defined in - the Bro language, and an event materializes through invocation of an event handler. - Each remote agent can define its own event handlers. - - - Broccoli applications will typically do one or more of the following: - - - - - Configuration/Management Tasks: the Broccoli application - is used to configure remotely running Bros without the need for a restart. - - - - - Interfacing other Systems: the Broccoli application - is used to convert Bro events to other alert/notice formats, for into - syslogd entries. - - - - - Host-based Sensor Feeds into Bro: the Broccoli - application reports events based on host-based activity generated in - kernel space or user space applications. - - - - - - - - Installing Broccoli - - The installation process will hopefully be painless: Broccoli is installed from source - using the usual ./configure <options> && make && make install - routine after extraction of the tarball. Or if you're on a Linux systems supporting - RPMs, we provide those as well. - - - The relevant configuration options to pass to configure are: - - - --prefix=<DIR>: sets the installation root to DIR. - The default is to install below /usr/local. - - - --enable-debug: enables debugging output. - Please refer to the Broccoli debugging - section for details on configuring and using debugging output. - - - - --with-configfile=<FILE>: use FILE as location of configuration file. - See the section on configuration files - below for more on this. - - - - --with-openssl=<DIR>: use the OpenSSL installation below DIR. - - - --with-kerberos=<DIR>: use the Kerberos installation below DIR. - - - - - After installation, you'll find the library in shared and static versions in <prefix>/lib - the header file for compilation in <prefix>/include, and the - manual in HTML below <prefix>/share/gtk-doc/html/broccoli. - - - When installing from source, you can get rid of the installation using make uninstall. - - - - - Using Broccoli - - - - - Obtaining information about your build using <filename>broccoli-config</filename> - - Similarly to many other software packages, the Broccoli distribution - provides a script that you can use to obtain details about your - Broccoli setup. The script currently provides the following flags: - - - --build prints the name of the machine the build was - made on, when, and whether debugging support was enabled or not. - - - --prefix prints the directory in the filesystem - below which Broccoli was installed. - - - --version prints the version of the distribution - you have installed. - - - --libs prints the flags to pass to the - linker in order to link in the Broccoli library. - - - --cflags prints the flags to pass to the - compiler in order to properly include Broccoli's header file. - - - --config prints the location of the system-wide - config file your installation will use. - - - - - The --cflags and --libs flags - are the suggested way of obtaining the necessary information for integrating - Broccoli into your build environment. It is generally recommended to use - broccoli-config for this purpose, rather than, say, - develop new autoconf tests. - If you use the autoconf/automake - tools, we recommend something along the following lines for your - configure script: - - - - - - You can then use the compiler/linker flags in your Makefile.in/ams by - substituting in the values accordingly, which might look as follows: - - - - - - - - Suggestions for instrumenting applications - - Often you will want to make existing applications Bro-aware, - that is, instrument them so that they can send and - receive Bro events at appropriate moments in the execution flow. - This will involve modifying an existing code tree, so care needs to - be taken to avoid unwanted side effects. By protecting the instrumented - code with - #ifdef/#endif - statements you can still build the original application, using the - instrumented source tree. The &bcc; script helps you in doing so because - it already adds -DBROCCOLI to the compiler flags - reported when run with the --cflags option: - - - broccoli-config --cflags --I/usr/local/include -I/usr/local/include -DBROCCOLI -]]> - - - So simply surround all inserted code with a preprocessor check - for BROCCOLI and you will be able to - build the original application as soon as BROCCOLI - is not defined. - - - - The Broccoli API - - Time for some code. In the code snippets below we will introduce variables - whenever context requires them and not necessarily when C requires them. - The library does not require calling a global initialization function. - In order to make the API known, include broccoli.h: - - - -#endif -]]> - - - A note on Broccoli's memory management philosophy: - Broccoli generally does not release objects you allocate. - The approach taken is "you clean up what you allocate." - - - - - Initialization - - Broccoli requires global initialization before most of its - other other functions can be used. Generally, the way to - initialize Broccoli is as follows: - - - - - - The argument to - bro_init() - provides optional initialization context, and may be kept - NULL for normal use. If required, you may - allocate a BroCtx structure locally, - initialize it using - bro_ctx_init(), - fill in additional values as required and and subsequently pass it to - bro_init(): - - - - - - - The BroCtx structure currently contains - a set of five different callback function pointers. These - are required for thread-safe operation - of OpenSSL (Broccoli itself is thread-safe). If you intend - to use Broccoli in a multithreaded environment, you need to - implement functions and register them via the - BroCtx structure. The O'Reilly book - "Network Security with OpenSSL" by Viega et al. shows how to - implement these callbacks. - - - - You must call - bro_init() - at the start of your application. Undefined behavior may result - if you don't. - - - - - - Data types in Broccoli - - Broccoli declares a number of data types in broccoli.h that - you should know about. The more complex ones are kept opaque, while you do get - access to the fields in the simpler ones. The full list is as follows: - - - - Simple signed and unsigned types: int, uint, - uint32, uint16 and uchar. - - - Connection handles: BroConn, kept opaque. - - - Bro events: BroEvent, kept opaque. - - - Buffer objects: BroBuf, kept opaque. See the separate - section on buffer management for details. - - - Ports: BroPort for network ports, defined as follows: - - - - - - - Records: BroRecord, kept opaque. See the separate - section on record handling for details. - - - Strings (character and binary): BroString, defined as follows: - - - - - - BroStrings are mostly kept transparent for convenience; please have a look at the - string API: -bro_string_init(), -bro_string_set(), -bro_string_set_data(), -bro_string_copy(), -bro_string_cleanup(), and -bro_string_free(). - - - - Tables: BroTable, kept opaque. See the separate - section on table handling for details. - - - Sets: BroSet, kept opaque. See the separate - section on table handling for details. - - - Subnets: BroSubnet, defined as follows: - - - - - - - - - - - Managing connections - - You can use Broccoli to establish a connection to a remote Bro, or to create a - Broccoli-enabled server application that other Bros will connect to. (This - means that in principle, you can also use Broccoli purely as middleware and - have multiple Broccoli applications communicate directly.) - - - In order to establish a connection to a remote Bro, you first obtain a connection - handle. You then use this connection handle to request events, connect to the - remote Bro, send events, etc. Connection handles are pointers to BroConn - structures, which are kept opaque. Use - bro_conn_new() or - bro_conn_new_str() - to obtain a handle, depending on what parameters are more convenient for - you: the former accepts the IP address and port number as separate numerical - arguments, the latter uses a single string to encode both, in "hostname:port" - format. - - - To write a Broccoli-enabled server, you first need to implement the usual - socket() / bind() / - listen() / accept() routine. - Once you have obtained a file descriptor for the new connection from accept(), - you pass it to the third function that returns a BroConn - handle, - bro_conn_new_socket(). - The rest of the connection handling then proceeds as in the client scenario. - - - All three calls accept additional flags for fine-tuning connection behaviour. - These flags are: - - - BRO_CFLAG_NONE: no functionality. Use when - no flags are desired. - - - - BRO_CFLAG_RECONNECT: - When using this option, Broccoli will attempt to reconnect to the peer - after lost connectivity transparently. Essentially whenever you try to - read from or write to the peer and its connection broke down, a - full reconnect including complete handshaking is attempted. You can check - whether the connection to a peer is alive at any time using - bro_conn_alive(). - - - - BRO_CFLAG_ALWAYS_QUEUE: - When using this option, Broccoli will queue any events you send for - later transmission when a connection is currently down. Without using this - flag, any events you attempt to send while a connection is down get dropped - on the floor. Note that Broccoli maintains a maximum queue size per connection - so if you attempt to send lots of events while the connection is down, the - oldest events may start to get dropped nonetheless. Again, you can check - whether the connection is currently okay by using - bro_conn_alive(). - - - - BRO_CFLAG_DONTCACHE: - When using this option, Broccoli will ask the peer not to use caching on - the objects it sends to us. This is the default, and the flag need not - normally be used. It is kept to maintain backward compatibility. - - - - BRO_CFLAG_CACHE: - When using this option, Broccoli will ask the peer to use caching on - the objects it sends to us. Caching is normally disabled. - - - - BRO_CFLAG_YIELD: When - using this option, - bro_conn_process_input() - processes at most one event at a time and then - returns. - - - - - - - By obtaining a connection handle, you do not also establish a connection right - away. This is done using - bro_conn_connect(). - The main reason for this is to allow you to subscribe to events - (using - bro_event_registry_add(), - see below) - before establishing the connection. Upon returning from - bro_conn_connect() - you are guaranteed to receive all instances of the event types you have - requested, while later on during the connection some time may elapse between - the issuing of a request for events and the processing of that request at the - remote end. - Connections are established via TCP, optionally using SSL encryption. See - "Configuring encrypted communication" below for more - information on setting up enncryption. - The port numbers Bro agents and Broccoli applications listen on can vary from peer - to peer. - - - Finally, bro_conn_delete() - terminates a connection and releases all resources associated with it. - You can create as many connections as you like, to one or more peers. - You can obtain the file descriptor of a connection using - bro_conn_get_fd(). - - -h_addr_list[0])) { - /* Error handling -- could not resolve host */ -} - -/* In this example, we obtain a connection handle, then register event handlers, - * and finally connect to the remote Bro. - * - * First obtain a connection handle: - */ -if (! (bc = bro_conn_new((struct in_addr*) host->h_addr_list[0], htons(port), BRO_CFLAG_NONE))) { - /* Error handling - could not get connection handle */ -} - -/* Register event handlers: - */ -bro_event_registry_add(bc, "foo", bro_foo_handler, NULL); -/* ... */ - -/* Now connect to the peer: - */ -if (! bro_conn_connect(bc)) { - /* Error handling - could not connect to remote Bro. */ -} - -/* Send and receive events ... */ - -/* Disconnect from Bro and clean up connection */ -bro_conn_delete(bc); -]]> - - - Or simply use the string-based version: - - - - - - - - Connection classes - - When you want to establish connections from multiple Broccoli applications - with different purposes, the peer needs a means to understand what kind of - application each connection belongs to. The real meaning of "kind of application" - here is "sets of event types to request", because depending on the class of - an application, the peer will likey want to receive different types of events. - - - Broccoli lets you set the class of a connection using - bro_conn_set_class(). - When using this feature, you need to call that function before issuing a - bro_conn_connect(), - since the class of a connection is determined at connection startup. - - - - - - If your peer is a Bro node, you need to match the chosen connection class in - the remote Bro's Remote::destinations configuration. - See below for how to do this. - Finally, in order to obtain the class of a connection as indicated by the remote side, use - bro_conn_get_peer_class(). - - - - - Composing and sending events - - In order to send an event to the remote Bro agent, you first create - an empty event structure with the name of the event, then add parameters - to pass to the event handler at the remote agent, and then send off the - event. - - - - Bro peers ignore unrequested events. - - - You need to make sure that the remote Bro agent is interested in receiving - the events you send. This interest is expressed in policy configuration. - We'll explain this in more detail below - and for now assume that our remote peer is configured to receive the - events we send. - - - - Let's assume we want to request a report of all connections a remote - Bro currently keeps state for that match a given destination port and - host name and that have amassed more than a certain number of bytes. - The idea is to send an event to the remote Bro that contains the - query, identifiable through a request ID, and have the remote Bro - answer us with remote_conn events - containing the information we asked for. The definition of our - requesting event could look as follows in the Bro policy: - - - - - - First, create a new event: - - - - - - Now we need to add parameters to the event. The sequence and types must - match the event handler declaration — check the Bro policy to make - sure they match. The function to use for adding parameter values is - bro_event_add_val() - All values are passed as pointer arguments and are copied internally, - so the object you're pointing to stays unmodified at all times. You clean - up what you allocate. In order to indicate the type of the value passed into the - function, you need to pass a numerical type identifier along as well. - Table 1 lists the value types that Broccoli supports along with - the type identifier and data structures to point to. - - -Types, type tags, and data structures for event parameters in Broccoli - - - - Type - Type tag - Data type pointed to - - - - - Boolean - BRO_TYPE_BOOL - int - - Integer value - BRO_TYPE_INT - int - - Counter (nonnegative integers) - BRO_TYPE_COUNT - uint32 - - Enums (enumerated values) - BRO_TYPE_ENUM - int (see also the description of - bro_event_add_val()'s - type_name argument below) - - Floating-point number - BRO_TYPE_DOUBLE - double - - Timestamp - BRO_TYPE_TIME - double (see also - bro_util_timeval_to_double() and - bro_util_current_time()) - - Time interval - BRO_TYPE_INTERVAL - double - - Strings (text and binary) - BRO_TYPE_STRING - BroString (see also the family of bro_string_xxx() functions) - - Network ports - BRO_TYPE_PORT - BroPort, with the port number in host byte order - - IPv4 address - BRO_TYPE_IPADDR - uint32, in network byte order - - IPv4 network - BRO_TYPE_NET - uint32, in network byte order - - IPv4 subnet - BRO_TYPE_SUBNET - BroSubnet, with the sn_net member in network byte order - - Record - BRO_TYPE_RECORD - BroRecord (see also the family of - bro_record_xxx() functions and their - explanation below) - - - Table - BRO_TYPE_TABLE - BroTable (see also the family of - bro_table_xxx() functions and their - explanation below) - - - Record - BRO_TYPE_SET - BroSet (see also the family of - bro_set_xxx() functions and their - explanation below) - - - -
- - Knowing these, we can now compose a - request_connections event: - - - - - - The third argument to - bro_event_add_val() - lets you specify a specialization of the types listed in - Table 1. This is generally not necessary - except for one situationn: When using BRO_TYPE_ENUM. You currently - cannot define - a Bro-level enum type in Broccoli, and thus when sending an enum value, you - have to specify the type of the enum along with the value. For example, in order - to add an instance of enum transport_type defined in - Bro's bro.init, you would use - - - - to get the equivalent of "udp" on the remote side. The same system is used - to point out type names when calling - bro_event_set_val(), - bro_record_add_val(), - bro_record_set_nth_val(), and - bro_record_set_named_val(). - - - All that's left to do now is to send off the event. For this, use - bro_event_send() - and pass it the connection handle and the event. The function returns - TRUE when the event could be sent right away or if - it was queued for later delivery. FALSE is returned - on error. If the event get queued, this does not indicate an error — - likely the connection was just not - ready to send the event at this point. Whenever you call - bro_event_send(), - Broccoli attempts to send as much of an existing event queue as possible. - Again, the event is copied internally to make it easier for you to - send the same event repeatedly. You clean up what you allocate. - - - - - - Two other functions may be useful to you: - bro_event_queue_length() - tells you how many events are currently queued, and - bro_event_queue_flush() - attempts to flush the current event queue and returns the number of events that do remain - in the queue after the flush. Note: you do not normally need - to call this function, queue flushing is attempted every time you send an event. - -
- - - Receiving events - - Receiving events is a little more work because you need to - - - - tell Broccoli what to do when requested events arrive, - - - let the remote Bro agent know that you would like to receive those events, - - - find a spot in the code path suitable for extracting and processing arriving events. - - - - Each of these steps is explained in the following sections. - - - - Implementing event callbacks - - When Broccoli receives an event, it tries to dispatch the event to callbacks - registered for that event type. The place where callbacks get registered is - called the callback registry. Any callbacks registered for the arriving - event's name are invoked with the parameters shipped with the event. There - are two styles of argument passing to the event callbacks. - Which one is better suited depends on your application. - - - Expanded argument passing. Each event argument - is passed via a pointer to the callback. This makes best sense when you - know the type of the event and of its arguments, because it provides you - immediate access to arguments as when using a normal C function. - - - In order to register a callback with expanded argument passing, use - bro_event_registry_add() - and pass it the connection handle, the name of the event for which you - register the callback, the callback itself that matches the signature - of the BroEventFunc type, and any user data (or - NULL) you want to see passed to the callback on - each invocation. The callback's type is defined rather generically as follows: - - - - - - It requires a connection handle as its first argument - and a pointer to user-provided callback data as the second argument. - Broccoli will pass the connection handle of the connection on which the event - arrived through to the callback. BroEventFuncs - are variadic, because each callback you provide is directly invoked with - pointers to the parameters of the event, in a format directly usable in C. - All you need to know is what type to point to in order to receive the - parameters in the right layout. Refer to Table 1 - again for a summary of those types. Record types are more involved and are - addressed in more detail below. - - - Note that all parameters are passed to the - callback as pointers, even elementary types such as ints - that would normally be passed directly. - Also note that Broccoli manages the lifecycle of event parameters - and therefore you do not have to clean them up inside - the event handler. - - - - Continuing our example, we will want to process the connection reports - that contain the responses to our report_conns - event. Let's assume those look as follows: - - - - - - The reply events contain the request ID so we can associate requests - with replies, and a connection record (defined in bro.init - in Bro. (It'd be nicer to report all replies in a single event but we'll - ignore that for now.) For this event, our callback would look like this: - - - - - - Once more, you clean up what you allocate, and since you never allocated the - space these arguments point to, you also don't clean them up. Finally, we register - the callback using - bro_event_registry_add(): - - - - - - In this case we have no additional data to be passed into the - callback, so we use NULL for the last argument. - If you have multiple events you are interested in, register - each one in this fashion. - - - - Compact argument passing. This is designed for - situations when you have to determine how to handle different types of - events at runtime, for example when writing language bindings or when - implementing generic event handlers for multiple event types. - The callback is passed a connection handle and the - user data as above but is only passed one additional pointer, to a - BroEvMeta structure. This structure contains all metadata - about the event, including its name, timestamp (in UTC) of creation, - number of arguments, the arguments' - types (via type tags as listed in Table 1), - and the arguments themselves. - - - In order to register a callback with compact argument passing, use - bro_event_registry_add_compact() - and pass it similar arguments as you'd use with - bro_event_registry_add(). - The callback's type is defined as follows: - - - - - - As before, Broccoli manages the lifecycle of event parameters. - You do not have to clean up the BroEvMeta - structure or any of its contents. - - - - Below is sample code for extracting the arguments form the BroEvMeta - structure, using our running example. This is still written with the assumption - that we know the types of the arguments, but note that this is not a requirement - for this style of callback. - - -ev_name); - - /* Sanity-check the number of arguments: */ - - if (meta->ev_numargs != 2) - { /* error */ } - - /* Sanity-check the argument types: */ - - if (meta->ev_args[0].arg_type != BRO_TYPE_INT) - { /* error */ } - - if (meta->ev_args[1].arg_type != BRO_TYPE_RECORD) - { /* error */ } - - req_id = (int *) meta->ev_args[0].arg_data; - rec = (BroRecord *) meta->ev_args[1].arg_data; - - /* ... */ -} -]]> - - - Finally, register the callback using - bro_event_registry_add_compact(): - - - - - - - - - - - Requesting event delivery - - At this point, Broccoli knows what to do with the requested events upon - arrival. What's left to do is to let the remote Bro know that you - would like to receive the events for which you registered. If you haven't - yet called bro_conn_connect(), - then there is nothing to do, since that function will request the registered - events anyway. Once connected, you can still request events. To do so, call - bro_event_registry_request(): - - - - - - This mechanism also implies that no unrequested events will be delivered - to us (and if that happened for whatever reason, the event would simply - be dropped on the floor). - - - Note that at the moment you cannot unrequest events, nor - can you request events based on predicates on the values of the - events' arguments. - - - - - Reading events from the connection handle - - At this point the remote Bro will start sending you the requested events - once they are triggered. What is left to do is to read the arriving events - from the connection and trigger dispatching them to the registered callbacks. - - - If you are writing a new Bro-enabled application, this is easy, and you can - choose among two approaches: polling explicitly via Broccoli's API, or using - select() on the file handle associated with a BroConn. - The former case is particularly straightforward; all you need to do is - call - bro_conn_process_input(), - which will go off and check if any events have arrived and if so, dispatch - them accordingly. This function does not block — if no events have - arrived, then the call will return immediately. For more fine-grained control - over your I/O handling, you will probably want to use - bro_conn_get_fd() - to obtain the file descriptor of your connection and then incorporate that - in your standard FD_SET/select() - code. Once you have determined that data in fact are ready to be read from - the obtained file descriptor, you can then try another - bro_conn_process_input(), - this time knowing that it'll find something to dispatch. - - - As a side note, if you don't process arriving events frequently enough, - then TCP's flow control will start to slow down the sender until eventually - events will queue up and be dropped at the sending end. - - - - - - Handling records - - Broccoli supports record structures, i.e., types that pack a set of values - together, placing each value into its own field. In Broccoli, the way you handle - records is somewhat similar to events: - after creating an empty record (of opaque type BroRecord, you can - iteratively add fields and values to it. The main difference is that you must specify a - field name with the value; each value in a record can be identified both by position - (a numerical index starting from zero), and by field name. You can retrieve vals - in a record by field index or field name. You can also reassign values. - There is no explicit, IDL-style definition of record types. You define the type of - a record implicitly by the sequence of field names and the sequence of the types - of the values you put into the record. - - - Note that all fields in a record must be assigned before it can be shipped. - - - The API for record composition consists of - bro_record_new(), - bro_record_free(), - bro_record_add_val(), - bro_record_set_nth_val(), and - bro_record_set_named_val(). - - - On records that use field names, the names of individual fields can be extracted using - bro_record_get_nth_name(). - Extracting values from a record is done using - bro_record_get_nth_val() and - bro_record_get_named_val(). - The former allows numerical indexing of the fields in the record, the latter provides - name-based lookups. Both need to be passed the record you want to extract a value from, - the index or name of the field, and either a pointer to an int holding a - BRO_TYPE_xxx value (see again Table 1 for a - summary of those types) or NULL. The pointer, if not - NULL, serves two purposes: type checking and type retrieval. - Type checking is performed if the value of the int upon calling the - functions is not BRO_TYPE_UNKNOWN. The type tag of the requested record - field then has to match the type tag stored in the int, otherwise - NULL is returned. If the int stores BRO_TYPE_UNKNOWN - upon calling, no type-checking is performed. In both cases, - the actual type of the - requested record field is returned in the int pointed to upon - return from the function. Since you have no guarantees of the type of the value - upon return if you pass NULL as the int pointer, - this is a bad idea and either BRO_TYPE_UNKNOWN or another type value - should always be used. - - - For example, you could extract the value of the record field "label", which - we assume should be a string, in the following ways: - - - - - - Record fields can be records, for example in the case of Bro's standard - connection record type. In this case, in order to get to a nested record, you - use BRO_TYPE_RECORD: - - - - - - - - Handling tables - - Broccoli supports Bro-style tables, i.e., associative containers that map - instances of a key type to an instance of a value type. A given key - can only ever point to a single value. The key type can be - composite, i.e., it may consist of an ordered - sequence ofdifferent types, or it can be direct, - i.e., consisting of a single type (such as an integer, a string, or - a record). - - - The API for table manipulation consists of - bro_table_new(), - bro_table_free(), - bro_table_insert(), - bro_table_find(), - bro_table_get_size(), - bro_table_get_types(), - and - bro_table_foreach(). - - - Tables are handled similarly to records in that typing is determined - dynamically by the initial key/value pair inserted. The resulting types - can be obtained via - bro_table_get_types(). - Should the types not have been determined yet, BRO_TYPE_UNKNOWN - will result. Also, as with records, - values inserted into the table are copied internally, and the ones passed - to the insertion functions remain unaffected. - - - In contrast to records, table entries can be iterated. By passing a function - of signature - BroTableCallback() - and a pointer to data of your choosing, - bro_table_foreach() - will invoke the given function for each key/value pair stored in the table. - Return TRUE to keep the iteration going, or FALSE - to stop it. - - - The main thing to know about Broccoli's tables is how to use composite key - types. To avoid additional API calls, you may treat composite key types - exactly as records, though you do not need to use field names when assigning - elements to individual fields. So in order to insert a key/value pair, you - create a record with the needed items assigned to its slots, and use this - record as the key object. In order to differentiate composite index types - from direct ones consisting of a single record, use BRO_TYPE_LIST - as the type of the record, as opposed to BRO_TYPE_RECORD. - Broccoli will then know to interpret the record - as an ordered sequence of items making up a composite element, not a regular - record. - - - brotable.c in the test subdirectory of the Broccoli tree - contains an extensive example of using tables with composite as well as direct - indexing types. - - - - - Handling sets - - Sets are essentially tables with void value types. - The API for set manipulation consists of - bro_set_new(), - bro_set_free(), - bro_set_insert(), - bro_set_find(), - bro_set_get_size(), - bro_set_get_type(), - and - bro_set_foreach(). - - - - - Associating data with connections - - You will often find that you would like to connect data with - a BroConn. Broccoli provides an API that - lets you associate data items with a connection handle through - a string-based key–value registry. The functions of interest - are - bro_conn_data_set(), - bro_conn_data_get(), and - bro_conn_data_del(). - You need to provide a string identifier for a data item and can then use - that string to register, look up, and remove the associated data item. - Note that there is currently no mechanism to trigger a destructor - function for registered data items when the Bro connection is terminated. - You therefore need to make sure that all data items that you do - not have pointers to via some other means are properly released before - calling - bro_disconnect(). - - - - - Configuration files - - Imagine you have instrumented the mother of all server applications. - Building it takes forever, and every now and then you need to change - some of the parameters that your Broccoli code uses, such as the host names - of the Bro agents to talk to. - To allow you to do this quickly, Broccoli comes with support for - configuration files. All you need to do is change the settings in the - file and restart the application (we're considering adding support - for volatile configuration items that are read from the file every - time they are requested). - - - A configuration is read from a single configuration file. - This file can be read from two different locations: - - - The system-wide configuration file. You can obtain the location - of this config file by running broccoli-config --config. - - - - Alternatively, a per-user configuration file stored in ~/.broccoli.conf - can be used. - - - - If a user has a configuration file in ~/.broccoli.conf, - it is used exclusively, otherwise the global one is used. - - - ~/.broccoli.conf will only be used if - it is a regular file, not executable, and neither group nor others have - any permissions on the file. That is, the file's permissions must look - like -rw------- or -r--------. - - - - In the configuration file, a "#" anywhere starts a comment that runs - to the end of the line. Configuration items are specified as key-value - pairs: - - - , where the identifier -# is a sequence of letters, and value can be a string (including -# whitespace), and floating point or integer numbers. Comments start -# with a "#" and go to the end of the line. For boolean values, you -# may also use "yes", "on", "true", "no", "off", or "false". -# Strings may contain whitespace, but need to be surrounded by -# double quotes '"'. -# -# Examples: -# -Foo/PeerName mybro.securesite.com -Foo/PortNum 123 -Bar/SomeFloat 1.23443543 -Bar/SomeLongStr "Hello World" -]]> - - - You can also have multiple sections in your configuration. Your application can - select a section as the current one, and queries for configuration settings will - then only be answered with values specified in that section. A section is started - by putting its name (no whitespace please) between square brackets. Configuration - items positioned before the first section title are in the default domain and - will be used by default. - - - - - - You can name identifiers any way you like, but to keep things - organized it is recommended to keep a namespace hierarchy similar - to the file system. In the code, you can query configuration - items using - bro_conf_get_str(), - bro_conf_get_int(), and - bro_conf_get_dbl(). - You can switch between sections using - bro_conf_set_domain(). - - - - - Using dynamic buffers - - Broccoli provides an API for dynamically allocatable, growable, shrinkable, - and consumable buffers with BroBufs. You may or may - not find this useful — Broccoli mainly provides this feature in - broccoli.h because these buffers are used internally - anyway and because they are typical case of something that people implement - themselves over and over again, for example to collect a set of data before - sending it through a file descriptor, etc. - - - The buffers work as follows. The structure implementing a buffer is - called BroBuf. BroBufs are initialized to a default size when created via - bro_buf_new(), - and released using - bro_buf_free(). - Each BroBuf has a content - pointer that points to an arbitrary location between the start of the - buffer and the first byte after the last byte currently - used in the buffer (see buf_off in the illustration below). The content - pointer can seek to arbitrary locations, and data can be copied from and - into the buffer, adjusting the content pointer accordingly. - You can repeatedly append data to end of the buffer's used contents using - bro_buf_append(). - - - - <======== used buffer space ========> - ^ ^ ^ ^ - | | | | - `buf `buf_ptr `buf_off `buf_len -]]> - - - Have a look at the following functions for the details: - bro_buf_new(), - bro_buf_free(), - bro_buf_append(), - bro_buf_consume(), - bro_buf_reset(), - bro_buf_get(), - bro_buf_get_end(), - bro_buf_get_size(), - bro_buf_get_used_size(), - bro_buf_ptr_get(), - bro_buf_ptr_tell(), - bro_buf_ptr_seek(), - bro_buf_ptr_check(), and - bro_buf_ptr_read(). - - -
- - - Configuring encrypted communication - - Encrypted communication between Bro peers takes place over an SSL connection in - which both endpoints of the connection are authenticated. This requires at least - some PKI in the form of a certificate authority (CA) which you use to issue and sign - certificates for your Bro peers. To facilitate the SSL setup, each peer requires - three documents: a certificate signed by the CA and containing the public key, the - corresponding private key, and a copy of the CA's certificate. - - - The OpenSSL command line tool openssl can be used to create all - files neccessary, but its unstructured arguments and poor documentation make it - a pain to use and waste lots of people a lot of timeIn other - documents and books on OpenSSL you will find this expressed more politely, using - terms such as "daunting to the uninitiated", "challenging", "complex", "intimidating". - . Therefore, the Bro distribution comes with two scripts, - ca-create and ca-issue. You use the former - once to set up your CA, and the latter to create a certificate for each of the Bro - peers in your infrastructure. - - - ca-create lets you choose a directory in which the - CA maintains its files. If you set BRO_CA_DIR in your - environment, it will be used for this purpose. After entering a passphrase - for the private key of your CA, you can find the self-signed certificate - of your CA in $BRO_CA_DIR/ca_cert.pem. - - - - ca-issue first requires the directory of the CA, - offering $BRO_CA_DIR if that is found. It asks you for - a prefix for the certificate to be generated, for the passphrase of the - private key of the CA so the new certificate can be signed, for the - passphrase for the new private key, and for a few parameters that make up - the "distinguished name" of the certificate. This name (i.e., the combination - of all the fields you enter a value for) must be unique among all your Bro - peers. Once that is done, you find a new certificate named - <prefix>.pem in your current - directory. This file actually consists of two of the three cryptographic - documents mentioned above, namely the new certificate and the private key. - We refer to it as "certificate" for simplicity. - - - - In order to enable encrypted communication for your Broccoli application, you - need to put the CA certificate and the peer certificate in the - /broccoli/ca_cert and - /broccoli/host_cert keys, respectively, in the configuration file. - To quickly enable/disable a certificate configuration, the - /broccoli/use_ssl key can be used. - - This is where you configure whether to use encrypted or unencrypted - connections. - If the /broccoli/use_ssl key is present and set to one of - "yes", "true", "on", or 1, then SSL will be used and an incorrect or - missing certificate configuration will cause connection attempts to fail. - If the key's value is one of "no", "false", "off", or 0, then in no case - will SSL be used and connections will always be cleartext. - - If the /broccoli/use_ssl key is not - present, then SSL will be used if a certificate configuration is - found, and invalid certificates will cause the connection to fail. - If no certificates are configured, cleartext connections will be used. - - In no case does an SSL-enabled setup ever fall back to a cleartext one. - - - -/ca_cert.pem -/broccoli/host_cert /bro_cert.pem -]]> - - - In a Bro policy, you need to load the listen-ssl.bro policy and - redef ssl_ca_certificate and ssl_private_key, - defined in bro.init: - - -/ca_cert.pem"; -redef ssl_private_key = "/bro.pem"; -]]> - - - By default, you will be prompted for the passphrase for the private key matching - the public key in your agent's certificate. Depending on your application's user - interface and deployment, this may be inappropriate. You can store the passphrase - in the config file as well, using the following identifier: - - - - - - Make sure that access to your configuration is restricted. - - If you provide the passphrase this way, it is obviously essential to have - restrictive permissions on the configuration file. Broccoli partially enforces - this. Please refer to the section on - configuration files for details. - - - - - - Configuring event reception in Bro policies - - Before a remote Bro will accept your connection and your events, it needs to have its - policy configured accordingly: - - - Load either listen-ssl or listen-clear, - depending on whether you want to have encrypted or cleartext communication. Obviously, - encrypting the event exchange is recommended and cleartext should only be used for - early experimental setups. See below for details on how to set up encrypted - communication via SSL. - - - - - You need to find a port to use for the Bros and Broccoli applications that will - listen for connections. Every such agent can use a different port, though default - ports are provided in the Bro policies. - To change the port the Bro agent will be listening on from its default - redefine the listen_port_ssl or - listen_port_clear variables from listen-clear.bro - or listen-ssl.bro, respectively. Have a look at these policies as well - as remote.bro for the default values. Here is the policy - for the unencrypted case: - - - - - - Including the settings for the cryptographic files introduced in the previous section, - here is the encrypted one: - - -/ca_cert.pem"; -redef ssl_private_key = "/bro.pem"; -]]> - - - - - The policy controlling which peers a Bro agent will communicate with and how this - communication will happen are defined in the destinations table - defined in remote.bro. This table contains entries of type - Destination, whose members mostly provide default values so you do not - need to define everything. You need to come up with a tag for the connection - under which it can be found in the table (a creative one would be "broccoli"), - the IP address of the peer, the pattern of names of the events the Bro will accept - from you, whether you want Bro to connect to your - machine on startup or not, if so, a port to connect to (defaults are - default_port_ssl and default_port_clear, also - defined in remote.bro), a retry timeout, whether to use SSL, - and the class of a connection as set on the Broccoli side via - bro_conn_set_class(). - - - An example could look as follows: - - - - - - This example is taken from broping.bro, the policy the - remote Bro must run when you want to use the broping tool - explained in the section on testing below. - It will allow an agent on the local host to connect and send "ping" events. - Our Bro will not attempt to connect, and incoming connections will be expected - in cleartext. - - - - - - - - Configuring debugging output - - If your Broccoli installation was configured with --enable-debug, - Broccoli will report two kinds of debugging information: (i) - function call traces and - (ii) individual debugging messages. Both are enabled by default, but can be adjusted - in two ways. - - - In the configuration file: in the appropriate section of the configuration - file, you can set the keys /broccoli/debug_messages and - /broccoli/debug_calltrace to on/off - to enable/disable the corresponding output. - - - - In code: you can set the variables - bro_debug_calltrace and - bro_debug_messages - to 1/0 at any time to enable/disable the corresponding output. - - - - - - By default, debugging output is inactive (even with debuggin support compiled in). - You need to enable it explicitly either in your code by assigning 1 to - bro_debug_calltrace and - bro_debug_messages, - or by enabling it in the configuration file. - - - - - Test programs - - The Broccoli distribution comes with a few small test programs, - located in the test/ directory of the tree. - The most notable one is &bp; - Pronunciation is said to be somewhere on the continuum between - "brooping" and "burping"., a mini-version of ping. - It sends "ping" events to a remote Bro agent, expecting "pong" events - in return. It operates in two flavours: one uses atomic types for sending - information across, and the other one uses records. The Bro agent you want - to ping needs to run either the broping.bro or - broping-record.bro policies. You can find these - in the test/ directory of the source tree, and - in <prefix>/share/broccoli in the installed - version. broping.bro is shown below. By default, - pinging a Bro on the same machine is configured. If you want your Bro - to be pinged from another machine, you need to update the - destinations variable accordingly. - - - - - - &bp; sends ping events to Bro. Bro accepts those because they are configured - accordingly in the destinations table. As shown in the policy, ping events - trigger pong events, and &bc; requests delivery of all pong events back to it. - When running &bp;, you'll see something like this: - - - ./test/broping -pong event from 127.0.0.1: seq=1, time=0.004700/1.010303 s -pong event from 127.0.0.1: seq=2, time=0.053777/1.010266 s -pong event from 127.0.0.1: seq=3, time=0.006435/1.010284 s -pong event from 127.0.0.1: seq=4, time=0.020278/1.010319 s -pong event from 127.0.0.1: seq=5, time=0.004563/1.010187 s -pong event from 127.0.0.1: seq=6, time=0.005685/1.010393 s -]]> - - -
- - - Broccoli API Reference - &bc-header; - - - - Appendix - - License - - Copyright (C) 2004-2008 Christian Kreibich and various contributors. - - - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: - - - The above copyright notice and this permission notice shall be included in - all copies of the Software and its documentation and acknowledgment shall be - given in the documentation and software packages that this Software was - used. - - - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - - - - About this document - - This documentation is maintained in SGML DocBook, - API documentation is extracted from the code using the - gtk-doc tools. - - - -
diff --git a/aux/broccoli/docs/broccoli-sections.txt b/aux/broccoli/docs/broccoli-sections.txt deleted file mode 100644 index 2c32d932ff..0000000000 --- a/aux/broccoli/docs/broccoli-sections.txt +++ /dev/null @@ -1,91 +0,0 @@ -
-broccoli -bro_debug_calltrace -bro_debug_messages -BroEventFunc -BroCompactEventFunc -bro_conn_new -bro_conn_new_str -bro_conn_new_socket -bro_conn_set_class -bro_conn_get_peer_class -bro_conn_connect -bro_conn_alive -bro_conn_delete -bro_conn_adopt_events -bro_conn_get_fd -bro_conn_process_input -bro_conn_data_set -bro_conn_data_get -bro_conn_data_del -bro_event_new -bro_event_free -bro_event_add_val -bro_event_set_val -bro_event_send -bro_event_queue_length -bro_event_queue_flush -bro_event_registry_add -bro_event_registry_add_compact -bro_event_registry_remove -bro_event_registry_request -bro_buf_new -bro_buf_free -bro_buf_append -bro_buf_consume -bro_buf_reset -bro_buf_get -bro_buf_get_end -bro_buf_get_size -bro_buf_get_used_size -bro_buf_ptr_get -bro_buf_ptr_tell -bro_buf_ptr_seek -bro_buf_ptr_check -bro_buf_ptr_read -bro_buf_ptr_write -bro_conf_get_int -bro_conf_get_dbl -bro_conf_get_str -bro_conf_set_domain -bro_string_init -bro_string_set -bro_string_set_data -bro_string_get_data -bro_string_get_length -bro_string_copy -bro_string_cleanup -bro_string_free -bro_record_new -bro_record_free -bro_record_add_val -bro_record_get_nth_val -bro_record_get_nth_name -bro_record_get_named_val -bro_record_set_nth_val -bro_record_set_named_val -BroTableCallback -bro_table_new -bro_table_free -bro_table_insert -bro_table_find -bro_table_get_size -bro_table_get_types -bro_table_foreach -BroSetCallback -bro_set_new -bro_set_free -bro_set_insert -bro_set_find -bro_set_get_size -bro_set_get_type -bro_set_foreach -bro_conn_set_packet_ctxt -bro_conn_get_packet_ctxt -bro_packet_new -bro_packet_clone -bro_packet_free -bro_packet_send -bro_util_current_time -bro_util_timeval_to_double -
diff --git a/aux/broccoli/docs/broccoli.types b/aux/broccoli/docs/broccoli.types deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/aux/broccoli/docs/html/a3621.html b/aux/broccoli/docs/html/a3621.html deleted file mode 100644 index cc9d735b8d..0000000000 --- a/aux/broccoli/docs/html/a3621.html +++ /dev/null @@ -1,210 +0,0 @@ - -Appendix
Broccoli: The Bro Client Communications Library
Prev 

Appendix A. Appendix

Table of Contents
A.1. License
A.2. About this document

A.1. License

Copyright (C) 2004-2008 Christian Kreibich and various contributors. -

- Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to - deal in the Software without restriction, including without limitation the - rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - sell copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: -

The above copyright notice and this permission notice shall be included in - all copies of the Software and its documentation and acknowledgment shall be - given in the documentation and software packages that this Software was - used. -

- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER - IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -


A.2. About this document

This documentation is maintained in SGML DocBook, - API documentation is extracted from the code using the - gtk-doc tools. -


PrevHome 
broccoli  
\ No newline at end of file diff --git a/aux/broccoli/docs/html/api.html b/aux/broccoli/docs/html/api.html deleted file mode 100644 index cb4a6b72e5..0000000000 --- a/aux/broccoli/docs/html/api.html +++ /dev/null @@ -1,139 +0,0 @@ - -Broccoli API Reference
Broccoli: The Bro Client Communications Library
PrevNext

Chapter 4. Broccoli API Reference


PrevHomeNext
Using Broccoli broccoli
\ No newline at end of file diff --git a/aux/broccoli/docs/html/broccoli-broccoli.html b/aux/broccoli/docs/html/broccoli-broccoli.html deleted file mode 100644 index 5dd659d482..0000000000 --- a/aux/broccoli/docs/html/broccoli-broccoli.html +++ /dev/null @@ -1,6645 +0,0 @@ - -broccoli
Broccoli: The Bro Client Communications Library
PrevNext

broccoli

Name

broccoli -- 

Synopsis

extern              int bro_debug_calltrace;
-extern              int bro_debug_messages;
-void                (*BroEventFunc)                     (BroConn *bc,
-                                                         void *user_data,
-                                                         ...);
-void                (*BroCompactEventFunc)              (BroConn *bc,
-                                                         void *user_data,
-                                                         BroEvMeta *meta);
-BroConn*            bro_conn_new                        (struct in_addr *ip_addr,
-                                                         uint16 port,
-                                                         int flags);
-BroConn*            bro_conn_new_str                    (const char *hostname,
-                                                         int flags);
-BroConn*            bro_conn_new_socket                 (int socket,
-                                                         int flags);
-void                bro_conn_set_class                  (BroConn *bc,
-                                                         const char *classname);
-const char*         bro_conn_get_peer_class             (const BroConn *bc);
-int                 bro_conn_connect                    (BroConn *bc);
-int                 bro_conn_alive                      (const BroConn *bc);
-int                 bro_conn_delete                     (BroConn *bc);
-void                bro_conn_adopt_events               (BroConn *src,
-                                                         BroConn *dst);
-int                 bro_conn_get_fd                     (BroConn *bc);
-int                 bro_conn_process_input              (BroConn *bc);
-void                bro_conn_data_set                   (BroConn *bc,
-                                                         const char *key,
-                                                         void *val);
-void*               bro_conn_data_get                   (BroConn *bc,
-                                                         const char *key);
-void*               bro_conn_data_del                   (BroConn *bc,
-                                                         const char *key);
-BroEvent*           bro_event_new                       (const char *event_name);
-void                bro_event_free                      (BroEvent *be);
-int                 bro_event_add_val                   (BroEvent *be,
-                                                         int type,
-                                                         const char *type_name,
-                                                         const void *val);
-int                 bro_event_set_val                   (BroEvent *be,
-                                                         int val_num,
-                                                         int type,
-                                                         const char *type_name,
-                                                         const void *val);
-int                 bro_event_send                      (BroConn *bc,
-                                                         BroEvent *be);
-int                 bro_event_queue_length              (BroConn *bc);
-int                 bro_event_queue_flush               (BroConn *bc);
-void                bro_event_registry_add              (BroConn *bc,
-                                                         const char *event_name,
-                                                         BroEventFunc func,
-                                                         void *user_data);
-void                bro_event_registry_add_compact      (BroConn *bc,
-                                                         const char *event_name,
-                                                         BroCompactEventFunc func,
-                                                         void *user_data);
-void                bro_event_registry_remove           (BroConn *bc,
-                                                         const char *event_name);
-void                bro_event_registry_request          (BroConn *bc);
-BroBuf*             bro_buf_new                         (void);
-void                bro_buf_free                        (BroBuf *buf);
-int                 bro_buf_append                      (BroBuf *buf,
-                                                         void *data,
-                                                         int data_len);
-void                bro_buf_consume                     (BroBuf *buf);
-void                bro_buf_reset                       (BroBuf *buf);
-uchar*              bro_buf_get                         (BroBuf *buf);
-uchar*              bro_buf_get_end                     (BroBuf *buf);
-uint                bro_buf_get_size                    (BroBuf *buf);
-uint                bro_buf_get_used_size               (BroBuf *buf);
-uchar*              bro_buf_ptr_get                     (BroBuf *buf);
-uint32              bro_buf_ptr_tell                    (BroBuf *buf);
-int                 bro_buf_ptr_seek                    (BroBuf *buf,
-                                                         int offset,
-                                                         int whence);
-int                 bro_buf_ptr_check                   (BroBuf *buf,
-                                                         int size);
-int                 bro_buf_ptr_read                    (BroBuf *buf,
-                                                         void *data,
-                                                         int size);
-int                 bro_buf_ptr_write                   (BroBuf *buf,
-                                                         void *data,
-                                                         int size);
-int                 bro_conf_get_int                    (const char *val_name,
-                                                         int *val);
-int                 bro_conf_get_dbl                    (const char *val_name,
-                                                         double *val);
-const char*         bro_conf_get_str                    (const char *val_name);
-void                bro_conf_set_domain                 (const char *domain);
-void                bro_string_init                     (BroString *bs);
-int                 bro_string_set                      (BroString *bs,
-                                                         const char *s);
-int                 bro_string_set_data                 (BroString *bs,
-                                                         const uchar *data,
-                                                         int data_len);
-const uchar*        bro_string_get_data                 (const BroString *bs);
-uint32              bro_string_get_length               (const BroString *bs);
-BroString*          bro_string_copy                     (BroString *bs);
-void                bro_string_cleanup                  (BroString *bs);
-void                bro_string_free                     (BroString *bs);
-BroRecord*          bro_record_new                      (void);
-void                bro_record_free                     (BroRecord *rec);
-int                 bro_record_add_val                  (BroRecord *rec,
-                                                         const char *name,
-                                                         int type,
-                                                         const char *type_name,
-                                                         const void *val);
-void*               bro_record_get_nth_val              (BroRecord *rec,
-                                                         int num,
-                                                         int *type);
-const char*         bro_record_get_nth_name             (BroRecord *rec,
-                                                         int num);
-void*               bro_record_get_named_val            (BroRecord *rec,
-                                                         const char *name,
-                                                         int *type);
-int                 bro_record_set_nth_val              (BroRecord *rec,
-                                                         int num,
-                                                         int type,
-                                                         const char *type_name,
-                                                         const void *val);
-int                 bro_record_set_named_val            (BroRecord *rec,
-                                                         const char *name,
-                                                         int type,
-                                                         const char *type_name,
-                                                         const void *val);
-int                 (*BroTableCallback)                 (void *key,
-                                                         void *val,
-                                                         void *user_data);
-BroTable*           bro_table_new                       (void);
-void                bro_table_free                      (BroTable *tbl);
-int                 bro_table_insert                    (BroTable *tbl,
-                                                         int key_type,
-                                                         const void *key,
-                                                         int val_type,
-                                                         const void *val);
-void*               bro_table_find                      (BroTable *tbl,
-                                                         const void *key);
-int                 bro_table_get_size                  (BroTable *tbl);
-void                bro_table_get_types                 (BroTable *tbl,
-                                                         int *key_type,
-                                                         int *val_type);
-void                bro_table_foreach                   (BroTable *tbl,
-                                                         BroTableCallback cb,
-                                                         void *user_data);
-int                 (*BroSetCallback)                   (void *val,
-                                                         void *user_data);
-BroSet*             bro_set_new                         (void);
-void                bro_set_free                        (BroSet *set);
-int                 bro_set_insert                      (BroSet *set,
-                                                         int type,
-                                                         const void *val);
-int                 bro_set_find                        (BroSet *set,
-                                                         const void *key);
-int                 bro_set_get_size                    (BroSet *set);
-void                bro_set_get_type                    (BroSet *set,
-                                                         int *type);
-void                bro_set_foreach                     (BroSet *set,
-                                                         BroSetCallback cb,
-                                                         void *user_data);
-void                bro_conn_set_packet_ctxt            (BroConn *bc,
-                                                         int link_type);
-void                bro_conn_get_packet_ctxt            (BroConn *bc,
-                                                         int *link_type);
-BroPacket*          bro_packet_new                      (const struct pcap_pkthdr *hdr,
-                                                         const u_char *data,
-                                                         const char *tag);
-BroPacket*          bro_packet_clone                    (const BroPacket *packet);
-void                bro_packet_free                     (BroPacket *packet);
-int                 bro_packet_send                     (BroConn *bc,
-                                                         BroPacket *packet);
-double              bro_util_current_time               (void);
-double              bro_util_timeval_to_double          (const struct timeval *tv);

Description

Details

bro_debug_calltrace

extern int bro_debug_calltrace;

If you have debugging support built in (i.e., your package was configured -with --enable-debugging), you can enable/disable debugging output for -call tracing by setting this to 0 (off) or 1 (on). Default is off.


bro_debug_messages

extern int bro_debug_messages;

If you have debugging support built in (i.e., your package was configured -with --enable-debugging), you can enable/disable debugging messages -by setting this to 0 (off) or 1 (on). Default is off.


BroEventFunc ()

void                (*BroEventFunc)                     (BroConn *bc,
-                                                         void *user_data,
-                                                         ...);

This is the signature of callbacks for handling received -Bro events, called in the argument-expanded style. For details -see bro_event_registry_add().

bc :

Bro connection handle.

user_data :

user data provided to bro_event_registry_add().

... :

varargs.


BroCompactEventFunc ()

void                (*BroCompactEventFunc)              (BroConn *bc,
-                                                         void *user_data,
-                                                         BroEvMeta *meta);

This is the signature of callbacks for handling received -Bro events, called in the compact-argument style. For details -see bro_event_registry_add_compact().

bc :

Bro connection handle.

user_data :

user data provided to bro_event_registry_add_compact().

meta :

metadata for the event


bro_conn_new ()

BroConn*            bro_conn_new                        (struct in_addr *ip_addr,
-                                                         uint16 port,
-                                                         int flags);

The function creates a new Bro connection handle for communication with -Bro through a network. Depending on the flags passed in, the connection -and its setup process can be adjusted. If you don't want to pass any -flags, use BRO_CFLAG_NONE.

ip_addr :

4-byte IP address of Bro to contact, in network byte order.

port :

port of machine at ip_addr to contact, in network byte order.

flags :

an or-combination of the BRO_CONN_xxx flags.

Returns :

pointer to a newly allocated and initialized -Bro connection structure. You need this structure for all -other calls in order to identify the connection to Bro.


bro_conn_new_str ()

BroConn*            bro_conn_new_str                    (const char *hostname,
-                                                         int flags);

The function is identical to bro_conn_new(), but allows you to specify the -host and port to connect to in a string as "<hostname>:<port>". flags can -be used to adjust the connection features and the setup process. If you don't -want to pass any flags, use BRO_CFLAG_NONE.

hostname :

string describing the host and port to connect to.

flags :

an or-combination of the BRO_CONN_xxx flags.

Returns :

pointer to a newly allocated and initialized -Bro connection structure. You need this structure for all -other calls in order to identify the connection to Bro.


bro_conn_new_socket ()

BroConn*            bro_conn_new_socket                 (int socket,
-                                                         int flags);

The function is identical to bro_conn_new(), but allows you to pass in an -open socket to use for the communication. flags can be used to -adjust the connection features and the setup process. If you don't want to -pass any flags, use BRO_CFLAG_NONE.

socket :

open socket.

flags :

an or-combination of the BRO_CONN_xxx flags.

Returns :

pointer to a newly allocated and initialized -Bro connection structure. You need this structure for all -other calls in order to identify the connection to Bro.


bro_conn_set_class ()

void                bro_conn_set_class                  (BroConn *bc,
-                                                         const char *classname);

Broccoli connections can indicate that they belong to a certain class -of connections, which is needed primarily if multiple Bro/Broccoli -instances are running on the same node and connect to a single remote -peer. You can set this class with this function, and you have to do so -before calling bro_connect() since the connection class is determined -upon connection establishment. You remain responsible for the memory -pointed to by classname.

bc :

connection handle.

classname :

class identifier.


bro_conn_get_peer_class ()

const char*         bro_conn_get_peer_class             (const BroConn *bc);

bc :

connection handle.

Returns :

a string containing the connection class indicated by the peer, -if any, otherwise NULL.


bro_conn_connect ()

int                 bro_conn_connect                    (BroConn *bc);

The function attempts to set up and configure a connection to -the peer configured when the connection handle was obtained.

bc :

connection handle.

Returns :

TRUE on success, FALSE on failure.


bro_conn_alive ()

int                 bro_conn_alive                      (const BroConn *bc);

This predicate reports whether the connection handle is currently -usable for sending/receiving data or not, e.g. because the peer -died. The function does not actively check and update the -connection's state, it only reports the value of flags indicating -its status. In particular, this means that when calling -bro_conn_alive() directly after a select() on the connection's -descriptor, bro_conn_alive() may return an incorrent value. It will -however return the correct value after a subsequent call to -bro_conn_process_input(). Also note that the connection is also -dead after the connection handle is obtained and before -bro_conn_connect() is called.

bc :

Bro connection handle.

Returns :

TRUE if the connection is alive, FALSE otherwise.


bro_conn_delete ()

int                 bro_conn_delete                     (BroConn *bc);

This function will terminate the given connection if necessary -and release all resources associated with the connection handle.

bc :

Bro connection handle

Returns :

FALSE on error, TRUE otherwise.


bro_conn_adopt_events ()

void                bro_conn_adopt_events               (BroConn *src,
-                                                         BroConn *dst);

The function makes the connection identified by dst use the same event -mask as the one identified by src.

src :

Bro connection handle for connection whose event list to adopt.

dst :

Bro connection handle for connection whose event list to change.


bro_conn_get_fd ()

int                 bro_conn_get_fd                     (BroConn *bc);

If you need to know the file descriptor of the connection -(such as when select()ing it etc), use this accessor function.

bc :

Bro connection handle.

Returns :

file descriptor for connection bc, or negative value -on error.


bro_conn_process_input ()

int                 bro_conn_process_input              (BroConn *bc);

The function reads all input sent to the local sensor by the -Bro peering at the connection identified by bc. It is up -to you to find a spot in the application you're instrumenting -to make sure this is called. This function cannot block. -bro_conn_alive() will report the actual state of the connection -after a call to bro_conn_process_input().

bc :

Bro connection handle

Returns :

TRUE if any input was processed, FALSE otherwise.


bro_conn_data_set ()

void                bro_conn_data_set                   (BroConn *bc,
-                                                         const char *key,
-                                                         void *val);

The function stores val under name key in the connection handle bc. -key is copied internally so you do not need to duplicate it before -passing.

bc :

Bro connection handle.

key :

name of the data item.

val :

data item.


bro_conn_data_get ()

void*               bro_conn_data_get                   (BroConn *bc,
-                                                         const char *key);

The function tries to look up the data item with name key and -if found, returns it.

bc :

Bro connection handle.

key :

name of the data item.

Returns :

data item if lookup was successful, NULL otherwise.


bro_conn_data_del ()

void*               bro_conn_data_del                   (BroConn *bc,
-                                                         const char *key);

The function tries to remove the data item with name key.

bc :

Bro connection handle.

key :

name of the data item.

Returns :

the removed data item if it exists, NULL otherwise.


bro_event_new ()

BroEvent*           bro_event_new                       (const char *event_name);

The function creates a new empty event with the given -name and returns it.

event_name :

name of the Bro event.

Returns :

new event, or NULL if allocation failed.


bro_event_free ()

void                bro_event_free                      (BroEvent *be);

The function releases all memory associated with be. Note -that you do NOT have to call this after sending an event.

be :

event to release.


bro_event_add_val ()

int                 bro_event_add_val                   (BroEvent *be,
-                                                         int type,
-                                                         const char *type_name,
-                                                         const void *val);

The function adds the given val to the argument list of -event be. The type of val is derived from type, and may be -specialized to the type named type_name. If type_name is not -desired, use NULL.

val remains the caller's responsibility and is copied internally.

be :

event to add to.

type :

numerical type identifier (a BRO_TYPE_xxx constant).

type_name :

optional name of specialized type.

val :

value to add to event.

Returns :

TRUE if the operation was successful, FALSE otherwise.


bro_event_set_val ()

int                 bro_event_set_val                   (BroEvent *be,
-                                                         int val_num,
-                                                         int type,
-                                                         const char *type_name,
-                                                         const void *val);

The function replaces whatever value is currently stored in the -event pointed to by be with the val specified through the type and -val arguments. If the event does not currently hold enough -values to replace one in position val_num, the function does -nothing. If you want to indicate a type specialized from type, -use type_name to give its name, otherwise pass NULL for type_name.

be :

event handle.

val_num :

number of the value to replace, starting at 0.

type :

numerical type identifier (a BRO_TYPE_xxx constant).

type_name :

optional name of specialized type.

val :

value to put in.

Returns :

TRUE if successful, FALSE on error.


bro_event_send ()

int                 bro_event_send                      (BroConn *bc,
-                                                         BroEvent *be);

The function tries to send be to the Bro agent connected -through bc. Regardless of the outcome, you do NOT have -to release the event afterwards using bro_event_free().

bc :

Bro connection handle

be :

event to send.

Returns :

TRUE if the event got sent or queued for later transmission, -FALSE on error. There are no automatic repeated send attempts -(to minimize the effect on the code that Broccoli is linked to). -If you have to make sure that everything got sent, you have -to try to empty the queue using bro_event_queue_flush(), and -also look at bro_event_queue_empty().


bro_event_queue_length ()

int                 bro_event_queue_length              (BroConn *bc);

Use this function to find out how many events are currently queued -on the client side.

bc :

Bro connection handle

Returns :

number of items currently queued.


bro_event_queue_flush ()

int                 bro_event_queue_flush               (BroConn *bc);

The function tries to send as many queued events to the Bro -agent as possible.

bc :

Bro connection handle

Returns :

remaining queue length after flush.


bro_event_registry_add ()

void                bro_event_registry_add              (BroConn *bc,
-                                                         const char *event_name,
-                                                         BroEventFunc func,
-                                                         void *user_data);

This function registers the callback func to be invoked when events -of name event_name arrive on connection bc. user_data is passed along -to the callback, which will receive it as the second parameter. You -need to ensure that the memory user_data points to is valid during the -time the callback might be invoked.

Note that this function only registers the callback in the state -associated with bc. If you use bro_event_registry_add() and bc -has not yet been connected via bro_conn_connect(), then no further -action is required. bro_conn_connect() request ant registered event types. -If however you are requesting additional event types after the connection has -been established, then you also need to call bro_event_registry_request() -in order to signal to the peering Bro that you want to receive those events.

bc :

Bro connection handle

event_name :

Name of events that trigger callback

func :

callback to invoke.

user_data :

user data passed through to the callback.


bro_event_registry_add_compact ()

void                bro_event_registry_add_compact      (BroConn *bc,
-                                                         const char *event_name,
-                                                         BroCompactEventFunc func,
-                                                         void *user_data);

This function registers the callback func to be invoked when events -of name event_name arrive on connection bc. user_data is passed along -to the callback, which will receive it as the second parameter. You -need to ensure that the memory user_data points to is valid during the -time the callback might be invoked. See bro_event_registry_add() for -details.

bc :

Bro connection handle

event_name :

Name of events that trigger callback

func :

callback to invoke.

user_data :

user data passed through to the callback.


bro_event_registry_remove ()

void                bro_event_registry_remove           (BroConn *bc,
-                                                         const char *event_name);

The function removes all callbacks for event event_name from the -event registry for connection bc.

bc :

Bro connection handle

event_name :

event to ignore from now on.


bro_event_registry_request ()

void                bro_event_registry_request          (BroConn *bc);

The function requests the events you have previously requested using -bro_event_registry_add() from the Bro listening on bc.

bc :

Bro connection handle


bro_buf_new ()

BroBuf*             bro_buf_new                         (void);

Returns :

a new buffer object, or NULL on error. Use paired with -bro_buf_free().


bro_buf_free ()

void                bro_buf_free                        (BroBuf *buf);

The function releases all memory held by the buffer pointed -to by buf. Use paired with bro_buf_new().

buf :

buffer pointer.


bro_buf_append ()

int                 bro_buf_append                      (BroBuf *buf,
-                                                         void *data,
-                                                         int data_len);

The function appends data to the end of the buffer, -enlarging it if necessary to hold the len new bytes. -NOTE: it does not modify the buffer pointer. It only -appends new data where buf_off is currently pointing -and updates it accordingly. If you DO want the buffer -pointer to be updated, have a look at bro_buf_ptr_write() -instead.

buf :

buffer pointer.

data :

new data to append to buffer.

data_len :

size of data.

Returns :

TRUE if successful, FALSE otherwise.


bro_buf_consume ()

void                bro_buf_consume                     (BroBuf *buf);

The function removes the buffer contents between the start -of the buffer and the point where the buffer pointer -currently points to. The idea is that you call bro_buf_ptr_read() -a few times to extract data from the buffer, and then -call bro_buf_consume() to signal to the buffer that the -extracted data are no longer needed inside the buffer.

buf :

buffer pointer.


bro_buf_reset ()

void                bro_buf_reset                       (BroBuf *buf);

The function resets the buffer pointers to the beginning of the -currently allocated buffer, i.e., it marks the buffer as empty.

buf :

buffer pointer.


bro_buf_get ()

uchar*              bro_buf_get                         (BroBuf *buf);

buf :

buffer pointer.

Returns :

the entire buffer's contents.


bro_buf_get_end ()

uchar*              bro_buf_get_end                     (BroBuf *buf);

buf :

buffer pointer.

Returns :

a pointer to the first byte in the -buffer that is not currently used.


bro_buf_get_size ()

uint                bro_buf_get_size                    (BroBuf *buf);

buf :

buffer pointer.

Returns :

the number of actual bytes allocated for the -buffer.


bro_buf_get_used_size ()

uint                bro_buf_get_used_size               (BroBuf *buf);

buf :

buffer pointer.

Returns :

number of bytes currently used.


bro_buf_ptr_get ()

uchar*              bro_buf_ptr_get                     (BroBuf *buf);

buf :

buffer pointer.

Returns :

current buffer content pointer.


bro_buf_ptr_tell ()

uint32              bro_buf_ptr_tell                    (BroBuf *buf);

buf :

buffer pointer.

Returns :

current offset of buffer content pointer.


bro_buf_ptr_seek ()

int                 bro_buf_ptr_seek                    (BroBuf *buf,
-                                                         int offset,
-                                                         int whence);

The function adjusts the position of buf's content -pointer. Call semantics are identical to fseek(), thus -use offset to indicate the offset by which to jump and -use SEEK_SET, SEEK_CUR, or SEEK_END to specify the -position relative to which to adjust.

buf :

buffer pointer.

offset :

number of bytes by which to adjust pointer, positive or negative.

whence :

location relative to which to adjust.

Returns :

TRUE if adjustment could be made, FALSE -if not (e.g. because the offset requested is not within -legal bounds).


bro_buf_ptr_check ()

int                 bro_buf_ptr_check                   (BroBuf *buf,
-                                                         int size);

The function checks whether size bytes could be read from the -buffer using bro_buf_ptr_read().

buf :

buffer pointer.

size :

number of bytes to check for availability.

Returns :

TRUE if size bytes can be read, FALSE if not.


bro_buf_ptr_read ()

int                 bro_buf_ptr_read                    (BroBuf *buf,
-                                                         void *data,
-                                                         int size);

The function copies size bytes into data if the buffer -has size bytes available from the current location of -the buffer content pointer onward, incrementing the content -pointer accordingly. If not, the function doesn't do anything. -It behaves thus different from the normal read() in that -it either copies the amount requested or nothing.

buf :

buffer pointer.

data :

destination area.

size :

number of bytes to copy into data.

Returns :

TRUE if size bytes were copied, FALSE if not.


bro_buf_ptr_write ()

int                 bro_buf_ptr_write                   (BroBuf *buf,
-                                                         void *data,
-                                                         int size);

The function writes size bytes of the area pointed to by data -into the buffer buf at the current location of its content pointer, -adjusting the content pointer accordingly. If the buffer doesn't have -enough space to receive size bytes, more space is allocated.

buf :

buffer pointer.

data :

data to write.

size :

number of bytes to copy into data.

Returns :

TRUE if size bytes were copied, FALSE if an error -occurred and the bytes could not be copied.


bro_conf_get_int ()

int                 bro_conf_get_int                    (const char *val_name,
-                                                         int *val);

The function tries to find an integer item named val_name in the -configuration. If it is found, its value is placed into the -int pointed to by val.

val_name :

key name for the value.

val :

result pointer for the value.

Returns :

TRUE if val_name was found, FALSE otherwise.


bro_conf_get_dbl ()

int                 bro_conf_get_dbl                    (const char *val_name,
-                                                         double *val);

The function tries to find a double float item named val_name -in the configuration. If it is found, its value is placed into the -double pointed to by val.

val_name :

key name for the value.

val :

result pointer for the value.

Returns :

TRUE if val_name was found, FALSE otherwise.


bro_conf_get_str ()

const char*         bro_conf_get_str                    (const char *val_name);

The function tries to find a string item named val_name in the -configuration.

val_name :

key name for the value.

Returns :

the config item if val_name was found, NULL otherwise. -A returned string is stored internally and not to be modified. If -you need to keep it around, strdup() it.


bro_conf_set_domain ()

void                bro_conf_set_domain                 (const char *domain);

Broccoli's config files are divided into sections. At the beginning of -each config file you can have an unnamed section that will be used by -default. Case is irrelevant. By passing NULL for domain, you select -the default domain, otherwise the one that matches domain. domain is -copied internally.

domain :

name of the domain, or NULL.


bro_string_init ()

void                bro_string_init                     (BroString *bs);

The function initializes the BroString pointed to by bs. Use this -function before using the members of a BroString you're using on the -stack.

bs :

string pointer.


bro_string_set ()

int                 bro_string_set                      (BroString *bs,
-                                                         const char *s);

The function initializes the BroString pointed to by bs to the string -given in s. s's content is copied, so you can modify or free s -after calling this, and you need to call bro_string_cleanup() on the -BroString pointed to by bs.

bs :

string pointer.

s :

C ASCII string.

Returns :

TRUE is successful, FALSE otherwise.


bro_string_set_data ()

int                 bro_string_set_data                 (BroString *bs,
-                                                         const uchar *data,
-                                                         int data_len);

The function initializes the BroString pointed to by bs to data_len -bytes starting at data. data's content is copied, so you can modify -or free data after calling this.

bs :

string pointer.

data :

arbitrary data.

data_len :

length of data.

Returns :

TRUE is successful, FALSE otherwise.


bro_string_get_data ()

const uchar*        bro_string_get_data                 (const BroString *bs);

The function returns a pointer to the string's internal data. You -can copy out the string using this function in combination with -bro_string_get_length(), for obtaining the string's length.

bs :

string pointer.

Returns :

pointer to string, or NULL on error.


bro_string_get_length ()

uint32              bro_string_get_length               (const BroString *bs);

bs :

string pointer.

Returns :

the string's length.


bro_string_copy ()

BroString*          bro_string_copy                     (BroString *bs);

bs :

string pointer.

Returns :

a deep copy of the BroString pointed to by bs, or NULL on -error.


bro_string_cleanup ()

void                bro_string_cleanup                  (BroString *bs);

This function releases all contents claimed by the BroString pointed -to by bs, without releasing that BroString structure itself. Use -this when manipulating a BroString on the stack, paired with -bro_string_init().

bs :

string pointer.


bro_string_free ()

void                bro_string_free                     (BroString *bs);

This function releases the entire BroString pointed to by bs, including -the BroString structure itself.

bs :

string pointer.


bro_record_new ()

BroRecord*          bro_record_new                      (void);

The function allocates and initializes a new empty record. BroRecords -are used for adding and retrieving records vals to/from events. You -do not have to specify a record type separately when you create a -record. The type is defined implicitly by the sequence of types formed -by the sequence of vals added to the record, along with the names for -each val. See the manual for details.

Returns :

a new record, or NULL on error.


bro_record_free ()

void                bro_record_free                     (BroRecord *rec);

The function releases all memory consumed by the record pointed to -by rec.

rec :

record handle.


bro_record_add_val ()

int                 bro_record_add_val                  (BroRecord *rec,
-                                                         const char *name,
-                                                         int type,
-                                                         const char *type_name,
-                                                         const void *val);

The function adds a new field to the record pointed to by rec and -assigns the value passed in to that field. The field name is given -in name, the type of the val is given in type and must be one of -the BRO_TYPE_xxx constants defined in broccoli.h. The type you give -implies what data type val must be pointing to; see the manual for -details. If you want to indicate a type specialized from type, -use type_name to give its name, otherwise pass NULL for type_name. -It is possible to leave fields unassigned, in that case, pass in -NULL for val.

val remains the caller's responsibility and is copied internally.

rec :

record handle.

name :

field name of the added val.

type :

numerical type tag of the new val.

type_name :

optional name of specialized type.

val :

pointer to the new val*.

Returns :

TRUE on success, FALSE on error.


bro_record_get_nth_val ()

void*               bro_record_get_nth_val              (BroRecord *rec,
-                                                         int num,
-                                                         int *type);

The function returns the num'th value of the record pointed to -by rec, expected to be of type. The returned value is internal -and needs to be duplicated if you want to keep it around. Upon -return, the int pointed to by type tells you the type of the returned -val, as a BRO_TYPE_xxx type tag. If the int pointed to upon calling -the function has the value BRO_TYPE_UNKNOWN, no type checking is -performed and the value is returned. If it is any other type tag, -its value is compared to that of the value, and if they match, the -value is returned. Otherwise, the return value is NULL. If you don't -care about type enforcement and don't want to know the value's type, -you may pass NULL for type.

rec :

record handle.

num :

field index, starting from 0.

type :

value-result argument for the expected/actual type of the value.

Returns :

pointer to queried value on success, NULL on error.


bro_record_get_nth_name ()

const char*         bro_record_get_nth_name             (BroRecord *rec,
-                                                         int num);

The function returns the num'th name of the record pointed to by rec.

rec :

record handle.

num :

field index, starting from 0.

Returns :

field name on success, NULL on error.


bro_record_get_named_val ()

void*               bro_record_get_named_val            (BroRecord *rec,
-                                                         const char *name,
-                                                         int *type);

The function returns the value of the field named name in the -record pointed to by rec. The returned value is internal and needs -to be duplicated if you want to keep it around. type works as with -bro_record_get_nth_val(), see there for more details.

rec :

record handle.

name :

field name.

type :

value-result argument for the expected/actual type of the value.

Returns :

pointer to queried value on success, NULL on error.


bro_record_set_nth_val ()

int                 bro_record_set_nth_val              (BroRecord *rec,
-                                                         int num,
-                                                         int type,
-                                                         const char *type_name,
-                                                         const void *val);

The function replaces the num'th value of the record pointed to -by rec, expected to be of type. All values are copied internally -so what val points to stays unmodified. The value of type implies -what result must be pointing to. See the manual for details. -If you want to indicate a type specialized from type, use -type_name to give its name, otherwise pass NULL for type_name.

rec :

record handle.

num :

field index, starting from 0.

type :

expected type of the value.

type_name :

optional name of specialized type.

val :

pointer to new val.

Returns :

TRUE on success, FALSE on error.


bro_record_set_named_val ()

int                 bro_record_set_named_val            (BroRecord *rec,
-                                                         const char *name,
-                                                         int type,
-                                                         const char *type_name,
-                                                         const void *val);

The function replaces the value named name in the record pointed to -by rec, expected to be of type. All values are copied internally -so what val points to stays unmodified. The value of type implies -what result must be pointing to. See the manual for details. -If you want to indicate a type specialized from type, -use type_name to give its name, otherwise pass NULL for type_name.

rec :

record handle.

name :

field name.

type :

expected type of the value.

type_name :

optional name of specialized type.

val :

pointer to new val.

Returns :

TRUE on success, FALSE on error.


BroTableCallback ()

int                 (*BroTableCallback)                 (void *key,
-                                                         void *val,
-                                                         void *user_data);

This is the signature of callbacks used when iterating over all -elements stored in a BroSet.

key :

val :

a pointer to an element in the set.

user_data :

user data passed through.

Returns :

TRUE if iteration should continue, FALSE if done.


bro_table_new ()

BroTable*           bro_table_new                       (void);

Returns :


bro_table_free ()

void                bro_table_free                      (BroTable *tbl);

tbl :


bro_table_insert ()

int                 bro_table_insert                    (BroTable *tbl,
-                                                         int key_type,
-                                                         const void *key,
-                                                         int val_type,
-                                                         const void *val);

tbl :

key_type :

key :

val_type :

val :

Returns :


bro_table_find ()

void*               bro_table_find                      (BroTable *tbl,
-                                                         const void *key);

tbl :

key :

Returns :


bro_table_get_size ()

int                 bro_table_get_size                  (BroTable *tbl);

tbl :

Returns :


bro_table_get_types ()

void                bro_table_get_types                 (BroTable *tbl,
-                                                         int *key_type,
-                                                         int *val_type);

tbl :

key_type :

val_type :


bro_table_foreach ()

void                bro_table_foreach                   (BroTable *tbl,
-                                                         BroTableCallback cb,
-                                                         void *user_data);

tbl :

cb :

user_data :


BroSetCallback ()

int                 (*BroSetCallback)                   (void *val,
-                                                         void *user_data);

val :

user_data :

Returns :


bro_set_new ()

BroSet*             bro_set_new                         (void);

Returns :


bro_set_free ()

void                bro_set_free                        (BroSet *set);

set :


bro_set_insert ()

int                 bro_set_insert                      (BroSet *set,
-                                                         int type,
-                                                         const void *val);

set :

type :

val :

Returns :


bro_set_find ()

int                 bro_set_find                        (BroSet *set,
-                                                         const void *key);

set :

key :

Returns :


bro_set_get_size ()

int                 bro_set_get_size                    (BroSet *set);

set :

Returns :


bro_set_get_type ()

void                bro_set_get_type                    (BroSet *set,
-                                                         int *type);

set :

type :


bro_set_foreach ()

void                bro_set_foreach                     (BroSet *set,
-                                                         BroSetCallback cb,
-                                                         void *user_data);

set :

cb :

user_data :


bro_conn_set_packet_ctxt ()

void                bro_conn_set_packet_ctxt            (BroConn *bc,
-                                                         int link_type);

The function sets the packet context for bc for future BroPackets -handled by this connection.

bc :

connection handle.

link_type :

libpcap DLT linklayer type.


bro_conn_get_packet_ctxt ()

void                bro_conn_get_packet_ctxt            (BroConn *bc,
-                                                         int *link_type);

The function returns bc's current packet context through link_type.

bc :

connection handle.

link_type :

result pointer for libpcap DLT linklayer type.


bro_packet_new ()

BroPacket*          bro_packet_new                      (const struct pcap_pkthdr *hdr,
-                                                         const u_char *data,
-                                                         const char *tag);

The function creates a new BroPacket by copying hdr and data internally. -Release the resulting packet using bro_packet_free().

hdr :

pointer to libpcap packet header.

data :

pointer to libpcap packet data.

tag :

pointer to ASCII tag (0 for no tag).

Returns :


bro_packet_clone ()

BroPacket*          bro_packet_clone                    (const BroPacket *packet);

packet :

packet to clone.

Returns :

a copy of packet, or NULL on error.


bro_packet_free ()

void                bro_packet_free                     (BroPacket *packet);

The function releases all memory occupied by a packet previously allocated -using bro_packet_new().

packet :

packet to release.


bro_packet_send ()

int                 bro_packet_send                     (BroConn *bc,
-                                                         BroPacket *packet);

The function sends packet to the Bro peer connected via bc.

bc :

connection on which to send packet.

packet :

packet to send.

Returns :

TRUE if successful, FALSE otherwise.


bro_util_current_time ()

double              bro_util_current_time               (void);

Returns :

the current system time as a double, in seconds, suitable -for passing to bro_event_add_time().


bro_util_timeval_to_double ()

double              bro_util_timeval_to_double          (const struct timeval *tv);

tv :

pointer to timeval structure.

Returns :

a double encoding the timestamp given in tv in a floating -point double, with the fraction of a second between 0.0 and 1.0.


PrevHomeNext
Broccoli API ReferenceUpAppendix
\ No newline at end of file diff --git a/aux/broccoli/docs/html/c20.html b/aux/broccoli/docs/html/c20.html deleted file mode 100644 index d903a4f4f9..0000000000 --- a/aux/broccoli/docs/html/c20.html +++ /dev/null @@ -1,330 +0,0 @@ - -Introduction
Broccoli: The Bro Client Communications Library
PrevNext

Chapter 1. Introduction

Table of Contents
1.1. What is Broccoli?
1.2. Why do I care?

Welcome! You're looking at the Broccoli manual. Thanks for reading this. -


1.1. What is Broccoli?

Broccoli is the BRO Client - COmmunications LIbrary. It allows - you to write applications that speak the communication protocol of the - Bro intrusion detection system. - In this document, we assume that you are familiar with the basic concepts - of Bro. If you need a refresher, please have a look at the - original paper, - the user manual, - and the material on bro-ids.org in general. -


1.2. Why do I care?

Having a single IDS on your network is good, but things become a lot more interesting - when you can communicate information among multiple vantage points in your network. - Bro agents can communicate with other Bro agents, sending and receiving events and - other state information. In the Bro context this is particularly interesting because - it means that you can build sophisticated policy-controlled distributed event - management systems. -

Broccoli enters the picture when it comes to integrating components that are not - Bro agents themselves. Broccoli lets you create applications that can speak the Bro - communication protocol. You can compose, send, request, and receive events. - You can register your own event handlers. You can talk to other Broccoli - applications or Bro agents — Bro agents cannot tell whether they are talking - to another Bro or a Broccoli application. Broccoli allows you to integrate applications - of your choosing into a distributed policy-controlled event management system. - Broccoli is intended - to be portable: it should build on Linux, the BSDs, Solaris, and Windows - (in the MinGW environment). -

Unlike other distributed IDSs, Bro does not assume a strict sensor–manager - hierarchy in the information flow. Instead, Bro agents can request delivery of - arbitrary events - from other instances. When an event is triggered in a Bro agent, it checks - whether any connected agents have requested notification of this event, - and send a copy of the event, including the event arguments. - Recall that in Bro, an event handler is essentially a function defined in - the Bro language, and an event materializes through invocation of an event handler. - Each remote agent can define its own event handlers. -

Broccoli applications will typically do one or more of the following: -

  • Configuration/Management Tasks: the Broccoli application - is used to configure remotely running Bros without the need for a restart. -

  • Interfacing other Systems: the Broccoli application - is used to convert Bro events to other alert/notice formats, for into - syslogd entries. -

  • Host-based Sensor Feeds into Bro: the Broccoli - application reports events based on host-based activity generated in - kernel space or user space applications. -


PrevHomeNext
Broccoli: The Bro Client Communications Library Installing Broccoli
\ No newline at end of file diff --git a/aux/broccoli/docs/html/c54.html b/aux/broccoli/docs/html/c54.html deleted file mode 100644 index b80639b22c..0000000000 --- a/aux/broccoli/docs/html/c54.html +++ /dev/null @@ -1,227 +0,0 @@ - -Installing Broccoli
Broccoli: The Bro Client Communications Library
PrevNext

Chapter 2. Installing Broccoli

The installation process will hopefully be painless: Broccoli is installed from source - using the usual ./configure <options> && make && make install - routine after extraction of the tarball. Or if you're on a Linux systems supporting - RPMs, we provide those as well. -

The relevant configuration options to pass to configure are: -

  • --prefix=<DIR>: sets the installation root to DIR. - The default is to install below /usr/local.

  • --enable-debug: enables debugging output. - Please refer to the Broccoli debugging - section for details on configuring and using debugging output. -

  • --with-configfile=<FILE>: use FILE as location of configuration file. - See the section on configuration files - below for more on this. -

  • --with-openssl=<DIR>: use the OpenSSL installation below DIR.

  • --with-kerberos=<DIR>: use the Kerberos installation below DIR.

-

After installation, you'll find the library in shared and static versions in <prefix>/lib - the header file for compilation in <prefix>/include, and the - manual in HTML below <prefix>/share/gtk-doc/html/broccoli. -

When installing from source, you can get rid of the installation using make uninstall. -


PrevHomeNext
Introduction Using Broccoli
\ No newline at end of file diff --git a/aux/broccoli/docs/html/c84.html b/aux/broccoli/docs/html/c84.html deleted file mode 100644 index 66175af506..0000000000 --- a/aux/broccoli/docs/html/c84.html +++ /dev/null @@ -1,4038 +0,0 @@ - -Using Broccoli
Broccoli: The Bro Client Communications Library
PrevNext

Chapter 3. Using Broccoli


3.1. Obtaining information about your build using broccoli-config

Similarly to many other software packages, the Broccoli distribution - provides a script that you can use to obtain details about your - Broccoli setup. The script currently provides the following flags: -

  • --build prints the name of the machine the build was - made on, when, and whether debugging support was enabled or not.

  • --prefix prints the directory in the filesystem - below which Broccoli was installed.

  • --version prints the version of the distribution - you have installed.

  • --libs prints the flags to pass to the - linker in order to link in the Broccoli library.

  • --cflags prints the flags to pass to the - compiler in order to properly include Broccoli's header file.

  • --config prints the location of the system-wide - config file your installation will use.

-

The --cflags and --libs flags - are the suggested way of obtaining the necessary information for integrating - Broccoli into your build environment. It is generally recommended to use - broccoli-config for this purpose, rather than, say, - develop new autoconf tests. - If you use the autoconf/automake - tools, we recommend something along the following lines for your - configure script: -

dnl ##################################################
-dnl # Check for Broccoli
-dnl ##################################################
-AC_ARG_WITH(broccoli-config,
-    AC_HELP_STRING([--with-broccoli-config=FILE], [Use given broccoli-config]),
-    [ brocfg="$withval" ],
-    [ AC_PATH_GENERIC(broccoli,,
-          brocfg="broccoli-config",
-          AC_MSG_ERROR(Cannot find Broccoli: Is broccoli-config in path? Use more fertilizer?)) ])
-
-broccoli_libs=`$brocfg --libs`
-broccoli_cflags=`$brocfg --cflags`
-AC_SUBST(broccoli_libs)
-AC_SUBST(broccoli_cflags)
-      

You can then use the compiler/linker flags in your Makefile.in/ams by - substituting in the values accordingly, which might look as follows: -

CFLAGS = -W -Wall -g -DFOOBAR @broccoli_cflags@
-LDFLAGS = -L/usr/lib/foobar @broccoli_libs@
-      

3.2. Suggestions for instrumenting applications

Often you will want to make existing applications Bro-aware, - that is, instrument them so that they can send and - receive Bro events at appropriate moments in the execution flow. - This will involve modifying an existing code tree, so care needs to - be taken to avoid unwanted side effects. By protecting the instrumented - code with - #ifdef/#endif - statements you can still build the original application, using the - instrumented source tree. The broccoli-config script helps you in doing so because - it already adds -DBROCCOLI to the compiler flags - reported when run with the --cflags option: -

cpk25@localhost:/home/cpk25 > broccoli-config --cflags
--I/usr/local/include -I/usr/local/include -DBROCCOLI
-      

So simply surround all inserted code with a preprocessor check - for BROCCOLI and you will be able to - build the original application as soon as BROCCOLI - is not defined. -


3.3. The Broccoli API

Time for some code. In the code snippets below we will introduce variables - whenever context requires them and not necessarily when C requires them. - The library does not require calling a global initialization function. - In order to make the API known, include broccoli.h: -

#ifdef BROCCOLI
-#include <broccoli.h>
-#endif
-      

A note on Broccoli's memory management philosophy:

Broccoli generally does not release objects you allocate. - The approach taken is "you clean up what you allocate." -


3.3.1. Initialization

Broccoli requires global initialization before most of its - other other functions can be used. Generally, the way to - initialize Broccoli is as follows: -

bro_init(NULL);
-        

The argument to - bro_init() - provides optional initialization context, and may be kept - NULL for normal use. If required, you may - allocate a BroCtx structure locally, - initialize it using - bro_ctx_init(), - fill in additional values as required and and subsequently pass it to - bro_init(): -

BroCtx ctx;
-bro_ctx_init(&ctx);
-/* Make adjustments to the context structure as required... */
-bro_init(&ctx);
-        

The BroCtx structure currently contains - a set of five different callback function pointers. These - are required for thread-safe operation - of OpenSSL (Broccoli itself is thread-safe). If you intend - to use Broccoli in a multithreaded environment, you need to - implement functions and register them via the - BroCtx structure. The O'Reilly book - "Network Security with OpenSSL" by Viega et al. shows how to - implement these callbacks. -

You must call - bro_init() - at the start of your application. Undefined behavior may result - if you don't. -


3.3.2. Data types in Broccoli

Broccoli declares a number of data types in broccoli.h that - you should know about. The more complex ones are kept opaque, while you do get - access to the fields in the simpler ones. The full list is as follows: - -

  • Simple signed and unsigned types: int, uint, - uint32, uint16 and uchar.

  • Connection handles: BroConn, kept opaque.

  • Bro events: BroEvent, kept opaque.

  • Buffer objects: BroBuf, kept opaque. See the separate - section on buffer management for details.

  • Ports: BroPort for network ports, defined as follows: -

    typedef struct bro_port {
    -  uint16       port_num;   /* port number in host byte order */
    -  int          port_proto; /* IPPROTO_xxx */
    -} BroPort;
    -              
  • Records: BroRecord, kept opaque. See the separate - section on record handling for details.

  • Strings (character and binary): BroString, defined as follows: -

    typedef struct bro_string {
    -  int          str_len;
    -  char        *str_val;
    -} BroString;
    -              

    BroStrings are mostly kept transparent for convenience; please have a look at the - string API: -bro_string_init(), -bro_string_set(), -bro_string_set_data(), -bro_string_copy(), -bro_string_cleanup(), and -bro_string_free(). -

  • Tables: BroTable, kept opaque. See the separate - section on table handling for details.

  • Sets: BroSet, kept opaque. See the separate - section on table handling for details.

  • Subnets: BroSubnet, defined as follows: -

    typedef struct bro_subnet
    -{
    -  uint32       sn_net;     /* IP address in network byte order */
    -  uint32       sn_width;   /* Length of prefix to consider. */
    -} BroSubnet;
    -              
-


3.3.3. Managing connections

You can use Broccoli to establish a connection to a remote Bro, or to create a - Broccoli-enabled server application that other Bros will connect to. (This - means that in principle, you can also use Broccoli purely as middleware and - have multiple Broccoli applications communicate directly.) -

- In order to establish a connection to a remote Bro, you first obtain a connection - handle. You then use this connection handle to request events, connect to the - remote Bro, send events, etc. Connection handles are pointers to BroConn - structures, which are kept opaque. Use - bro_conn_new() or - bro_conn_new_str() - to obtain a handle, depending on what parameters are more convenient for - you: the former accepts the IP address and port number as separate numerical - arguments, the latter uses a single string to encode both, in "hostname:port" - format. -

To write a Broccoli-enabled server, you first need to implement the usual - socket() / bind() / - listen() / accept() routine. - Once you have obtained a file descriptor for the new connection from accept(), - you pass it to the third function that returns a BroConn - handle, - bro_conn_new_socket(). - The rest of the connection handling then proceeds as in the client scenario. -

- All three calls accept additional flags for fine-tuning connection behaviour. - These flags are: -

  • BRO_CFLAG_NONE: no functionality. Use when - no flags are desired. -

  • BRO_CFLAG_RECONNECT: - When using this option, Broccoli will attempt to reconnect to the peer - after lost connectivity transparently. Essentially whenever you try to - read from or write to the peer and its connection broke down, a - full reconnect including complete handshaking is attempted. You can check - whether the connection to a peer is alive at any time using - bro_conn_alive(). -

  • BRO_CFLAG_ALWAYS_QUEUE: - When using this option, Broccoli will queue any events you send for - later transmission when a connection is currently down. Without using this - flag, any events you attempt to send while a connection is down get dropped - on the floor. Note that Broccoli maintains a maximum queue size per connection - so if you attempt to send lots of events while the connection is down, the - oldest events may start to get dropped nonetheless. Again, you can check - whether the connection is currently okay by using - bro_conn_alive(). -

  • BRO_CFLAG_DONTCACHE: - When using this option, Broccoli will ask the peer not to use caching on - the objects it sends to us. This is the default, and the flag need not - normally be used. It is kept to maintain backward compatibility. -

  • BRO_CFLAG_CACHE: - When using this option, Broccoli will ask the peer to use caching on - the objects it sends to us. Caching is normally disabled. -

  • BRO_CFLAG_YIELD: When - using this option, - bro_conn_process_input() - processes at most one event at a time and then - returns. -

- -

By obtaining a connection handle, you do not also establish a connection right - away. This is done using - bro_conn_connect(). - The main reason for this is to allow you to subscribe to events - (using - bro_event_registry_add(), - see below) - before establishing the connection. Upon returning from - bro_conn_connect() - you are guaranteed to receive all instances of the event types you have - requested, while later on during the connection some time may elapse between - the issuing of a request for events and the processing of that request at the - remote end. - Connections are established via TCP, optionally using SSL encryption. See - "Configuring encrypted communication" below for more - information on setting up enncryption. - The port numbers Bro agents and Broccoli applications listen on can vary from peer - to peer. -

Finally, bro_conn_delete() - terminates a connection and releases all resources associated with it. - You can create as many connections as you like, to one or more peers. - You can obtain the file descriptor of a connection using - bro_conn_get_fd(). -

char host_str = "bro.yourorganization.com";
-int port      = 1234;
-struct hostent *host;
-BroConn *bc;
-
-if (! (host = gethostbyname(host_str)) ||
-    ! (host->h_addr_list[0])) {
-	/* Error handling -- could not resolve host */
-}
-
-/* In this example, we obtain a connection handle, then register event handlers,
- * and finally connect to the remote Bro.
- *
- * First obtain a connection handle:
- */
-if (! (bc = bro_conn_new((struct in_addr*) host->h_addr_list[0], htons(port), BRO_CFLAG_NONE))) {
-	/* Error handling  - could not get connection handle */
-}
-
-/* Register event handlers:
- */
-bro_event_registry_add(bc, "foo", bro_foo_handler, NULL);
-/* ... */
-
-/* Now connect to the peer:
- */
-if (! bro_conn_connect(bc)) {
-	/* Error handling - could not connect to remote Bro. */
-}
-
-/* Send and receive events ... */
-
-/* Disconnect from Bro and clean up connection */
-bro_conn_delete(bc);
-        

Or simply use the string-based version: -

char host_str = "bro.yourcompany.com:1234";
-BroConn *bc;
-
-/* In this example we don't request any events from the peer, but
- * we ask it not to use the serialization cache.
- *
- * Again, first obtain a connection handle:
- */
-if (! (bc = bro_conn_new_str(host_str, BRO_CFLAG_DONTCACHE))) {
-	/* Error handling  - could not get connection handle */
-}
-
-/* Now connect to the peer:
- */
-if (! bro_conn_connect(bc)) {
-	/* Error handling - could not connect to remote Bro. */
-}
-
-/* ... */
-        

3.3.4. Connection classes

When you want to establish connections from multiple Broccoli applications - with different purposes, the peer needs a means to understand what kind of - application each connection belongs to. The real meaning of "kind of application" - here is "sets of event types to request", because depending on the class of - an application, the peer will likey want to receive different types of events. -

Broccoli lets you set the class of a connection using - bro_conn_set_class(). - When using this feature, you need to call that function before issuing a - bro_conn_connect(), - since the class of a connection is determined at connection startup. -

if (! (bc = bro_conn_new_str(host_str, BRO_CFLAG_DONTCACHE))) {
-	/* Error handling  - could not get connection handle */
-}
-
-/* Set class of this connection: */
-bro_conn_set_class(bc, "syslog");
-
-if (! bro_conn_connect(bc)) {
-	/* Error handling - could not connect to remote Bro. */
-}
-        

If your peer is a Bro node, you need to match the chosen connection class in - the remote Bro's Remote::destinations configuration. - See below for how to do this. - Finally, in order to obtain the class of a connection as indicated by the remote side, use - bro_conn_get_peer_class(). -


3.3.5. Composing and sending events

In order to send an event to the remote Bro agent, you first create - an empty event structure with the name of the event, then add parameters - to pass to the event handler at the remote agent, and then send off the - event. -

Bro peers ignore unrequested events. -

You need to make sure that the remote Bro agent is interested in receiving - the events you send. This interest is expressed in policy configuration. - We'll explain this in more detail below - and for now assume that our remote peer is configured to receive the - events we send. -

Let's assume we want to request a report of all connections a remote - Bro currently keeps state for that match a given destination port and - host name and that have amassed more than a certain number of bytes. - The idea is to send an event to the remote Bro that contains the - query, identifiable through a request ID, and have the remote Bro - answer us with remote_conn events - containing the information we asked for. The definition of our - requesting event could look as follows in the Bro policy: -

event report_conns(req_id: int, dest_host: string, dest_port: port, min_size: count);
-        

First, create a new event: -

BroEvent *ev;
-
-if (! (ev = bro_event_new("report_conns"))) {
-	/* Error handling - could not allocate new event. */
-}
-        

Now we need to add parameters to the event. The sequence and types must - match the event handler declaration — check the Bro policy to make - sure they match. The function to use for adding parameter values is - bro_event_add_val() - All values are passed as pointer arguments and are copied internally, - so the object you're pointing to stays unmodified at all times. You clean - up what you allocate. In order to indicate the type of the value passed into the - function, you need to pass a numerical type identifier along as well. - Table 1 lists the value types that Broccoli supports along with - the type identifier and data structures to point to. -

Table 3-1. Types, type tags, and data structures for event parameters in Broccoli

TypeType tagData type pointed to
BooleanBRO_TYPE_BOOLint
Integer valueBRO_TYPE_INTint
Counter (nonnegative integers)BRO_TYPE_COUNTuint32
Enums (enumerated values)BRO_TYPE_ENUMint (see also the description of - bro_event_add_val()'s - type_name argument below)
Floating-point numberBRO_TYPE_DOUBLEdouble
TimestampBRO_TYPE_TIMEdouble (see also - bro_util_timeval_to_double() and - bro_util_current_time())
Time intervalBRO_TYPE_INTERVALdouble
Strings (text and binary)BRO_TYPE_STRINGBroString (see also the family of bro_string_xxx() functions)
Network portsBRO_TYPE_PORTBroPort, with the port number in host byte order
IPv4 addressBRO_TYPE_IPADDRuint32, in network byte order
IPv4 networkBRO_TYPE_NETuint32, in network byte order
IPv4 subnetBRO_TYPE_SUBNETBroSubnet, with the sn_net member in network byte order
RecordBRO_TYPE_RECORDBroRecord (see also the family of - bro_record_xxx() functions and their - explanation below)
TableBRO_TYPE_TABLEBroTable (see also the family of - bro_table_xxx() functions and their - explanation below)
RecordBRO_TYPE_SETBroSet (see also the family of - bro_set_xxx() functions and their - explanation below)

Knowing these, we can now compose a - request_connections event: -

BroString dest_host;
-BroPort dest_port;
-uint32 min_size;
-int req_id = 0;
-
-bro_event_add_val(ev, BRO_TYPE_INT, NULL, &req_id);
-req_id++;
-
-bro_string_set(&dest_host, "desthost.destdomain.com");
-bro_event_add_val(ev, BRO_TYPE_STRING, NULL, &dest_host);
-bro_string_cleanup(&dest_host);
-
-dest_port.dst_port = 80;
-dest_port.dst_proto = IPPROTO_TCP;
-bro_event_add_val(ev, BRO_TYPE_PORT, NULL, &dest_port);
-
-min_size = 1000;
-bro_event_add_val(ev, BRO_TYPE_COUNT, NULL, &min_size);
-        

The third argument to - bro_event_add_val() - lets you specify a specialization of the types listed in - Table 1. This is generally not necessary - except for one situationn: When using BRO_TYPE_ENUM. You currently - cannot define - a Bro-level enum type in Broccoli, and thus when sending an enum value, you - have to specify the type of the enum along with the value. For example, in order - to add an instance of enum transport_type defined in - Bro's bro.init, you would use -
int transport_proto = 2;
-/* ... */
-bro_event_add_val(ev, BRO_TYPE_ENUM, "transport_proto", &transport_proto);
-	    
- to get the equivalent of "udp" on the remote side. The same system is used - to point out type names when calling - bro_event_set_val(), - bro_record_add_val(), - bro_record_set_nth_val(), and - bro_record_set_named_val(). -

All that's left to do now is to send off the event. For this, use - bro_event_send() - and pass it the connection handle and the event. The function returns - TRUE when the event could be sent right away or if - it was queued for later delivery. FALSE is returned - on error. If the event get queued, this does not indicate an error — - likely the connection was just not - ready to send the event at this point. Whenever you call - bro_event_send(), - Broccoli attempts to send as much of an existing event queue as possible. - Again, the event is copied internally to make it easier for you to - send the same event repeatedly. You clean up what you allocate. -

bro_event_send(bc, ev);
-bro_event_free(ev);
-        

Two other functions may be useful to you: - bro_event_queue_length() - tells you how many events are currently queued, and - bro_event_queue_flush() - attempts to flush the current event queue and returns the number of events that do remain - in the queue after the flush. Note: you do not normally need - to call this function, queue flushing is attempted every time you send an event. -


3.3.6. Receiving events

Receiving events is a little more work because you need to -

  1. tell Broccoli what to do when requested events arrive,

  2. let the remote Bro agent know that you would like to receive those events,

  3. find a spot in the code path suitable for extracting and processing arriving events.

Each of these steps is explained in the following sections. -


3.3.6.1. Implementing event callbacks

When Broccoli receives an event, it tries to dispatch the event to callbacks - registered for that event type. The place where callbacks get registered is - called the callback registry. Any callbacks registered for the arriving - event's name are invoked with the parameters shipped with the event. There - are two styles of argument passing to the event callbacks. - Which one is better suited depends on your application. -

  • Expanded argument passing. Each event argument - is passed via a pointer to the callback. This makes best sense when you - know the type of the event and of its arguments, because it provides you - immediate access to arguments as when using a normal C function. -

    In order to register a callback with expanded argument passing, use - bro_event_registry_add() - and pass it the connection handle, the name of the event for which you - register the callback, the callback itself that matches the signature - of the BroEventFunc type, and any user data (or - NULL) you want to see passed to the callback on - each invocation. The callback's type is defined rather generically as follows: -

    typedef void (*BroEventFunc) (BroConn *bc, void *user_data, ...);
    -                

    It requires a connection handle as its first argument - and a pointer to user-provided callback data as the second argument. - Broccoli will pass the connection handle of the connection on which the event - arrived through to the callback. BroEventFuncs - are variadic, because each callback you provide is directly invoked with - pointers to the parameters of the event, in a format directly usable in C. - All you need to know is what type to point to in order to receive the - parameters in the right layout. Refer to Table 1 - again for a summary of those types. Record types are more involved and are - addressed in more detail below. -

    Note that all parameters are passed to the - callback as pointers, even elementary types such as ints - that would normally be passed directly. - Also note that Broccoli manages the lifecycle of event parameters - and therefore you do not have to clean them up inside - the event handler. -

    Continuing our example, we will want to process the connection reports - that contain the responses to our report_conns - event. Let's assume those look as follows: -

    event remote_conn(req_id: int, conn: connection);
    -                

    The reply events contain the request ID so we can associate requests - with replies, and a connection record (defined in bro.init - in Bro. (It'd be nicer to report all replies in a single event but we'll - ignore that for now.) For this event, our callback would look like this: -

    void remote_conn_cb(BroConn *bc, void *user_data, int *req_id, BroRecord *conn);
    -                

    Once more, you clean up what you allocate, and since you never allocated the - space these arguments point to, you also don't clean them up. Finally, we register - the callback using - bro_event_registry_add(): -

    bro_event_registry_add(bc, "remote_conn", remote_conn_cb, NULL);
    -	        

    In this case we have no additional data to be passed into the - callback, so we use NULL for the last argument. - If you have multiple events you are interested in, register - each one in this fashion. -

  • Compact argument passing. This is designed for - situations when you have to determine how to handle different types of - events at runtime, for example when writing language bindings or when - implementing generic event handlers for multiple event types. - The callback is passed a connection handle and the - user data as above but is only passed one additional pointer, to a - BroEvMeta structure. This structure contains all metadata - about the event, including its name, timestamp (in UTC) of creation, - number of arguments, the arguments' - types (via type tags as listed in Table 1), - and the arguments themselves. -

    In order to register a callback with compact argument passing, use - bro_event_registry_add_compact() - and pass it similar arguments as you'd use with - bro_event_registry_add(). - The callback's type is defined as follows: -

    typedef void (*BroCompactEventFunc) (BroConn *bc, void *user_data, BroEvMeta *meta);
    -                

    As before, Broccoli manages the lifecycle of event parameters. - You do not have to clean up the BroEvMeta - structure or any of its contents. -

    Below is sample code for extracting the arguments form the BroEvMeta - structure, using our running example. This is still written with the assumption - that we know the types of the arguments, but note that this is not a requirement - for this style of callback. -

    void remote_conn_cb(BroConn *bc, void *user_data, BroEvMeta *meta)
    -{
    -	int *req_id;
    -	BroRecord *rec;
    -
    -	/* For demonstration, print out the event's name: */
    -
    -	printf("Handling a %s event.\n", meta->ev_name);
    -
    -	/* Sanity-check the number of arguments: */
    -
    -	if (meta->ev_numargs != 2)
    -		{ /* error */ }
    -
    -	/* Sanity-check the argument types: */
    -
    -	if (meta->ev_args[0].arg_type != BRO_TYPE_INT)
    -		{ /* error */ }
    -
    -	if (meta->ev_args[1].arg_type != BRO_TYPE_RECORD)
    -		{ /* error */ }
    -
    -	req_id = (int *) meta->ev_args[0].arg_data;
    -	rec = (BroRecord *) meta->ev_args[1].arg_data;
    -
    -	/* ... */
    -}
    -                

    Finally, register the callback using - bro_event_registry_add_compact(): -

    bro_event_registry_add_compact(bc, "remote_conn", remote_conn_cb, NULL);
    -	        
-


3.3.6.2. Requesting event delivery

At this point, Broccoli knows what to do with the requested events upon - arrival. What's left to do is to let the remote Bro know that you - would like to receive the events for which you registered. If you haven't - yet called bro_conn_connect(), - then there is nothing to do, since that function will request the registered - events anyway. Once connected, you can still request events. To do so, call - bro_event_registry_request(): -

bro_event_registry_request(bc);
-          

This mechanism also implies that no unrequested events will be delivered - to us (and if that happened for whatever reason, the event would simply - be dropped on the floor). -

Note that at the moment you cannot unrequest events, nor - can you request events based on predicates on the values of the - events' arguments.


3.3.6.3. Reading events from the connection handle

At this point the remote Bro will start sending you the requested events - once they are triggered. What is left to do is to read the arriving events - from the connection and trigger dispatching them to the registered callbacks. -

If you are writing a new Bro-enabled application, this is easy, and you can - choose among two approaches: polling explicitly via Broccoli's API, or using - select() on the file handle associated with a BroConn. - The former case is particularly straightforward; all you need to do is - call - bro_conn_process_input(), - which will go off and check if any events have arrived and if so, dispatch - them accordingly. This function does not block — if no events have - arrived, then the call will return immediately. For more fine-grained control - over your I/O handling, you will probably want to use - bro_conn_get_fd() - to obtain the file descriptor of your connection and then incorporate that - in your standard FD_SET/select() - code. Once you have determined that data in fact are ready to be read from - the obtained file descriptor, you can then try another - bro_conn_process_input(), - this time knowing that it'll find something to dispatch. -

As a side note, if you don't process arriving events frequently enough, - then TCP's flow control will start to slow down the sender until eventually - events will queue up and be dropped at the sending end. -


3.3.7. Handling records

Broccoli supports record structures, i.e., types that pack a set of values - together, placing each value into its own field. In Broccoli, the way you handle - records is somewhat similar to events: - after creating an empty record (of opaque type BroRecord, you can - iteratively add fields and values to it. The main difference is that you must specify a - field name with the value; each value in a record can be identified both by position - (a numerical index starting from zero), and by field name. You can retrieve vals - in a record by field index or field name. You can also reassign values. - There is no explicit, IDL-style definition of record types. You define the type of - a record implicitly by the sequence of field names and the sequence of the types - of the values you put into the record. -

Note that all fields in a record must be assigned before it can be shipped. -

The API for record composition consists of - bro_record_new(), - bro_record_free(), - bro_record_add_val(), - bro_record_set_nth_val(), and - bro_record_set_named_val(). -

On records that use field names, the names of individual fields can be extracted using - bro_record_get_nth_name(). - Extracting values from a record is done using - bro_record_get_nth_val() and - bro_record_get_named_val(). - The former allows numerical indexing of the fields in the record, the latter provides - name-based lookups. Both need to be passed the record you want to extract a value from, - the index or name of the field, and either a pointer to an int holding a - BRO_TYPE_xxx value (see again Table 1 for a - summary of those types) or NULL. The pointer, if not - NULL, serves two purposes: type checking and type retrieval. - Type checking is performed if the value of the int upon calling the - functions is not BRO_TYPE_UNKNOWN. The type tag of the requested record - field then has to match the type tag stored in the int, otherwise - NULL is returned. If the int stores BRO_TYPE_UNKNOWN - upon calling, no type-checking is performed. In both cases, - the actual type of the - requested record field is returned in the int pointed to upon - return from the function. Since you have no guarantees of the type of the value - upon return if you pass NULL as the int pointer, - this is a bad idea and either BRO_TYPE_UNKNOWN or another type value - should always be used. -

For example, you could extract the value of the record field "label", which - we assume should be a string, in the following ways: -

BroRecord *rec = /* obtained somehow */
-BroString *string;
-int type;
-
-/* --- Example 1 --- */
-
-type = BRO_TYPE_STRING; /* Use type-checking, will not accept other type */
-
-if (! (string = bro_record_get_named_val(rec, "label", &type))) {
-	/* Error handling, either there's no field of that value,
-	 * or the value is not of BRO_TYPE_STRING. The actual
-	 * type is now stored in "type".
-	 */
-}
-
-/* --- Example 2 --- */
-
-type = BRO_TYPE_UNKNOWN; /* No type checking, just report the existant type */
-
-if (! (string = bro_record_get_named_val(rec, "label", &type))) {
-	/* Error handling, no field of that name exists. */
-}
-
-printf("The type of the value in field 'label' is %i\n", type);
-
-/* --- Example 3 --- */
-
-if (! (string = bro_record_get_named_val(rec, "label", NULL))) {
-	/* Error handling, no field of that name exists. */
-}
-
-/* We now have a value, but we can't really be sure of its type */
-
-        

Record fields can be records, for example in the case of Bro's standard - connection record type. In this case, in order to get to a nested record, you - use BRO_TYPE_RECORD: -

void remote_conn_cb(BroConn *bc, int *req_id, BroRecord *conn) {
-	BroRecord *conn_id;
-	int type = BRO_TYPE_RECORD;
-	if (! (conn_id = bro_record_get_named_val(conn, "id", &type))) {
-		/* Error handling */
-	}
-}
-        

3.3.8. Handling tables

Broccoli supports Bro-style tables, i.e., associative containers that map - instances of a key type to an instance of a value type. A given key - can only ever point to a single value. The key type can be - composite, i.e., it may consist of an ordered - sequence ofdifferent types, or it can be direct, - i.e., consisting of a single type (such as an integer, a string, or - a record). -

The API for table manipulation consists of - bro_table_new(), - bro_table_free(), - bro_table_insert(), - bro_table_find(), - bro_table_get_size(), - bro_table_get_types(), - and - bro_table_foreach(). -

Tables are handled similarly to records in that typing is determined - dynamically by the initial key/value pair inserted. The resulting types - can be obtained via - bro_table_get_types(). - Should the types not have been determined yet, BRO_TYPE_UNKNOWN - will result. Also, as with records, - values inserted into the table are copied internally, and the ones passed - to the insertion functions remain unaffected. -

In contrast to records, table entries can be iterated. By passing a function - of signature - BroTableCallback() - and a pointer to data of your choosing, - bro_table_foreach() - will invoke the given function for each key/value pair stored in the table. - Return TRUE to keep the iteration going, or FALSE - to stop it. -

The main thing to know about Broccoli's tables is how to use composite key - types. To avoid additional API calls, you may treat composite key types - exactly as records, though you do not need to use field names when assigning - elements to individual fields. So in order to insert a key/value pair, you - create a record with the needed items assigned to its slots, and use this - record as the key object. In order to differentiate composite index types - from direct ones consisting of a single record, use BRO_TYPE_LIST - as the type of the record, as opposed to BRO_TYPE_RECORD. - Broccoli will then know to interpret the record - as an ordered sequence of items making up a composite element, not a regular - record. -

brotable.c in the test subdirectory of the Broccoli tree - contains an extensive example of using tables with composite as well as direct - indexing types. -


3.3.9. Handling sets

Sets are essentially tables with void value types. - The API for set manipulation consists of - bro_set_new(), - bro_set_free(), - bro_set_insert(), - bro_set_find(), - bro_set_get_size(), - bro_set_get_type(), - and - bro_set_foreach(). -


3.3.10. Associating data with connections

You will often find that you would like to connect data with - a BroConn. Broccoli provides an API that - lets you associate data items with a connection handle through - a string-based key–value registry. The functions of interest - are - bro_conn_data_set(), - bro_conn_data_get(), and - bro_conn_data_del(). - You need to provide a string identifier for a data item and can then use - that string to register, look up, and remove the associated data item. - Note that there is currently no mechanism to trigger a destructor - function for registered data items when the Bro connection is terminated. - You therefore need to make sure that all data items that you do - not have pointers to via some other means are properly released before - calling - bro_disconnect(). -


3.3.11. Configuration files

- Imagine you have instrumented the mother of all server applications. - Building it takes forever, and every now and then you need to change - some of the parameters that your Broccoli code uses, such as the host names - of the Bro agents to talk to. - To allow you to do this quickly, Broccoli comes with support for - configuration files. All you need to do is change the settings in the - file and restart the application (we're considering adding support - for volatile configuration items that are read from the file every - time they are requested). -

A configuration is read from a single configuration file. - This file can be read from two different locations: -

  • The system-wide configuration file. You can obtain the location - of this config file by running broccoli-config --config. -

  • Alternatively, a per-user configuration file stored in ~/.broccoli.conf - can be used. -

- If a user has a configuration file in ~/.broccoli.conf, - it is used exclusively, otherwise the global one is used. -

~/.broccoli.conf will only be used if - it is a regular file, not executable, and neither group nor others have - any permissions on the file. That is, the file's permissions must look - like -rw------- or -r--------. -

In the configuration file, a "#" anywhere starts a comment that runs - to the end of the line. Configuration items are specified as key-value - pairs: -

# This is the Broccoli system-wide configuration file.
-#
-# Entries are of the form <identifier> <value>, where the identifier
-# is a sequence of letters, and value can be a string (including
-# whitespace), and floating point or integer numbers. Comments start
-# with a "#" and go to the end of the line. For boolean values, you
-# may also use "yes", "on", "true", "no", "off", or "false".
-# Strings may contain whitespace, but need to be surrounded by
-# double quotes '"'.
-#
-# Examples:
-#
-Foo/PeerName          mybro.securesite.com
-Foo/PortNum           123
-Bar/SomeFloat         1.23443543
-Bar/SomeLongStr       "Hello World"
-        

You can also have multiple sections in your configuration. Your application can - select a section as the current one, and queries for configuration settings will - then only be answered with values specified in that section. A section is started - by putting its name (no whitespace please) between square brackets. Configuration - items positioned before the first section title are in the default domain and - will be used by default. -

# This section contains all settings for myapp.
-[ myapp ]
-        

You can name identifiers any way you like, but to keep things - organized it is recommended to keep a namespace hierarchy similar - to the file system. In the code, you can query configuration - items using - bro_conf_get_str(), - bro_conf_get_int(), and - bro_conf_get_dbl(). - You can switch between sections using - bro_conf_set_domain(). -


3.3.12. Using dynamic buffers

Broccoli provides an API for dynamically allocatable, growable, shrinkable, - and consumable buffers with BroBufs. You may or may - not find this useful — Broccoli mainly provides this feature in - broccoli.h because these buffers are used internally - anyway and because they are typical case of something that people implement - themselves over and over again, for example to collect a set of data before - sending it through a file descriptor, etc. -

The buffers work as follows. The structure implementing a buffer is - called BroBuf. BroBufs are initialized to a default size when created via - bro_buf_new(), - and released using - bro_buf_free(). - Each BroBuf has a content - pointer that points to an arbitrary location between the start of the - buffer and the first byte after the last byte currently - used in the buffer (see buf_off in the illustration below). The content - pointer can seek to arbitrary locations, and data can be copied from and - into the buffer, adjusting the content pointer accordingly. - You can repeatedly append data to end of the buffer's used contents using - bro_buf_append(). -


   <---------------- allocated buffer space ------------>
-   <======== used buffer space ========>
-   ^              ^                    ^               ^                 
-   |              |                    |               |
-   `buf           `buf_ptr             `buf_off        `buf_len
-        

Have a look at the following functions for the details: - bro_buf_new(), - bro_buf_free(), - bro_buf_append(), - bro_buf_consume(), - bro_buf_reset(), - bro_buf_get(), - bro_buf_get_end(), - bro_buf_get_size(), - bro_buf_get_used_size(), - bro_buf_ptr_get(), - bro_buf_ptr_tell(), - bro_buf_ptr_seek(), - bro_buf_ptr_check(), and - bro_buf_ptr_read(). -


3.4. Configuring encrypted communication

Encrypted communication between Bro peers takes place over an SSL connection in - which both endpoints of the connection are authenticated. This requires at least - some PKI in the form of a certificate authority (CA) which you use to issue and sign - certificates for your Bro peers. To facilitate the SSL setup, each peer requires - three documents: a certificate signed by the CA and containing the public key, the - corresponding private key, and a copy of the CA's certificate. -

The OpenSSL command line tool openssl can be used to create all - files neccessary, but its unstructured arguments and poor documentation make it - a pain to use and waste lots of people a lot of time[1]. Therefore, the Bro distribution comes with two scripts, - ca-create and ca-issue. You use the former - once to set up your CA, and the latter to create a certificate for each of the Bro - peers in your infrastructure. -

  • ca-create lets you choose a directory in which the - CA maintains its files. If you set BRO_CA_DIR in your - environment, it will be used for this purpose. After entering a passphrase - for the private key of your CA, you can find the self-signed certificate - of your CA in $BRO_CA_DIR/ca_cert.pem. -

  • ca-issue first requires the directory of the CA, - offering $BRO_CA_DIR if that is found. It asks you for - a prefix for the certificate to be generated, for the passphrase of the - private key of the CA so the new certificate can be signed, for the - passphrase for the new private key, and for a few parameters that make up - the "distinguished name" of the certificate. This name (i.e., the combination - of all the fields you enter a value for) must be unique among all your Bro - peers. Once that is done, you find a new certificate named - <prefix>.pem in your current - directory. This file actually consists of two of the three cryptographic - documents mentioned above, namely the new certificate and the private key. - We refer to it as "certificate" for simplicity. -

- In order to enable encrypted communication for your Broccoli application, you - need to put the CA certificate and the peer certificate in the - /broccoli/ca_cert and - /broccoli/host_cert keys, respectively, in the configuration file. - To quickly enable/disable a certificate configuration, the - /broccoli/use_ssl key can be used. -

This is where you configure whether to use encrypted or unencrypted - connections.

If the /broccoli/use_ssl key is present and set to one of - "yes", "true", "on", or 1, then SSL will be used and an incorrect or - missing certificate configuration will cause connection attempts to fail. - If the key's value is one of "no", "false", "off", or 0, then in no case - will SSL be used and connections will always be cleartext. -

If the /broccoli/use_ssl key is not - present, then SSL will be used if a certificate configuration is - found, and invalid certificates will cause the connection to fail. - If no certificates are configured, cleartext connections will be used. -

In no case does an SSL-enabled setup ever fall back to a cleartext one.

-

/broccoli/use_ssl	   yes
-/broccoli/ca_cert          <path>/ca_cert.pem
-/broccoli/host_cert        <path>/bro_cert.pem
-      

In a Bro policy, you need to load the listen-ssl.bro policy and - redef ssl_ca_certificate and ssl_private_key, - defined in bro.init: -

@load listen-ssl
-
-redef ssl_ca_certificate   = "<path>/ca_cert.pem";
-redef ssl_private_key      = "<path>/bro.pem";
-      

By default, you will be prompted for the passphrase for the private key matching - the public key in your agent's certificate. Depending on your application's user - interface and deployment, this may be inappropriate. You can store the passphrase - in the config file as well, using the following identifier: -

/broccoli/host_pass        foobar
-      

Make sure that access to your configuration is restricted.

If you provide the passphrase this way, it is obviously essential to have - restrictive permissions on the configuration file. Broccoli partially enforces - this. Please refer to the section on - configuration files for details. -


3.5. Configuring event reception in Bro policies

Before a remote Bro will accept your connection and your events, it needs to have its - policy configured accordingly: -

  1. Load either listen-ssl or listen-clear, - depending on whether you want to have encrypted or cleartext communication. Obviously, - encrypting the event exchange is recommended and cleartext should only be used for - early experimental setups. See below for details on how to set up encrypted - communication via SSL. -

  2. You need to find a port to use for the Bros and Broccoli applications that will - listen for connections. Every such agent can use a different port, though default - ports are provided in the Bro policies. - To change the port the Bro agent will be listening on from its default - redefine the listen_port_ssl or - listen_port_clear variables from listen-clear.bro - or listen-ssl.bro, respectively. Have a look at these policies as well - as remote.bro for the default values. Here is the policy - for the unencrypted case: -

    @load listen-clear
    -
    -redef listen_port_clear = 12345/tcp;
    -            

    Including the settings for the cryptographic files introduced in the previous section, - here is the encrypted one: -

    @load listen-ssl
    -
    -redef listen_port_ssl = 12345/tcp;
    -redef ssl_ca_certificate   = "<path>/ca_cert.pem";
    -redef ssl_private_key      = "<path>/bro.pem";
    -            
  3. The policy controlling which peers a Bro agent will communicate with and how this - communication will happen are defined in the destinations table - defined in remote.bro. This table contains entries of type - Destination, whose members mostly provide default values so you do not - need to define everything. You need to come up with a tag for the connection - under which it can be found in the table (a creative one would be "broccoli"), - the IP address of the peer, the pattern of names of the events the Bro will accept - from you, whether you want Bro to connect to your - machine on startup or not, if so, a port to connect to (defaults are - default_port_ssl and default_port_clear, also - defined in remote.bro), a retry timeout, whether to use SSL, - and the class of a connection as set on the Broccoli side via - bro_conn_set_class(). -

    An example could look as follows: -

    
redef Remote::destinations += {
    -	["broping"] = [$host = 127.0.0.1, $class="broping", $events = /ping/, $connect=F, $ssl=F]
    -};
    -            

    This example is taken from broping.bro, the policy the - remote Bro must run when you want to use the broping tool - explained in the section on testing below. - It will allow an agent on the local host to connect and send "ping" events. - Our Bro will not attempt to connect, and incoming connections will be expected - in cleartext. -

-


3.6. Configuring debugging output

If your Broccoli installation was configured with --enable-debug, - Broccoli will report two kinds of debugging information: (i) - function call traces and - (ii) individual debugging messages. Both are enabled by default, but can be adjusted - in two ways. -

  • In the configuration file: in the appropriate section of the configuration - file, you can set the keys /broccoli/debug_messages and - /broccoli/debug_calltrace to on/off - to enable/disable the corresponding output. -

  • In code: you can set the variables - bro_debug_calltrace and - bro_debug_messages - to 1/0 at any time to enable/disable the corresponding output. -

-

By default, debugging output is inactive (even with debuggin support compiled in). - You need to enable it explicitly either in your code by assigning 1 to - bro_debug_calltrace and - bro_debug_messages, - or by enabling it in the configuration file. -


3.7. Test programs

The Broccoli distribution comes with a few small test programs, - located in the test/ directory of the tree. - The most notable one is broping - [2], a mini-version of ping. - It sends "ping" events to a remote Bro agent, expecting "pong" events - in return. It operates in two flavours: one uses atomic types for sending - information across, and the other one uses records. The Bro agent you want - to ping needs to run either the broping.bro or - broping-record.bro policies. You can find these - in the test/ directory of the source tree, and - in <prefix>/share/broccoli in the installed - version. broping.bro is shown below. By default, - pinging a Bro on the same machine is configured. If you want your Bro - to be pinged from another machine, you need to update the - destinations variable accordingly. -

@load listen-clear;
-
-global ping_log = open_log_file("ping");
-
-redef Remote::destinations += {
-	["broping"] = [$host = 127.0.0.1, $events = /ping/, $connect=F, $retry = 60 secs, $ssl=F]
-};
-
-event ping(src_time: time, seq: count)
-{
-        event pong(src_time, current_time(), seq);
-}
-
-event pong(src_time: time, dst_time: time, seq: count)
-{
-        print ping_log, fmt("ping received, seq %d, %f at src, %f at dest, one-way: %f",
-                            seq, src_time, dst_time, dst_time-src_time);
-}
-      

broping sends ping events to Bro. Bro accepts those because they are configured - accordingly in the destinations table. As shown in the policy, ping events - trigger pong events, and broccoli requests delivery of all pong events back to it. - When running broping, you'll see something like this: -

cpk25@localhost:/home/cpk25/devel/broccoli > ./test/broping
-pong event from 127.0.0.1: seq=1, time=0.004700/1.010303 s
-pong event from 127.0.0.1: seq=2, time=0.053777/1.010266 s
-pong event from 127.0.0.1: seq=3, time=0.006435/1.010284 s
-pong event from 127.0.0.1: seq=4, time=0.020278/1.010319 s
-pong event from 127.0.0.1: seq=5, time=0.004563/1.010187 s
-pong event from 127.0.0.1: seq=6, time=0.005685/1.010393 s
-      

Notes

[1]

In other - documents and books on OpenSSL you will find this expressed more politely, using - terms such as "daunting to the uninitiated", "challenging", "complex", "intimidating". -

[2]

Pronunciation is said to be somewhere on the continuum between - "brooping" and "burping".


PrevHomeNext
Installing Broccoli Broccoli API Reference
\ No newline at end of file diff --git a/aux/broccoli/docs/html/index.html b/aux/broccoli/docs/html/index.html deleted file mode 100644 index 75cb71912e..0000000000 --- a/aux/broccoli/docs/html/index.html +++ /dev/null @@ -1,331 +0,0 @@ - -Broccoli: The Bro Client Communications Library

Broccoli: The Bro Client Communications Library

This is documentation for release 1.5 - of Broccoli, compatible with Bro IDS releases of 1.5 - or newer. Broccoli is free software under terms of the BSD license as given - in the License - section. This documentation is always available on the web for download - and online browsing at - http://www.icir.org/christian/broccoli. -

Feedback, patches and bug reports are all welcome, please - join the Bro mailing list. -

Yet Another SRG/ICIR Production — - http://www.cl.cam.ac.uk/Research/SRG — - http://www.icir.org -


  Next
  Introduction
diff --git a/aux/broccoli/docs/html/index.sgml b/aux/broccoli/docs/html/index.sgml deleted file mode 100644 index fec1661891..0000000000 --- a/aux/broccoli/docs/html/index.sgml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/aux/broccoli/docs/html/stylesheet.css b/aux/broccoli/docs/html/stylesheet.css deleted file mode 100644 index be89020cf9..0000000000 --- a/aux/broccoli/docs/html/stylesheet.css +++ /dev/null @@ -1,30 +0,0 @@ -body { margin-left:10px; - margin-right:10px; - margin-top:10px; - margin-bottom:10px; - color:#101010; - background-repeat:no-repeat; - } - -h1.title { text-align:center; } -.abstract { text-align:center; - margin-left:100px; - margin-right:100px; } - -.caption { margin-left:100px; - margin-right:100px; - font-style:italic; } - -.programlisting { font-size:12px; - font-family:courier; - } - -.type { font-size:12px; - font-family:courier; - } - -.mediaobject { text-align:center; } - -span, h1, h2, h3, h4, p, div, table { font-family:arial,helvetica; } - -li { margin-bottom:10px } diff --git a/aux/broccoli/docs/images/caution.gif b/aux/broccoli/docs/images/caution.gif deleted file mode 100644 index cf7c80e772..0000000000 Binary files a/aux/broccoli/docs/images/caution.gif and /dev/null differ diff --git a/aux/broccoli/docs/images/logo.jpg b/aux/broccoli/docs/images/logo.jpg deleted file mode 100644 index 35c50f6c4d..0000000000 Binary files a/aux/broccoli/docs/images/logo.jpg and /dev/null differ diff --git a/aux/broccoli/docs/images/note.gif b/aux/broccoli/docs/images/note.gif deleted file mode 100644 index d731483816..0000000000 Binary files a/aux/broccoli/docs/images/note.gif and /dev/null differ diff --git a/aux/broccoli/docs/images/warning.gif b/aux/broccoli/docs/images/warning.gif deleted file mode 100644 index 2abc1cfb89..0000000000 Binary files a/aux/broccoli/docs/images/warning.gif and /dev/null differ diff --git a/aux/broccoli/docs/mkhtml.in b/aux/broccoli/docs/mkhtml.in deleted file mode 100755 index 126e3dac65..0000000000 --- a/aux/broccoli/docs/mkhtml.in +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh -# -# Hacked version of gtkdoc-mkhtml to allow using different stylesheets. - -usage="\ -Usage: mkhtml MODULE SGML_FILE STYLESHEET" - -if test "x$1" = "x--version"; then - echo "0.10" - exit 0 -fi - -if test $# -lt 2; then - echo "${usage}" 1>&2 - exit 1 -fi - -module=$1 -document=$2 -gtkdocdir=/usr/share/gtk-doc - -# Delete the old index.sgml file, if it exists. -if test -f index.sgml; then - rm -f index.sgml -fi - -stylesheet=$gtkdocdir/gtk-doc.dsl -if test $# -ge 3; then - stylesheet=$3 -fi - -@OPENJADE@ -t sgml -w no-idref -d $stylesheet $document -sed s%href=\"%href=\"$module/% < index.sgml > index.sgml.tmp && mv index.sgml.tmp index.sgml - -echo "timestamp" > ../html.stamp diff --git a/aux/broccoli/docs/stylesheet.css b/aux/broccoli/docs/stylesheet.css deleted file mode 100644 index be89020cf9..0000000000 --- a/aux/broccoli/docs/stylesheet.css +++ /dev/null @@ -1,30 +0,0 @@ -body { margin-left:10px; - margin-right:10px; - margin-top:10px; - margin-bottom:10px; - color:#101010; - background-repeat:no-repeat; - } - -h1.title { text-align:center; } -.abstract { text-align:center; - margin-left:100px; - margin-right:100px; } - -.caption { margin-left:100px; - margin-right:100px; - font-style:italic; } - -.programlisting { font-size:12px; - font-family:courier; - } - -.type { font-size:12px; - font-family:courier; - } - -.mediaobject { text-align:center; } - -span, h1, h2, h3, h4, p, div, table { font-family:arial,helvetica; } - -li { margin-bottom:10px } diff --git a/aux/broccoli/docs/stylesheet.dsl b/aux/broccoli/docs/stylesheet.dsl deleted file mode 100644 index b1b086a0f8..0000000000 --- a/aux/broccoli/docs/stylesheet.dsl +++ /dev/null @@ -1,263 +0,0 @@ - -]> - - - - - -;; These are some customizations to the standard HTML output produced by the -;; Modular DocBook Stylesheets. -;; I've copied parts of a few functions from the stylesheets so these should -;; be checked occasionally to ensure they are up to date. -;; -;; The last check was with version 1.40 of the stylesheets. -;; It will not work with versions < 1.19 since the $shade-verbatim-attr$ -;; function was added then. Versions 1.19 to 1.39 may be OK, if you're lucky! - -;;(define %generate-book-toc% #f) - - -;; The email content should not line wrap in HTML, that looks ugly. -;; (okay there shouldn't be whitespace in there but when people want -;; to avoid an @ they can fill in all kinds of things). -(element email - ($mono-seq$ - (make sequence - (make element gi: "NOBR" - (literal "<") - (make element gi: "A" - attributes: (list (list "HREF" - (string-append "mailto:" - (data (current-node))))) - (process-children)) - (literal ">"))))) - - -;; We want to have some control over how sections are split up into -;; separate pages. -(define (chunk-element-list) - (list (normalize "preface") - (normalize "chapter") - (normalize "appendix") - (normalize "article") - (normalize "glossary") - (normalize "bibliography") - (normalize "index") - (normalize "colophon") - (normalize "setindex") - (normalize "reference") - (normalize "refentry") - (normalize "part") -;; Commented out to prevent splitting up every section into its own document -;; (normalize "sect1") -;; (normalize "section") - (normalize "book") ;; just in case nothing else matches... - (normalize "set") ;; sets are definitely chunks... - )) - - -;; If a Chapter has role="no-toc" we don't generate a table of contents. -;; This is useful if a better contents page has been added manually, e.g. for -;; the GTK+ Widgets & Objects page. (But it is a bit of a hack.) -(define ($generate-chapter-toc$) - (not (equal? (attribute-string (normalize "role") (current-node)) "no-toc"))) - -(define %chapter-autolabel% - ;; Are chapters enumerated? - #t) - -(define %section-autolabel% - ;; Are sections enumerated? - #t) - -(define %use-id-as-filename% #t) - -(define %html-ext% ".html") - -(define %shade-verbatim% #t) - -(define (book-titlepage-separator side) - (empty-sosofo)) - - -(define ($shade-verbatim-attr$) - ;; Attributes used to create a shaded verbatim environment. - (list - (list "WIDTH" "100%") - (list "BORDER" "0") - (list "BGCOLOR" "#eaeaf0"))) - - -;; This overrides the refsect2 definition (copied from 1.20, dbrfntry.dsl). -;; It puts a horizontal rule before each function/struct/... description, -;; except the first one in the refsect1. -(element refsect2 - (make sequence - (if (first-sibling?) - (empty-sosofo) - (make empty-element gi: "HR")) - ($block-container$))) - -;; Override the book declaration, so that we generate a crossreference -;; for the book - -(element book - (let* ((bookinfo (select-elements (children (current-node)) (normalize "bookinfo"))) - (ititle (select-elements (children bookinfo) (normalize "title"))) - (title (if (node-list-empty? ititle) - (select-elements (children (current-node)) (normalize "title")) - (node-list-first ititle))) - (nl (titlepage-info-elements (current-node) bookinfo)) - (tsosofo (with-mode head-title-mode - (process-node-list title))) - (dedication (select-elements (children (current-node)) (normalize "dedication")))) - (make sequence - (html-document - tsosofo - (make element gi: "DIV" - attributes: '(("CLASS" "BOOK")) - (if %generate-book-titlepage% - (make sequence - (book-titlepage nl 'recto) - (book-titlepage nl 'verso)) - (empty-sosofo)) - - (if (node-list-empty? dedication) - (empty-sosofo) - (with-mode dedication-page-mode - (process-node-list dedication))) - - (if (not (generate-toc-in-front)) - (process-children) - (empty-sosofo)) - - (if %generate-book-toc% - (build-toc (current-node) (toc-depth (current-node))) - (empty-sosofo)) - - ;; (let loop ((gilist %generate-book-lot-list%)) - ;; (if (null? gilist) - ;; (empty-sosofo) - ;; (if (not (node-list-empty? - ;; (select-elements (descendants (current-node)) - ;; (car gilist)))) - ;; (make sequence - ;; (build-lot (current-node) (car gilist)) - ;; (loop (cdr gilist))) - ;; (loop (cdr gilist))))) - - (if (generate-toc-in-front) - (process-children) - (empty-sosofo)))) - (make entity - system-id: "index.sgml" - (with-mode generate-index-mode - (process-children)))))) - -;; Mode for generating cross references - -(define (process-child-elements) - (process-node-list - (node-list-map (lambda (snl) - (if (equal? (node-property 'class-name snl) 'element) - snl - (empty-node-list))) - (children (current-node))))) - -(mode generate-index-mode - (element anchor - (if (attribute-string "href" (current-node)) - (empty-sosofo) - (make formatting-instruction data: - (string-append "\less-than-sign;ANCHOR id =\"" - (attribute-string "id" (current-node)) - "\" href=\"" - (href-to (current-node)) - "\"\greater-than-sign; -")))) - - ;; We also want to be able to link to complete RefEntry. - (element refentry - (make sequence - (make formatting-instruction data: - (string-append "\less-than-sign;ANCHOR id =\"" - (attribute-string "id" (current-node)) - "\" href=\"" - (href-to (current-node)) - "\"\greater-than-sign; -")) - (process-child-elements))) - - (default - (process-child-elements))) - -;; For hypertext links for which no target is found in the document, we output -;; our own special tag which we use later to resolve cross-document links. -(element link - (let* ((target (element-with-id (attribute-string (normalize "linkend"))))) - (if (node-list-empty? target) - (make element gi: "GTKDOCLINK" - attributes: (list - (list "HREF" (attribute-string (normalize "linkend")))) - (process-children)) - (make element gi: "A" - attributes: (list - (list "HREF" (href-to target))) - (process-children))))) - - - - -(define ($section-body$) - (make sequence - (make empty-element gi: "BR" - attributes: (list (list "CLEAR" "all"))) - (make element gi: "DIV" - attributes: (list (list "CLASS" (gi))) - ($section-separator$) - ($section-title$) - (process-children)))) - -;; We want to use a stylesheet! -(define %css-decoration% - ;; Enable CSS decoration of elements - #t) -(define %stylesheet% - ;; Name of the stylesheet to use - "stylesheet.css") - - -;; I want my own graphics with admonitions. -(define %admon-graphics% - ;; Use graphics in admonitions? - #t) -(define %admon-graphics-path% - ;; Path to admonition graphics - "images/") - - -;; Some stuff I really didn't like -- italics are -;; pretty hard to read most of the time. Don't use -;; them for parameter names and structure fields. -(element parameter ($mono-seq$)) -(element structfield ($mono-seq$)) - -;; And don't use italics for emphasis either, just -;; use bold text. -(element emphasis - (let* ((class (if (and (attribute-string (normalize "role")) - %emphasis-propagates-style%) - (attribute-string (normalize "role")) - "emphasis"))) - (make element gi: "SPAN" - attributes: (list (list "CLASS" class)) - (if (and (attribute-string (normalize "role")) - (or (equal? (attribute-string (normalize "role")) "strong") - (equal? (attribute-string (normalize "role")) "bold"))) - ($bold-seq$) ($bold-seq$))))) - - - - - diff --git a/aux/broccoli/shtool b/aux/broccoli/shtool deleted file mode 100755 index 4c1a7396fd..0000000000 --- a/aux/broccoli/shtool +++ /dev/null @@ -1,716 +0,0 @@ -#!/bin/sh -## -## GNU shtool -- The GNU Portable Shell Tool -## Copyright (c) 1994-2000 Ralf S. Engelschall -## -## See http://www.gnu.org/software/shtool/ for more information. -## See ftp://ftp.gnu.org/gnu/shtool/ for latest version. -## -## Version 1.4.9 (16-Apr-2000) -## Ingredients: 3/17 available modules -## - -## -## This program is free software; you can redistribute it and/or modify -## it under the terms of the GNU General Public License as published by -## the Free Software Foundation; either version 2 of the License, or -## (at your option) any later version. -## -## This program is distributed in the hope that it will be useful, -## but WITHOUT ANY WARRANTY; without even the implied warranty of -## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -## General Public License for more details. -## -## You should have received a copy of the GNU General Public License -## along with this program; if not, write to the Free Software -## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, -## USA, or contact Ralf S. Engelschall . -## -## Notice: Given that you include this file verbatim into your own -## source tree, you are justified in saying that it remains separate -## from your package, and that this way you are simply just using GNU -## shtool. So, in this situation, there is no requirement that your -## package itself is licensed under the GNU General Public License in -## order to take advantage of GNU shtool. -## - -## -## Usage: shtool [] [ [] []] -## -## Available commands: -## echo Print string with optional construct expansion -## install Install a program, script or datafile -## mkdir Make one or more directories -## -## Not available commands (because module was not built-in): -## mdate Pretty-print modification time of a file or dir -## table Pretty-print a field-separated list as a table -## prop Display progress with a running propeller -## move Move files with simultaneous substitution -## mkln Make link with calculation of relative paths -## mkshadow Make a shadow tree through symbolic links -## fixperm Fix file permissions inside a source tree -## tarball Roll distribution tarballs -## guessos Simple operating system guesser -## arx Extended archive command -## slo Separate linker options by library class -## scpp Sharing C Pre-Processor -## version Generate and maintain a version information file -## path Deal with program paths -## - -if [ $# -eq 0 ]; then - echo "$0:Error: invalid command line" 1>&2 - echo "$0:Hint: run \`$0 -h' for usage" 1>&2 - exit 1 -fi -if [ ".$1" = ".-h" -o ".$1" = ".--help" ]; then - echo "This is GNU shtool, version 1.4.9 (16-Apr-2000)" - echo "Copyright (c) 1994-2000 Ralf S. Engelschall " - echo "Report bugs to " - echo '' - echo "Usage: shtool [] [ [] []]" - echo '' - echo 'Available global :' - echo ' -v, --version display shtool version information' - echo ' -h, --help display shtool usage help page (this one)' - echo ' -d, --debug display shell trace information' - echo '' - echo 'Available [] []:' - echo ' echo [-n] [-e] [ ...]' - echo ' install [-v] [-t] [-c] [-C] [-s] [-m] [-o] [-g]' - echo ' [-e] ' - echo ' mkdir [-t] [-f] [-p] [-m] [ ...]' - echo '' - echo 'Not available (because module was not built-in):' - echo ' mdate [-n] [-z] [-s] [-d] [-f] [-o] ' - echo ' table [-F] [-w] [-c] [-s] ...' - echo ' prop [-p]' - echo ' move [-v] [-t] [-e] [-p] ' - echo ' mkln [-t] [-f] [-s] [ ...] ' - echo ' mkshadow [-v] [-t] [-a] ' - echo ' fixperm [-v] [-t] [ ...]' - echo ' tarball [-t] [-v] [-o ] [-c ] [-d ] [-u' - echo ' ] [-g ] [-e ] [ ...]' - echo ' guessos ' - echo ' arx [-t] [-C] [ ...]' - echo ' slo [-p] -- -L -l [-L -l ...]' - echo ' scpp [-v] [-p] [-f] [-o] [-t] [-M]' - echo ' [-D] [-C] [ ...]' - echo ' version [-l] [-n] [-p] [-s] [-i]' - echo ' [-d] ' - echo ' path [-s] [-r] [-d] [-b] [-m] [-p] [ ...]' - echo '' - exit 0 -fi -if [ ".$1" = ".-v" -o ".$1" = ."--version" ]; then - echo "GNU shtool 1.4.9 (16-Apr-2000)" - exit 0 -fi -if [ ".$1" = ".-d" -o ".$1" = ."--debug" ]; then - shift - set -x -fi -name=`echo "$0" | sed -e 's;.*/\([^/]*\)$;\1;' -e 's;-sh$;;' -e 's;\.sh$;;'` -case "$name" in - echo|install|mkdir ) - # implicit tool command selection - tool="$name" - ;; - * ) - # explicit tool command selection - tool="$1" - shift - ;; -esac -arg_spec="" -opt_spec="" -gen_tmpfile=no - -## -## DISPATCH INTO SCRIPT PROLOG -## - -case $tool in - echo ) - str_tool="echo" - str_usage="[-n] [-e] [ ...]" - arg_spec="0+" - opt_spec="n.e." - opt_n=no - opt_e=no - ;; - install ) - str_tool="install" - str_usage="[-v] [-t] [-c] [-C] [-s] [-m] [-o] [-g] [-e] " - arg_spec="2=" - opt_spec="v.t.c.C.s.m:o:g:e:" - opt_v=no - opt_t=no - opt_c=no - opt_C=no - opt_s=no - opt_m="" - opt_o="" - opt_g="" - opt_e="" - ;; - mkdir ) - str_tool="mkdir" - str_usage="[-t] [-f] [-p] [-m] [ ...]" - arg_spec="1+" - opt_spec="t.f.p.m:" - opt_t=no - opt_f=no - opt_p=no - opt_m="" - ;; - -* ) - echo "$0:Error: unknown option \`$tool'" 2>&1 - echo "$0:Hint: run \`$0 -h' for usage" 2>&1 - exit 1 - ;; - * ) - echo "$0:Error: unknown command \`$tool'" 2>&1 - echo "$0:Hint: run \`$0 -h' for usage" 2>&1 - exit 1 - ;; -esac - -## -## COMMON UTILITY CODE -## - -# determine name of tool -if [ ".$tool" != . ]; then - # used inside shtool script - toolcmd="$0 $tool" - toolcmdhelp="shtool $tool" - msgprefix="shtool:$tool" -else - # used as standalone script - toolcmd="$0" - toolcmdhelp="sh $0" - msgprefix="$str_tool" -fi - -# parse argument specification string -eval `echo $arg_spec |\ - sed -e 's/^\([0-9]*\)\([+=]\)/arg_NUMS=\1; arg_MODE=\2/'` - -# parse option specification string -eval `echo h.$opt_spec |\ - sed -e 's/\([a-zA-Z0-9]\)\([.:+]\)/opt_MODE_\1=\2;/g'` - -# interate over argument line -opt_PREV='' -while [ $# -gt 0 ]; do - # special option stops processing - if [ ".$1" = ".--" ]; then - shift - break - fi - - # determine option and argument - opt_ARG_OK=no - if [ ".$opt_PREV" != . ]; then - # merge previous seen option with argument - opt_OPT="$opt_PREV" - opt_ARG="$1" - opt_ARG_OK=yes - opt_PREV='' - else - # split argument into option and argument - case "$1" in - -[a-zA-Z0-9]*) - eval `echo "x$1" |\ - sed -e 's/^x-\([a-zA-Z0-9]\)/opt_OPT="\1";/' \ - -e 's/";\(.*\)$/"; opt_ARG="\1"/'` - ;; - -[a-zA-Z0-9]) - opt_OPT=`echo "x$1" | cut -c3-` - opt_ARG='' - ;; - *) - break - ;; - esac - fi - - # eat up option - shift - - # determine whether option needs an argument - eval "opt_MODE=\$opt_MODE_${opt_OPT}" - if [ ".$opt_ARG" = . -a ".$opt_ARG_OK" != .yes ]; then - if [ ".$opt_MODE" = ".:" -o ".$opt_MODE" = ".+" ]; then - opt_PREV="$opt_OPT" - continue - fi - fi - - # process option - case $opt_MODE in - '.' ) - # boolean option - eval "opt_${opt_OPT}=yes" - ;; - ':' ) - # option with argument (multiple occurances override) - eval "opt_${opt_OPT}=\"\$opt_ARG\"" - ;; - '+' ) - # option with argument (multiple occurances append) - eval "opt_${opt_OPT}=\"\$opt_${opt_OPT} \$opt_ARG\"" - ;; - * ) - echo "$msgprefix:Error: unknown option: \`-$opt_OPT'" 1>&2 - echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2 - exit 1 - ;; - esac -done -if [ ".$opt_PREV" != . ]; then - echo "$msgprefix:Error: missing argument to option \`-$opt_PREV'" 1>&2 - echo "$msgprefix:Hint: run \`$toolcmdhelp -h' or \`man shtool' for details" 1>&2 - exit 1 -fi - -# process help option -if [ ".$opt_h" = .yes ]; then - echo "Usage: $toolcmdhelp $str_usage" - exit 0 -fi - -# complain about incorrect number of arguments -case $arg_MODE in - '=' ) - if [ $# -ne $arg_NUMS ]; then - echo "$msgprefix:Error: invalid number of arguments (exactly $arg_NUMS expected)" 1>&2 - echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man shtool' for details" 1>&2 - exit 1 - fi - ;; - '+' ) - if [ $# -lt $arg_NUMS ]; then - echo "$msgprefix:Error: invalid number of arguments (at least $arg_NUMS expected)" 1>&2 - echo "$msgprefix:Hint: run \`$toolcmd -h' or \`man shtool' for details" 1>&2 - exit 1 - fi - ;; -esac - -# establish a temporary file on request -if [ ".$gen_tmpfile" = .yes ]; then - if [ ".$TMPDIR" != . ]; then - tmpdir="$TMPDIR" - elif [ ".$TEMPDIR" != . ]; then - tmpdir="$TEMPDIR" - else - tmpdir="/tmp" - fi - tmpfile="$tmpdir/.shtool.$$" - rm -f $tmpfile >/dev/null 2>&1 - touch $tmpfile -fi - -## -## DISPATCH INTO SCRIPT BODY -## - -case $tool in - -echo ) - ## - ## echo -- Print string with optional construct expansion - ## Copyright (c) 1998-2000 Ralf S. Engelschall - ## Originally written for WML as buildinfo - ## - - text="$*" - - # check for broken escape sequence expansion - seo='' - bytes=`echo '\1' | wc -c | awk '{ printf("%s", $1); }'` - if [ ".$bytes" != .3 ]; then - bytes=`echo -E '\1' | wc -c | awk '{ printf("%s", $1); }'` - if [ ".$bytes" = .3 ]; then - seo='-E' - fi - fi - - # check for existing -n option (to suppress newline) - minusn='' - bytes=`echo -n 123 2>/dev/null | wc -c | awk '{ printf("%s", $1); }'` - if [ ".$bytes" = .3 ]; then - minusn='-n' - fi - - # determine terminal bold sequence - term_bold='' - term_norm='' - if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[Bb]'`" != . ]; then - case $TERM in - # for the most important terminal types we directly know the sequences - xterm|xterm*|vt220|vt220*) - term_bold=`awk 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' /dev/null` - term_norm=`awk 'BEGIN { printf("%c%c%c", 27, 91, 109); }' /dev/null` - ;; - vt100|vt100*) - term_bold=`awk 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' /dev/null` - term_norm=`awk 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' /dev/null` - ;; - # for all others, we try to use a possibly existing `tput' or `tcout' utility - * ) - paths=`echo $PATH | sed -e 's/:/ /g'` - for tool in tput tcout; do - for dir in $paths; do - if [ -r "$dir/$tool" ]; then - for seq in bold md smso; do # 'smso' is last - bold="`$dir/$tool $seq 2>/dev/null`" - if [ ".$bold" != . ]; then - term_bold="$bold" - break - fi - done - if [ ".$term_bold" != . ]; then - for seq in sgr0 me rmso reset; do # 'reset' is last - norm="`$dir/$tool $seq 2>/dev/null`" - if [ ".$norm" != . ]; then - term_norm="$norm" - break - fi - done - fi - break - fi - done - if [ ".$term_bold" != . -a ".$term_norm" != . ]; then - break; - fi - done - ;; - esac - if [ ".$term_bold" = . -o ".$term_norm" = . ]; then - echo "$msgprefix:Warning: unable to determine terminal sequence for bold mode" 1>&2 - fi - fi - - # determine user name - username='' - if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[uU]'`" != . ]; then - username="$LOGNAME" - if [ ".$username" = . ]; then - username="$USER" - if [ ".$username" = . ]; then - username="`(whoami) 2>/dev/null |\ - awk '{ printf("%s", $1); }'`" - if [ ".$username" = . ]; then - username="`(who am i) 2>/dev/null |\ - awk '{ printf("%s", $1); }'`" - if [ ".$username" = . ]; then - username='unknown' - fi - fi - fi - fi - fi - - # determine user id - userid='' - if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%U'`" != . ]; then - userid="`(id -u) 2>/dev/null`" - if [ ".$userid" = . ]; then - str="`(id) 2>/dev/null`" - if [ ".`echo $str | grep '^uid[ ]*=[ ]*[0-9]*('`" != . ]; then - userid=`echo $str | sed -e 's/^uid[ ]*=[ ]*//' -e 's/(.*//'` - fi - if [ ".$userid" = . ]; then - userid=`egrep "^${username}:" /etc/passwd 2>/dev/null | \ - sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'` - if [ ".$userid" = . ]; then - userid=`(ypcat passwd) 2>/dev/null | - egrep "^${username}:" | \ - sed -e 's/[^:]*:[^:]*://' -e 's/:.*$//'` - if [ ".$userid" = . ]; then - userid='?' - fi - fi - fi - fi - fi - - # determine host name - hostname='' - if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%h'`" != . ]; then - hostname="`(uname -n) 2>/dev/null |\ - awk '{ printf("%s", $1); }'`" - if [ ".$hostname" = . ]; then - hostname="`(hostname) 2>/dev/null |\ - awk '{ printf("%s", $1); }'`" - if [ ".$hostname" = . ]; then - hostname='unknown' - fi - fi - case $hostname in - *.* ) - domainname=".`echo $hostname | cut -d. -f2-`" - hostname="`echo $hostname | cut -d. -f1`" - ;; - esac - fi - - # determine domain name - domainname='' - if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%d'`" != . ]; then - if [ ".$domainname" = . ]; then - if [ -f /etc/resolv.conf ]; then - domainname="`egrep '^[ ]*domain' /etc/resolv.conf | head -1 |\ - sed -e 's/.*domain//' \ - -e 's/^[ ]*//' -e 's/^ *//' -e 's/^ *//' \ - -e 's/^\.//' -e 's/^/./' |\ - awk '{ printf("%s", $1); }'`" - if [ ".$domainname" = . ]; then - domainname="`egrep '^[ ]*search' /etc/resolv.conf | head -1 |\ - sed -e 's/.*search//' \ - -e 's/^[ ]*//' -e 's/^ *//' -e 's/^ *//' \ - -e 's/ .*//' -e 's/ .*//' \ - -e 's/^\.//' -e 's/^/./' |\ - awk '{ printf("%s", $1); }'`" - fi - fi - fi - fi - - # determine current time - time_day='' - time_month='' - time_year='' - time_monthname='' - if [ ".$opt_e" = .yes -a ".`echo $text | egrep '%[DMYm]'`" != . ]; then - time_day=`date '+%d'` - time_month=`date '+%m'` - time_year=`date '+%Y' 2>/dev/null` - if [ ".$time_year" = . ]; then - time_year=`date '+%y'` - case $time_year in - [5-9][0-9]) time_year="19$time_year" ;; - [0-4][0-9]) time_year="20$time_year" ;; - esac - fi - case $time_month in - 1|01) time_monthname='Jan' ;; - 2|02) time_monthname='Feb' ;; - 3|03) time_monthname='Mar' ;; - 4|04) time_monthname='Apr' ;; - 5|05) time_monthname='May' ;; - 6|06) time_monthname='Jun' ;; - 7|07) time_monthname='Jul' ;; - 8|08) time_monthname='Aug' ;; - 9|09) time_monthname='Sep' ;; - 10) time_monthname='Oct' ;; - 11) time_monthname='Nov' ;; - 12) time_monthname='Dec' ;; - esac - fi - - # expand special ``%x'' constructs - if [ ".$opt_e" = .yes ]; then - text=`echo $seo "$text" |\ - sed -e "s/%B/${term_bold}/g" \ - -e "s/%b/${term_norm}/g" \ - -e "s/%u/${username}/g" \ - -e "s/%U/${userid}/g" \ - -e "s/%h/${hostname}/g" \ - -e "s/%d/${domainname}/g" \ - -e "s/%D/${time_day}/g" \ - -e "s/%M/${time_month}/g" \ - -e "s/%Y/${time_year}/g" \ - -e "s/%m/${time_monthname}/g" 2>/dev/null` - fi - - # create output - if [ .$opt_n = .no ]; then - echo $seo "$text" - else - # the harder part: echo -n is best, because - # awk may complain about some \xx sequences. - if [ ".$minusn" != . ]; then - echo $seo $minusn "$text" - else - echo dummy | awk '{ printf("%s", TEXT); }' TEXT="$text" - fi - fi - ;; - -install ) - ## - ## install -- Install a program, script or datafile - ## Copyright (c) 1997-2000 Ralf S. Engelschall - ## Originally written for shtool - ## - - src="$1" - dst="$2" - - # If destination is a directory, append the input filename - if [ -d $dst ]; then - dst=`echo "$dst" | sed -e 's:/$::'` - dstfile=`echo "$src" | sed -e 's;.*/\([^/]*\)$;\1;'` - dst="$dst/$dstfile" - fi - - # Add a possible extension to src and dst - if [ ".$opt_e" != . ]; then - src="$src$opt_e" - dst="$dst$opt_e" - fi - - # Check for correct arguments - if [ ".$src" = ".$dst" ]; then - echo "$msgprefix:Error: source and destination are the same" 1>&2 - exit 1 - fi - - # Make a temp file name in the destination directory - dstdir=`echo $dst | sed -e 's;[^/]*$;;' -e 's;\(.\)/$;\1;' -e 's;^$;.;'` - dsttmp="$dstdir/#INST@$$#" - - # Verbosity - if [ ".$opt_v" = .yes ]; then - echo "$src -> $dst" 1>&2 - fi - - # Copy or move the file name to the temp name - # (because we might be not allowed to change the source) - if [ ".$opt_C" = .yes ]; then - opt_c=yes - fi - if [ ".$opt_c" = .yes ]; then - if [ ".$opt_t" = .yes ]; then - echo "cp $src $dsttmp" 1>&2 - fi - cp $src $dsttmp || exit $? - else - if [ ".$opt_t" = .yes ]; then - echo "mv $src $dsttmp" 1>&2 - fi - mv $src $dsttmp || exit $? - fi - - # Adjust the target file - # (we do chmod last to preserve setuid bits) - if [ ".$opt_s" = .yes ]; then - if [ ".$opt_t" = .yes ]; then - echo "strip $dsttmp" 1>&2 - fi - strip $dsttmp || exit $? - fi - if [ ".$opt_o" != . ]; then - if [ ".$opt_t" = .yes ]; then - echo "chown $opt_o $dsttmp" 1>&2 - fi - chown $opt_o $dsttmp || exit $? - fi - if [ ".$opt_g" != . ]; then - if [ ".$opt_t" = .yes ]; then - echo "chgrp $opt_g $dsttmp" 1>&2 - fi - chgrp $opt_g $dsttmp || exit $? - fi - if [ ".$opt_m" != . ]; then - if [ ".$opt_t" = .yes ]; then - echo "chmod $opt_m $dsttmp" 1>&2 - fi - chmod $opt_m $dsttmp || exit $? - fi - - # Determine whether to do a quick install - # (has to be done _after_ the strip was already done) - quick=no - if [ ".$opt_C" = .yes ]; then - if [ -r $dst ]; then - if cmp -s $src $dst; then - quick=yes - fi - fi - fi - - # Finally install the file to the real destination - if [ $quick = yes ]; then - if [ ".$opt_t" = .yes ]; then - echo "rm -f $dsttmp" 1>&2 - fi - rm -f $dsttmp - else - if [ ".$opt_t" = .yes ]; then - echo "rm -f $dst && mv $dsttmp $dst" 1>&2 - fi - rm -f $dst && mv $dsttmp $dst - fi - ;; - -mkdir ) - ## - ## mkdir -- Make one or more directories - ## Copyright (c) 1996-2000 Ralf S. Engelschall - ## Originally written for public domain by Noah Friedman - ## Cleaned up and enhanced for shtool - ## - - errstatus=0 - for p in ${1+"$@"}; do - # if the directory already exists... - if [ -d "$p" ]; then - if [ ".$opt_f" = .no ] && [ ".$opt_p" = .no ]; then - echo "$msgprefix:Error: directory already exists: $p" 1>&2 - errstatus=1 - break - else - continue - fi - fi - # if the directory has to be created... - if [ ".$opt_p" = .no ]; then - if [ ".$opt_t" = .yes ]; then - echo "mkdir $p" 1>&2 - fi - mkdir $p || errstatus=$? - else - # the smart situation - set fnord `echo ":$p" |\ - sed -e 's/^:\//%/' \ - -e 's/^://' \ - -e 's/\// /g' \ - -e 's/^%/\//'` - shift - pathcomp='' - for d in ${1+"$@"}; do - pathcomp="$pathcomp$d" - case "$pathcomp" in - -* ) pathcomp="./$pathcomp" ;; - esac - if [ ! -d "$pathcomp" ]; then - if [ ".$opt_t" = .yes ]; then - echo "mkdir $pathcomp" 1>&2 - fi - mkdir $pathcomp || errstatus=$? - if [ ".$opt_m" != . ]; then - if [ ".$opt_t" = .yes ]; then - echo "chmod $opt_m $pathcomp" 1>&2 - fi - chmod $opt_m $pathcomp || errstatus=$? - fi - fi - pathcomp="$pathcomp/" - done - fi - done - exit $errstatus - ;; - -esac - -exit 0 - -##EOF## diff --git a/aux/broccoli/src/Makefile.am b/aux/broccoli/src/Makefile.am deleted file mode 100644 index 8044b37a1f..0000000000 --- a/aux/broccoli/src/Makefile.am +++ /dev/null @@ -1,91 +0,0 @@ -## Process this file with automake to produce Makefile.in - -# A list of all the files in the current directory which can be regenerated -MAINTAINERCLEANFILES = Makefile.in Makefile - -# A list of everything we build locally, for distcheck. -DISTCLEANFILES = bro_parser.c bro_parser.h bro_lexer.c - -# Always include the lexer and parser source and generated output in -# the distribution, regardless of whether we have lex and yacc on -# this system. -# -EXTRA_DIST = bro_parser.y bro_lexer.l bro_lexer.c bro_parser.c bro_parser.h - -# On Solaris, we need to specifically include networking libraries. -# On Windows, we need to specifically include winsock. These are -# handled through the substitution of BRO_LIBADD, which gets defined -# according to the platform detection mechanism in the configure script. -# -# On Windows, we also need extra flags for the linker to build a DLL. -# The approach taken here is described in more detail in -# http://sources.redhat.com/autobook/autobook/autobook_253.html#SEC253 -# -libbroccoli_la_LIBADD = @BRO_LIBADD@ - -if WINDOWS_HOST -libbroccoli_la_LDFLAGS = -mwindows -no-undefined -version-info 0:0:0 -else -libbroccoli_la_LDFLAGS = -version-info 3:0:0 -endif - -# Optionally include support files for pcap packets -# -if BRO_PCAP_SUPPORT -PACKET_FILES = bro_packet.c bro_packet.h -else -PACKET_FILES = -endif - -# Use the parser source files when we do have lex/yacc, and the generated -# parser code otherwise. Seeing .y/.l's triggers yacc/lex automatically. -if HAVE_LEX_AND_YACC -PARSER_FILES = bro_parser.y bro_lexer.l -else -PARSER_FILES = bro_lexer.c bro_parser.c bro_parser.h -endif - -# lex/yacc flags -- those need to be defined regardless of whether -# we have those tools because of automake bogosity. -LEX_OUTPUT_ROOT = lex.bro -AM_LFLAGS = -Pbro -AM_YFLAGS = -d -v -p bro - -DEBUGFLAGS = -W -Wall -Wno-unused -INCLUDES = $(DEBUGFLAGS) -I$(top_srcdir)/compat - -# Make sure the main header file gets installed in the appropriate -# include directory: -include_HEADERS = broccoli.h - -# Most importantly, make sure we build a library out of all this. -lib_LTLIBRARIES = libbroccoli.la - -# The sources. If we have lex and yacc, the .y and .l files for -# the parser are included, otherwise the generated .c/.h's. -libbroccoli_la_SOURCES = $(PARSER_FILES) \ - $(PACKET_FILES) \ - broccoli.h \ - bro.c \ - bro_attr.c bro_attr.h \ - bro_attrs.c bro_attrs.h \ - bro_buf.h bro_buf.c \ - bro_config.h bro_config.c \ - bro_debug.h bro_debug.c \ - bro_event.h bro_event.c \ - bro_event_reg.h bro_event_reg.c \ - bro_hashtable.h bro_hashtable.c \ - bro_id.h bro_id.c \ - bro_io.h bro_io.c \ - bro_list.h bro_list.c \ - bro_location.h bro_location.c \ - bro_object.h bro_object.c \ - bro_openssl.h bro_openssl.c \ - bro_record.h bro_record.c \ - bro_sobject.h bro_sobject.c \ - bro_table.h bro_table.c \ - bro_type.h bro_type.c \ - bro_type_decl.h bro_type_decl.c \ - bro_types.h \ - bro_util.h bro_util.c \ - bro_val.h bro_val.c diff --git a/aux/broccoli/src/bro.c b/aux/broccoli/src/bro.c deleted file mode 100644 index c7e04d1315..0000000000 --- a/aux/broccoli/src/bro.c +++ /dev/null @@ -1,1976 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __MINGW32__ -#include -#else -#include -#include -#include -#include -#include -#include -#endif - -#if HAVE_CONFIG_H -# include -#endif - -#include "broccoli.h" -#include "bro_debug.h" -#include "bro_buf.h" -#include "bro_config.h" -#include "bro_hashtable.h" -#include "bro_types.h" -#include "bro_type.h" -#include "bro_val.h" -#include "bro_id.h" -#include "bro_event.h" -#include "bro_event_reg.h" -#include "bro_io.h" -#include "bro_util.h" -#include "bro_openssl.h" -#include "bro_record.h" -#include "bro_table.h" -#ifdef BRO_PCAP_SUPPORT -#include "bro_packet.h" -#endif - - -/* Don't attempt to reconnect more than once every 5 seconds: */ -#define BRO_RECONNECT_MAX_RATE 5 - -/* Default maximum cache size. */ -#define BRO_MAX_CACHE_SIZE 1000 - -/* Macro for putting safety brakes on some functions to ensure the - * user is now calling bro_init() first. - */ -#define BRO_SAFETY_CHECK init_check(__FUNCTION__); - -/* Pointer to BroCtx provided by the user at initialization time. */ -const BroCtx *global_ctx = NULL; - -/* To make MinGW happy, we provide an initialization handler for the - * DLL if we are building on Windows. - */ -#ifdef __MINGW32__ -int main() { return 0; } -#endif - -static int -conn_init_await(BroConn *bc, int conn_state) -{ - /* Wait for a maximum of 10 seconds until the connection - * reaches the desired state. We check every 0.2 seconds. - */ - int i = 0, intervals = 10 * 5 + 1; - - D_ENTER; - - if (bc->state->conn_state_self == conn_state) - { - D(("Self already in requested state.\n")); - D_RETURN_(TRUE); - } - - /* Set our own connection state to the requested one. - */ - bc->state->conn_state_self = conn_state; - - /* Wait for a while, processing the peer's input, - * and return as soon as we reach the desired state. - */ - while (i++ < intervals) - { - struct timeval timeout; - timeout.tv_sec = 0; - timeout.tv_usec = 200000; - - if (bc->state->conn_state_peer >= conn_state) - D_RETURN_(TRUE); - - if (select(0, NULL, NULL, NULL, &timeout) < 0) - { - D(("select() caused '%s'\n", strerror(errno))); - D_RETURN_(FALSE); - } - - __bro_io_process_input(bc); - } - - D_RETURN_(FALSE); -} - -static int -conn_init_setup(BroConn *bc) -{ - BroBuf buf; - uint32 descriptor[4]; - int result; - - D_ENTER; - - descriptor[0] = htonl((uint32) BRO_PROTOCOL_VERSION); - descriptor[1] = htonl((uint32) BRO_MAX_CACHE_SIZE); - descriptor[2] = htonl((uint32) BRO_DATA_FORMAT_VERSION); - descriptor[3] = 0; /* Relative uptime of the process */ - - __bro_buf_init(&buf); - __bro_buf_append(&buf, descriptor, 4 * sizeof(uint32)); - - if (bc->class) - __bro_buf_append(&buf, bc->class, strlen(bc->class) + 1); - - if (! __bro_io_raw_queue(bc, BRO_MSG_VERSION, - __bro_buf_get(&buf), - __bro_buf_get_used_size(&buf))) - { - D(("Setup data not sent to %p\n", bc)); - __bro_buf_cleanup(&buf); - D_RETURN_(FALSE); - } - - __bro_buf_cleanup(&buf); - - /* This phase does NOT send PHASE_END ... */ - - D(("Phase done to peer on %p, self now in HANDSHAKE stage.\n", bc)); - result = conn_init_await(bc, BRO_CONNSTATE_HANDSHAKE); - D_RETURN_(result); -} - -static int -conn_init_handshake(BroConn *bc) -{ - uint32 caps[3]; - int result; - - D_ENTER; - - /* --- Request events, if any -------------------------------------- */ - if (bc->ev_reg->num_handlers > 0) - __bro_event_reg_request(bc); - - /* --- Capabilities ------------------------------------------------ */ - - /* We never compress at the moment. */ - - /* Unless user requested caching, tell peer we do not cache. Note - * that at the moment we never cache data we send, so this only - * affects received data. - */ - caps[0] = 0; - caps[1] = 0; - caps[2] = 0; - - caps[0] |= (bc->conn_flags & BRO_CFLAG_CACHE) ? 0 : BRO_CAP_DONTCACHE; - - caps[0] = htonl(caps[0]); - caps[1] = htonl(caps[1]); - caps[2] = htonl(caps[2]); - - if (! __bro_io_raw_queue(bc, BRO_MSG_CAPS, - (uchar*) caps, 3 * sizeof(uint32))) - { - D(("Handshake data not sent to %p\n", bc)); - D_RETURN_(FALSE); - } - - /* --- End of phase ------------------------------------------------ */ - - if (! __bro_io_raw_queue(bc, BRO_MSG_PHASE_DONE, NULL, 0)) - { - D(("End-of-Handshake not sent to %p\n", bc)); - D_RETURN_(FALSE); - } - - if (bc->state->sync_state_requested) - { - D(("Phase done to peer on %p, sync requested, self now in SYNC stage.\n", bc)); - result = conn_init_await(bc, BRO_CONNSTATE_SYNC); - } - else - { - D(("Phase done to peer on %p, no sync requested, self now in RUNNING stage.\n", bc)); - result = conn_init_await(bc, BRO_CONNSTATE_RUNNING); - } - - D_RETURN_(result); -} - -static int -conn_init_sync(BroConn *bc) -{ - int result = TRUE; - - D_ENTER; - - /* If the peer requested synced state, we just send another phase done. - * Otherwise we don't do anything and immediately move to the "running" - * state. - */ - if (bc->state->sync_state_requested) - { - if (! __bro_io_raw_queue(bc, BRO_MSG_PHASE_DONE, NULL, 0)) - { - D(("End-of-Sync not sent to %p\n", bc)); - D_RETURN_(FALSE); - } - - D(("Phase done to peer on %p\n", bc)); - } - - D(("Self now in RUNNING stage.\n")); - result = conn_init_await(bc, BRO_CONNSTATE_RUNNING); - - D_RETURN_(result); -} - -/* This function walks lock-step with the peer through - * the entire handshake procedure. - */ -static int -conn_init_configure(BroConn *bc) -{ - if (! conn_init_setup(bc)) - return FALSE; - if (! conn_init_handshake(bc)) - return FALSE; - if (! conn_init_sync(bc)) - return FALSE; - - return TRUE; -} - -static int -conn_init(BroConn *bc) -{ - D_ENTER; - - if (! (bc->rx_buf = __bro_buf_new())) - goto error_exit; - if (! (bc->tx_buf = __bro_buf_new())) - goto error_exit; - - if (! (bc->state = calloc(1, sizeof(BroConnState)))) - goto error_exit; - - bc->state->conn_state_self = BRO_CONNSTATE_SETUP; - bc->state->conn_state_peer = BRO_CONNSTATE_SETUP; - - if (! __bro_openssl_connect(bc)) - goto error_exit; - - D_RETURN_(TRUE); - - error_exit: - __bro_buf_free(bc->rx_buf); - __bro_buf_free(bc->tx_buf); - bc->rx_buf = NULL; - bc->tx_buf = NULL; - - D_RETURN_(FALSE); -} - -static void -conn_free(BroConn *bc) -{ - D_ENTER; - - __bro_openssl_shutdown(bc); - - if (bc->state) - free(bc->state); - - __bro_buf_free(bc->rx_buf); - __bro_buf_free(bc->tx_buf); - bc->rx_buf = NULL; - bc->tx_buf = NULL; - - D_RETURN; -} - -static void -init_check(const char *func) -{ - if (global_ctx == NULL) { - fprintf(stderr, - "*** Broccoli error: %s called without prior initialization.\n" - "*** Initialization of the Broccoli library is now required.\n" - "*** See documentation for details. Aborting.\n", - func); - exit(-1); - } -} - -int -bro_init(const BroCtx* ctx) -{ - if (global_ctx != NULL) - return TRUE; - - if (ctx == NULL) { - ctx = calloc(1, sizeof(BroCtx)); - bro_ctx_init((BroCtx*) ctx); - } - - global_ctx = ctx; - __bro_conf_init(); - if (! __bro_openssl_init()) - return FALSE; - - return TRUE; -} - -void -bro_ctx_init(BroCtx *ctx) -{ - memset(ctx, 0, sizeof(BroCtx)); -} - -BroConn * -bro_conn_new_str(const char *hostname, int flags) -{ - BroConn *bc; - static int counter = 0; - - BRO_SAFETY_CHECK; - - D_ENTER; - - if (! hostname || !*hostname) - D_RETURN_(NULL); - - if (! (bc = (BroConn *) calloc(1, sizeof(BroConn)))) - D_RETURN_(NULL); - - D(("Connecting to host %s\n", hostname)); - - bc->conn_flags = flags; - bc->id_pid = getpid(); - bc->id_num = counter++; - bc->peer = strdup(hostname); - bc->io_cache_maxsize = BRO_MAX_CACHE_SIZE; - bc->socket = -1; - - TAILQ_INIT(&bc->msg_queue); - bc->msg_queue_len = 0; - - if (! (bc->ev_reg = __bro_event_reg_new())) - goto error_exit; - - if (! (bc->io_cache = __bro_ht_new(__bro_ht_int_hash, - __bro_ht_int_cmp, - NULL, - (BroHTFreeFunc) __bro_sobject_release, - TRUE))) - goto error_exit; - - if (! (bc->data = __bro_ht_new(__bro_ht_str_hash, - __bro_ht_str_cmp, - __bro_ht_mem_free, - NULL, FALSE))) - goto error_exit; - - if (! (bc->ev_mask = __bro_ht_new(__bro_ht_str_hash, - __bro_ht_str_cmp, - __bro_ht_mem_free, - NULL, FALSE))) - goto error_exit; - - D_RETURN_(bc); - - error_exit: - __bro_event_reg_free(bc->ev_reg); - __bro_ht_free(bc->ev_mask); - __bro_ht_free(bc->io_cache); - __bro_ht_free(bc->data); - - if (bc->peer) - free(bc->peer); - - free(bc); - D_RETURN_(NULL); -} - - -BroConn * -bro_conn_new(struct in_addr *ip_addr, uint16 port, int flags) -{ - BroConn *bc; - char hostname[1024]; - - BRO_SAFETY_CHECK; - - D_ENTER; - __bro_util_snprintf(hostname, 1024, "%s:%hu", inet_ntoa(*ip_addr), ntohs(port)); - bc = bro_conn_new_str(hostname, flags); - D_RETURN_(bc); -} - -BroConn * -bro_conn_new_socket(int fd, int flags) -{ - BroConn *bc; - - BRO_SAFETY_CHECK; - - D_ENTER; - - if ( fd < 0 ) - D_RETURN_(NULL); - - bc = bro_conn_new_str("", flags); - if (! bc) - D_RETURN_(NULL); - - bc->socket = fd; - D_RETURN_(bc); -} - -void -bro_conn_set_class(BroConn *bc, const char *class) -{ - if (! bc) - return; - - if (bc->class) - free(bc->class); - - bc->class = strdup(class); -} - -const char * -bro_conn_get_peer_class(const BroConn *bc) -{ - if (! bc) - return NULL; - - return bc->peer_class; -} - -void -bro_conn_get_connstats(const BroConn *bc, BroConnStats *cs) -{ - if (! bc || ! cs) - return; - - memset(cs, 0, sizeof(BroConnStats)); - cs->tx_buflen = __bro_buf_get_used_size(bc->tx_buf); - cs->rx_buflen = __bro_buf_get_used_size(bc->rx_buf); -} - -int -bro_conn_connect(BroConn *bc) -{ - D_ENTER; - - if (! bc) - D_RETURN_(FALSE); - - if ( (bc->conn_flags & BRO_CFLAG_SHAREABLE)) - fprintf(stderr, "WARNING: BRO_CFLAG_SHAREABLE is no longer supported.\n"); - - if (! conn_init(bc)) - D_RETURN_(FALSE); - - /* Handshake procedure. */ - if (! conn_init_configure(bc)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -int -bro_conn_reconnect(BroConn *bc) -{ - BroMsg *msg, *msg_first, **msg_last; - int msg_queue_len; - time_t current_time; - - D_ENTER; - - if (! bc) - D_RETURN_(FALSE); - - if (bc->state->in_reconnect) - D_RETURN_(FALSE); - - if ( (current_time = time(NULL)) > 0) - { - if (current_time - bc->state->last_reconnect < BRO_RECONNECT_MAX_RATE) - { - D(("Less than %i seconds since last reconnect attempt, not reconnecting.\n", - BRO_RECONNECT_MAX_RATE)); - D_RETURN_(FALSE); - } - - bc->state->last_reconnect = current_time; - } - - D(("Attempting reconnection...\n")); - bc->state->in_reconnect = TRUE; - - /* NOTE: the sequencing in this function is quite tricky and very picky. - * Don't move things around unneccesarily ... - */ - bc->state->tx_dead = bc->state->rx_dead = FALSE; - - /* Clean up the old connection state: */ - bc->state->conn_state_self = BRO_CONNSTATE_SETUP; - bc->state->conn_state_peer = BRO_CONNSTATE_SETUP; - bc->state->sync_state_requested = FALSE; - - if (bc->bio) - { - BIO_free_all(bc->bio); - bc->bio = NULL; - } - - /* Attempt to establish new connection */ - if (! __bro_openssl_reconnect(bc)) - goto error_return; - - __bro_buf_reset(bc->rx_buf); - __bro_buf_reset(bc->tx_buf); - - /* Only *after* we managed to connect, we clear the event mask for events - * the peer expects, etc. If we do this earlier and fail to connect, then future - * sent events never trigger a reconnect because they're never sent since - * they don't seem to be requested. - */ - - /* Temporarily unhook messages from the message queue so the new messages - * get sent right away. We hook the old ones back in below. - */ - msg_first = bc->msg_queue.tqh_first; - msg_last = bc->msg_queue.tqh_last; - msg_queue_len = bc->msg_queue_len; - bc->msg_queue_len = 0; - TAILQ_INIT(&bc->msg_queue); - - __bro_ht_free(bc->ev_mask); - - if (! (bc->ev_mask = __bro_ht_new(__bro_ht_str_hash, - __bro_ht_str_cmp, - __bro_ht_mem_free, - NULL, FALSE))) - goto reset_error_return; - - __bro_ht_free(bc->io_cache); - - if (! (bc->io_cache = __bro_ht_new(__bro_ht_int_hash, - __bro_ht_int_cmp, - NULL, - (BroHTFreeFunc) __bro_sobject_release, - TRUE))) - goto reset_error_return; - - if (! conn_init_configure(bc)) - goto reset_error_return; - - /* Hook old events back in */ - if (bc->msg_queue_len == 0) - bc->msg_queue.tqh_first = msg_first; - else - { - msg_first->msg_queue.tqe_prev = bc->msg_queue.tqh_last; - *bc->msg_queue.tqh_last = msg_first; - } - - bc->msg_queue.tqh_last = msg_last; - bc->msg_queue_len += msg_queue_len; - - D(("Reconnect completed successfully.\n")); - bc->state->in_reconnect = FALSE; - - D_RETURN_(TRUE); - - reset_error_return: - - /* If the reconnect went wrong somehow, nuke the queue and - * place old queue contents back in. - */ - while ( (msg = bc->msg_queue.tqh_first)) - { - TAILQ_REMOVE(&bc->msg_queue, msg, msg_queue); - __bro_io_msg_free(msg); - } - - bc->msg_queue.tqh_first = msg_first; - bc->msg_queue.tqh_last = msg_last; - bc->msg_queue_len = msg_queue_len; - - error_return: - bc->state->tx_dead = bc->state->rx_dead = TRUE; - bc->state->in_reconnect = FALSE; - - D_RETURN_(FALSE); -} - - -int -bro_conn_delete(BroConn *bc) -{ - BroMsg *msg; - - D_ENTER; - - if (!bc || !bc->state) - D_RETURN_(FALSE); - - if (! bc->state->tx_dead) - { - /* Try to flush command queue */ - __bro_io_msg_queue_flush(bc); - } - - while ( (msg = bc->msg_queue.tqh_first)) - { - TAILQ_REMOVE(&bc->msg_queue, msg, msg_queue); - __bro_io_msg_free(msg); - } - - __bro_ht_free(bc->ev_mask); - __bro_event_reg_free(bc->ev_reg); - __bro_ht_free(bc->io_cache); - __bro_ht_free(bc->data); - - conn_free(bc); - - if (bc->class) - free(bc->class); - if (bc->peer_class) - free(bc->peer_class); - - if (bc->peer) - free(bc->peer); - - free(bc); - D_RETURN_(TRUE); -} - - -int -bro_conn_alive(const BroConn *bc) -{ - if (!bc || !bc->state) - return FALSE; - - return (! bc->state->tx_dead && ! bc->state->rx_dead); -} - - -static int -conn_adopt_events_cb(char *ev_name, void *data, BroHT *dst) -{ - char *key; - - /* If the event is already reported, ignore. */ - if (__bro_ht_get(dst, ev_name)) - return TRUE; - - D(("Adopting event %s\n", ev_name)); - key = strdup(ev_name); - __bro_ht_add(dst, key, key); - - return TRUE; - data = NULL; -} - -void -bro_conn_adopt_events(BroConn *src, BroConn *dst) -{ - D_ENTER; - - if (!src || !dst) - D_RETURN; - - __bro_ht_foreach(src->ev_mask, (BroHTCallback) conn_adopt_events_cb, dst->ev_mask); - - D_RETURN; -} - - -int -bro_conn_get_fd(BroConn *bc) -{ - int fd; - - if (! bc || !bc->state || bc->state->tx_dead || bc->state->rx_dead || !bc->bio) - return -1; - -#ifdef __MINGW32__ - return 0; -#else - BIO_get_fd(bc->bio, &fd); - return fd; -#endif -} - - -int -bro_conn_process_input(BroConn *bc) -{ - if (! bc || !bc->state || bc->state->rx_dead) - return FALSE; - - return __bro_io_process_input(bc); -} - - -int -bro_event_queue_length(BroConn *bc) -{ - if (! bc) - return 0; - - return bc->msg_queue_len; -} - - -int -bro_event_queue_length_max(BroConn *bc) -{ - return BRO_MSG_QUEUELEN_MAX; - bc = NULL; -} - - -int -bro_event_queue_flush(BroConn *bc) -{ - return __bro_io_msg_queue_flush(bc); -} - - -int -bro_event_send(BroConn *bc, BroEvent *ev) -{ - int result; - - D_ENTER; - - if (! bc || !ev) - { - D(("Input error\n")); - D_RETURN_(FALSE); - } - - D(("Sending event with %i args\n", __bro_list_length(ev->val_list))); - result = __bro_io_event_queue(bc, ev); - D_RETURN_(result); -} - - -int -bro_event_send_raw(BroConn *bc, const uchar *data, int data_len) -{ - BroBuf *buf = NULL; - - D_ENTER; - - if (! bc || !data) - { - D(("Input error\n")); - D_RETURN_(FALSE); - } - - if (data_len == 0) - { - D(("Nothing to send\n")); - D_RETURN_(TRUE); - } - - if (! (buf = __bro_buf_new())) - { - D(("Out of memory\n")); - D_RETURN_(FALSE); - } - - __bro_buf_write_char(buf, 'e'); - __bro_buf_write_data(buf, data, data_len); - - __bro_io_rawbuf_queue(bc, BRO_MSG_SERIAL, buf); - __bro_io_msg_queue_flush(bc); - - D_RETURN_(TRUE); -} - - -void -bro_conn_data_set(BroConn *bc, const char *key, void *val) -{ - if (!bc || !key || !*key) - return; - - __bro_ht_add(bc->data, strdup(key), val); -} - - -void * -bro_conn_data_get(BroConn *bc, const char *key) -{ - if (!bc || !key || !*key) - return NULL; - - return __bro_ht_get(bc->data, (void *) key); -} - - -void * -bro_conn_data_del(BroConn *bc, const char *key) -{ - if (!bc || !key || !*key) - return NULL; - - return __bro_ht_del(bc->data, (void *) key); -} - - -/* ----------------------------- Bro Events -------------------------- */ - -BroEvent * -bro_event_new(const char *event_name) -{ - BroString name; - BroEvent *result; - - bro_string_set(&name, event_name); - result = __bro_event_new(&name); - bro_string_cleanup(&name); - - return result; -} - - -void -bro_event_free(BroEvent *be) -{ - __bro_event_free(be); -} - - -int -bro_event_add_val(BroEvent *be, int type, const char *type_name, const void *val) -{ - BroVal *v; - - D_ENTER; - - if (! be || ! val || type < 0 || type >= BRO_TYPE_MAX) - { - D(("Invalid input: (%p, %i, %p)\n", be, type, val)); - D_RETURN_(FALSE); - } - - if (! (v = __bro_val_new_of_type(type, type_name))) - D_RETURN_(FALSE); - - if (! __bro_val_assign(v, val)) - { - __bro_sobject_release((BroSObject *) v); - D_RETURN_(FALSE); - } - - __bro_event_add_val(be, v); - - D_RETURN_(TRUE); -} - - -int -bro_event_set_val(BroEvent *be, int val_num, - int type, const char *type_name, - const void *val) -{ - BroVal *v; - int result; - - D_ENTER; - - if (! be || ! val || type < 0 || type >= BRO_TYPE_MAX) - { - D(("Invalid input: (%p, %i, %p)\n", be, type, val)); - D_RETURN_(FALSE); - } - - if (! (v = __bro_val_new_of_type(type, type_name))) - D_RETURN_(FALSE); - - if (! __bro_val_assign(v, val)) - { - __bro_sobject_release((BroSObject *) v); - D_RETURN_(FALSE); - } - - result = __bro_event_set_val(be, val_num, v); - D_RETURN_(result); -} - - -void -bro_event_registry_add(BroConn *bc, - const char *event_name, - BroEventFunc func, - void *user_data) -{ - __bro_event_reg_add(bc, event_name, func, user_data); -} - - -void -bro_event_registry_add_compact(BroConn *bc, - const char *event_name, - BroCompactEventFunc func, - void *user_data) -{ - __bro_event_reg_add_compact(bc, event_name, func, user_data); -} - - -void -bro_event_registry_remove(BroConn *bc, const char *event_name) -{ - __bro_event_reg_remove(bc, event_name); -} - - -void -bro_event_registry_request(BroConn *bc) -{ - D_ENTER; - - if (!bc || !bc->state) - D_RETURN; - - /* A connection that isn't up and running yet cannot request - * events. The handshake phase will request any registered - * events automatically. - */ - if (bc->state->conn_state_self != BRO_CONNSTATE_RUNNING) - D_RETURN; - - __bro_event_reg_request(bc); - - D_RETURN; -} - - - -/* ------------------------ Dynamic-size Buffers --------------------- */ - -BroBuf * -bro_buf_new(void) -{ - BroBuf *buf; - - if (! (buf = calloc(1, sizeof(BroBuf)))) - return NULL; - - __bro_buf_init(buf); - return buf; -} - - -void -bro_buf_free(BroBuf *buf) -{ - if (!buf) - return; - - __bro_buf_cleanup(buf); - free(buf); -} - - -int -bro_buf_append(BroBuf *buf, void *data, int data_len) -{ - return __bro_buf_append(buf, data, data_len); -} - - -void -bro_buf_consume(BroBuf *buf) -{ - __bro_buf_consume(buf); -} - - -void -bro_buf_reset(BroBuf *buf) -{ - __bro_buf_reset(buf); -} - - -uchar * -bro_buf_get(BroBuf *buf) -{ - return __bro_buf_get(buf); -} - - -uchar * -bro_buf_get_end(BroBuf *buf) -{ - return __bro_buf_get_end(buf); -} - - -uint -bro_buf_get_size(BroBuf *buf) -{ - return __bro_buf_get_size(buf); -} - - -uint -bro_buf_get_used_size(BroBuf *buf) -{ - return __bro_buf_get_used_size(buf); -} - - -uchar * -bro_buf_ptr_get(BroBuf *buf) -{ - return __bro_buf_ptr_get(buf); -} - - -uint32 -bro_buf_ptr_tell(BroBuf *buf) -{ - return __bro_buf_ptr_tell(buf); -} - - -int -bro_buf_ptr_seek(BroBuf *buf, int offset, int whence) -{ - return __bro_buf_ptr_seek(buf, offset, whence); -} - - -int -bro_buf_ptr_check(BroBuf *buf, int size) -{ - return __bro_buf_ptr_check(buf, size); -} - - -int -bro_buf_ptr_read(BroBuf *buf, void *data, int size) -{ - return __bro_buf_ptr_read(buf, data, size); -} - - -int -bro_buf_ptr_write(BroBuf *buf, void *data, int size) -{ - return __bro_buf_ptr_write(buf, data, size); -} - - - -/* ------------------------ Configuration Access --------------------- */ - -void -bro_conf_set_domain(const char *domain) -{ - BRO_SAFETY_CHECK; - __bro_conf_set_domain(domain); -} - - -int -bro_conf_get_int(const char *val_name, int *val) -{ - BRO_SAFETY_CHECK; - - if (! val_name || ! val) - return FALSE; - - return __bro_conf_get_int(val_name, val); -} - - -int -bro_conf_get_dbl(const char *val_name, double *val) -{ - BRO_SAFETY_CHECK; - - if (! val_name || ! val) - return FALSE; - - return __bro_conf_get_dbl(val_name, val); -} - - -const char * -bro_conf_get_str(const char *val_name) -{ - BRO_SAFETY_CHECK; - - if (! val_name) - return FALSE; - - return __bro_conf_get_str(val_name); -} - - -/* -------------------------- Record Handling ------------------------ */ - -BroRecord * -bro_record_new(void) -{ - return __bro_record_new(); -} - - -void -bro_record_free(BroRecord *rec) -{ - __bro_record_free(rec); -} - -int -bro_record_get_length(BroRecord *rec) -{ - return __bro_record_get_length(rec); -} - -int -bro_record_add_val(BroRecord *rec, const char *name, - int type, const char *type_name, const void *val) -{ - BroVal *v; - - D_ENTER; - - if (! rec) - { - D(("Input error: (%p, %s, %i, %p)\n", rec, name, type, val)); - D_RETURN_(FALSE); - } - - if (! (v = __bro_val_new_of_type(type, type_name))) - { - D(("Could not get val of type %i\n", type)); - D_RETURN_(FALSE); - } - - if (! name) - name = ""; - - __bro_sobject_data_set((BroSObject *) v, "field", strdup(name)); - - if (! __bro_val_assign(v, val)) - { - D(("Could not assign value to the new val.\n")); - __bro_sobject_release((BroSObject *) v); - D_RETURN_(FALSE); - } - - __bro_record_add_val(rec, v); - D_RETURN_(TRUE); -} - - -const char* -bro_record_get_nth_name(BroRecord *rec, int num) -{ - const char *name; - - if ( (name = __bro_record_get_nth_name(rec, num))) - return name; - - return NULL; -} - - -void * -bro_record_get_nth_val(BroRecord *rec, int num, int *type) -{ - BroVal *val; - int type_found; - void *result = NULL; - - if (type && (*type < BRO_TYPE_UNKNOWN || *type >= BRO_TYPE_MAX)) - { - D(("Invalid value for type pointer (%i)\n", *type)); - return NULL; - } - - if (! (val = __bro_record_get_nth_val(rec, num))) - return NULL; - - /* Now transform the val into a form expected in *result, - * based on the type given in the val. - */ - if (! __bro_val_get_data(val, &type_found, &result)) - return NULL; - - if (type) - { - if (*type != BRO_TYPE_UNKNOWN && type_found != *type) - { - D(("Type mismatch: expected type tag %i, found type tag %i\n", *type, type_found)); - result = NULL; - } - - *type = type_found; - } - - return result; -} - - -void * -bro_record_get_named_val(BroRecord *rec, const char *name, int *type) -{ - BroVal *val; - int type_found; - void *result = NULL; - - if (type && (*type < BRO_TYPE_UNKNOWN || *type >= BRO_TYPE_MAX)) - { - D(("Invalid value for type pointer (%i)\n", *type)); - return NULL; - } - - if (! (val = __bro_record_get_named_val(rec, name))) - return NULL; - - /* Now transform the val into a form expected in *result, - * based on the type given in the val. - */ - if (! __bro_val_get_data(val, &type_found, &result)) - return NULL; - - if (type) - { - if (*type != BRO_TYPE_UNKNOWN && type_found != *type) - { - D(("Type mismatch: expected type tag %i for field '%s', found tag %i\n", - *type, name, type_found)); - result = NULL; - } - - *type = type_found; - } - - return result; -} - - -int -bro_record_set_nth_val(BroRecord *rec, int num, - int type, const char *type_name, const void *val) -{ - BroVal *v; - char *name; - - D_ENTER; - - if (! rec || num < 0 || num >= rec->val_len || - type < 0 || type >= BRO_TYPE_MAX || ! val) - { - D(("Input error: (%p, %i, %i, %p)\n", rec, num, type, val)); - D_RETURN_(FALSE); - } - - if (! (v = __bro_record_get_nth_val(rec, num))) - D_RETURN_(FALSE); - - if (! (name = __bro_sobject_data_get((BroSObject *) v, "field"))) - D_RETURN_(FALSE); - - if (! (v = __bro_val_new_of_type(type, type_name))) - { - D(("Could not get val of type %i\n", type)); - D_RETURN_(FALSE); - } - - __bro_sobject_data_set((BroSObject *) v, "field", strdup(name)); - - if (! __bro_val_assign(v, val)) - { - D(("Could not assign value to the new val.\n")); - __bro_sobject_release((BroSObject *) v); - D_RETURN_(FALSE); - } - - __bro_record_set_nth_val(rec, num, v); - D_RETURN_(TRUE); -} - - -int -bro_record_set_named_val(BroRecord *rec, const char *name, - int type, const char *type_name, const void *val) -{ - BroVal *v; - - D_ENTER; - - if (! rec || ! name || !*name || - type < 0 || type >= BRO_TYPE_MAX || ! val) - { - D(("Input error: (%p, %s, %i, %p)\n", rec, name, type, val)); - D_RETURN_(FALSE); - } - - if (! (v = __bro_val_new_of_type(type, type_name))) - { - D(("Could not get val of type %i\n", type)); - D_RETURN_(FALSE); - } - - if (! __bro_val_assign(v, val)) - { - D(("Could not assign value to the new val.\n")); - __bro_sobject_release((BroSObject *) v); - D_RETURN_(FALSE); - } - - __bro_record_set_named_val(rec, name, v); - D_RETURN_(TRUE); -} - - -/* -------------------------- Tables & Sets -------------------------- */ - -BroTable * -bro_table_new(void) -{ - BroTable *tbl; - - D_ENTER; - tbl = __bro_table_new(); - D_RETURN_(tbl); -} - - -void -bro_table_free(BroTable *tbl) -{ - D_ENTER; - __bro_table_free(tbl); - D_RETURN; -} - - -int -bro_table_insert(BroTable *tbl, - int key_type, const void *key, - int val_type, const void *val) -{ - BroVal *vv = NULL; - BroListVal *lv; - - D_ENTER; - - if (! tbl || !key || !val) - D_RETURN_(FALSE); - - if (tbl->tbl_key_type != BRO_TYPE_UNKNOWN && - tbl->tbl_key_type != key_type) - { - D(("Type mismatch when inserting key of type %d, expecting %d\n", - key_type, tbl->tbl_key_type)); - D_RETURN_(FALSE); - } - - tbl->tbl_key_type = key_type; - - if (tbl->tbl_val_type != BRO_TYPE_UNKNOWN && - tbl->tbl_val_type != val_type) - { - D(("Type mismatch when inserting val of type %d, expecting %d\n", - val_type, tbl->tbl_val_type)); - D_RETURN_(FALSE); - } - - tbl->tbl_val_type = val_type; - - /* Now need to creat BroVals out of the raw data provided. - * If the key_type is BRO_TYPE_LIST, it means the argument - * is expected to be a BroRecord and its elements will be - * used as elements of a list of values, as used internally - * by Bro. For all other BRO_TYPE_xxx values, the type is - * used in the obvious way. - */ - lv = __bro_list_val_new(); - - if (key_type == BRO_TYPE_LIST) - { - /* We need to unroll the record elements and put them - * all in the list val. - */ - - BroRecord *rec = (BroRecord*) key; - int i; - - for (i = 0; i < __bro_record_get_length(rec); i++) - { - /* We can here leverage the fact that internally, all - * elements of a BroRec are BroVals. - */ - BroVal *v = __bro_record_get_nth_val(rec, i); - BroVal *v_copy = (BroVal*) __bro_sobject_copy((BroSObject*) v); - __bro_list_val_append(lv, v_copy); - } - } - else - { - BroVal *kv; - - /* In this case we actually need to create a BroVal from - * the user's raw data first. - */ - if (! (kv = __bro_val_new_of_type(key_type, NULL))) - { - D(("Could not create val of type %d\n", key_type)); - D_RETURN_(FALSE); - } - - __bro_val_assign(kv, key); - __bro_list_val_append(lv, kv); - } - - if (val) - { - if (! (vv = __bro_val_new_of_type(val_type, NULL))) - { - D(("Could not crate val of type %d\n", val_type)); - D_RETURN_(FALSE); - } - - __bro_val_assign(vv, val); - } - - __bro_table_insert(tbl, (BroVal*) lv, vv); - - D_RETURN_(TRUE); -} - - -void * -bro_table_find(BroTable *tbl, const void *key) -{ - BroListVal *lv; - BroVal *val, *result_val; - void *result = NULL; - BroRecord *rec = NULL; - - D_ENTER; - - lv = __bro_list_val_new(); - - if (tbl->tbl_key_type == BRO_TYPE_LIST) - { - /* Need to interpret the given key as a record and hook its - * elements into the list. Below we unhook the list from the - * ListVal before releasing it. - */ - rec = (BroRecord *) key; - lv->list = rec->val_list; - lv->len = rec->val_len; - } - else - { - if (! (val = __bro_val_new_of_type(tbl->tbl_key_type, NULL))) - { - D(("Could not create val of type %d.\n", tbl->tbl_key_type)); - D_RETURN_(NULL); - } - - __bro_val_assign(val, key); - __bro_list_val_append(lv, val); - } - - if ( (result_val = __bro_table_find(tbl, (BroVal*) lv))) - { - if (! __bro_val_get_data(result_val, NULL, &result)) - { - __bro_sobject_release((BroSObject*) lv); - D_RETURN_(NULL); - } - } - - if (rec) - { - lv->list = NULL; - lv->len = 0; - } - - __bro_sobject_release((BroSObject*) lv); - - D_RETURN_(result); -} - - -int -bro_table_get_size(BroTable *tbl) -{ - int result; - - D_ENTER; - result = __bro_table_get_size(tbl); - D_RETURN_(result); -} - -typedef struct bro_table_cb_data -{ - void *user_data; - BroTableCallback cb; - int is_set; -} BroTableCBData; - -static int -bro_table_foreach_cb(BroListVal *key, BroVal *val, BroTableCBData *data) -{ - int result; - void *key_data = NULL, *val_data = NULL; - BroRecord *rec = NULL; - - if (__bro_list_val_get_length(key) > 1) - { - /* Need to shrink-wrap it into a record. */ - BroList *l; - rec = __bro_record_new(); - - for (l = key->list; l; l = __bro_list_next(l)) - { - BroVal *tmp = (BroVal*) __bro_list_data(l); - - /* __bro_record_add_val() does not internally copy the added - * val. Without bumping up the val's refcount, __bro_record_free() - * below would possibly nuke the val when it decrements the count - * by 1. - */ - __bro_sobject_ref((BroSObject*) tmp); - __bro_record_add_val(rec, tmp); - } - - key_data = (void*) rec; - } - else - { - /* Direct passthrough. */ - BroVal *v = __bro_list_val_get_front(key); - D(("Index type is atomic, type %d/%d\n", - v->val_type->tag, v->val_type->internal_tag)); - - if (! __bro_val_get_data(v, NULL, &key_data)) - { - D(("Failed to obtain user-suitable data representation.\n")); - return TRUE; - } - } - - if (! data->is_set && ! __bro_val_get_data(val, NULL, &val_data)) - { - D(("Failed to obtain user-suitable data representation.\n")); - result = FALSE; - goto return_result; - } - - result = data->cb(key_data, val_data, data->user_data); - - return_result: - if (rec) - __bro_record_free(rec); - - return result; -} - -void -bro_table_foreach(BroTable *tbl, - BroTableCallback cb, - void *user_data) -{ - BroTableCBData data; - - D_ENTER; - - data.user_data = user_data; - data.cb = cb; - data.is_set = __bro_table_is_set(tbl); - - __bro_table_foreach(tbl, - (BroTableCallback) bro_table_foreach_cb, - &data); - D_RETURN; -} - -void -bro_table_get_types(BroTable *tbl, - int *key_type, int *val_type) -{ - if (! tbl) - return; - - if (key_type) - *key_type = tbl->tbl_key_type; - if (val_type) - *val_type = tbl->tbl_val_type; -} - - -BroSet * -bro_set_new(void) -{ - BroSet *result; - - D_ENTER; - result = (BroSet*) __bro_table_new(); - D_RETURN_(result); -} - -void -bro_set_free(BroSet *set) -{ - D_ENTER; - __bro_table_free((BroTable*) set); - D_RETURN; -} - -int -bro_set_insert(BroSet *set, int type, const void *val) -{ - int result; - - D_ENTER; - - result = bro_table_insert((BroTable*) set, - type, val, - BRO_TYPE_UNKNOWN, NULL); - - D_RETURN_(result); -} - -int -bro_set_find(BroSet *set, const void *key) -{ - int result; - - D_ENTER; - result = (bro_table_find((BroTable*) set, key) != NULL); - D_RETURN_(result); -} - -int -bro_set_get_size(BroSet *set) -{ - int result; - - D_ENTER; - result = __bro_table_get_size((BroTable*) set); - D_RETURN_(result); -} - -typedef struct bro_set_cb_data -{ - void *user_data; - BroSetCallback cb; -} BroSetCBData; - -static int -bro_set_foreach_cb(void *key, void *val, BroSetCBData *data) -{ - return data->cb(key, data->user_data); -} - -void -bro_set_foreach(BroSet *set, - BroSetCallback cb, - void *user_data) -{ - BroSetCBData data; - - D_ENTER; - - data.user_data = user_data; - data.cb = cb; - - bro_table_foreach((BroTable*) set, - (BroTableCallback) bro_set_foreach_cb, - &data); - - D_RETURN; -} - -void -bro_set_get_type(BroSet *set, int *type) -{ - return bro_table_get_types((BroTable*) set, type, NULL); -} - -/* ------------------------------ Strings ---------------------------- */ - -void -bro_string_init(BroString *bs) -{ - if (! bs) - return; - - memset(bs, 0, sizeof(BroString)); -} - - -int -bro_string_set(BroString *bs, const char *s) -{ - if (! bs || !s) - return FALSE; - - return bro_string_set_data(bs, (const uchar *) s, strlen(s)); -} - - -int -bro_string_set_data(BroString *bs, const uchar *data, int data_len) -{ - uchar *data_copy; - - if (! bs || !data || data_len < 0) - return FALSE; - - if (! (data_copy = malloc(data_len + 1))) - return FALSE; - - memcpy(data_copy, data, data_len); - data_copy[data_len] = '\0'; - - bs->str_len = data_len; - bs->str_val = data_copy; - - return TRUE; -} - - -const uchar * -bro_string_get_data(const BroString *bs) -{ - return bs ? bs->str_val : NULL; -} - - -uint32 -bro_string_get_length(const BroString *bs) -{ - return bs ? bs->str_len : 0; -} - - -BroString * -bro_string_copy(BroString *bs) -{ - BroString *result; - - if (! bs) - return NULL; - - if (! (result = calloc(1, sizeof(BroString)))) - return NULL; - - bro_string_assign(bs, result); - return result; -} - - -void -bro_string_assign(BroString *src, BroString *dst) -{ - if (! src || ! dst) - return; - - bro_string_cleanup(dst); - dst->str_len = src->str_len; - - if (! (dst->str_val = malloc(dst->str_len + 1))) - { - D(("Out of memory.\n")); - dst->str_len = 0; - return; - } - - memcpy(dst->str_val, src->str_val, dst->str_len); - dst->str_val[dst->str_len] = '\0'; -} - - -void -bro_string_cleanup(BroString *bs) -{ - if (! bs) - return; - - if (bs->str_val) - free(bs->str_val); - - memset(bs, 0, sizeof(BroString)); -} - - -void -bro_string_free(BroString *bs) -{ - if (! bs) - return; - - bro_string_cleanup(bs); - free(bs); -} - -/* ----------------------- Pcap Packet Handling ---------------------- */ -#ifdef BRO_PCAP_SUPPORT - -void -bro_conn_set_packet_ctxt(BroConn *bc, int link_type) -{ - if (! bc) - return; - - bc->pcap_link_type = link_type; -} - - -void -bro_conn_get_packet_ctxt(BroConn *bc, int *link_type) -{ - if (! bc) - return; - - if (link_type) - *link_type = bc->pcap_link_type; -} - - -BroPacket * -bro_packet_new(const struct pcap_pkthdr *hdr, const u_char *data, const char *tag) -{ - BroPacket *packet; - - if (! hdr || ! data) - return NULL; - - if (! (packet = calloc(1, sizeof(BroPacket)))) - return NULL; - - packet->pkt_pcap_hdr = *hdr; - packet->pkt_tag = strdup(tag ? tag : ""); - - if (! (packet->pkt_data = malloc(hdr->caplen))) - { - free(packet); - return NULL; - } - - memcpy((u_char *) packet->pkt_data, data, hdr->caplen); - return packet; -} - - -BroPacket * -bro_packet_clone(const BroPacket *src) -{ - BroPacket *dst; - - if (! (dst = calloc(1, sizeof(BroPacket)))) - return NULL; - - if (! __bro_packet_clone(dst, src)) - { - bro_packet_free(dst); - return NULL; - } - - return dst; -} - - -void -bro_packet_free(BroPacket *packet) -{ - if (! packet) - return; - - if (packet->pkt_data) - free((u_char *) packet->pkt_data); - - if (packet->pkt_tag) - free((u_char *) packet->pkt_tag); - - free(packet); -} - -int -bro_packet_send(BroConn *bc, BroPacket *packet) -{ - if (! bc || ! packet) - { - D(("Invalid input.\n")); - return FALSE; - } - - return __bro_io_packet_queue(bc, packet); -} - -#endif - -/* --------------------------- Miscellaneous ------------------------- */ - -double -bro_util_current_time(void) -{ - return __bro_util_get_time(); -} - - -double -bro_util_timeval_to_double(const struct timeval *tv) -{ - return __bro_util_timeval_to_double(tv); -} - - - diff --git a/aux/broccoli/src/bro_attr.c b/aux/broccoli/src/bro_attr.c deleted file mode 100644 index ad92dfe622..0000000000 --- a/aux/broccoli/src/bro_attr.c +++ /dev/null @@ -1,132 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include - -#ifdef __EMX__ -#include -#endif - -#include -#include -#include -#include - - -BroAttr * -__bro_attr_new(void) -{ - BroAttr *attr; - - D_ENTER; - - if (! (attr = calloc(1, sizeof(BroAttr)))) - D_RETURN_(NULL); - - D_RETURN_(attr); -} - - -BroAttr * -__bro_attr_copy(BroAttr *attr) -{ - BroAttr *copy; - - D_ENTER; - - if (! (copy = __bro_attr_new())) - D_RETURN_(NULL); - - if (! attr) - D_RETURN_(NULL); - - copy->tag = attr->tag; - - /* FIXME copy->expr = __bro_sobject_copy((BroSObject *) attr->expr); */ - - D_RETURN_(copy); -} - - -void -__bro_attr_free(BroAttr *attr) -{ - D_ENTER; - - /* FIXME __bro_expr_free(attr->expr); */ - free(attr); - - D_RETURN; -} - - -int -__bro_attr_read(BroAttr *attr, BroConn *bc) -{ - char opt; - - D_ENTER; - - if (! __bro_buf_read_char(bc->rx_buf, &opt)) - D_RETURN_(FALSE); - if (opt) - { - /* FIXME - if (attr->expr) - __bro_expr_free(attr->expr); - if (! (attr->expr = (BroExpr *) __bro_sobject_unserialize(SER_IS_EXPR, buf))) - D_RETURN_(FALSE); - */ - } - - if (! __bro_buf_read_char(bc->rx_buf, &attr->tag)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -int -__bro_attr_write(BroAttr *attr, BroConn *bc) -{ - D_ENTER; - - if (! __bro_buf_write_char(bc->tx_buf, attr->expr ? 1 : 0)) - D_RETURN_(FALSE); - if (attr->expr && ! __bro_sobject_serialize((BroSObject *) attr->expr, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_char(bc->tx_buf, attr->tag)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} diff --git a/aux/broccoli/src/bro_attr.h b/aux/broccoli/src/bro_attr.h deleted file mode 100644 index b82756ee03..0000000000 --- a/aux/broccoli/src/bro_attr.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_attr_h -#define broccoli_attr_h - -#include - -/* Definitions of attribute type identifiers. - * They must match the values of attr_tag in Bro's Attrs.h. - */ -#define BRO_ATTR_OPTIONAL 0 -#define BRO_ATTR_DEFAULT 1 -#define BRO_ATTR_REDEF 2 -#define BRO_ATTR_ROTATE_INTERVAL 3 -#define BRO_ATTR_ROTATE_SIZE 4 -#define BRO_ATTR_ADD_FUNC 5 -#define BRO_ATTR_DEL_FUNC 6 -#define BRO_ATTR_EXPIRE_FUNC 7 -#define BRO_ATTR_EXPIRE_READ 8 -#define BRO_ATTR_EXPIRE_WRITE 9 -#define BRO_ATTR_EXPIRE_CREATE 10 -#define BRO_ATTR_PERSISTENT 11 -#define BRO_ATTR_SYNCHRONIZED 12 -#define BRO_ATTR_POSTPROCESSOR 13 -#define BRO_ATTR_ENCRYPT 14 -#define BRO_ATTR_MATCH 15 - -typedef struct bro_expr -{ -} BroExpr; - -/* NOTE: these attributes do *not* follow the inheritance approach, - * unlike the attributes in Bro. This is because they're not currently - * using the serialization framework like the rest of the Bro objects, - * and all we need for Broccoli purposes is a (non-inherited) simple - * way to read and write an attribute. - */ -typedef struct bro_attr -{ - char tag; - BroExpr *expr; -} BroAttr; - -BroAttr *__bro_attr_new(void); -BroAttr *__bro_attr_copy(BroAttr *attr); -void __bro_attr_free(BroAttr *attr); - -int __bro_attr_read(BroAttr *attr, BroConn *bc); -int __bro_attr_write(BroAttr *attr, BroConn *bc); - -#endif diff --git a/aux/broccoli/src/bro_attrs.c b/aux/broccoli/src/bro_attrs.c deleted file mode 100644 index 8ec4aafc96..0000000000 --- a/aux/broccoli/src/bro_attrs.c +++ /dev/null @@ -1,258 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include - -#ifdef __EMX__ -#include -#endif - -#include -#include -#include -#include - - -BroAttrs * -__bro_attrs_new(void) -{ - BroAttrs *attrs; - - D_ENTER; - - if (! (attrs = calloc(1, sizeof(BroAttrs)))) - D_RETURN_(NULL); - - __bro_attrs_init(attrs); - D_RETURN_(attrs); -} - - -void -__bro_attrs_init(BroAttrs *attrs) -{ - BroSObject *sobj = (BroSObject *) attrs; - - D_ENTER; - - __bro_object_init((BroObject *) attrs); - - sobj->read = (BroSObjectRead) __bro_attrs_read; - sobj->write = (BroSObjectWrite) __bro_attrs_write; - sobj->free = (BroSObjectFree) __bro_attrs_free; - sobj->clone = (BroSObjectClone) __bro_attrs_clone; - sobj->hash = (BroSObjectHash) __bro_attrs_hash; - sobj->cmp = (BroSObjectCmp) __bro_attrs_cmp; - - sobj->type_id = SER_ATTRIBUTES; - - D_RETURN; -} - - -void -__bro_attrs_free(BroAttrs *attrs) -{ - uint32 i; - - D_ENTER; - - __bro_sobject_release((BroSObject *) attrs->type); - - for (i = 0; i < attrs->num_attrs; i++) - __bro_attr_free(attrs->attrs[i]); - free(attrs->attrs); - - __bro_object_free((BroObject *) attrs); - D_RETURN; -} - - -int -__bro_attrs_read(BroAttrs *attrs, BroConn *bc) -{ - uint32 i; - - D_ENTER; - - if (! __bro_object_read((BroObject *) attrs, bc)) - D_RETURN_(FALSE); - - if (attrs->type) - __bro_sobject_release((BroSObject *) attrs->type); - - if (! (attrs->type = (BroType *) __bro_sobject_unserialize(SER_IS_TYPE, bc))) - D_RETURN_(FALSE); - - if (attrs->attrs) - { - for (i = 0; i < attrs->num_attrs; i++) - __bro_attr_free(attrs->attrs[i]); - free(attrs->attrs); - } - - if (! __bro_buf_read_int(bc->rx_buf, &attrs->num_attrs)) - D_RETURN_(FALSE); - - if (! (attrs->attrs = calloc(attrs->num_attrs, sizeof(BroAttr*)))) - D_RETURN_(FALSE); - - for (i = 0; i < attrs->num_attrs; i++) - { - BroAttr *attr; - - if (! (attr = __bro_attr_new())) - D_RETURN_(FALSE); - - if (! __bro_attr_read(attr, bc)) - D_RETURN_(FALSE); - - attrs->attrs[i] = attr; - } - - D_RETURN_(TRUE); -} - - -int -__bro_attrs_write(BroAttrs *attrs, BroConn *bc) -{ - uint32 i; - - D_ENTER; - - if (! __bro_object_write((BroObject *) attrs, bc)) - D_RETURN_(FALSE); - - if (! __bro_sobject_serialize((BroSObject *) attrs->type, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_int(bc->tx_buf, attrs->num_attrs)) - D_RETURN_(FALSE); - - for (i = 0; i < attrs->num_attrs; i++) - { - if (! __bro_sobject_serialize((BroSObject *) attrs->attrs[i], bc)) - D_RETURN_(FALSE); - } - - D_RETURN_(TRUE); -} - - -int -__bro_attrs_clone(BroAttrs *dst, BroAttrs *src) -{ - uint32 i; - - D_ENTER; - - if (! __bro_object_clone((BroObject *) dst, (BroObject *) src)) - D_RETURN_(FALSE); - - if (src->type && ! (dst->type = (BroType *) __bro_sobject_copy((BroSObject *) dst->type))) - D_RETURN_(FALSE); - - if (dst->attrs) - { - for (i = 0; i < dst->num_attrs; i++) - __bro_attr_free(dst->attrs[i]); - free(dst->attrs); - } - - dst->num_attrs = src->num_attrs; - - if (! (dst->attrs = calloc(dst->num_attrs, sizeof(BroAttr *)))) - D_RETURN_(FALSE); - - for (i = 0; i < dst->num_attrs; i++) - { - if (! (dst->attrs[i] = __bro_attr_copy(src->attrs[i]))) - D_RETURN_(FALSE); - } - - D_RETURN_(TRUE); -} - -uint32 -__bro_attrs_hash(BroAttrs *attrs) -{ - uint32 result, i, shift; - - D_ENTER; - - if (! attrs) - D_RETURN_(0); - - result = __bro_sobject_hash((BroSObject*) attrs->type) ^ attrs->num_attrs; - - /* Cycle through the attributes and XOR their tags, also - * cycling through a shifting regime shifting by 0, 8, 16, - * 24, 0, etc. - */ - for (i = 0, shift = 0; i < attrs->num_attrs; i++, shift += 8) - { - uint32 val; - - if (shift > 24) - shift = 0; - - val = (uint32) attrs->attrs[i]->tag; - result ^= val << shift; - } - - D_RETURN_(result); -} - -int -__bro_attrs_cmp(BroAttrs *attrs1, BroAttrs *attrs2) -{ - uint32 i, j; - - D_ENTER; - - if (! __bro_sobject_cmp((BroSObject*) attrs1->type, (BroSObject*) attrs2->type)) - D_RETURN_(FALSE); - - if (attrs1->num_attrs != attrs2->num_attrs) - D_RETURN_(FALSE); - - for (i = 0, j = 0; i < attrs1->num_attrs && attrs2->num_attrs; - i++, j++) - { - if (attrs1->attrs[i]->tag != attrs2->attrs[j]->tag) - D_RETURN_(FALSE); - } - - D_RETURN_(TRUE); -} - diff --git a/aux/broccoli/src/bro_attrs.h b/aux/broccoli/src/bro_attrs.h deleted file mode 100644 index 4c221ce613..0000000000 --- a/aux/broccoli/src/bro_attrs.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_attrs_h -#define broccoli_attrs_h - -#include -#include - -typedef struct bro_attrs -{ - BroObject object; - - BroType *type; - uint32 num_attrs; - BroAttr **attrs; -} BroAttrs; - -BroAttrs *__bro_attrs_new(void); -void __bro_attrs_init(BroAttrs *attrs); -void __bro_attrs_free(BroAttrs *attrs); - -int __bro_attrs_read(BroAttrs *attrs, BroConn *bc); -int __bro_attrs_write(BroAttrs *attrs, BroConn *bc); -int __bro_attrs_clone(BroAttrs *dst, BroAttrs *src); -uint32 __bro_attrs_hash(BroAttrs *attrs); -int __bro_attrs_cmp(BroAttrs *attrs1, BroAttrs *attrs2); - -#endif diff --git a/aux/broccoli/src/bro_buf.c b/aux/broccoli/src/bro_buf.c deleted file mode 100644 index 4d89f108ea..0000000000 --- a/aux/broccoli/src/bro_buf.c +++ /dev/null @@ -1,588 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include - -#ifdef __EMX__ -#include -#endif - -#include -#include -#include -#include - -#define BRO_BUF_DEFAULT 4096 - -#ifdef BRO_DEBUG - -/* Use this to get detailed output of what is read -- - * useful for debugging serialization format bugs. - */ -#define DEBUG_READS - -#endif - -#ifndef DEBUG_READS -# define D(x) -#endif - -BroBuf * -__bro_buf_new(void) -{ - BroBuf *buf; - - if (! (buf = calloc(1, sizeof(BroBuf)))) - return NULL; - - __bro_buf_init(buf); - buf->may_grow = TRUE; - - return buf; -} - -BroBuf * -__bro_buf_new_mem(u_char *mem, int mem_size) -{ - BroBuf *buf; - - if (! mem) - { - D(("Input error.\n")); - return NULL; - } - - if ((size_t) mem_size < sizeof(BroBuf) + BRO_BUF_DEFAULT) - { - D(("Given memory chunk of size %i is not big enough, need at least %i\n", - mem_size, sizeof(BroBuf) + BRO_BUF_DEFAULT)); - return NULL; - } - - buf = (BroBuf *) mem; - memset(buf, 0, sizeof(BroBuf)); - - buf->buf = mem + sizeof(BroBuf); - buf->buf_len = mem_size - sizeof(BroBuf); - buf->may_grow = FALSE; - - return buf; -} - - -void -__bro_buf_free(BroBuf *buf) -{ - if (! buf) - return; - - __bro_buf_cleanup(buf); - free(buf); -} - -void -__bro_buf_init(BroBuf *buf) -{ - D_ENTER; - - if (!buf) - D_RETURN; - - memset(buf, 0, sizeof(BroBuf)); - buf->buf = calloc(1, BRO_BUF_DEFAULT); - buf->buf_len = BRO_BUF_DEFAULT; - - D_RETURN; -} - - -void -__bro_buf_cleanup(BroBuf *buf) -{ - D_ENTER; - - if (!buf) - D_RETURN; - - if (buf->buf) - free(buf->buf); - - memset(buf, 0, sizeof(BroBuf)); - - D_RETURN; -} - - -int -__bro_buf_append(BroBuf *buf, void *data, int data_len) -{ - if (!buf) - return FALSE; - - if (data_len == 0) - return TRUE; - - if (buf->buf_off + data_len >= buf->buf_len) - { - uchar *new_buf; - - if (! buf->may_grow) - { - D(("Cannot expand this buffer, sorry.\n")); - return FALSE; - } - - buf->buf_len += MAX(BRO_BUF_DEFAULT, data_len); - - D(("Reallocating buffer\n")); - if (! (new_buf = realloc(buf->buf, sizeof(uchar) * buf->buf_len))) - { - D(("Realloc'ing buffer failed.\n")); - return FALSE; - } - - buf->buf = new_buf; - } - - memcpy(buf->buf + buf->buf_off, data, data_len); - buf->buf_off += data_len; - - return TRUE; -} - - -void -__bro_buf_consume(BroBuf *buf) -{ - if (!buf || buf->buf_ptr == 0) - return; - - D(("Consuming %i bytes in buffer.\n", buf->buf_ptr)); - memmove(buf->buf, buf->buf + buf->buf_ptr, buf->buf_len - buf->buf_ptr); - buf->buf_off -= buf->buf_ptr; - buf->buf_ptr = 0; -} - - -void -__bro_buf_reset(BroBuf *buf) -{ - if (! buf) - return; - - buf->buf_off = buf->buf_ptr = 0; -} - - -uchar * -__bro_buf_get(BroBuf *buf) -{ - if (!buf) - return NULL; - - return buf->buf; -} - -uchar * -__bro_buf_get_end(BroBuf *buf) -{ - if (!buf) - return NULL; - - return (buf->buf + buf->buf_off); -} - - -uint -__bro_buf_get_size(BroBuf *buf) -{ - if (!buf) - return 0; - - return buf->buf_len; -} - - -uint -__bro_buf_get_used_size(BroBuf *buf) -{ - if (!buf) - return 0; - - return buf->buf_off; -} - - -uchar * -__bro_buf_ptr_get(BroBuf *buf) -{ - if (!buf) - return NULL; - - return (buf->buf + buf->buf_ptr); -} - - -uint32 -__bro_buf_ptr_tell(BroBuf *buf) -{ - if (!buf) - return 0; - - return buf->buf_ptr; -} - - -int -__bro_buf_ptr_seek(BroBuf *buf, int offset, int whence) -{ - if (!buf) - return FALSE; - - switch (whence) - { - case SEEK_SET: - if (offset >= 0 && (uint32) offset <= buf->buf_off) - { - buf->buf_ptr = offset; - return TRUE; - } - break; - - case SEEK_CUR: - if ((int) buf->buf_ptr + offset >= 0 && - buf->buf_ptr + offset <= buf->buf_off) - { - buf->buf_ptr += offset; - return TRUE; - } - break; - - case SEEK_END: - if ((int) buf->buf_off + offset >= 0 && - buf->buf_off + offset <= buf->buf_off) - { - buf->buf_ptr = buf->buf_off + offset; - return TRUE; - } - break; - - default: - break; - } - - return FALSE; -} - - -int -__bro_buf_ptr_check(BroBuf *buf, int size) -{ - if (!buf || size < 0) - return FALSE; - - if (buf->buf_ptr + size > buf->buf_off) - { - D(("Checking for %i bytes available, but have only %i\n", - size, buf->buf_off - buf->buf_ptr)); - return FALSE; - } - - return TRUE; -} - - -int -__bro_buf_ptr_read(BroBuf *buf, void *data, int size) -{ - if (size == 0) - return TRUE; - - if (!buf || !data) - return FALSE; - - if (! __bro_buf_ptr_check(buf, size)) - return FALSE; - - memcpy(data, buf->buf + buf->buf_ptr, size); - buf->buf_ptr += size; - - return TRUE; -} - - -int -__bro_buf_ptr_write(BroBuf *buf, const void *data, int size) -{ - if (! buf || size < 0) - return FALSE; - - if (size == 0) - return TRUE; - - if (! data) - { - D(("Input error -- data length is %i but no data given.\n", size)); - return FALSE; - } - - if (buf->buf_ptr + size >= buf->buf_len) - { - /* Check how much the requested amount is bigger than - * what we have, and add some extra buffering on top of it. - */ - uchar *new_buf; - int inc = size - (buf->buf_off - buf->buf_ptr); - - if (! buf->may_grow) - { - D(("Cannot expand this buffer, sorry.\n")); - return FALSE; - } - - D(("Reallocating buffer\n")); - - if (! (new_buf = realloc(buf->buf, buf->buf_len + inc + BRO_BUF_DEFAULT))) - { - D(("Realloc'ing buffer failed.\n")); - return FALSE; - } - - buf->buf_len += inc + BRO_BUF_DEFAULT; - buf->buf = new_buf; - } - - memcpy(buf->buf + buf->buf_ptr, data, size); - buf->buf_ptr += size; - - if (buf->buf_off < buf->buf_ptr) - buf->buf_off = buf->buf_ptr; - - return TRUE; -} - - - -/* I/O API below ---------------------------------------------------- */ - -int -__bro_buf_read_data(BroBuf *buf, void *dest, int size) -{ - return __bro_buf_ptr_read(buf, dest, size); -} - - -int -__bro_buf_read_char(BroBuf *buf, char *val) -{ - int result; - - result = __bro_buf_ptr_read(buf, val, sizeof(char)); - D(("Read char: %i/0x%02x\n", *val, *val)); - - return result; -} - - -int -__bro_buf_read_string(BroBuf *buf, BroString *val) -{ - if (!buf || !val) - return FALSE; - - bro_string_init(val); - - if (! __bro_buf_read_int(buf, &val->str_len)) - return FALSE; - - /* We create space for the string's length plus one extra byte that - * we use as the string terminator so things work with normal C strings. - */ - if (! (val->str_val = malloc(val->str_len + 1))) - return FALSE; - - if (val->str_len > 0) - { - if (! (__bro_buf_ptr_read(buf, val->str_val, val->str_len))) - { - free(val->str_val); - return FALSE; - } - } - - /* Terminate the string. - */ - val->str_val[val->str_len] = '\0'; - - D(("Read string: '%s'\n", val->str_val)); - return TRUE; -} - - -int -__bro_buf_read_double(BroBuf *buf, double *d) -{ - if (! buf || ! d) - return FALSE; - - if (! __bro_buf_ptr_read(buf, d, sizeof(double))) - return FALSE; - - *d = __bro_util_ntohd(*d); - D(("Read double: %f\n", *d)); - - return TRUE; -} - - -int -__bro_buf_read_int(BroBuf *buf, uint32 *i) -{ - if (! __bro_buf_ptr_read(buf, i, sizeof(uint32))) - return FALSE; - - *i = ntohl(*i); - D(("Read int: %i/0x%08x\n", *i, *i)); - - return TRUE; -} - - -int -__bro_buf_read_short(BroBuf *buf, uint16 *i) -{ - if (! __bro_buf_ptr_read(buf, i, sizeof(uint16))) - return FALSE; - - *i = ntohs(*i); - D(("Read short: %i/0x%04x\n", *i, *i)); - - return TRUE; -} - - -int -__bro_buf_write_data(BroBuf *buf, const void *data, int size) -{ - return __bro_buf_ptr_write(buf, data, size); -} - - -int -__bro_buf_write_char(BroBuf *buf, char val) -{ - int result; - - result = __bro_buf_ptr_write(buf, &val, sizeof(char)); - D(("Wrote char: %i/0x%02x\n", val, val)); - return result; -} - - -int -__bro_buf_write_string(BroBuf *buf, BroString *val) -{ - int result; - BroString tmp_val; - - if (! buf) - return FALSE; - - if (! val) - { - tmp_val.str_val = (uchar*) ""; - tmp_val.str_len = 0; - - val = &tmp_val; - } - - if (! (__bro_buf_write_int(buf, val->str_len))) - return FALSE; - - result = __bro_buf_write_data(buf, val->str_val, val->str_len); - - D(("Wrote string: '%s'\n", val->str_val)); - return result; -} - - -int -__bro_buf_write_double(BroBuf *buf, double d) -{ - int result; - double d_tmp; - - if (! buf) - return FALSE; - - d_tmp = __bro_util_htond(d); - result = __bro_buf_ptr_write(buf, &d_tmp, sizeof(double)); - D(("Wrote double: %f\n", d)); - - return result; -} - - -int -__bro_buf_write_int(BroBuf *buf, uint32 i) -{ - int result; - uint32 i_tmp; - - if (! buf) - return FALSE; - - i_tmp = htonl(i); - result = __bro_buf_write_data(buf, &i_tmp, sizeof(uint32)); - D(("Wrote int: %i/0x%08x\n", i, i)); - - return result; -} - - -int -__bro_buf_write_short(BroBuf *buf, uint16 i) -{ - int result; - uint16 i_tmp; - - if (! buf) - return FALSE; - - i_tmp = htons(i); - result =__bro_buf_write_data(buf, &i_tmp, sizeof(uint16)); - D(("Wrote short: %i/0x%04x\n", i, i)); - - return result; -} diff --git a/aux/broccoli/src/bro_buf.h b/aux/broccoli/src/bro_buf.h deleted file mode 100644 index e378b9d85d..0000000000 --- a/aux/broccoli/src/bro_buf.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_buf_h -#define broccoli_buf_h - -#include -#include - -/* - * BroBufs are self-allocating, seekable, and read/writable - * buffers. You can repeatedly append data to the buffer - * while the buffer makes sure it is large enough to handle - * the amount requested. A buffer has a content pointer that - * points to an arbitrary location between the start of the - * buffer and the first byte after the last byte currently - * used in the buffer (buf_off). The content pointer can be - * seeked to arbitrary locations, and data can be copied from - * the buffer, adjusting the content pointer at the same time. - * - * Illustration: - * - * <---------------- allocated buffer space ------------> - * <======== used buffer space ========> - * ^ ^ ^ ^ - * | | | | - * `buf `buf_ptr `buf_off `buf_len - */ - -struct bro_buf { - uchar *buf; - - /* The size of the allocated buffer BUF: */ - uint32 buf_len; - - /* The first byte in BUF after the ones occupied */ - uint32 buf_off; - - /* A pointer to a position between the start of BUF - * and BUF + BUF_OFF. - */ - uint32 buf_ptr; - - /* Flag that indicates whether or not the allocated buffer - * can grow or not. It can't if we require the buffer to - * live in a fixed amount of memory. - */ - int may_grow; -}; - -/* See API comments in broccoli.h for details */ - -BroBuf *__bro_buf_new(void); - -/* Creates a new buffer using a given chunk of memory. We use - * this for example to allocate a buffer in shared memory. - */ -BroBuf *__bro_buf_new_mem(u_char *mem, int mem_size); - -void __bro_buf_free(BroBuf *buf); - -/* Initializes an existing buffer structure to default values */ -void __bro_buf_init(BroBuf *buf); -void __bro_buf_cleanup(BroBuf *buf); - -int __bro_buf_append(BroBuf *buf, void *data, int data_len); -void __bro_buf_consume(BroBuf *buf); -void __bro_buf_reset(BroBuf *buf); - -uchar *__bro_buf_get(BroBuf *buf); -uchar *__bro_buf_get_end(BroBuf *buf); -uint __bro_buf_get_size(BroBuf *buf); -uint __bro_buf_get_used_size(BroBuf *buf); -uchar *__bro_buf_ptr_get(BroBuf *buf); -uint32 __bro_buf_ptr_tell(BroBuf *buf); -int __bro_buf_ptr_seek(BroBuf *buf, int offset, int whence); -int __bro_buf_ptr_check(BroBuf *buf, int size); -int __bro_buf_ptr_read(BroBuf *buf, void *data, int size); -int __bro_buf_ptr_write(BroBuf *buf, const void *data, int size); - - -/* Buffer-based I/O API --------------------------------------------- */ - -/* The read functions read data from the given buffer into the variables - * pointed to by the arguments, the write functions to the opposite and - * write the passed-in parameters into the given buffers. - */ - -int __bro_buf_read_data(BroBuf *buf, void *dest, int size); -int __bro_buf_read_char(BroBuf *buf, char *val); -int __bro_buf_read_string(BroBuf *buf, BroString *val); -int __bro_buf_read_double(BroBuf *buf, double *d); -int __bro_buf_read_int(BroBuf *buf, uint32 *i); -int __bro_buf_read_short(BroBuf *buf, uint16 *i); - -int __bro_buf_write_data(BroBuf *buf, const void *data, int size); -int __bro_buf_write_char(BroBuf *buf, char val); -int __bro_buf_write_string(BroBuf *buf, BroString *val); -int __bro_buf_write_double(BroBuf *buf, double d); -int __bro_buf_write_int(BroBuf *buf, uint32 i); -int __bro_buf_write_short(BroBuf *buf, uint16 i); - -#endif diff --git a/aux/broccoli/src/bro_config.c b/aux/broccoli/src/bro_config.c deleted file mode 100644 index 3edd6abc12..0000000000 --- a/aux/broccoli/src/bro_config.c +++ /dev/null @@ -1,492 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __EMX__ -#include -#endif - -#include -#include -#include -#include - -typedef enum { - BRO_CONF_INT, - BRO_CONF_DBL, - BRO_CONF_STR, - BRO_CONF_NET, - BRO_CONF_ERR -} BroConfType; - -typedef struct bro_conf_it -{ - char *ci_name; - BroConfType ci_type; - - union { - int ci_int; - double ci_dbl; - char *ci_str; - } ci_val; - -#define ci_int ci_val.ci_int -#define ci_dbl ci_val.ci_dbl -#define ci_str ci_val.ci_str - -} BroConfIt; - - -static char *config_file = BRO_SYSCONF_FILE; - -/* The name of the current domain, may be NULL. */ -static char *cur_dom; - -/* The default domain's configuration, used when cur_dom == NULL. */ -static BroHT *default_conf; - -/* While parsing the configuration, we switch from domain to domain - * as contained in the file, but leave the user's currently selected - * domain unaffected. We point to the current domain while parsing - * using parsing_conf, which by default is the same as default_conf. - */ -static BroHT *parsing_conf; - -/* A hashtable of hashtables, indexed by domain names. The inner - * hash tables contain BroConfIt items, indexed by strings. - */ -static BroHT *dom_conf; - -extern int __bro_parse_config(const char *filename); - - -static BroConfIt * -conf_item_new(const char *name, BroConfType type, void *val) -{ - BroConfIt *ci; - - if (! (ci = calloc(1, sizeof(BroConfIt)))) - return NULL; - - ci->ci_name = strdup(name); - ci->ci_type = type; - - switch (type) - { - case BRO_CONF_INT: - ci->ci_int = *((int*) val); - break; - - case BRO_CONF_DBL: - ci->ci_dbl = *((double*) val); - break; - - case BRO_CONF_STR: - ci->ci_str = strdup((char *) val); - break; - - default: - free(ci); - return NULL; - } - - return ci; -} - -static void -conf_item_free(BroConfIt *ci) -{ - if (!ci) - return; - - if (ci->ci_name) - free(ci->ci_name); - - if (ci->ci_type == BRO_CONF_STR) - { - memset(ci->ci_str, 0, strlen(ci->ci_str)); - free(ci->ci_str); - ci->ci_str = NULL; - } - - free(ci); -} - -static int -conf_permissions_ok(struct stat *st) -{ - /* We consider the file okay if it is not a link, only - * the owner can read it, and the current user can open it. - */ - if (S_ISREG(st->st_mode) && /* regular file */ - (st->st_mode & S_IRUSR) && /* user-readable */ - ! (st->st_mode & S_IXUSR) && /* not user-exec'able (paranoia) */ - ! (st->st_mode & S_IRWXG) && /* no group permissions */ - ! (st->st_mode & S_IRWXO)) /* no other permissions */ - { - if (st->st_uid == geteuid()) - return TRUE; - } - - fprintf(stderr, "Insufficient permissions for reading ~/.broccoli.conf.\n"); - fprintf(stderr, "NOTE: ~/.broccoli.conf must be regular file and -rw-------\n"); - return FALSE; -} - -static char * -get_passwd_home(void) -{ -#if defined(HAVE_GETEUID) && defined(HAVE_GETPWUID) - struct passwd *passwd; - uid_t uid = geteuid(); - - if ( (passwd = getpwuid(uid))) - { - D(("Getting home directory from user %u's passwd entry: %s.\n", uid, passwd->pw_dir)); - return strdup(passwd->pw_dir); - } -#endif - - return NULL; -} - - -void -__bro_conf_init(void) -{ - static int deja_vu = FALSE; - struct stat st; - char *pwd_home = NULL; - char home_config[MAXPATHLEN]; - char home_config2[MAXPATHLEN]; - int try_env = TRUE, debug_messages, debug_calltrace; - - if (deja_vu) - return; - - home_config[0] = '\0'; - home_config2[0] = '\0'; - - parsing_conf = default_conf = __bro_ht_new(__bro_ht_str_hash, - __bro_ht_str_cmp, - NULL, - (BroHTFreeFunc)conf_item_free, - FALSE); - - dom_conf = __bro_ht_new(__bro_ht_str_hash, - __bro_ht_str_cmp, - __bro_ht_mem_free, - (BroHTFreeFunc)__bro_ht_free, - FALSE); - - /* Now figure out what config file to read: if the user - * has a ~/.broccoli.conf, use that, otherwise use the - * global one. We first try via the passwd entry, then - * fall back to using $HOME. - */ - if ( (pwd_home = get_passwd_home())) - { - __bro_util_snprintf(home_config, MAXPATHLEN, "%s/.broccoli.conf", pwd_home); - free(pwd_home); - - if (stat(home_config, &st) == 0 && conf_permissions_ok(&st)) - { - config_file = strdup(home_config); - try_env = FALSE; - } - } - - if (try_env) - { - __bro_util_snprintf(home_config2, MAXPATHLEN, "%s/.broccoli.conf", getenv("HOME")); - - /* Only check this variant if it didn't yield the same file as the - * pwd-based filename. - */ - if (strcmp(home_config, home_config2) && - stat(home_config2, &st) == 0 && conf_permissions_ok(&st)) - config_file = strdup(home_config2); - } - - __bro_parse_config(config_file); - deja_vu = TRUE; - - /* Read out debugging verbosity settings and assign if found. */ - if (__bro_conf_get_int("/broccoli/debug_messages", &debug_messages)) - bro_debug_messages = debug_messages; - if (__bro_conf_get_int("/broccoli/debug_calltrace", &debug_calltrace)) - bro_debug_calltrace = debug_calltrace; - -} - -static BroHT * -assert_domain(void) -{ - BroHT *conf = default_conf; - - D(("Selecting configuration domain, name is %s\n", cur_dom)); - - if (cur_dom && ! (conf = (BroHT *) __bro_ht_get(dom_conf, cur_dom))) - { - D(("Allocating domain '%s'\n", cur_dom)); - - conf = __bro_ht_new(__bro_ht_str_hash, - __bro_ht_str_cmp, - NULL, - (BroHTFreeFunc)conf_item_free, - FALSE); - - __bro_ht_add(dom_conf, strdup(cur_dom), conf); - } - - return conf; -} - - -void -__bro_conf_set_domain(const char *new_domain) -{ - /* First reset to the default domain */ - if (cur_dom) - free(cur_dom); - cur_dom = NULL; - - /* Then if given, switch to the new one. */ - if (new_domain && *new_domain) - { - char *str; - - str = cur_dom = strdup(new_domain); - - while (*str != '\0') - { - *str = tolower(*str); - str++; - } - - D(("Configuration domain set to '%s'\n", cur_dom)); - } -} - - -void -__bro_conf_set_storage_domain(const char *storage_domain) -{ - if (! storage_domain || ! *storage_domain) - { - parsing_conf = default_conf; - return; - } - - if (! (parsing_conf = (BroHT *) __bro_ht_get(dom_conf, storage_domain))) - { - D(("Allocating domain '%s'\n", storage_domain)); - - parsing_conf = __bro_ht_new(__bro_ht_str_hash, - __bro_ht_str_cmp, - NULL, - (BroHTFreeFunc)conf_item_free, - FALSE); - - __bro_ht_add(dom_conf, strdup(storage_domain), parsing_conf); - } -} - - -const char * -__bro_conf_get_domain(void) -{ - return cur_dom; -} - - -void -__bro_conf_add_int(const char *val_name, int val) -{ - BroConfIt *ci; - - if (! (ci = conf_item_new(val_name, BRO_CONF_INT, &val))) - return; - - __bro_ht_add(parsing_conf, ci->ci_name, ci); -} - - -void -__bro_conf_add_dbl(const char *val_name, double val) -{ - BroConfIt *ci; - - if (! (ci = conf_item_new(val_name, BRO_CONF_DBL, &val))) - return; - - __bro_ht_add(parsing_conf, ci->ci_name, ci); -} - - -void -__bro_conf_add_str(const char *val_name, char *val) -{ - BroConfIt *ci; - - if (! (ci = conf_item_new(val_name, BRO_CONF_STR, val))) - return; - - __bro_ht_add(parsing_conf, ci->ci_name, ci); -} - - -int -__bro_conf_get_int(const char *val_name, int *val) -{ - BroConfIt *ci; - BroHT *conf; - - __bro_conf_init(); - conf = assert_domain(); - - do { - if (! (ci = __bro_ht_get(conf, (void*) val_name))) - break; - if (ci->ci_type != BRO_CONF_INT) - break; - - *val = ci->ci_int; - return TRUE; - - } while (0); - - do { - if (! (ci = __bro_ht_get(default_conf, (void*) val_name))) - break; - if (ci->ci_type != BRO_CONF_INT) - break; - - *val = ci->ci_int; - return TRUE; - - } while (0); - - return FALSE; -} - - -int -__bro_conf_get_dbl(const char *val_name, double *val) -{ - BroConfIt *ci; - BroHT *conf; - - __bro_conf_init(); - conf = assert_domain(); - - do { - if (! (ci = __bro_ht_get(conf, (void*) val_name))) - break; - if (ci->ci_type != BRO_CONF_DBL) - break; - - *val = ci->ci_dbl; - return TRUE; - } while (0); - - do { - if (! (ci = __bro_ht_get(default_conf, (void*) val_name))) - break; - if (ci->ci_type != BRO_CONF_DBL) - break; - - *val = ci->ci_dbl; - return TRUE; - } while (0); - - return FALSE; -} - - -const char * -__bro_conf_get_str(const char *val_name) -{ - BroConfIt *ci; - BroHT *conf; - - __bro_conf_init(); - conf = assert_domain(); - - do { - if (! (ci = __bro_ht_get(conf, (void*) val_name))) - break; - if (ci->ci_type != BRO_CONF_STR) - break; - - return ci->ci_str; - } while (0); - - do { - if (! (ci = __bro_ht_get(default_conf, (void*) val_name))) - break; - if (ci->ci_type != BRO_CONF_STR) - break; - - return ci->ci_str; - } while (0); - - return NULL; -} - - -int -__bro_conf_forget_item(const char *val_name) -{ - BroConfIt *ci; - BroHT *conf; - - __bro_conf_init(); - conf = assert_domain(); - - if (! (ci = __bro_ht_del(conf, (void*) val_name))) - { - if (! (ci = __bro_ht_del(default_conf, (void*) val_name))) - return FALSE; - } - - conf_item_free(ci); - return TRUE; -} - diff --git a/aux/broccoli/src/bro_config.h b/aux/broccoli/src/bro_config.h deleted file mode 100644 index 91f22c1336..0000000000 --- a/aux/broccoli/src/bro_config.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_config_h -#define broccoli_config_h - -void __bro_conf_init(void); -void __bro_conf_set_domain(const char *domain); -void __bro_conf_set_storage_domain(const char *domain); -const char *__bro_conf_get_domain(void); - -void __bro_conf_add_int(const char *val_name, int val); -void __bro_conf_add_dbl(const char *val_name, double val); -void __bro_conf_add_str(const char *val_name, char *val); - -int __bro_conf_get_int(const char *val_name, int *val); -int __bro_conf_get_dbl(const char *val_name, double *val); -const char * __bro_conf_get_str(const char *val_name); - -int __bro_conf_forget_item(const char *val_name); - -#endif diff --git a/aux/broccoli/src/bro_debug.c b/aux/broccoli/src/bro_debug.c deleted file mode 100644 index d5162268e8..0000000000 --- a/aux/broccoli/src/bro_debug.c +++ /dev/null @@ -1,90 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifdef HAVE_CONFIG_H -# include -#endif - -#include -#include - -#include -#include - -int bro_debug_calltrace = 0; -int bro_debug_messages = 0; - -static int calldepth = 0; - -static void -debug_whitespace(void) -{ - int i; - - for (i = 0; i < 2*calldepth; i++) - fprintf(stderr, "-"); -} - - -void -bro_debug(const char *fmt, ...) -{ - va_list argp; - - if (bro_debug_messages) - { - va_start(argp, fmt); - vfprintf(stderr, fmt, argp); - va_end(argp); - } -} - - -void -bro_debug_enter(const char *function, int line) -{ - if (! bro_debug_calltrace) - return; - - fprintf(stderr, "%u ", getpid()); - calldepth++; - debug_whitespace(); - fprintf(stderr, "> %s(%i)\n", function, line); -} - - -void -bro_debug_return(const char *function, int line) -{ - if (! bro_debug_calltrace) - return; - - fprintf(stderr, "%u <", getpid()); - debug_whitespace(); - fprintf(stderr, " %s(%i)\n", function, line); - - if (--calldepth < 0) - calldepth = 0; -} diff --git a/aux/broccoli/src/bro_debug.h b/aux/broccoli/src/bro_debug.h deleted file mode 100644 index cc60f5af38..0000000000 --- a/aux/broccoli/src/bro_debug.h +++ /dev/null @@ -1,81 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef __broccoli_debug_h -#define __broccoli_debug_h - -#include -#include - -#include -#include - -void bro_debug_enter(const char *function, int line); -void bro_debug_return(const char *function, int line); - -#ifdef BRO_DEBUG - -void bro_debug(const char *msg, ...); - -/** - * D - prints debugging output - * @x: debugging information. - * - * Use this macro to output debugging information. @x is - * the content as you would pass it to printf(), including - * braces to make the arguments appear as one argument to - * the macro. The macro is void if BRO_DEBUG is not defined - * at compile time. - */ -#undef D -#define D(x) do { bro_debug("%u %f %s/%i ", getpid(), __bro_util_get_time(), __FILE__, __LINE__); bro_debug x ; } while (0) - -#undef D_ENTER -#define D_ENTER bro_debug_enter(__FUNCTION__, __LINE__) - -#undef D_RETURN -#define D_RETURN do { bro_debug_return(__FUNCTION__, __LINE__); return; } while (0) - -#undef D_RETURN_ -#define D_RETURN_(x) do { bro_debug_return(__FUNCTION__, __LINE__); return (x); } while (0) - -#else - -#undef D -#define D(x) - -#undef D_ENTER -#define D_ENTER - -#undef D_RETURN -#define D_RETURN return - -#undef D_RETURN_ -#define D_RETURN_(x) return (x) - -#endif /* BRO_DEBUG */ - -#endif - diff --git a/aux/broccoli/src/bro_event.c b/aux/broccoli/src/bro_event.c deleted file mode 100644 index 45b0dc1f9f..0000000000 --- a/aux/broccoli/src/bro_event.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __EMX__ -#include -#endif - -#include -#include -#include -#include -#include - -BroEvent * -__bro_event_new(BroString *name) -{ - BroEvent *ev; - - if (!name) - return NULL; - - if (! (ev = calloc(1, sizeof(BroEvent)))) - return NULL; - - if (! bro_string_set_data(&(ev->name), name->str_val, name->str_len)) - { - free(ev); - return NULL; - } - - return ev; -} - - -void -__bro_event_free(BroEvent *ev) -{ - if (!ev) - return; - - bro_string_cleanup(&ev->name); - __bro_list_free(ev->val_list, (BroFunc) __bro_sobject_release); - free(ev); -} - - -BroEvent * -__bro_event_copy(BroEvent *ev) -{ - BroEvent *ev_copy; - BroVal *val, *val_copy; - BroList *l; - - if (! ev) - return NULL; - - if (! (ev_copy = __bro_event_new(&ev->name))) - return NULL; - - for (l = ev->val_list; l; l = __bro_list_next(l)) - { - val = __bro_list_data(l); - - if (! (val_copy = (BroVal *) __bro_sobject_copy((BroSObject *) val))) - { - __bro_event_free(ev_copy); - return NULL; - } - - __bro_event_add_val(ev_copy, val_copy); - } - - D(("Copied event has %i arguments.\n", __bro_list_length(ev->val_list))); - - return ev_copy; -} - - -const char * -__bro_event_get_name(BroEvent *ev) -{ - if (! ev) - return NULL; - - return (const char*) ev->name.str_val; -} - - -int -__bro_event_serialize(BroEvent *ev, BroConn *bc) -{ - BroVal *val; - BroList *l; - - D_ENTER; - - /* Prepare the beginning of a serialized event call -- - * event identifier, event name plus argument description. - */ - if (! __bro_buf_write_char(bc->tx_buf, 'e')) - D_RETURN_(FALSE); - - if (! __bro_buf_write_string(bc->tx_buf, &ev->name)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_double(bc->tx_buf, __bro_util_get_time())) - D_RETURN_(FALSE); - - if (! __bro_buf_write_int(bc->tx_buf, ev->val_len)) - D_RETURN_(FALSE); - - /* Now serialize each remaining parameter into the buffer: */ - D(("Serializing event parameters\n")); - for (l = ev->val_list; l; l = __bro_list_next(l)) - { - val = __bro_list_data(l); - - if (! __bro_sobject_serialize((BroSObject *) val, bc)) - D_RETURN_(FALSE); - - D((" Serialized one argument\n")); - } - - D_RETURN_(TRUE); -} - - -BroEvent * -__bro_event_unserialize(BroConn *bc) -{ - int i; - BroString ev_name; - double ev_ts; - uint32 ev_args; - BroEvent *ev = NULL; - BroVal *val = NULL; - - D_ENTER; - - if (! __bro_buf_read_string(bc->rx_buf, &ev_name)) - { - D(("Couldn't read event name.\n")); - D_RETURN_(NULL); - } - - if (! __bro_buf_read_double(bc->rx_buf, &ev_ts)) - { - D(("Couldn't read event time.\n")); - bro_string_cleanup(&ev_name); - D_RETURN_(NULL); - } - - if (! __bro_buf_read_int(bc->rx_buf, &ev_args)) - { - D(("Couldn't read number of event arguments.\n")); - bro_string_cleanup(&ev_name); - D_RETURN_(NULL); - } - - D(("Reading %i arguments for event %s\n", ev_args, ev_name.str_val)); - ev = __bro_event_new(&ev_name); - ev->ts = ev_ts; - bro_string_cleanup(&ev_name); - - for (i = 0; i < (int) ev_args; i++) - { - D(("Reading parameter %i\n", i+1)); - if (! (val = (BroVal *) __bro_sobject_unserialize(SER_IS_VAL, bc))) - { - D(("Couldn't read parameter val %i.\n", i+1)); - __bro_event_free(ev); - D_RETURN_(NULL); - } - - __bro_event_add_val(ev, val); - } - - D_RETURN_(ev); -} - - -void -__bro_event_add_val(BroEvent *ev, BroVal *v) -{ - D_ENTER; - ev->val_list = __bro_list_append(ev->val_list, v); - ev->val_len++; - D_RETURN; -} - - -int -__bro_event_set_val(BroEvent *ev, int val_num, BroVal *v) -{ - BroList *l; - - D_ENTER; - - if (val_num < 0 || val_num >= ev->val_len) - { - D(("Invalid val index: given %i, having %i elements.\n", val_num, ev->val_len)); - D_RETURN_(FALSE); - } - - if ( (l = __bro_list_nth(ev->val_list, val_num))) - { - BroVal *val = __bro_list_set_data(l, v); - __bro_sobject_release((BroSObject *) val); - D_RETURN_(TRUE); - } - - D_RETURN_(FALSE); -} diff --git a/aux/broccoli/src/bro_event.h b/aux/broccoli/src/bro_event.h deleted file mode 100644 index 5a65c85320..0000000000 --- a/aux/broccoli/src/bro_event.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_event_h -#define broccoli_event_h - -#include -#include - -BroEvent *__bro_event_new(BroString *name); -void __bro_event_free(BroEvent *be); -BroEvent *__bro_event_copy(BroEvent *be); -const char *__bro_event_get_name(BroEvent *be); - -int __bro_event_serialize(BroEvent *be, BroConn *bc); -BroEvent *__bro_event_unserialize(BroConn *bc); - -void __bro_event_add_val(BroEvent *be, BroVal *val); -int __bro_event_set_val(BroEvent *be, int val_num, BroVal *val); - -#endif diff --git a/aux/broccoli/src/bro_event_reg.c b/aux/broccoli/src/bro_event_reg.c deleted file mode 100644 index 67aa1b8860..0000000000 --- a/aux/broccoli/src/bro_event_reg.c +++ /dev/null @@ -1,643 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include - -#ifdef __EMX__ -#include -#endif - -#include -#include -#include -#include -#include - -typedef void (*BroEvDispatcher)(BroConn *bc, BroEventCB *cb, BroEvent *ev); - -#define DISPATCH_TABLE_SIZE 15 - -/* Goes through all vals in the given event ev and extracts - * from each val a pointer to its actual value, storing it - * into the vals array. - */ -static int -event_reg_init_vals(BroEvent *ev, void **vals) -{ - int i; - BroList *l; - BroVal *val; - - for (i = 0, l = ev->val_list; l; i++, l = __bro_list_next(l)) - { - val = __bro_list_data(l); - - if (! __bro_val_get_data(val, NULL, &(vals[i]))) - { - D(("Error during callback parameter marshaling of parameter %i\n", i)); - return FALSE; - } - } - - return TRUE; -} - -/* Goes through all vals in the given event ev and extracts - * from each val a pointer to its actual value and the type - * of the val, storing it into the given BroEvArg and BroValMeta - * structures. - */ -static int -event_reg_init_args(BroEvent *ev, BroEvArg *args) -{ - int i; - BroList *l; - BroVal *val; - - for (i = 0, l = ev->val_list; l; l = __bro_list_next(l), args++, i++) - { - val = __bro_list_data(l); - - if (! __bro_val_get_data(val, &args->arg_type, &args->arg_data)) - { - D(("Error during callback parameter marshaling of parameter %i\n", i)); - return FALSE; - } - } - - return TRUE; -} - -static void -dispatcher_compact(BroConn *bc, BroEventCB *cb, BroEvent *ev) -{ - BroEvMeta meta; - BroEvArg *args = NULL; - - memset(&meta, 0, sizeof(meta)); - - if (! (args = calloc(ev->val_len, sizeof(BroEvArg)))) { - D(("Out of memory when allocating %d BroEvArgs\n", ev->val_len)); - return; - } - - meta.ev_name = (const char*) bro_string_get_data(&ev->name); - meta.ev_ts = ev->ts; - meta.ev_numargs = ev->val_len; - meta.ev_args = args; - meta.ev_start = (const uchar*) bc->rx_ev_start; - meta.ev_end = (const uchar*) bc->rx_ev_end; - - if (! event_reg_init_args(ev, args)) { - free(args); - return; - } - - cb->cb_compact_func(bc, cb->cb_user_data, &meta); - - free(args); -} - -static void -dispatcher0(BroConn *bc, BroEventCB *cb, BroEvent *ev) -{ - cb->cb_expanded_func(bc, cb->cb_user_data); - return; ev = 0; -} - -static void -dispatcher1(BroConn *bc, BroEventCB *cb, BroEvent *ev) -{ - void *vals[1]; - - if (! event_reg_init_vals(ev, vals)) - return; - - cb->cb_expanded_func(bc, cb->cb_user_data, vals[0]); -} - -static void -dispatcher2(BroConn *bc, BroEventCB *cb, BroEvent *ev) -{ - void *vals[2]; - - if (! event_reg_init_vals(ev, vals)) - return; - - cb->cb_expanded_func(bc, cb->cb_user_data, vals[0], vals[1]); -} - -static void -dispatcher3(BroConn *bc, BroEventCB *cb, BroEvent *ev) -{ - void *vals[3]; - - if (! event_reg_init_vals(ev, vals)) - return; - - cb->cb_expanded_func(bc, cb->cb_user_data, vals[0], vals[1], vals[2]); -} - -static void -dispatcher4(BroConn *bc, BroEventCB *cb, BroEvent *ev) -{ - void *vals[4]; - - if (! event_reg_init_vals(ev, vals)) - return; - - cb->cb_expanded_func(bc, cb->cb_user_data, vals[0], vals[1], vals[2], vals[3]); -} - -static void -dispatcher5(BroConn *bc, BroEventCB *cb, BroEvent *ev) -{ - void *vals[5]; - - if (! event_reg_init_vals(ev, vals)) - return; - - cb->cb_expanded_func(bc, cb->cb_user_data, vals[0], vals[1], vals[2], - vals[3], vals[4]); -} - -static void -dispatcher6(BroConn *bc, BroEventCB *cb, BroEvent *ev) -{ - void *vals[6]; - - if (! event_reg_init_vals(ev, vals)) - return; - - cb->cb_expanded_func(bc, cb->cb_user_data, vals[0], vals[1], vals[2], - vals[3], vals[4], vals[5]); -} - -static void -dispatcher7(BroConn *bc, BroEventCB *cb, BroEvent *ev) -{ - void *vals[7]; - - if (! event_reg_init_vals(ev, vals)) - return; - - cb->cb_expanded_func(bc, cb->cb_user_data, vals[0], vals[1], vals[2], - vals[3], vals[4], vals[5], vals[6]); -} - -static void -dispatcher8(BroConn *bc, BroEventCB *cb, BroEvent *ev) -{ - void *vals[8]; - - if (! event_reg_init_vals(ev, vals)) - return; - - cb->cb_expanded_func(bc, cb->cb_user_data, vals[0], vals[1], vals[2], - vals[3], vals[4], vals[5], vals[6], vals[7]); -} - -static void -dispatcher9(BroConn *bc, BroEventCB *cb, BroEvent *ev) -{ - void *vals[9]; - - if (! event_reg_init_vals(ev, vals)) - return; - - cb->cb_expanded_func(bc, cb->cb_user_data, vals[0], vals[1], vals[2], - vals[3], vals[4], vals[5], vals[6], vals[7], - vals[8]); -} - -static void -dispatcher10(BroConn *bc, BroEventCB *cb, BroEvent *ev) -{ - void *vals[10]; - - if (! event_reg_init_vals(ev, vals)) - return; - - cb->cb_expanded_func(bc, cb->cb_user_data, vals[0], vals[1], vals[2], - vals[3], vals[4], vals[5], vals[6], vals[7], - vals[8], vals[9]); -} - -static void -dispatcher11(BroConn *bc, BroEventCB *cb, BroEvent *ev) -{ - void *vals[11]; - - if (! event_reg_init_vals(ev, vals)) - return; - - cb->cb_expanded_func(bc, cb->cb_user_data, vals[0], vals[1], vals[2], - vals[3], vals[4], vals[5], vals[6], vals[7], - vals[8], vals[9], vals[10]); -} - -static void -dispatcher12(BroConn *bc, BroEventCB *cb, BroEvent *ev) -{ - void *vals[12]; - - if (! event_reg_init_vals(ev, vals)) - return; - - cb->cb_expanded_func(bc, cb->cb_user_data, vals[0], vals[1], vals[2], - vals[3], vals[4], vals[5], vals[6], vals[7], - vals[8], vals[9], vals[10], vals[11]); -} - -static void -dispatcher13(BroConn *bc, BroEventCB *cb, BroEvent *ev) -{ - void *vals[13]; - - if (! event_reg_init_vals(ev, vals)) - return; - - cb->cb_expanded_func(bc, cb->cb_user_data, vals[0], vals[1], vals[2], - vals[3], vals[4], vals[5], vals[6], vals[7], - vals[8], vals[9], vals[10], vals[11], vals[12]); -} - -static void -dispatcher14(BroConn *bc, BroEventCB *cb, BroEvent *ev) -{ - void *vals[14]; - - if (! event_reg_init_vals(ev, vals)) - return; - - cb->cb_expanded_func(bc, cb->cb_user_data, vals[0], vals[1], vals[2], - vals[3], vals[4], vals[5], vals[6], vals[7], - vals[8], vals[9], vals[10], vals[11], vals[12], - vals[13]); -} - -static void -dispatcher15(BroConn *bc, BroEventCB *cb, BroEvent *ev) -{ - void *vals[15]; - - if (! event_reg_init_vals(ev, vals)) - return; - - cb->cb_expanded_func(bc, cb->cb_user_data, vals[0], vals[1], vals[2], - vals[3], vals[4], vals[5], vals[6], vals[7], - vals[8], vals[9], vals[10], vals[11], vals[12], - vals[13], vals[14]); -} - -static BroEvDispatcher disp_table[] = - { - dispatcher0, dispatcher1, dispatcher2, dispatcher3, - dispatcher4, dispatcher5, dispatcher6, dispatcher7, - dispatcher8, dispatcher9, dispatcher10, dispatcher11, - dispatcher12, dispatcher13, dispatcher14, dispatcher15, - }; - -static BroEventHandler* -event_reg_handler_new(const char *ev_name) -{ - BroEventHandler *beh; - - if (!ev_name || !*ev_name) - return NULL; - - if (! (beh = calloc(1, sizeof(BroEventHandler)))) - return NULL; - - beh->ev_name = strdup(ev_name); - TAILQ_INIT(&beh->cb_list); - - return beh; -} - -static void -event_reg_handler_free(BroEventHandler *beh) -{ - BroEventCB *cb; - - if (!beh) - return; - - if (beh->ev_name) - free(beh->ev_name); - - while ( (cb = beh->cb_list.tqh_first)) - { - TAILQ_REMOVE(&beh->cb_list, cb, cb_list); - free(cb); - } - - free(beh); -} - -static void -event_reg_handler_dispatch(BroConn *bc, BroEventHandler *beh, BroEvent *ev) -{ - BroEventCB *cb; - - if (!beh || !ev) - return; - - if (ev->val_len > DISPATCH_TABLE_SIZE) - return; - - for (cb = beh->cb_list.tqh_first; cb; cb = cb->cb_list.tqe_next) - { - switch (cb->cb_style) { - case BRO_CALLBACK_EXPANDED: - disp_table[ev->val_len](bc, cb, ev); - break; - - case BRO_CALLBACK_COMPACT: - dispatcher_compact(bc, cb, ev); - break; - - default: - ; - }; - } -} - - -BroEventReg * -__bro_event_reg_new(void) -{ - BroEventReg *reg; - - if (! (reg = calloc(1, sizeof(BroEventReg)))) - return NULL; - - TAILQ_INIT(®->handler_list); - return reg; -} - - -void -__bro_event_reg_free(BroEventReg *reg) -{ - BroEventHandler *beh; - - if (!reg) - return; - - while ( (beh = reg->handler_list.tqh_first)) - { - TAILQ_REMOVE(®->handler_list, beh, handler_list); - event_reg_handler_free(beh); - } - - free(reg); -} - -static void -event_reg_add(BroEventCB *cb, BroEventReg *reg, - const char *ev_name) -{ - BroEventHandler *beh; - - for (beh = reg->handler_list.tqh_first; beh; beh = beh->handler_list.tqe_next) - { - if (strcmp(beh->ev_name, ev_name)) - continue; - - /* We have found a handler for this event. - * Add the new callback and return. - */ - TAILQ_INSERT_TAIL(&beh->cb_list, cb, cb_list); - reg->num_handlers++; - return; - } - - /* We don't have a handler for this event yet. - * Create it, add a callback for the given func, - * and register it. - */ - if (! (beh = event_reg_handler_new(ev_name))) - { - free(cb); - return; - } - - TAILQ_INSERT_TAIL(&beh->cb_list, cb, cb_list); - TAILQ_INSERT_TAIL(®->handler_list, beh, handler_list); - reg->num_handlers++; -} - -void -__bro_event_reg_add(BroConn *bc, const char *ev_name, - BroEventFunc func, void *user_data) -{ - BroEventHandler *beh; - BroEventCB *cb; - BroEventReg *reg; - - if (!bc || !ev_name || !*ev_name) - return; - if (! (reg = bc->ev_reg)) - return; - - /* Create a new callback data structure */ - if (! (cb = calloc(1, sizeof(BroEventCB)))) - return; - - cb->cb_expanded_func = func; - cb->cb_user_data = user_data; - cb->cb_style = BRO_CALLBACK_EXPANDED; - - event_reg_add(cb, reg, ev_name); -} - - -void -__bro_event_reg_add_compact(BroConn *bc, const char *ev_name, - BroCompactEventFunc func, void *user_data) -{ - BroEventHandler *beh; - BroEventCB *cb; - BroEventReg *reg; - - if (!bc || !ev_name || !*ev_name) - return; - if (! (reg = bc->ev_reg)) - return; - - /* Create a new callback data structure */ - if (! (cb = calloc(1, sizeof(BroEventCB)))) - return; - - cb->cb_compact_func = func; - cb->cb_user_data = user_data; - cb->cb_style = BRO_CALLBACK_COMPACT; - - event_reg_add(cb, reg, ev_name); -} - - -int -__bro_event_reg_remove(BroConn *bc, const char *ev_name) -{ - BroEventHandler *beh; - BroEventReg *reg; - - if (!bc || !ev_name || !*ev_name) - return FALSE; - if (! (reg = bc->ev_reg)) - return FALSE; - - for (beh = reg->handler_list.tqh_first; beh; beh = beh->handler_list.tqe_next) - { - if (strcmp(beh->ev_name, ev_name)) - continue; - - TAILQ_REMOVE(®->handler_list, beh, handler_list); - event_reg_handler_free(beh); - reg->num_handlers--; - return TRUE; - } - - return FALSE; -} - - -int -__bro_event_reg_request(BroConn *bc) -{ - BroEventReg *reg; - BroEventHandler *beh; - BroRequest *req; - int len = 0; - int result; - char *ptr; - - D_ENTER; - - if (!bc) - D_RETURN_(FALSE); - - if (! (reg = bc->ev_reg)) - D_RETURN_(FALSE); - - /* Go over all handlers once, and collect the total length of - * all event names including terminating 0s. - */ - for (beh = reg->handler_list.tqh_first; beh; beh = beh->handler_list.tqe_next) - len += strlen(beh->ev_name) + 1; - - /* Allocate a request structure for that length */ - if (! (req = __bro_event_request_new(len))) - D_RETURN_(FALSE); - - /* Go through again and copy all event names into the - * request structure. - */ - ptr = req->req_dat; - for (beh = reg->handler_list.tqh_first; beh; beh = beh->handler_list.tqe_next) - { - D(("Requesting event '%s'\n", beh->ev_name)); - memcpy(ptr, beh->ev_name, strlen(beh->ev_name)); - ptr += strlen(ptr) + 1; - } - - if (! __bro_io_request_queue(bc, req)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -void -__bro_event_reg_dispatch(BroConn *bc, BroEvent *ev) -{ - BroEventReg *reg; - BroEventHandler *beh; - - D_ENTER; - - if (!bc || !ev || ! (reg = bc->ev_reg)) - { - D(("Input error\n")); - D_RETURN; - } - - D(("Dispatching event '%s' with %i paramaters.\n", ev->name.str_val, ev->val_len)); - - for (beh = reg->handler_list.tqh_first; beh; beh = beh->handler_list.tqe_next) - { - if (strcmp(__bro_event_get_name(ev), beh->ev_name) == 0) - event_reg_handler_dispatch(bc, beh, ev); - } - - D_RETURN; -} - - -BroRequest * -__bro_event_request_new(int len) -{ - BroRequest *req; - - if (len <= 0) - return NULL; - - if (! (req = calloc(1, sizeof(BroRequest)))) - return NULL; - - if (! (req->req_dat = calloc(len + 1, sizeof(char)))) - { - free(req); - return NULL; - } - - req->req_len = len; - return req; -} - - -void -__bro_event_request_free(BroRequest *req) -{ - if (! req) - return; - - if (req->req_dat) - free(req->req_dat); - - free(req); -} - diff --git a/aux/broccoli/src/bro_event_reg.h b/aux/broccoli/src/bro_event_reg.h deleted file mode 100644 index e3320bb713..0000000000 --- a/aux/broccoli/src/bro_event_reg.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_event_reg_h -#define broccoli_event_reg_h - -#include - -BroEventReg *__bro_event_reg_new(void); -void __bro_event_reg_free(BroEventReg *reg); - -void __bro_event_reg_add(BroConn *bc, - const char *ev_name, - BroEventFunc func, - void *user_data); - -void __bro_event_reg_add_compact(BroConn *bc, - const char *ev_name, - BroCompactEventFunc func, - void *user_data); - -int __bro_event_reg_remove(BroConn *bc, const char *ev_name); -int __bro_event_reg_request(BroConn *bc); -void __bro_event_reg_dispatch(BroConn *bc, BroEvent *ev); - -BroRequest *__bro_event_request_new(int len); -void __bro_event_request_free(BroRequest *req); - -#endif diff --git a/aux/broccoli/src/bro_hashtable.c b/aux/broccoli/src/bro_hashtable.c deleted file mode 100644 index a450207dcb..0000000000 --- a/aux/broccoli/src/bro_hashtable.c +++ /dev/null @@ -1,424 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include - -#ifdef __EMX__ -#include -#endif - -#include -#include -#include -#include - -#define BRO_HT_NUM_SLOTS 127 - -#ifdef BRO_DEBUG -#define DEBUG_HTS -#endif - -#ifdef DEBUG_HTS -# define DEBUG_HT(x) do { printf("%s/%i: ", __FILE__, __LINE__); printf x ; } while (0); -#else -# define DEBUG_HT(x) -#endif - -typedef struct bro_hash_item -{ - /* For the age list in the hashtable. We know every node will - * occur only once in the hashtable, and we want the items - * themselves to be the nodes, so the macros are okay. - */ - TAILQ_ENTRY(bro_hash_item) age_list; - - void *it_key; - void *it_data; - -} BroHTIt; - -typedef TAILQ_HEAD(hi_list, bro_hash_item) BroHIList; - -struct bro_ht -{ - BroList **ht_slots; - int ht_numslots; - int ht_size; - - /* Age list for elements in hash table, only used if - * requested in __bro_ht_new(). The youngest element - * of the age list sits at the *tail* of the list, - * the oldest is at the *front*. - */ - int use_age_list; - BroHIList age_list; - - BroHTHashFunc ht_hash_func; - BroHTCmpFunc ht_cmp_func; - BroHTFreeFunc ht_key_free_func; - BroHTFreeFunc ht_val_free_func; -}; - - -BroHT * -__bro_ht_new(BroHTHashFunc hash_func, - BroHTCmpFunc cmp_func, - BroHTFreeFunc key_free_func, - BroHTFreeFunc val_free_func, - int use_age_list) -{ - BroHT *ht; - int i; - - D_ENTER; - - /* It may be okay if we get no free_funcs ... */ - if (!hash_func || !cmp_func) - D_RETURN_(NULL); - - if (! (ht = calloc(1, sizeof(BroHT)))) - D_RETURN_(NULL); - - ht->ht_numslots = BRO_HT_NUM_SLOTS; - ht->ht_size = 0; - ht->use_age_list = use_age_list; - ht->ht_hash_func = hash_func; - ht->ht_cmp_func = cmp_func; - ht->ht_key_free_func = key_free_func; - ht->ht_val_free_func = val_free_func; - - /* ht_slots is kept NULL here to avoid work on tables that are never - * inserted into. - */ - - /* Initialize the age list no matter whether it'll be - * used or not. - */ - TAILQ_INIT(&ht->age_list); - - D_RETURN_(ht); -} - - -void -__bro_ht_free(BroHT *ht) -{ - BroList *l; - BroHTIt *it; - int i; - - D_ENTER; - - if (! ht) - D_RETURN; - - /* Age list doesn't need cleaning up as its nodes are - * entries in the regular hashtable, which are cleaned - * up now: - */ - - if (ht->ht_slots == NULL) - { - free(ht); - D_RETURN; - } - - for (i = 0; i < ht->ht_numslots; i++) - { - for (l = ht->ht_slots[i]; l; l = __bro_list_next(l)) - { - it = __bro_list_data(l); - - if (ht->ht_key_free_func) - ht->ht_key_free_func(it->it_key); - - if (ht->ht_val_free_func) - ht->ht_val_free_func(it->it_data); - - free(it); - } - - __bro_list_free(ht->ht_slots[i], NULL); - } - - free(ht->ht_slots); - free(ht); - D_RETURN; -} - - -int -__bro_ht_add(BroHT *ht, void *key, void *data) -{ - uint32 slot; - BroHTIt *it; - - D_ENTER; - - if (!ht || !key) - { - D(("Input error: (%p, %p, %p)\n", ht, key, data)); - D_RETURN_(FALSE); - } - - if (! (it = calloc(1, sizeof(BroHTIt)))) - { - D(("Out of memory.\n")); - D_RETURN_(FALSE); - } - - it->it_key = key; - it->it_data = data; - - if (ht->ht_slots == NULL) - { - if (! (ht->ht_slots = calloc(ht->ht_numslots, sizeof(BroList*)))) - { - D(("Out of memory.\n")); - D_RETURN_(FALSE); - } - } - - slot = ht->ht_hash_func(key) % ht->ht_numslots; - ht->ht_slots[slot] = __bro_list_append(ht->ht_slots[slot], it); - ht->ht_size++; - - if (ht->use_age_list) - TAILQ_INSERT_TAIL(&ht->age_list, it, age_list); - - D_RETURN_(TRUE); -} - - -void * -__bro_ht_get(BroHT *ht, const void *key) -{ - BroList *l; - BroHTIt *it; - uint32 slot; - - if (!ht || !key) - { - D(("Input error: (%p, %p)\n", ht, key)); - return NULL; - } - - if (!ht->ht_slots) - return NULL; - - slot = ht->ht_hash_func(key) % ht->ht_numslots; - - for (l = ht->ht_slots[slot]; l; l = __bro_list_next(l)) - { - it = __bro_list_data(l); - - if (ht->ht_cmp_func(it->it_key, key)) - { - if (ht->use_age_list) - { - TAILQ_REMOVE(&ht->age_list, it, age_list); - TAILQ_INSERT_TAIL(&ht->age_list, it, age_list); - } - - return it->it_data; - } - } - - return NULL; -} - - -void * -__bro_ht_del(BroHT *ht, void *key) -{ - void *result; - BroHTIt *it; - BroList *l; - uint32 slot; - - D_ENTER; - - if (!ht || !key) - D_RETURN_(NULL); - - if (!ht->ht_slots) - D_RETURN_(NULL); - - slot = ht->ht_hash_func(key) % ht->ht_numslots; - - for (l = ht->ht_slots[slot]; l; l = __bro_list_next(l)) - { - it = __bro_list_data(l); - - if (ht->ht_cmp_func(it->it_key, key)) - { - result = it->it_data; - ht->ht_slots[slot] = __bro_list_remove(ht->ht_slots[slot], l); - ht->ht_size--; - - /* Free the key if possible -- don't free the - * value, as we just return that. - */ - if (ht->ht_key_free_func) - ht->ht_key_free_func(it->it_key); - - if (ht->use_age_list) - TAILQ_REMOVE(&ht->age_list, it, age_list); - - free(it); - - D_RETURN_(result); - } - } - - D_RETURN_(NULL); -} - - -int -__bro_ht_get_size(BroHT *ht) -{ - if (! ht) - return -1; - - return ht->ht_size; -} - - -void -__bro_ht_get_oldest(BroHT *ht, void **key, void **data) -{ - if (! ht || !ht->use_age_list) - { - if (key) - *key = NULL; - if (data) - *data = NULL; - - return; - } - - if (key) - *key = ht->age_list.tqh_first->it_key; - - if (data) - *data = ht->age_list.tqh_first->it_data; -} - - -int -__bro_ht_evict_oldest(BroHT *ht) -{ - if (! ht) - return 0; - - if (ht->use_age_list && ht->age_list.tqh_first) - __bro_ht_del(ht, ht->age_list.tqh_first->it_key); - - return ht->ht_size; -} - - -void -__bro_ht_foreach(BroHT *ht, BroHTCallback callback, void *user_data) -{ - BroList *l; - BroHTIt *it; - int i; - - if (!ht || !callback) - return; - - if (!ht->ht_slots) - return; - - for (i = 0; i < ht->ht_numslots; i++) - { - for (l = ht->ht_slots[i]; l; l = __bro_list_next(l)) - { - it = __bro_list_data(l); - - if (! callback(it->it_key, it->it_data, user_data)) - return; - } - } -} - - -uint32 -__bro_ht_str_hash(const void *val) -{ - char *val_ptr; - uint32 hash; - - if (!val) - return 0; - - val_ptr = (char *) val; - - for (hash = 0; *val_ptr != '\0'; val_ptr++) - hash = (64 * hash + *val_ptr); - - return hash; -} - - -int -__bro_ht_str_cmp(const void *val1, const void *val2) -{ - if (! val1 || ! val2) - return FALSE; - - return strcmp((char*) val1, (char*) val2) == 0; -} - - -void -__bro_ht_mem_free(void *data) -{ - if (data) - free(data); -} - - -uint32 -__bro_ht_int_hash(const void *val) -{ - return (uint32)(uintptr_t) val; -} - - -int -__bro_ht_int_cmp(const void *val1, const void *val2) -{ - return val1 == val2; -} diff --git a/aux/broccoli/src/bro_hashtable.h b/aux/broccoli/src/bro_hashtable.h deleted file mode 100644 index b289d68768..0000000000 --- a/aux/broccoli/src/bro_hashtable.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_ht_h -#define broccoli_ht_h - -#include - -typedef struct bro_ht BroHT; - -/* Hash function -- pass something in, get integer back. - */ -typedef uint32 (*BroHTHashFunc)(const void *data); - -/* Key comparison function -- compares two keys, returns %TRUE - * if equal, %FALSE otherwise, NOT -1/0/1. - */ -typedef int (*BroHTCmpFunc)(const void *key1, const void *key2); - -/* Destructor function, one for keys, one for values. - */ -typedef void (*BroHTFreeFunc)(void *data); - -/** - * BroHTCallback - The signature of functions used with __bro_ht_foreach() - * @key: key of current hash table item - * @data: value part of current hash table item. - * @user_data: arbitrary user data passed through from __bro_ht_foreach(). - * - * Returning %FALSE signals abortion of the loop. - */ -typedef int (*BroHTCallback)(void *key, void *data, void *user_data); - -/** - * __bro_ht_new - creates new hashtable. - * @hash_func: hashing function to use, see BroHTHashFunc. - * @cmp_func: element comparison function to use, see BroHTCmpFunc. - * @key_free_func: callback for erasing key of an item, if desirable. - * @val_free_func: callback for erasing data item itself, if desirable. - * @use_age_list: whether to maintain an age list (%TRUE) or not (%FALSE). - * - * The function creates and returns a new hashtable. @key_free_func and - * @val_free_func can be used to clean up contained elements automatically - * as they are removed from the table. If you don't want this feature, - * pass %NULL -- you can still iterate over all items in the table using - * __bro_ht_foreach(). - * - * The table can optionally maintain an age list (see - * __bro_ht_get_oldest() and __bro_ht_evict_oldest()), pass %TRUE to - * @use_age_list if desired. - * - * Returns: new table, or %NULL when out of memory. - */ -BroHT *__bro_ht_new(BroHTHashFunc hash_func, - BroHTCmpFunc cmp_func, - BroHTFreeFunc key_free_func, - BroHTFreeFunc val_free_func, - int use_age_list); - -void __bro_ht_free(BroHT *ht); - -int __bro_ht_add(BroHT *ht, void *key, void *data); -void *__bro_ht_get(BroHT *ht, const void *key); -void *__bro_ht_del(BroHT *ht, void *key); -int __bro_ht_get_size(BroHT *ht); - -void __bro_ht_foreach(BroHT *ht, BroHTCallback cb, void *user_data); - -/* Returns pointers to key and value of oldest item in the table, - * if age list is maintained. Otherwise sets both @key and @data - * to %NULL. - */ -void __bro_ht_get_oldest(BroHT *ht, void **key, void **data); - -/* If age list is used, removes oldest element from the table - * and returns number of items in the table after eviction. - * If age list is not used, does nothing and returns table size. - */ -int __bro_ht_evict_oldest(BroHT *ht); - -uint32 __bro_ht_str_hash(const void *val); -int __bro_ht_str_cmp(const void *val1, const void *val2); -void __bro_ht_mem_free(void *data); - -uint32 __bro_ht_int_hash(const void *val); -int __bro_ht_int_cmp(const void *val1, const void *val2); - -#endif diff --git a/aux/broccoli/src/bro_id.c b/aux/broccoli/src/bro_id.c deleted file mode 100644 index a72b85fd59..0000000000 --- a/aux/broccoli/src/bro_id.c +++ /dev/null @@ -1,296 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __EMX__ -#include -#endif - -#include -#include -#include - -BroID * -__bro_id_new(void) -{ - BroID *id; - - D_ENTER; - - if (! (id = calloc(1, sizeof(BroID)))) - D_RETURN_(NULL); - - __bro_id_init(id); - - D_RETURN_(id); -} - -void -__bro_id_init(BroID *id) -{ - BroSObject *sobj = (BroSObject *) id; - - D_ENTER; - - /* First initialize parent */ - __bro_object_init((BroObject *) id); - - /* Now hook our callbacks into the vtable */ - sobj->read = (BroSObjectRead) __bro_id_read; - sobj->write = (BroSObjectWrite) __bro_id_write; - sobj->free = (BroSObjectFree) __bro_id_free; - sobj->clone = (BroSObjectClone) __bro_id_clone; - sobj->hash = (BroSObjectHash) __bro_id_hash; - sobj->cmp = (BroSObjectCmp) __bro_id_cmp; - - sobj->type_id = SER_ID; - - /* And finally initialize our own stuff */ - bro_string_init(&id->name); - id->type = __bro_type_new(); - - /* For now we don't have attrs + val, these get - * hooked in on demand. - */ - D_RETURN; -} - -void -__bro_id_free(BroID *id) -{ - D_ENTER; - - if (!id) - D_RETURN; - - /* First clean up our stuff */ - bro_string_cleanup(&id->name); - - __bro_sobject_release((BroSObject *) id->type); - __bro_sobject_release((BroSObject *) id->attrs); - __bro_sobject_release((BroSObject *) id->val); - - /* Then clean up parent -- will eventually call free() */ - __bro_object_free((BroObject *) id); - - D_RETURN; -} - -int -__bro_id_read(BroID *id, BroConn *bc) -{ - char opt; - - D_ENTER; - - if (! id || ! bc) - D_RETURN_(FALSE); - - if (! __bro_object_read((BroObject *) id, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_read_string(bc->rx_buf, &id->name)) - D_RETURN_(FALSE); - - if (! __bro_buf_read_char(bc->rx_buf, &id->scope)) - D_RETURN_(FALSE); - - if (! __bro_buf_read_char(bc->rx_buf, &id->is_export)) - D_RETURN_(FALSE); - if (! __bro_buf_read_int(bc->rx_buf, &id->is_const)) - D_RETURN_(FALSE); - if (! __bro_buf_read_int(bc->rx_buf, &id->is_enum_const)) - D_RETURN_(FALSE); - if (! __bro_buf_read_int(bc->rx_buf, &id->is_type)) - D_RETURN_(FALSE); - - if (! __bro_buf_read_int(bc->rx_buf, &id->offset)) - D_RETURN_(FALSE); - - if (! __bro_buf_read_char(bc->rx_buf, &id->infer_return_type)) - D_RETURN_(FALSE); - if (! __bro_buf_read_char(bc->rx_buf, &id->weak_ref)) - D_RETURN_(FALSE); - - if (id->type) - __bro_sobject_release((BroSObject*) id->type); - if (! (id->type = (BroType *) __bro_sobject_unserialize(SER_IS_TYPE, bc))) - D_RETURN_(FALSE); - - if (! __bro_buf_read_char(bc->rx_buf, &opt)) - D_RETURN_(FALSE); - if (opt) - { - if (id->attrs) - __bro_sobject_release((BroSObject *) id->attrs); - - if (! (id->attrs = (BroAttrs *) __bro_sobject_unserialize(SER_ATTRIBUTES, bc))) - D_RETURN_(FALSE); - } - - if (! __bro_buf_read_char(bc->rx_buf, &opt)) - D_RETURN_(FALSE); - if (opt) - { - if (id->val) - __bro_sobject_release((BroSObject *) id->val); - - if (! (id->val = (BroVal *) __bro_sobject_unserialize(SER_IS_VAL, bc))) - D_RETURN_(FALSE); - } - - D_RETURN_(TRUE); -} - -int -__bro_id_write(BroID *id, BroConn *bc) -{ - D_ENTER; - - if (! id || ! bc) - D_RETURN_(FALSE); - - if (! __bro_object_write((BroObject *) id, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_string(bc->tx_buf, &id->name)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_char(bc->tx_buf, id->scope)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_char(bc->tx_buf, id->is_export)) - D_RETURN_(FALSE); - if (! __bro_buf_write_int(bc->tx_buf, id->is_const)) - D_RETURN_(FALSE); - if (! __bro_buf_write_int(bc->tx_buf, id->is_enum_const)) - D_RETURN_(FALSE); - if (! __bro_buf_write_int(bc->tx_buf, id->is_type)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_int(bc->tx_buf, id->offset)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_char(bc->tx_buf, id->infer_return_type)) - D_RETURN_(FALSE); - if (! __bro_buf_write_char(bc->tx_buf, id->weak_ref)) - D_RETURN_(FALSE); - - if (! __bro_sobject_serialize((BroSObject *) id->type, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_char(bc->tx_buf, id->attrs ? 1 : 0)) - D_RETURN_(FALSE); - if (id->attrs && ! __bro_sobject_serialize((BroSObject *) id->attrs, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_char(bc->tx_buf, id->val ? 1 : 0)) - D_RETURN_(FALSE); - if (id->attrs && ! __bro_sobject_serialize((BroSObject *) id->val, bc)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -int -__bro_id_clone(BroID *dst, BroID *src) -{ - BroString *string; - - D_ENTER; - - if (! __bro_object_clone((BroObject *) dst, (BroObject *) src)) - D_RETURN_(FALSE); - - if (! (string = bro_string_copy(&src->name))) - D_RETURN_(FALSE); - - dst->name = *string; - dst->scope = src->scope; - dst->is_export = src->is_export; - dst->is_const = src->is_const; - dst->is_enum_const = src->is_enum_const; - dst->is_type = src->is_type; - dst->offset = src->offset; - dst->infer_return_type = src->infer_return_type; - dst->weak_ref = src->weak_ref; - - if (src->type && ! (dst->type = (BroType *) __bro_sobject_copy((BroSObject *) src->type))) - D_RETURN_(FALSE); - - if (src->val && ! (dst->val = (BroVal *) __bro_sobject_copy((BroSObject *) src->val))) - D_RETURN_(FALSE); - - if (src->attrs && ! (dst->attrs = (BroAttrs *) __bro_sobject_copy((BroSObject *) src->attrs))) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -uint32 -__bro_id_hash(BroID *id) -{ - uint32 result = 0; - - D_ENTER; - - if (! id) - D_RETURN_(0); - - result ^= __bro_ht_str_hash(id->name.str_val); - result ^= ((uint32) id->scope) << 8; - result ^= (uint32) id->is_export; - result ^= id->is_const; - result ^= id->is_enum_const; - result ^= id->is_type; - result ^= id->offset; - - D_RETURN_(result); -} - - -int -__bro_id_cmp(BroID *id1, BroID *id2) -{ - D_ENTER; - - if (! id1 || ! id2) - D_RETURN_(FALSE); - - D_RETURN_(__bro_ht_str_cmp(id1->name.str_val, id2->name.str_val)); -} diff --git a/aux/broccoli/src/bro_id.h b/aux/broccoli/src/bro_id.h deleted file mode 100644 index fe81ed0b39..0000000000 --- a/aux/broccoli/src/bro_id.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_id_h -#define broccoli_id_h - -#include -#include -#include -#include - -struct bro_id -{ - BroObject object; - BroString name; - char scope; - - char is_export; - uint32 is_const; - uint32 is_enum_const; - uint32 is_type; - - uint32 offset; - - char infer_return_type; - char weak_ref; - - BroType *type; - BroVal *val; - BroAttrs *attrs; -}; - -BroID *__bro_id_new(void); -void __bro_id_init(BroID *id); -void __bro_id_free(BroID *id); - -int __bro_id_write(BroID *id, BroConn *bc); -int __bro_id_read(BroID *id, BroConn *bc); -int __bro_id_clone(BroID *dst, BroID *src); -uint32 __bro_id_hash(BroID *obj); -int __bro_id_cmp(BroID *obj1, BroID *obj2); - -#endif diff --git a/aux/broccoli/src/bro_io.c b/aux/broccoli/src/bro_io.c deleted file mode 100644 index 2e4ad36902..0000000000 --- a/aux/broccoli/src/bro_io.c +++ /dev/null @@ -1,1205 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __MINGW32__ -#include -#else -#include -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef BRO_PCAP_SUPPORT -#include -#endif - -/* A static array that can translate message types into strings so - * it's clearer what's going on when debugging: - */ -static char * msg_type_str[] = { - "BRO_MSG_NONE", - "BRO_MSG_VERSION", - "BRO_MSG_SERIAL", - "BRO_MSG_CLOSE", - "BRO_MSG_CLOSE_ALL", - "BRO_MSG_ERROR", - "BRO_MSG_CONNECTTO", - "BRO_MSG_CONNECTED", - "BRO_MSG_REQUEST", - "BRO_MSG_LISTEN", - "BRO_MSG_LISTEN_STOP", - "BRO_MSG_STATS", - "BRO_MSG_CAPTURE_FILTER", - "BRO_MSG_REQUEST_SYNC", - "BRO_MSG_PHASE_DONE", - "BRO_MSG_PING", - "BRO_MSG_PONG", - "BRO_MSG_CAPS", - "BRO_MSG_COMPRESS", -}; - -static const char * -msg_type_2_str(int type) -{ - if (type < 0 || type >= BRO_MSG_MAX) - return ""; - - return msg_type_str[type]; -} - -/* The maximum number of attempts we make in one go in order - * to extract data from the pipe. It appears that OpenSSL does - * not fully hide the record-oriented transfer and repeated - * writes at one end also require repeated reads at the other - * end. If anyone can confirm or deny this, please get in touch. - */ -#define BRO_BIO_READ_ROUNDS_MAX 20 - -/* Reading-related --------------------------------------------------- */ - -static int -io_read_chunk_size(BroConn *bc, uint32 *chunk_size) -{ - if (! __bro_buf_ptr_read(bc->rx_buf, chunk_size, sizeof(uint32))) - { - D(("Couldn't read chunk size\n")); - return FALSE; - } - - *chunk_size = ntohl(*chunk_size); - - if (! __bro_buf_ptr_check(bc->rx_buf, *chunk_size)) - { - D(("Not all chunk data available\n")); - return FALSE; - } - - D(("We have a chunk of size %i\n", *chunk_size)); - return TRUE; -} - -static int -io_read_msg_hdr(BroConn *bc, BroMsgHeader *msg_hdr) -{ - if (! __bro_buf_ptr_read(bc->rx_buf, msg_hdr, sizeof(BroMsgHeader))) - { - D(("Couldn't read message header\n")); - return FALSE; - } - - msg_hdr->hdr_peer_id = ntohs(msg_hdr->hdr_peer_id); - - return TRUE; -} - -static int -io_msg_fill_rx(BroConn *bc) -{ - BroBuf tmp_buf; - int i, n, total = 0; - - if (bc->state->rx_dead) - { - if (! (bc->conn_flags & BRO_CFLAG_RECONNECT)) - return FALSE; - - D(("Connection dead and we want to reconnect ...\n")); - - if (! bro_conn_reconnect(bc)) - return FALSE; - } - - for (i = 0; i < BRO_BIO_READ_ROUNDS_MAX; i++) - { - __bro_buf_init(&tmp_buf); - - n = __bro_openssl_read(bc, __bro_buf_get(&tmp_buf), - __bro_buf_get_size(&tmp_buf)); - - if (n <= 0) - { - __bro_buf_cleanup(&tmp_buf); - - if (n < 0) - { - D(("Read returned error after %i/%i rounds and %i bytes\n", - i, BRO_BIO_READ_ROUNDS_MAX, total)); - return -1; - } -#ifdef BRO_DEBUG - if (total > 0) - D(("Read %i bytes in %i/%i rounds.\n", - total, i, BRO_BIO_READ_ROUNDS_MAX)); -#endif - if (total == 0) - continue; - - return total; - } - - __bro_buf_append(bc->rx_buf, __bro_buf_get(&tmp_buf), n); - __bro_buf_cleanup(&tmp_buf); - total += n; - } - - D(("Read %i bytes in %i/%i rounds.\n", - total, i, BRO_BIO_READ_ROUNDS_MAX)); - - return total; -} - - -static int -io_skip_chunk(BroBuf *buf, uint32 buf_off, uint32 chunk_size) -{ - if (! buf) - return FALSE; - - if (! __bro_buf_ptr_seek(buf, buf_off, SEEK_SET)) - return FALSE; - - /* We skip a uint32 for the chunk size and then chunk_size - * bytes. - */ - if (! __bro_buf_ptr_seek(buf, sizeof(uint32) + chunk_size, SEEK_CUR)) - return FALSE; - - D(("Skipping %i + %i\n", sizeof(uint32), chunk_size)); - - return TRUE; -} - - -static int -io_process_serialization(BroConn *bc) -{ - BroVal vbuf; - - D_ENTER; - - if (! __bro_buf_read_char(bc->rx_buf, &vbuf.val_char)) - { - D(("Couldn't read serialization type\n")); - D_RETURN_(FALSE); - } - - switch (vbuf.val_char) - { - case 'e': - { - BroEvent *ev; - - bc->rx_ev_start = (const char*) bro_buf_ptr_get(bc->rx_buf); - - D(("Processing serialized event.\n")); - if (! (ev = __bro_event_unserialize(bc))) - { - bc->rx_ev_start = bc->rx_ev_end = NULL; - D_RETURN_(FALSE); - } - - bc->rx_ev_end = (const char*) bro_buf_ptr_get(bc->rx_buf); - __bro_event_reg_dispatch(bc, ev); - __bro_event_free(ev); - bc->rx_ev_start = bc->rx_ev_end = NULL; - } - break; - - case 'i': - { - BroID *id; - - D(("Processing serialized ID.\n")); - if (! (id = (BroID *) __bro_sobject_unserialize(SER_IS_ID, bc))) - D_RETURN_(FALSE); - - D(("ID read successfully.\n")); - /* Except we don't do anything with it yet. :) */ - __bro_sobject_release((BroSObject *) id); - } - break; - - case 'p': - { -#ifdef BRO_PCAP_SUPPORT - BroPacket *packet; - - if (! (packet = __bro_packet_unserialize(bc))) - D_RETURN_(FALSE); - - D(("Packet read successfully.\n")); - bro_packet_free(packet); -#else - D_RETURN_(FALSE); -#endif - } - break; - - default: - /* We do not handle anything else yet -- just say - * we are happy and return. - */ - D(("Unknown serialization of type %c\n", vbuf.val_char)); - D_RETURN_(FALSE); - } - - /* After a complete unserialization, we enforce the size limit - * of the cache. We can't do it on the go as a new object that - * is unserialized may still contain references to previously - * cached items which we might evict. - */ - while (__bro_ht_get_size(bc->io_cache) > bc->io_cache_maxsize) - __bro_ht_evict_oldest(bc->io_cache); - - D_RETURN_(TRUE); -} - - -/* Writing-related --------------------------------------------------- */ - -static int -io_fill_raw(BroBuf *buf, BroBuf *data) -{ - return __bro_buf_write_data(buf, __bro_buf_get(data), __bro_buf_get_used_size(data)); -} - - -static int -io_fill_request(BroBuf *buf, BroRequest *req) -{ - return __bro_buf_write_data(buf, req->req_dat, req->req_len); -} - -static int -io_fill_msg_header(BroBuf *buf, BroMsgHeader *mh) -{ - mh->hdr_peer_id = htonl(mh->hdr_peer_id); - return __bro_buf_write_data(buf, mh, sizeof(BroMsgHeader)); -} - -static int -io_msg_empty_tx(BroConn *bc) -{ - int n; - int todo; - - D_ENTER; - - if (bc->state->tx_dead && (bc->conn_flags & BRO_CFLAG_RECONNECT)) - bro_conn_reconnect(bc); - - if (bc->state->tx_dead) - { - D(("Connection dead, not writing anything. Todo: %i\n", __bro_buf_get_used_size(bc->tx_buf))); - D_RETURN_(FALSE); - } - - /* This function loops until the entire buffer contents - * are written out. This is not perfect but easier for now. - * Revisit this as a FIXME. - */ - for ( ; ; ) - { - todo = __bro_buf_get_used_size(bc->tx_buf); - - if (todo == 0) - D_RETURN_(TRUE); - - n = __bro_openssl_write(bc, __bro_buf_get(bc->tx_buf), todo); - - /* If we couldn't write out anything at all, then we report - * failure. - */ - if (n < 0) - { - D(("SSL error -- nothing written.\n")); - D_RETURN_(FALSE); - } - - if (0 < n && n < todo) - { - /* We have an incomplete write. Consume what we were - * able to write out. - */ - D(("*** Incomplete write: %i/%i\n", n, todo)); - - if (! __bro_buf_ptr_seek(bc->tx_buf, n, SEEK_SET)) - { - /* This should never happen. */ - D(("*** Buffer contents are screwed :(\n")); - D_RETURN_(FALSE); - } - - __bro_buf_consume(bc->tx_buf); - } - - D(("<<< Sent %i/%i bytes.\n", n, todo)); - - if (n == todo) - { - /* If we wrote out everything that was left, report success. */ - __bro_buf_reset(bc->tx_buf); - D_RETURN_(TRUE); - } - } -} - -static int -io_msg_fill_tx(BroConn *bc, BroMsg *msg) -{ - int result = TRUE; - - D_ENTER; - - if (!bc || !msg) - { - D(("Input error.\n")); - D_RETURN_(FALSE); - } - - /* Check if anything is still left in the input buffer. In that case, - * we don't fill anything in but return right away, so the message - * gets queued. - */ - if (__bro_buf_get_used_size(bc->tx_buf) > 0) - { - D(("Buffer not empty; not filling!\n")); - D_RETURN_(FALSE); - } - - D((">>> Attempting write of %s\n", msg_type_2_str(msg->msg_header.hdr_type))); - - /* We will collect the message chunk in the connection's tx buffer. - * We append stuff to it as we go along and at the end write it out. - * When being sent, he buffer has the amount of octets to send at - * the beginning, so the reader knows how much is coming. - */ - __bro_buf_reset(bc->tx_buf); - - msg->msg_header_size = sizeof(BroMsgHeader); - - if (! __bro_buf_write_int(bc->tx_buf, msg->msg_header_size)) - { - __bro_buf_reset(bc->tx_buf); - D_RETURN_(FALSE); - } - - /* Hook in the Bro message header */ - if (! io_fill_msg_header(bc->tx_buf, &msg->msg_header)) - { - __bro_buf_reset(bc->tx_buf); - D_RETURN_(FALSE); - } - - if (msg->msg_cont_type != BRO_MSG_CONT_NONE) - { - uint32 msg_size_pos, msg_size_end; - - /* This starts another chunk of data (in Bro protocol speak), - * but here we cannot yet know how big the chunk will be. - * We save the offset in the buffer and return to it later, - * overwriting the value with the then correct one. - */ - msg_size_pos = __bro_buf_get_used_size(bc->tx_buf); - if (! __bro_buf_write_int(bc->tx_buf, msg->msg_size)) - { - __bro_buf_reset(bc->tx_buf); - D_RETURN_(FALSE); - } - - /* Gather the payload of the message we are about - * to send into the buffer BUF. - */ - switch (msg->msg_cont_type) - { - case BRO_MSG_CONT_RAW: - D(("Filling raw data into buffer\n")); - if (! io_fill_raw(bc->tx_buf, msg->msg_cont_raw)) - { - __bro_buf_reset(bc->tx_buf); - D_RETURN_(FALSE); - } - break; - - case BRO_MSG_CONT_EVENT: - /* Check if the peer actually requested the event, and if not, - * drop it silently (i.e., still return success). - */ - if (! __bro_ht_get(bc->ev_mask, msg->msg_cont_ev->name.str_val)) - { - D(("Event '%s' not requested by peer -- dropping.\n", - msg->msg_cont_ev->name.str_val)); - __bro_buf_reset(bc->tx_buf); - - /* This is not an error but a silent drop, so we - * return success. - */ - D_RETURN_(TRUE); - } - - D(("Filling event into buffer\n")); - - if (! __bro_event_serialize(msg->msg_cont_ev, bc)) - { - D(("Error during serialization.\n")); - __bro_buf_reset(bc->tx_buf); - D_RETURN_(FALSE); - } - break; - - case BRO_MSG_CONT_REQUEST: - D(("Filling request into buffer\n")); - if (! io_fill_request(bc->tx_buf, msg->msg_cont_req)) - { - __bro_buf_reset(bc->tx_buf); - D_RETURN_(FALSE); - } - break; - -#ifdef BRO_PCAP_SUPPORT - case BRO_MSG_CONT_PACKET: - if (! __bro_packet_serialize(msg->msg_cont_packet, bc)) - { - __bro_buf_reset(bc->tx_buf); - D_RETURN_(FALSE); - } - break; -#endif - default: - D(("ERROR -- invalid message content code %i\n", msg->msg_cont_type)); - break; - } - - /* Now calculate length of entire transmission -- - * we know where we wrote the uint32 containing the - * size of the chunk, and we know where we are now, - * so the length is their difference, minus the uint32 - * itself. - */ - msg_size_end = __bro_buf_get_used_size(bc->tx_buf); - msg->msg_size = msg_size_end - msg_size_pos - sizeof(uint32); - D(("Serialized message sized %i bytes.\n", msg->msg_size)); - - if (! __bro_buf_ptr_seek(bc->tx_buf, msg_size_pos, SEEK_SET)) - { - D(("Cannot seek to position %u -- we're screwed.\n", msg_size_pos)); - __bro_buf_reset(bc->tx_buf); - D_RETURN_(FALSE); - } - - if (! __bro_buf_write_int(bc->tx_buf, msg->msg_size)) - { - __bro_buf_reset(bc->tx_buf); - D_RETURN_(FALSE); - } - } - - D_RETURN_(result); -} - - -static int -io_msg_queue(BroConn *bc, BroMsg *msg) -{ - D_ENTER; - - if (!bc || !msg) - D_RETURN_(FALSE); - - /* If anything is left over in the buffer, write it out now. - * We don't care if it succeeds or not. - */ - io_msg_empty_tx(bc); - - /* If the queue is empty, try to send right away. - * If not, enqueue the event, and try to flush. - */ - D(("Enqueing msg of type %s\n", msg_type_2_str(msg->msg_header.hdr_type))); - - if (! bc->msg_queue.tqh_first) - { - D(("No queue yet.\n")); - if (io_msg_fill_tx(bc, msg)) - { - D(("Message serialized.\n")); - - if (io_msg_empty_tx(bc)) - { - D(("Message sent.\n")); - } - - __bro_io_msg_free(msg); - bc->state->io_msg = BRO_IOMSG_WRITE; - D_RETURN_(TRUE); - } - } - - if (bc->state->tx_dead && ! (bc->conn_flags & BRO_CFLAG_ALWAYS_QUEUE)) - { - D(("Connection %p disconnected, and no queuing requested: dropping message.\n", bc)); - __bro_io_msg_free(msg); - D_RETURN_(FALSE); - } - - TAILQ_INSERT_TAIL(&bc->msg_queue, msg, msg_queue); - bc->msg_queue_len++; - D(("Queue length now %i\n", bc->msg_queue_len)); - - __bro_io_msg_queue_flush(bc); - - /* Check that the queue does not grow too big: */ - while (bc->msg_queue_len > BRO_MSG_QUEUELEN_MAX) - { - BroMsg *msg = bc->msg_queue.tqh_first; - - TAILQ_REMOVE(&bc->msg_queue, msg, msg_queue); - __bro_io_msg_free(msg); - bc->msg_queue_len--; - - D(("Dropped one message due to excess queue length, now %i\n", bc->msg_queue_len)); - } - - D_RETURN_(TRUE); -} - - -/* Non-static stuff below: ------------------------------------------- */ - -BroMsg * -__bro_io_msg_new(char type, uint32 peer_id) -{ - static int msg_counter = 0; - BroMsg *msg; - - if (! (msg = calloc(1, sizeof(BroMsg)))) - return NULL; - - msg->msg_header.hdr_type = type; - msg->msg_header.hdr_peer_id = peer_id; - msg->msg_cont_type = BRO_MSG_CONT_NONE; - msg->msg_num = msg_counter++; - - return msg; -} - - -void -__bro_io_msg_free(BroMsg *msg) -{ - if (!msg) - return; - - switch (msg->msg_cont_type) - { - case BRO_MSG_CONT_RAW: - __bro_buf_free(msg->msg_cont_raw); - break; - - case BRO_MSG_CONT_EVENT: - __bro_event_free(msg->msg_cont_ev); - break; - - case BRO_MSG_CONT_REQUEST: - __bro_event_request_free(msg->msg_cont_req); - break; -#ifdef BRO_PCAP_SUPPORT - case BRO_MSG_CONT_PACKET: - bro_packet_free(msg->msg_cont_packet); - break; -#endif - - default: - break; - } - - free(msg); -} - - -void -__bro_io_msg_set_cont(BroMsg *msg, int type, void *content) -{ - if (!msg) - return; - - msg->msg_cont_type = type; - - switch (type) - { - case BRO_MSG_CONT_RAW: - msg->msg_cont_raw = (BroBuf*) content; - D(("Setting raw buffer content for message, type now %i, buffer data: %p\n", - msg->msg_cont_type, content)); - break; - - case BRO_MSG_CONT_EVENT: - msg->msg_cont_ev = (BroEvent *) content; - D(("Setting event content for message, type now %i, event: %s\n", - msg->msg_cont_type, msg->msg_cont.msg_ev->name.str_val)); - break; - - case BRO_MSG_CONT_REQUEST: - msg->msg_cont_req = (BroRequest *) content; - D(("Setting request content for message, type now %i\n", msg->msg_cont_type)); - break; - -#ifdef BRO_PCAP_SUPPORT - case BRO_MSG_CONT_PACKET: - msg->msg_cont_packet = (BroPacket *) content; - break; -#endif - - default: - msg->msg_cont_type = BRO_MSG_CONT_NONE; - } -} - - -int -__bro_io_msg_queue_flush(BroConn *bc) -{ - BroMsg *msg; - int result; - - D_ENTER; - - if (! bc) - D_RETURN_(-1); - - for ( ; ; ) - { - if (! io_msg_empty_tx(bc)) - break; - - if (! (msg = bc->msg_queue.tqh_first)) - break; - - if (! io_msg_fill_tx(bc, msg)) - break; - - TAILQ_REMOVE(&bc->msg_queue, msg, msg_queue); - __bro_io_msg_free(msg); - bc->msg_queue_len--; - - bc->state->io_msg = BRO_IOMSG_WRITE; - } - - result = bc->msg_queue_len; - D_RETURN_(result); -} - - -void -__bro_io_msg_queue_dump(BroConn *bc, const char *message) -{ - BroMsg *msg; - - printf("%s: connection %p, length %i\n", message, bc, bc->msg_queue_len); - - for (msg = bc->msg_queue.tqh_first; msg; msg = msg->msg_queue.tqe_next) - printf(" -- %s(%i)\n", msg_type_2_str(msg->msg_header.hdr_type), msg->msg_num); -} - -int -__bro_io_raw_queue(BroConn *bc, int type, uchar *data, int data_len) -{ - BroMsg *msg; - int result = FALSE; - - D_ENTER; - - if (!bc) - D_RETURN_(FALSE); - - if (! (msg = __bro_io_msg_new(type, 0))) - D_RETURN_(FALSE); - - if (data_len > 0) - { - BroBuf *buf; - - if (! (buf = __bro_buf_new())) - { - __bro_io_msg_free(msg); - D_RETURN_(FALSE); - } - - __bro_buf_append(buf, data, data_len); - __bro_io_msg_set_cont(msg, BRO_MSG_CONT_RAW, buf); - } - - result = io_msg_queue(bc, msg); - - D_RETURN_(result); -} - -int -__bro_io_rawbuf_queue(BroConn *bc, int type, BroBuf *buf) -{ - BroMsg *msg; - int result = FALSE; - - D_ENTER; - - if (!bc || !buf) - D_RETURN_(FALSE); - - if (! (msg = __bro_io_msg_new(type, 0))) - D_RETURN_(FALSE); - - __bro_io_msg_set_cont(msg, BRO_MSG_CONT_RAW, buf); - result = io_msg_queue(bc, msg); - - D_RETURN_(result); -} - -int -__bro_io_event_queue(BroConn *bc, BroEvent *ev) -{ - BroEvent *ev_copy; - BroMsg *msg; - int result; - - D_ENTER; - - if (!bc) - D_RETURN_(FALSE); - - if (! (msg = __bro_io_msg_new(BRO_MSG_SERIAL, 0))) - D_RETURN_(FALSE); - - if (! (ev_copy = __bro_event_copy(ev))) - { - D(("Could not clone event\n")); - D_RETURN_(FALSE); - } - - __bro_io_msg_set_cont(msg, BRO_MSG_CONT_EVENT, ev_copy); - result = io_msg_queue(bc, msg); - D_RETURN_(result); -} - -int -__bro_io_request_queue(BroConn *bc, BroRequest *req) -{ - BroMsg *msg; - int result; - - D_ENTER; - - if (!bc) - D_RETURN_(FALSE); - - if (! (msg = __bro_io_msg_new(BRO_MSG_REQUEST, 0))) - D_RETURN_(FALSE); - - __bro_io_msg_set_cont(msg, BRO_MSG_CONT_REQUEST, req); - result = io_msg_queue(bc, msg); - D_RETURN_(result); -} - -#ifdef BRO_PCAP_SUPPORT -int -__bro_io_packet_queue(BroConn *bc, BroPacket *packet) -{ - BroPacket *clone; - BroMsg *msg; - int result; - - D_ENTER; - - if (!bc) - D_RETURN_(FALSE); - - if (! (msg = __bro_io_msg_new(BRO_MSG_SERIAL, 0))) - D_RETURN_(FALSE); - - if (! (clone = bro_packet_clone(packet))) - { - __bro_io_msg_free(msg); - D_RETURN_(FALSE); - } - - __bro_io_msg_set_cont(msg, BRO_MSG_CONT_PACKET, clone); - result = io_msg_queue(bc, msg); - D_RETURN_(result); -} -#endif - -int -__bro_io_process_input(BroConn *bc) -{ - uint32 buf_off, chunk_size; - BroMsgHeader msg_hdr; - int result = FALSE; - - D_ENTER; - - /* Read all available data into receive buffer. Our socket is - * nonblocking so if nothing's available we'll be back right - * away. If nothing was read, the subsequent for loop will exit - * right away, so the io_msg_fill_rx() return code need not be - * checked here. - */ - io_msg_fill_rx(bc); - - /* Try to process as much in the input buffer as we can */ - for ( ; ; ) - { - D(("----- Attempting to extract a message\n")); - - /* Get the current offset of the buffer pointer to make - * sure we can reset to it if things go wrong. - */ - buf_off = __bro_buf_ptr_tell(bc->rx_buf); - - /* Now check the buffer contents and see if there's enough - * for us to analyze it. Start with a uint32 for the size - * of the first chunk, and then the chunk itself. - */ - if (! io_read_chunk_size(bc, &chunk_size)) - goto reset_return; - - if (chunk_size != sizeof(BroMsgHeader)) - { - D(("Received chunk should be %i bytes, but is %i\n", - sizeof(BroMsgHeader), chunk_size)); - io_skip_chunk(bc->rx_buf, buf_off, chunk_size); - result = TRUE; - continue; - } - - if (! io_read_msg_hdr(bc, &msg_hdr)) - goto reset_return; - - switch (msg_hdr.hdr_type) - { - case BRO_MSG_REQUEST: - { - char *tmp = NULL, *tmp2 = NULL; - - D(("Received MSQ_REQUEST\n")); - - /* We need to read another chunk, whose data will contain - * a sequence of 0-terminated strings, each one being the - * name of an event that the peering Bro is interested in. - */ - if (! io_read_chunk_size(bc, &chunk_size)) - goto reset_return; - - if (! (tmp = (char *) malloc(chunk_size * sizeof(char)))) - goto reset_return; - - if (! __bro_buf_read_data(bc->rx_buf, tmp, chunk_size)) - { - free(tmp); - goto reset_return; - } - - for (tmp2 = tmp; tmp2 < tmp + chunk_size; tmp2 = tmp2 + strlen(tmp2) + 1) - { - char *key; - - if (__bro_ht_get(bc->ev_mask, tmp2)) - continue; - - key = strdup(tmp2); - __bro_ht_add(bc->ev_mask, key, key); - D(("Will report event '%s'\n", tmp2)); - } - - D(("Now reporting %i event(s).\n", __bro_ht_get_size(bc->ev_mask))); - free(tmp); - } - break; - - case BRO_MSG_VERSION: - { - uchar *data; - uint32 proto_version; - uint32 cache_size; - uint32 data_version; - uint32 runtime; /* unused */ - - D(("Received MSG_VERSION\n")); - - /* We need to read another chunk for the raw data. - */ - if (! io_read_chunk_size(bc, &chunk_size)) - goto reset_return; - - if (! (data = malloc(sizeof(uchar) * chunk_size))) - goto reset_return; - - if (! __bro_buf_read_data(bc->rx_buf, data, chunk_size)) - { - free(data); - goto reset_return; - } - - proto_version = ntohl(((uint32 *) data)[0]); - cache_size = ntohl(((uint32 *) data)[1]); - data_version = ntohl(((uint32 *) data)[2]); - runtime = ntohl(((uint32 *) data)[3]); - - /* If there are more bytes than required for the 4 uint32s - * used above, it means that the peer has sent a connection class - * identifier. Extract and register in the handle. - */ - if (chunk_size > 4 * sizeof(uint32)) - { - if (bc->peer_class) - free(bc->peer_class); - - bc->peer_class = strdup((char *) (data + 4 * sizeof(uint32))); - } - - if (proto_version != BRO_PROTOCOL_VERSION) - { - D(("EEEK -- we speak protocol version %i, peer speeks %i. Aborting.\n", - BRO_PROTOCOL_VERSION, proto_version)); - __bro_openssl_shutdown(bc); - goto reset_return; - } else { - D(("Protocols compatible, we speak version %i\n", BRO_PROTOCOL_VERSION)); - } - - if (data_version != 0 && data_version != BRO_DATA_FORMAT_VERSION) - { - D(("EEEK -- we speak data format version %i, peer speeks %i. Aborting.\n", - BRO_DATA_FORMAT_VERSION, data_version)); - __bro_openssl_shutdown(bc); - goto reset_return; - } else { - D(("Data formats compatible, we speak version %i\n", BRO_DATA_FORMAT_VERSION)); - } - - bc->io_cache_maxsize = cache_size; - D(("Receiver cache size set to %i entries.\n", cache_size)); - free(data); - - bc->state->conn_state_peer = BRO_CONNSTATE_HANDSHAKE; - D(("VERSION received, on %p, peer now in HANDSHAKE stage.\n")); - } - break; - - case BRO_MSG_SERIAL: - { - uint32 pre_serial; - - D(("Received MSQ_SERIAL\n")); - pre_serial = __bro_buf_ptr_tell(bc->rx_buf); - - if (! io_read_chunk_size(bc, &chunk_size)) - goto reset_return; - - if (! io_process_serialization(bc)) - io_skip_chunk(bc->rx_buf, pre_serial, chunk_size); - } - break; - - case BRO_MSG_CAPTURE_FILTER: - { - uint32 pre_capture; - - D(("Received MSQ_CAPTURE_FILTER\n")); - pre_capture = __bro_buf_ptr_tell(bc->rx_buf); - - if (! io_read_chunk_size(bc, &chunk_size)) - goto reset_return; - - io_skip_chunk(bc->rx_buf, pre_capture, chunk_size); - } - break; - - case BRO_MSG_PHASE_DONE: - /* No additional content for this one. */ - switch (bc->state->conn_state_peer) - { - case BRO_CONNSTATE_HANDSHAKE: - /* When we complete the handshake phase, it depends - * on whether or not the peer has requested synced - * state. If so, enter the sync phase, otherwise - * we're up and running. - */ - if (bc->state->sync_state_requested) - { - bc->state->conn_state_peer = BRO_CONNSTATE_SYNC; - D(("Phase done from peer on %p, sync requested, peer now in SYNC stage.\n", bc)); - } - else - { - bc->state->conn_state_peer = BRO_CONNSTATE_RUNNING; - D(("Phase done from peer on %p, no sync requested, peer now in RUNNING stage.\n", bc)); - } - break; - - case BRO_CONNSTATE_SYNC: - bc->state->conn_state_peer = BRO_CONNSTATE_RUNNING; - D(("Phase done from peer on %p, peer now in RUNNING stage.\n", bc)); - break; - - default: - D(("Ignoring PHASE_DONE in conn state %i/%i on conn %p\n", - bc->state->conn_state_self, bc->state->conn_state_peer, bc)); - } - break; - - case BRO_MSG_REQUEST_SYNC: - { - uchar *data; - - D(("Received MSQ_REQUEST_SYNC, peer now in SYNC stage.\n")); - - bc->state->sync_state_requested = 1; - bc->state->conn_state_peer = BRO_CONNSTATE_SYNC; - - /* We need to read another chunk for the raw data. - */ - if (! io_read_chunk_size(bc, &chunk_size)) - goto reset_return; - - if (! (data = malloc(sizeof(uchar) * chunk_size))) - goto reset_return; - - if (! __bro_buf_read_data(bc->rx_buf, data, chunk_size)) - { - free(data); - goto reset_return; - } - D(("Skipping sync interpretation\n")); - free(data); - break; - } - - - case BRO_MSG_CAPS: - { - uchar *data; - - D(("Received MSG_CAPS\n")); - - /* We need to read another chunk for the raw data. - */ - if (! io_read_chunk_size(bc, &chunk_size)) - goto reset_return; - - if (! (data = malloc(sizeof(uchar) * chunk_size))) - goto reset_return; - - if (! __bro_buf_read_data(bc->rx_buf, data, chunk_size)) - { - free(data); - goto reset_return; - } - D(("Skipping capabilities interpretation\n")); - free(data); - break; - } - - default: - D(("Skipping unknown message type %i\n", msg_hdr.hdr_type)); - break; - } - - __bro_buf_consume(bc->rx_buf); - result = TRUE; - - if ((bc->conn_flags & BRO_CFLAG_YIELD) && - bc->state->conn_state_self == BRO_CONNSTATE_RUNNING && - bc->state->conn_state_peer == BRO_CONNSTATE_RUNNING) - break; - } - - reset_return: - __bro_buf_ptr_seek(bc->rx_buf, buf_off, SEEK_SET); - D_RETURN_(result); -} - - -void -__bro_io_loop(BroConn *bc) -{ - D_ENTER; - - for ( ; ; ) - { - D(("I/O loop iteration\n")); - - switch (bc->state->io_msg) - { - case BRO_IOMSG_STOP: - D(("I/O process %u exiting by request.\n", getpid())); - __bro_openssl_shutdown(bc); - exit(0); - - case BRO_IOMSG_WRITE: - if (bc->state->tx_dead) - break; - - if (! io_msg_empty_tx(bc)) - { - D(("I/O handler %u encountered write error.\n", getpid())); - __bro_openssl_shutdown(bc); - } - break; - - case BRO_IOMSG_READ: - if (bc->state->rx_dead) - break; - - if (io_msg_fill_rx(bc) < 0) - { - D(("I/O handler %u encountered read error.\n", getpid())); - __bro_openssl_shutdown(bc); - } - break; - } - - bc->state->io_msg = BRO_IOMSG_NONE; - } -} diff --git a/aux/broccoli/src/bro_io.h b/aux/broccoli/src/bro_io.h deleted file mode 100644 index 62b4cace38..0000000000 --- a/aux/broccoli/src/bro_io.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_io_h -#define broccoli_io_h - -#include -#include - -/** - * __bro_io_msg_new -- allocates a new message destined to a given peer. - */ -BroMsg * __bro_io_msg_new(char type, uint32 peer_id); - -/** - * __bro_io_msg_free -- releases message plus any data hooked into it. - * @msg: msg to free. - */ -void __bro_io_msg_free(BroMsg *msg); - -/** - * __bro_io_msg_set_cont -- sets the content of a message. - * @msg: message to set content of. - * @type: type of the message, a BRO_MSG_CONT_xxx constant. - * @content: the content itself. - * - * The function sets @msg's content, of given @type, to @content. - * Note that __bro_io_msg_free will release the data pointed to - * by @content, depending on @type! - */ -void __bro_io_msg_set_cont(BroMsg *msg, int type, void *content); - -int __bro_io_msg_queue_flush(BroConn *bc); -void __bro_io_msg_queue_dump(BroConn *bc, const char *message); - -/** - * __bro_io_raw_queue -- enqueues raw data. - * @bc: connection handle. - * @type: type of the message, a BRO_MSG_xxx value. - * @data: raw bytes of data - * @data_len: length of @data. - * - * The function enqueues a message containing raw data for a - * message of type @type. - * - * Returns: %FALSE on error, %TRUE otherwise. - */ -int __bro_io_raw_queue(BroConn *bc, int type, - uchar *data, int data_len); - -/** - * __bro_io_rawbuf_queue -- enqueues raw buffer data. - * @bc: connection handle. - * @type: type of the message, a BRO_MSG_xxx value. - * @buf: buffer with payload to be enqueued. - * - * The function enqueues a message containing raw buffer data for a - * message of type @type. - * - * NOTE: @buf's ownership is taken over by the function. You do not - * need to clean it up, and should not expect the pointer to it to - * remain valid. - * - * Returns: %FALSE on error, %TRUE otherwise. - */ -int __bro_io_rawbuf_queue(BroConn *bc, int type, BroBuf *buf); - -/** - * __bro_io_event_queue -- enqueues an event. - * @bc: connection handle. - * @ev: event handle. - * - * The function enqueues an event for later transmission. - * - * Returns: %FALSE on error, %TRUE otherwise. - */ -int __bro_io_event_queue(BroConn *bc, BroEvent *ev); - -/** - * __bro_io_request_queue -- enqueues a request. - * @bc: connection handle. - * @req: request handle. - * - * The function enqueues an request for later transmission. - * - * Returns: %FALSE on error, %TRUE otherwise. - */ -int __bro_io_request_queue(BroConn *bc, BroRequest *req); - -/** - * __bro_io_packet_queue - enqueues a pcap packet. - * @bc: connection handle. - * @packet: pcap packet. - * - * The function enqueues a pcap packet wrapped via bro_packet_new() - * for later transmission. - * - * Returns: %FALSE on error, %TRUE otherwise. - */ -#ifdef BRO_PCAP_SUPPORT -int __bro_io_packet_queue(BroConn *bc, BroPacket *packet); -#endif - - -int __bro_io_process_input(BroConn *bc); - -void __bro_io_writer_loop(BroConn *bc); - -/** - * __bro_io_loop -- performs I/O in the handler process. - * @bc: connection handle. - * - * This function is the implementation of the I/O handler processes. - * It sits in a blocking loop and depending on the request sent to it via - * bc->state->io_msg it performs the requested I/O operation. It does not - * return unless the connection encounters an error or teardown is requested. - */ -void __bro_io_loop(BroConn *bc); - -#endif diff --git a/aux/broccoli/src/bro_lexer.l b/aux/broccoli/src/bro_lexer.l deleted file mode 100644 index 0353e922e5..0000000000 --- a/aux/broccoli/src/bro_lexer.l +++ /dev/null @@ -1,42 +0,0 @@ -%option noyywrap - -%{ -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include "broccoli.h" -#include "bro_debug.h" -#include "bro_parser.h" - -int broerror(char *fmt, ...); -#define yyerror broerror -#define yylval brolval - -extern int bro_parse_lineno; - -%} - - -%% -[\[\]] return yytext[0]; - -yes|true|on { yylval.i = 1; return BROINT; } -no|false|off { yylval.i = 0; return BROINT; } -[ \t]+ ; -[0-9]+ { yylval.i = strtol(yytext, NULL, 10); return BROINT; } -[0-9]+\.[0-9]+ { yylval.d = strtod(yytext, NULL); return BRODOUBLE; } -[[:alnum:][:punct:]]+ { yylval.s = strdup(yytext); return BROWORD; } -\".*\" { yylval.s = strdup(yytext+1); - yylval.s[strlen(yylval.s) - 1] = '\0'; - return BROSTRING; - } - -"#".*\n { bro_parse_lineno++; } -"//".*\n { bro_parse_lineno++; } -\n { bro_parse_lineno++; } - -. { D(("Syntax error: '%s'\n", yytext)); } - -%% diff --git a/aux/broccoli/src/bro_list.c b/aux/broccoli/src/bro_list.c deleted file mode 100644 index 729a6a033d..0000000000 --- a/aux/broccoli/src/bro_list.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif -#include -#include -#include - -#include -#include - -struct bro_list -{ - struct bro_list *prev; - struct bro_list *next; - void *data; -}; - - -BroList * -__bro_list_new(void *data) -{ - BroList *l; - - l = calloc(1, sizeof(BroList)); - l->prev = l->next = NULL; - l->data = data; - - return l; -} - - -void -__bro_list_free(BroList *l, BroFunc free_func) -{ - BroList *lnext; - - while (l) - { - lnext = l->next; - if (l->data && free_func) - { - free_func(l->data); - } - free(l); - l = lnext; - } -} - - -BroList * -__bro_list_head(BroList *l) -{ - if (!l) - return NULL; - - while (l->prev) - l = l->prev; - - return l; -} - - -BroList * -__bro_list_next(BroList *l) -{ - if (!l) - return NULL; - - return l->next; -} - - -BroList * -__bro_list_prev(BroList *l) -{ - if (!l) - return NULL; - - return l->prev; -} - - -BroList * -__bro_list_nth(BroList *l, int n) -{ - while (l && n > 0) - { - l = l->next; - n--; - } - - return l; -} - - -int -__bro_list_length(BroList *l) -{ - int i = 0; - - while (l) - { - i++; - l = l->next; - } - - return i; -} - - -BroList * -__bro_list_append(BroList *l, void *data) -{ - BroList *ltmp = NULL; - BroList *lnew = NULL; - - lnew = __bro_list_new(data); - - if (l) - { - ltmp = l; - - while (ltmp->next) - ltmp = ltmp->next; - - ltmp->next = lnew; - } - - lnew->prev = ltmp; - return l ? l : lnew; -} - - -BroList * -__bro_list_prepend(BroList *l, void *data) -{ - BroList *lnew; - - lnew = __bro_list_new(data); - lnew->next = l; - - if (l) - l->prev = lnew; - - return lnew; -} - - -BroList * -__bro_list_insert(BroList *l, void *data) -{ - BroList *new; - - /* Data item can be NULL if user wants that */ - if (!l) - return NULL; - - new = __bro_list_new(data); - new->next = l->next; - new->prev = l; - - l->next = new; - - if (new->next) - new->next->prev = l; - - return new; -} - - -BroList * -__bro_list_remove(BroList *l, BroList *item) -{ - BroList *prev; - BroList *next; - - if (!l) - return NULL; - - prev = item->prev; - next = item->next; - free(item); - - /* first item */ - if (!prev) - { - if (!next) - return NULL; - else - { - next->prev = NULL; - return next; - } - } - - /* last item */ - if (!next) - { - if (!prev) - return l; - else - { - prev->next = NULL; - return l; - } - } - - /* middle item */ - prev->next = next; - next->prev = prev; - - return l; -} - - -void * -__bro_list_data(BroList *l) -{ - if (!l) - return NULL; - - return l->data; -} - - -void * -__bro_list_set_data(BroList *l, void *data) -{ - void *result; - - if (!l) - return NULL; - - result = l->data; - l->data = data; - - return result; -} - - -BroList * -__bro_list_move_to_front(BroList *l, BroList *item) -{ - BroList *prev; - BroList *next; - - if (!l || !item) - return NULL; - - prev = item->prev; - next = item->next; - - /* first item already */ - if (!prev) - return l; - - /* last item */ - if (!next) - { - prev->next = NULL; - item->prev = NULL; - item->next = l; - l->prev = item; - - return item; - } - - /* middle item */ - prev->next = next; - next->prev = prev; - - item->next = l; - item->prev = NULL; - l->prev = item; - - return item; -} diff --git a/aux/broccoli/src/bro_list.h b/aux/broccoli/src/bro_list.h deleted file mode 100644 index 84479425cb..0000000000 --- a/aux/broccoli/src/bro_list.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_list_h -#define broccoli_list_h - -typedef struct bro_list BroList; -typedef void(*BroFunc) (void *data); - -/* Create new list with data item. - */ -BroList *__bro_list_new(void *data); - -/* Erase entire list, applying free_func to each item - * in order to free it. Pass %NULL for free_func if no-op - * is desired. - */ -void __bro_list_free(BroList *l, BroFunc free_func); - -/* Given list element, returns the head of list by - * walking back to it. - */ -BroList *__bro_list_head(BroList *l); - -/* Next/prev items. */ -BroList *__bro_list_next(BroList *l); -BroList *__bro_list_prev(BroList *l); - -/* Returns nth list member, starting at 0, or NULL if not found. - */ -BroList *__bro_list_nth(BroList *l, int n); - -/* Returns length of list, or 0 on error. - */ -int __bro_list_length(BroList *l); - -/* Appends item to end of list and returns pointer to - * the list. NOTE: O(N) runtime. Try to use - * __bro_list_prepend() or track last list - * element in case lists contain more than a handful - * of elements. - */ -BroList *__bro_list_append(BroList *l, void *data); - -/* Prepends item and returns pointer to it. - */ -BroList *__bro_list_prepend(BroList *l, void *data); - -/* Inserts new node for @data after @l. - * Returns pointer to new item. - */ -BroList *__bro_list_insert(BroList *l, void *data); - -/* Removes a node and returns a pointer to the first - * element of the resulting list. - */ -BroList *__bro_list_remove(BroList *l, BroList *ll); - -/* List node data element accessor. - */ -void *__bro_list_data(BroList *l); - -/* Set data of list node, return old ones. - */ -void *__bro_list_set_data(BroList *l, void *data); - -/* Moves an item to the front of the list. For implementing - * MRU/LRU schemes. - */ -BroList *__bro_list_move_to_front(BroList *l, BroList *item); - -#endif diff --git a/aux/broccoli/src/bro_location.c b/aux/broccoli/src/bro_location.c deleted file mode 100644 index 38f342f815..0000000000 --- a/aux/broccoli/src/bro_location.c +++ /dev/null @@ -1,212 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __EMX__ -#include -#endif - -#include -#include - -BroLoc * -__bro_loc_new(void) -{ - BroLoc *loc; - - D_ENTER; - - if (! (loc = calloc(1, sizeof(BroLoc)))) { - D_RETURN_(NULL); - } - - __bro_loc_init(loc); - - D_RETURN_(loc); -} - - -void -__bro_loc_init(BroLoc *loc) -{ - BroSObject *sobj = (BroSObject *) loc; - - D_ENTER; - - __bro_sobject_init(sobj); - - sobj->read = (BroSObjectRead) __bro_loc_read; - sobj->write = (BroSObjectWrite)__bro_loc_write; - sobj->free = (BroSObjectFree) __bro_loc_free; - sobj->clone = (BroSObjectClone) __bro_loc_clone; - sobj->hash = (BroSObjectHash) __bro_loc_hash; - sobj->cmp = (BroSObjectCmp) __bro_loc_cmp; - - sobj->type_id = SER_LOCATION; - bro_string_init(&loc->filename); - - D_RETURN; -} - - -void -__bro_loc_free(BroLoc *loc) -{ - D_ENTER; - - if (! loc) - D_RETURN; - - bro_string_cleanup(&loc->filename); - __bro_sobject_free((BroSObject *) loc); - - D_RETURN; -} - - -int -__bro_loc_read(BroLoc *loc, BroConn *bc) -{ - D_ENTER; - - if (! loc || ! bc) - D_RETURN_(FALSE); - - if (! __bro_sobject_read((BroSObject *) loc, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_read_string(bc->rx_buf, &loc->filename)) - D_RETURN_(FALSE); - if (! __bro_buf_read_int(bc->rx_buf, &loc->first_line)) - D_RETURN_(FALSE); - if (! __bro_buf_read_int(bc->rx_buf, &loc->last_line)) - D_RETURN_(FALSE); - if (! __bro_buf_read_int(bc->rx_buf, &loc->first_column)) - D_RETURN_(FALSE); - if (! __bro_buf_read_int(bc->rx_buf, &loc->last_column)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -int -__bro_loc_write(BroLoc *loc, BroConn *bc) -{ - D_ENTER; - - if (! loc || ! bc) - D_RETURN_(FALSE); - - if (! __bro_sobject_write((BroSObject *) loc, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_string(bc->tx_buf, &loc->filename)) - D_RETURN_(FALSE); - if (! __bro_buf_write_int(bc->tx_buf, loc->first_line)) - D_RETURN_(FALSE); - if (! __bro_buf_write_int(bc->tx_buf, loc->last_line)) - D_RETURN_(FALSE); - if (! __bro_buf_write_int(bc->tx_buf, loc->first_column)) - D_RETURN_(FALSE); - if (! __bro_buf_write_int(bc->tx_buf, loc->last_column)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -int -__bro_loc_clone(BroLoc *dst, BroLoc *src) -{ - BroString *string; - - D_ENTER; - - if (! __bro_sobject_clone((BroSObject *) dst, (BroSObject *) src)) - D_RETURN_(FALSE); - - if (! (string = bro_string_copy(&src->filename))) - D_RETURN_(FALSE); - - dst->filename = *string; - dst->first_line = src->first_line; - dst->last_line = src->last_line; - dst->first_column = src->first_column; - dst->last_column = src->last_column; - - D_RETURN_(TRUE); -} - - -uint32 -__bro_loc_hash(BroLoc *loc) -{ - uint32 result; - - D_ENTER; - - if (! loc) - D_RETURN_(0); - - result = __bro_ht_str_hash(loc->filename.str_val); - result ^= loc->first_line; - result ^= loc->last_line; - result ^= loc->first_column; - result ^= loc->last_column; - - D_RETURN_(result); - -} - - -int -__bro_loc_cmp(BroLoc *loc1, BroLoc *loc2) -{ - D_ENTER; - - if (! __bro_ht_str_cmp(loc1->filename.str_val, loc2->filename.str_val)) - D_RETURN_(FALSE); - - if (loc1->first_line != loc2->first_line || - loc1->last_line != loc2->last_line || - loc1->first_column < loc2->first_column || - loc1->last_column < loc2->last_column || - loc1->last_column > loc2->last_column) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} diff --git a/aux/broccoli/src/bro_location.h b/aux/broccoli/src/bro_location.h deleted file mode 100644 index 4843a31299..0000000000 --- a/aux/broccoli/src/bro_location.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_location_h -#define broccoli_location_h - -#include -#include - -typedef struct bro_loc BroLoc; - -struct bro_loc -{ - BroSObject sobject; - - BroString filename; - uint32 first_line; - uint32 last_line; - uint32 first_column; - uint32 last_column; -}; - -BroLoc *__bro_loc_new(void); -void __bro_loc_init(BroLoc *loc); -void __bro_loc_free(BroLoc *loc); - -int __bro_loc_read(BroLoc *loc, BroConn *bc); -int __bro_loc_write(BroLoc *loc, BroConn *bc); -int __bro_loc_clone(BroLoc *dst, BroLoc *src); - -uint32 __bro_loc_hash(BroLoc *loc); -int __bro_loc_cmp(BroLoc *loc1, BroLoc *loc2); - -#endif diff --git a/aux/broccoli/src/bro_object.c b/aux/broccoli/src/bro_object.c deleted file mode 100644 index f388c80984..0000000000 --- a/aux/broccoli/src/bro_object.c +++ /dev/null @@ -1,183 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __EMX__ -#include -#endif - -#include -#include -#include - -BroObject * -__bro_object_new(void) -{ - BroObject *obj; - - D_ENTER; - - if (! (obj = calloc(1, sizeof(BroObject)))) - D_RETURN_(NULL); - - __bro_object_init(obj); - - D_RETURN_(obj); -} - -void -__bro_object_init(BroObject *obj) -{ - BroSObject *sobj = (BroSObject *) obj; - - D_ENTER; - - __bro_sobject_init(sobj); - - sobj->read = (BroSObjectRead) __bro_object_read; - sobj->write = (BroSObjectWrite)__bro_object_write; - sobj->free = (BroSObjectFree) __bro_object_free; - sobj->clone = (BroSObjectClone) __bro_object_clone; - sobj->hash = (BroSObjectHash) __bro_object_hash; - sobj->cmp = (BroSObjectCmp) __bro_object_cmp; - - D_RETURN; -} - -void -__bro_object_free(BroObject *obj) -{ - D_ENTER; - - if (! obj) - D_RETURN; - - __bro_sobject_release((BroSObject *) obj->loc); - __bro_sobject_free((BroSObject *) obj); - - D_RETURN; -} - - -int -__bro_object_read(BroObject *obj, BroConn *bc) -{ - char opt; - - D_ENTER; - - if (! __bro_sobject_read((BroSObject *) obj, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_read_char(bc->rx_buf, &opt)) - D_RETURN_(FALSE); - if (opt) - { - if (! (obj->loc = (BroLoc *) __bro_sobject_unserialize(SER_LOCATION, bc))) - D_RETURN_(FALSE); - } - - D_RETURN_(TRUE); -} - - -int -__bro_object_write(BroObject *obj, BroConn *bc) -{ - D_ENTER; - - if (! __bro_sobject_write((BroSObject *) obj, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_char(bc->tx_buf, obj->loc ? 1 : 0)) - D_RETURN_(FALSE); - - if (obj->loc && ! __bro_sobject_serialize((BroSObject *) obj->loc, bc)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -int -__bro_object_clone(BroObject *dst, BroObject *src) -{ - D_ENTER; - - if (! __bro_sobject_clone((BroSObject *) dst, (BroSObject *) src)) - { - D(("Cloning parent failed.\n")); - D_RETURN_(FALSE); - } - - if (src->loc && ! (dst->loc = (BroLoc *) __bro_sobject_copy((BroSObject *) src->loc))) - { - D(("Cloning location failed.\n")); - D_RETURN_(FALSE); - } - - D_RETURN_(TRUE); -} - - -uint32 -__bro_object_hash(BroObject *obj) -{ - uint32 result; - - D_ENTER; - - if (! obj) - D_RETURN_(0); - - result = __bro_sobject_hash((BroSObject *) obj); - result ^= __bro_loc_hash(obj->loc); - - D_RETURN_(result); - -} - - -int -__bro_object_cmp(BroObject *obj1, BroObject *obj2) -{ - D_ENTER; - - if (! obj1 || ! obj2) - D_RETURN_(FALSE); - - D_RETURN_(__bro_loc_cmp(obj1->loc, obj2->loc)); -} diff --git a/aux/broccoli/src/bro_object.h b/aux/broccoli/src/bro_object.h deleted file mode 100644 index b5fdca6b8b..0000000000 --- a/aux/broccoli/src/bro_object.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_object_h -#define broccoli_object_h - -#include -#include - -typedef struct bro_object -{ - /* See comments in bro_sobject.h for how Broccoli models - * classes, objects, and inheritance. --cpk - */ - BroSObject sobject; - BroLoc *loc; -} BroObject; - -BroObject *__bro_object_new(void); -void __bro_object_init(BroObject *obj); -void __bro_object_free(BroObject *obj); - -int __bro_object_read(BroObject *obj, BroConn *bc); -int __bro_object_write(BroObject *obj, BroConn *bc); -int __bro_object_clone(BroObject *dst, BroObject *src); -uint32 __bro_object_hash(BroObject *obj); -int __bro_object_cmp(BroObject *obj1, BroObject *obj2); - -#endif diff --git a/aux/broccoli/src/bro_openssl.c b/aux/broccoli/src/bro_openssl.c deleted file mode 100644 index cd1fbccfe5..0000000000 --- a/aux/broccoli/src/bro_openssl.c +++ /dev/null @@ -1,730 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __MINGW32__ -#include -#else -#include -#include -#include -#include -#include -#endif - -#ifdef __EMX__ -#include -#endif - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -/* PLEASE NOTE: this file deals with handling I/O through OpenSSL in - * an unencrypted and an encrypted fashion. There are no ifdefs for one - * mode or the other, because using OpenSSL connection abstraction helps - * portability so we always use OpenSSL, even when not encryting traffic. - * - * Encryption is automatically attempted if the certificate files can be - * read from configuration items "/broccoli/host_cert" and "/broccoli/ca_cert". - * (Note that when Bro peers communicate over an encrypted channel, they - * both need to certify themselves). - * - * Much of the code here is from the O'Reilly book on OpenSSL, by Viega, - * Messier, and Chandra. However the problem with their example application - * is that they use SSL_read/SSL_write, thus losing the transparency of - * the generic BIO_... functions regarding the use of encryption (we do - * allow for plaintext communication as well). Since I don't want to write - * duplicate code for the encrypted and unencrypted traffic, I use the - * approach given in man BIO_f_ssl(3), which uses BIO_new_ssl_connect() - * so I can still speak into a BIO at all times. In the case of no encryption, - * it'll simply be a regular BIO. - * - * We currently do not support the following: - * - ephemeral keying. - * - session caching. - * - * I haven't specifically looked at whether this code supports session - * renegotiation. - */ - -/* Broccoli initialization context; defined in bro.c. */ -extern const BroCtx *global_ctx; - -/* The connection creation context. If this context is NULL, - * it means we are not using encryption. - */ -static SSL_CTX *ctx = NULL; - -#ifdef BRO_DEBUG -static void -print_errors(void) -{ - if (bro_debug_messages) - { - D(("OpenSSL error dump:\n")); - if (ERR_peek_error() == 0) - fprintf(stdout, "--> %s\n", strerror(errno)); - else - ERR_print_errors_fp(stdout); - } -} -#else -#define print_errors() -#endif - - -static int -verify_cb(int ok, X509_STORE_CTX *store) -{ - char data[256]; - int depth, err; - X509 *cert; - - if (ok) - return ok; - - cert = X509_STORE_CTX_get_current_cert(store); - depth = X509_STORE_CTX_get_error_depth(store); - err = X509_STORE_CTX_get_error(store); - - D(("Handshake failure: verification problem at depth %i:\n", depth)); - X509_NAME_oneline(X509_get_issuer_name(cert), data, 256); - D((" issuer = %s\n", data)); - X509_NAME_oneline(X509_get_subject_name(cert), data, 256); - D((" subject = %s\n", data)); - D((" error code %i: %s\n", err, X509_verify_cert_error_string(err))); - - return ok; -} - - -static int -prng_init_file(char *file) -{ - struct stat st; - int fd, flags, i; - uchar buf[1024]; - - /* Check if file is available, and try to seed the PRNG - * from it. If things fail, do nothing and rely on OpenSSL to - * initialize from /dev/urandom. - */ - - if (stat(file, &st) != 0) - { - D(("%s does not exist, not seeding from it.\n", file)); - return FALSE; - } - - /* Now we need to figure out how much entropy the device - * can provide. We try to read 1K, and accept if it can - * read at least 256 bytes. - */ - if ( (fd = open(file, O_RDONLY)) < 0) - { - D(("Could not read from %s.\n", file)); - return FALSE; - } - - if ( (flags = fcntl(fd, F_GETFL, 0)) < 0) - { - D(("can't obtain socket flags: %s", strerror(errno))); - close(fd); - return FALSE; - } - - if ( fcntl(fd, F_SETFL, flags|O_NONBLOCK) < 0 ) - { - D(("can't set fd to non-blocking: %s.", strerror(errno))); - close(fd); - return FALSE; - } - - if ( (i = read(fd, buf, 1024)) < 256) - { - D(("Could only read %i bytes from %s, not enough.\n", i, file)); - close(fd); - return FALSE; - } - - D(("Seeding PRNG from %s, using %i bytes.\n", file, i)); - close(fd); - RAND_seed(buf, i); - - return TRUE; -} - - - -static void -prng_init(void) -{ - static int deja_vu = FALSE; - - if (deja_vu) - return; - - if (prng_init_file("/dev/random")) - { - deja_vu = TRUE; - return; - } - - if (prng_init_file("/dev/urandom")) - { - deja_vu = TRUE; - return; - } - - D(("*** CAUTION: Unable to initialize random number generator ***\n")); -} - - -static int -pem_passwd_cb(char *buf, int size, int rwflag, void *pass) -{ - /* Note that if |pass| < size, the remainder in buf will be - * zero-padded by strncpy(). - */ - strncpy(buf, (char *) pass, size); - buf[size - 1] = '\0'; - - return strlen(buf); - rwflag = 0; -} - -int -__bro_openssl_init(void) -{ - static int deja_vu = FALSE; - int use_ssl = FALSE; - const char *our_cert, *our_pass, *ca_cert; - - D_ENTER; - - if (deja_vu) - D_RETURN_(TRUE); - - deja_vu = TRUE; - - /* I hope these should go before SSL_library_init() -- not even the - * O'Reilly book is clear on that. :( --cpk - */ - if (global_ctx) - { - if (global_ctx->id_func) - CRYPTO_set_id_callback(global_ctx->id_func); - if (global_ctx->lock_func) - CRYPTO_set_locking_callback(global_ctx->lock_func); - if (global_ctx->dl_create_func) - CRYPTO_set_dynlock_create_callback(global_ctx->dl_create_func); - if (global_ctx->dl_lock_func) - CRYPTO_set_dynlock_lock_callback(global_ctx->dl_lock_func); - if (global_ctx->dl_free_func) - CRYPTO_set_dynlock_destroy_callback(global_ctx->dl_free_func); - } - - SSL_library_init(); - prng_init(); - -#ifdef BRO_DEBUG - D(("Loading OpenSSL error strings for debugging\n")); - SSL_load_error_strings(); -#endif - - if (__bro_conf_get_int("/broccoli/use_ssl", &use_ssl) && ! use_ssl) - { - D(("SSL disabled in configuration, not using SSL.\n")); - D_RETURN_(TRUE); - } - - if (! (our_cert = __bro_conf_get_str("/broccoli/host_cert"))) - { - if (use_ssl) - { - D(("SSL requested but host certificate not given -- aborting.\n")); - D_RETURN_(FALSE); - } - else - { - D(("use_ssl not used and host certificate not given -- not using SSL.\n")); - D_RETURN_(TRUE); - } - } - - /* At this point we either haven't seen use_ssl but a host_cert, or - * we have seen use_ssl and it is set to true. Either way, we attempt - * to set up an SSL connection now and abort if this fails in any way. - */ - - if (! (ctx = SSL_CTX_new(SSLv3_method()))) - D_RETURN_(FALSE); - - /* We expect things to be stored in PEM format, which means that we - * can store multiple entities in one file. In this case, our own - * certificate is expected to be stored along with the private key - * in the file pointed to by preference setting /broccoli/certificate. - * - * See page 121 in O'Reilly's OpenSSL book for details. - */ - if (SSL_CTX_use_certificate_chain_file(ctx, our_cert) != 1) - { - D(("Error loading certificate from '%s'.\n", our_cert)); - goto error_return; - } - - if ( (our_pass = __bro_conf_get_str("/broccoli/host_pass"))) - { - D(("Host passphrase given in config file, not prompting for input.\n")); - SSL_CTX_set_default_passwd_cb(ctx, pem_passwd_cb); - SSL_CTX_set_default_passwd_cb_userdata(ctx, (void *) our_pass); - } - - if (SSL_CTX_use_PrivateKey_file(ctx, our_cert, SSL_FILETYPE_PEM) != 1) - { - D(("SSL used but error loading private key from '%s' -- aborting.\n", our_cert)); - goto error_return; - } - - /* We should not need the passphrase, if existant, ever again. - * Therefore we erase it from memory now. - */ - if (our_pass) - { - our_pass = NULL; - __bro_conf_forget_item("/broccoli/host_pass"); - } - - /* For validation purposes, our trusted CA's certificate will - * be needed as well: - */ - if (! (ca_cert = __bro_conf_get_str("/broccoli/ca_cert"))) - { - D(("SSL used but CA certificate not given -- aborting.")); - goto error_return; - } - - if (! SSL_CTX_load_verify_locations(ctx, ca_cert, 0)) - { - D(("SSL used but CA certificate could not be loaded -- aborting\n")); - goto error_return; - } - - /* Only use real ciphers. - */ - if (! SSL_CTX_set_cipher_list(ctx, "HIGH")) - { - D(("SSL used but can't set cipher list -- aborting\n")); - goto error_return; - } - - /* We require certificates from all communication peers, regardless of - * whether we're the "server" or "client" (these concepts are blurred in our - * case anyway). In order to be able to give better error feedback, we - * add our own verification filter callback, "verify_cb". - */ - SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, - verify_cb); - - D(("SSL setup successful.\n")); - D_RETURN_(TRUE); - - error_return: - SSL_CTX_free(ctx); - ctx = NULL; - D_RETURN_(FALSE); -} - -int -__bro_openssl_rand_bytes(u_char *buf, int num) -{ - if (! buf || num <= 0) - return FALSE; - - /* Make sure PRNG is initialized; has effect only once. */ - prng_init(); - - if (RAND_bytes(buf, num) > 0) - return TRUE; - - RAND_pseudo_bytes(buf, num); - return TRUE; -} - - -int -__bro_openssl_encrypted(void) -{ - return ctx != NULL; -} - -static int -openssl_connect_impl(BIO *bio, int with_hack) -{ - int sockfd, port; - struct sockaddr_in addr; - char *hostname, *colon; - struct hostent *he; - - /* Okay, I must ask you not to scream now. All the rest of this function - * is to make sure that we detect whether the peer is listening or not. - * OpenSSL sometimes considers failure to connect() a temporary problem - * and I cannot figure out a way to force it to give up when connection - * establishment fails. So we establish our own connection and tear it - * down right away in case we succeeded. Unfortunately I cannot seem to - * figure out a way to just make OpenSSL use the existing connection - * either. It's such a mess. - */ - - /* In the encrypted case we do not have this problem, since the handshake - * here is a real one that only succeeds when the remote side answers. - */ - if (ctx) - return BIO_do_connect(bio); - - if (! with_hack) - return 1; - - /* I've found BIO_get_conn_...() to be broken even after calling - * BIO_do_connect() first, so I'm just doing this whole crap here - * manually to get to hostname and port. - */ - if (! (hostname = strdup(BIO_get_conn_hostname(bio)))) - { - D(("Out of memory.\n")); - return 0; - } - - if (! (colon = strchr(hostname, ':'))) - { - free(hostname); - return 0; - } - - *colon = '\0'; - port = atoi(colon + 1); - D(("OpenSSL kludge: manual connection to %s:%s\n", hostname, colon+1)); - - if (! (he = gethostbyname(hostname))) - { - D(("gethostbyname() failed.\n")); - free(hostname); - return 0; - } - - free(hostname); - - if (he->h_addr_list[0] == NULL) - { - D(("Could not resolve hostname.\n")); - return 0; - } - - if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) - { - D(("Could not create socket: %s\n", strerror(errno))); - return 0; - } - - bzero(&addr, sizeof(struct sockaddr_in)); - addr.sin_family = AF_INET; - addr.sin_port = htons(port); - addr.sin_addr = *((struct in_addr *) he->h_addr_list[0]); - - if (connect(sockfd, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) != 0) - goto error_return; - - close(sockfd); - return 1; - - error_return: - D(("Connection error: %s\n", strerror(errno))); - close(sockfd); - return 0; -} - - -static int -openssl_connect(BroConn *bc, int with_hack) -{ - int flags; - BIO *bio = NULL; - - D_ENTER; - - if (! bc || ! bc->peer || ! *(bc->peer)) - D_RETURN_(FALSE); - - /* Make sure OpenSSL is initialised -- this has effect only once */ - if (! __bro_openssl_init()) - D_RETURN_(FALSE); - - /* If we got a socket, we wrap it into a BIO and are done. */ - if (bc->socket >= 0) - { - if (! (bio = BIO_new_socket(bc->socket, BIO_CLOSE))) - { - D(("Error creating connection BIO from socket.\n")); - goto err_return; - } - - if ( (flags = fcntl(bc->socket, F_GETFL, 0)) < 0) - { - D(("Error getting socket flags.\n")); - goto err_return; - } - - if ( fcntl(bc->socket, F_SETFL, flags|O_NONBLOCK) < 0 ) - { - D(("Error setting socket to non-blocking.\n")); - goto err_return; - } - - /* Don't know whether this is needed but it does not hurt either. - * It is however not sufficient to just call this; we manually need to - * set the socket to non-blocking as done above. */ - BIO_set_nbio(bio, 1); - - bc->bio = bio; - D(("Connection created from externally provided socket.\n")); - D_RETURN_(TRUE); - } - - /* If we managed to set up a context object, we use encryption. */ - if (ctx) - { - if (! (bio = BIO_new_ssl_connect(ctx))) - { - D(("Error creating SSL connection BIO.\n")); - goto err_return; - } - - BIO_set_conn_hostname(bio, bc->peer); - } - else - { - if (! (bio = BIO_new_connect(bc->peer))) - { - D(("Error creating non-SSL connection BIO.\n")); - goto err_return; - } - } - - /* BIO_set_nbio's manpage says we need to set nonblocking before - * connecting. - */ - BIO_set_nbio(bio, 1); - - /* This is not exactly elegant but we want to make sure we only - * return once the potential SSL handshake is complete. - */ - for ( ; ; ) - { - if (openssl_connect_impl(bio, with_hack) > 0) - break; - - if ( ! BIO_should_retry(bio)) - { - D(("Error connecting to peer.\n")); - goto err_return; - } - } - - bc->bio = bio; - D(("Connection established successfully.\n")); - - D_RETURN_(TRUE); - - err_return: - - print_errors(); - -#ifdef BRO_DEBUG - if (ctx) - D(("--- SSL CONNECTION SETUP FAILED. ---")); - else - D(("--- CLEARTEXT CONNECTION SETUP FAILED. ---")); -#endif - - if (bio) - BIO_free_all(bio); - - bc->state->rx_dead = bc->state->tx_dead = TRUE; - bc->bio = NULL; - D_RETURN_(FALSE); -} - - -int -__bro_openssl_connect(BroConn *bc) -{ - return openssl_connect(bc, FALSE); -} - -int -__bro_openssl_reconnect(BroConn *bc) -{ - return openssl_connect(bc, TRUE); -} - - -void -__bro_openssl_shutdown(BroConn *bc) -{ - if (!bc || !bc->bio) - return; - - if (getpid() != bc->id_pid) - return; - - if (bc->state->rx_dead) - return; - - bc->state->rx_dead = bc->state->tx_dead = TRUE; - - BIO_flush(bc->bio); - BIO_free_all(bc->bio); - bc->bio = NULL; -} - - -int -__bro_openssl_read(BroConn *bc, uchar *buf, uint buf_size) -{ - int n; - - D_ENTER; - - /* It's important here to use <= for comparison, since, as the - * invaluable O'Reilly OpenSSL book reports, "for each of the four - * reading and writing functions, a 0 or -1 return value may or may - * not necessarily indicate that an error has occurred." This may or - * may not necessarily be indicative of the incredible PITA that - * OpenSSL is. --cpk - */ - if ( (n = BIO_read(bc->bio, buf, buf_size)) <= 0) - { - if (BIO_should_retry(bc->bio)) - D_RETURN_(0); - - __bro_openssl_shutdown(bc); - D(("Connection closed, BIO_read() returned %i.\n", n)); - print_errors(); - D_RETURN_(-1); - } - - D_RETURN_(n); -} - - -int -__bro_openssl_write(BroConn *bc, uchar *buf, uint buf_size) -{ - int n; - void *old_sig; - - D_ENTER; - -#ifdef BRO_DEBUG - if (bro_debug_messages) - { - unsigned int i = 0; - int last_hex = 0; - - D(("Sending %u bytes: ", buf_size)); - - for (i = 0; i < buf_size; i++) - { - if (buf[i] >= 32 && buf[i] <= 126) - { - printf("%s%c", last_hex ? " " : "", buf[i]); - last_hex = 0; - } - else - { - printf(" 0x%.2x", buf[i]); - last_hex = 1; - } - } - printf("\n"); - } -#endif - - /* We may get a SIGPIPE if we write to a connection whose peer - * died. Since we don't know the application context in which - * we're running, we temporarily set the SIGPIPE handler to our - * own and then set it back to the old one after we wrote. - */ - old_sig = signal(SIGPIPE, SIG_IGN); - - n = BIO_write(bc->bio, buf, buf_size); - - if (n <= 0) - { - if (BIO_should_retry(bc->bio)) - { - n = 0; - goto error_return; - } - - print_errors(); - __bro_openssl_shutdown(bc); - D(("Connection closed.\n")); - n = -1; - } - - BIO_flush(bc->bio); - - error_return: - - if (old_sig != SIG_ERR) - signal(SIGPIPE, old_sig); - - D_RETURN_(n); -} diff --git a/aux/broccoli/src/bro_openssl.h b/aux/broccoli/src/bro_openssl.h deleted file mode 100644 index 0a450e9d46..0000000000 --- a/aux/broccoli/src/bro_openssl.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_openssl_h -#define broccoli_openssl_h - -#include - -int __bro_openssl_init(void); -int __bro_openssl_encrypted(void); -int __bro_openssl_rand_bytes(u_char *buf, int num); - -int __bro_openssl_connect(BroConn *bc); - -/* Like __bro_openssl_connect, but uses gross manual-connect hack to make - * sure peer is actually available. - */ -int __bro_openssl_reconnect(BroConn *bc); - -void __bro_openssl_shutdown(BroConn *bc); - -int __bro_openssl_read(BroConn *bc, uchar *buf, uint buf_size); - -/** - * __bro_openssl_write - writes a chunk of data to the connection. - * @bc: Bro connection handle. - * @buf: buffer of data to write. - * @buf_size: size of buffer pointed to by @buf. - * - * Returns: value < 0 on error, 1 if all data was written, 0 - * otherwise (*no* data being written). - */ -int __bro_openssl_write(BroConn *bc, uchar *buf, uint buf_size); - -#endif diff --git a/aux/broccoli/src/bro_packet.c b/aux/broccoli/src/bro_packet.c deleted file mode 100644 index da6d484a88..0000000000 --- a/aux/broccoli/src/bro_packet.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __EMX__ -#include -#endif - -#include -#include -#include - - -static int -packet_get_link_header_size(int dl) -{ - switch (dl) - { - case DLT_NULL: - return 4; - - case DLT_EN10MB: - return 14; - - case DLT_FDDI: - return 13 + 8; -#ifdef LINUX_HOST - case DLT_LINUX_SLL: - return 16; -#endif - case DLT_RAW: - return 0; - } - - D(("WARNING: unknown DLT type %i encountered.\n", dl)); - return -1; -} - - -BroPacket * -__bro_packet_unserialize(BroConn *bc) -{ - BroPacket *packet; - - if (! (packet = calloc(1, sizeof(BroPacket)))) - return NULL; - - if (! __bro_packet_read(packet, bc)) - { - bro_packet_free(packet); - return NULL; - } - - return packet; -} - - -int -__bro_packet_serialize(BroPacket *packet, BroConn *bc) -{ - D_ENTER; - - /* Prepare the beginning of a serialized packet. - */ - if (! __bro_buf_write_char(bc->tx_buf, 'p')) - D_RETURN_(FALSE); - - if (! __bro_packet_write(packet, bc)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -int -__bro_packet_read(BroPacket *packet, BroConn *bc) -{ - BroString packet_data; - BroString packet_tag; - uint32 tv_sec, tv_usec, len, pcap_link_type; - - D_ENTER; - - if (! packet || ! bc) - D_RETURN_(FALSE); - - packet->pkt_link_type = bc->pcap_link_type; - packet->pkt_hdr_size = packet_get_link_header_size(bc->pcap_link_type); - - if (! __bro_buf_read_int(bc->rx_buf, &tv_sec)) - D_RETURN_(FALSE); - if (! __bro_buf_read_int(bc->rx_buf, &tv_usec)) - D_RETURN_(FALSE); - if (! __bro_buf_read_int(bc->rx_buf, &len)) - D_RETURN_(FALSE); - if (! __bro_buf_read_int(bc->rx_buf, &pcap_link_type)) - D_RETURN_(FALSE); - if (! __bro_buf_read_string(bc->rx_buf, &packet_tag)) - D_RETURN_(FALSE); - if (! __bro_buf_read_string(bc->rx_buf, &packet_data)) - D_RETURN_(FALSE); - - packet->pkt_pcap_hdr.ts.tv_sec = tv_sec; - packet->pkt_pcap_hdr.ts.tv_usec = tv_usec; - packet->pkt_pcap_hdr.len = len; - packet->pkt_pcap_hdr.caplen = packet_data.str_len; - packet->pkt_link_type = pcap_link_type; - packet->pkt_data = (const u_char *) packet_data.str_val; - packet->pkt_tag = (const char *) packet_tag.str_val; - packet->pkt_time = bro_util_current_time(); - - D_RETURN_(TRUE); -} - -int -__bro_packet_write(BroPacket *packet, BroConn *bc) -{ - BroString packet_data; - BroString packet_tag; - - D_ENTER; - - if (! packet || ! bc) - D_RETURN_(FALSE); - - if (! __bro_buf_write_int(bc->tx_buf, (uint32)packet->pkt_pcap_hdr.ts.tv_sec)) - D_RETURN_(FALSE); - if (! __bro_buf_write_int(bc->tx_buf, (uint32)packet->pkt_pcap_hdr.ts.tv_usec)) - D_RETURN_(FALSE); - if (! __bro_buf_write_int(bc->tx_buf, (uint32)packet->pkt_pcap_hdr.len)) - D_RETURN_(FALSE); - if (! __bro_buf_write_int(bc->tx_buf, (uint32)bc->pcap_link_type)) - D_RETURN_(FALSE); - - bro_string_init(&packet_tag); - packet_tag.str_len = strlen(packet->pkt_tag); - packet_tag.str_val = (u_char *) packet->pkt_tag; - - if (! __bro_buf_write_string(bc->tx_buf, &packet_tag)) - D_RETURN_(FALSE); - - bro_string_init(&packet_data); - packet_data.str_len = packet->pkt_pcap_hdr.caplen; - packet_data.str_val = (u_char *) packet->pkt_data; - - if (! __bro_buf_write_string(bc->tx_buf, &packet_data)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -int -__bro_packet_clone(BroPacket *dst, const BroPacket *src) -{ - D_ENTER; - - *dst = *src; - - if (! (dst->pkt_tag = strdup(src->pkt_tag))) - D_RETURN_(FALSE); - - if (! (dst->pkt_data = malloc(src->pkt_pcap_hdr.caplen))) - D_RETURN_(FALSE); - - memcpy((u_char *) dst->pkt_data, src->pkt_data, src->pkt_pcap_hdr.caplen); - D_RETURN_(TRUE); -} diff --git a/aux/broccoli/src/bro_packet.h b/aux/broccoli/src/bro_packet.h deleted file mode 100644 index 138a5bf477..0000000000 --- a/aux/broccoli/src/bro_packet.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_packet_h -#define broccoli_packet_h - -BroPacket *__bro_packet_unserialize(BroConn *bc); -int __bro_packet_serialize(BroPacket *packet, BroConn *bc); - -int __bro_packet_read(BroPacket *packet, BroConn *bc); -int __bro_packet_write(BroPacket *packet, BroConn *bc); -int __bro_packet_clone(BroPacket *dst, const BroPacket *src); - -#endif diff --git a/aux/broccoli/src/bro_parser.y b/aux/broccoli/src/bro_parser.y deleted file mode 100644 index 67811ce53d..0000000000 --- a/aux/broccoli/src/bro_parser.y +++ /dev/null @@ -1,124 +0,0 @@ -%{ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include -#include -#include -#include -#include -#include - -#include "bro_debug.h" -#include "bro_config.h" - -int brolex(void); -int broparse(void); -int broerror(char *, ...); - -#define yylex brolex -#define yyparse broparse -#define yyerror broerror - -int bro_parse_errors = 0; -int bro_parse_lineno = 0; -const char *bro_parse_filename = NULL; - -%} - -%union { - int i; - char *s; - double d; -} - -%token BROINT -%token BROWORD BROSTRING -%token BRODOUBLE - -%% -configfile: - | options - ; -options: option - | options option - ; - -option: domain - | intopt - | stringopt - | floatopt - ; - -intopt: BROWORD BROINT { __bro_conf_add_int($1, $2); - free($1); - } - ; - -stringopt: BROWORD BROSTRING { __bro_conf_add_str($1, $2); - free($1); free($2); - } - | BROWORD BROWORD { __bro_conf_add_str($1, $2); - free($1); free($2); - } - ; - -floatopt: BROWORD BRODOUBLE { __bro_conf_add_dbl($1, $2); - free($1); - } - ; - -domain: '[' BROWORD ']' { __bro_conf_set_storage_domain($2); - free($2); - } - ; -%% - -int -yyerror(char *fmt, ...) -{ - va_list ap; - bro_parse_errors++; - -#ifdef BRO_DEBUG - va_start(ap, fmt); - fprintf(stderr, "%s:%d: ", bro_parse_filename, bro_parse_lineno); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); - va_end(ap); -#endif - return 0; -} - -int -__bro_parse_config(const char *filename) -{ - const char *domain; - extern FILE *broin; - - /* Save the current config domain */ - if ( (domain = __bro_conf_get_domain())) - domain = strdup(domain); - - D(("Parsing configuration from '%s'.\n", filename)); - - if (! (broin = fopen(filename, "r"))) - { - D(("Error opening config file %s: %s\n", filename, strerror(errno))); - return -1; - } - - bro_parse_lineno = 1; - bro_parse_filename = filename; - bro_parse_errors = 0; - - yyparse(); - fclose(broin); - - /* Reset the config domain to the original one. */ - __bro_conf_set_domain(domain); - - return (bro_parse_errors ? -1 : 0); -} diff --git a/aux/broccoli/src/bro_record.c b/aux/broccoli/src/bro_record.c deleted file mode 100644 index 032773a028..0000000000 --- a/aux/broccoli/src/bro_record.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include - -#ifdef __EMX__ -#include -#endif - -#include -#include -#include -#include -#include - - -BroRecord * -__bro_record_new(void) -{ - BroRecord *rec; - - if (! (rec = calloc(1, sizeof(BroRecord)))) - return NULL; - - return rec; -} - - -void -__bro_record_free(BroRecord *rec) -{ - BroList *l; - - if (! rec) - return; - - for (l = rec->val_list; l; l = __bro_list_next(l)) - { - char *field; - BroSObject *obj = __bro_list_data(l); - - if ( (field = __bro_sobject_data_del(obj, "field"))) - free(field); - - __bro_sobject_release(obj); - } - - __bro_list_free(rec->val_list, NULL); - free(rec); -} - -int -__bro_record_get_length(BroRecord *rec) -{ - D_ENTER; - - if (! rec) - D_RETURN_(0); - - D_RETURN_(rec->val_len); -} - -BroRecord * -__bro_record_copy(BroRecord *rec) -{ - BroList *l; - BroVal *val, *val_copy; - BroRecord *copy; - - D_ENTER; - - if (! rec) - D_RETURN_(NULL); - - if (! (copy = __bro_record_new())) - D_RETURN_(NULL); - - for (l = rec->val_list; l; l = __bro_list_next(l)) - { - char *field; - - val = __bro_list_data(l); - - /* Check if it's an assigned val or not */ - if (! val->val_type) - { - D(("Error: unassigned val in record.\n")); - goto error_return; - } - - if (! (val_copy = (BroVal *) __bro_sobject_copy((BroSObject *) val))) - goto error_return; - -#ifdef BRO_DEBUG - if (! val_copy->val_type) - D(("WARNING -- typeless val duplicated as %p, original %p had type %p\n", - val_copy, val, val->val_type)); -#endif - if (! (field = __bro_sobject_data_get((BroSObject *) val, "field"))) - { - D(("Val %p in record %p doesn't have a field name.\n", val, rec)); - goto error_return; - } - - __bro_sobject_data_set((BroSObject *) val_copy, "field", strdup(field)); - __bro_record_add_val(copy, val_copy); - } - - D_RETURN_(copy); - - error_return: - __bro_record_free(copy); - D_RETURN_(NULL); -} - - -void -__bro_record_add_val(BroRecord *rec, BroVal *val) -{ - if (! rec || ! val) - return; - - rec->val_list = __bro_list_append(rec->val_list, val); - rec->val_len++; -} - - -BroVal * -__bro_record_get_nth_val(BroRecord *rec, int num) -{ - BroList *l; - - if (! rec || num < 0 || num >= rec->val_len) - return NULL; - - if( (l = __bro_list_nth(rec->val_list, num))) - return __bro_list_data(l); - - return NULL; -} - - -const char * -__bro_record_get_nth_name(BroRecord *rec, int num) -{ - BroList *l; - - if (! rec || num < 0 || num >= rec->val_len) - return NULL; - - if( (l = __bro_list_nth(rec->val_list, num))) - return __bro_sobject_data_get((BroSObject *) __bro_list_data(l), "field"); - - return NULL; -} - - -BroVal * -__bro_record_get_named_val(BroRecord *rec, const char *name) -{ - BroList *l; - BroVal *val; - - if (! rec || ! name || ! *name) - return NULL; - - for (l = rec->val_list; l; l = __bro_list_next(l)) - { - char *val_name; - - val = __bro_list_data(l); - val_name = __bro_sobject_data_get((BroSObject *) val, "field"); - - if (val_name && ! strcmp(val_name, name)) - return val; - } - - return NULL; -} - - -int -__bro_record_set_nth_val(BroRecord *rec, int num, BroVal *v) -{ - BroVal *val; - BroList *l; - - if (! rec || num < 0 || num >= rec->val_len || ! v) - return FALSE; - - if ( (l = __bro_list_nth(rec->val_list, num))) - { - val = __bro_list_set_data(l, v); - __bro_sobject_release((BroSObject *) val); - return TRUE; - } - - return FALSE; -} - - -int -__bro_record_set_nth_name(BroRecord *rec, int num, const char *name) -{ - BroVal *val; - BroList *l; - - if (! rec || num < 0 || num >= rec->val_len || ! name) - return FALSE; - - if ( (l = __bro_list_nth(rec->val_list, num))) - { - char *val_name; - - val = __bro_list_data(l); - val_name = __bro_sobject_data_del((BroSObject *) val, "field"); - if (val_name) - free(val_name); - - __bro_sobject_data_set((BroSObject *) val, "field", strdup(name)); - return TRUE; - } - - return FALSE; -} - - -int -__bro_record_set_named_val(BroRecord *rec, const char *name, BroVal *v) -{ - BroVal *val; - BroList *l; - - if (! rec || ! name || !*name || ! v) - return FALSE; - - for (l = rec->val_list; l; l = __bro_list_next(l)) - { - char *val_name; - - val = __bro_list_data(l); - val_name = __bro_sobject_data_get((BroSObject *) val, "field"); - - if (val_name && ! strcmp(val_name, name)) - { - /* We're about to delete the old val, make sure it doesn't have - * the name tag associated with it. - */ - __bro_sobject_data_del((BroSObject *) val, "field"); - free(val_name); - - /* If the new val has a name tag, likewise delete it. - */ - if ( (val_name = __bro_sobject_data_del((BroSObject *) val, "field"))) - free(val_name); - - /* Set the new val's name tag - */ - __bro_sobject_data_set((BroSObject *) v, "field", strdup(name)); - - __bro_list_set_data(l, v); - __bro_sobject_release((BroSObject *) val); - - return TRUE; - } - } - - return FALSE; -} - -uint32 -__bro_record_hash(BroRecord *rec) -{ - uint32 result; - BroList *l; - - D_ENTER; - - if (! rec) - D_RETURN_(0); - - result = rec->val_len; - - for (l = rec->val_list; l; l = __bro_list_next(l)) - result ^= __bro_sobject_hash((BroSObject*) __bro_list_data(l)); - - D_RETURN_(result); -} - -int -__bro_record_cmp(BroRecord *rec1, BroRecord *rec2) -{ - BroList *l1, *l2; - - D_ENTER; - - if (! rec1 || ! rec2) - D_RETURN_(FALSE); - - if (rec1->val_len != rec2->val_len) - D_RETURN_(FALSE); - - for (l1 = rec1->val_list, l2 = rec2->val_list; l1 && l2; - l1 = __bro_list_next(l1), l2 = __bro_list_next(l2)) - { - if (! __bro_sobject_cmp((BroSObject*) __bro_list_data(l1), - (BroSObject*) __bro_list_data(l2))) - D_RETURN_(FALSE); - } - - if (l1 || l2) - { - D(("WARNING -- value list inconsistency.\n")); - D_RETURN_(FALSE); - } - - D_RETURN_(TRUE); -} diff --git a/aux/broccoli/src/bro_record.h b/aux/broccoli/src/bro_record.h deleted file mode 100644 index 41bef26678..0000000000 --- a/aux/broccoli/src/bro_record.h +++ /dev/null @@ -1,62 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_record_h -#define broccoli_record_h - -#include -#include - -/* Typedef is in broccoli.h because the users need to know it -- we keep - * it opaque for them though by defining it here. - */ -struct bro_record -{ - BroList *val_list; - int val_len; -}; - -BroRecord *__bro_record_new(void); -void __bro_record_free(BroRecord *rec); -BroRecord *__bro_record_copy(BroRecord *rec); -int __bro_record_get_length(BroRecord *rec); - -/* Adds the given val as a new field and adopts ownership, - * i.e, the value is not duplicated internally. - */ -void __bro_record_add_val(BroRecord *rec, BroVal *val); - -BroVal *__bro_record_get_nth_val(BroRecord *rec, int num); -const char *__bro_record_get_nth_name(BroRecord *rec, int num); -BroVal *__bro_record_get_named_val(BroRecord *rec, const char *name); - -int __bro_record_set_nth_val(BroRecord *rec, int num, BroVal *val); -int __bro_record_set_nth_name(BroRecord *rec, int num, const char *name); -int __bro_record_set_named_val(BroRecord *rec, const char *name, BroVal *val); - -uint32 __bro_record_hash(BroRecord *rec); -int __bro_record_cmp(BroRecord *rec1, BroRecord *rec2); - -#endif diff --git a/aux/broccoli/src/bro_sem.h b/aux/broccoli/src/bro_sem.h deleted file mode 100644 index d061429649..0000000000 --- a/aux/broccoli/src/bro_sem.h +++ /dev/null @@ -1,106 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_sem_h -#define broccoli_sem_h - -#include - -typedef struct bro_sem_impl BroSemImpl; - -typedef struct bro_sem { - int sem_blocked; - BroSemImpl *sem_impl; -} BroSem; - -/* Broccoli semaphore abstractions. - * ================================ - * - * Semaphores are created with __bro_sem_new() and released with - * __bro_sem_free(). Before being used they have to be - * __bro_sem_attach()ed and after using them __bro_sem_detach()ed. - * - * Semaphores are initalized to 0. - * - * All functions can be called with NULL parameters, for robustness. - */ - -int __bro_sem_init(BroSem *sem, const BroConn *bc); -void __bro_sem_cleanup(BroSem *sem); - -int __bro_sem_attach(BroSem *sem); -int __bro_sem_detach(BroSem *sem); - -/** - * __bro_sem_decr - decreases semaphore. - * @sem: semaphore. - * - * The function decreases the value of the semaphore by one, returning - * if the initial value was greater than 0, and blocking otherwise. - * - * Returns: %TRUE on success, %FALSE otherwise. - */ -int __bro_sem_decr(BroSem *sem); - - -/** - * __bro_sem_trydecr - decreases semaphore, but never blocks - * @sem: semaphore. - * - * The function decreases the value of the semaphore by one, returning - * if the initial value was greater than 0. If the semaphore is - * currently locked, the function returns %FALSE immediately. - * - * Returns: %TRUE on success, %FALSE otherwise. - */ -int __bro_sem_trydecr(BroSem *sem); - - -/** - * __bro_sem_incr - increases semaphore. - * @sem: semaphore. - * - * The function increases the value of the semaphore by 1. - * - * Returns: %TRUE on success, %FALSE otherwise. - */ -int __bro_sem_incr(BroSem *sem); - - -/** - * __bro_sem_get - returns current value of sempahore. - * @sem: semaphore. - * @result: result pointer. - * - * The function returns the current value of the semaphore through - * the @result pointer. - * - * Returns: %TRUE on success, %FALSE otherwise. - */ -int __bro_sem_get(BroSem *sem, int *result); - -int __bro_sem_get_blocked(BroSem *sem, int *result); - -#endif diff --git a/aux/broccoli/src/bro_sem_none.c b/aux/broccoli/src/bro_sem_none.c deleted file mode 100644 index e805f96aab..0000000000 --- a/aux/broccoli/src/bro_sem_none.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include - -struct bro_sem { }; - -BroSem * -__bro_sem_new(const BroConn *bc) -{ - bc = NULL; - return NULL; -} - - -void -__bro_sem_free(BroSem *sem) -{ - sem = NULL; -} - - -int -__bro_sem_attach(BroSem *sem) -{ - return TRUE; - sem = NULL; -} - - -int -__bro_sem_detach(BroSem *sem) -{ - return TRUE; - sem = NULL; -} - - -int -__bro_sem_decr(BroSem *sem) -{ - sem = NULL; -} - - -int -__bro_sem_incr(BroSem *sem) -{ - sem = NULL; -} diff --git a/aux/broccoli/src/bro_sem_posix.c b/aux/broccoli/src/bro_sem_posix.c deleted file mode 100644 index d1bf8486ea..0000000000 --- a/aux/broccoli/src/bro_sem_posix.c +++ /dev/null @@ -1,213 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef __EMX__ -#include -#endif - -#include -#include -#include -#include - -struct bro_sem_impl { - char *name; - sem_t *sem; -}; - -int -__bro_sem_init(BroSem *sem, const BroConn *bc) -{ - static int counter = 0; - char sem_name[512]; - - D_ENTER; - - if (! sem || ! bc) - D_RETURN_(FALSE); - - memset(sem, 0, sizeof(BroSem)); - - if (! (sem->sem_impl = calloc(1, sizeof(BroSemImpl)))) - D_RETURN_(FALSE); - - __bro_util_snprintf(sem_name, 512, "/broccoli-%u-%i-%i", bc->id_pid, bc->id_num, counter++); - sem->sem_impl->name = strdup(sem_name); - sem->sem_impl->sem = sem_open(sem_name, O_CREAT, S_IRWXU, 1); - - if (sem->sem_impl->sem == SEM_FAILED) - { - if (sem->sem_impl->name) - free(sem->sem_impl->name); - - free(sem->sem_impl); - - D(("POSIX semaphore creation failed: %s\n", strerror(errno))); - D_RETURN_(FALSE); - } - - D_RETURN_(TRUE); -} - - -void -__bro_sem_cleanup(BroSem *sem) -{ - D_ENTER; - - if (! sem || ! sem->sem_impl) - D_RETURN; - - sem_unlink(sem->sem_impl->name); - - free(sem->sem_impl->name); - free(sem->sem_impl); - memset(sem, 0, sizeof(BroSem)); - - D_RETURN; -} - - -int -__bro_sem_attach(BroSem *sem) -{ - /* Unused in Posix. */ - return TRUE; - sem = NULL; -} - - -int -__bro_sem_detach(BroSem *sem) -{ - if (! sem || ! sem->sem_impl) - return FALSE; - - sem_close(sem->sem_impl->sem); - return TRUE; -} - - -int -__bro_sem_decr(BroSem *sem) -{ - D_ENTER; - - if (! sem || ! sem->sem_impl) - D_RETURN_(FALSE); - - sem->sem_blocked++; - - if (sem_wait(sem->sem_impl->sem) < 0) - { - D(("sem_wait() error: %s\n", strerror(errno))); - sem->sem_blocked--; - D_RETURN_(FALSE); - } - - sem->sem_blocked--; - D_RETURN_(TRUE); -} - - -int -__bro_sem_trydecr(BroSem *sem) -{ - if (! sem || ! sem->sem_impl) - return FALSE; - - sem->sem_blocked++; - - if (sem_trywait(sem->sem_impl->sem) < 0) - { - sem->sem_blocked--; - - if (errno == EAGAIN) - return FALSE; - - D(("sem_wait() error: %s\n", strerror(errno))); - return FALSE; - } - - sem->sem_blocked--; - return TRUE; -} - - -int -__bro_sem_incr(BroSem *sem) -{ - D_ENTER; - - if (! sem || ! sem->sem_impl) - D_RETURN_(FALSE); - - if (sem_post(sem->sem_impl->sem) < 0) - { - D(("sem_post() error: %s\n", strerror(errno))); - D_RETURN_(FALSE); - } - - D_RETURN_(TRUE); -} - - -int -__bro_sem_get(BroSem *sem, int *result) -{ - if (! sem || ! sem->sem_impl || ! result) - return FALSE; - - if (! sem_getvalue(sem->sem_impl->sem, result)) - return FALSE; - - return TRUE; -} - - -int -__bro_sem_get_blocked(BroSem *sem, int *result) -{ - if (! sem || ! sem->sem_impl || ! result) - return FALSE; - - *result = sem->sem_blocked; - - return TRUE; -} diff --git a/aux/broccoli/src/bro_sem_sysv.c b/aux/broccoli/src/bro_sem_sysv.c deleted file mode 100644 index 0c13d30373..0000000000 --- a/aux/broccoli/src/bro_sem_sysv.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#define BRO_SEM_ATTEMPTS_MAX 50 - -#ifdef SEM_R -#define BRO_SEMFLAGS SEM_A|SEM_R -#else -#define BRO_SEMFLAGS S_IRWXU -#endif - -/* It's not my fault -- blame the standards and deviating - * implementations for this goop. :( - */ -#if defined(BSD_HOST) && ! defined(__NetBSD__) -/* union semun is defined by including */ -#else -/* according to X/OPEN we have to define it ourselves */ -union semun { - int val; /* value for SETVAL */ - struct semid_ds *buf; /* buffer for IPC_STAT, IPC_SET */ - unsigned short *array; /* array for GETALL, SETALL */ - /* Linux specific part: */ - struct seminfo *__buf; /* buffer for IPC_INFO */ -}; -#endif - - -struct bro_sem_impl { - int sem_id; -}; - - -int -__bro_sem_init(BroSem *sem, const BroConn *bc) -{ - int sem_id = -1; - union semun arg; - - D_ENTER; - - if (! sem || ! sem->sem_impl) - D_RETURN_(FALSE); - - memset(sem, 0, sizeof(BroSem)); - - /* Attempt to allocate the semaphore set */ - if ( (sem_id = semget(IPC_PRIVATE, 1, IPC_CREAT|IPC_EXCL|BRO_SEMFLAGS)) < 0) - { - D(("semget error: %s\n", strerror(errno))); - D_RETURN_(FALSE); - } - - /* Initialize the semaphore. Note: I'm not 100% sure whether this - * code is prone to the race condition that Stevens describes on - * p. 284 of UNP Vol 2 (IPC). It would likely be safer to take - * precautions, this is a FIXME. - */ - arg.val = 1; - if (semctl(sem_id, 0, SETVAL, arg) < 0) - { - D(("semctl failed: %s\n", strerror(errno))); - D_RETURN_(FALSE); - } - - if (! (sem->sem_impl = calloc(1, sizeof(BroSemImpl)))) - D_RETURN_(FALSE); - - sem->sem_impl->sem_id = sem_id; - - D_RETURN_(TRUE); - bc = NULL; -} - - -void -__bro_sem_cleanup(BroSem *sem) -{ - D_ENTER; - - if (! sem || ! sem->sem_impl) - D_RETURN; - - if (semctl(sem->sem_impl->sem_id, 0, IPC_RMID) < 0) - { - D(("semctl could not remove semaphore: %s.\n", strerror(errno))); - } - - free(sem->sem_impl); - memset(sem, 0, sizeof(BroSem)); - D_RETURN; -} - - -int -__bro_sem_attach(BroSem *sem) -{ - /* Unused in SYSV. */ - return TRUE; - sem = NULL; -} - - -int -__bro_sem_detach(BroSem *sem) -{ - /* Unused in SYSV. */ - return TRUE; - sem = NULL; -} - - -int -__bro_sem_decr(BroSem *sem) -{ - struct sembuf opt; - - if (! sem || ! sem->sem_impl) - return FALSE; - - /* This hopefully does the following atomically: - * - * (1) block until the semaphore's value becomes >= 1 - * (2) subtracts 1 from the semaphore's value (i.e., sets it to 0) - * (3) wakes up thread. - * - * This is how I parse Stevens UNP Vol 2 (IPC), p. 287. - */ - opt.sem_num = 0; - opt.sem_op = -1; - opt.sem_flg = 0; - sem->sem_blocked++; - - if (semop(sem->sem_impl->sem_id, &opt, 1) < 0) - { - sem->sem_blocked--; - return FALSE; - } - - sem->sem_blocked--; - return TRUE; -} - - -int -__bro_sem_trydecr(BroSem *sem) -{ - struct sembuf opt; - - if (! sem || ! sem->sem_impl) - return FALSE; - - opt.sem_num = 0; - opt.sem_op = -1; - opt.sem_flg = IPC_NOWAIT; - sem->sem_blocked++; - - if (semop(sem->sem_impl->sem_id, &opt, 1) < 0) - { - sem->sem_blocked--; - return FALSE; - } - - sem->sem_blocked--; - return TRUE; -} - - -int -__bro_sem_incr(BroSem *sem) -{ - struct sembuf opt; - - if (! sem || ! sem->sem_impl) - return FALSE; - - /* Add one to the semaphore's value. That one should - * be easy ... - */ - opt.sem_num = 0; - opt.sem_op = 1; - opt.sem_flg = 0; - - if (semop(sem->sem_impl->sem_id, &opt, 1) < 0) - return FALSE; - - return TRUE; -} - - -int -__bro_sem_get(BroSem *sem, int *result) -{ - if (! sem || ! sem->sem_impl || ! result) - return FALSE; - - if (semctl(sem->sem_impl->sem_id, 0, GETVAL, result) < 0) - { - D(("semctl failed: %s\n", strerror(errno))); - return FALSE; - } - - return TRUE; -} - - -int -__bro_sem_get_blocked(BroSem *sem, int *result) -{ - if (! sem || ! sem->sem_impl || ! result) - return FALSE; - - *result = sem->sem_blocked; - - return TRUE; -} diff --git a/aux/broccoli/src/bro_shm.h b/aux/broccoli/src/bro_shm.h deleted file mode 100644 index 0d5590e3a8..0000000000 --- a/aux/broccoli/src/bro_shm.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_shm_h -#define broccoli_shm_h - -#include -#include - -typedef struct bro_shared_mem BroSharedMem; - -BroSharedMem *__bro_shm_new(int size); -void __bro_shm_free(BroSharedMem *shm); - -int __bro_shm_attach(BroSharedMem *shm); -int __bro_shm_detach(BroSharedMem *shm); - -void *__bro_shm_get_mem(const BroSharedMem *shm); -int __bro_shm_get_size(const BroSharedMem *shm); - -#endif diff --git a/aux/broccoli/src/bro_shm_none.c b/aux/broccoli/src/bro_shm_none.c deleted file mode 100644 index da49307b41..0000000000 --- a/aux/broccoli/src/bro_shm_none.c +++ /dev/null @@ -1,103 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include - -struct bro_shared_mem { - void *mem; - int mem_size; -}; - -BroSharedMem * -__bro_shm_new(int size) -{ - BroSharedMem *shm; - - if (size <= 0) - return NULL; - - if (! (shm = calloc(1, sizeof(BroSharedMem)))) - return NULL; - - if (! (shm->mem = malloc(size))) - { - free(shm); - return NULL; - } - - shm->mem_size = size; - - return shm; -} - - -void -__bro_shm_free(BroSharedMem *shm) -{ - if (! shm) - return; - - if (shm->mem) - free(shm->mem); - - free(shm); -} - - -void * -__bro_shm_get_mem(const BroSharedMem *shm) -{ - if (! shm) - return NULL; - - return shm->mem; -} - - -int -__bro_shm_get_size(const BroSharedMem *shm) -{ - return shm->mem_size; -} - - -int -__bro_shm_attach(BroSharedMem *shm) -{ - return TRUE; - shm = NULL; -} - - -int -__bro_shm_detach(BroSharedMem *shm) -{ - return TRUE; - shm = NULL; -} diff --git a/aux/broccoli/src/bro_shm_sysv.c b/aux/broccoli/src/bro_shm_sysv.c deleted file mode 100644 index 294c300258..0000000000 --- a/aux/broccoli/src/bro_shm_sysv.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -struct bro_shared_mem { - int shm_id; - int shm_size; - void *shm_mem; - - int shm_attached; -}; - -BroSharedMem * -__bro_shm_new(int size) -{ - int shm_id; - BroSharedMem *shm; - - if (size <= 0) - return NULL; - - if ( (shm_id = shmget(IPC_PRIVATE,size, IPC_CREAT|IPC_EXCL|S_IRWXU)) < 0) - { - D(("shmget error: %s\n", strerror(errno))); - return NULL; - } - - if (! (shm = calloc(1, sizeof(BroSharedMem)))) - return NULL; - - shm->shm_id = shm_id; - shm->shm_size = size; - - return shm; -} - - -void -__bro_shm_free(BroSharedMem *shm) -{ - if (! shm) - return; - - shmctl(shm->shm_id, IPC_RMID, NULL); - free(shm); -} - - -void * -__bro_shm_get_mem(const BroSharedMem *shm) -{ - if (! shm || ! shm->shm_attached) - return NULL; - - return shm->shm_mem; -} - - -int -__bro_shm_get_size(const BroSharedMem *shm) -{ - return shm->shm_size; -} - - - -int -__bro_shm_attach(BroSharedMem *shm) -{ - if (! shm) - return FALSE; - - shm->shm_mem = shmat(shm->shm_id, NULL, 0); - - if ((int) shm->shm_mem == -1) - { - D(("shmat problem: %s.\n", strerror(errno))); - return FALSE; - } - - shm->shm_attached = TRUE; - return TRUE; -} - - -int -__bro_shm_detach(BroSharedMem *shm) -{ - if (! shm || ! shm->shm_attached) - return FALSE; - - if (shmdt(shm->shm_mem) < 0) - { - D(("shmdt problem: %s.\n", strerror(errno))); - return FALSE; - } - - return TRUE; -} diff --git a/aux/broccoli/src/bro_sobject.c b/aux/broccoli/src/bro_sobject.c deleted file mode 100644 index c995cbb270..0000000000 --- a/aux/broccoli/src/bro_sobject.c +++ /dev/null @@ -1,519 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __EMX__ -#include -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static uint32 __bro_sobject_hash_impl(BroSObject *obj); -static int __bro_sobject_cmp_impl(BroSObject *obj1, BroSObject *obj2); - -/* Factory for object instances -- essentially a mapping from a type ID - * to a function taking no arguments and returning an object derived - * from BroSObject. - */ -typedef struct bro_obj_factory_entry -{ - uint16 type_id; - BroSObject *(* create)(void); -} BroObjFactoryEntry; - -static BroObjFactoryEntry obj_factories[] = { - { SER_OBJ, (BroSObjectNew) __bro_object_new }, - { SER_VAL, (BroSObjectNew) __bro_val_new }, - { SER_INTERVAL_VAL, (BroSObjectNew) __bro_val_new }, - { SER_PORT_VAL, (BroSObjectNew) __bro_val_new }, - { SER_ADDR_VAL, (BroSObjectNew) __bro_val_new }, - { SER_SUBNET_VAL, (BroSObjectNew) __bro_val_new }, - { SER_NET_VAL, (BroSObjectNew) __bro_val_new }, - { SER_STRING_VAL, (BroSObjectNew) __bro_val_new }, - { SER_ENUM_VAL, (BroSObjectNew) __bro_val_new }, - { SER_LIST_VAL, (BroSObjectNew) __bro_list_val_new }, - { SER_MUTABLE_VAL, (BroSObjectNew) __bro_mutable_val_new }, - { SER_RECORD_VAL, (BroSObjectNew) __bro_record_val_new }, - { SER_TABLE_VAL, (BroSObjectNew) __bro_table_val_new }, - - { SER_TYPE, (BroSObjectNew) __bro_type_new }, - { SER_TYPE_LIST, (BroSObjectNew) __bro_type_list_new }, - { SER_RECORD_TYPE, (BroSObjectNew) __bro_record_type_new }, - { SER_INDEX_TYPE, (BroSObjectNew) __bro_index_type_new }, - { SER_TABLE_TYPE, (BroSObjectNew) __bro_table_type_new }, - { SER_SET_TYPE, (BroSObjectNew) __bro_set_type_new }, - { SER_ATTRIBUTES, (BroSObjectNew) __bro_attrs_new }, - { SER_ID, (BroSObjectNew) __bro_id_new }, - { SER_LOCATION, (BroSObjectNew) __bro_loc_new }, -}; - - -BroSObject * -__bro_sobject_create(uint16 type_id) -{ - int i, num_factories; - - D_ENTER; - - num_factories = sizeof(obj_factories) / sizeof(BroObjFactoryEntry); - - for (i = 0; i < num_factories; i++) - { - if (obj_factories[i].type_id == type_id && obj_factories[i].create) - { - BroSObject *result = obj_factories[i].create(); - D_RETURN_(result); - } - } - - D(("Creation of object type 0x%04x failed.\n", type_id)); - D_RETURN_(NULL); -} - - -void -__bro_sobject_release(BroSObject *obj) -{ - D_ENTER; - - if (! obj) - D_RETURN; - - obj->ref_count--; - - if (obj->ref_count > 0) - { - D(("Object %p has non-zero refcount, not releasing\n", obj)); - D_RETURN; - } - - if (obj->free) - obj->free(obj); - - D_RETURN; -} - - -void -__bro_sobject_ref(BroSObject *obj) -{ - obj->ref_count++; -} - - -BroSObject * -__bro_sobject_copy(BroSObject *obj) -{ - BroSObject *clone; - - D_ENTER; - - if (! obj) - D_RETURN_(NULL); - - if (! (clone = __bro_sobject_create(obj->type_id))) - D_RETURN_(NULL); - - if (clone->clone) - clone->clone(clone, obj); - - D_RETURN_(clone); -} - - -BroSObject * -__bro_sobject_new(void) -{ - BroSObject *obj; - - D_ENTER; - - if (! (obj = calloc(1, sizeof(BroSObject)))) - D_RETURN_(NULL); - - __bro_sobject_init(obj); - - D_RETURN_(obj); -} - -void -__bro_sobject_init(BroSObject *obj) -{ - D_ENTER; - - obj->ref_count = 1; - - if (! (obj->data = __bro_ht_new(__bro_ht_str_hash, - __bro_ht_str_cmp, - __bro_ht_mem_free, - NULL, - FALSE))) - { - D(("Out of memory.\n")); - /* FIXME -- add return value to initializer methods. */ - } - - obj->read = __bro_sobject_read; - obj->write = __bro_sobject_write; - obj->free = __bro_sobject_free; - obj->clone = __bro_sobject_clone; - obj->hash = __bro_sobject_hash_impl; - obj->cmp = __bro_sobject_cmp_impl; - - D_RETURN; -} - -void -__bro_sobject_free(BroSObject *obj) -{ - D_ENTER; - - if (! obj) - D_RETURN; - - __bro_ht_free(obj->data); - free(obj); - - D_RETURN; -} - - -int -__bro_sobject_clone(BroSObject *dst, BroSObject *src) -{ - D_ENTER; - - dst->perm_id = src->perm_id; - dst->type_id = src->type_id; /* Should aready be set, but what the heck .. */ - dst->ref_count = 1; - - /* We don't clone the contents of the data hashtable -- - * actually we can't right now ... - */ - - D_RETURN_(TRUE); -} - - -static uint32 -__bro_sobject_hash_impl(BroSObject *obj) -{ - uint32 result; - - D_ENTER; - - if (! obj) - D_RETURN_(0); - - result = obj->perm_id ^ (uint32) obj->type_id; - - D_RETURN_(result); -} - - -static int -__bro_sobject_cmp_impl(BroSObject *obj1, BroSObject *obj2) -{ - D_ENTER; - - if (! obj1 || ! obj2) - D_RETURN_(FALSE); - - if (obj1->perm_id != obj2->perm_id) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -uint32 -__bro_sobject_hash(BroSObject *obj) -{ - D_ENTER; - - if (! obj) - D_RETURN_(0); - - D_RETURN_(obj->hash(obj)); -} - -int -__bro_sobject_cmp(BroSObject *obj1, BroSObject *obj2) -{ - D_ENTER; - - if (! obj1 || !obj2) - D_RETURN_(FALSE); - - D_RETURN_(obj1->cmp(obj1, obj2)); -} - - -int -__bro_sobject_serialize(BroSObject *obj, BroConn *bc) -{ - char full_obj; - - D_ENTER; - - if (! obj || !bc) - D_RETURN_(FALSE); - - /* Special case for types: they indicate at the very beginning - * whether they're transferred in their entirety or just via - * their name (in which case we can't do much at the moment). - */ - if ( (obj->type_id & SER_TYPE_MASK) == SER_IS_TYPE) - { - BroType *type = (BroType *) obj; - - D(("Serializing type %X as type\n", obj->type_id)); - - if (! __bro_buf_write_char(bc->tx_buf, type->is_complete)) - D_RETURN_(FALSE); - - if (! type->is_complete) - { - if (! __bro_buf_write_string(bc->tx_buf, &type->type_name)) - D_RETURN_(FALSE); - - D(("Type sent by type-name '%s' only.\n", bro_string_get_data(&type->type_name))); - D_RETURN_(TRUE); - } - } - - /* FIXME: for now we never use the serialization cache when sending. */ - full_obj = 1; - - if (! __bro_buf_write_char(bc->tx_buf, full_obj)) - D_RETURN_(FALSE); - if (! __bro_buf_write_int(bc->tx_buf, obj->perm_id)) - D_RETURN_(FALSE); - - if (! obj->write(obj, bc)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -BroSObject * -__bro_sobject_unserialize(uint16 type_id_wanted, BroConn *bc) -{ - BroSObject *obj; - char full_obj; - uint32 perm_id; - uint16 type_id; - - D_ENTER; - - if (! bc) - D_RETURN_(NULL); - - /* Same special case for types as in __bro_sobject_serialize(). - */ - if ( (type_id_wanted & SER_TYPE_MASK) == SER_IS_TYPE) - { - D(("Unserializing a type, checking for name-only format.\n")); - - if (! __bro_buf_read_char(bc->rx_buf, &full_obj)) - D_RETURN_(NULL); - - if (! full_obj) - { - BroString tmp; - bro_string_init(&tmp); - - /* We only get the name. */ - if (! __bro_buf_read_string(bc->rx_buf, &tmp)) - D_RETURN_(FALSE); - - /* We don't really have a namespace in which we can now - * look up the type, so there's not much we can do! - */ - D(("Received name-only type '%s', reporting failure.\n", - bro_string_get_data(&tmp))); - D_RETURN_(FALSE); - } - } - - if (! __bro_buf_read_char(bc->rx_buf, &full_obj)) - D_RETURN_(NULL); - - if (! __bro_buf_read_int(bc->rx_buf, &perm_id)) - D_RETURN_(NULL); - - if (! full_obj) - { -#ifdef BRO_DEBUG - if (! (bc->conn_flags & BRO_CFLAG_CACHE)) - D(("WARNING: no caching requested, yet peer sends cached data.\n")); -#endif - if (! (obj = __bro_ht_get(bc->io_cache, (void *)(uintptr_t) perm_id))) - { - D(("Cache inconsistency: cache should contain object %i\n", perm_id)); - D_RETURN_(NULL); - } - - __bro_sobject_ref(obj); - - D(("Returning object %i/%p from cache.\n", perm_id, obj)); - D_RETURN_(obj); - } - - if (! __bro_buf_read_short(bc->rx_buf, &type_id)) - D_RETURN_(NULL); - - /* Now check if the stuff that's arriving is actually an - * instance of the type we'd like to see -- we can only do - * primitive checking for inherited types (when we want to - * know that it's a type, say, but we cannot know what exact - * kind of type) -- so we just check whether all the bits set - * in both type id's match: - */ - if ((type_id_wanted & SER_TYPE_MASK) != (type_id & SER_TYPE_MASK)) - { - D(("Type mismatch in serialization: wanted %04x, got %04x.\n", - type_id_wanted, type_id)); - D_RETURN_(NULL); - } - - if (! (obj = __bro_sobject_create(type_id))) - D_RETURN_(NULL); - - /* Polymorphism: depending on the constructor of the object, - * this call will start from the bottom of the hierarchy and - * read members in step by step, so by the time we return - * from this function the object is fully unserialized. - */ - if (! obj->read(obj, bc)) - { - D(("Reading object %i of type 0x%04x FAILED.\n", perm_id, type_id)); - __bro_sobject_release(obj); - D_RETURN_(NULL); - } - - /* If we have asked the peer to use caching, - * make sure the object is in the cache: - */ - if ( (bc->conn_flags & BRO_CFLAG_CACHE) && - ! __bro_ht_get(bc->io_cache, (void *)(uintptr_t) perm_id)) - { - D(("Storing object %i in cache.\n", perm_id)); - __bro_ht_add(bc->io_cache, (void *)(uintptr_t) perm_id, obj); - obj->perm_id = perm_id; - __bro_sobject_ref(obj); - } - - D(("Object %i of type 0x%04x unserialized successfully.\n", perm_id, type_id)); - D_RETURN_(obj); -} - - -int -__bro_sobject_read(BroSObject *obj, BroConn *bc) -{ - D_ENTER; - D_RETURN_(TRUE); - - obj = NULL; - bc = NULL; -} - - -int -__bro_sobject_write(BroSObject *obj, BroConn *bc) -{ - D_ENTER; - - if (! __bro_buf_write_short(bc->tx_buf, obj->type_id)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -void -__bro_sobject_data_set(BroSObject *obj, const char *key, void *val) -{ - D_ENTER; - - if (! obj || ! key || ! *key) - D_RETURN; - - __bro_ht_add(obj->data, strdup(key), val); - /* D(("Setting data item '%s' in object %p\n", key, obj)); */ - - D_RETURN; -} - - -void * -__bro_sobject_data_get(BroSObject *obj, const char *key) -{ - void *result; - - if (! obj || ! key || ! *key) - return NULL; - - result = __bro_ht_get(obj->data, (void *) key); - /* D(("Retrieving data item '%s' from object %p yields %p\n", key, obj, result)); */ - return result; -} - - -void * -__bro_sobject_data_del(BroSObject *obj, const char *key) -{ - void *result; - - D_ENTER; - - if (! obj || ! key || ! *key) - D_RETURN_(NULL); - - result = __bro_ht_del(obj->data, (void *) key); - /* D(("Removing data item '%s' from object %p yields %p\n", key, obj, result)); */ - D_RETURN_(result); -} diff --git a/aux/broccoli/src/bro_sobject.h b/aux/broccoli/src/bro_sobject.h deleted file mode 100644 index c633fb2177..0000000000 --- a/aux/broccoli/src/bro_sobject.h +++ /dev/null @@ -1,263 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_serial_object_h -#define broccoli_serial_object_h - -#include -#include - -/* A whole bunch of definitons taken straight out of Bro and run through cpp :) - * These are type tags -- see explanation in SerialTypes.h in the Bro tree. We use - * these tags to map to the default constructor implementation for an - * object upon unserialization. - */ -#define SER_TYPE_MASK 0xff00 -#define SER_NONE 0 - - -/* "Abstract" parent classes, not used directly */ -#define SER_IS_OBJ 0x8000 -#define SER_IS_CONNECTION (0x0100 | SER_IS_OBJ) -#define SER_IS_TIMER 0x0200 -#define SER_IS_TCP_ENDPOINT 0x0300 -#define SER_IS_TCP_ANALYZER (0x0400 | SER_IS_OBJ) -#define SER_IS_TCP_ENDPOINT_ANALYZER (0x0500 | SER_IS_OBJ) -#define SER_IS_TCP_CONTENTS 0x0600 -#define SER_IS_REASSEMBLER 0x0700 -#define SER_IS_VAL (0x0800 | SER_IS_OBJ) -#define SER_IS_EXPR (0x0900 | SER_IS_OBJ) -#define SER_IS_TYPE (0x0a00 | SER_IS_OBJ) -#define SER_IS_STMT (0x0b00 | SER_IS_OBJ) -#define SER_IS_ATTRIBUTES (0x0c00 | SER_IS_OBJ) -#define SER_IS_EVENT_HANDLER 0x0d00 -#define SER_IS_FILE (0x0e00 | SER_IS_OBJ) -#define SER_IS_FUNC (0x0f00 | SER_IS_OBJ) -#define SER_IS_ID (0x1000 | SER_IS_OBJ) -#define SER_IS_STATE_ACCESS 0x1100 -#define SER_IS_CASE (0x1200 | SER_IS_OBJ) -#define SER_IS_LOCATION 0x1300 -#define SER_IS_RE_MATCHER 0x1400 - -/* Usable derivations */ -#define SER_OBJ (1 | SER_IS_OBJ) -#define SER_VAL (1 | SER_IS_VAL) -#define SER_INTERVAL_VAL (2 | SER_IS_VAL) -#define SER_PORT_VAL (3 | SER_IS_VAL) -#define SER_ADDR_VAL (4 | SER_IS_VAL) -#define SER_NET_VAL (5 | SER_IS_VAL) -#define SER_SUBNET_VAL (6 | SER_IS_VAL) -#define SER_STRING_VAL (7 | SER_IS_VAL) -#define SER_PATTERN_VAL (8 | SER_IS_VAL) -#define SER_LIST_VAL (9 | SER_IS_VAL) -#define SER_TABLE_VAL (10 | SER_IS_VAL) -#define SER_RECORD_VAL (11 | SER_IS_VAL) -#define SER_ENUM_VAL (12 | SER_IS_VAL) -#define SER_VECTOR_VAL (13 | SER_IS_VAL) -#define SER_MUTABLE_VAL (14 | SER_IS_VAL) - -#define SER_EXPR (1 | SER_IS_EXPR) -#define SER_NAME_EXPR (2 | SER_IS_EXPR) -#define SER_CONST_EXPR (3 | SER_IS_EXPR) -#define SER_UNARY_EXPR (4 | SER_IS_EXPR) -#define SER_BINARY_EXPR (5 | SER_IS_EXPR) -#define SER_INCR_EXPR (6 | SER_IS_EXPR) -#define SER_NOT_EXPR (7 | SER_IS_EXPR) -#define SER_POS_EXPR (8 | SER_IS_EXPR) -#define SER_NEG_EXPR (9 | SER_IS_EXPR) -#define SER_ADD_EXPR (10 | SER_IS_EXPR) -#define SER_SUB_EXPR (11 | SER_IS_EXPR) -#define SER_TIMES_EXPR (12 | SER_IS_EXPR) -#define SER_DIVIDE_EXPR (13 | SER_IS_EXPR) -#define SER_MOD_EXPR (14 | SER_IS_EXPR) -#define SER_BOOL_EXPR (15 | SER_IS_EXPR) -#define SER_EQ_EXPR (16 | SER_IS_EXPR) -#define SER_REL_EXPR (17 | SER_IS_EXPR) -#define SER_COND_EXPR (18 | SER_IS_EXPR) -#define SER_REF_EXPR (19 | SER_IS_EXPR) -#define SER_ASSIGN_EXPR (20 | SER_IS_EXPR) -#define SER_INDEX_EXPR (21 | SER_IS_EXPR) -#define SER_FIELD_EXPR (22 | SER_IS_EXPR) -#define SER_HAS_FIELD_EXPR (23 | SER_IS_EXPR) -#define SER_RECORD_CONSTRUCTOR_EXPR (24 | SER_IS_EXPR) -#define SER_FIELD_ASSIGN_EXPR (25 | SER_IS_EXPR) -#define SER_RECORD_MATCH_EXPR (26 | SER_IS_EXPR) -#define SER_ARITH_COERCE_EXPR (27 | SER_IS_EXPR) -#define SER_RECORD_COERCE_EXPR (28 | SER_IS_EXPR) -#define SER_FLATTEN_EXPR (29 | SER_IS_EXPR) -#define SER_SCHEDULE_EXPR (30 | SER_IS_EXPR) -#define SER_IN_EXPR (31 | SER_IS_EXPR) -#define SER_CALL_EXPR (32 | SER_IS_EXPR) -#define SER_EVENT_EXPR (33 | SER_IS_EXPR) -#define SER_LIST_EXPR (34 | SER_IS_EXPR) -#define SER_RECORD_ASSIGN_EXPR (35 | SER_IS_EXPR) - -#define SER_TYPE (1 | SER_IS_TYPE) -#define SER_TYPE_LIST (2 | SER_IS_TYPE) -#define SER_INDEX_TYPE (3 | SER_IS_TYPE) -#define SER_TABLE_TYPE (4 | SER_IS_TYPE) -#define SER_SET_TYPE (5 | SER_IS_TYPE) -#define SER_FUNC_TYPE (6 | SER_IS_TYPE) -#define SER_RECORD_TYPE (7 | SER_IS_TYPE) -#define SER_SUBNET_TYPE (8 | SER_IS_TYPE) -#define SER_FILE_TYPE (9 | SER_IS_TYPE) -#define SER_ENUM_TYPE (10 | SER_IS_TYPE) -#define SER_VECTOR_TYPE (11 | SER_IS_TYPE) - -#define SER_ATTRIBUTES (1 | SER_IS_ATTRIBUTES) - -#define SER_EVENT_HANDLER (1 | SER_IS_EVENT_HANDLER) -#define SER_FILE (1 | SER_IS_FILE) - -#define SER_FUNC (1 | SER_IS_FUNC) -#define SER_BRO_FUNC (2 | SER_IS_FUNC) -#define SER_DEBUG_FUNC (3 | SER_IS_FUNC) -#define SER_BUILTIN_FUNC (4 | SER_IS_FUNC) - -#define SER_ID (1 | SER_IS_ID) -#define SER_STATE_ACCESS (1 | SER_IS_STATE_ACCESS) -#define SER_CASE (1 | SER_IS_CASE) -#define SER_LOCATION (1 | SER_IS_LOCATION) -#define SER_RE_MATCHER (1 | SER_IS_RE_MATCHER) - -typedef struct bro_serial_object BroSObject; - -typedef BroSObject *(* BroSObjectNew) (void); - -/* Signatures for all functions which we virtualize. */ -typedef int (* BroSObjectRead) (BroSObject *obj, BroConn *bc); -typedef int (* BroSObjectWrite) (BroSObject *obj, BroConn *bc); -typedef void (* BroSObjectFree) (BroSObject *obj); -typedef int (* BroSObjectClone) (BroSObject *dst, BroSObject *src); -typedef uint32 (* BroSObjectHash) (BroSObject *obj); -typedef int (* BroSObjectCmp) (BroSObject *obj1, BroSObject *obj2); - -/* BroSObjects are the base "class" of objects that can be serialized. - * They mirror SerialObj in Bro. The way Broccoli realizes classes, - * objects, and inheritance is as follows: - * - * (1) There is no distinction between classes and the objects that - * are created from them. That means that each object carries with - * it all the function pointers needed to implement polymorphism. - * Yes, this wastes space, but for now I don't think it wastes - * enough to justify the additional complexity of explicit-class, - * Gtk-style object orientation in C. - * - * (2) Currently, the only virtualized functions are the ones defined - * in BroSObject below, though this may change in the future. - * These functions implement reading/writing from/to a buffer, - * cleanup, cloning, hashing to a uint32, and strcmp()-style - * instance comparison. - * - * Implementations of these functions need to work in typical OO - * fashion, i.e., they may need to call the implementation of the - * parent "class" explicitly. This is the case for the (un)seriali- - * zation functions (which need to read/write all elements of the - * inheritance chain. It is not the case for the virtual ..._hash() - * and ..._cmp() implementations, which usually define equality - * and the computed hash value exclusively from the most derived - * type's values. - * - * (3) Instances of BroSObject are usually created either by - * unserializing them from a buffer (via __bro_sobject_unserialize()) - * or by specialized "constructors" in inherited classes. The - * main constructor of this sort if __bro_val_new_of_type(), which - * initializes BroVals with correct type information. - * - * Instances of BroSObject are to be deallocated via - * __bro_sobject_release(). Since BroSObjects may be referenced - * in multiple locations (the serialization cache being a main - * example), you must not explicitly release the memory associated - * with a BroSObject but let the BroSObject implementation decide - * when to do so. - */ -struct bro_serial_object -{ - /* The value by which the object is identified in the - * serialization cache. - */ - uint32 perm_id; - - /* One of the SER_xxx values above to identify the type - * of object upon (un)serialization. - */ - uint16 type_id; - - /* Reference count, used for unserialized objects that - * sit in the connection's serialization cache and may - * be referenced by multiple SObjects. - */ - int ref_count; - - /* Storage for arbitrary user data: - */ - BroHT *data; - - BroSObjectRead read; - BroSObjectWrite write; - BroSObjectFree free; - BroSObjectClone clone; - BroSObjectHash hash; - BroSObjectCmp cmp; -}; - -BroSObject *__bro_sobject_create(uint16 type_id); -void __bro_sobject_release(BroSObject *obj); -void __bro_sobject_ref(BroSObject *obj); -BroSObject *__bro_sobject_copy(BroSObject *obj); - -BroSObject *__bro_sobject_new(void); - -void __bro_sobject_init(BroSObject *obj); -void __bro_sobject_free(BroSObject *obj); - -/* We need the connection handle for the next two and not just - * a buffer because we might need the cache associated with the - * connection. - */ -int __bro_sobject_serialize(BroSObject *obj, BroConn *bc); -BroSObject *__bro_sobject_unserialize(uint16 type_id, BroConn *bc); - -/* Hash a SObject or compare them. These are the virtualized - * functions -- the actual implementation of these functions - * for SObjects themselves are static in bro_sobject.c. - */ -uint32 __bro_sobject_hash(BroSObject *obj); -int __bro_sobject_cmp(BroSObject *obj1, BroSObject *obj2); - -int __bro_sobject_read(BroSObject *obj, BroConn *bc); -int __bro_sobject_write(BroSObject *obj, BroConn *bc); -int __bro_sobject_clone(BroSObject *dst, BroSObject *src); - -/* Our base class has a facility for associating arbitrary stuff - * with each instance. Make sure to clean up the associated items - * before releasing the instance, because the object doesn't know - * how to do this. - */ -void __bro_sobject_data_set(BroSObject *obj, const char *key, void *val); -void *__bro_sobject_data_get(BroSObject *obj, const char *key); -void *__bro_sobject_data_del(BroSObject *obj, const char *key); - -#endif diff --git a/aux/broccoli/src/bro_table.c b/aux/broccoli/src/bro_table.c deleted file mode 100644 index 1197e27e1e..0000000000 --- a/aux/broccoli/src/bro_table.c +++ /dev/null @@ -1,227 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include - -#ifdef __EMX__ -#include -#endif - -#include -#include -#include -#include -#include - - -BroTable * -__bro_table_new(void) -{ - BroTable *tbl; - - if (! (tbl = calloc(1, sizeof(BroTable)))) - return NULL; - - tbl->tbl_impl = __bro_ht_new((BroHTHashFunc) __bro_table_hash_key, - (BroHTCmpFunc) __bro_table_cmp_key, - (BroHTFreeFunc) __bro_sobject_release, - (BroHTFreeFunc) __bro_sobject_release, FALSE); - - if (! tbl->tbl_impl) - { - free(tbl); - return NULL; - } - - return tbl; -} - -void -__bro_table_free(BroTable *tbl) -{ - if (! tbl) - return; - - __bro_ht_free(tbl->tbl_impl); - free(tbl); -} - -static int __bro_table_copy_cb(BroVal *key, BroVal *val, BroTable *dest) -{ - __bro_table_insert(dest, key, val); - return TRUE; /* Continue the iteration */ -} - -BroTable * -__bro_table_copy(BroTable *tbl) -{ - BroVal *val, *val_copy; - BroTable *copy; - - if (! tbl) - return NULL; - - if (! (copy = __bro_table_new())) - return NULL; - - __bro_ht_foreach(tbl->tbl_impl, - (BroHTCallback) __bro_table_copy_cb, - (void *) copy); - - return copy; -} - -void -__bro_table_insert(BroTable *tbl, BroVal *key, BroVal *val) -{ - if (! tbl || ! key) /* NULL for val is okay -- that's a set. */ - return; - - __bro_ht_add(tbl->tbl_impl, key, val); -} - -BroVal * -__bro_table_find(BroTable *tbl, const BroVal *key) -{ - if (! tbl || ! key) - return NULL; - - return __bro_ht_get(tbl->tbl_impl, key); -} - -int -__bro_table_get_size(BroTable *tbl) -{ - if (! tbl) - return -1; - - return __bro_ht_get_size(tbl->tbl_impl); -} - -void -__bro_table_foreach(BroTable *tbl, BroTableCallback cb, void *user_data) -{ - if (! tbl || ! cb) - return; - - __bro_ht_foreach(tbl->tbl_impl, cb, user_data); -} - -int -__bro_table_is_set(BroTable *tbl) -{ - return tbl->tbl_val_type == BRO_TYPE_UNKNOWN; -} - -uint32 -__bro_table_hash_key(BroVal *key) -{ - return ((BroSObject *) key)->hash((BroSObject *) key); -} - -int -__bro_table_cmp_key(BroVal *val1, BroVal *val2) -{ - BroSObject *obj1 = (BroSObject *) val1; - BroSObject *obj2 = (BroSObject *) val2; - - return obj1->cmp(obj1, obj2); -} - -static int -__bro_table_hash_cb(BroVal *key, BroVal *val, int *result) -{ - *result ^= __bro_sobject_hash((BroSObject*) key); - *result ^= __bro_sobject_hash((BroSObject*) val); - return TRUE; -} - -uint32 -__bro_table_hash(BroTable *tbl) -{ - uint32 result; - - D_ENTER; - - if (! tbl) - D_RETURN_(0); - - result = __bro_ht_get_size(tbl->tbl_impl); - - __bro_ht_foreach(tbl->tbl_impl, (BroHTCallback) __bro_table_hash_cb, &result); - - D_RETURN_(result); -} - -typedef struct bro_table_cmp -{ - BroHT *table; - int result; -} BroTableCmp; - -static int -__bro_table_cmp_cb(BroVal *key, BroVal *val, BroTableCmp *cmp) -{ - BroVal *val2 = __bro_ht_get(cmp->table, key); - - if (! val2) - goto no_luck; - - if (! __bro_sobject_cmp((BroSObject*) val, (BroSObject*) val2)) - goto no_luck; - - return TRUE; - - no_luck: - cmp->result = FALSE; - return FALSE; -} - -int -__bro_table_cmp(BroTable *tbl1, BroTable *tbl2) -{ - BroTableCmp cmp; - - D_ENTER; - - cmp.table = tbl2->tbl_impl; - cmp.result = TRUE; - - if (__bro_ht_get_size(tbl1->tbl_impl) != __bro_ht_get_size(tbl2->tbl_impl)) - D_RETURN_(FALSE); - - __bro_ht_foreach(tbl1->tbl_impl, (BroHTCallback) __bro_table_cmp_cb, &cmp); - - D_RETURN_(TRUE); -} diff --git a/aux/broccoli/src/bro_table.h b/aux/broccoli/src/bro_table.h deleted file mode 100644 index d12e629d31..0000000000 --- a/aux/broccoli/src/bro_table.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_table_h -#define broccoli_table_h - -#include -#include -#include - -/* BroTable is the table type we export to the user. It relies - * on BroHTs for the implementation. - * - * Related typedefs are in broccoli.h because the users need - * to know them -- we keep the definition opaque here. - */ -struct bro_table -{ - /* The underlying hashtable */ - BroHT *tbl_impl; - int tbl_key_type, tbl_val_type; -}; - -BroTable *__bro_table_new(void); -void __bro_table_free(BroTable *tbl); -BroTable *__bro_table_copy(BroTable *tbl); - -/* Inserts the given key-val pair and adopts ownership, - * i.e., the values are not duplicated internally. - */ -void __bro_table_insert(BroTable *tbl, BroVal *key, BroVal *val); - -BroVal *__bro_table_find(BroTable *tbl, const BroVal *key); -int __bro_table_get_size(BroTable *tbl); - -void __bro_table_foreach(BroTable *tbl, BroTableCallback cb, void *user_data); - -/* Sets are just tables that have no meaningful values associated - * with the keys. As long as a table's tbl_val_type remains unknown, - * a table is in fact a set. - */ -int __bro_table_is_set(BroTable *tbl); - -uint32 __bro_table_hash_key(BroVal *key); -int __bro_table_cmp_key(BroVal *val1, BroVal *val2); - -uint32 __bro_table_hash(BroTable *tbl); -int __bro_table_cmp(BroTable *tbl1, BroTable *tbl2); - -#endif diff --git a/aux/broccoli/src/bro_type.c b/aux/broccoli/src/bro_type.c deleted file mode 100644 index 0d87693719..0000000000 --- a/aux/broccoli/src/bro_type.c +++ /dev/null @@ -1,1303 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include - -#ifdef __EMX__ -#include -#endif - -#include -#include -#include -#include -#include -#include - -/* The virtual implementations of BroSObject's functions are - * kept static in this module, and so are the ..._init() methods - * not currently needed by other, derived classes. - */ - -static void __bro_type_init(BroType *type); -static void __bro_type_free(BroType *type); -static int __bro_type_read(BroType *type, BroConn *bc); -static int __bro_type_write(BroType *type, BroConn *bc); -static int __bro_type_clone(BroType *dst, BroType *src); -static uint32 __bro_type_hash(BroType *type); -static int __bro_type_cmp(BroType *type1, BroType *type2); - -static void __bro_type_list_init(BroTypeList *tl); -static void __bro_type_list_free(BroTypeList *tl); -static int __bro_type_list_read(BroTypeList *tl, BroConn *bc); -static int __bro_type_list_write(BroTypeList *tl, BroConn *bc); -static int __bro_type_list_clone(BroTypeList *dst, BroTypeList *src); -static uint32 __bro_type_list_hash(BroTypeList *tl); -static int __bro_type_list_cmp(BroTypeList *tl1, BroTypeList *tl2); - -static void __bro_record_type_init(BroRecordType *rt); -static void __bro_record_type_free(BroRecordType *rt); -static int __bro_record_type_read(BroRecordType *rt, BroConn *bc); -static int __bro_record_type_write(BroRecordType *rt, BroConn *bc); -static int __bro_record_type_clone(BroRecordType *dst, BroRecordType *src); -static uint32 __bro_record_type_hash(BroRecordType *rt); -static int __bro_record_type_cmp(BroRecordType *rt1, BroRecordType *rt2); - -static void __bro_index_type_init(BroIndexType *it); -static void __bro_index_type_free(BroIndexType *it); -static int __bro_index_type_read(BroIndexType *it, BroConn *bc); -static int __bro_index_type_write(BroIndexType *it, BroConn *bc); -static int __bro_index_type_clone(BroIndexType *dst, BroIndexType *src); -static uint32 __bro_index_type_hash(BroIndexType *it); -static int __bro_index_type_cmp(BroIndexType *it1, BroIndexType *it2); - -static void __bro_table_type_init(BroTableType *tt); -static void __bro_table_type_free(BroTableType *tt); -static int __bro_table_type_read(BroTableType *tt, BroConn *bc); -static int __bro_table_type_write(BroTableType *tt, BroConn *bc); -static int __bro_table_type_clone(BroTableType *dst, BroTableType *src); -static uint32 __bro_table_type_hash(BroTableType *tt); -static int __bro_table_type_cmp(BroTableType *tt1, BroTableType *tt2); - -static void __bro_set_type_init(BroSetType *st); -static void __bro_set_type_free(BroSetType *st); -static int __bro_set_type_read(BroSetType *st, BroConn *bc); -static int __bro_set_type_write(BroSetType *st, BroConn *bc); -static int __bro_set_type_clone(BroSetType *dst, BroSetType *src); -static uint32 __bro_set_type_hash(BroSetType *st); -static int __bro_set_type_cmp(BroSetType *st1, BroSetType *st2); - - -BroType * -__bro_type_new(void) -{ - BroType *type; - - D_ENTER; - - if (! (type = calloc(1, sizeof(BroType)))) - D_RETURN_(NULL); - - __bro_type_init(type); - - D_RETURN_(type); -} - - -BroType * -__bro_type_new_of_type(int type_tag, const char *type_name) -{ - BroType *type = NULL; - int internal_tag; - char is_nbo = 0; - - D_ENTER; - - switch (type_tag) - { - case BRO_TYPE_BOOL: - case BRO_TYPE_INT: - case BRO_TYPE_ENUM: - internal_tag = BRO_INTTYPE_INT; - break; - - case BRO_TYPE_COUNT: - case BRO_TYPE_COUNTER: - internal_tag = BRO_INTTYPE_UNSIGNED; - break; - - case BRO_TYPE_PORT: - internal_tag = BRO_INTTYPE_UNSIGNED; - is_nbo = 1; - break; - - case BRO_TYPE_DOUBLE: - case BRO_TYPE_TIME: - case BRO_TYPE_INTERVAL: - internal_tag = BRO_INTTYPE_DOUBLE; - break; - - case BRO_TYPE_STRING: - internal_tag = BRO_INTTYPE_STRING; - break; - - case BRO_TYPE_IPADDR: - case BRO_TYPE_NET: - internal_tag = BRO_INTTYPE_IPADDR; - break; - - case BRO_TYPE_SUBNET: - internal_tag = BRO_INTTYPE_SUBNET; - break; - - case BRO_TYPE_PATTERN: - case BRO_TYPE_TIMER: - case BRO_TYPE_ANY: - case BRO_TYPE_UNION: - case BRO_TYPE_LIST: - case BRO_TYPE_FUNC: - case BRO_TYPE_FILE: - case BRO_TYPE_VECTOR: - internal_tag = BRO_INTTYPE_OTHER; - break; - - case BRO_TYPE_TABLE: - if (! (type = (BroType *) __bro_table_type_new())) - D_RETURN_(NULL); - - internal_tag = BRO_INTTYPE_OTHER; - break; - - case BRO_TYPE_RECORD: - if (! (type = (BroType *) __bro_record_type_new())) - D_RETURN_(NULL); - - internal_tag = BRO_INTTYPE_OTHER; - break; - - case BRO_TYPE_SET: - if (! (type = (BroType *) __bro_set_type_new())) - D_RETURN_(NULL); - - internal_tag = BRO_INTTYPE_OTHER; - break; - - case BRO_TYPE_ERROR: - default: - internal_tag = BRO_INTTYPE_ERROR; - } - - if (! type) - { - if (! (type = __bro_type_new())) - D_RETURN_(NULL); - } - - type->tag = type_tag; - type->internal_tag = internal_tag; - type->is_nbo = is_nbo; - type->is_complete = TRUE; - - if (type_name) - { - type->is_complete = FALSE; - bro_string_set(&type->type_name, type_name); - } - - D_RETURN_(type); -} - - -static void -__bro_type_init(BroType *type) -{ - BroSObject *sobj = (BroSObject *) type; - - D_ENTER; - - __bro_object_init((BroObject *) type); - - sobj->read = (BroSObjectRead) __bro_type_read; - sobj->write = (BroSObjectWrite) __bro_type_write; - sobj->free = (BroSObjectFree) __bro_type_free; - sobj->clone = (BroSObjectClone) __bro_type_clone; - sobj->hash = (BroSObjectHash) __bro_type_hash; - sobj->cmp = (BroSObjectCmp) __bro_type_cmp; - - sobj->type_id = SER_TYPE; - - bro_string_init(&type->type_name); - type->is_complete = TRUE; - - D_RETURN; -} - - -static void -__bro_type_free(BroType *type) -{ - D_ENTER; - bro_string_cleanup(&type->type_name); - __bro_sobject_release((BroSObject *) type->attrs_type); - __bro_object_free((BroObject *) type); - D_RETURN; -} - - -static int -__bro_type_read(BroType *type, BroConn *bc) -{ - char opt; - - D_ENTER; - - if (! __bro_object_read((BroObject *) type, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_read_char(bc->rx_buf, &type->tag)) - D_RETURN_(FALSE); - if (! __bro_buf_read_char(bc->rx_buf, &type->internal_tag)) - D_RETURN_(FALSE); - - if (! __bro_buf_read_char(bc->rx_buf, &type->is_nbo)) - D_RETURN_(FALSE); - if (! __bro_buf_read_char(bc->rx_buf, &type->is_base_type)) - D_RETURN_(FALSE); - if (! __bro_buf_read_char(bc->rx_buf, &type->is_global_attrs_type)) - D_RETURN_(FALSE); - - if (! __bro_buf_read_char(bc->rx_buf, &opt)) - D_RETURN_(FALSE); - if (opt) - { - if (type->attrs_type) - __bro_sobject_release((BroSObject *) type->attrs_type); - - if (! (type->attrs_type = (BroRecordType *) - __bro_sobject_unserialize(SER_RECORD_TYPE, bc))) - D_RETURN_(FALSE); - } - - D_RETURN_(TRUE); -} - - -static int -__bro_type_write(BroType *type, BroConn *bc) -{ - D_ENTER; - - if (! __bro_object_write((BroObject *) type, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_char(bc->tx_buf, type->tag)) - D_RETURN_(FALSE); - if (! __bro_buf_write_char(bc->tx_buf, type->internal_tag)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_char(bc->tx_buf, type->is_nbo)) - D_RETURN_(FALSE); - if (! __bro_buf_write_char(bc->tx_buf, type->is_base_type)) - D_RETURN_(FALSE); - if (! __bro_buf_write_char(bc->tx_buf, type->is_global_attrs_type)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_char(bc->tx_buf, type->attrs_type ? 1 : 0)) - D_RETURN_(FALSE); - - if (type->attrs_type && ! __bro_sobject_serialize((BroSObject *) type->attrs_type, bc)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -static int -__bro_type_clone(BroType *dst, BroType *src) -{ - D_ENTER; - - if (! __bro_object_clone((BroObject *) dst, (BroObject *) src)) - D_RETURN_(FALSE); - - dst->tag = src->tag; - dst->internal_tag = src->internal_tag; - dst->is_nbo = src->is_nbo; - dst->is_base_type = src->is_base_type; - dst->is_global_attrs_type = src->is_global_attrs_type; - dst->is_complete = src->is_complete; - bro_string_set(&dst->type_name, (const char *) bro_string_get_data(&src->type_name)); - - if (src->attrs_type && - ! (dst->attrs_type = (BroRecordType *) __bro_sobject_copy((BroSObject *) src->attrs_type))) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -static uint32 -__bro_type_hash(BroType *type) -{ - uint32 result; - - D_ENTER; - - if (! type) - D_RETURN_(0); - - result = __bro_ht_str_hash(type->type_name.str_val); - result ^= (uint32) type->tag; - result ^= ((uint32) type->internal_tag) << 8; - result ^= ((uint32) type->is_nbo) << 8; - result ^= ((uint32) type->is_base_type) << 8; - result ^= (uint32) type->is_global_attrs_type; - result ^= ((uint32) type->is_complete) << 8; - - D_RETURN_(result); - -} - - -static int -__bro_type_cmp(BroType *type1, BroType *type2) -{ - int result; - - D_ENTER; - - if (! type1 || ! type2) - D_RETURN_(FALSE); - - if (type1->type_name.str_val && type2->type_name.str_val && - ! __bro_ht_str_cmp(type1->type_name.str_val, type2->type_name.str_val)) - D_RETURN_(FALSE); - - if (type1->tag != type2->tag || - type1->internal_tag != type2->internal_tag || - type1->is_nbo != type2->is_nbo || - type1->is_base_type != type2->is_base_type || - type1->is_global_attrs_type != type2->is_global_attrs_type || - type1->is_complete != type2->is_complete) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); - -} - -BroTypeList * -__bro_type_list_new(void) -{ - BroTypeList *tl; - - D_ENTER; - - if (! (tl = calloc(1, sizeof(BroTypeList)))) - D_RETURN_(NULL); - - __bro_type_list_init(tl); - - D_RETURN_(tl); -} - - -static void -__bro_type_list_init(BroTypeList *tl) -{ - BroSObject *sobj = (BroSObject *) tl; - - D_ENTER; - - __bro_type_init((BroType *) tl); - - sobj->read = (BroSObjectRead) __bro_type_list_read; - sobj->write = (BroSObjectWrite) __bro_type_list_write; - sobj->free = (BroSObjectFree) __bro_type_list_free; - sobj->clone = (BroSObjectClone) __bro_type_list_clone; - sobj->hash = (BroSObjectHash) __bro_type_list_hash; - sobj->cmp = (BroSObjectCmp) __bro_type_list_cmp; - - sobj->type_id = SER_TYPE_LIST; - - tl->types = NULL; - - D_RETURN; -} - - -static void -__bro_type_list_free(BroTypeList *tl) -{ - D_ENTER; - - __bro_list_free(tl->types, (BroFunc) __bro_sobject_release); - __bro_sobject_release((BroSObject *) tl->pure_type); - __bro_type_free((BroType *) tl); - - D_RETURN; -} - - -static int -__bro_type_list_read(BroTypeList *tl, BroConn *bc) -{ - char opt; - uint32 i; - - D_ENTER; - - if (! __bro_type_read((BroType *) tl, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_read_char(bc->rx_buf, &opt)) - D_RETURN_(FALSE); - - /* Clean out old optional pure type */ - if (tl->pure_type) - __bro_sobject_release((BroSObject *) tl->pure_type); - - if (opt) - { - if (! (tl->pure_type = (BroType *) __bro_sobject_unserialize(SER_IS_TYPE, bc))) - D_RETURN_(FALSE); - } - - if (! __bro_buf_read_int(bc->rx_buf, &tl->num_types)) - D_RETURN_(FALSE); - - if (tl->num_types > 0) - { - for (i = 0; i < tl->num_types; i++) - { - BroType *type; - - if (! (type = (BroType *) __bro_sobject_unserialize(SER_IS_TYPE, bc))) - D_RETURN_(FALSE); - - tl->types = __bro_list_append(tl->types, type); - } - } - - D_RETURN_(TRUE); -} - - -static int -__bro_type_list_write(BroTypeList *tl, BroConn *bc) -{ - BroList *l; - - D_ENTER; - - if (! __bro_type_write((BroType *) tl, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_char(bc->tx_buf, tl->pure_type ? 1 : 0)) - D_RETURN_(FALSE); - - if (tl->pure_type && ! __bro_sobject_serialize((BroSObject *) tl->pure_type, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_int(bc->tx_buf, tl->num_types)) - D_RETURN_(FALSE); - - for (l = tl->types; l; l = __bro_list_next(l)) - { - if (! __bro_sobject_serialize((BroSObject *) __bro_list_data(l), bc)) - D_RETURN_(FALSE); - } - - D_RETURN_(TRUE); -} - - -static int -__bro_type_list_clone(BroTypeList *dst, BroTypeList *src) -{ - BroList *l; - BroType *type; - - D_ENTER; - - if (! __bro_type_clone((BroType *) dst, (BroType *) src)) - D_RETURN_(FALSE); - - dst->num_types = src->num_types; - - if (dst->types) - __bro_list_free(dst->types, (BroFunc) __bro_sobject_release); - - dst->types = NULL; - - for (l = src->types; l; l = __bro_list_next(l)) - { - BroType *type_copy; - - type = __bro_list_data(l); - - if (! (type_copy = (BroType *) __bro_sobject_copy((BroSObject *) type))) - D_RETURN_(FALSE); - - dst->types = __bro_list_append(dst->types, type_copy); - } - - if (src->pure_type && ! (dst->pure_type = (BroType *) __bro_sobject_copy((BroSObject *) src->pure_type))) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -static uint32 -__bro_type_list_hash(BroTypeList *tl) -{ - uint32 result; - BroList *l; - - D_ENTER; - - if (! tl) - D_RETURN_(0); - - result = tl->num_types; - result ^= __bro_sobject_hash((BroSObject*) tl->pure_type); - - for (l = tl->types; l; l = __bro_list_next(l)) - result ^= __bro_sobject_hash((BroSObject*) __bro_list_data(l)); - - D_RETURN_(result); -} - - -static int -__bro_type_list_cmp(BroTypeList *tl1, BroTypeList *tl2) -{ - BroList *l1, *l2; - - D_ENTER; - - if (! tl1 || ! tl2) - D_RETURN_(FALSE); - - if (tl1->num_types != tl2->num_types || - ! __bro_sobject_cmp((BroSObject*) tl1->pure_type, - (BroSObject*) tl2->pure_type)) - D_RETURN_(FALSE); - - for (l1 = tl1->types, l2 = tl2->types; l1 && l2; - l1 = __bro_list_next(l1), l2 = __bro_list_next(l2)) - { - if (! __bro_sobject_cmp((BroSObject*) __bro_list_data(l1), - (BroSObject*) __bro_list_data(l2))) - D_RETURN_(FALSE); - } - - if (l1 || l2) D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -BroRecordType * -__bro_record_type_new(void) -{ - BroRecordType *rt; - - D_ENTER; - - if (! (rt = calloc(1, sizeof(BroRecordType)))) - D_RETURN_(NULL); - - __bro_record_type_init(rt); - - D_RETURN_(rt); -} - - -static void -__bro_record_type_init(BroRecordType *rt) -{ - BroSObject *sobj = (BroSObject *) rt; - - D_ENTER; - - __bro_type_init((BroType *) rt); - - sobj->read = (BroSObjectRead) __bro_record_type_read; - sobj->write = (BroSObjectWrite) __bro_record_type_write; - sobj->free = (BroSObjectFree) __bro_record_type_free; - sobj->clone = (BroSObjectClone) __bro_record_type_clone; - sobj->hash = (BroSObjectHash) __bro_record_type_hash; - sobj->cmp = (BroSObjectCmp) __bro_record_type_cmp; - - sobj->type_id = SER_RECORD_TYPE; - - D_RETURN; -} - - -static void -__bro_record_type_free(BroRecordType *rt) -{ - D_ENTER; - - __bro_sobject_release((BroSObject *) rt->base); - __bro_list_free(rt->type_decls, (BroFunc) __bro_type_decl_free); - __bro_type_free((BroType *) rt); - - D_RETURN; -} - - -void -__bro_record_type_add_type(BroRecordType *rt, const char *field, BroType *type) -{ - BroTypeDecl *td; - - D_ENTER; - - if (! rt || ! type) - D_RETURN; - - if (! (td = __bro_type_decl_new())) - D_RETURN; - - if (! (td->type = (BroType *) __bro_sobject_copy((BroSObject *) type))) - { - D(("Cloning of type failed.\n")); - __bro_type_decl_free(td); - D_RETURN; - } - - if (! bro_string_set(&td->id, field)) - { - __bro_type_decl_free(td); - D_RETURN; - } - - rt->type_decls = __bro_list_append(rt->type_decls, td); - rt->num_fields++; - rt->num_types++; - D_RETURN; -} - - -const char * -__bro_record_type_get_nth_field(BroRecordType *rt, int num) -{ - BroList *l; - - if (! rt || num < 0 || (uint) num >= rt->num_fields) - return NULL; - - if( (l = __bro_list_nth(rt->type_decls, num))) - { - BroTypeDecl *td = __bro_list_data(l); - return (const char *) td->id.str_val; - } - - return NULL; -} - - -static int -__bro_record_type_read(BroRecordType *rt, BroConn *bc) -{ - uint32 i; - char opt; - - D_ENTER; - - if (! __bro_type_read((BroType *) rt, bc)) - D_RETURN_(FALSE); - - /* Read type declarations */ - - rt->type_decls = NULL; - rt->num_fields = 0; - rt->num_types = 0; - - if (! __bro_buf_read_int(bc->rx_buf, &rt->num_fields)) - D_RETURN_(FALSE); - - if (! __bro_buf_read_char(bc->rx_buf, &opt)) - D_RETURN_(FALSE); - if (opt) - { - if (! __bro_buf_read_int(bc->rx_buf, &rt->num_types)) - D_RETURN_(FALSE); - - if (rt->num_types > 0) - { - for (i = 0; i < rt->num_types; i++) - { - BroTypeDecl *td; - - if (! (td = __bro_type_decl_new())) - D_RETURN_(FALSE); - - if (! __bro_type_decl_read(td, bc)) - D_RETURN_(FALSE); - - rt->type_decls = __bro_list_append(rt->type_decls, td); - } - } - } - - /* Read optional base */ - - __bro_sobject_release((BroSObject *) rt->base); - rt->base = NULL; - - if (! __bro_buf_read_char(bc->rx_buf, &opt)) - D_RETURN_(FALSE); - if (opt) - { - if (! (rt->base = (BroTypeList *) __bro_sobject_unserialize(SER_TYPE_LIST, bc))) - D_RETURN_(FALSE); - } - - D_RETURN_(TRUE); -} - - -static int -__bro_record_type_write(BroRecordType *rt, BroConn *bc) -{ - BroList *l; - - D_ENTER; - - if (! __bro_type_write((BroType *) rt, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_int(bc->tx_buf, rt->num_fields)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_char(bc->tx_buf, rt->type_decls ? 1 : 0)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_int(bc->tx_buf, rt->num_types)) - D_RETURN_(FALSE); - - for (l = rt->type_decls; l; l = __bro_list_next(l)) - { - BroTypeDecl *td = __bro_list_data(l); - - if (! __bro_type_decl_write(td, bc)) - D_RETURN_(FALSE); - } - - if (! __bro_buf_write_char(bc->tx_buf, rt->base ? 1 : 0)) - D_RETURN_(FALSE); - - if (rt->base && ! __bro_sobject_serialize((BroSObject *) rt->base, bc)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -static int -__bro_record_type_clone(BroRecordType *dst, BroRecordType *src) -{ - BroList *l; - - D_ENTER; - - if (! __bro_type_clone((BroType *) dst, (BroType *) src)) - D_RETURN_(FALSE); - - if (src->base && ! (dst->base = (BroTypeList *) __bro_sobject_copy((BroSObject *) src->base))) - D_RETURN_(FALSE); - - dst->num_fields = src->num_fields; - dst->num_types = src->num_types; - - for (l = src->type_decls; l; l = __bro_list_next(l)) - { - BroTypeDecl *td = __bro_list_data(l); - BroTypeDecl *td_copy = __bro_type_decl_copy(td); - - if (! td_copy) - D_RETURN_(FALSE); - - dst->type_decls = __bro_list_append(dst->type_decls, td_copy); - } - - D_RETURN_(TRUE); -} - - -static uint32 -__bro_record_type_hash(BroRecordType *rt) -{ - uint32 result; - BroList *l; - - D_ENTER; - - if (! rt) - D_RETURN_(0); - - result = __bro_type_list_hash(rt->base); - result ^= rt->num_fields; - result ^= rt->num_types << 16; - - for (l = rt->type_decls; l; l = __bro_list_next(l)) - result ^= __bro_type_decl_hash((BroTypeDecl*) __bro_list_data(l)); - - D_RETURN_(result); -} - - -static int -__bro_record_type_cmp(BroRecordType *rt1, BroRecordType *rt2) -{ - BroList *l1, *l2; - - D_ENTER; - - if (! rt1 || ! rt2) - D_RETURN_(FALSE); - - if (rt1->num_fields != rt2->num_fields || - rt1->num_types != rt2->num_types || - ! __bro_type_list_cmp(rt1->base, rt2->base)) - D_RETURN_(FALSE); - - for (l1 = rt1->type_decls, l2 = rt2->type_decls; l1 && l2; - l1 = __bro_list_next(l1), l2 = __bro_list_next(l2)) - { - if (! __bro_type_decl_cmp((BroTypeDecl*) __bro_list_data(l1), - (BroTypeDecl*) __bro_list_data(l2))) - D_RETURN_(FALSE); - } - - if (l1 || l2) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -BroIndexType * -__bro_index_type_new(void) -{ - BroIndexType *it; - - D_ENTER; - - if (! (it = calloc(1, sizeof(BroIndexType)))) - D_RETURN_(NULL); - - __bro_index_type_init(it); - - D_RETURN_(it); -} - -static void -__bro_index_type_init(BroIndexType *it) -{ - BroSObject *sobj = (BroSObject *) it; - - D_ENTER; - - __bro_type_init((BroType *) it); - - sobj->read = (BroSObjectRead) __bro_index_type_read; - sobj->write = (BroSObjectWrite) __bro_index_type_write; - sobj->free = (BroSObjectFree) __bro_index_type_free; - sobj->clone = (BroSObjectClone) __bro_index_type_clone; - sobj->hash = (BroSObjectHash) __bro_index_type_hash; - sobj->cmp = (BroSObjectCmp) __bro_index_type_cmp; - - sobj->type_id = SER_INDEX_TYPE; - - D_RETURN; -} - -static void -__bro_index_type_free(BroIndexType *it) -{ - D_ENTER; - - __bro_sobject_release((BroSObject *) it->indices); - __bro_sobject_release((BroSObject *) it->yield_type); - __bro_type_free((BroType *) it); - - D_RETURN; -} - -void -__bro_index_type_set_indices(BroIndexType *it, BroTypeList *indices) -{ - BroTypeList *tl; - - D_ENTER; - - if (! it || ! indices) - D_RETURN; - - if (! (tl = __bro_type_list_new())) - D_RETURN; - - if (! __bro_type_list_clone(tl, indices)) - { - __bro_type_list_free(tl); - D_RETURN; - } - - it->indices = tl; - - D_RETURN; -} - -void -__bro_index_type_set_yield_type(BroIndexType *it, BroType *yield_type) -{ - D_ENTER; - - if (! it || ! yield_type) - D_RETURN; - - if (! (it->yield_type = (BroType *) __bro_sobject_copy((BroSObject *) yield_type))) - D_RETURN; - - D_RETURN; -} - -static int -__bro_index_type_read(BroIndexType *it, BroConn *bc) -{ - char opt; - - D_ENTER; - - if (! __bro_type_read((BroType *) it, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_read_char(bc->rx_buf, &opt)) - D_RETURN_(FALSE); - if (opt) - { - if (! (it->yield_type = (BroType *) __bro_sobject_unserialize(SER_TYPE, bc))) - D_RETURN_(FALSE); - } - - if (! (it->indices = (BroTypeList *) __bro_sobject_unserialize(SER_TYPE_LIST, bc))) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - -static int -__bro_index_type_write(BroIndexType *it, BroConn *bc) -{ - D_ENTER; - - if (! __bro_type_write((BroType *) it, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_char(bc->tx_buf, it->yield_type ? 1 : 0)) - D_RETURN_(FALSE); - - if (it->yield_type && ! __bro_sobject_serialize((BroSObject *) it->yield_type, bc)) - D_RETURN_(FALSE); - - if (! __bro_sobject_serialize((BroSObject *) it->indices, bc)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - -static int -__bro_index_type_clone(BroIndexType *dst, BroIndexType *src) -{ - D_ENTER; - - if (! __bro_type_clone((BroType *) dst, (BroType *) src)) - D_RETURN_(FALSE); - - if (src->yield_type && ! (dst->yield_type = (BroType *) __bro_sobject_copy((BroSObject *) src->yield_type))) - D_RETURN_(FALSE); - - if (! (dst->indices = (BroTypeList *) __bro_sobject_copy((BroSObject *) src->indices))) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - -static uint32 -__bro_index_type_hash(BroIndexType *it) -{ - uint32 result; - - D_ENTER; - - if (! it) - D_RETURN_(0); - - result = __bro_type_list_hash(it->indices); - result ^= __bro_sobject_hash((BroSObject*) it->yield_type); - - D_RETURN_(result); -} - -static int -__bro_index_type_cmp(BroIndexType *it1, BroIndexType *it2) -{ - D_ENTER; - - if (! it1 || ! it2) - D_RETURN_(FALSE); - - if (! __bro_type_list_cmp(it1->indices, it2->indices) || - ! __bro_sobject_cmp((BroSObject*) it1->yield_type, - (BroSObject*) it2->yield_type)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -BroTableType * -__bro_table_type_new(void) -{ - BroTableType *tt; - - D_ENTER; - - if (! (tt = calloc(1, sizeof(BroTableType)))) - D_RETURN_(NULL); - - __bro_table_type_init(tt); - - D_RETURN_(tt); -} - -static void -__bro_table_type_init(BroTableType *tt) -{ - BroSObject *sobj = (BroSObject *) tt; - - D_ENTER; - - __bro_index_type_init((BroIndexType *) tt); - - sobj->read = (BroSObjectRead) __bro_table_type_read; - sobj->write = (BroSObjectWrite) __bro_table_type_write; - sobj->free = (BroSObjectFree) __bro_table_type_free; - sobj->clone = (BroSObjectClone) __bro_table_type_clone; - sobj->hash = (BroSObjectHash) __bro_table_type_hash; - sobj->cmp = (BroSObjectCmp) __bro_table_type_cmp; - - sobj->type_id = SER_TABLE_TYPE; - - D_RETURN; -} - -static void -__bro_table_type_free(BroTableType *tt) -{ - D_ENTER; - __bro_index_type_free((BroIndexType *) tt); - D_RETURN; -} - -static int -__bro_table_type_read(BroTableType *tt, BroConn *bc) -{ - D_ENTER; - - if (! __bro_index_type_read((BroIndexType *) tt, bc)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - -static int -__bro_table_type_write(BroTableType *tt, BroConn *bc) -{ - D_ENTER; - - if (! __bro_index_type_write((BroIndexType *) tt, bc)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - -static int -__bro_table_type_clone(BroTableType *dst, BroTableType *src) -{ - D_ENTER; - - if (! __bro_index_type_clone((BroIndexType *) dst, (BroIndexType *) src)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - -static uint32 -__bro_table_type_hash(BroTableType *tt) -{ - uint32 result; - - D_ENTER; - result = __bro_index_type_hash((BroIndexType*) tt); - D_RETURN_(result); -} - -static int -__bro_table_type_cmp(BroTableType *tt1, BroTableType *tt2) -{ - D_ENTER; - - if (! tt1 || ! tt2) - D_RETURN_(FALSE); - - D_RETURN_(__bro_index_type_cmp((BroIndexType*) tt1, - (BroIndexType*) tt2)); -} - - -BroSetType * -__bro_set_type_new(void) -{ - BroSetType *st; - - D_ENTER; - - if (! (st = calloc(1, sizeof(BroSetType)))) - D_RETURN_(NULL); - - __bro_set_type_init(st); - - D_RETURN_(st); -} - -static void -__bro_set_type_init(BroSetType *st) -{ - BroSObject *sobj = (BroSObject *) st; - - D_ENTER; - - __bro_table_type_init((BroTableType *) st); - - sobj->read = (BroSObjectRead) __bro_set_type_read; - sobj->write = (BroSObjectWrite) __bro_set_type_write; - sobj->free = (BroSObjectFree) __bro_set_type_free; - sobj->clone = (BroSObjectClone) __bro_set_type_clone; - sobj->hash = (BroSObjectHash) __bro_set_type_hash; - sobj->cmp = (BroSObjectCmp) __bro_set_type_cmp; - - sobj->type_id = SER_SET_TYPE; - - D_RETURN; -} - -static void -__bro_set_type_free(BroSetType *st) -{ - D_ENTER; - __bro_table_type_free((BroTableType *) st); - D_RETURN; -} - -static int -__bro_set_type_read(BroSetType *st, BroConn *bc) -{ - char opt; - - D_ENTER; - - if (! __bro_table_type_read((BroTableType *) st, bc)) - D_RETURN_(FALSE); - - /* To allow unambiguous differentiation between tables and sets, - * we set the type tag to set here, in divergence of Bro's - * internal procedure. - */ - ((BroType*) st)->tag = BRO_TYPE_SET; - - if (! __bro_buf_read_char(bc->rx_buf, &opt)) - D_RETURN_(FALSE); - if (opt) - { - D(("Error: expressions are not yet supported. Sorry.\n")); - D_RETURN_(FALSE); - } - - D_RETURN_(TRUE); -} - -static int -__bro_set_type_write(BroSetType *st, BroConn *bc) -{ - int ret; - - D_ENTER; - - /* Compatibility hack for Bro: its type tags don't differentiate - * between sets and tables (they always indicate table types), so - * we must ensure here that we do appear as a table type. - */ - ((BroType*) st)->tag = BRO_TYPE_TABLE; - ret = __bro_table_type_write((BroTableType *) st, bc); - ((BroType*) st)->tag = BRO_TYPE_SET; - - if (! ret) - D_RETURN_(FALSE); - - /* We never send expressions. */ - if (! __bro_buf_write_char(bc->tx_buf, FALSE)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - -static int -__bro_set_type_clone(BroSetType *dst, BroSetType *src) -{ - D_ENTER; - - if (! __bro_table_type_clone((BroTableType *) dst, (BroTableType *) src)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - -static uint32 -__bro_set_type_hash(BroSetType *st) -{ - uint32 result; - - D_ENTER; - result = __bro_table_type_hash((BroTableType*) st); - D_RETURN_(result); -} - -static int -__bro_set_type_cmp(BroSetType *st1, BroSetType *st2) -{ - int result; - - D_ENTER; - - if (! st1 || ! st2) - D_RETURN_(FALSE); - - result = __bro_table_type_cmp((BroTableType*) st1, - (BroTableType*) st2);; - D_RETURN_(result); -} diff --git a/aux/broccoli/src/bro_type.h b/aux/broccoli/src/bro_type.h deleted file mode 100644 index c8c92c4b6f..0000000000 --- a/aux/broccoli/src/bro_type.h +++ /dev/null @@ -1,124 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_type_h -#define broccoli_type_h - -#include -#include - -/* Internal types used to represent a Bro type. - * Taken from Type.h. - */ -#define BRO_INTTYPE_INT 1 -#define BRO_INTTYPE_UNSIGNED 2 -#define BRO_INTTYPE_DOUBLE 3 -#define BRO_INTTYPE_STRING 4 -#define BRO_INTTYPE_IPADDR 5 -#define BRO_INTTYPE_SUBNET 6 -#define BRO_INTTYPE_OTHER 7 -#define BRO_INTTYPE_ERROR 8 - -/* typedefs are in bro_types.h */ - -struct bro_type -{ - BroObject object; - - char tag; - char internal_tag; - - char is_nbo; - char is_base_type; - char is_global_attrs_type; - - /* Whether or not this is a complete type object or - * just the name of type. In the latter case, type_name - * (below) will contain the name of the type. - */ - char is_complete; - - BroString type_name; - - BroRecordType *attrs_type; -}; - -struct bro_type_list -{ - BroType type; - - uint32 num_types; - BroList *types; - BroType *pure_type; -}; - -struct bro_record_type -{ - BroType type; - - BroTypeList *base; - uint32 num_fields; - - uint32 num_types; - BroList *type_decls; -}; - -struct bro_index_type -{ - BroType type; - - BroTypeList *indices; - BroType *yield_type; /* optional */ -}; - -struct bro_table_type -{ - BroIndexType type; -}; - -struct bro_set_type -{ - BroTableType type; -}; - -BroType *__bro_type_new(void); -BroType *__bro_type_new_of_type(int type, const char *type_name); -void __bro_type_set_incomplete_impl(BroType *type, const BroString *type_name); - -BroTypeList *__bro_type_list_new(void); - -BroRecordType *__bro_record_type_new(void); -void __bro_record_type_add_type(BroRecordType *rt, const char *field, BroType *type); -const char *__bro_record_type_get_nth_field(BroRecordType *rt, int num); - -BroIndexType *__bro_index_type_new(void); -void __bro_index_type_set_indices(BroIndexType *it, BroTypeList *indices); -void __bro_index_tye_set_yield_type(BroIndexType *it, BroType *yield_type); - -BroTableType *__bro_table_type_new(void); - -BroSetType *__bro_set_type_new(); - -#endif diff --git a/aux/broccoli/src/bro_type_decl.c b/aux/broccoli/src/bro_type_decl.c deleted file mode 100644 index 2c061ef875..0000000000 --- a/aux/broccoli/src/bro_type_decl.c +++ /dev/null @@ -1,196 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include - -BroTypeDecl * -__bro_type_decl_new(void) -{ - BroTypeDecl *td; - - D_ENTER; - - if (! (td = calloc(1, sizeof(BroTypeDecl)))) - D_RETURN_(NULL); - - D_RETURN_(td); -} - - -BroTypeDecl * -__bro_type_decl_copy(BroTypeDecl *td) -{ - BroTypeDecl *copy; - - D_ENTER; - - if (! td) - D_RETURN_(NULL); - - if (! (copy = __bro_type_decl_new())) - D_RETURN_(NULL); - - if (td->attrs && ! (copy->attrs = (BroAttrs *) __bro_sobject_copy((BroSObject *) td->attrs))) - goto error_result; - - if (td->type && ! (copy->type = (BroType *) __bro_sobject_copy((BroSObject *) td->type))) - goto error_result; - - if (! (bro_string_set_data(©->id, - bro_string_get_data(&td->id), - bro_string_get_length(&td->id)))) - goto error_result; - - D_RETURN_(copy); - - error_result: - __bro_type_decl_free(copy); - D_RETURN_(NULL); -} - - -void -__bro_type_decl_free(BroTypeDecl *td) -{ - D_ENTER; - - if (! td) - D_RETURN; - - __bro_sobject_release((BroSObject *) td->type); - __bro_sobject_release((BroSObject *) td->attrs); - bro_string_cleanup(&td->id); - free(td); - - D_RETURN; -} - - -int -__bro_type_decl_read(BroTypeDecl *td, BroConn *bc) -{ - char opt; - - D_ENTER; - - if (! td || !bc) - D_RETURN_(FALSE); - - /* Read an optional BroAttrs */ - - if (td->attrs) - __bro_sobject_release((BroSObject *) td->attrs); - td->attrs = NULL; - - if (! __bro_buf_read_char(bc->rx_buf, &opt)) - D_RETURN_(FALSE); - if (opt) - { - if (! (td->attrs = (BroAttrs *) __bro_sobject_unserialize(SER_ATTRIBUTES, bc))) - D_RETURN_(FALSE); - } - - /* Read a type */ - - if (td->type) - __bro_sobject_release((BroSObject *) td->type); - td->type = NULL; - - if (! (td->type = (BroType *) __bro_sobject_unserialize(SER_IS_TYPE, bc))) - D_RETURN_(FALSE); - - /* Read ID name string */ - - bro_string_cleanup(&td->id); - if (! __bro_buf_read_string(bc->rx_buf, &td->id)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -int -__bro_type_decl_write(BroTypeDecl *td, BroConn *bc) -{ - D_ENTER; - - if (! td || !bc) - D_RETURN_(FALSE); - - if (! __bro_buf_write_char(bc->tx_buf, td->attrs ? 1 : 0)) - D_RETURN_(FALSE); - - if (td->attrs && ! __bro_sobject_serialize((BroSObject *) td->attrs, bc)) - D_RETURN_(FALSE); - - if (! __bro_sobject_serialize((BroSObject *) td->type, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_string(bc->tx_buf, &td->id)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -uint32 -__bro_type_decl_hash(BroTypeDecl *td) -{ - uint32 result; - - D_ENTER; - - if (! td) - D_RETURN_(0); - - result = __bro_ht_str_hash(td->id.str_val); - result ^= __bro_sobject_hash((BroSObject*) td->attrs); - result ^= __bro_sobject_hash((BroSObject*) td->type); - - D_RETURN_(result); -} - - -int -__bro_type_decl_cmp(BroTypeDecl *td1, BroTypeDecl *td2) -{ - D_ENTER; - - if (! td1 || ! td2) - D_RETURN_(FALSE); - - if (! __bro_sobject_cmp((BroSObject*) td1->attrs, (BroSObject*) td2->attrs) || - ! __bro_sobject_cmp((BroSObject*) td1->type, (BroSObject*) td2->type)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - diff --git a/aux/broccoli/src/bro_type_decl.h b/aux/broccoli/src/bro_type_decl.h deleted file mode 100644 index 8c579e5ed4..0000000000 --- a/aux/broccoli/src/bro_type_decl.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_type_decl_h -#define broccoli_type_decl_h - -#include -#include - -/* BroTypeDecls live outside the inheritance chain and are currently - * only of interest for bro_type.c. The function names only resemble - * the virtualized ones for easier integration with the virtualized - * code. - */ - -typedef struct bro_type_decl -{ - BroAttrs *attrs; - BroType *type; - BroString id; -} BroTypeDecl; - -BroTypeDecl *__bro_type_decl_new(void); -BroTypeDecl *__bro_type_decl_copy(BroTypeDecl *td); -void __bro_type_decl_free(BroTypeDecl *td); -int __bro_type_decl_read(BroTypeDecl *td, BroConn *bc); -int __bro_type_decl_write(BroTypeDecl *td, BroConn *bc); -uint32 __bro_type_decl_hash(BroTypeDecl *td); -int __bro_type_decl_cmp(BroTypeDecl *td1, BroTypeDecl *td2); - -#endif diff --git a/aux/broccoli/src/bro_types.h b/aux/broccoli/src/bro_types.h deleted file mode 100644 index 847125413b..0000000000 --- a/aux/broccoli/src/bro_types.h +++ /dev/null @@ -1,414 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_types_h -#define broccoli_types_h - -#include -#include - -#include -#include -#include -#include -#include - -/* Protocol version */ -#define BRO_PROTOCOL_VERSION 0x06 - -/* Data format version */ -#define BRO_DATA_FORMAT_VERSION 18 - -/* The maximum number of messages we queue before we start - * dropping messages. Might be worth moving this to the - * config file. - * - * FIXME: this should become configurable via the config file. - * - */ -#define BRO_MSG_QUEUELEN_MAX 1000 - -/* Message codes, taken from RemoteSerializer.cc. - * Don't know why the hex -- 0a-0f seem to be missing. - * Doesn't really matter though. - */ -#define BRO_MSG_NONE 0x00 -#define BRO_MSG_VERSION 0x01 -#define BRO_MSG_SERIAL 0x02 -#define BRO_MSG_CLOSE 0x03 -#define BRO_MSG_CLOSE_ALL 0x04 -#define BRO_MSG_ERROR 0x05 -#define BRO_MSG_CONNECTTO 0x06 -#define BRO_MSG_CONNECTED 0x07 -#define BRO_MSG_REQUEST 0x08 -#define BRO_MSG_LISTEN 0x09 -#define BRO_MSG_LISTEN_STOP 0x0a -#define BRO_MSG_STATS 0x0b -#define BRO_MSG_CAPTURE_FILTER 0x0c -#define BRO_MSG_REQUEST_SYNC 0x0d -#define BRO_MSG_PHASE_DONE 0x0e -#define BRO_MSG_PING 0x0f -#define BRO_MSG_PONG 0x10 -#define BRO_MSG_CAPS 0x11 -#define BRO_MSG_COMPRESS 0x12 -#define BRO_MSG_MAX 0x13 - -/* State of the handshake of a connection. Both sides - * can be in the handshake phase or have finished it. - */ -#define BRO_CONNSTATE_SETUP 0 /* Version numbers, cache size...*/ -#define BRO_CONNSTATE_HANDSHAKE 1 /* Event request, capabilities... */ -#define BRO_CONNSTATE_SYNC 2 /* State synchronization */ -#define BRO_CONNSTATE_RUNNING 3 /* Up and running. */ - -/* Capabilities we might have. - */ -#define BRO_CAP_COMPRESS 1 -#define BRO_CAP_DONTCACHE 2 - -/* Message payload types -- these do not - * respond to anything inside Bro and are - * used only locally. - */ -#define BRO_MSG_CONT_NONE 0 -#define BRO_MSG_CONT_RAW 1 /* BroBufs, for strings, integer arrays, etc */ -#define BRO_MSG_CONT_EVENT 2 /* Events */ -#define BRO_MSG_CONT_REQUEST 3 /* Requests for events etc */ -#define BRO_MSG_CONT_PACKET 4 /* Pcap packets */ - -/* Messages between master process and I/O handler in - * shared connections case. - */ -#define BRO_IOMSG_NONE 0 -#define BRO_IOMSG_STOP 1 -#define BRO_IOMSG_READ 2 -#define BRO_IOMSG_WRITE 3 - -/* Event handler callback invocation styles - */ -#define BRO_CALLBACK_EXPANDED 0 /* Each argument passed separately */ -#define BRO_CALLBACK_COMPACT 1 /* All arguments passed as a single BroEvArg* */ - -typedef struct bro_type BroType; -typedef struct bro_type_list BroTypeList; -typedef struct bro_record_type BroRecordType; -typedef struct bro_index_type BroIndexType; -typedef struct bro_table_type BroTableType; -typedef struct bro_set_type BroSetType; - -typedef struct bro_id BroID; -typedef struct bro_val BroVal; -typedef struct bro_list_val BroListVal; -typedef struct bro_mutable_val BroMutableVal; -typedef struct bro_record_val BroRecordVal; -typedef struct bro_table_val BroTableVal; - -typedef struct bro_msg_header BroMsgHeader; -typedef struct bro_msg BroMsg; -typedef struct bro_event_reg BroEventReg; -typedef struct bro_event_handler BroEventHandler; -typedef struct bro_event_cb BroEventCB; -typedef struct bro_request BroRequest; - -/* General per-connection state information that we keep in a separate - * structure so we can put it into shared memory if required. This is - * a remnant from older code, but seems to make sense to preserve. - */ -typedef struct bro_conn_state -{ - /* Whether we are currently attempting a reconnect. Used to make - * sure we do not attempt reconnects while we are attempting a - * reconnect. :) - */ - int in_reconnect; - - /* Timestamp of the last reconnection attempt of this connection. */ - time_t last_reconnect; - - - /* Flags declaring whether or not individual transmission - * directions have shut down (e.g., because of an error). - */ - int tx_dead; - int rx_dead; - - /* State of the connection, for ourselves and the peer. - * Connections go through a - * - * (1) setup - * (2) handshake - * (3) state synchronization - * (4) normal operation - * - * lifecycle, of which phase 3 is optional. - */ - int conn_state_self; - int conn_state_peer; - - /* True if the other side has requested synchronized state. Then - * there is an additional phase in the communication. - */ - int sync_state_requested; - - /* Messages for I/O handler. Only used in shared connection case. */ - int io_msg; - - /* If != 0, ID of writer process for messages in the tx buffer. */ - pid_t io_pid; - -} BroConnState; - - -/* The most important structure: Bro connection handles. - * ===================================================== - */ -struct bro_conn -{ - /* Flags set for this connection at creation time by the user. - */ - int conn_flags; - - /* Two numerical values used for creating identifiers based on - * connection handles. - */ - pid_t id_pid; - int id_num; - - /* The peer we connect to, in : format */ - char *peer; - - /* The class of this connection. It's just an (optional) string. - * If set, gets sent in the setup phase of the connection's - * configuration. - */ - char *class; - - /* A similar class identifier, if sent by the remote side. */ - char *peer_class; - - /* OpenSSL I/O buffer for communication regardless of whether - * we're using encryption or not. - */ - BIO *bio; - - /* Incoming data are buffered in the following buffer - * structure. Each time data arrive, Broccoli checks - * whether there's enough data in the buffer to do - * anything useful with in, in which case those data - * are consumed and make room for more input. - * - * The main purpose of the buffer is to disconnect - * the arrival of data from the time of processing - * because we want to avoid blocking of the instrumented - * application by all means. - * - * Note that the buffers are used in the code directly - * as rx_buf/tx_buf, but may actually live in the shared - * memory segments pointed to by rx_buf_shm/tx_buf_shm. - */ - BroBuf *rx_buf; - - /* Fields to mark the currently processed event in the - * input buffer if event is currently processed, NULLs - * otherwise: - */ - const char *rx_ev_start; - const char *rx_ev_end; - - /* Similar buffer for outgoing data: - */ - BroBuf *tx_buf; - - /* A message queue plus its length counter for messages - * that we haven't yet sent to the peer. - */ - TAILQ_HEAD(mqueue, bro_msg) msg_queue; - uint msg_queue_len; - - /* A hashtable of all the names of events the peer accepts - * from us. - */ - BroHT *ev_mask; - - /* We maintain an event handler registry per conection: - * these registries define callbacks for events that we - * receive and at the same time can be using to request - * event delivery from the peering Bro agent. - */ - BroEventReg *ev_reg; - - /* Serialization data are cached when they will be - * repeated identically. To handle this, there's a per- - * connection cache implemented as a hash table: - */ - BroHT *io_cache; - - /* Size limit for io_cache. *Must* match MAX_CACHE_SIZE - * value defined in Bro's RemoteSerialier.cc. - */ - int io_cache_maxsize; - - /* Storage for arbitrary user data: - */ - BroHT *data; - -#ifdef BRO_PCAP_SUPPORT - uint32 pcap_link_type; -#endif - - /* General connection state */ - BroConnState *state; - - /* Externally provided socket to be used for connection. */ - int socket; -}; - -struct bro_msg_header -{ - char hdr_type; - uint32 hdr_peer_id; -}; - -struct bro_msg -{ - /* Messages get queued inside BroConns. - * These are the list pointers for that. - */ - TAILQ_ENTRY(bro_msg) msg_queue; - uint32 msg_size; - - /* Header of the message, a CMsg in Bro. - */ - struct bro_msg_header msg_header; - - /* A counter for identifying this message. Not used otherwise. */ - int msg_num; - - /* We know the header size, but we need to store it - * somewhere when we send the message. We use this: - */ - uint32 msg_header_size; - - /* A BRO_MSG_CONT_xxx value to identify the type of - * data in the union below. This is easier to use than - * using the type field in the message header all the time. - */ - char msg_cont_type; - - union { - BroBuf *msg_raw; - BroEvent *msg_ev; - BroRequest *msg_req; -#ifdef BRO_PCAP_SUPPORT - BroPacket *msg_packet; -#endif - } msg_cont; - -#define msg_cont_raw msg_cont.msg_raw -#define msg_cont_ev msg_cont.msg_ev -#define msg_cont_req msg_cont.msg_req -#define msg_cont_packet msg_cont.msg_packet -}; - -struct bro_event -{ - /* Name of the event, as listed in event.bif. - */ - BroString name; - - /* Timestamp (seconds since epoch) of creation of event. - */ - double ts; - - /* A list of values to pass to the event, plus the - * length of the list. - */ - BroList *val_list; - int val_len; -}; - - -struct bro_request -{ - int req_len; - char *req_dat; -}; - -/* The Bro event registry: - * ======================= - * - * Each Bro connection handle contains a BroEventReg structure. - * In it, a list of BroEventHandlers registered. Each - * handler represents one particular type of event that can - * be received, and contains a list of BroEventCBs. Each of - * those represents one actual callback performed when an - * event for the handler is received (similarly to Bro, Broccoli - * can have multiple event handlers for a single event type). - * - * Since the number and type of each event will vary, the callback - * mechanism becomes a little tricky. When an event is received, - * its parameters are deserialized accordingly. The registered - * callbacks are then called with POINTERS to all these values -- - * since the size of a pointer is always the same no matter what - * it's pointing to, we can in fact call the callbacks with - * pointers to all these arguments. The number of parameters is - * currently limited to a maximum of 15. If you need that many, - * chances are you'll forget one anyway ;) - */ - -struct bro_event_cb -{ - TAILQ_ENTRY(bro_event_cb) cb_list; - - /* One of the various styles of callbacks, - * identified by cb_style below. - */ - union { - BroEventFunc cb_expd; - BroCompactEventFunc cb_comp; - } cb_func; - -#define cb_expanded_func cb_func.cb_expd -#define cb_compact_func cb_func.cb_comp - - void *cb_user_data; - int cb_style; /* A BRO_CALLBACK_xxx value */ -}; - -struct bro_event_handler -{ - char *ev_name; - - TAILQ_ENTRY(bro_event_handler) handler_list; - TAILQ_HEAD(cblist, bro_event_cb) cb_list; -}; - -struct bro_event_reg -{ - TAILQ_HEAD(hlist, bro_event_handler) handler_list; - int num_handlers; -}; - -#endif diff --git a/aux/broccoli/src/bro_util.c b/aux/broccoli/src/bro_util.c deleted file mode 100644 index 1bd1240799..0000000000 --- a/aux/broccoli/src/bro_util.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include - -#ifdef __EMX__ -#include -#endif - -#include - -#ifdef __MINGW32__ - -/* MinGW does not define a gettimeofday so we need to roll our own. - * This one is largely following - * http://lists.gnu.org/archive/html/bug-gnu-chess/2004-01/msg00020.html - */ - -static int -gettimeofday(struct timeval* p, void* tz /* IGNORED */){ - union { - long long ns100; /*time since 1 Jan 1601 in 100ns units */ - FILETIME ft; - } _now; - - GetSystemTimeAsFileTime( &(_now.ft) ); - p->tv_usec=(long)((_now.ns100 / 10LL) % 1000000LL ); - p->tv_sec= (long)((_now.ns100-(116444736000000000LL))/10000000LL); - return 0; -} -#endif - - -int -__bro_util_snprintf(char *str, size_t size, const char *format, ...) -{ - int result; - va_list al; - va_start(al, format); - result = vsnprintf(str, size, format, al); - va_end(al); - str[size-1] = '\0'; - - return result; -} - -void -__bro_util_fill_subnet(BroSubnet *sn, uint32 net, uint32 width) -{ - if (! sn) - return; - - sn->sn_net = net; - sn->sn_width = width; -} - - -double -__bro_util_get_time(void) -{ - struct timeval tv; - - if (gettimeofday(&tv, 0) < 0) - return 0.0; - - return __bro_util_timeval_to_double(&tv); -} - - -double -__bro_util_timeval_to_double(const struct timeval *tv) -{ - if (! tv) - return 0.0; - - return ((double) tv->tv_sec) + ((double) tv->tv_usec) / 1000000; -} - -#ifndef WORDS_BIGENDIAN -double -__bro_util_htond(double d) -{ - /* Should work as long as doubles have an even length */ - int i, dsize; - double tmp; - char* src = (char*) &d; - char* dst = (char*) &tmp; - - dsize = sizeof(d) - 1; - - for (i = 0; i <= dsize; i++) - dst[i] = src[dsize - i]; - - return tmp; -} - -double -__bro_util_ntohd(double d) -{ - return __bro_util_htond(d); -} -#endif diff --git a/aux/broccoli/src/bro_util.h b/aux/broccoli/src/bro_util.h deleted file mode 100644 index 4d56454230..0000000000 --- a/aux/broccoli/src/bro_util.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_util_h -#define broccoli_util_h - -#include - -#if HAVE_CONFIG_H -# include -#endif - -#ifndef MIN -#define MIN(a,b) (((a)<(b))?(a):(b)) -#endif -#ifndef MAX -#define MAX(a,b) (((a)>(b))?(a):(b)) -#endif - -int __bro_util_snprintf(char *str, size_t size, const char *format, ...); - -void __bro_util_fill_subnet(BroSubnet *sn, uint32 net, uint32 width); - -double __bro_util_get_time(void); - -double __bro_util_timeval_to_double(const struct timeval *tv); - -#ifdef WORDS_BIGENDIAN -#define __bro_util_ntohd(x) x -#define __bro_util_htond(x) x -#else -double __bro_util_htond(double d); -double __bro_util_ntohd(double d); -#endif - -#endif diff --git a/aux/broccoli/src/bro_val.c b/aux/broccoli/src/bro_val.c deleted file mode 100644 index 33502a3337..0000000000 --- a/aux/broccoli/src/bro_val.c +++ /dev/null @@ -1,1863 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include -#include -#include -#include -#include - -#ifdef __EMX__ -#include -#endif - -#include -#include -#include -#include -#include -#include -#include - -/* The virtual implementations of BroSObject's functions are - * kept static in this module, and so are the ..._init() methods - * not currently needed by other, derived classes. - */ -static void __bro_val_init(BroVal *val); -static void __bro_val_free(BroVal *val); -static int __bro_val_read(BroVal *val, BroConn *bc); -static int __bro_val_write(BroVal *val, BroConn *bc); -static int __bro_val_clone(BroVal *dst, BroVal *src); -static uint32 __bro_val_hash(BroVal *val); -static int __bro_val_cmp(BroVal *val1, BroVal *val2); -static void *__bro_val_get(BroVal *val); - -static void __bro_list_val_init(BroListVal *lv); -static void __bro_list_val_free(BroListVal *lv); -static int __bro_list_val_read(BroListVal *lv, BroConn *bc); -static int __bro_list_val_write(BroListVal *lv, BroConn *bc); -static int __bro_list_val_clone(BroListVal *dst, BroListVal *src); -static uint32 __bro_list_val_hash(BroListVal *lv); -static int __bro_list_val_cmp(BroListVal *lv1, BroListVal *lv2); -static BroList *__bro_list_val_get(BroListVal *lv); - -static void __bro_mutable_val_init(BroMutableVal *mv); -static void __bro_mutable_val_free(BroMutableVal *mv); -static int __bro_mutable_val_read(BroMutableVal *mv, BroConn *bc); -static int __bro_mutable_val_write(BroMutableVal *mv, BroConn *bc); -static int __bro_mutable_val_clone(BroMutableVal *dst, BroMutableVal *src); -static uint32 __bro_mutable_val_hash(BroMutableVal *mv); -static int __bro_mutable_val_cmp(BroMutableVal *mv1, BroMutableVal *mv2); - -static void __bro_record_val_init(BroRecordVal *rv); -static void __bro_record_val_free(BroRecordVal *rv); -static int __bro_record_val_read(BroRecordVal *rv, BroConn *bc); -static int __bro_record_val_write(BroRecordVal *rv, BroConn *bc); -static int __bro_record_val_clone(BroRecordVal *dst, BroRecordVal *src); -static uint32 __bro_record_val_hash(BroRecordVal *rv); -static int __bro_record_val_cmp(BroRecordVal *rv1, BroRecordVal *rv2); -static void *__bro_record_val_get(BroRecordVal *rv); - -static void __bro_table_val_init(BroTableVal *tv); -static void __bro_table_val_free(BroTableVal *tv); -static int __bro_table_val_read(BroTableVal *tv, BroConn *bc); -static int __bro_table_val_write(BroTableVal *tv, BroConn *bc); -static int __bro_table_val_clone(BroTableVal *dst, BroTableVal *src); -static uint32 __bro_table_val_hash(BroTableVal *tv); -static int __bro_table_val_cmp(BroTableVal *tv1, BroTableVal *tv2); -static void *__bro_table_val_get(BroTableVal *tv); - -BroVal * -__bro_val_new(void) -{ - BroVal *val; - - D_ENTER; - - if (! (val = calloc(1, sizeof(BroVal)))) - D_RETURN_(NULL); - - __bro_val_init(val); - - D_RETURN_(val); -} - - -BroVal * -__bro_val_new_of_type(int type, const char *type_name) -{ - BroVal *val; - - D_ENTER; - - switch (type) - { - case BRO_TYPE_BOOL: - case BRO_TYPE_INT: - case BRO_TYPE_COUNT: - case BRO_TYPE_COUNTER: - case BRO_TYPE_DOUBLE: - case BRO_TYPE_TIME: - case BRO_TYPE_INTERVAL: - case BRO_TYPE_STRING: - case BRO_TYPE_TIMER: - case BRO_TYPE_PORT: - case BRO_TYPE_IPADDR: - case BRO_TYPE_NET: - case BRO_TYPE_SUBNET: - case BRO_TYPE_ENUM: - if (! (val = __bro_val_new())) - D_RETURN_(NULL); - break; - - case BRO_TYPE_SET: - /* A hack -- sets are table vals, but have set type, - * at least while Bro still has SetType. - */ - case BRO_TYPE_TABLE: - if (! (val = (BroVal *) __bro_table_val_new())) - D_RETURN_(NULL); - break; - - case BRO_TYPE_RECORD: - if (! (val = (BroVal *) __bro_record_val_new())) - D_RETURN_(NULL); - break; - - case BRO_TYPE_PATTERN: - case BRO_TYPE_ANY: - case BRO_TYPE_UNION: - case BRO_TYPE_LIST: - case BRO_TYPE_FUNC: - case BRO_TYPE_FILE: - case BRO_TYPE_VECTOR: - case BRO_TYPE_ERROR: - default: - D(("Unsupported value type %i\n", type)); - D_RETURN_(NULL); - } - - if (! (val->val_type = __bro_type_new_of_type(type, type_name))) - { - __bro_val_free(val); - D_RETURN_(NULL); - } - - D_RETURN_(val); -} - - -int -__bro_val_assign(BroVal *val, const void *data) -{ - D_ENTER; - - if (! val) - { - D(("Input error: (%p, %p)\n", val, data)); - D_RETURN_(FALSE); - } - - if (! data) - { - if (val->val_type) - { - __bro_sobject_release((BroSObject *) val->val_type); - val->val_type = NULL; - } - - D(("Marked val %p as unassigned.\n", val)); - D_RETURN_(TRUE); - } - - - /* If we intend to assign data to the val, it must have a type. */ - if (! val->val_type) - { - D(("Cannot assign to val without a type.\n")); - D_RETURN_(FALSE); - } - - switch (val->val_type->tag) - { - case BRO_TYPE_BOOL: - { - int tmp = *((int *) data); - val->val.char_val = (tmp != 0 ? 1 : 0); - } - break; - - case BRO_TYPE_INT: - case BRO_TYPE_COUNT: - case BRO_TYPE_COUNTER: - case BRO_TYPE_ENUM: - val->val_int = *((int *) data); - break; - - case BRO_TYPE_DOUBLE: - case BRO_TYPE_TIME: - case BRO_TYPE_INTERVAL: - val->val_double = *((double *) data); - break; - - case BRO_TYPE_STRING: - { - BroString *str = (BroString *) data; - bro_string_set_data(&val->val_str, str->str_val, str->str_len); - } - break; - - case BRO_TYPE_PORT: - { - BroPort *tmp = (BroPort *) data; - - if (tmp->port_proto != IPPROTO_TCP && - tmp->port_proto != IPPROTO_UDP && - tmp->port_proto != IPPROTO_ICMP) - { - __bro_sobject_release((BroSObject *) data); - D_RETURN_(FALSE); - } - - val->val_port = *tmp; - } - break; - - case BRO_TYPE_IPADDR: - case BRO_TYPE_NET: - val->val_int = *((uint32 *) data); - break; - - case BRO_TYPE_SUBNET: - val->val_subnet = *((BroSubnet *) data); - break; - - case BRO_TYPE_RECORD: - { - BroList *l; - BroVal *tmp_val; - BroRecordVal *rv = (BroRecordVal *) val; - BroRecord *rec = (BroRecord *) data; - - if (rv->rec) - __bro_record_free(rv->rec); - - rv->rec = __bro_record_copy(rec); - - /* Record vals also have a record type, copy that: */ - for (l = rec->val_list; l; l = __bro_list_next(l)) - { - char *field; - - tmp_val = __bro_list_data(l); - - if (! tmp_val->val_type) - { - D(("Cannot create record type component from val without type.\n")); - D_RETURN_(FALSE); - } - - if (! (field = __bro_sobject_data_get((BroSObject *) tmp_val, "field"))) - { - D(("Val in record doesn't have field name associated with it.\n")); - D_RETURN_(FALSE); - } - - __bro_record_type_add_type((BroRecordType *) val->val_type, field, tmp_val->val_type);; - } - } - break; - - case BRO_TYPE_TABLE: - { - BroTableVal *tv = (BroTableVal *) val; - BroTable *table = (BroTable *) data; - - if (tv->table) - __bro_table_free(tv->table); - - tv->table = __bro_table_copy(table); - - /* XXX need to create the appropriate content in (BroTableType*) val->val_type! */ - } - break; - - case BRO_TYPE_PATTERN: - case BRO_TYPE_TIMER: - case BRO_TYPE_ANY: - case BRO_TYPE_UNION: - case BRO_TYPE_LIST: - case BRO_TYPE_FUNC: - case BRO_TYPE_FILE: - case BRO_TYPE_VECTOR: - case BRO_TYPE_ERROR: - D(("Type %i currently unsupported.\n", val->val_type->tag)); - D_RETURN_(FALSE); - - default: - D(("Unknown type identifier %i\n", val->val_type->tag)); - D_RETURN_(FALSE); - } - - D_RETURN_(TRUE); -} - - -static void -__bro_val_init(BroVal *val) -{ - BroSObject *sobj = (BroSObject *) val; - - D_ENTER; - - __bro_object_init((BroObject *) val); - - sobj->read = (BroSObjectRead) __bro_val_read; - sobj->write = (BroSObjectWrite) __bro_val_write; - sobj->free = (BroSObjectFree) __bro_val_free; - sobj->clone = (BroSObjectClone) __bro_val_clone; - sobj->hash = (BroSObjectHash) __bro_val_hash; - sobj->cmp = (BroSObjectCmp) __bro_val_cmp; - - /* Note: we don't know yet what type_id we'll be using since - * that will depend on the type object hooked into this val. - * We take care of that when we're serializing this val out - * in that case. - */ - sobj->type_id = SER_VAL; - - val->get_data = __bro_val_get; - - D_RETURN; -} - - -static void -__bro_val_free(BroVal *val) -{ - D_ENTER; - - /* If there is no type in the val, then it's unassigned and - * hence there won't be anything to clean up anyway. - */ - if (val->val_type) - { - switch (val->val_type->tag) - { - case BRO_TYPE_STRING: - bro_string_cleanup(&val->val_str); - break; - - default: - /* Nothing to do */ - break; - } - } - - __bro_sobject_release((BroSObject *) val->val_type); - __bro_object_free((BroObject *) val); - - D_RETURN; -} - - -int -__bro_val_get_type_num(const BroVal *val) -{ - if (! val) - return 0; - - return val->val_type->tag; -} - - -int -__bro_val_get_data(BroVal *val, int *type, void **data) -{ - if (! val || ! data) - return FALSE; - - if (! val->get_data) - return FALSE; - - if (type && val->val_type) - *type = val->val_type->tag; - - *data = val->get_data(val); - return TRUE; -} - - -static int -__bro_val_read(BroVal *val, BroConn *bc) -{ - char opt; - uint32 tmp; - - D_ENTER; - - if (! val || !bc) - D_RETURN_(FALSE); - - if (! __bro_object_read((BroObject *) val, bc)) - D_RETURN_(FALSE); - - /* Read type */ - - if (val->val_type) - { - __bro_sobject_release((BroSObject *) val->val_type); - val->val_type = NULL; - } - - if (! (val->val_type = (BroType *) __bro_sobject_unserialize(SER_IS_TYPE, bc))) - D_RETURN_(FALSE); - - D(("Type in val has type tags %i/%i\n", - val->val_type->tag, val->val_type->internal_tag)); - - /* Read optional Attributes */ - - if (val->val_attrs) - { - __bro_sobject_release((BroSObject *) val->val_attrs); - val->val_attrs = NULL; - } - - if (! __bro_buf_read_char(bc->rx_buf, &opt)) - D_RETURN_(FALSE); - if (opt) - { - if (! (val->val_attrs = (BroRecordVal *) __bro_sobject_unserialize(SER_RECORD_VAL, bc))) - D_RETURN_(FALSE); - } - - switch (val->val_type->internal_tag) - { - case BRO_INTTYPE_INT: - case BRO_INTTYPE_UNSIGNED: - /* Hack for ports */ - if (val->val_type->tag == BRO_TYPE_PORT) - { - if (! __bro_buf_read_int(bc->rx_buf, &tmp)) - D_RETURN_(FALSE); - - if ( (tmp & 0xf0000) == 0x10000 ) - val->val_port.port_proto = IPPROTO_TCP; - else if ( (tmp & 0xf0000) == 0x20000 ) - val->val_port.port_proto = IPPROTO_UDP; - else if ( (tmp & 0xf0000) == 0x30000 ) - val->val_port.port_proto = IPPROTO_ICMP; - - val->val_port.port_num = (tmp & 0xFFFF); - } - else - { - if (! __bro_buf_read_int(bc->rx_buf, &val->val_int)) - D_RETURN_(FALSE); - } - break; - - case BRO_INTTYPE_DOUBLE: - if (! __bro_buf_read_double(bc->rx_buf, &val->val_double)) - D_RETURN_(FALSE); - break; - - case BRO_INTTYPE_STRING: - if (! __bro_buf_read_string(bc->rx_buf, &val->val_str)) - D_RETURN_(FALSE); - break; - - case BRO_INTTYPE_IPADDR: - if (! __bro_buf_read_int(bc->rx_buf, &tmp)) - D_RETURN_(FALSE); - - if (tmp != 1) - { - D(("We don't handle IPv6 addresses yet.\n")); - D_RETURN_(FALSE); - } - - if (! __bro_buf_read_int(bc->rx_buf, &val->val_int)) - D_RETURN_(FALSE); - - val->val_int = ntohl(val->val_int); - break; - - case BRO_INTTYPE_SUBNET: - if (! __bro_buf_read_int(bc->rx_buf, &tmp)) - D_RETURN_(FALSE); - - if (tmp != 1) - { - D(("We don't handle IPv6 addresses yet.\n")); - D_RETURN_(FALSE); - } - - if (! __bro_buf_read_int(bc->rx_buf, &val->val_subnet.sn_net)) - D_RETURN_(FALSE); - val->val_subnet.sn_net = ntohl(val->val_subnet.sn_net); - - if (! __bro_buf_read_int(bc->rx_buf, &val->val_subnet.sn_width)) - D_RETURN_(FALSE); - break; - - case BRO_INTTYPE_OTHER: - /* See Val.cc around 165 -- these are handled by derived classes. - * We only make sure here it's not functions and not files. - */ - if (val->val_type->tag != BRO_TYPE_FUNC && - val->val_type->tag != BRO_TYPE_FILE) - break; - - /* Otherwise fall through to warning. */ - - default: - D(("Unsupported internal type tag: %i\n", val->val_type->internal_tag)); - D_RETURN_(FALSE); - } - - D_RETURN_(TRUE); -} - - -static int -__bro_val_write(BroVal *val, BroConn *bc) -{ - BroType *type; - BroSObject *obj; - - D_ENTER; - - if (! val || !bc) - D_RETURN_(FALSE); - - /* We need to make sure that the BroSObject at the root has the - * correct type_id (a SER_xxx value). This depends on the type object - * so map the type tag of that object to a SER_xxx value: - */ - if (! val->val_type) - { - D(("Val %p doesn't have a type.\n", val)); - D_RETURN_(FALSE); - } - - type = (BroType *) val->val_type; - obj = (BroSObject *) val; - - switch (type->tag) - { - case BRO_TYPE_BOOL: - case BRO_TYPE_INT: - case BRO_TYPE_COUNT: - case BRO_TYPE_COUNTER: - case BRO_TYPE_STRING: - case BRO_TYPE_DOUBLE: - case BRO_TYPE_TIME: - obj->type_id = SER_VAL; - break; - - case BRO_TYPE_ENUM: - obj->type_id = SER_ENUM_VAL; - break; - - case BRO_TYPE_PORT: - obj->type_id = SER_PORT_VAL; - break; - - case BRO_TYPE_INTERVAL: - obj->type_id = SER_INTERVAL_VAL; - break; - - case BRO_TYPE_IPADDR: - obj->type_id = SER_ADDR_VAL; - break; - - case BRO_TYPE_NET: - obj->type_id = SER_NET_VAL; - break; - - case BRO_TYPE_SUBNET: - obj->type_id = SER_SUBNET_VAL; - break; - - case BRO_TYPE_RECORD: - obj->type_id = SER_RECORD_VAL; - break; - - default: - D(("Val %p's type unhandled: type tag is %i.\n", val, type->tag)); - D_RETURN_(FALSE); - } - - if (! __bro_object_write((BroObject *) val, bc)) - D_RETURN_(FALSE); - - if (! __bro_sobject_serialize((BroSObject *) val->val_type, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_char(bc->tx_buf, val->val_attrs ? 1 : 0)) - D_RETURN_(FALSE); - - if (val->val_attrs && ! __bro_sobject_serialize((BroSObject *) val->val_attrs, bc)) - D_RETURN_(FALSE); - - switch (val->val_type->internal_tag) - { - case BRO_INTTYPE_INT: - case BRO_INTTYPE_UNSIGNED: - /* Hack for ports */ - if (val->val_type->tag == BRO_TYPE_PORT) - { - int tmp = val->val_port.port_num; - - if (val->val_port.port_proto == IPPROTO_TCP) - tmp |= 0x10000; - else if (val->val_port.port_proto == IPPROTO_UDP) - tmp |= 0x20000; - else if (val->val_port.port_proto == IPPROTO_ICMP) - tmp |= 0x30000; - - if (! __bro_buf_write_int(bc->tx_buf, tmp)) - D_RETURN_(FALSE); - } - else - { - if (! __bro_buf_write_int(bc->tx_buf, val->val_int)) - D_RETURN_(FALSE); - } - break; - - case BRO_INTTYPE_DOUBLE: - if (! __bro_buf_write_double(bc->tx_buf, val->val_double)) - D_RETURN_(FALSE); - break; - - case BRO_INTTYPE_STRING: - if (! __bro_buf_write_string(bc->tx_buf, &val->val_str)) - D_RETURN_(FALSE); - break; - - case BRO_INTTYPE_IPADDR: - if (! __bro_buf_write_int(bc->tx_buf, 1)) - D_RETURN_(FALSE); - if (! __bro_buf_write_int(bc->tx_buf, htonl(val->val_int))) - D_RETURN_(FALSE); - break; - - case BRO_INTTYPE_SUBNET: - if (! __bro_buf_write_int(bc->tx_buf, 1)) - D_RETURN_(FALSE); - if (! __bro_buf_write_int(bc->tx_buf, htonl(val->val_subnet.sn_net))) - D_RETURN_(FALSE); - if (! __bro_buf_write_int(bc->tx_buf, val->val_subnet.sn_width)) - D_RETURN_(FALSE); - break; - - case BRO_INTTYPE_OTHER: - /* That's fine, will be handled in derived classes - * like __bro_record_val_write(). - */ - break; - - default: - D(("Unknown internal type tag: %i\n", val->val_type->internal_tag)); - D_RETURN_(FALSE); - } - - D_RETURN_(TRUE); -} - -static int -__bro_val_clone(BroVal *dst, BroVal *src) -{ - D_ENTER; - - if (! __bro_object_clone((BroObject *) dst, (BroObject *) src)) - { - D(("Cloning parent failed.\n")); - D_RETURN_(FALSE); - } - - if (src->val_type && - ! (dst->val_type = (BroType *) __bro_sobject_copy((BroSObject *) src->val_type))) - { - D(("Cloning type failed.\n")); - D_RETURN_(FALSE); - } - - if (src->val_attrs && - ! (dst->val_attrs = (BroRecordVal *) __bro_sobject_copy((BroSObject *) src->val_attrs))) - { - D(("Cloning attributes failed.\n")); - D_RETURN_(FALSE); - } - - switch (dst->val_type->internal_tag) - { - case BRO_INTTYPE_INT: - case BRO_INTTYPE_UNSIGNED: - case BRO_INTTYPE_IPADDR: - /* Hack for ports */ - if (src->val_type->tag == BRO_TYPE_PORT) - dst->val_port = src->val_port; - else - dst->val_int = src->val_int; - break; - - case BRO_INTTYPE_DOUBLE: - dst->val_double = src->val_double; - break; - - case BRO_INTTYPE_STRING: - bro_string_assign(&src->val_str, &dst->val_str); - break; - - case BRO_INTTYPE_SUBNET: - dst->val_subnet = src->val_subnet; - break; - - case BRO_INTTYPE_OTHER: - /* That's okay, handled in subtype */ - break; - - default: - D(("Unknown internal type tag: %i\n", dst->val_type->internal_tag)); - D_RETURN_(FALSE); - } - - D_RETURN_(TRUE); -} - -static uint32 -__bro_val_hash(BroVal *val) -{ - uint32 result; - - D_ENTER; - - if (! val) - D_RETURN_(0); - - result = __bro_sobject_hash((BroSObject*) val->val_type); - - switch (val->val_type->internal_tag) - { - case BRO_INTTYPE_INT: - case BRO_INTTYPE_UNSIGNED: - case BRO_INTTYPE_IPADDR: - result ^= val->val_int; - break; - - case BRO_INTTYPE_DOUBLE: - result ^= (uint32) val->val_double; - break; - - case BRO_INTTYPE_STRING: - result ^= __bro_ht_str_hash(val->val_str.str_val); - break; - - case BRO_INTTYPE_SUBNET: - result ^= val->val_subnet.sn_net; - result ^= val->val_subnet.sn_width; - break; - - case BRO_INTTYPE_OTHER: - D(("WARNING -- __bro_val_hash() invoked on derived type.\n")); - break; - - default: - D(("Unknown internal type tag: %i\n", val->val_type->internal_tag)); - break; - } - - D_RETURN_(result); -} - -static int -__bro_val_cmp(BroVal *val1, BroVal *val2) -{ - D_ENTER; - - if (! val1 || ! val2) - D_RETURN_(FALSE); - - if (! __bro_sobject_cmp((BroSObject*) val1->val_type, - (BroSObject*) val2->val_type)) - D_RETURN_(FALSE); - - switch (val1->val_type->internal_tag) - { - case BRO_INTTYPE_INT: - case BRO_INTTYPE_UNSIGNED: - case BRO_INTTYPE_IPADDR: - if (val1->val_int != val2->val_int) - D_RETURN_(FALSE); - break; - - case BRO_INTTYPE_DOUBLE: - if (val1->val_double != val2->val_double) - D_RETURN_(FALSE); - break; - - case BRO_INTTYPE_STRING: - if (! __bro_ht_str_cmp(val1->val_str.str_val, val2->val_str.str_val)) - D_RETURN_(FALSE); - break; - - case BRO_INTTYPE_SUBNET: - if (val1->val_subnet.sn_net != val2->val_subnet.sn_net || - val1->val_subnet.sn_width != val2->val_subnet.sn_width) - D_RETURN_(FALSE); - break; - - case BRO_INTTYPE_OTHER: - D(("WARNING -- __bro_val_cmp() invoked on derived type.\n")); - break; - - default: - D(("Unknown internal type tag: %i\n", val1->val_type->internal_tag)); - break; - } - - D_RETURN_(TRUE); -} - -static void * -__bro_val_get(BroVal *val) -{ - /* Following the comments in broccoli.h, we return atomic values - * as copies into *result, and complex types (i.e., structs) have - * all members assigned to point to internal values so the user - * does not have to clean up the returned value. The user can - * still keep those values around if necessary by copying them. - */ - if (! val->val_type) - { - D(("No type in val %p\n", val)); - return NULL; - } - - switch (val->val_type->tag) - { - case BRO_TYPE_BOOL: - case BRO_TYPE_INT: - case BRO_TYPE_ENUM: - case BRO_TYPE_COUNT: - case BRO_TYPE_COUNTER: - case BRO_TYPE_IPADDR: - case BRO_TYPE_NET: - return &val->val_int; - - case BRO_TYPE_PORT: - return &val->val_port; - - case BRO_TYPE_DOUBLE: - case BRO_TYPE_TIME: - case BRO_TYPE_INTERVAL: - return &val->val_double; - - case BRO_TYPE_STRING: - return &val->val_str; - - case BRO_TYPE_SUBNET: - return &val->val_subnet; - - case BRO_TYPE_RECORD: - D(("WARNING: Inheritance broken -- record types should not be handled here.\n")); - return NULL; - - case BRO_TYPE_TABLE: - D(("WARNING: Inheritance broken -- table types should not be handled here.\n")); - return NULL; - - default: - D(("Type %i currently not extractable.\n", val->val_type->tag)); - } - - return NULL; -} - - -BroListVal * -__bro_list_val_new(void) -{ - BroListVal *val; - - D_ENTER; - - if (! (val = calloc(1, sizeof(BroListVal)))) - D_RETURN_(NULL); - - __bro_list_val_init(val); - - D_RETURN_(val); -} - -static void -__bro_list_val_init(BroListVal *lv) -{ - BroSObject *sobj = (BroSObject *) lv; - BroVal *val = (BroVal *) lv; - - D_ENTER; - - __bro_val_init((BroVal *) lv); - - sobj->read = (BroSObjectRead) __bro_list_val_read; - sobj->write = (BroSObjectWrite) __bro_list_val_write; - sobj->free = (BroSObjectFree) __bro_list_val_free; - sobj->clone = (BroSObjectClone) __bro_list_val_clone; - sobj->hash = (BroSObjectHash) __bro_list_val_hash; - sobj->cmp = (BroSObjectCmp) __bro_list_val_cmp; - - sobj->type_id = SER_LIST_VAL; - - val->get_data = (BroValAccessor) __bro_list_val_get; - - D_RETURN; -} - -static void -__bro_list_val_free(BroListVal *lv) -{ - D_ENTER; - - if (! lv) - D_RETURN; - - __bro_list_free(lv->list, (BroFunc) __bro_sobject_release); - __bro_val_free((BroVal *) lv); - - D_RETURN; -} - -static int -__bro_list_val_read(BroListVal *lv, BroConn *bc) -{ - int i; - uint32 ui; - - D_ENTER; - - if (! __bro_val_read((BroVal *) lv, bc)) - D_RETURN_(FALSE); - - __bro_list_free(lv->list, (BroFunc) __bro_sobject_release); - lv->list = NULL; - - if (! __bro_buf_read_char(bc->rx_buf, &lv->type_tag)) - goto error_return; - if (! __bro_buf_read_int(bc->rx_buf, &ui)) - goto error_return; - - lv->len = (int) ui; - - for (i = 0; i < lv->len; i++) - { - BroVal *val; - - if (! (val = (BroVal *) __bro_sobject_unserialize(SER_IS_VAL, bc))) - goto error_return; - - lv->list = __bro_list_append(lv->list, val); - } - - D_RETURN_(TRUE); - - error_return: - __bro_list_free(lv->list, (BroFunc) __bro_sobject_release); - lv->list = NULL; - D_RETURN_(FALSE); -} - -static int -__bro_list_val_write(BroListVal *lv, BroConn *bc) -{ - BroList *l; - - D_ENTER; - - if (! __bro_val_write((BroVal *) lv, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_char(bc->tx_buf, lv->type_tag)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_int(bc->tx_buf, lv->len)) - D_RETURN_(FALSE); - - for (l = lv->list; l; l = __bro_list_next(l)) - { - BroVal *val = __bro_list_data(l); - - if (! __bro_sobject_serialize((BroSObject *) val, bc)) - D_RETURN_(FALSE); - } - - D_RETURN_(TRUE); -} - -static int -__bro_list_val_clone(BroListVal *dst, BroListVal *src) -{ - BroList *l; - - D_ENTER; - - if (! __bro_val_clone((BroVal *) dst, (BroVal *) src)) - D_RETURN_(FALSE); - - dst->type_tag = src->type_tag; - dst->len = src->len; - - if (dst->list) - { - __bro_list_free(dst->list, (BroFunc) __bro_sobject_release); - dst->list = NULL; - } - - for (l = src->list; l; l = __bro_list_next(l)) - dst->list = __bro_list_append(dst->list, __bro_sobject_copy(__bro_list_data(l))); - - D_RETURN_(TRUE); -} - -static uint32 -__bro_list_val_hash(BroListVal *lv) -{ - uint32 result; - BroList *l; - - D_ENTER; - - if (! lv) - D_RETURN_(0); - - result = lv->len ^ lv->type_tag; - - for (l = lv->list; l; l = __bro_list_next(l)) - result ^= __bro_sobject_hash((BroSObject *) __bro_list_data(l)); - - D_RETURN_(result); -} - -static int -__bro_list_val_cmp(BroListVal *lv1, BroListVal *lv2) -{ - BroList *l1, *l2; - - D_ENTER; - - if (! lv1 || ! lv2) - D_RETURN_(FALSE); - - if (lv1->len != lv2->len || - lv1->type_tag != lv2->type_tag) - D_RETURN_(FALSE); - - for (l1 = lv1->list, l2 = lv2->list; l1 && l2; - l1 = __bro_list_next(l1), l2 = __bro_list_next(l2)) - { - if (! __bro_sobject_cmp((BroSObject*) __bro_list_data(l1), - (BroSObject*) __bro_list_data(l2))) - D_RETURN_(FALSE); - } - - if (l1 || l2) - { - D(("WARNING -- list length inconsistency.\n")); - D_RETURN_(FALSE); - } - - D_RETURN_(TRUE); -} - -static BroList * -__bro_list_val_get(BroListVal *lv) -{ - D_ENTER; - D_RETURN_(lv->list); -} - -void -__bro_list_val_append(BroListVal *lv, BroVal *val) -{ - D_ENTER; - - if (! lv || ! val) - D_RETURN; - - lv->list = __bro_list_append(lv->list, val); - lv->len++; - - D_RETURN; -} - -BroVal * -__bro_list_val_pop_front(BroListVal *lv) -{ - BroVal *result; - BroList *l; - - D_ENTER; - - if (! lv) - D_RETURN_(NULL); - - l = lv->list; - lv->list = __bro_list_remove(lv->list, lv->list); - - result = (BroVal*) __bro_list_data(l); - __bro_list_free(l, NULL); - - D_RETURN_(result); -} - -BroVal * -__bro_list_val_get_front(BroListVal *lv) -{ - BroVal *result; - BroList *l; - - D_ENTER; - - if (! lv) - D_RETURN_(NULL); - - D_RETURN_((BroVal*) __bro_list_data(lv->list)); -} - -int -__bro_list_val_get_length(BroListVal *lv) -{ - D_ENTER; - - if (! lv) - D_RETURN_(0); - - D_RETURN_(lv->len); -} - - - -BroMutableVal * -__bro_mutable_val_new(void) -{ - BroMutableVal *val; - - D_ENTER; - - if (! (val = calloc(1, sizeof(BroMutableVal)))) - D_RETURN_(NULL); - - __bro_mutable_val_init(val); - - D_RETURN_(val); -} - - -static void -__bro_mutable_val_init(BroMutableVal *mv) -{ - BroSObject *sobj = (BroSObject *) mv; - - D_ENTER; - - __bro_val_init((BroVal *) mv); - - sobj->read = (BroSObjectRead) __bro_mutable_val_read; - sobj->write = (BroSObjectWrite) __bro_mutable_val_write; - sobj->free = (BroSObjectFree) __bro_mutable_val_free; - sobj->clone = (BroSObjectClone) __bro_mutable_val_clone; - sobj->hash = (BroSObjectHash) __bro_mutable_val_hash; - sobj->cmp = (BroSObjectCmp) __bro_mutable_val_cmp; - - sobj->type_id = SER_MUTABLE_VAL; - - /* BroMutableVal inherits __bro_val_get and doesn't override it. */ - - D_RETURN; -} - - -static void -__bro_mutable_val_free(BroMutableVal *mv) -{ - D_ENTER; - - __bro_sobject_release((BroSObject *) mv->id); - __bro_val_free((BroVal *) mv); - - D_RETURN; -} - - -static int -__bro_mutable_val_read(BroMutableVal *mv, BroConn *bc) -{ - BroString tmp; - - D_ENTER; - - bro_string_init(&tmp); - - if (! __bro_val_read((BroVal *) mv, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_read_char(bc->rx_buf, &mv->props)) - D_RETURN_(FALSE); - - if (! __bro_buf_read_string(bc->rx_buf, &tmp)) - D_RETURN_(FALSE); - - /* FIXME: now need to obtain real BroID from that name */ - bro_string_cleanup(&tmp); - - D_RETURN_(TRUE); -} - - -static int -__bro_mutable_val_write(BroMutableVal *mv, BroConn *bc) -{ - D_ENTER; - - if (! __bro_val_write((BroVal *) mv, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_char(bc->tx_buf, mv->props)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_string(bc->tx_buf, (mv->id ? &mv->id->name : NULL))) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -static int -__bro_mutable_val_clone(BroMutableVal *dst, BroMutableVal *src) -{ - D_ENTER; - - if (! __bro_val_clone((BroVal *) dst, (BroVal *) src)) - D_RETURN_(FALSE); - - if (src->id && ! (dst->id = (BroID *) __bro_sobject_copy((BroSObject *) src->id))) - D_RETURN_(FALSE); - - src->props = dst->props; - - D_RETURN_(TRUE); -} - - -static uint32 -__bro_mutable_val_hash(BroMutableVal *mv) -{ - uint32 result; - - D_ENTER; - - if (! mv) - D_RETURN_(0); - - result = __bro_id_hash(mv->id) ^ mv->props; - - D_RETURN_(result); -} - - -static int -__bro_mutable_val_cmp(BroMutableVal *mv1, BroMutableVal *mv2) -{ - D_ENTER; - - if (! mv1 || ! mv2) - D_RETURN_(FALSE); - - if (! __bro_id_cmp(mv1->id, mv2->id)) - D_RETURN_(FALSE); - - if (mv1->props != mv2->props) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -BroRecordVal * -__bro_record_val_new(void) -{ - BroRecordVal *val; - - D_ENTER; - - if (! (val = calloc(1, sizeof(BroRecordVal)))) - D_RETURN_(NULL); - - __bro_record_val_init(val); - - D_RETURN_(val); -} - - -static void -__bro_record_val_init(BroRecordVal *rv) -{ - BroSObject *sobj = (BroSObject *) rv; - BroVal *val = (BroVal *) rv; - - D_ENTER; - - __bro_mutable_val_init((BroMutableVal *) rv); - - sobj->read = (BroSObjectRead) __bro_record_val_read; - sobj->write = (BroSObjectWrite) __bro_record_val_write; - sobj->free = (BroSObjectFree) __bro_record_val_free; - sobj->clone = (BroSObjectClone) __bro_record_val_clone; - sobj->hash = (BroSObjectHash) __bro_record_val_hash; - sobj->cmp = (BroSObjectCmp) __bro_record_val_cmp; - - sobj->type_id = SER_RECORD_VAL; - - val->get_data = (BroValAccessor) __bro_record_val_get; - - D_RETURN; -} - - -static void -__bro_record_val_free(BroRecordVal *rv) -{ - D_ENTER; - - if (! rv) - D_RETURN; - - __bro_record_free(rv->rec); - __bro_mutable_val_free((BroMutableVal *) rv); - - D_RETURN; -} - - -static int -__bro_record_val_read(BroRecordVal *rv, BroConn *bc) -{ - char opt; - uint32 i, len; - BroVal *val; - - D_ENTER; - - if (! __bro_mutable_val_read((BroMutableVal *) rv, bc)) - D_RETURN_(FALSE); - - /* Clean out old vals, if any */ - __bro_record_free(rv->rec); - - if (! (rv->rec = __bro_record_new())) - D_RETURN_(FALSE); - - /* Read in new vals */ - - if (! __bro_buf_read_int(bc->rx_buf, &len)) - goto error_return; - - for (i = 0; i < len; i++) - { - const char *field_name; - BroVal *rv_val = (BroVal *) rv; - BroType *rv_type = rv_val->val_type; - - D(("Reading val %i/%i into record %p of val %p\n", - i+1, len, rv->rec, rv)); - - if (! __bro_buf_read_char(bc->rx_buf, &opt)) - goto error_return; - - if (opt) - { - if (! (val = (BroVal *) __bro_sobject_unserialize(SER_IS_VAL, bc))) - { - D(("WARNING -- unserializing record element failed.\n")); - goto error_return; - } - } - else - { - /* We need an empty val if none was given in order to maintain - * a chain of vals nonetheless -- the missing type in this new - * val indicates that it is an unassigned val. - */ - D(("WARNING -- unassigned val.\n")); - if (! (val = __bro_val_new())) - goto error_return; - } - - __bro_record_add_val(rv->rec, val); - - if (! (field_name = __bro_record_type_get_nth_field((BroRecordType *) rv_type, i))) - { - D(("WARNING -- record type field %i has no name.\n", i)); - goto error_return; - } - - __bro_record_set_nth_name(rv->rec, i, field_name); - } - - D_RETURN_(TRUE); - - error_return: - __bro_record_free(rv->rec); - rv->rec = NULL; - D_RETURN_(FALSE); -} - - -static int -__bro_record_val_write(BroRecordVal *rv, BroConn *bc) -{ - BroList *l; - BroVal *val; - int i; - - D_ENTER; - - if (! __bro_mutable_val_write((BroMutableVal *) rv, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_int(bc->tx_buf, rv->rec->val_len)) - D_RETURN_(FALSE); - - if (! rv->rec && rv->rec->val_len > 0) - D_RETURN_(FALSE); - - D(("Writing out %i vals in record %p.\n", rv->rec->val_len, rv->rec)); - - for (i = 0, l = rv->rec->val_list; l; i++, l = __bro_list_next(l)) - { - val = __bro_list_data(l); - - D(("Val %i/%p's type: %p\n", i, val, val->val_type)); - - if (! __bro_buf_write_char(bc->tx_buf, (val->val_type ? 1 :0))) - D_RETURN_(FALSE); - - if (val->val_type) - { - if (! __bro_sobject_serialize((BroSObject *) val, bc)) - D_RETURN_(FALSE); - } - } - - D_RETURN_(TRUE); -} - - -static int -__bro_record_val_clone(BroRecordVal *dst, BroRecordVal *src) -{ - D_ENTER; - - if (! __bro_mutable_val_clone((BroMutableVal *) dst, (BroMutableVal *) src)) - D_RETURN_(FALSE); - - if (src->rec && ! (dst->rec = __bro_record_copy(src->rec))) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - - -static uint32 -__bro_record_val_hash(BroRecordVal *rv) -{ - uint32 result; - - D_ENTER; - - if (! rv) - D_RETURN_(0); - - result = __bro_record_hash(rv->rec); - - D_RETURN_(result); - -} - - -static int -__bro_record_val_cmp(BroRecordVal *rv1, BroRecordVal *rv2) -{ - D_ENTER; - - if (! rv1 || ! rv2) - D_RETURN_(FALSE); - - if (! __bro_record_cmp(rv1->rec, rv2->rec)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); - -} - - -static void * -__bro_record_val_get(BroRecordVal *rv) -{ - return rv->rec; -} - - -BroTableVal * -__bro_table_val_new(void) -{ - BroTableVal *val; - - D_ENTER; - - if (! (val = calloc(1, sizeof(BroTableVal)))) - D_RETURN_(NULL); - - __bro_table_val_init(val); - - D_RETURN_(val); -} - -static void -__bro_table_val_init(BroTableVal *tbl) -{ - BroSObject *sobj = (BroSObject *) tbl; - BroVal *val = (BroVal *) tbl; - - D_ENTER; - - __bro_mutable_val_init((BroMutableVal *) tbl); - - sobj->read = (BroSObjectRead) __bro_table_val_read; - sobj->write = (BroSObjectWrite) __bro_table_val_write; - sobj->free = (BroSObjectFree) __bro_table_val_free; - sobj->clone = (BroSObjectClone) __bro_table_val_clone; - sobj->hash = (BroSObjectHash) __bro_table_val_hash; - sobj->cmp = (BroSObjectCmp) __bro_table_val_cmp; - - sobj->type_id = SER_TABLE_VAL; - - val->get_data = (BroValAccessor) __bro_table_val_get; - - D_RETURN; -} - -static void -__bro_table_val_free(BroTableVal *tbl) -{ - D_ENTER; - - if (! tbl) - D_RETURN; - - __bro_table_free(tbl->table); - __bro_mutable_val_free((BroMutableVal *) tbl); - - D_RETURN; -} - -static int -__bro_table_val_read(BroTableVal *tbl, BroConn *bc) -{ - double d; - char opt; - int num_keys = 0, num_vals = 0; - - D_ENTER; - - if (! __bro_mutable_val_read((BroMutableVal *) tbl, bc)) - D_RETURN_(FALSE); - - /* Clean out old vals, if any */ - __bro_table_free(tbl->table); - - if (! (tbl->table = __bro_table_new())) - D_RETURN_(FALSE); - - /* expire_time, currently unused */ - if (! __bro_buf_read_double(bc->rx_buf, &d)) - goto error_return; - - if (! __bro_buf_read_char(bc->rx_buf, &opt)) - goto error_return; - if (opt) - { - if (! (tbl->attrs = (BroAttrs *) __bro_sobject_unserialize(SER_ATTRIBUTES, bc))) - { - D(("WARNING -- unserializing table attributes failed.\n")); - goto error_return; - } - } - - if (! __bro_buf_read_char(bc->rx_buf, &opt)) - goto error_return; - if (opt) - { - D(("WARNING -- cannot unserialize expression, try to use table without expiration expression.\n")); - goto error_return; - } - - /* Table entries are next: */ - for ( ; ; ) - { - BroType *type; - BroListVal *keys = NULL; - BroVal *val = NULL; - BroIndexType *itype = NULL; - int i, len, key_type = 0, val_type = 0; - double d; - - if (! __bro_buf_read_char(bc->rx_buf, &opt)) - goto error_return; - - /* End of set members is announced if opt is 0: */ - if (! opt) - break; - - if (! (keys = (BroListVal *) __bro_sobject_unserialize(SER_LIST_VAL, bc))) - goto error_return; - - /* If this isn't a set, we have a value associated with the keys too. */ - type = ((BroVal *) tbl)->val_type; - itype = (BroIndexType*) type; - num_vals++; - - if (itype->yield_type) - { - if (! (val = (BroVal *) __bro_sobject_unserialize(SER_IS_VAL, bc))) - goto error_return; - - val_type = val->val_type->tag; - num_keys++; - } - - /* If the key is a composite, we report BRO_TYPE_LIST to the user, - * so the user can access the individual values via a record. If - * the key is atomic, we extract its type and use it directly. - */ - - if (keys->len > 1) - key_type = BRO_TYPE_LIST; - else if (keys->len == 1) - key_type = __bro_list_val_get_front(keys)->val_type->tag; - else - goto error_return; - - if (tbl->table->tbl_key_type != BRO_TYPE_UNKNOWN && - tbl->table->tbl_key_type != key_type) - { - D(("Type mismatch when unserializing key of type %d, expecting %d\n", - key_type, tbl->table->tbl_key_type)); - goto error_return; - } - - tbl->table->tbl_key_type = key_type; - - if (tbl->table->tbl_val_type != BRO_TYPE_UNKNOWN && - tbl->table->tbl_val_type != val_type) - { - D(("Type mismatch when unserializing val of type %d, expecting %d\n", - val_type, tbl->table->tbl_val_type)); - goto error_return; - } - - tbl->table->tbl_val_type = val_type; - - /* Eat two doubles -- one for the last access time and - * one for when the item is supposed to expire. - * XXX: currently unimplemented. - */ - if (! __bro_buf_read_double(bc->rx_buf, &d) || - ! __bro_buf_read_double(bc->rx_buf, &d)) - goto error_return; - - /* The key type of a BroTable is always a BroListVal, even - * though it might well have only a single element. - * - * Since we just unserialized it, we pass on ownership of - * both key and value to the table. - */ - __bro_table_insert(tbl->table, (BroVal*) keys, val); - } - - D_RETURN_(TRUE); - - error_return: - __bro_table_free(tbl->table); - tbl->table = NULL; - D_RETURN_(FALSE); -} - -static int -__bro_table_val_write_cb_direct(BroVal *key, BroVal *val, BroConn *bc) -{ - if (! __bro_sobject_serialize((BroSObject *) key, bc)) - return FALSE; - - if (val && ! __bro_sobject_serialize((BroSObject *) val, bc)) - return FALSE; - - return TRUE; -} - -static int -__bro_table_val_write_cb_unpack(BroVal *key, BroRecordVal *val, BroConn *bc) -{ - BroRecord *rec = val->rec; - BroListVal *lv = __bro_list_val_new(); - - /* Just hook the list into the list val, we unhook below. */ - lv->list = rec->val_list; - lv->len = rec->val_len; - - if (! __bro_sobject_serialize((BroSObject *) lv, bc)) - goto error_return; - - if (val && ! __bro_sobject_serialize((BroSObject *) val, bc)) - goto error_return; - - lv->list = NULL; - __bro_list_val_free(lv); - - return TRUE; - - error_return: - lv->list = NULL; - __bro_list_val_free(lv); - return FALSE; -} - -static int -__bro_table_val_write(BroTableVal *tbl, BroConn *bc) -{ - double d = 0; - char opt = 0; - - D_ENTER; - - if (! __bro_mutable_val_write((BroMutableVal *) tbl, bc)) - D_RETURN_(FALSE); - - if (! __bro_buf_write_double(bc->tx_buf, d)) - D_RETURN_(FALSE); - - /* XXX For now we neever send any attributes, nor an expire expr */ - if (! __bro_buf_write_char(bc->tx_buf, opt)) - D_RETURN_(FALSE); - if (! __bro_buf_write_char(bc->tx_buf, opt)) - D_RETURN_(FALSE); - - /* How we iterate depends on whether the index type is atomic or not. - * If atomic, we use __bro_table_val_write_cb_direct(), otherwise - * we use ..._unpack(), which converts the elements of the RecordVal - * into a ListVal before sending. - */ - if (__bro_table_val_has_atomic_key(tbl)) - __bro_table_foreach(tbl->table, (BroTableCallback) __bro_table_val_write_cb_direct, bc); - else - __bro_table_foreach(tbl->table, (BroTableCallback) __bro_table_val_write_cb_unpack, bc); - - D_RETURN_(TRUE); -} - -static int -__bro_table_val_clone(BroTableVal *dst, BroTableVal *src) -{ - D_ENTER; - - if (! __bro_mutable_val_clone((BroMutableVal *) dst, (BroMutableVal *) src)) - D_RETURN_(FALSE); - - if (src->table && ! (dst->table = __bro_table_copy(src->table))) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - -static uint32 -__bro_table_val_hash(BroTableVal *tv) -{ - uint32 result; - - D_ENTER; - - if (! tv) - D_RETURN_(0); - - result = __bro_sobject_hash((BroSObject*) tv->table_type); - result ^= __bro_sobject_hash((BroSObject*) tv->attrs); - result ^= __bro_table_hash(tv->table); - - D_RETURN_(result); - -} - -static int -__bro_table_val_cmp(BroTableVal *tv1, BroTableVal *tv2) -{ - D_ENTER; - - if (! tv1 || ! tv2) - D_RETURN_(FALSE); - - if (! __bro_sobject_cmp((BroSObject*) tv1->table_type, - (BroSObject*) tv2->table_type)) - D_RETURN_(FALSE); - - if (! __bro_table_cmp(tv1->table, tv2->table)) - D_RETURN_(FALSE); - - D_RETURN_(TRUE); -} - -static void * -__bro_table_val_get(BroTableVal *tbl) -{ - return tbl->table; -} - -int -__bro_table_val_has_atomic_key(BroTableVal *tbl) -{ - if (! tbl || ! tbl->table_type) - return FALSE; - - return ((BroIndexType *) tbl->table_type)->indices->num_types == 1; -} diff --git a/aux/broccoli/src/bro_val.h b/aux/broccoli/src/bro_val.h deleted file mode 100644 index 46a758e910..0000000000 --- a/aux/broccoli/src/bro_val.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2008 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_val_h -#define broccoli_val_h - -#include -#include -#include -#include -#include - -typedef void *(* BroValAccessor) (BroVal *val); - -struct bro_val -{ - BroObject object; - - /* A class method for accessing the data contained by - * a val: - */ - BroValAccessor get_data; - - /* The full type object of this val -- this also yields - * what member of the union is used below (unless we're - * inside a derived type and store our data elsewhere). - * If val_type is NULL, it means we're dealing with an - * unassigned val. - */ - BroType *val_type; - - BroRecordVal *val_attrs; - - union { - char char_val; - uint32 int_val; - double double_val; - BroPort port_val; - BroString str_val; - BroSubnet subnet_val; - } val; - -#define val_char val.char_val -#define val_int val.int_val -#define val_double val.double_val -#define val_port val.port_val -#define val_str val.str_val -#define val_strlen val.str_val.str_len -#define val_subnet val.subnet_val -}; - -struct bro_list_val -{ - BroVal val; - - char type_tag; - int len; - - BroList *list; -}; - -struct bro_mutable_val -{ - BroVal val; - - BroID *id; - char props; -}; - -#define BRO_VAL_PROP_PERS 0x01 -#define BRO_VAL_PROP_SYNC 0x02 - -struct bro_record_val -{ - BroMutableVal mutable; - - /* We don't use the full record val when interacting - * with the user, but only what's really necessary. - */ - BroRecord *rec; -}; - -struct bro_table_val -{ - BroMutableVal mutable; - - BroTableType *table_type; - BroAttrs *attrs; - - BroTable *table; -}; - - -BroVal *__bro_val_new(void); -BroVal *__bro_val_new_of_type(int type, const char *type_name); -int __bro_val_assign(BroVal *val, const void *data); - -/* Returns a pointer to the val's data depending on its type. - * Type is returned through *type if provided. - */ -int __bro_val_get_data(BroVal *val, int *type, void **data); -int __bro_val_get_type_num(const BroVal *val); - -BroListVal *__bro_list_val_new(void); - -/* Append a val to the list. This does not duplicate, so adopts the - * given val. - */ -void __bro_list_val_append(BroListVal *lv, BroVal *val); - -/* Removes the first value from the list and returns it. */ -BroVal *__bro_list_val_pop_front(BroListVal *lv); - -/* Only returns the first value from the list. */ -BroVal *__bro_list_val_get_front(BroListVal *lv); -int __bro_list_val_get_length(BroListVal *lv); - -BroMutableVal *__bro_mutable_val_new(void); - -BroRecordVal *__bro_record_val_new(void); - -BroTableVal *__bro_table_val_new(void); -int __bro_table_val_has_atomic_key(BroTableVal *tv); - -#endif diff --git a/aux/broccoli/src/broccoli.h.in b/aux/broccoli/src/broccoli.h.in deleted file mode 100644 index f56f33957a..0000000000 --- a/aux/broccoli/src/broccoli.h.in +++ /dev/null @@ -1,1418 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2007 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#ifndef broccoli_h -#define broccoli_h - -#include -#include -#include -#ifdef __MINGW32__ -#include -#else -#include -#endif -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * bro_debug_calltrace - Debugging output switch for call tracing. - * - * If you have debugging support built in (i.e., your package was configured - * with --enable-debugging), you can enable/disable debugging output for - * call tracing by setting this to 0 (off) or 1 (on). Default is off. - */ -extern int bro_debug_calltrace; - -/** - * bro_debug_messages - Output switch for debugging messages. - * - * If you have debugging support built in (i.e., your package was configured - * with --enable-debugging), you can enable/disable debugging messages - * by setting this to 0 (off) or 1 (on). Default is off. - */ -extern int bro_debug_messages; - -#ifndef FALSE -#define FALSE (0) -#endif - -#ifndef TRUE -#define TRUE (!FALSE) -#endif - -/* Numeric values of Bro type identifiers, corresponding - * to the values of the TypeTag enum in Bro's Type.h. Use - * these values with bro_event_add_val(), bro_record_add_val(), - * bro_record_get_nth_val() and bro_record_get_named_val(). - * - * BRO_TYPE_UNKNOWN is not used in the data exchange, - * see bro_record_get_{nth,named}_val() for its use. - */ -#define BRO_TYPE_UNKNOWN 0 -#define BRO_TYPE_BOOL 1 -#define BRO_TYPE_INT 2 -#define BRO_TYPE_COUNT 3 -#define BRO_TYPE_COUNTER 4 -#define BRO_TYPE_DOUBLE 5 -#define BRO_TYPE_TIME 6 -#define BRO_TYPE_INTERVAL 7 -#define BRO_TYPE_STRING 8 -#define BRO_TYPE_PATTERN 9 -#define BRO_TYPE_ENUM 10 -#define BRO_TYPE_TIMER 11 -#define BRO_TYPE_PORT 12 -#define BRO_TYPE_IPADDR 13 -#define BRO_TYPE_NET 14 -#define BRO_TYPE_SUBNET 15 -#define BRO_TYPE_ANY 16 -#define BRO_TYPE_TABLE 17 -#define BRO_TYPE_UNION 18 -#define BRO_TYPE_RECORD 19 -#define BRO_TYPE_LIST 20 -#define BRO_TYPE_FUNC 21 -#define BRO_TYPE_FILE 22 -#define BRO_TYPE_VECTOR 23 -#define BRO_TYPE_ERROR 24 -#define BRO_TYPE_PACKET 25 /* CAUTION -- not defined in Bro! */ -#define BRO_TYPE_SET 26 /* ----------- (ditto) ---------- */ -#define BRO_TYPE_MAX 27 - -/* Flags for new connections, to pass to bro_conn_new() - * and bro_conn_new_str(). See manual for details. - */ -#define BRO_CFLAG_NONE 0 -#define BRO_CFLAG_RECONNECT (1 << 0) /* Attempt transparent reconnects */ -#define BRO_CFLAG_ALWAYS_QUEUE (1 << 1) /* Queue events sent while disconnected */ -#define BRO_CFLAG_SHAREABLE (1 << 2) /* DO NOT USE -- no longer supported */ -#define BRO_CFLAG_DONTCACHE (1 << 3) /* Ask peer not to use I/O cache (default) */ -#define BRO_CFLAG_YIELD (1 << 4) /* Process just one event at a time */ -#define BRO_CFLAG_CACHE (1 << 5) /* Ask per to use I/O cache */ - - -/* ---------------------------- Typedefs ----------------------------- */ - -@TYPEDEF_UINT@ -typedef unsigned int uint32; -typedef unsigned short uint16; -typedef unsigned char uchar; - -typedef struct bro_conn BroConn; -typedef struct bro_event BroEvent; -typedef struct bro_buf BroBuf; -typedef struct bro_record BroRecord; -typedef struct bro_table BroTable; -typedef struct bro_table BroSet; -typedef struct bro_ev_meta BroEvMeta; -typedef struct bro_packet BroPacket; - -/* ----------------------- Callback Signatures ----------------------- */ - -/** - * BroEventFunc - The signature of expanded event callbacks. - * @bc: Bro connection handle. - * @user_data: user data provided to bro_event_registry_add(). - * @...: varargs. - * - * This is the signature of callbacks for handling received - * Bro events, called in the argument-expanded style. For details - * see bro_event_registry_add(). - */ -typedef void (*BroEventFunc) (BroConn *bc, void *user_data, ...); - -/** - * BroCompactEventFunc - The signature of compact event callbacks. - * @bc: Bro connection handle. - * @user_data: user data provided to bro_event_registry_add_compact(). - * @meta: metadata for the event - * - * This is the signature of callbacks for handling received - * Bro events, called in the compact-argument style. For details - * see bro_event_registry_add_compact(). - */ -typedef void (*BroCompactEventFunc) (BroConn *bc, void *user_data, BroEvMeta *meta); - -typedef void (*BroPacketFunc) (BroConn *bc, void *user_data, - const BroPacket *packet); - -/** - * OpenSSL_lockfunc - locking function for OpenSSL thread safeness. - * @mode: acquire nth lock if (mode & CRYPTO_LOCK) is true, release otherwise. - * @n: lock index. You need to support at least CRYPTO_num_locks(). - * @file: file from which OpenSSL invokes the callback. - * @line: line in file from which OpenSSL invokes the callback. - * - * If you are using Broccoli in a multithreaded environment, you need - * to use bro_init() with a BroCtx structure and use it to point at an - * implementation of this callback. Refer to pages 74ff in O'Reilly's - * OpenSSL book (by Viega et al.) for details. You could also look at - * - * http://www.openssl.org/support/faq.html#PROG1 - * http://www.openssl.org/docs/crypto/threads.html - * - * but you will only curse OpenSSL even more than you already do after - * reading those. - */ -typedef void (*OpenSSL_lock_func) (int mode, int n, const char *file, int line); - -/** - * OpenSSL_thread_id_func - thread ID function for OpenSSL thread safeness. - * @id: target pointer into which the current thread's numeric ID must be written. - * - * Please refer to pages 74ff in O'Reilly's OpenSSL book, and also see - * the comments for OpenSSL_lockfunc. - */ -typedef unsigned long (*OpenSSL_thread_id_func) (void); - - -/** - * OpenSSL_dynlock_create_func - allocator for dynamic locks, for OpenSSL thread safeness. - * @file: file from which OpenSSL invokes the callback. - * @line: line in file from which OpenSSL invokes the callback. - * - * Please refer to pages 74ff in O'Reilly's OpenSSL book, and also see - * the comments for OpenSSL_lockfunc(). - */ -typedef struct CRYPTO_dynlock_value* (*OpenSSL_dynlock_create_func) (const char *file, int line); - -/** - * OpenSSL_dynlock_lock_func - lock/unlock dynamic locks, for OpenSSL thread safeness. - * @mode: acquire nth lock if (mode & CRYPTO_LOCK) is true, release otherwise. - * @mutex: lock to lock/unlock. - * @file: file from which OpenSSL invokes the callback. - * @line: line in file from which OpenSSL invokes the callback. - * - * Please refer to pages 74ff in O'Reilly's OpenSSL book, and also see - * the comments for OpenSSL_lockfunc(). - */ -typedef void (*OpenSSL_dynlock_lock_func) (int mode, struct CRYPTO_dynlock_value *mutex, - const char *file, int line); - -/** - * OpenSSL_dynlock_free_func - dynamic lock deallocator, for OpenSSL thread safeness. - * @mutex: lock to deallocate. - * @file: file from which OpenSSL invokes the callback. - * @line: line in file from which OpenSSL invokes the callback. - * - * Please refer to pages 74ff in O'Reilly's OpenSSL book, and also see - * the comments for OpenSSL_lockfunc(). - */ -typedef void (*OpenSSL_dynlock_free_func) (struct CRYPTO_dynlock_value *mutex, - const char *file, int line); - - -/* ---------------------------- Structures --------------------------- */ - - -/* Initialization context for the Broccoli library. */ -typedef struct bro_ctx { - OpenSSL_lock_func lock_func; - OpenSSL_thread_id_func id_func; - OpenSSL_dynlock_create_func dl_create_func; - OpenSSL_dynlock_lock_func dl_lock_func; - OpenSSL_dynlock_free_func dl_free_func; -} BroCtx; - -/* Statistical properties of a given connection. */ -typedef struct bro_conn_stats { - int tx_buflen; // Number of bytes to process in output buffer. - int rx_buflen; // Number of bytes to process in input buffer. -} BroConnStats; - -/* BroStrings are used to access string parameters in received events. - */ -typedef struct bro_string { - uint32 str_len; - uchar *str_val; -} BroString; - -/* Ports in Broccoli do not only consist of a number but also indicate - * whether they are TCP or UDP. - */ -typedef struct bro_port { - uint16 port_num; /* port number in host byte order */ - int port_proto; /* IPPROTO_xxx */ -} BroPort; - -/* Subnets are a 4-byte address with a prefix width in bits. - */ -typedef struct bro_subnet -{ - uint32 sn_net; /* IP address in network byte order */ - uint32 sn_width; /* Length of prefix to consider. */ -} BroSubnet; - -/* Encapsulation of arguments passed to an event callback, - * for the compact style of argument passing. - */ -typedef struct bro_ev_arg -{ - void *arg_data; /* Pointer to the actual event argument */ - int arg_type; /* A BRO_TYPE_xxx constant */ -} BroEvArg; - -/* Metadata for an event, passed to callbacks of the BroCompactEventFunc - * prototype. - */ -struct bro_ev_meta -{ - const char *ev_name; /* The name of the event */ - double ev_ts; /* Timestamp of event, taken from BroEvent itself */ - int ev_numargs; /* How many arguments are passed */ - BroEvArg *ev_args; /* Array of BroEvArgs, one for each argument */ - const uchar *ev_start; /* Start and end pointers to serialized version */ - const uchar *ev_end; /* of currently processed event. */ -}; - -@BRO_PCAP_SUPPORT@ -#ifdef BRO_PCAP_SUPPORT -#include - -/* Broccoli can send and receive pcap-captured packets, wrapped into - * the following structure: - */ -struct bro_packet -{ - double pkt_time; - uint32 pkt_hdr_size; - uint32 pkt_link_type; - - struct pcap_pkthdr pkt_pcap_hdr; - const u_char *pkt_data; - const char *pkt_tag; - -}; - -#endif - -/* ============================ API ================================== */ - -/* -------------------------- Initialization ------------------------- */ - -/** - * bro_init - Initializes the library. - * @ctx: pointer to a BroCtx structure. - * - * The function initializes the library. It MUST be called before - * anything else in Broccoli. Specific initialization context may be - * provided using a BroCtx structure pointed to by ctx. It may be - * omitted by passing %NULL, for default values. See bro_init_ctx() for - * initialization of the context structure to default values. - * - * Returns: %TRUE if initialization succeeded, %FALSE otherwise. - */ -int bro_init(const BroCtx *ctx); - - -/** - * bro_ctx_init - Initializes initialization context to default values. - * @ctx: pointer to a BroCtx structure. - */ -void bro_ctx_init(BroCtx *ctx); - - -/* ----------------------- Connection Handling ----------------------- */ - -/** - * bro_conn_new - Creates and returns a handle for a connection to a remote Bro. - * @ip_addr: 4-byte IP address of Bro to contact, in network byte order. - * @port: port of machine at @ip_addr to contact, in network byte order. - * @flags: an or-combination of the %BRO_CONN_xxx flags. - * - * The function creates a new Bro connection handle for communication with - * Bro through a network. Depending on the flags passed in, the connection - * and its setup process can be adjusted. If you don't want to pass any - * flags, use %BRO_CFLAG_NONE. - * - * Returns: pointer to a newly allocated and initialized - * Bro connection structure. You need this structure for all - * other calls in order to identify the connection to Bro. - */ -BroConn *bro_conn_new(struct in_addr *ip_addr, uint16 port, int flags); - - -/** - * bro_conn_new_str - Same as bro_conn_new(), but accepts strings for hostname and port. - * @hostname: string describing the host and port to connect to. - * @flags: an or-combination of the %BRO_CONN_xxx flags. - * - * The function is identical to bro_conn_new(), but allows you to specify the - * host and port to connect to in a string as ":". @flags can - * be used to adjust the connection features and the setup process. If you don't - * want to pass any flags, use %BRO_CFLAG_NONE. - * - * Returns: pointer to a newly allocated and initialized - * Bro connection structure. You need this structure for all - * other calls in order to identify the connection to Bro. - */ -BroConn *bro_conn_new_str(const char *hostname, int flags); - -/** - * bro_conn_new_socket - Same as bro_conn_new(), but uses existing socket. - * @socket: open socket. - * @flags: an or-combination of the %BRO_CONN_xxx flags. - * - * The function is identical to bro_conn_new(), but allows you to pass in an - * open socket to use for the communication. @flags can be used to - * adjust the connection features and the setup process. If you don't want to - * pass any flags, use %BRO_CFLAG_NONE. - * - * Returns: pointer to a newly allocated and initialized - * Bro connection structure. You need this structure for all - * other calls in order to identify the connection to Bro. - */ -BroConn *bro_conn_new_socket(int socket, int flags); - -/** - * bro_conn_set_class - Sets a connection's class identifier. - * @bc: connection handle. - * @classname: class identifier. - * - * Broccoli connections can indicate that they belong to a certain class - * of connections, which is needed primarily if multiple Bro/Broccoli - * instances are running on the same node and connect to a single remote - * peer. You can set this class with this function, and you have to do so - * before calling bro_connect() since the connection class is determined - * upon connection establishment. You remain responsible for the memory - * pointed to by @classname. - */ -void bro_conn_set_class(BroConn *bc, const char *classname); - -/** - * bro_conn_get_peer_class - Reports connection class indicated by peer. - * @bc: connection handle. - * - * Returns: a string containing the connection class indicated by the peer, - * if any, otherwise %NULL. - */ -const char *bro_conn_get_peer_class(const BroConn *bc); - - -/** - * bro_conn_get_connstats - Reports connection properties. - * @bc: connection handle. - * @cs: BroConnStats handle. - * - * The function fills the BroConnStats structure provided via @cs with - * information about the given connection. - */ -void bro_conn_get_connstats(const BroConn *bc, BroConnStats *cs); - - -/** - * bro_conn_connect - Establish connection to peer. - * @bc: connection handle. - * - * The function attempts to set up and configure a connection to - * the peer configured when the connection handle was obtained. - * - * Returns: %TRUE on success, %FALSE on failure. - */ -int bro_conn_connect(BroConn *bc); - - -/** - * bro_conn_reconnect - Drop the current connection and reconnect, reusing all settings. - * @bc: Bro connection handle. - * - * The functions drops the current connection identified by @bc and attempts to - * establish a new one with all the settings associated with @bc, including full - * handshake completion. - * - * Returns: %TRUE if successful, %FALSE otherwise. No matter what the outcome, - * you can continue to use @bc as normal (e.g. you have to release it using - * bro_conn_delete()). - */ -int bro_conn_reconnect(BroConn *bc); - - -/** - * bro_conn_delete - terminates and releases connection. - * @bc: Bro connection handle - * - * This function will terminate the given connection if necessary - * and release all resources associated with the connection handle. - * - * - * Returns: %FALSE on error, %TRUE otherwise. - */ -int bro_conn_delete(BroConn *bc); - - -/** - * bro_conn_alive - Reports whether a connection is currently alive or has died. - * @bc: Bro connection handle. - - * This predicate reports whether the connection handle is currently - * usable for sending/receiving data or not, e.g. because the peer - * died. The function does not actively check and update the - * connection's state, it only reports the value of flags indicating - * its status. In particular, this means that when calling - * bro_conn_alive() directly after a select() on the connection's - * descriptor, bro_conn_alive() may return an incorrent value. It will - * however return the correct value after a subsequent call to - * bro_conn_process_input(). Also note that the connection is also - * dead after the connection handle is obtained and before - * bro_conn_connect() is called. - * - * Returns: %TRUE if the connection is alive, %FALSE otherwise. - */ -int bro_conn_alive(const BroConn *bc); - - -/** - * bro_conn_adopt_events - Makes one connection send out the same events as another. - * @src: Bro connection handle for connection whose event list to adopt. - * @dst: Bro connection handle for connection whose event list to change. - * - * The function makes the connection identified by @dst use the same event - * mask as the one identified by @src. - */ -void bro_conn_adopt_events(BroConn *src, BroConn *dst); - - -/** - * bro_conn_get_fd - Returns file descriptor of a Bro connection. - * @bc: Bro connection handle. - * - * If you need to know the file descriptor of the connection - * (such as when select()ing it etc), use this accessor function. - * - * Returns: file descriptor for connection @bc, or negative value - * on error. - */ -int bro_conn_get_fd(BroConn *bc); - - -/** - * bro_conn_process_input - Processes input sent to the sensor by Bro. - * @bc: Bro connection handle - * - * The function reads all input sent to the local sensor by the - * Bro peering at the connection identified by @bc. It is up - * to you to find a spot in the application you're instrumenting - * to make sure this is called. This function cannot block. - * bro_conn_alive() will report the actual state of the connection - * after a call to bro_conn_process_input(). - * - * Returns: %TRUE if any input was processed, %FALSE otherwise. - */ -int bro_conn_process_input(BroConn *bc); - - -/* ---------------------- Connection data storage -------------------- */ - -/* Connection handles come with a faciity to store and retrieve - * arbitrary data items. Use the following functions to store, - * query, and remove items from a connection handle. - */ - -/** - * bro_conn_data_set - Puts a data item into the registry. - * @bc: Bro connection handle. - * @key: name of the data item. - * @val: data item. - * - * The function stores @val under name @key in the connection handle @bc. - * @key is copied internally so you do not need to duplicate it before - * passing. - */ -void bro_conn_data_set(BroConn *bc, const char *key, void *val); - - -/** - * bro_conn_data_get - Looks up a data item. - * @bc: Bro connection handle. - * @key: name of the data item. - * - * The function tries to look up the data item with name @key and - * if found, returns it. - * - * Returns: data item if lookup was successful, %NULL otherwise. - */ -void *bro_conn_data_get(BroConn *bc, const char *key); - - -/** - * bro_conn_data_del - Removes a data item. - * @bc: Bro connection handle. - * @key: name of the data item. - * - * The function tries to remove the data item with name @key. - * - * Returns: the removed data item if it exists, %NULL otherwise. - */ -void *bro_conn_data_del(BroConn *bc, const char *key); - - -/* ----------------------------- Bro Events -------------------------- */ - -/** - * bro_event_new - Creates a new empty event with a given name. - * @event_name: name of the Bro event. - * - * The function creates a new empty event with the given - * name and returns it. - * - * Returns: new event, or %NULL if allocation failed. - */ -BroEvent *bro_event_new(const char *event_name); - - -/** - * bro_event_free - Releases all memory associated with an event. - * @be: event to release. - * - * The function releases all memory associated with @be. Note - * that you do NOT have to call this after sending an event. - */ -void bro_event_free(BroEvent *be); - - -/** - * bro_event_add_val - Adds a parameter to an event. - * @be: event to add to. - * @type: numerical type identifier (a %BRO_TYPE_xxx constant). - * @type_name: optional name of specialized type. - * @val: value to add to event. - * - * The function adds the given @val to the argument list of - * event @be. The type of @val is derived from @type, and may be - * specialized to the type named @type_name. If @type_name is not - * desired, use %NULL. - * - * @val remains the caller's responsibility and is copied internally. - * - * Returns: %TRUE if the operation was successful, %FALSE otherwise. - */ -int bro_event_add_val(BroEvent *be, int type, - const char *type_name,const void *val); - - -/** - * bro_event_set_val - Replace a value in an event. - * @be: event handle. - * @val_num: number of the value to replace, starting at 0. - * @type: numerical type identifier (a %BRO_TYPE_xxx constant). - * @type_name: optional name of specialized type. - * @val: value to put in. - * - * The function replaces whatever value is currently stored in the - * event pointed to by @be with the val specified through the @type and - * @val arguments. If the event does not currently hold enough - * values to replace one in position @val_num, the function does - * nothing. If you want to indicate a type specialized from @type, - * use @type_name to give its name, otherwise pass %NULL for @type_name. - * - * Returns: %TRUE if successful, %FALSE on error. - */ -int bro_event_set_val(BroEvent *be, int val_num, - int type, const char *type_name, - const void *val); - -/** - * bro_event_send - Tries to send an event to a Bro agent. - * @bc: Bro connection handle - * @be: event to send. - * - * The function tries to send @be to the Bro agent connected - * through @bc. Regardless of the outcome, you do NOT have - * to release the event afterwards using bro_event_free(). - * - * Returns: %TRUE if the event got sent or queued for later transmission, - * %FALSE on error. There are no automatic repeated send attempts - * (to minimize the effect on the code that Broccoli is linked to). - * If you have to make sure that everything got sent, you have - * to try to empty the queue using bro_event_queue_flush(), and - * also look at bro_event_queue_empty(). - */ -int bro_event_send(BroConn *bc, BroEvent *be); - - -/** - * bro_event_send_raw - Enqueues a serialized event directly into a connection's send buffer. - * @bc: Bro connection handle - * @data: pointer to serialized event data. - * @data_len: length of buffer pointed to by @data. - * - * The function enqueues the given event data into @bc's transmit buffer. - * @data_len bytes at @data must correspond to a single event. - * - * Returns: %TRUE if successful, %FALSE on error. - */ -int bro_event_send_raw(BroConn *bc, const uchar *data, int data_len); - - -/** - * bro_event_queue_length - Returns current queue length. - * @bc: Bro connection handle - * - * Use this function to find out how many events are currently queued - * on the client side. - * - * Returns: number of items currently queued. - */ -int bro_event_queue_length(BroConn *bc); - - -/** - * bro_event_queue_length_max - Returns maximum queue length. - * @bc: Bro connection handle - * - * Use this function to find out how many events can be queued before - * events start to get dropped. - * - * Returns: maximum possible queue size. - */ -int bro_event_queue_length_max(BroConn *bc); - - -/** - * bro_event_queue_flush - Tries to flush the send queue of a connection. - * @bc: Bro connection handle - * - * The function tries to send as many queued events to the Bro - * agent as possible. - * - * Returns: remaining queue length after flush. - */ -int bro_event_queue_flush(BroConn *bc); - - -/* ------------------------ Bro Event Callbacks ---------------------- */ - -/** - * bro_event_registry_add - Adds an expanded-argument event callback to the event registry. - * @bc: Bro connection handle - * @event_name: Name of events that trigger callback - * @func: callback to invoke. - * @user_data: user data passed through to the callback. - * - * This function registers the callback @func to be invoked when events - * of name @event_name arrive on connection @bc. @user_data is passed along - * to the callback, which will receive it as the second parameter. You - * need to ensure that the memory @user_data points to is valid during the - * time the callback might be invoked. - * - * Note that this function only registers the callback in the state - * associated with @bc. If you use bro_event_registry_add() and @bc - * has not yet been connected via bro_conn_connect(), then no further - * action is required. bro_conn_connect() request ant registered event types. - * If however you are requesting additional event types after the connection has - * been established, then you also need to call bro_event_registry_request() - * in order to signal to the peering Bro that you want to receive those events. - */ -void bro_event_registry_add(BroConn *bc, - const char *event_name, - BroEventFunc func, - void *user_data); - -/** - * bro_event_registry_add_compact - Adds a compact-argument event callback to the event registry. - * @bc: Bro connection handle - * @event_name: Name of events that trigger callback - * @func: callback to invoke. - * @user_data: user data passed through to the callback. - * - * This function registers the callback @func to be invoked when events - * of name @event_name arrive on connection @bc. @user_data is passed along - * to the callback, which will receive it as the second parameter. You - * need to ensure that the memory @user_data points to is valid during the - * time the callback might be invoked. See bro_event_registry_add() for - * details. - */ -void bro_event_registry_add_compact(BroConn *bc, - const char *event_name, - BroCompactEventFunc func, - void *user_data); - -/** - * bro_event_registry_remove - Removes an event handler. - * @bc: Bro connection handle - * @event_name: event to ignore from now on. - * - * The function removes all callbacks for event @event_name from the - * event registry for connection @bc. - */ -void bro_event_registry_remove(BroConn *bc, const char *event_name); - -/** - * bro_event_registry_request - Notifies peering Bro to send events. - * @bc: Bro connection handle - * - * The function requests the events you have previously requested using - * bro_event_registry_add() from the Bro listening on @bc. - */ -void bro_event_registry_request(BroConn *bc); - - - -/* ------------------------ Dynamic-size Buffers --------------------- */ - -/** - * bro_buf_new - Creates a new buffer object. - * - * Returns a new buffer object, or %NULL on error. Use paired with - * bro_buf_free(). - */ -BroBuf *bro_buf_new(void); - -/** - * bro_buf_free - Releases a dynamically allocated buffer object. - * @buf: buffer pointer. - * - * The function releases all memory held by the buffer pointed - * to by @buf. Use paired with bro_buf_new(). - */ -void bro_buf_free(BroBuf *buf); - -/** - * bro_buf_append - appends data to the end of the buffer. - * @buf: buffer pointer. - * @data: new data to append to buffer. - * @data_len: size of @data. - * - * The function appends data to the end of the buffer, - * enlarging it if necessary to hold the @len new bytes. - * NOTE: it does not modify the buffer pointer. It only - * appends new data where buf_off is currently pointing - * and updates it accordingly. If you DO want the buffer - * pointer to be updated, have a look at bro_buf_ptr_write() - * instead. - * - * Returns: %TRUE if successful, %FALSE otherwise. - */ -int bro_buf_append(BroBuf *buf, void *data, int data_len); - - -/** - * bro_buf_consume - shrinks the buffer. - * @buf: buffer pointer. - * - * The function removes the buffer contents between the start - * of the buffer and the point where the buffer pointer - * currently points to. The idea is that you call bro_buf_ptr_read() - * a few times to extract data from the buffer, and then - * call bro_buf_consume() to signal to the buffer that the - * extracted data are no longer needed inside the buffer. - */ -void bro_buf_consume(BroBuf *buf); - - -/** - * bro_buf_reset - resets the buffer. - * @buf: buffer pointer. - * - * The function resets the buffer pointers to the beginning of the - * currently allocated buffer, i.e., it marks the buffer as empty. - */ -void bro_buf_reset(BroBuf *buf); - - -/** - * bro_buf_get - Returns pointer to actual start of buffer. - * @buf: buffer pointer. - * - * Returns the entire buffer's contents. - */ -uchar *bro_buf_get(BroBuf *buf); - - -/** - * bro_buf_get_end - Returns pointer to the end of the buffer. - * @buf: buffer pointer. - * - * Returns: a pointer to the first byte in the - * buffer that is not currently used. - */ -uchar *bro_buf_get_end(BroBuf *buf); - - -/** - * bro_buf_get_size - Returns number of bytes allocated for buffer. - * @buf: buffer pointer. - * - * Returns: the number of actual bytes allocated for the - * buffer. - */ -uint bro_buf_get_size(BroBuf *buf); - - -/** - * bro_buf_get_used_size - Returns number of bytes currently used. - * @buf: buffer pointer. - * - * Returns: number of bytes currently used. - */ -uint bro_buf_get_used_size(BroBuf *buf); - - -/** - * bro_buf_ptr_get - Returns current buffer content pointer. - * @buf: buffer pointer. - * - * Returns: current buffer content pointer. - */ -uchar *bro_buf_ptr_get(BroBuf *buf); - - -/** - * bro_buf_ptr_tell - Returns current offset of buffer content pointer. - * @buf: buffer pointer. - * - * Returns: current offset of buffer content pointer. - */ -uint32 bro_buf_ptr_tell(BroBuf *buf); - - -/** - * bro_buf_ptr_seek - Adjusts buffer content pointer. - * @buf: buffer pointer. - * @offset: number of bytes by which to adjust pointer, positive or negative. - * @whence: location relative to which to adjust. - * - * The function adjusts the position of @buf's content - * pointer. Call semantics are identical to fseek(), thus - * use @offset to indicate the offset by which to jump and - * use %SEEK_SET, %SEEK_CUR, or %SEEK_END to specify the - * position relative to which to adjust. - * - * Returns: %TRUE if adjustment could be made, %FALSE - * if not (e.g. because the offset requested is not within - * legal bounds). - */ -int bro_buf_ptr_seek(BroBuf *buf, int offset, int whence); - - -/** - * bro_buf_ptr_check - Checks whether a number of bytes can be read. - * @buf: buffer pointer. - * @size: number of bytes to check for availability. - * - * The function checks whether @size bytes could be read from the - * buffer using bro_buf_ptr_read(). - * - * Returns: %TRUE if @size bytes can be read, %FALSE if not. - */ -int bro_buf_ptr_check(BroBuf *buf, int size); - - -/** - * bro_buf_ptr_read - Extracts a number of bytes from buffer. - * @buf: buffer pointer. - * @data: destination area. - * @size: number of bytes to copy into @data. - * - * The function copies @size bytes into @data if the buffer - * has @size bytes available from the current location of - * the buffer content pointer onward, incrementing the content - * pointer accordingly. If not, the function doesn't do anything. - * It behaves thus different from the normal read() in that - * it either copies the amount requested or nothing. - * - * Returns: %TRUE if @size bytes were copied, %FALSE if not. - */ -int bro_buf_ptr_read(BroBuf *buf, void *data, int size); - -/** - * bro_buf_ptr_write - Writes a number of bytes into buffer. - * @buf: buffer pointer. - * @data: data to write. - * @size: number of bytes to copy into @data. - * - * The function writes @size bytes of the area pointed to by @data - * into the buffer @buf at the current location of its content pointer, - * adjusting the content pointer accordingly. If the buffer doesn't have - * enough space to receive @size bytes, more space is allocated. - * - * Returns: %TRUE if @size bytes were copied, %FALSE if an error - * occurred and the bytes could not be copied. - */ -int bro_buf_ptr_write(BroBuf *buf, void *data, int size); - - -/* ------------------------ Configuration Access --------------------- */ - -/** - * bro_conf_set_domain - Sets the current domain to use in a config file. - * @domain: name of the domain, or %NULL. - * - * Broccoli's config files are divided into sections. At the beginning of - * each config file you can have an unnamed section that will be used by - * default. Case is irrelevant. By passing %NULL for @domain, you select - * the default domain, otherwise the one that matches @domain. @domain is - * copied internally. - */ -void bro_conf_set_domain(const char *domain); - - -/** - * bro_conf_get_int - Retrieves an integer from the configuration - * @val_name: key name for the value. - * @val: result pointer for the value. - * - * The function tries to find an integer item named @val_name in the - * configuration. If it is found, its value is placed into the - * int pointed to by @val. - * - * Returns: %TRUE if @val_name was found, %FALSE otherwise. - */ -int bro_conf_get_int(const char *val_name, int *val); - - -/** - * bro_conf_get_dbl - Retrieves a double float from the configuration - * @val_name: key name for the value. - * @val: result pointer for the value. - * - * The function tries to find a double float item named @val_name - * in the configuration. If it is found, its value is placed into the - * double pointed to by @val. - * - * Returns: %TRUE if @val_name was found, %FALSE otherwise. - */ -int bro_conf_get_dbl(const char *val_name, double *val); - - -/** - * bro_conf_get_str - Retrieves an integer from the configuration - * @val_name: key name for the value. - * - * The function tries to find a string item named @val_name in the - * configuration. - * - * Returns: the config item if @val_name was found, %NULL otherwise. - * A returned string is stored internally and not to be modified. If - * you need to keep it around, strdup() it. - */ -const char *bro_conf_get_str(const char *val_name); - - - -/* ------------------------------ Strings ---------------------------- */ - -/** - * bro_string_init - Initializes an existing string structure. - * @bs: string pointer. - * - * The function initializes the BroString pointed to by @bs. Use this - * function before using the members of a BroString you're using on the - * stack. - */ -void bro_string_init(BroString *bs); - -/** - * bro_string_set - Sets a BroString's contents. - * @bs: string pointer. - * @s: C ASCII string. - * - * The function initializes the BroString pointed to by @bs to the string - * given in @s. @s's content is copied, so you can modify or free @s - * after calling this, and you need to call bro_string_cleanup() on the - * BroString pointed to by @bs. - * - * Returns: %TRUE is successful, %FALSE otherwise. - */ -int bro_string_set(BroString *bs, const char *s); - -/** - * bro_string_set_data - Sets a BroString's contents. - * @bs: string pointer. - * @data: arbitrary data. - * @data_len: length of @data. - * - * The function initializes the BroString pointed to by @bs to @data_len - * bytes starting at @data. @data's content is copied, so you can modify - * or free @data after calling this. - * - * Returns: %TRUE is successful, %FALSE otherwise. - */ -int bro_string_set_data(BroString *bs, const uchar *data, int data_len); - -/** - * bro_string_get_data - Returns pointer to the string data. - * @bs: string pointer. - * - * The function returns a pointer to the string's internal data. You - * can copy out the string using this function in combination with - * bro_string_get_length(), for obtaining the string's length. - * - * Returns: pointer to string, or %NULL on error. - */ -const uchar *bro_string_get_data(const BroString *bs); - -/** - * bro_string_get_length - Returns string's length. - * @bs: string pointer. - * - * Returns: the string's length. - */ -uint32 bro_string_get_length(const BroString *bs); - -/** - * bro_string_copy - Duplicates a BroString. - * @bs: string pointer. - * - * Returns: a deep copy of the BroString pointed to by @bs, or %NULL on - * error. - */ -BroString *bro_string_copy(BroString *bs); - -/** - * bro_string_assign - Duplicates a BroString's content, assigning it to an existing one. - * @src: source string. - * @dst: target string. - * - * Copies the string content pointed to by @src into the existing - * BroString pointed to by @dst. bro_string_cleanup() is called on - * @dst before the assignment. - */ -void bro_string_assign(BroString *src, BroString *dst); - -/** - * bro_string_cleanup - Cleans up existing BroString. - * @bs: string pointer. - * - * This function releases all contents claimed by the BroString pointed - * to by @bs, without releasing that BroString structure itself. Use - * this when manipulating a BroString on the stack, paired with - * bro_string_init(). - */ -void bro_string_cleanup(BroString *bs); - -/** - * bro_string_free - Cleans up dynamically allocated BroString. - * @bs: string pointer. - * - * This function releases the entire BroString pointed to by @bs, including - * the BroString structure itself. - */ -void bro_string_free(BroString *bs); - - -/* -------------------------- Record Handling ------------------------ */ - -/** - * bro_record_new - Creates a new record. - * - * The function allocates and initializes a new empty record. BroRecords - * are used for adding and retrieving records vals to/from events. You - * do not have to specify a record type separately when you create a - * record. The type is defined implicitly by the sequence of types formed - * by the sequence of vals added to the record, along with the names for - * each val. See the manual for details. - * - * Returns: a new record, or %NULL on error. - */ -BroRecord *bro_record_new(void); - -/** - * bro_record_free - Releases a record. - * @rec: record handle. - * - * The function releases all memory consumed by the record pointed to - * by @rec. - */ -void bro_record_free(BroRecord *rec); - -/** - * bro_record_get_length - Returns number of fields in record. - * @rec: record handle. - * - * Returns the number of fields in the record. - */ -int bro_record_get_length(BroRecord *rec); - -/** - * bro_record_add_val - Adds a val to a record. - * @rec: record handle. - * @name: field name of the added val. - * @type: numerical type tag of the new val. - * @type_name: optional name of specialized type. - * @val: pointer to the new val*. - * - * The function adds a new field to the record pointed to by @rec and - * assigns the value passed in to that field. The field name is given - * in @name, the type of the val is given in @type and must be one of - * the %BRO_TYPE_xxx constants defined in broccoli.h. The type you give - * implies what data type @val must be pointing to; see the manual for - * details. If you want to indicate a type specialized from @type, - * use @type_name to give its name, otherwise pass %NULL for @type_name. - * It is possible to leave fields unassigned, in that case, pass in - * %NULL for @val. - * - * @val remains the caller's responsibility and is copied internally. - * - * Returns: %TRUE on success, %FALSE on error. - */ -int bro_record_add_val(BroRecord *rec, const char *name, - int type, const char *type_name, - const void *val); - -/** - * bro_record_get_nth_val - Retrieves a val from a record by field index. - * @rec: record handle. - * @num: field index, starting from 0. - * @type: value-result argument for the expected/actual type of the value. - * - * The function returns the @num'th value of the record pointed to - * by @rec, expected to be of @type. The returned value is internal - * and needs to be duplicated if you want to keep it around. Upon - * return, the int pointed to by @type tells you the type of the returned - * val, as a BRO_TYPE_xxx type tag. If the int pointed to upon calling - * the function has the value BRO_TYPE_UNKNOWN, no type checking is - * performed and the value is returned. If it is any other type tag, - * its value is compared to that of the value, and if they match, the - * value is returned. Otherwise, the return value is %NULL. If you don't - * care about type enforcement and don't want to know the value's type, - * you may pass %NULL for @type. - * - * Returns: pointer to queried value on success, %NULL on error. - */ -void* bro_record_get_nth_val(BroRecord *rec, int num, int *type); - - -/** - * bro_record_get_nth_name - Retrieves a name from a record by field index. - * @rec: record handle. - * @num: field index, starting from 0. - * - * The function returns the @num'th name of the record pointed to by @rec. - * - * Returns: field name on success, %NULL on error. - */ -const char* bro_record_get_nth_name(BroRecord *rec, int num); - - -/** - * bro_record_get_named_val - Retrieves a val from a record by field name. - * @rec: record handle. - * @name: field name. - * @type: value-result argument for the expected/actual type of the value. - * - * The function returns the value of the field named @name in the - * record pointed to by @rec. The returned value is internal and needs - * to be duplicated if you want to keep it around. @type works as with - * bro_record_get_nth_val(), see there for more details. - * - * Returns: pointer to queried value on success, %NULL on error. - */ -void* bro_record_get_named_val(BroRecord *rec, const char *name, int *type); - - -/** - * bro_record_set_nth_val - Replaces a val in a record, identified by field index. - * @rec: record handle. - * @num: field index, starting from 0. - * @type: expected type of the value. - * @type_name: optional name of specialized type. - * @val: pointer to new val. - * - * The function replaces the @num'th value of the record pointed to - * by @rec, expected to be of @type. All values are copied internally - * so what @val points to stays unmodified. The value of @type implies - * what @result must be pointing to. See the manual for details. - * If you want to indicate a type specialized from @type, use - * @type_name to give its name, otherwise pass %NULL for @type_name. - * - * Returns: %TRUE on success, %FALSE on error. - */ -int bro_record_set_nth_val(BroRecord *rec, int num, - int type, const char *type_name, - const void *val); - -/** - * bro_record_set_named_val - Replaces a val in a record, identified by name. - * @rec: record handle. - * @name: field name. - * @type: expected type of the value. - * @type_name: optional name of specialized type. - * @val: pointer to new val. - * - * The function replaces the value named @name in the record pointed to - * by @rec, expected to be of @type. All values are copied internally - * so what @val points to stays unmodified. The value of @type implies - * what @result must be pointing to. See the manual for details. - * If you want to indicate a type specialized from @type, - * use @type_name to give its name, otherwise pass %NULL for @type_name. - * - * Returns: %TRUE on success, %FALSE on error. - */ -int bro_record_set_named_val(BroRecord *rec, const char *name, - int type, const char *type_name, - const void *val); - - -/* -------------------------- Tables & Sets -------------------------- */ - -/** - * BroTableCallback - The signature of callbacks for iterating over tables. - * @key: a pointer to the key of a key-value pair. - * @val: a pointer to @key's corresponding value. - * @user_data: user data passed through. - * - * This is the signature of callbacks used when iterating over all - * elements stored in a BroTable. - * - * Returns: TRUE if iteration should continue, FALSE if done. - */ -typedef int (*BroTableCallback) (void *key, void *val, void *user_data); - - -BroTable *bro_table_new(void); -void bro_table_free(BroTable *tbl); - -int bro_table_insert(BroTable *tbl, - int key_type, const void *key, - int val_type, const void *val); - -void *bro_table_find(BroTable *tbl, const void *key); - -int bro_table_get_size(BroTable *tbl); - -void bro_table_foreach(BroTable *tbl, BroTableCallback cb, - void *user_data); - -void bro_table_get_types(BroTable *tbl, - int *key_type, int *val_type); - - -/** - * BroTableCallback - The signature of callbacks for iterating over sets. - * @val: a pointer to an element in the set. - * @user_data: user data passed through. - * - * This is the signature of callbacks used when iterating over all - * elements stored in a BroSet. - * - * Returns: TRUE if iteration should continue, FALSE if done. - */ -typedef int (*BroSetCallback) (void *val, void *user_data); - -BroSet *bro_set_new(void); -void bro_set_free(BroSet *set); - -int bro_set_insert(BroSet *set, int type, const void *val); - -int bro_set_find(BroSet *set, const void *key); - -int bro_set_get_size(BroSet *set); - -void bro_set_foreach(BroSet *set, BroSetCallback cb, - void *user_data); - -void bro_set_get_type(BroSet *set, int *type); - - -/* ----------------------- Pcap Packet Handling ---------------------- */ -#ifdef BRO_PCAP_SUPPORT - -/** - * bro_conn_set_packet_ctxt - Sets current packet context for connection. - * @bc: connection handle. - * @link_type: libpcap DLT linklayer type. - * - * The function sets the packet context for @bc for future BroPackets - * handled by this connection. - */ -void bro_conn_set_packet_ctxt(BroConn *bc, int link_type); - -/** - * bro_conn_get_packet_ctxt - Gets current packet context for connection. - * @bc: connection handle. - * @link_type: result pointer for libpcap DLT linklayer type. - * - * The function returns @bc's current packet context through @link_type. - */ -void bro_conn_get_packet_ctxt(BroConn *bc, int *link_type); - -/** - * bro_packet_new - Creates new packet. - * @hdr: pointer to libpcap packet header. - * @data: pointer to libpcap packet data. - * @tag: pointer to ASCII tag (0 for no tag). - * - * The function creates a new BroPacket by copying @hdr and @data internally. - * Release the resulting packet using bro_packet_free(). - */ -BroPacket *bro_packet_new(const struct pcap_pkthdr *hdr, const u_char *data, const char* tag); - -/** - * bro_packet_clone - Clones a packet. - * @packet: packet to clone. - * - * Returns: a copy of @packet, or %NULL on error. - */ -BroPacket *bro_packet_clone(const BroPacket *packet); - -/** - * bro_packet_free - Releases a packet. - * @packet: packet to release. - * - * The function releases all memory occupied by a packet previously allocated - * using bro_packet_new(). - */ -void bro_packet_free(BroPacket *packet); - -/** - * bro_packet_send - Sends a packet over a given connection. - * @bc: connection on which to send packet. - * @packet: packet to send. - * - * The function sends @packet to the Bro peer connected via @bc. - * - * Returns: %TRUE if successful, %FALSE otherwise. - */ -int bro_packet_send(BroConn *bc, BroPacket *packet); - -#endif - -/* --------------------------- Miscellaneous ------------------------- */ - -/** - * bro_util_current_time - Gets current time - * - * Returns: the current system time as a double, in seconds, suitable - * for passing to bro_event_add_time(). - */ -double bro_util_current_time(void); - -/** - * bro_util_timeval_to_double - Converts timeval struct to double. - * @tv: pointer to timeval structure. - * - * Returns: a double encoding the timestamp given in @tv in a floating - * point double, with the fraction of a second between 0.0 and 1.0. - */ -double bro_util_timeval_to_double(const struct timeval *tv); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/aux/broccoli/svn.pl b/aux/broccoli/svn.pl deleted file mode 100755 index 581593f615..0000000000 --- a/aux/broccoli/svn.pl +++ /dev/null @@ -1,183 +0,0 @@ -#!/usr/bin/perl -w - -# CVS/SVN wrapper script that maintains a nice ChangeLog for us. -# Heavily hacked & cleaned up, originally based upon a script -# that was once used in the Enlightenment project. - -use strict; -use FileHandle; - - -# Prototypes -#_______________________________________________________________________ - -sub create_changelog; -sub validate_commit_message; -sub create_commit_message; -sub setup_username_translation; -sub update_changelog; -sub check_parameters; - - -# Globals -#_______________________________________________________________________ -my %names; -my ($date, $author); - -# Formats -#_______________________________________________________________________ -format ENTRY = -@<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< @>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> -$date, $author -. - - -# Subroutines -#_______________________________________________________________________ - -sub setup_username_translation { - - $names{"kreibich"} = "Christian "; - $names{"cpk25"} = "Christian "; - $names{"christian"} = "Christian "; -} - - - -sub create_changelog { - - my $cl = "ChangeLog"; - my $num_lines; - my $wc; - my @lines; - my @commitlines; - my $line; - - print "Updating the ChangeLog with your entry.\n"; - - if (open CHANGELOG, $cl) { - @lines = ; - close CHANGELOG; - - shift (@lines); - shift (@lines); - } - - - open CHANGELOG, ">$cl"; - print CHANGELOG <; - close COMMITLOG; - } - - CHANGELOG->format_name("ENTRY"); - $date = `date`; - $author = $names{$ENV{USER}}; - write CHANGELOG; - CHANGELOG->format_name(); - print CHANGELOG "\n"; - print CHANGELOG @commitlines; - print CHANGELOG "\n------------------------------------------------------------------------\n"; - print CHANGELOG @lines; - close CHANGELOG; -} - -sub create_commit_message { - - print "Please create a log message for the ChangeLog.\n"; - - if (open COMMITLOG, ">CommitLog") { - print COMMITLOG "-" x 72; - print COMMITLOG "\n"; - close COMMITLOG; - } - - if($ENV{EDITOR}) { - system("$ENV{EDITOR} CommitLog"); - } else { - system("vi CommitLog"); - } -} - - -sub update_changelog { - - my @ARGV2; - - @ARGV2 = @ARGV; - $ARGV2[0] = "update"; - - print "Force updating ChangeLog\n"; - unlink "ChangeLog"; - system("svn update ChangeLog"); -} - - -sub check_parameters { - - if (scalar(@ARGV) < 1) { - print "USAGE: cvs.pl \n"; - exit (0); - } -} - -# Main Program -#_______________________________________________________________________ - -check_parameters(); -setup_username_translation(); - -if (($ARGV[0] =~ /com/) || ($ARGV[0] =~ /ci/)) { - my @ARGV2; - - create_commit_message(); - update_changelog(); - - $ARGV[0] .= " -F CommitLog"; - @ARGV2 = @ARGV; - $ARGV2[0] = "update"; - - print "Updating the files you are committing.\n"; - system("svn @ARGV2 2>&1 |tee errors"); - - if (open ERRORS, "errors") { - - while() { - - if (/conflicts during merge/) { - print "There are one or more conflicts,\n" . - "Please resolve and try again.\n"; - unlink "errors" if(-f "errors"); - exit(0); - } - } - - close ERRORS; - } - - unlink "errors" if(-f "errors"); - create_changelog(); - - if($#ARGV >= 1) { - - my $found; - - $found = 0; - - foreach(@ARGV) { - $found = 1 if(/ChangeLog$/); - } - - push @ARGV, "ChangeLog" if(! $found); - } -} - -print "svn @ARGV\n"; -system("svn @ARGV"); -print "Finished.\n" diff --git a/aux/broccoli/test/Makefile.am b/aux/broccoli/test/Makefile.am deleted file mode 100644 index a41709e187..0000000000 --- a/aux/broccoli/test/Makefile.am +++ /dev/null @@ -1,29 +0,0 @@ -## Process this file with automake to produce Makefile.in - -# A list of all the files in the current directory which can be regenerated -MAINTAINERCLEANFILES = Makefile.in Makefile dummysensor - -INCLUDES = -I$(top_srcdir)/src -W -Wall -Wno-unused - -if BRO_PCAP_SUPPORT -PCAP_TESTS = -else -PCAP_TESTS = -endif - -noinst_PROGRAMS = broping broconn brohose broconftest broenum brotable $(PCAP_TESTS) - -LDADD = $(top_builddir)/src/.libs/libbroccoli.a @BRO_LIBADD@ - -broping_SOURCES = broping.c -broconn_SOURCES = broconn.c -brohose_SOURCES = brohose.c -broenum_SOURCES = broenum.c -broconftest_SOURCES = broconftest.c -brotable_SOURCES = brotable.c - -# don't install any of this stuff -#install-binPROGRAMS: -#uninstall-binPROGRAMS: - -EXTRA_DIST = broping.bro brohose.bro broenum.bro broping-record.bro broconn.bro diff --git a/aux/broccoli/test/broconftest.c b/aux/broccoli/test/broconftest.c deleted file mode 100644 index d221d59968..0000000000 --- a/aux/broccoli/test/broconftest.c +++ /dev/null @@ -1,50 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2007 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#include -#include - -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -int -main(int argc, char **argv) -{ - int i; - const char *s; - - bro_init(NULL); - - if ( (s = bro_conf_get_str("PeerName"))) - printf("PeerName: %s\n", s); - - if (bro_conf_get_int("PeerPort", &i)) - printf("PeerPort: %i\n", i); - - return 0; -} diff --git a/aux/broccoli/test/broconn.bro b/aux/broccoli/test/broconn.bro deleted file mode 100644 index 37540df01b..0000000000 --- a/aux/broccoli/test/broconn.bro +++ /dev/null @@ -1,50 +0,0 @@ -# Depending on whether you want to use encryption or not, -# include "listen-clear" or "listen-ssl": -# -# @load listen-ssl -@load listen-clear -@load conn -@load dpd - -# Let's make sure we use the same port no matter whether we use encryption or not: -# -@ifdef (listen_port_clear) -redef listen_port_clear = 47758/tcp; -@endif - -# If we're using encrypted communication, redef the SSL port and hook in -# the necessary certificates: -# -@ifdef (listen_port_ssl) -redef listen_port_ssl = 47758/tcp; -redef ssl_ca_certificate = "/ca_cert.pem"; -redef ssl_private_key = "/bro.pem"; -@endif - -redef Remote::destinations += { - ["broconn"] = [$host = 127.0.0.1, $connect=F, $ssl=F] -}; - -redef dpd_conn_logs = T; - -function services_to_string(ss: string_set): string -{ - local result = ""; - - for (s in ss) - result = fmt("%s %s", result, s); - - return result; -} - -event new_connection(c: connection) -{ - print fmt("new_connection: %s, services:%s", - id_string(c$id), services_to_string(c$service)); -} - -event connection_finished(c: connection) -{ - print fmt("connection_finished: %s, services:%s", - id_string(c$id), services_to_string(c$service)); -} diff --git a/aux/broccoli/test/broconn.c b/aux/broccoli/test/broconn.c deleted file mode 100644 index dea050870d..0000000000 --- a/aux/broccoli/test/broconn.c +++ /dev/null @@ -1,354 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2007 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -char *host_default = "127.0.0.1"; -char *port_default = "47758"; -char *host_str; -char *port_str; - -int count = -1; -int seq; - -static void -usage(void) -{ - printf("broconn - dumps arriving connection events to console.\n" - "USAGE: broconn [-h|-?] [-d] [-p port] host\n"); - exit(0); -} - -/* Snippet from Bro policies containing relevant record types: - -type connection: record { - id: conn_id; - orig: endpoint; - resp: endpoint; - start_time: time; - duration: interval; - service: string; - addl: string; - hot: count; -}; - -type conn_id: record { - orig_h: addr; - orig_p: port; - resp_h: addr; - resp_p: port; -}; - -type endpoint: record { - size: count; - state: count; -}; - -*/ - -static int -services_print_cb(BroString *service, void *user_data) -{ - printf("'%s' ", service->str_val); - - return TRUE; - user_data = NULL; -} - -static void -conn_generic(BroConn *bc, BroRecord *conn) -{ - BroRecord *id, *orig, *resp; - BroSet *services; - BroString *addl; - BroPort *port; - uint32 *addr, *size, *state; - double *start_time, *duration; - struct in_addr ip; - int type = BRO_TYPE_RECORD; - - if (! (id = bro_record_get_named_val(conn, "id", &type))) - { - printf("[Error obtaining 'id' member from connection record.]\n"); - return; - } - - if (! (orig = bro_record_get_named_val(conn, "orig", &type))) - { - printf("[Error obtaining 'orig' member from connection record.]\n"); - return; - } - - if (! (resp = bro_record_get_named_val(conn, "resp", &type))) - { - printf("[Error obtaining 'orig' member from connection record.]\n"); - return; - } - - type = BRO_TYPE_IPADDR; - - if (! (addr = bro_record_get_named_val(id, "orig_h", &type))) - { - printf("[Error obtaining 'orig_h' member from connection ID record.]\n"); - return; - } - - type = BRO_TYPE_PORT; - - if (! (port = bro_record_get_named_val(id, "orig_p", &type))) - { - printf("[Error obtaining 'orig_p' member from connection ID record.]\n"); - return; - } - - type = BRO_TYPE_COUNT; - - if (! (size = bro_record_get_named_val(orig, "size", &type))) - { - printf("[Error obtaining 'size' member from orig endpoint record.]\n"); - return; - } - - if (! (state = bro_record_get_named_val(orig, "state", &type))) - { - printf("[Error obtaining 'state' member from orig endpoint record.]\n"); - return; - } - - ip.s_addr = *addr; - printf("%s/%u [%u/%u] -> ", inet_ntoa(ip), port->port_num, *size, *state); - type = BRO_TYPE_IPADDR; - - if (! (addr = bro_record_get_named_val(id, "resp_h", &type))) - { - printf("[Error obtaining 'resp_h' member from connection ID record.]\n"); - return; - } - - type = BRO_TYPE_PORT; - - if (! (port = bro_record_get_named_val(id, "resp_p", &type))) - { - printf("[Error obtaining 'resp_p' member from connection ID record.]\n"); - return; - } - - type = BRO_TYPE_COUNT; - - if (! (size = bro_record_get_named_val(resp, "size", &type))) - { - printf("[Error obtaining 'size' member from orig endpoint record.]\n"); - return; - } - - if (! (state = bro_record_get_named_val(resp, "state", &type))) - { - printf("[Error obtaining 'state' member from orig endpoint record.]\n"); - return; - } - - ip.s_addr = *addr; - printf("%s/%u [%u/%u], ", inet_ntoa(ip), port->port_num, *size, *state); - type = BRO_TYPE_TIME; - - if (! (start_time = bro_record_get_named_val(conn, "start_time", &type))) - { - printf("[Error obtaining 'start_time' member from connection record.]\n"); - return; - } - - type = BRO_TYPE_INTERVAL; - - if (! (duration = bro_record_get_named_val(conn, "duration", &type))) - { - printf("[Error obtaining 'duration' member from connection record.]\n"); - return; - } - - type = BRO_TYPE_SET; - - services = bro_record_get_named_val(conn, "service", &type); - - type = BRO_TYPE_STRING; - - if (! (addl = bro_record_get_named_val(conn, "addl", &type))) - { - printf("[Error obtaining 'addl' member from connection record.]\n"); - return; - } - - printf("start: %f, duration: %f, addl: '%s', ", - *start_time, *duration, addl->str_val); - - if (services) - { - int type; - - bro_set_get_type(services, &type); - - printf("%i services (type check: %d) ", - bro_set_get_size(services), type); - - if (bro_set_get_size(services) > 0) - bro_set_foreach(services, (BroSetCallback) services_print_cb, NULL); - } - else - printf("no services listed"); - - printf("\n"); -} - -static void -conn_new(BroConn *bc, void *data, BroRecord *conn) -{ - printf("new_connection: "); - conn_generic(bc, conn); - data = NULL; -} - -static void -conn_fin(BroConn *bc, void *data, BroRecord *conn) -{ - printf("connection_finished: "); - conn_generic(bc, conn); - data = NULL; -} - - -int -main(int argc, char **argv) -{ - int opt, port, fd, debugging = 0; - BroConn *bc; - extern char *optarg; - extern int optind; - char hostname[512]; - fd_set fd_read; - - bro_init(NULL); - - host_str = host_default; - port_str = port_default; - - bro_debug_calltrace = 0; - bro_debug_messages = 0; - - while ( (opt = getopt(argc, argv, "c:p:dh?r")) != -1) - { - switch (opt) - { - case 'd': - debugging++; - - if (debugging == 1) - bro_debug_messages = 1; - - if (debugging > 1) - bro_debug_calltrace = 1; - break; - - case 'h': - case '?': - usage(); - - case 'p': - port_str = optarg; - break; - - default: - usage(); - } - } - - argc -= optind; - argv += optind; - - if (argc > 0) - host_str = argv[0]; - - port = strtol(port_str, NULL, 0); - if (errno == ERANGE) - { - printf("Please provide a port number with -p.\n"); - exit(-1); - } - - snprintf(hostname, 512, "%s:%s", host_str, port_str); - - /* Connect to Bro */ - if (! (bc = bro_conn_new_str(hostname, BRO_CFLAG_RECONNECT | BRO_CFLAG_ALWAYS_QUEUE))) - { - printf("Couldn't get Bro connection handle.\n"); - exit(-1); - } - - /* Request a few event types and have the corresponding callbacks - * called when they arrive. The callback mechanism automatically figures out - * the number of arguments and invokes the callback accordingly. - */ - bro_event_registry_add(bc, "new_connection", (BroEventFunc) conn_new, NULL); - bro_event_registry_add(bc, "connection_finished", (BroEventFunc) conn_fin, NULL); - - if (! bro_conn_connect(bc)) - { - printf("Could not connect to Bro at %s:%s.\n", host_str, port_str); - exit(-1); - } - - /* Sit and wait for events */ - fd = bro_conn_get_fd(bc); - - for ( ; ; ) - { - FD_ZERO(&fd_read); - FD_SET(fd, &fd_read); - - if (select(fd + 1, &fd_read, NULL, NULL, NULL) <= 0) - break; - - bro_conn_process_input(bc); - } - - /* Disconnect from Bro and release state. */ - bro_conn_delete(bc); - - return 0; -} diff --git a/aux/broccoli/test/broenum.bro b/aux/broccoli/test/broenum.bro deleted file mode 100644 index fd4d55fc4f..0000000000 --- a/aux/broccoli/test/broenum.bro +++ /dev/null @@ -1,33 +0,0 @@ -# Depending on whether you want to use encryption or not, -# include "listen-clear" or "listen-ssl": -# -# @load listen-ssl -@load listen-clear - -# Let's make sure we use the same port no matter whether we use encryption or not: -# -@ifdef (listen_port_clear) -redef listen_port_clear = 47758/tcp; -@endif - -# If we're using encrypted communication, redef the SSL port and hook in -# the necessary certificates: -# -@ifdef (listen_port_ssl) -redef listen_port_ssl = 47758/tcp; -redef ssl_ca_certificate = "/ca_cert.pem"; -redef ssl_private_key = "/bro.pem"; -@endif - -module enumtest; - -type enumtype: enum { ENUM1, ENUM2, ENUM3, ENUM4 }; - -redef Remote::destinations += { - ["broenum"] = [$host = 127.0.0.1, $events = /enumtest/, $connect=F, $ssl=F] -}; - -event enumtest(e: enumtype) - { - print fmt("Received enum val %d/%s", e, e); - } diff --git a/aux/broccoli/test/broenum.c b/aux/broccoli/test/broenum.c deleted file mode 100644 index a450dbfcb1..0000000000 --- a/aux/broccoli/test/broenum.c +++ /dev/null @@ -1,171 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2007 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#include -#include -#include -#include -#include -#include - -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -char *host_default = "127.0.0.1"; -char *port_default = "47758"; -char *host_str; -char *port_str; - -char *type = "enumtest::enumtype"; - -static void -usage(void) -{ - printf("broenum - sends enum vals to a Bro node, printing the corresponding\n" - "string value on the Bro side.\n" - "USAGE: broping [-h|-?] [-d] [-p port] [-t type] [-n num] host\n"); - exit(0); -} - -int -main(int argc, char **argv) -{ - int opt, port, debugging = 0; - BroConn *bc; - BroEvent *ev; - extern char *optarg; - extern int optind; - char hostname[512]; - int enumval; - - bro_init(NULL); - - host_str = host_default; - port_str = port_default; - - bro_debug_calltrace = 0; - bro_debug_messages = 0; - - while ( (opt = getopt(argc, argv, "t:n:p:dh?")) != -1) - { - switch (opt) - { - case 'd': - debugging++; - - if (debugging == 1) - bro_debug_messages = 1; - - if (debugging > 1) - bro_debug_calltrace = 1; - break; - - case 'h': - case '?': - usage(); - - case 't': - type = optarg; - break; - - case 'n': - enumval = strtol(optarg, NULL, 0); - if (errno == ERANGE) - { - printf("Please provide an integer to -n.\n"); - exit(-1); - } - break; - - case 'p': - port_str = optarg; - break; - - default: - usage(); - } - } - - argc -= optind; - argv += optind; - - if (argc > 0) - host_str = argv[0]; - - port = strtol(port_str, NULL, 0); - if (errno == ERANGE) - { - printf("Please provide a port number with -p.\n"); - exit(-1); - } - - if (!type) - usage(); - - printf("Sending enum val %i to remote peer.\n", enumval); - - snprintf(hostname, 512, "%s:%s", host_str, port_str); - - /* Connect to Bro */ - if (! (bc = bro_conn_new_str(hostname, BRO_CFLAG_NONE))) - { - printf("Could not get Bro connection handle.\n"); - exit(-1); - } - - if (! bro_conn_connect(bc)) - { - printf("Could not connect to Bro at %s:%s.\n", host_str, port_str); - exit(-1); - } - - /* Create empty "ping" event */ - if (! (ev = bro_event_new("enumtest"))) - { - printf("Couldn't create event structure.\n"); - exit(-1); - } - - /* We send the given number as an instance of an enum type defined - * in the remote Bro's policy: - */ - bro_event_add_val(ev, BRO_TYPE_ENUM, type, &enumval); - - /* Ship it -- sends it if possible, queues it otherwise */ - bro_event_send(bc, ev); - bro_event_free(ev); - - /* Make sure we sent the thing. */ - while (bro_event_queue_length(bc) > 0) - bro_event_queue_flush(bc); - - /* Disconnect from Bro and release state. */ - bro_conn_delete(bc); - - return 0; -} diff --git a/aux/broccoli/test/brohose.bro b/aux/broccoli/test/brohose.bro deleted file mode 100644 index a2081bb70c..0000000000 --- a/aux/broccoli/test/brohose.bro +++ /dev/null @@ -1,30 +0,0 @@ -# Depending on whether you want to use encryption or not, -# include "listen-clear" or "listen-ssl": -# -# @load listen-ssl -@load listen-clear - -global brohose_log = open_log_file("brohose"); - -# Let's make sure we use the same port no matter whether we use encryption or not: -# -@ifdef (listen_port_clear) -redef listen_port_clear = 47758/tcp; -@endif - -# If we're using encrypted communication, redef the SSL port and hook in -# the necessary certificates: -# -@ifdef (listen_port_ssl) -redef listen_port_ssl = 47758/tcp; -redef ssl_ca_certificate = "/ca_cert.pem"; -redef ssl_private_key = "/bro.pem"; -@endif - -redef Remote::destinations += { - ["brohose"] = [$host = 127.0.0.1, $events = /brohose/, $connect=F, $ssl=F] -}; - -event brohose(id: string) { - print brohose_log, fmt("%s %s", id, current_time()); -} diff --git a/aux/broccoli/test/brohose.c b/aux/broccoli/test/brohose.c deleted file mode 100644 index b1c79adedb..0000000000 --- a/aux/broccoli/test/brohose.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2007 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -char *host_default = "127.0.0.1"; -char *port_default = "47758"; -char *host_str; -char *port_str; - -int num_procs = 10; -int num_events = 1000; -int seq; - -static void -usage(void) -{ - printf("brohose - sends events to a Bro node from multiple processes in parallel.\n" - "USAGE: brohose [-h|-?] [-n <# processes>] [-e <# events>] [-p port] host\n" - " -h|? this message\n" - " -n <# processes> number of processes to use (10)\n" - " -e <# events> number of events per process (1000)\n" - " -p port to contact\n" - " host host to contanct\n\n"); - exit(0); -} - -static void -hose_away(BroConn *bc) -{ - BroEvent *ev; - BroString str; - int i; - pid_t pid = getpid(); - char msg[1024]; - - printf("++ child %u\n", pid); - - for (i = 0; i < num_events; i++) - { - /* Create empty "ping" event */ - if (! (ev = bro_event_new("brohose"))) - { - printf("**** EEEEK\n"); - bro_conn_delete(bc); - return; - } - - snprintf(msg, 1024, "%u-%i-%i", pid, i, bro_event_queue_length(bc)); - bro_string_set(&str, msg); - bro_event_add_val(ev, BRO_TYPE_STRING, NULL, &str); - - /* Ship it -- sends it if possible, queues it otherwise */ - bro_event_send(bc, ev); - - bro_event_free(ev); - bro_string_cleanup(&str); - - if (bro_event_queue_length(bc) > bro_event_queue_length_max(bc) / 2) - { - while (bro_event_queue_length(bc) > 0) - bro_event_queue_flush(bc); - } - } - - while (bro_event_queue_length(bc) > 0) - bro_event_queue_flush(bc); - - printf("-- child %u, %i queued\n", pid, bro_event_queue_length(bc)); - bro_conn_delete(bc); -} - - -int -main(int argc, char **argv) -{ - int i, opt, port, debugging = 0; - BroConn *bc; - extern char *optarg; - extern int optind; - char hostname[512]; - - bro_init(NULL); - - host_str = host_default; - port_str = port_default; - - bro_debug_calltrace = 0; - bro_debug_messages = 0; - - while ( (opt = getopt(argc, argv, "n:e:p:dh?")) != -1) - { - switch (opt) - { - case 'd': - debugging++; - - if (debugging == 1) - bro_debug_messages = 1; - - if (debugging > 1) - bro_debug_calltrace = 1; - break; - - case 'h': - case '?': - usage(); - - case 'n': - num_procs = strtol(optarg, NULL, 0); - if (errno == ERANGE || num_procs < 1 || num_procs > 100) - { - printf("Please restrict the number of processes to 1-100.\n"); - exit(-1); - } - break; - - case 'e': - num_events = strtol(optarg, NULL, 0); - if (errno == ERANGE || num_events < 1 || num_events > 10000) - { - printf("Please restrict the number of events to 1-10,000..\n"); - exit(-1); - } - break; - - case 'p': - port_str = optarg; - break; - - default: - usage(); - } - } - - argc -= optind; - argv += optind; - - if (argc > 0) - host_str = argv[0]; - - port = strtol(port_str, NULL, 0); - if (errno == ERANGE) - { - printf("Please provide a port number with -p.\n"); - exit(-1); - } - - snprintf(hostname, 512, "%s:%s", host_str, port_str); - - printf("Will attempt to send %i events from %i processes, to %s\n", - num_events, num_procs, hostname); - - /* Connect to Bro */ - if (! (bc = bro_conn_new_str(hostname, BRO_CFLAG_SHAREABLE))) - { - printf("Couldn't get Bro connection handle.\n"); - exit(-1); - } - - if (! bro_conn_connect(bc)) - { - printf("Could not connect to Bro at %s:%s.\n", host_str, port_str); - exit(-1); - } - - for (i = 0; i < num_procs; i++) - { - int pid = fork(); - - if (pid < 0) - { - printf("Couldn't fork children, aborting.\n"); - exit(-1); - } - - if (pid == 0) - { - hose_away(bc); - exit(0); - } - } - - while (i > 0) - { - int status; - - wait(&status); - i--; - } - - - /* Disconnect from Bro -- this will keep the copies in the children - * working but reduce the reference count of the underlying socket so - * that eventually it is really closed. - */ - bro_conn_delete(bc); - printf("Exiting ...\n"); - - return 0; -} diff --git a/aux/broccoli/test/broping-record.bro b/aux/broccoli/test/broping-record.bro deleted file mode 100644 index 3a4370fa1e..0000000000 --- a/aux/broccoli/test/broping-record.bro +++ /dev/null @@ -1,59 +0,0 @@ -# Depending on whether you want to use encryption or not, -# include "listen-clear" or "listen-ssl": -# -# @load listen-ssl -@load listen-clear - -global ping_log = open_log_file("ping"); - -# Let's make sure we use the same port no matter whether we use encryption or not: -# -@ifdef (listen_port_clear) -redef listen_port_clear = 47758/tcp; -@endif - -# If we're using encrypted communication, redef the SSL port and hook in -# the necessary certificates: -# -@ifdef (listen_port_ssl) -redef listen_port_ssl = 47758/tcp; -redef ssl_ca_certificate = "/ca_cert.pem"; -redef ssl_private_key = "/bro.pem"; -@endif - -redef Remote::destinations += { - ["broping"] = [$host = 127.0.0.1, $events = /ping/, $connect=F, $ssl=F] -}; - -type ping_data: record { - seq: count; - src_time: time; -}; - -type pong_data: record { - seq: count; - src_time: time; - dst_time: time; -}; - -# global pdata: pong_data; - -global ping: event(data: ping_data); -global pong: event(data: pong_data); - -event ping(data: ping_data) - { - local pdata: pong_data; - - pdata$seq = data$seq; - pdata$src_time = data$src_time; - pdata$dst_time = current_time(); - - event pong(pdata); - } - -event pong(data: pong_data) - { - print ping_log, fmt("ping received, seq %d, %f at src, %f at dest, one-way: %f", - data$seq, data$src_time, data$dst_time, data$dst_time - data$src_time); - } diff --git a/aux/broccoli/test/broping.bro b/aux/broccoli/test/broping.bro deleted file mode 100644 index 86e7f2d52e..0000000000 --- a/aux/broccoli/test/broping.bro +++ /dev/null @@ -1,40 +0,0 @@ -# Depending on whether you want to use encryption or not, -# include "listen-clear" or "listen-ssl": -# -# @load listen-ssl -@load listen-clear - -global ping_log = open_log_file("ping"); - -# Let's make sure we use the same port no matter whether we use encryption or not: -# -@ifdef (listen_port_clear) -redef listen_port_clear = 47758/tcp; -@endif - -# If we're using encrypted communication, redef the SSL port and hook in -# the necessary certificates: -# -@ifdef (listen_port_ssl) -redef listen_port_ssl = 47758/tcp; -redef ssl_ca_certificate = "/ca_cert.pem"; -redef ssl_private_key = "/bro.pem"; -@endif - -global ping: event(src_time: time, seq: count); -global pong: event(src_time: time, dst_time: time, seq: count); - -redef Remote::destinations += { - ["broping"] = [$host = 127.0.0.1, $events = /ping/, $connect=F, $ssl=F] -}; - -event ping(src_time: time, seq: count) - { - event pong(src_time, current_time(), seq); - } - -event pong(src_time: time, dst_time: time, seq: count) - { - print ping_log, fmt("ping received, seq %d, %f at src, %f at dest, one-way: %f", - seq, src_time, dst_time, dst_time-src_time); - } diff --git a/aux/broccoli/test/broping.c b/aux/broccoli/test/broping.c deleted file mode 100644 index c3ccf4d57e..0000000000 --- a/aux/broccoli/test/broping.c +++ /dev/null @@ -1,456 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2007 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -char *host_default = "127.0.0.1"; -char *port_default = "47758"; -char *host_str; -char *port_str; - -int count = -1; -int seq; - -static void -usage(void) -{ - printf("broping - sends ping events to a Bro agent, expecting pong events.\n" - "USAGE: broping [-h|-?] [-d] [-l] [-r] [-c num] [-p port] host\n" - " -h|-? This message.\n" - " -d Enable debugging (only useful if configured with --enable-debug).\n" - " -r Use record types to transfer data.\n" - " -C Use compact callback argument passing.\n" - " -c Number of events to send.\n" - " -p Port on to contact.\n"); - - exit(0); -} - - -static void -bro_pong(BroConn *conn, void *data, double *src_time, double *dst_time, uint32 *seq) -{ - double now = bro_util_current_time(); - - printf("pong event from %s: seq=%i, time=%f/%f s\n", - host_str, *seq, *dst_time - *src_time, - now - *src_time); - - conn = NULL; - data = NULL; -} - -static void -bro_pong_record(BroConn *conn, void *data, BroRecord *rec) -{ - double now = bro_util_current_time(); - double *src_time, *dst_time; - uint32 *seq; - int type = BRO_TYPE_COUNT; - - if (! (seq = bro_record_get_nth_val(rec, 0, &type))) - { - printf("Error getting sequence count from event, got type %i\n", type); - return; - } - - type = BRO_TYPE_TIME; - - if (! (src_time = bro_record_get_nth_val(rec, 1, &type))) - { - printf("Error getting src time from event, got type %i.\n", type); - return; - } - - type = BRO_TYPE_TIME; - - if (! (dst_time = bro_record_get_nth_val(rec, 2, &type))) - { - printf("Error getting dst time from event, got type %i\n", type); - return; - } - - printf("pong event from %s: seq=%i, time=%f/%f s\n", - host_str, *seq, *dst_time - *src_time, - now - *src_time); - - conn = NULL; - data = NULL; -} - -static void -bro_pong_compact(BroConn *conn, void *data, BroEvMeta *meta) -{ - double *src_time; - double *dst_time; - uint32 *seq; - - /* Sanity-check arguments: */ - - if (strcmp(meta->ev_name, "pong") != 0) - { - printf("Event should be 'pong', is '%s', error.\n", - meta->ev_name); - return; - } - - if (meta->ev_numargs != 3) - { - printf("Pong event should have 3 arguments, has %d, error.\n", - meta->ev_numargs); - return; - } - - if (meta->ev_args[0].arg_type != BRO_TYPE_TIME) - { - printf("Type of first argument should be %i, is %i, error.\n", - BRO_TYPE_TIME, meta->ev_args[0].arg_type); - return; - } - - if (meta->ev_args[1].arg_type != BRO_TYPE_TIME) - { - printf("Type of second argument should be %i, is %i, error.\n", - BRO_TYPE_TIME, meta->ev_args[1].arg_type); - return; - } - - if (meta->ev_args[2].arg_type != BRO_TYPE_COUNT) - { - printf("Type of third argument should be %i, is %i, error.\n", - BRO_TYPE_COUNT, meta->ev_args[2].arg_type); - return; - } - - src_time = (double *) meta->ev_args[0].arg_data; - dst_time = (double *) meta->ev_args[1].arg_data; - seq = (uint32 *) meta->ev_args[2].arg_data; - - bro_pong(conn, data, src_time, dst_time, seq); -} - -static void -bro_pong_compact_record(BroConn *conn, void *data, BroEvMeta *meta) -{ - BroRecord *rec; - - /* Sanity-check argument type: */ - - if (strcmp(meta->ev_name, "pong") != 0) - { - printf("Event should be 'pong', is '%s', error.\n", - meta->ev_name); - return; - } - - if (meta->ev_numargs != 1) - { - printf("Pong event should have 1 argument, has %d, error.\n", - meta->ev_numargs); - return; - } - - if (meta->ev_args[0].arg_type != BRO_TYPE_RECORD) - { - printf("Type of argument should be %i, is %i, error.\n", - BRO_TYPE_RECORD, meta->ev_args[0].arg_type); - return; - } - - rec = (BroRecord *) meta->ev_args[0].arg_data; - - bro_pong_record(conn, data, rec); -} - -BroConn* -start_listen(int port) -{ - int fd = 0; - struct sockaddr_in server; - struct sockaddr_in client; - socklen_t len = sizeof(client); - fd_set fds; - const int turn_on = 1; - BroConn *bc = 0; - - fd = socket(PF_INET, SOCK_STREAM, 0); - if ( fd < 0 ) - { - printf("can't create listen socket: %s\n", strerror(errno)); - exit(-1); - } - - // Set SO_REUSEADDR. - if ( setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &turn_on, sizeof(turn_on)) < 0 ) - { - printf("can't set SO_REUSEADDR: %s\n", strerror(errno)); - exit(-1); - } - - bzero(&server, sizeof(server)); - server.sin_family = AF_INET; - server.sin_port = htons(port); - server.sin_addr.s_addr = 0; - - if ( bind(fd, (struct sockaddr*) &server, sizeof(server)) < 0 ) - { - printf("can't bind to port %d: %s\n", port, strerror(errno)); - exit(-1); - } - - if ( listen(fd, 50) < 0 ) - { - printf("can't listen: %s\n", strerror(errno)); - exit(-1); - } - - FD_ZERO(&fds); - FD_SET(fd, &fds); - - if ( select(fd + 1, &fds, &fds, &fds, 0) < 0 ) - { - printf("can't select: %s\n", strerror(errno)); - exit(-1); - } - - fd = accept(fd, (struct sockaddr*) &client, &len); - if ( fd < 0 ) - { - printf("can't accept: %s\n", strerror(errno)); - exit(-1); - } - - bc = bro_conn_new_socket(fd, BRO_CFLAG_ALWAYS_QUEUE); - if ( ! bc ) - { - printf("can't create connection form fd\n"); - exit(-1); - } - - return bc; -} - -int -main(int argc, char **argv) -{ - int opt, port, use_record = 0, use_compact = 0, debugging = 0, listen = 0; - BroConn *bc; - extern char *optarg; - extern int optind; - char hostname[512]; - int fd = -1; - - bro_init(NULL); - - host_str = host_default; - port_str = port_default; - - bro_debug_calltrace = 0; - bro_debug_messages = 0; - - while ( (opt = getopt(argc, argv, "Cc:p:dh?lr")) != -1) - { - switch (opt) - { - case 'd': - debugging++; - - if (debugging == 1) - bro_debug_messages = 1; - - if (debugging > 1) - bro_debug_calltrace = 1; - break; - - case 'l': - listen = 1; - break; - - case 'h': - case '?': - usage(); - - case 'c': - count = strtol(optarg, NULL, 0); - if (errno == ERANGE || count < 1) - { - printf("Please provide an integer to -c.\n"); - exit(-1); - } - break; - - case 'p': - port_str = optarg; - break; - - case 'r': - use_record = 1; - break; - - case 'C': - use_compact = 1; - break; - - default: - usage(); - } - } - - argc -= optind; - argv += optind; - - if (argc > 0) - host_str = argv[0]; - - /* - if (! (host = gethostbyname(host_str)) || - ! (host->h_addr_list[0])) - { - printf("Could not resolve host %s\n", host_str); - exit(-1); - } - */ - - port = strtol(port_str, NULL, 0); - if (errno == ERANGE) - { - printf("Please provide a port number with -p.\n"); - exit(-1); - } - - snprintf(hostname, 512, "%s:%s", host_str, port_str); - - - if ( listen ) - bc = start_listen(port); - - /* Connect to Bro */ - else if (! (bc = bro_conn_new_str(hostname, BRO_CFLAG_RECONNECT | BRO_CFLAG_ALWAYS_QUEUE))) - { - printf("Could not get Bro connection handle.\n"); - exit(-1); - } - - /* Request "pong" events, and have bro_pong called when they - * arrive. The callback mechanism automatically figures out - * the number of arguments and invokes the callback accordingly. - * Use record-based callback if -r option was given, and compact - * argument passing if -C was provided. - */ - if (use_compact) - { - if (use_record) - bro_event_registry_add_compact(bc, "pong", (BroCompactEventFunc) - bro_pong_compact_record, NULL); - else - bro_event_registry_add_compact(bc, "pong", (BroCompactEventFunc) - bro_pong_compact, NULL); - } - else - { - if (use_record) - bro_event_registry_add(bc, "pong", (BroEventFunc) bro_pong_record, NULL); - else - bro_event_registry_add(bc, "pong", (BroEventFunc) bro_pong, NULL); - } - - if (! bro_conn_connect(bc)) - { - printf("Could not connect to Bro at %s:%s.\n", host_str, port_str); - exit(-1); - } - - /* Enter pinging loop */ - for ( ; ; ) - { - BroEvent *ev; - - bro_conn_process_input(bc); - - if (count > 0 && seq == count) - break; - - /* Create empty "ping" event */ - if ( (ev = bro_event_new("ping"))) - { - double timestamp = bro_util_current_time(); - - if (use_record) - { - /* Create a record with the sequence number as first - * element of type counter, and the second element the - * current time: - */ - BroRecord *rec = bro_record_new(); - - bro_record_add_val(rec, "seq", BRO_TYPE_COUNT, NULL, &seq); - bro_record_add_val(rec, "src_time", BRO_TYPE_TIME, NULL, ×tamp); - - bro_event_add_val(ev, BRO_TYPE_RECORD, NULL, rec); - - bro_record_free(rec); - } - else - { - /* Add a timestamp to it: */ - bro_event_add_val(ev, BRO_TYPE_TIME, NULL, ×tamp); - - /* Add the sequence counter: */ - bro_event_add_val(ev, BRO_TYPE_COUNT, NULL, &seq); - } - - seq++; - - /* Ship it -- sends it if possible, queues it otherwise */ - bro_event_send(bc, ev); - bro_event_free(ev); - } - -#ifdef __MINGW32__ - sleep(1000); -#else - sleep(1); -#endif - } - - /* Disconnect from Bro and release state. */ - bro_conn_delete(bc); - - return 0; -} diff --git a/aux/broccoli/test/brotable.c b/aux/broccoli/test/brotable.c deleted file mode 100644 index 4249472477..0000000000 --- a/aux/broccoli/test/brotable.c +++ /dev/null @@ -1,328 +0,0 @@ -/* - B R O C C O L I -- The Bro Client Communications Library - -Copyright (C) 2004-2007 Christian Kreibich - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to -deal in the Software without restriction, including without limitation the -rights to use, copy, modify, merge, publish, distribute, sublicense, and/or -sell copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies of the Software and its documentation and acknowledgment shall be -given in the documentation and software packages that this Software was -used. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER -IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -*/ -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -void -print_val(void *val, int type) -{ - char br_open = '['; - char br_close = ']'; - - if (! val) - { - printf("NULL"); - return; - } - - switch (type) { - case BRO_TYPE_BOOL: - printf("%s", *((int*) val) == 0 ? "false" : "true"); - break; - - case BRO_TYPE_INT: - printf("%i", *((int*) val)); - break; - - case BRO_TYPE_DOUBLE: - printf("%f", *((double*) val)); - break; - - case BRO_TYPE_STRING: - printf("'%s'", bro_string_get_data((BroString*) val)); - break; - - case BRO_TYPE_LIST: - /* This means that we're dealing with a composite indexing type. - * Except for this differing type code, treatment is exactly as - * with a record: - */ - br_open = '{'; - br_close = '}'; - - /* Fall through */ - - case BRO_TYPE_RECORD: - { - void *item; - int i, type; - BroRecord *rec = (BroRecord*) val; - - printf("%c", br_open); - - for (i = 0; i < bro_record_get_length(rec); i++) - { - /* We don't want to enforce typechecking of the - * queried value, so we use BRO_TYPE_UNKNOWN. - */ - type = BRO_TYPE_UNKNOWN; - item = bro_record_get_nth_val(rec, i, &type); - print_val(item, type); - - if (i + 1 < bro_record_get_length(rec)) - printf(", "); - } - - printf("%c", br_close); - } - break; - - default: - printf("", type); - } -} - -int -table_it_cb(void *key, void *val, BroTable *table) -{ - int key_type, val_type; - - bro_table_get_types(table, &key_type, &val_type); - - print_val(key, key_type); - printf(" -> "); - print_val(val, val_type); - printf("\n"); - - return TRUE; -} - -int -main(int argc, char **argv) -{ - int opt, debugging = 0; - - /* A few tables with different atomic indexing/yield types: */ - BroTable *int_to_str; - BroTable *str_to_double; - - /* A table with a composite indexing type: */ - BroTable *int_str_double_to_int; - - /* Placeholders for the stuff we insert/retrieve: */ - BroString str, *str_ptr; - BroRecord *rec; - int i, i2, *i_ptr; - double d, *d_ptr; - - while ( (opt = getopt(argc, argv, "c:p:dh?r")) != -1) - { - switch (opt) - { - case 'd': - debugging++; - - if (debugging == 1) - bro_debug_messages = 1; - - if (debugging > 1) - bro_debug_calltrace = 1; - break; - - default: - break; - } - } - - /* ---- Mandatory initialization ------------------------------------- */ - bro_init(NULL); - - /* ---- int -> string ------------------------------------------------ */ - - printf("int_to_str table dump:\n"); - printf("----------------------\n"); - - int_to_str = bro_table_new(); - - i = 10; - bro_string_set(&str, "foo"); - bro_table_insert(int_to_str, BRO_TYPE_INT, &i, BRO_TYPE_STRING, &str); - bro_string_cleanup(&str); - - i = 20; - bro_string_set(&str, "bar"); - bro_table_insert(int_to_str, BRO_TYPE_INT, &i, BRO_TYPE_STRING, &str); - bro_string_cleanup(&str); - - i = 30; - bro_string_set(&str, "baz"); - bro_table_insert(int_to_str, BRO_TYPE_INT, &i, BRO_TYPE_STRING, &str); - bro_string_cleanup(&str); - - bro_table_foreach(int_to_str, (BroTableCallback) table_it_cb, int_to_str); - - printf("\ntest lookup: "); - i = 20; - str_ptr = (BroString*) bro_table_find(int_to_str, &i); - - print_val(&i, BRO_TYPE_INT); - printf(" -> "); - print_val(str_ptr, BRO_TYPE_STRING); - printf("\n\n"); - - bro_table_free(int_to_str); - - - /* ---- string -> double --------------------------------------------- */ - - printf("str_to_double table dump:\n"); - printf("-------------------------\n"); - - str_to_double = bro_table_new(); - - d = 1.1; - bro_string_set(&str, "foo"); - bro_table_insert(str_to_double, BRO_TYPE_STRING, &str, BRO_TYPE_DOUBLE, &d); - bro_string_cleanup(&str); - - d = 2.2; - bro_string_set(&str, "bar"); - bro_table_insert(str_to_double, BRO_TYPE_STRING, &str, BRO_TYPE_DOUBLE, &d); - bro_string_cleanup(&str); - - d = 3.3; - bro_string_set(&str, "baz"); - bro_table_insert(str_to_double, BRO_TYPE_STRING, &str, BRO_TYPE_DOUBLE, &d); - bro_string_cleanup(&str); - - bro_table_foreach(str_to_double, (BroTableCallback) table_it_cb, str_to_double); - - printf("\ntest lookup: "); - bro_string_set(&str, "bar"); - d_ptr = (double*) bro_table_find(str_to_double, &str); - - print_val(&str, BRO_TYPE_STRING); - printf(" -> "); - print_val(d_ptr, BRO_TYPE_DOUBLE); - printf("\n\n"); - - bro_string_cleanup(&str); - - bro_table_free(str_to_double); - - - /* ---- {int, string, double} -> int --------------------------------- */ - - printf("int_str_double_to_int table dump:\n"); - printf("---------------------------------\n"); - - int_str_double_to_int = bro_table_new(); - - /* -- first element -- */ - - i = 1; - d = 1.1; - bro_string_set(&str, "foo"); - i2 = 10; - - /* You may pass NULL as the field name, but then of course looking - * up elements by field name will not work in case you need it. - */ - rec = bro_record_new(); - bro_record_add_val(rec, NULL, BRO_TYPE_INT, NULL, &i); - bro_record_add_val(rec, NULL, BRO_TYPE_STRING, NULL, &str); - bro_record_add_val(rec, NULL, BRO_TYPE_DOUBLE, NULL, &d); - bro_table_insert(int_str_double_to_int, BRO_TYPE_LIST, rec, BRO_TYPE_INT, &i2); - - bro_string_cleanup(&str); - bro_record_free(rec); - - /* -- second element -- */ - - i = 2; - d = 2.2; - bro_string_set(&str, "bar"); - i2 = 20; - - /* You may pass NULL as the field name, but then of course looking - * up elements by field name will not work in case you need it. - */ - rec = bro_record_new(); - bro_record_add_val(rec, NULL, BRO_TYPE_INT, NULL, &i); - bro_record_add_val(rec, NULL, BRO_TYPE_STRING, NULL, &str); - bro_record_add_val(rec, NULL, BRO_TYPE_DOUBLE, NULL, &d); - bro_table_insert(int_str_double_to_int, BRO_TYPE_LIST, rec, BRO_TYPE_INT, &i2); - - bro_string_cleanup(&str); - bro_record_free(rec); - - /* -- third element -- */ - - i = 3; - d = 3.3; - bro_string_set(&str, "baz"); - i2 = 30; - - /* You may pass NULL as the field name, but then of course looking - * up elements by field name will not work in case you need it. - */ - rec = bro_record_new(); - bro_record_add_val(rec, NULL, BRO_TYPE_INT, NULL, &i); - bro_record_add_val(rec, NULL, BRO_TYPE_STRING, NULL, &str); - bro_record_add_val(rec, NULL, BRO_TYPE_DOUBLE, NULL, &d); - bro_table_insert(int_str_double_to_int, BRO_TYPE_LIST, rec, BRO_TYPE_INT, &i2); - - bro_string_cleanup(&str); - bro_record_free(rec); - - bro_table_foreach(int_str_double_to_int, (BroTableCallback) table_it_cb, int_str_double_to_int); - - printf("\ntest lookup: "); - - i = 2; - d = 2.2; - bro_string_set(&str, "bar"); - - rec = bro_record_new(); - bro_record_add_val(rec, NULL, BRO_TYPE_INT, NULL, &i); - bro_record_add_val(rec, NULL, BRO_TYPE_STRING, NULL, &str); - bro_record_add_val(rec, NULL, BRO_TYPE_DOUBLE, NULL, &d); - - i_ptr = (int*) bro_table_find(int_str_double_to_int, rec); - - print_val(rec, BRO_TYPE_LIST); - printf(" -> "); - print_val(i_ptr, BRO_TYPE_INT); - printf("\n\n"); - - bro_string_cleanup(&str); - bro_record_free(rec); - - bro_table_free(int_str_double_to_int); - - return 0; -} diff --git a/aux/broccoli/test/dummysensor.c b/aux/broccoli/test/dummysensor.c deleted file mode 100644 index aff40e8006..0000000000 --- a/aux/broccoli/test/dummysensor.c +++ /dev/null @@ -1,91 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef HAVE_CONFIG_H -#include -#endif - -char *ip_default = "127.0.0.1"; -char *port_default = "47756"; - -int -main(int argc, char **argv) -{ - char *ip_str = ip_default; - char *port_str = port_default; - int port; - struct in_addr ipaddr; - BroConn *bc; - BroEvent *ev; - int i; - - if (argc >= 2) - ip_str = argv[1]; - if (argc >= 3) - port_str = argv[2]; - - if (inet_pton(AF_INET, ip_str, &ipaddr) <= 0) - { - printf("Please provide an IP address to contact as first argument.\n"); - exit(-1); - } - - port = strtol(port_str, NULL, 0); - if (errno == ERANGE) - { - printf("Please provide a port number as second argument.\n"); - exit(-1); - } - - bro_init(NULL); - - printf("Opening connection.\n"); - if (! (bc = bro_connect_remote(0x0000, &ipaddr, port))) - { - printf("Couldn't connect.\n"); - exit(-1); - } - - sleep(1); - bro_conn_process_input(bc); - - sleep(5); - bro_conn_process_input(bc); - - /* - if ( (ev = bro_event_new("bar"))) - { - bro_event_add_string(ev, "hello world"); - - if (bro_event_send(bc, ev)) - printf("Bro test event sent.\n"); - else - printf("Bro test event queued.\n"); - } - - if ( (ev = bro_event_new("foo"))) - { - bro_event_add_string(ev, "hello world"); - - if (bro_event_send(bc, ev)) - printf("Bro test event sent.\n"); - else - printf("Bro test event queued.\n"); - } - */ - sleep(2); - - printf("Disconnecting.\n"); - bro_disconnect(bc); - - return 0; -} diff --git a/aux/broccoli/ylwrap b/aux/broccoli/ylwrap deleted file mode 100755 index 102bd893f7..0000000000 --- a/aux/broccoli/ylwrap +++ /dev/null @@ -1,223 +0,0 @@ -#! /bin/sh -# ylwrap - wrapper for lex/yacc invocations. - -scriptversion=2005-05-14.22 - -# Copyright (C) 1996, 1997, 1998, 1999, 2001, 2002, 2003, 2004, 2005 -# Free Software Foundation, Inc. -# -# Written by Tom Tromey . -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -# 02110-1301, USA. - -# As a special exception to the GNU General Public License, if you -# distribute this file as part of a program that contains a -# configuration script generated by Autoconf, you may include it under -# the same distribution terms that you use for the rest of that program. - -# This file is maintained in Automake, please report -# bugs to or send patches to -# . - -case "$1" in - '') - echo "$0: No files given. Try \`$0 --help' for more information." 1>&2 - exit 1 - ;; - --basedir) - basedir=$2 - shift 2 - ;; - -h|--h*) - cat <<\EOF -Usage: ylwrap [--help|--version] INPUT [OUTPUT DESIRED]... -- PROGRAM [ARGS]... - -Wrapper for lex/yacc invocations, renaming files as desired. - - INPUT is the input file - OUTPUT is one file PROG generates - DESIRED is the file we actually want instead of OUTPUT - PROGRAM is program to run - ARGS are passed to PROG - -Any number of OUTPUT,DESIRED pairs may be used. - -Report bugs to . -EOF - exit $? - ;; - -v|--v*) - echo "ylwrap $scriptversion" - exit $? - ;; -esac - - -# The input. -input="$1" -shift -case "$input" in - [\\/]* | ?:[\\/]*) - # Absolute path; do nothing. - ;; - *) - # Relative path. Make it absolute. - input="`pwd`/$input" - ;; -esac - -pairlist= -while test "$#" -ne 0; do - if test "$1" = "--"; then - shift - break - fi - pairlist="$pairlist $1" - shift -done - -# The program to run. -prog="$1" -shift -# Make any relative path in $prog absolute. -case "$prog" in - [\\/]* | ?:[\\/]*) ;; - *[\\/]*) prog="`pwd`/$prog" ;; -esac - -# FIXME: add hostname here for parallel makes that run commands on -# other machines. But that might take us over the 14-char limit. -dirname=ylwrap$$ -trap "cd `pwd`; rm -rf $dirname > /dev/null 2>&1" 1 2 3 15 -mkdir $dirname || exit 1 - -cd $dirname - -case $# in - 0) $prog "$input" ;; - *) $prog "$@" "$input" ;; -esac -ret=$? - -if test $ret -eq 0; then - set X $pairlist - shift - first=yes - # Since DOS filename conventions don't allow two dots, - # the DOS version of Bison writes out y_tab.c instead of y.tab.c - # and y_tab.h instead of y.tab.h. Test to see if this is the case. - y_tab_nodot="no" - if test -f y_tab.c || test -f y_tab.h; then - y_tab_nodot="yes" - fi - - # The directory holding the input. - input_dir=`echo "$input" | sed -e 's,\([\\/]\)[^\\/]*$,\1,'` - # Quote $INPUT_DIR so we can use it in a regexp. - # FIXME: really we should care about more than `.' and `\'. - input_rx=`echo "$input_dir" | sed 's,\\\\,\\\\\\\\,g;s,\\.,\\\\.,g'` - - while test "$#" -ne 0; do - from="$1" - # Handle y_tab.c and y_tab.h output by DOS - if test $y_tab_nodot = "yes"; then - if test $from = "y.tab.c"; then - from="y_tab.c" - else - if test $from = "y.tab.h"; then - from="y_tab.h" - fi - fi - fi - if test -f "$from"; then - # If $2 is an absolute path name, then just use that, - # otherwise prepend `../'. - case "$2" in - [\\/]* | ?:[\\/]*) target="$2";; - *) target="../$2";; - esac - - # We do not want to overwrite a header file if it hasn't - # changed. This avoid useless recompilations. However the - # parser itself (the first file) should always be updated, - # because it is the destination of the .y.c rule in the - # Makefile. Divert the output of all other files to a temporary - # file so we can compare them to existing versions. - if test $first = no; then - realtarget="$target" - target="tmp-`echo $target | sed s/.*[\\/]//g`" - fi - # Edit out `#line' or `#' directives. - # - # We don't want the resulting debug information to point at - # an absolute srcdir; it is better for it to just mention the - # .y file with no path. - # - # We want to use the real output file name, not yy.lex.c for - # instance. - # - # We want the include guards to be adjusted too. - FROM=`echo "$from" | sed \ - -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'\ - -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'` - TARGET=`echo "$2" | sed \ - -e 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/'\ - -e 's/[^ABCDEFGHIJKLMNOPQRSTUVWXYZ]/_/g'` - - sed -e "/^#/!b" -e "s,$input_rx,," -e "s,$from,$2," \ - -e "s,$FROM,$TARGET," "$from" >"$target" || ret=$? - - # Check whether header files must be updated. - if test $first = no; then - if test -f "$realtarget" && cmp -s "$realtarget" "$target"; then - echo "$2" is unchanged - rm -f "$target" - else - echo updating "$2" - mv -f "$target" "$realtarget" - fi - fi - else - # A missing file is only an error for the first file. This - # is a blatant hack to let us support using "yacc -d". If -d - # is not specified, we don't want an error when the header - # file is "missing". - if test $first = yes; then - ret=1 - fi - fi - shift - shift - first=no - done -else - ret=$? -fi - -# Remove the directory. -cd .. -rm -rf $dirname - -exit $ret - -# Local Variables: -# mode: shell-script -# sh-indentation: 2 -# eval: (add-hook 'write-file-hooks 'time-stamp) -# time-stamp-start: "scriptversion=" -# time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-end: "$" -# End: diff --git a/aux/broctl/BroControl/__init__.py b/aux/broctl/BroControl/__init__.py deleted file mode 100644 index 4f3d61a5d8..0000000000 --- a/aux/broctl/BroControl/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -# $Id: __init__.py 6811 2009-07-06 20:41:10Z robin $ -# -# Intentionally empty. diff --git a/aux/broctl/BroControl/config.py b/aux/broctl/BroControl/config.py deleted file mode 100644 index 86b4bfd2e2..0000000000 --- a/aux/broctl/BroControl/config.py +++ /dev/null @@ -1,513 +0,0 @@ -#! /usr/bin/env python -# -# $Id: config.py 6948 2009-12-03 20:59:41Z robin $ -# -# Functions to read and access the broctl configuration. - -import os -import sys -import socket -import imp -import re - -import ConfigParser - -import options -import execute -import util - -# One broctl node. -class Node: - - # Valid tags in nodes file. The values will be stored - # in attributes of the same name. - _tags = { "type": 1, "host": 1, "interface": 1, "aux_scripts": 1, "brobase": 1, "ether": 1 } - - def __init__(self, tag): - self.tag = tag - - def __str__(self): - def fmt(v): - if type(v) == type([]): - v = ",".join(v) - return v - - return ("%15s - " % self.tag) + " ".join(["%s=%s" % (k, fmt(self.__dict__[k])) for k in sorted(self.__dict__.keys())]) - - # Returns the working directory for this node. - def cwd(self): - return os.path.join(Config.spooldir, self.tag) - - # Stores the nodes process ID. - def setPID(self, pid): - Config._setState("%s-pid" % self.tag, str(pid)) - - # Returns the stored process ID. - def getPID(self): - t = "%s-pid" % self.tag - if t in Config.state: - return Config.state[t] - return None - - # Unsets the stored process ID. - def clearPID(self): - Config._setState("%s-pid" % self.tag, "") - - # Mark node as having terminated unexpectedly. - def setCrashed(self): - Config._setState("%s-crashed" % self.tag, "1") - - # Unsets the flag for unexpected termination. - def clearCrashed(self): - Config._setState("%s-crashed" % self.tag, "0") - - # Returns true if node has terminated unexpectedly. - def hasCrashed(self): - t = "%s-crashed" % self.tag - return t in Config.state and Config.state[t] == "1" - - # Set the Bro port this node is using. - def setPort(self, port): - Config._setState("%s-port" % self.tag, str(port)) - - # Get the Bro port this node is using. - def getPort(self): - t = "%s-port" % self.tag - return t in Config.state and int(Config.state[t]) or -1 - -# Class managing types of analysis. -class Analysis: - def __init__(self, cfgfile): - - self.types = {} - cnt = 0 - - if not os.path.exists(cfgfile): - if Installing: - return - - util.error("analysis configuration %s does not exist" % cfgfile) - - for line in open(cfgfile): - cnt += 1 - line = line.strip() - if not line or line.startswith("#"): - continue - - f = line.split() - if len(f) < 2: - util.warn("cannot parse line %d in %s" % (cnt, cfgfile)) - continue - - type = f[0] - mechanism = f[1] - descr = "" - if len(f) > 2: - descr = " ".join(f[2:]) - - self.types[type] = (mechanism, descr) - - # Returns true if we know this kind of analysis. - def isValid(self, type): - return type in self.types - - # Returns true if type is enabled. - # Default is yes if we haven't disabled it. - def isEnabled(self, type): - tag = "analysis-%s" % type - try: - return int(Config.state[tag]) != 0 - except KeyError: - return True - - # Enable/disable type. - def toggle(self, type, enable=True): - tag = "analysis-%s" % type - if enable: - try: - del Config.state[tag] - except KeyError: - pass - else: - Config.state[tag] = 0 - - # Returns tuples (type, status, mechanism, descr) of all known analysis types. - # 'type' is tag for analysis. - # 'status' is True if analysis is activated. - # 'mechanism' gives the method how to control the analysis within Bro (see etc/analysis.dat). - # 'descr' is textual dscription for the kind of analysis. - def all(self): - result = [] - keys = self.types.keys() - keys.sort() - for type in keys: - (mechanism, descr) = self.types[type] - result += [(type, self.isEnabled(type), mechanism, descr)] - return result - -# Class storing the broctl configuration. -# -# This class provides access to four types of configuration/state: -# -# - the global broctl configuration from broctl.cfg -# - the node configuration from nodes.cfg -# - dynamic state variables which are kept across restarts in spool/broctl.dat -# - types of analysis which can be toggled via the shell - -Config = None # Globally accessible instance of Configuration. -Installing = False -BroBase = None -MakeDestDir = None - -class Configuration: - def __init__(self, config, basedir, distdir, version, standalone): - global Config - global Installing - - Config = self - - if "BROCTL_INSTALL" in os.environ: - Installing = True - - global BroBase - BroBase = basedir - - if "MAKE_DESTDIR" in os.environ: - global MakeDestDir - MakeDestDir = os.environ["MAKE_DESTDIR"] - - self.config = {} - self.state = {} - - # Read broctl.cfg. - self.config = self._readConfig(os.path.join(basedir, config)) - - # Set defaults for options we get passed in. - self._setOption("brobase", basedir) - self._setOption("distdir", distdir) - self._setOption("version", version) - self._setOption("standalone", standalone and "1" or "0") - - # Initialize options. - for opt in options.options: - if not opt.dontinit: - self._setOption(opt.name.lower(), opt.default) - - # Set defaults for options we derive dynamically. - self._setOption("mailto", "%s" % os.getenv("USER")) - self._setOption("mailfrom", "Big Brother " % socket.gethostname()) - self._setOption("home", os.getenv("HOME")) - self._setOption("mailalarmsto", self.config["mailto"]) - - # Determine operating system. - (success, output) = execute.captureCmd("uname") - if not success: - util.error("cannot run uname") - self._setOption("os", output[0].lower().strip()) - - # Find the time command (should be a GNU time for best results). - (success, output) = execute.captureCmd("which time") - self._setOption("time", output[0].lower().strip()) - - # Read nodes.cfg and broctl.dat. - self._readNodes() - self.readState() - - # Setup the kinds of analyses which we support. - self._analysis = Analysis(self.analysiscfg) - - # Make sure cron flag is cleared. - self.config["cron"] = "0" - - # Provides access to the configuration options via the dereference operator. - # Lookups the attribute in broctl.cfg first, then in the dynamic variables from broctl.dat. - # Defaults to empty string for unknown options. - def __getattr__(self, attr): - if attr in self.config: - return self.config[attr] - if attr in self.state: - return self.state[attr] - return "" - - # Returns True if attribute is defined. - def hasAttr(self, attr): - if attr in self.config: - return True - if attr in self.state: - return True - return False - - # Returns a list of all broctl.cfg entries. - # Includes dynamic variables if dynamic is true. - def options(self, dynamic=True): - if dynamic: - return self.config.items() + self.state.items() - else: - return self.config.items() - - # Returns a list of Nodes. - # - If tag is "global" or "all", all Nodes are returned if "expand_all" is true. - # If "expand_all" is false, returns an empty list in this case. - # - If tag is "proxies" or "proxy", all proxy Nodes are returned. - # - If tag is "workers" or "worker", all worker Nodes are returned. - # - If tag is "manager", the manager Node is returned. - def nodes(self, tag=None, expand_all=True): - nodes = [] - type = None - - if tag == "cluster" or tag == "all": - if not expand_all: - return [] - - tag = None - - if tag == "proxies": - tag = "proxy" - - if tag == "workers": - tag = "worker" - - if ("scripts-%s" % tag) in self.config: - type = tag - - for n in self.nodelist.values(): - - if type: - if type == n.type: - nodes += [n] - - elif tag == n.tag or not tag: - nodes += [n] - - nodes.sort(key=lambda n: (n.type, n.tag)) - - if not nodes and tag == "manager": - nodes = self.nodes("standalone") - - return nodes - - # Returns the manager Node. - def manager(self): - n = self.nodes("manager") - if n: - return n[0] - n = self.nodes("standalone") - if n: - return n[0] - return None - - # Returns a list of nodes which is a subset of the result a similar call to - # nodes() would yield but within which each host appears only once. - def hosts(self, tag = None): - hosts = {} - for node in self.nodes(tag): - if not node.host in hosts: - hosts[node.host] = node - - return hosts.values() - - # Replace all occurences of "${option}", with option being either - # broctl.cfg option or a dynamic variable, with the corresponding value. - # Defaults to replacement with the empty string for unknown options. - def subst(self, str, make_dest=True): - while True: - m = re.search(r"(\$\{([A-Za-z]+)(:([^}]+))?\})", str) - if not m: - - # This is a hack to support make's DESTDIR: if the env variable - # MAKE_DESTDIR is set, and the string we return starts with our - # installation prefix, we prepend the var's content. This it not - # totally perfect but should do the trick. - if Installing and MakeDestDir and MakeDestDir != "": - - if make_dest and str.startswith(BroBase): - str = MakeDestDir + str - - if not make_dest: - str = str.replace(MakeDestDir, "") - - return str - - key = m.group(2).lower() - if self.hasAttr(key): - value = self.__getattr__(key) - else: - value = m.group(4) - - if not value: - value = "" - - str = str[0:m.start(1)] + value + str[m.end(1):] - - # Returns instance of class Analysis. - def analysis(self): - return self._analysis - - # Parse nodes.cfg. - def _readNodes(self): - self.nodelist = {} - config = ConfigParser.SafeConfigParser() - if not config.read(self.nodecfg) and not Installing: - util.error("cannot read '%s'" % self.nodecfg) - - manager = False - proxy = False - standalone = False - - file = self.nodecfg - - counts = {} - for sec in config.sections(): - - node = Node(sec) - self.nodelist[sec] = node - - for (key, val) in config.items(sec): - if not key in Node._tags: - util.warn("%s: unknown key '%s' in section '%s'" % (file, key, sec)) - continue - - if key == "type": - # We determine which types are valid by checking for having an - # option specifying which scripts to use for it. - cfg = "scripts-%s" % val - if not cfg in self.config: - util.error("%s: unknown type '%s' in section '%s'" % (file, val, sec)) - - self.nodelist[sec].scripts = self.config[cfg].split() - - if val == "manager": - if manager: - util.error("only one manager can be defined") - manager = True - - if val == "proxy": - proxy = True - - if val == "standalone": - standalone = True - - node.__dict__[key] = val - - try: - node.addr = socket.gethostbyname(node.host) - except AttributeError: - util.error("%s: no host given in section '%s'" % (file, sec)) - except socket.gaierror, e: - util.error("%s: unknown host '%s' in section '%s' [%s]" % (file, node.host, sec, e.args[1])) - - # Each node gets a number unique across its type. - type = self.nodelist[sec].type - try: - counts[type] += 1 - except KeyError: - counts[type] = 1 - - node.count = counts[type] - - if self.nodelist: - - if not standalone: - if not manager: - util.error("%s: no manager defined" % file) - - if not proxy: - util.error("%s: no proxy defined" % file) - - else: - if len(self.nodelist) > 1: - util.error("%s: more than one node defined in stand-alone setup" % file) - - for n in self.nodelist.values(): - if n.type == "manager": - if not execute.isLocal(n): - util.error("script must be run on manager node") - - if n.addr == "127.0.0.1" and n.type != "standalone": - util.error("cannot use localhost/127.0.0.1 for manager host in nodes configuration") - - - # Parses broctl.cfg and returns a dictionary of all entries. - def _readConfig(self, file): - config = {} - try: - for line in open(file): - - line = line.strip() - if not line or line.startswith("#"): - continue - - args = line.split("=") - if len(args) != 2: - util.error("%s: syntax error '%s'" % (file, line)) - - (key, val) = args - key = key.strip().lower() - val = val.strip() - - config[key] = val - - except IOError, e: - if not Installing: - util.error("cannot read '%s'" % file) - - return config - - # Initialize a global option if not already set. - def _setOption(self, val, key): - if not val in self.config: - self.config[val] = self.subst(key) - - # Set a dynamic state variable. - def _setState(self, val, key): - self.state[val] = key - - # Read dynamic state variables from {$spooldir}/broctl.dat . - def readState(self): - self.state = self._readConfig(self.statefile) - - # Write the dynamic state variables into {$spooldir}/broctl.dat . - def writeState(self): - try: - out = open(self.statefile, "w") - except IOError: - if not Installing: - util.warn("can't write '%s'" % self.statefile) - return - - print >>out, "# Automatically generated. Do not edit.\n" - - for (key, val) in self.state.items(): - print >>out, "%s = %s" % (key, self.subst(str(val), make_dest=False)) - - # Runs Bro to get its version numbers. - def determineBroVersion(self): - version = None - bro = os.path.join(self.distdir, "src/bro") - if execute.exists(None, bro): - (success, output) = execute.captureCmd("%s -v 2>&1" % bro) - if success: - version = output[0] - - if not version: - # Ok if it's already set. - if "broversion" in self.state: - return - - util.error("cannot find Bro binary to determine version") - - m = re.search(".* version ([^ ]*).*$", version) - if not m: - util.error("cannot determine Bro version [%s]" % version.strip()) - - version = m.group(1) - if version.endswith("-debug"): - version = version[:-6] - - self.state["broversion"] = version - self.state["bro"] = self.subst("${bindir}/bro") - - # Returns true if we're running via "make install" - def installing(self): - return Installing - diff --git a/aux/broctl/BroControl/control.py b/aux/broctl/BroControl/control.py deleted file mode 100644 index fe4b94b9e1..0000000000 --- a/aux/broctl/BroControl/control.py +++ /dev/null @@ -1,1059 +0,0 @@ -#! /usr/bin/env python -# -# $Id: control.py 6948 2009-12-03 20:59:41Z robin $ -# -# Functions to control the nodes' operations. - -import os -import sys -import glob -import fileinput -import time -import tempfile -import re - -import execute -import util -import config -import cron -import install - -# Convert a number into a string with a unit (e.g., 1024 into "1M"). -def prettyPrintVal(val): - for (prefix, unit, factor) in (("", "G", 1024*1024*1024), ("", "M", 1024*1024), ("", "K", 1024), (" ", "", 0)): - if val >= factor: - return "%s%3.0f%s" % (prefix, val / factor, unit) - return val # Should not happen - -# Checks multiple nodes in parallel and returns list of tuples (node, isrunning). -def isRunning(nodes, setcrashed=True): - - results = [] - cmds = [] - - for node in nodes: - pid = node.getPID() - if not pid: - results += [(node, False)] - continue - - cmds += [(node, "check-pid", [pid])] - - for (node, success, output) in execute.runHelperParallel(cmds): - - # If we cannot connect to the host at all, we filter it out because - # the process might actually still be running but we can't tell. - if output == None: - util.warn("cannot connect to %s" % node.tag) - continue - - results += [(node, success)] - - if not success: - if setcrashed: - # Grmpf. It crashed. - node.clearPID(); - node.setCrashed() - - return results - -# Waits for the nodes' Bro processes to reach the given status. -def waitForBros(nodes, status, timeout, ensurerunning): - - # If ensurerunning is true, process must still be running. - if ensurerunning: - running = isRunning(nodes) - else: - running = [(node, True) for node in nodes] - - results = [] - - # Determine set of nodes still to check. - todo = {} - for (node, isrunning) in running: - if isrunning: - todo[node.tag] = node - else: - results += [(node, False)] - - points = False - while True: - - # Determine whether process is still running. We need to do this - # before we get the state to avoid a race condition. - running = isRunning(todo.values(), setcrashed=False) - - # Check nodes' .status file - cmds = [] - for node in todo.values(): - cmds += [(node, "cat-file", ["%s/.status" % node.cwd()])] - - for (node, success, output) in execute.runHelperParallel(cmds): - if success: - try: - (stat, loc) = output[0].split() - if status in stat: - # Status reached. Cool. - del todo[node.tag] - results += [(node, True)] - except IndexError: - # Something's wrong. We give up on that node. - del todo[node.tag] - results += [(node, False)] - - for (node, isrunning) in running: - if node.tag in todo and not isrunning: - # Alright, a dead node's status will not change anymore. - del todo[node.tag] - results += [(node, False)] - - if len(todo) == 0: - # All done. - break - - # Wait a bit before we start over. - time.sleep(1) - - # Timeout reached? - timeout -= 1 - if timeout <= 0: - break - - util.output("%d " % len(todo), nl=False) - points = True - - for node in todo.values(): - # These did time-out. - results += [(node, False)] - - if points: - util.output("%d " % len(todo)) - - return results - -# Build the Bro parameters for the given node. Include -# script for live operation if live is true. -def _makeBroParams(node, live): - args = [] - - if live: - try: - args += ["-i %s " % node.interface] - except AttributeError: - pass - - if config.Config.savetraces == "1": - args += ["-w trace.pcap"] - - args += ["-U .status"] - - args += ["-p broctl"] - - if node.type != "standalone": - args += ["-p cluster"] - else: - args += ["-p standalone"] - - for p in config.Config.prefixes.split(":"): - args += ["-p %s" % p] - - args += ["-p %s" % node.tag] - - args += node.scripts - - if live: - args += ["broctl-live"] - else: - args += ["broctl-check"] - - if node.type == "worker" or node.type == "proxy": - args += config.Config.sitepolicyworker.split() - args += config.Config.auxscriptsworker.split() - - if node.type == "manager": - args += config.Config.sitepolicymanager.split() - args += config.Config.auxscriptsmanager.split() - - if node.type == "standalone": - args += config.Config.sitepolicystandalone.split() - args += config.Config.auxscriptsstandalone.split() - - if "aux_scripts" in node.__dict__: - args += [node.aux_scripts] - - args += ["analysis-policy"] - - if config.Config.broargs: - args += [config.Config.broargs] - -# args += ["-B comm,serial"] - - return args - -# Build the environment variable for the given node. -def _makeEnvParam(node): - env = "" - env = "BRO_%s=%s" % (node.type.upper(), str(node.count)) - - return env - -# Do a "post-terminate crash" for the given nodes. -def _makeCrashReports(nodes): - cmds = [] - for node in nodes: - cmds += [(node, "run-cmd", [os.path.join(config.Config.scriptsdir, "post-terminate"), node.cwd(), "crash"])] - - for (node, success, output) in execute.runHelperParallel(cmds): - if not success: - util.output("cannot run post-terminate for %s" % node.tag) - else: - util.sendMail("Crash report from %s" % node.tag, "\n".join(output)) - - node.clearCrashed() - -# Starts the given nodes. Returns true if all nodes were successfully started. -def _startNodes(nodes): - - result = True - - filtered = [] - # Ignore nodes which are still running. - for (node, isrunning) in isRunning(nodes): - if not isrunning: - filtered += [node] - util.output("starting %s ..." % node.tag) - else: - util.output("%s still running" % node.tag) - - nodes = filtered - - # Generate crash report for any crashed nodes. - crashed = [node for node in nodes if node.hasCrashed()] - _makeCrashReports(crashed) - - # Make working directories. - dirs = [(node, node.cwd()) for node in nodes] - nodes = [] - for (node, success) in execute.mkdirs(dirs): - if success: - nodes += [node] - else: - util.output("cannot create working directory for %s" % node.tag) - result = False - - # Start Bro process. - cmds = [] - envs = [] - for node in nodes: - cmds += [(node, "start", [node.cwd()] + _makeBroParams(node, True))] - envs += [_makeEnvParam(node)] - - nodes = [] - for (node, success, output) in execute.runHelperParallel(cmds, envs=envs): - if success: - nodes += [node] - node.setPID(int(output[0])) - else: - util.output("cannot start %s" % node.tag) - result = False - - # Check whether processes did indeed start up. - hanging = [] - running = [] - - for (node, success) in waitForBros(nodes, "RUNNING", 3, True): - if success: - running += [node] - else: - hanging += [node] - - # It can happen that Bro hangs in DNS lookups at startup - # which can take a while. At this point we already know - # that the process has been started (waitForBro ensures that). - # If by now there is not a TERMINATED status, we assume that it - # is doing fine and will move on to RUNNING once DNS is done. - for (node, success) in waitForBros(hanging, "TERMINATED", 0, False): - if success: - util.output("%s terminated immediately after starting; check output with \"diag\"" % node.tag) - node.clearPID() - result = False - else: - util.output("(%s still initializing)" % node.tag) - running += [node] - - for node in running: - cron.logAction(node, "started") - - return result - -# Start Bro processes on nodes if not already running. -def start(nodes): - - if len(nodes) > 0: - # User picked nodes to start. - _startNodes(nodes) - return - - # Start all nodes. Do it in the order manager, proxies, workers. - if not _startNodes(config.Config.nodes("manager")): - return - - if not _startNodes(config.Config.nodes("proxies")): - return - - if not _startNodes(config.Config.nodes("workers")): - return - -def _stopNodes(nodes): - - running = [] - - # Check for crashed nodes. - for (node, isrunning) in isRunning(nodes): - if isrunning: - running += [node] - util.output("stopping %s ..." % node.tag) - else: - if node.hasCrashed(): - _makeCrashReports([node]) - util.output("%s not running (was crashed)" % node.tag) - else: - util.output("%s not running" % node.tag) - - # Helper function to stop nodes with given signal. - def stop(nodes, signal): - cmds = [] - for node in nodes: - cmds += [(node, "stop", [node.getPID(), str(signal)])] - - return execute.runHelperParallel(cmds) - - # Stop nodes. - for (node, success, output) in stop(running, 15): - if not success: - util.output("failed to send stop signal to %s" % node.tag) - - if running: - time.sleep(1) - - # Check whether they terminated. - terminated = [] - kill = [] - for (node, success) in waitForBros(running, "TERMINATED", 60, False): - if not success: - # Check whether it crashed during shutdown ... - result = isRunning([node]) - for (node, isrunning) in result: - if isrunning: - util.output("%s did not terminate ... killing ..." % node.tag) - kill += [node] - else: - # crashed flag is set by isRunning(). - util.output("%s crashed during shutdown" % node.tag) - - if len(kill): - # Kill those which did not terminate gracefully. - stop(kill, 9) - # Given them a bit to disappear. - time.sleep(5) - - # Check which are still running. We check all nodes to be on the safe side - # and give them a bit more time to finally disappear. - timeout = 10 - - todo = {} - for node in running: - todo[node.tag] = node - - while True: - - running = isRunning(todo.values(), setcrashed=False) - - for (node, isrunning) in running: - if node.tag in todo and not isrunning: - # Alright, it's gone. - del todo[node.tag] - terminated += [node] - - if len(todo) == 0: - # All done. - break - - # Wait a bit before we start over. - - if timeout <= 0: - break - - time.sleep(1) - timeout -= 1 - - # Do post-terminate cleanup for those which terminated gracefully. - cleanup = [node for node in terminated if not node.hasCrashed()] - - cmds = [] - for node in cleanup: - cmds += [(node, "run-cmd", [os.path.join(config.Config.scriptsdir, "post-terminate"), node.cwd()])] - - for (node, success, output) in execute.runHelperParallel(cmds): - if not success: - util.output("cannot run post-terminate for %s" % node.tag) - cron.logAction(node, "stopped (failed)") - else: - cron.logAction(node, "stopped") - - node.clearPID() - node.clearCrashed() - -# Stop Bro processes on nodes. -def stop(nodes): - - if len(nodes) > 0: - # User picked nodes to stop. - _stopNodes(nodes) - return - - # Start all nodes. Do it in the order workers, proxies, manager. - _stopNodes(config.Config.nodes("workers")) - _stopNodes(config.Config.nodes("proxies")) - _stopNodes(config.Config.nodes("manager")) - -# First stop, then start Bro processes on nodes. -def restart(nodes, clean): - - if len(nodes) > 0: - all_nodes = nodes - else: - all_nodes = config.Config.nodes() - - util.output("stopping ...") - if len(nodes) > 0: - # User picked nodes to restart. - _stopNodes(nodes) - else: - stop([]) - - if clean: - # Can't delete the tmp here because log archival might still be going on there in the background. - cleanup(all_nodes, False) - - util.output("checking configuration ...") - if not checkConfigs(all_nodes): - return - - util.output("installing ...") - install.install(False, False) - - util.output("starting ...") - if len(nodes) > 0: - _startNodes(nodes) - else: - start([]) - -# Output status summary for nodes. -def status(nodes): - - util.output("%-10s %-10s %-10s %-13s %-6s %-6s %-20s " % ("Name", "Type", "Host", "Status", "Pid", "Peers", "Started")) - - all = isRunning(nodes) - running = [] - - cmds1 = [] - cmds2 = [] - for (node, isrunning) in all: - if isrunning: - running += [node] - cmds1 += [(node, "cat-file", ["%s/.startup" % node.cwd()])] - cmds2 += [(node, "cat-file", ["%s/.status" % node.cwd()])] - - startups = execute.runHelperParallel(cmds1) - statuses = execute.runHelperParallel(cmds2) - - startups = dict([(n.tag, success and util.fmttime(output[0]) or "???") for (n, success, output) in startups]) - statuses = dict([(n.tag, success and output[0].split()[0].lower() or "???") for (n, success, output) in statuses]) - - peers = {} - nodes = [n for n in running if statuses[n.tag] == "running"] - for (node, success, args) in _queryPeerStatus(nodes): - if success: - peers[node.tag] = [] - for f in args[0].split(): - (key, val) = f.split("=") - if key == "peer" and val != "": - peers[node.tag] += [val] - else: - peers[node.tag] = None - - for (node, isrunning) in all: - - util.output("%-10s " % node.tag, nl=False) - util.output("%-10s %-10s " % (node.type, node.host), nl=False) - - if isrunning: - util.output("%-13s " % statuses[node.tag], nl=False) - - elif node.hasCrashed(): - util.output("%-13s " % "crashed", nl=False) - else: - util.output("%-13s " % "stopped", nl=False) - - if isrunning: - util.output("%-6s " % node.getPID(), nl=False) - - if node.tag in peers and peers[node.tag] != None: - util.output("%-6d " % len(peers[node.tag]), nl=False) - else: - util.output("%-6s " % "???", nl=False) - - util.output("%-8s " % startups[node.tag], nl=False) - - util.output() - -# Outputs state of remote connections for host. - - -# Helper for getting top output. -# -# Returns tuples of the form (node, error, vals) where 'error' is None if we -# were able to get the data or otherwise a string with an error message; -# in case there's no error, 'vals' is a list of dicts which map tags to their values. -# -# Tags are "pid", "proc", "vsize", "rss", "cpu", and "cmd". -# -# We do all the stuff in parallel across all nodes which is why this looks -# a bit confusing ... -def getTopOutput(nodes): - - results = [] - cmds = [] - - running = isRunning(nodes) - - # Get all the PIDs first. - - pids = {} - parents = {} - - for (node, isrunning) in running: - if isrunning: - pid = node.getPID() - pids[node.tag] = [int(pid)] - parents[node.tag] = pid - - cmds += [(node, "get-childs", [pid])] - else: - results += [(node, "not running", [{}])] - continue - - if not cmds: - return results - - for (node, success, output) in execute.runHelperParallel(cmds): - - if not success: - results += [(node, "cannot get child pids", [{}])] - continue - - pids[node.tag] += [int(line) for line in output] - - cmds = [] - - # Now run top. - for node in nodes: # Do the loop again to keep the order. - if not node.tag in pids: - continue - - cmds += [(node, "top", [])] - - if not cmds: - return results - - for (node, success, output) in execute.runHelperParallel(cmds): - - if not success: - results += [(node, "cannot get top output", [{}])] - - procs = [line.split() for line in output if int(line.split()[0]) in pids[node.tag]] - - if not procs: - # It can happen that on the meantime the process is not there anymore. - results += [(node, "not running", [{}])] - continue - - vals = [] - - for p in procs: - d = {} - d["pid"] = int(p[0]) - d["proc"] = (p[0] == parents[node.tag] and "parent" or "child") - d["vsize"] = int(p[1]) - d["rss"] = int(p[2]) - d["cpu"] = p[3] - d["cmd"] = " ".join(p[4:]) - vals += [d] - - results += [(node, None, vals)] - - return results - -# Produce a top-like output for node's processes. -# If hdr is true, output column headers first. -def top(nodes): - - util.output("%-10s %-10s %-10s %-8s %-8s %-8s %-8s %-8s %-8s" % ("Name", "Type", "Node", "Pid", "Proc", "VSize", "Rss", "Cpu", "Cmd")) - - for (node, error, vals) in getTopOutput(nodes): - - if not error: - for d in vals: - util.output("%-10s " % node.tag, nl=False) - util.output("%-10s " % node.type, nl=False) - util.output("%-10s " % node.host, nl=False) - util.output("%-8s " % d["pid"], nl=False) - util.output("%-8s " % d["proc"], nl=False) - util.output("%-8s " % prettyPrintVal(d["vsize"]), nl=False) - util.output("%-8s " % prettyPrintVal(d["rss"]), nl=False) - util.output("%-8s " % ("%s%%" % d["cpu"]), nl=False) - util.output("%-8s " % d["cmd"], nl=False) - util.output() - else: - util.output("%-10s " % node.tag, nl=False) - util.output("%-8s " % node.type, nl=False) - util.output("%-8s " % node.host, nl=False) - util.output("<%s> " % error, nl=False) - util.output() - -def _doCheckConfig(nodes, installed, list_scripts, fullpaths): - - ok = True - - manager = config.Config.manager() - - all = [(node, os.path.join(config.Config.tmpdir, "check-config-%s" % node.tag)) for node in nodes] - - nodes = [] - for (node, cwd) in all: - if os.path.isdir(cwd): - if not execute.rmdir(config.Config.manager(), cwd): - util.output("cannot remove directory %s on manager" % cwd) - continue - - if not execute.mkdir(config.Config.manager(), cwd): - util.output("cannot create directory %s on manager" % cwd) - continue - - nodes += [(node, cwd)] - - cmds = [] - for (node, cwd) in nodes: - - env = "" - if node.type == "worker" or node.type == "proxy": - env = "BRO_%s=%s" % (node.type.upper(), str(node.count)) - - dashl = list_scripts and ["-l"] or [] - - broargs = " ".join(dashl + _makeBroParams(node, False)) + " terminate" - installed_policies = installed and "1" or "0" - - cmd = os.path.join(config.Config.scriptsdir, "check-config") + " %s %s %s" % (installed_policies, cwd, broargs) - - cmds += [((node, cwd), cmd, env, None)] - - for ((node, cwd), success, output) in execute.runLocalCmdsParallel(cmds): - - if not list_scripts: - - if success: - util.output("%s is ok." % node.tag) - else: - ok = False - util.output("%s failed." % node.tag) - for line in output: - util.output(" %s" % line) - - else: - util.output(node.tag) - for line in output: - if line.find("loading") >= 0: - - line = line.replace("loading ", "") - if not fullpaths: - line = re.sub("\S+/", "", line) - - util.output(" %s" % line) - - if not success: - ok = False - util.output("%s failed to load all scripts correctly." % node.tag) - - execute.rmdir(manager, cwd) - - return ok - -# Check the configuration for nodes without installing first. -def checkConfigs(nodes): - return _doCheckConfig(nodes, False, False, False) - -# Extracts the list of loaded scripts from the -l output. -def listScripts(nodes, paths, check): - _doCheckConfig(nodes, not check, True, paths) - -# Report diagostics for node (e.g., stderr output). -def crashDiag(node): - - util.output("[%s]" % node.tag) - - if not execute.isdir(node, node.cwd()): - util.output("No work dir found\n") - return - - (rc, output) = execute.runHelper(node, "run-cmd", [os.path.join(config.Config.scriptsdir, "crash-diag"), node.cwd()]) - if not rc: - util.output("cannot run crash-diag for %s" % node.tag) - return - - for line in output: - util.output(line) - -# Clean up the working directory for nodes (flushes state). -# If cleantmp is true, also wipes ${tmpdir}; this is done -# even when the node is still running. -def cleanup(nodes, cleantmp=False): - util.output("cleaning up nodes ...") - result = isRunning(nodes) - running = [node for (node, on) in result if on] - notrunning = [node for (node, on) in result if not on] - - execute.rmdirs([(n, n.cwd()) for n in notrunning]) - execute.mkdirs([(n, n.cwd()) for n in notrunning]) - - for node in notrunning: - node.clearCrashed(); - - for node in running: - util.output(" %s is still running, not cleaning work directory" % node.tag) - - if cleantmp: - execute.rmdirs([(n, config.Config.tmpdir) for n in running + notrunning]) - execute.mkdirs([(n, config.Config.tmpdir) for n in running + notrunning]) - -# Attach gdb to the main Bro processes on the given nodes. -def attachGdb(nodes): - running = isRunning(nodes) - - cmds = [] - for (node, isrunning) in running: - if isrunning: - cmds += [(node, "gdb-attach", ["gdb-%s" % node.tag, config.Config.bro, node.getPID()])] - - results = execute.runHelperParallel(cmds) - for (node, success, output) in results: - if success: - util.output("gdb attached on %s" % node.tag) - else: - util.output("cannot attach gdb on %s: %s" % node.tag, output) - -# Helper for getting capstats output. -# -# Returns tuples of the form (node, error, vals) where 'error' is None if we -# were able to get the data or otherwise a string with an error message; -# in case there's no error, 'vals' maps tags to their values. -# -# Tags are those as returned by capstats on the command-line -# -# We do all the stuff in parallel across all nodes which is why this looks -# a bit confusing ... - -# Gather capstats from interfaces. -def getCapstatsOutput(nodes, interval): - - if not config.Config.capstats: - if config.Config.cron == "0": - util.warn("do not have capstats binary available") - return [] - - results = [] - cmds = [] - - hosts = {} - for node in nodes: - try: - hosts[(node.addr, node.interface)] = node - except AttributeError: - continue - - for (addr, interface) in hosts.keys(): - node = hosts[addr, interface] - - capstats = [config.Config.capstats, "-i", interface, "-I", str(interval), "-n", "1"] - -# Unfinished feature: only consider a particular MAC. Works here for capstats -# but Bro config is not adapted currently so we disable it for now. -# try: -# capstats += ["-f", "\\'", "ether dst %s" % node.ether, "\\'"] -# except AttributeError: -# pass - - cmds += [(node, "run-cmd", capstats)] - - outputs = execute.runHelperParallel(cmds) - - for (node, success, output) in outputs: - - if not success: - results += [(node, "%s: cannot execute capstats" % node.tag, {})] - continue - - fields = output[0].split() - vals = { } - - try: - for field in fields[1:]: - (key, val) = field.split("=") - vals[key] = float(val) - - results += [(node, None, vals)] - - except ValueError: - results += [(node, "%s: unexpected capstats output: %s" % (node.tag, output[0]), {})] - - return results - -# Get current statistics from cFlow. -# -# Returns dict of the form port->(cum-pkts, cum-bytes). -# -# Returns None if we can't run the helper sucessfully. -def getCFlowStatus(): - (success, output) = execute.runLocalCmd(os.path.join(config.Config.scriptsdir, "cflow-stats")) - if not success or not output: - util.warn("failed to run cflow-stats") - return None - - vals = {} - - for line in output: - try: - (port, pps, bps, pkts, bytes) = line.split() - vals[port] = (float(pkts), float(bytes)) - except ValueError: - # Probably an error message because we can't connect. - util.warn("failed to get cFlow statistics: %s" % line) - return None - - return vals - -# Calculates the differences between to getCFlowStatus() calls. -# Returns tuples in the same form as getCapstatsOutput() does. -def calculateCFlowRate(start, stop, interval): - diffs = [(port, stop[port][0] - start[port][0], (stop[port][1] - start[port][1])) for port in start.keys() if port in stop] - - rates = [] - for (port, pkts, bytes) in diffs: - vals = { "kpps": "%.1f" % (pkts / 1e3 / interval) } - if start[port][1] >= 0: - vals["mbps"] = "%.1f" % (bytes * 8 / 1e6 / interval) - - rates += [(port, None, vals)] - - return rates - -def capstats(nodes, interval): - - def output(tag, data): - util.output("\n%-12s %-10s %-10s (%ds average)" % (tag, "kpps", "mbps", interval)) - util.output("-" * 30) - - for (port, error, vals) in data: - - if error: - util.output(error) - continue - - util.output("%-12s " % port, nl=False) - - if not error: - util.output("%-10s " % vals["kpps"], nl=False) - if "mbps" in vals: - util.output("%-10s " % vals["mbps"], nl=False) - util.output() - else: - util.output("<%s> " % error) - - have_cflow = config.Config.cflowaddress and config.Config.cflowuser and config.Config.cflowpassword - have_capstats = config.Config.capstats - - if not have_cflow and not have_capstats: - util.warn("do not have capstats binary available") - return - - if have_cflow: - cflow_start = getCFlowStatus() - - if have_capstats: - capstats = [(node.tag, error, vals) for (node, error, vals) in getCapstatsOutput(nodes, interval)] - - else: - time.sleep(interval) - - if have_cflow: - cflow_stop = getCFlowStatus() - - if have_capstats: - output("Interface", sorted(capstats)) - - if have_cflow and cflow_start and cflow_stop: - diffs = calculateCFlowRate(cflow_start, cflow_stop, interval) - output("cFlow Port", sorted(diffs)) - -# Update the configuration of a running instance on the fly. -def update(nodes): - - running = isRunning(nodes) - - cmds = [] - for (node, isrunning) in running: - if isrunning: - env = _makeEnvParam(node) - env += " BRO_DNS_FAKE=1" - args = " ".join(_makeBroParams(node, False)) - cmds += [(node.tag, os.path.join(config.Config.scriptsdir, "update") + " %s %s" % (node.tag.replace("worker-", "w"), args), env, None)] - util.output("updating %s ..." % node.tag) - - results = execute.runLocalCmdsParallel(cmds) - - for (tag, success, output) in results: - if not success: - util.output("could not update %s: %s" % (tag, output)) - else: - util.output("%s: %s" % (tag, output[0])) - -# Enable/disable types of analysis. -def toggleAnalysis(types, enable=True): - - ana = config.Config.analysis() - - for t in types: - if ana.isValid(t.lower()): - ana.toggle(t.lower(), enable) - else: - util.output("unknown analysis type '%s'" % t) - - -# Print summary of analysis status. -def showAnalysis(): - for (tag, status, mechanism, descr) in config.Config.analysis().all(): - print "%15s is %s - %s" % (tag, (status and "enabled " or "disabled"), descr) - -# Gets disk space on all volumes relevant to broctl installation. -# Returns dict which for each node has a list of tuples (fs, total, used, avail). -def getDf(nodes): - - dirs = ("logdir", "bindir", "helperdir", "cfgdir", "spooldir", "policydir", "libdir", "tmpdir", "staticdir", "scriptsdir") - - df = {} - for node in nodes: - df[node.tag] = {} - - for dir in dirs: - path = config.Config.config[dir] - - cmds = [] - for node in nodes: - cmds += [(node, "df", [path])] - - results = execute.runHelperParallel(cmds) - - for (node, success, output) in results: - if success: - fields = output[0].split() - - # Ignore NFS mounted volumes. - if fields[0].find(":") < 0: - df[node.tag][fields[0]] = fields - - - result = {} - for node in df: - result[node] = df[node].values() - - return result - -def df(nodes): - - util.output("%10s %15s %-5s %-5s %-5s" % ("", "", "total", "avail", "capacity")) - - for (node, dfs) in getDf(nodes).items(): - for df in dfs: - total = float(df[1]) - used = float(df[2]) - avail = float(df[3]) - perc = used * 100.0 / (used + avail) - - util.output("%10s %15s %-5s %-5s %-5.1f%%" % (node, df[0], - prettyPrintVal(total), - prettyPrintVal(avail), perc)) - - -def printID(nodes, id): - running = isRunning(nodes) - - events = [] - for (node, isrunning) in running: - if isrunning: - events += [(node, "request_id", [id], "request_id_response")] - - results = execute.sendEventsParallel(events) - - for (node, success, args) in results: - if success: - print "%10s %s = %s" % (node.tag, args[0], args[1]) - else: - print "%10s " % (node.tag, args) - -def _queryPeerStatus(nodes): - running = isRunning(nodes) - - events = [] - for (node, isrunning) in running: - if isrunning: - events += [(node, "get_peer_status", [], "get_peer_status_response")] - - return execute.sendEventsParallel(events) - -def _queryNetStats(nodes): - running = isRunning(nodes) - - events = [] - for (node, isrunning) in running: - if isrunning: - events += [(node, "get_net_stats", [], "get_net_stats_response")] - - return execute.sendEventsParallel(events) - -def peerStatus(nodes): - for (node, success, args) in _queryPeerStatus(nodes): - if success: - print "%10s\n%s" % (node.tag, args[0]) - else: - print "%10s " % (node.tag, args) - -def netStats(nodes): - for (node, success, args) in _queryNetStats(nodes): - if success: - print "%10s: %s" % (node.tag, args[0]), - else: - print "%10s: " % (node.tag, args) - -def executeCmd(nodes, cmd): - - for special in "|'\"": - cmd = cmd.replace(special, "\\" + special) - - cmds = [(n, "run-cmd", [cmd]) for n in nodes] - - for (node, success, output) in execute.runHelperParallel(cmds): - util.output("[%s] %s\n> %s" % (node.host, (success and " " or "error"), "\n> ".join(output))) - - - diff --git a/aux/broctl/BroControl/cron.py b/aux/broctl/BroControl/cron.py deleted file mode 100644 index 8e77ba6509..0000000000 --- a/aux/broctl/BroControl/cron.py +++ /dev/null @@ -1,242 +0,0 @@ -#! /usr/bin/env python -# -# $Id: cron.py 6813 2009-07-07 18:54:12Z robin $ -# -# Tasks which are to be done on a regular basis from cron. - -import os -import sys - -import util -import config -import execute -import control -import time -import shutil - -# Triggers all activity which is to be done regularly via cron. -def doCron(): - - if config.Config.cronenabled == "0": - return - - if not util.lock(): - return - - util.bufferOutput() - config.Config.config["cron"] = "1" # Flag to indicate that we're running from cron. - - # Check whether nodes are still running an restart if neccessary. - for (node, isrunning) in control.isRunning(config.Config.nodes()): - if not isrunning and node.hasCrashed(): - control.start([node]) - - # Check for dead hosts. - _checkHosts() - - # Generate statistics. - _logStats(5) - - # Check available disk space. - _checkDiskSpace() - - # Expire old log files. - _expireLogs() - - # Update the HTTP stats directory. - _updateHTTPStats() - - # Run external command if we have one. - if config.Config.croncmd: - execute.runLocalCmd(config.Config.croncmd) - - # Mail potential output. - output = util.getBufferedOutput() - if output: - util.sendMail("cron: " + output.split("\n")[0], output) - - config.Config.config["cron"] = "0" - - util.unlock() - -def logAction(node, action): - t = time.time() - out = open(config.Config.statslog, "a") - print >>out, t, node.tag, "action", action - out.close() - -def _logStats(interval): - - nodes = config.Config.nodes() - top = control.getTopOutput(nodes) - - have_cflow = config.Config.cflowaddress and config.Config.cflowuser and config.Config.cflowpassword - have_capstats = config.Config.capstats - cflow_start = cflow_end = None - capstats = [] - cflow_rates = [] - - if have_cflow: - cflow_start = control.getCFlowStatus() - - if have_capstats: - capstats = control.getCapstatsOutput(nodes, interval) - elif have_cflow: - time.sleep(interval) - - if have_cflow: - cflow_end = control.getCFlowStatus() - if cflow_start and cflow_end: - cflow_rates = control.calculateCFlowRate(cflow_start, cflow_end, interval) - - t = time.time() - - out = open(config.Config.statslog, "a") - - for (node, error, vals) in top: - if not error: - for proc in vals: - type = proc["proc"] - for (val, key) in proc.items(): - if val != "proc": - print >>out, t, node.tag, type, val, key - else: - print >>out, t, node.tag, "error", "error", error - - for (node, error, vals) in capstats: - if not error: - for (key, val) in vals.items(): - # Report if we don't see packets on an interface. - tag = "lastpkts-%s" % node.tag - - if key == "pkts": - if tag in config.Config.state: - last = float(config.Config.state[tag]) - else: - last = -1.0 - - if float(val) == 0.0 and last != 0.0: - util.output("%s is not seeing any packets on interface %s" % (node.host, node.interface)) - - if float(val) != 0.0 and last == 0.0: - util.output("%s is seeing packets again on interface %s" % (node.host, node.interface)) - - config.Config._setState(tag, val) - - print >>out, t, node.tag, "interface", key, val - - else: - print >>out, t, node.tag, "error", "error", error - - for (port, error, vals) in cflow_rates: - if not error: - for (key, val) in vals.items(): - print >>out, t, "cflow", port.lower(), key, val - - out.close() - -def _checkDiskSpace(): - - minspace = float(config.Config.mindiskspace) - if minspace == 0.0: - return - - for (node, dfs) in control.getDf(config.Config.nodes()).items(): - for df in dfs: - fs = df[0] - total = float(df[1]) - used = float(df[2]) - avail = float(df[3]) - perc = used * 100.0 / (used + avail) - key = "disk-space-%s%s" % (node, fs.replace("/", "-")) - - if perc > 100 - minspace: - try: - if float(config.Config.state[key]) > 100 - minspace: - # Already reported. - continue - except KeyError: - pass - - util.output("Disk space low on %s:%s - %.1f%% used." % (node, fs, perc)) - - config.Config.state[key] = "%.1f" % perc - -def _expireLogs(): - - i = int(config.Config.logexpireinterval) - - if not i: - return - - (success, output) = execute.runLocalCmd(os.path.join(config.Config.scriptsdir, "expire-logs")) - - if not success: - util.output("error running expire-logs\n\n") - util.output(output) - -def _checkHosts(): - - for node in config.Config.hosts(): - - tag = "alive-%s" % node.host - alive = execute.isAlive(node.addr) and "1" or "0" - - if tag in config.Config.state: - previous = config.Config.state[tag] - - if alive != previous: - util.output("host %s %s" % (node.host, alive == "1" and "up" or "down")) - - config.Config._setState(tag, alive) - -def _getProfLogs(): - - dir = config.Config.statsdir - if not os.path.exists(dir): - os.mkdir(dir) - - if not os.path.exists(dir) or not os.path.isdir(dir): - util.output("cannot create directory %s" % dir) - return - - cmds = [] - - for node in config.Config.hosts(): - cmd = os.path.join(config.Config.scriptsdir, "get-prof-log") + " %s %s %s/prof.log" % (node.tag, node.host, node.cwd()) - cmds += [(node, cmd, [], None)] - - for (node, success, output) in execute.runLocalCmdsParallel(cmds): - if not success: - util.output("cannot get prof.log from %s" % node.tag) - -def _updateHTTPStats(): - - # Get the prof.logs. - _getProfLogs() - - # Copy stats.dat. - shutil.copy(config.Config.statslog, config.Config.statsdir) - - # Creat meta file. - meta = open(os.path.join(config.Config.statsdir, "meta.dat"), "w") - for node in config.Config.hosts(): - print >>meta, "node", node.tag, node.type, node.host - - print >>meta, "time", time.asctime() - print >>meta, "version", config.Config.version - - try: - print >>meta, "os", execute.captureCmd("uname -a")[1][0] - except IndexError: - print >>meta, "os " - - try: - print >>meta, "host", execute.captureCmd("hostname")[1][0] - except IndexError: - print >>meta, "host " - - meta.close() - - - diff --git a/aux/broctl/BroControl/execute.py b/aux/broctl/BroControl/execute.py deleted file mode 100644 index 23e16c8f2a..0000000000 --- a/aux/broctl/BroControl/execute.py +++ /dev/null @@ -1,545 +0,0 @@ -# $Id: execute.py 6956 2009-12-14 22:01:17Z robin $ -# -# These modules provides a set of functions to execute actions on a host. -# If the host is local, it's done direcly; if it's remote we log in via SSH. - -import os -import sys -import socket -import shutil -import re -import util -import time -import subprocess - -import config - -haveBroccoli = True - -try: - import broccoli -except ImportError: - haveBroccoli = False - -LocalAddrs = None - -# Wrapper around subprocess.POpen() -def popen(cmdline, stderr_to_stdout=False): - stderr = None - if stderr_to_stdout: - stderr = subprocess.STDOUT - - # os.setid makes sure that the child process doesn't receive our CTRL-Cs. - proc = subprocess.Popen([cmdline], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=stderr, - close_fds=True, shell=True, preexec_fn=os.setsid) - # Compatibility with older popen4. - proc.tochild = proc.stdin - proc.fromchild = proc.stdout - - return proc - -# Returns true if given node corresponds to the host we're running on. -def isLocal(node): - global LocalAddrs - if not LocalAddrs: - (success, output) = runLocalCmd(os.path.join(config.Config.scriptsdir, "local-interfaces")) - if not success: - if not config.Config.installing(): - util.warn("cannot get list of local IP addresses") - - try: - # This does not work for multi-homed hosts. - LocalAddrs = [socket.gethostbyname(socket.gethostname()), "127.0.0.1"] - except: - LocalAddrs = ["127.0.0.1"] - else: - LocalAddrs = [line.strip() for line in output] - - util.debug(1, "Local IPs: %s" % ",".join(LocalAddrs)) - - return not node or node.host == "localhost" or node.addr in LocalAddrs - -# Takes list of (node, dir) pairs and ensures the directories exist on the nodes' host. -# Returns list of (node, sucess) pairs. -def mkdirs(dirs): - - results = [] - cmds = [] - fullcmds = [] - - for (node, dir) in dirs: - # We make local directories directly. - if isLocal(node): - if not exists(node, dir): - util.debug(1, "%-10s %s" % ("[local]", "mkdir %s" % dir)) - os.mkdir(dir) - - results += [(node, True)] - - else: - cmds += [(node, [], [])] - # Need to be careful here as our helper scripts may not be installed yet. - fullcmds += [("test -d %s || mkdir %s 2>/dev/null; echo $?; echo ~~~" % (dir, dir))] - - for (node, success, output) in runHelperParallel(cmds, fullcmds=fullcmds): - results += [(node, success)] - - return results - -# Takes list of (node, dir) pairs and ensures the directories exist on the nodes' host. -# Returns list of (node, sucess) pairs. -def mkdir(node, dir): - return mkdirs([(node, dir)])[0][1] - -def rmdirs(dirs): - results = [] - cmds = [] - - for (node, dir) in dirs: - # We remove local directories directly. - if isLocal(node): - (success, output) = captureCmd("rm -rf %s" % dir) - results += [(node, success)] - else: - cmds += [(node, "rmdir", [dir])] - - for (node, success, output) in runHelperParallel(cmds): - results += [(node, success)] - - return results - -# Removes the directory on the host if it's there. -def rmdir(node, dir): - return rmdirs([(node, dir)])[0][1] - -# Returns true if the path exists on the host. -def exists(host, path): - if isLocal(host): - return os.path.lexists(path) - else: - (success, output) = runHelper(host, "exists", [path]) - return success - -# Returns true if the path exists and refers to a file on the host. -def isfile(host, path): - if isLocal(host): - return os.path.isfile(path) - else: - util.error("isfile() not yet supported for remote hosts") - -# Returns true if the path exists and refers to a directory on the host. -def isdir(host, path): - if isLocal(host): - return os.path.isdir(path) - else: - (success, output) = runHelper(host, "is-dir", [path]) - return success - -# Copies src to dst, preserving permission bits. -# Works for files and directories (non-recursive). -def install(host, src, dst): - if isLocal(host): - if not exists(host, src): - util.output("file does not exist: %s" % src) - return False - - if os.path.isfile(dst): - os.remove(dst) - - util.debug(1, "cp %s %s" % (src, dst)) - shutil.copy2(src, dst) - return True - else: - util.error("install() not yet supported for remote hosts") - return False - -# rsyns paths from localhost to destination hosts. -def sync(nodes, paths): - - cmds = [] - for n in nodes: - args = ["-a", "--delete", "--rsh=\"ssh -o ConnectTimeout=30\""] - dst = ["%s:%s/" % (n.host, config.Config.brobase)] - args += paths + dst - cmdline = "rsync %s" % " ".join(args) - cmds += [(n, cmdline, "", None)] - - for (id, success, output) in runLocalCmdsParallel(cmds): - if not success: - util.warn("error rsyncing to %s: %s" % (id.host, output)) - -# Checks whether the given host is alive. -_deadHosts = {} - -def isAlive(host): - - if host in _deadHosts: - return False - - (success, output) = runLocalCmd(os.path.join(config.Config.scriptsdir, "is-alive") + " " + host) - - if not success and not config.Config.cron == "1": - _deadHosts[host] = True - util.warn("host %s is not alive" % host) - - return success - -# Runs command locally and returns tuple (success, output) -# with success being true if the command terminated with exit code 0, -# and output being the combinded stdout/stderr output of the command. -def captureCmd(cmd, env = "", input = None): - - cmdline = env + " " + cmd - util.debug(1, "%-10s %s" % ("[local]", cmdline)) - - proc = popen(cmdline, stderr_to_stdout=True) - - if input: - print >>proc.tochild, input - proc.tochild.close() - - rc = proc.wait() - output = [line.strip() for line in proc.fromchild] - - util.debug(1, "%-10s exit code %d" % ("[local]", os.WEXITSTATUS(rc))) - for line in output: - util.debug(2, " > %s" % line) - - return (os.WIFEXITED(rc) and os.WEXITSTATUS(rc) == 0, output) - -## FIXME: Replace "captureCmd" with "runLocalCmd". - -# Runs command locally and returns tuple (success, output) -# with success being true if the command terminated with exit code 0, -# and output being the combinded stdout/stderr output of the command. -def runLocalCmd(cmd, env = "", input=None): - proc = _runLocalCmdInit("single", cmd, env, input) - if not proc: - return (False, []) - - return _runLocalCmdWait(proc) - -# Same as above but runs a set of local commands in parallel. -# Cmds is a list of (id, cmd, envs, input) tuples, where id is -# an arbitrary cookie identifying each command. -# Returns a list of (id, success, output) tuples. -# 'output' is None (vs. []) if we couldn't connect to host. -def runLocalCmdsParallel(cmds): - - results = [] - running = [] - - for (id, cmd, envs, input) in cmds: - proc = _runLocalCmdInit(id, cmd, envs, input) - if proc: - running += [(id, proc)] - else: - results += [(id, False, None)] - - for (id, proc) in running: - status = _runLocalCmdWait(proc) - if status: - (success, output) = status - results += [(id, success, output)] - else: - results += [(id, False, None)] - - return results - -def _runLocalCmdInit(id, cmd, env, input): - - if not env: - env = "" - - cmdline = env + " " + cmd - util.debug(1, "%-10s %s" % ("[local]", cmdline)) - - proc = popen(cmdline, stderr_to_stdout=True) - - if input: - print >>proc.tochild, input - - proc.tochild.close() - return proc - -def stripNL(str): - if len(str) == 0 or str[-1] != "\n": - return str - - return str[0:-1] - -def _runLocalCmdWait(proc): - - rc = proc.wait() - output = [stripNL(line) for line in proc.fromchild] - - util.debug(1, "%-10s exit code %d" % ("[local]", os.WEXITSTATUS(rc))) - for line in output: - util.debug(2, " > %s" % line) - - return (os.WIFEXITED(rc) and os.WEXITSTATUS(rc) == 0, output) - -# Runs a helper script from bin/helpers, according to the helper -# protocol. -# If fullcmd is given, this is the exact & complete command line (incl. paths). -# Otherwise, cmd is just the helper's name (wo/ path) and args are the -# arguments. Env is an optional enviroment variable of the form -# "key=val". Return value as for captureCmd(). -# 'output' is None (vs. []) if we couldn't connect to host. -def runHelper(host, cmd=None, args=None, fullcmd=None, env = ""): - util.disableSignals() - try: - status = _runHelperInit(host, cmd, args, fullcmd, env) - if not status: - return (False, None) - - status = _runHelperWait(status) - if not status: - return (False, None) - - return status - - finally: - util.enableSignals() - -# Same as above but runs commands on a set of hosts in parallel. -# Cmds is a list of (node, cmd, args) tuples. -# Fullcmds, if given, is a parallel list of full command lines. -# Envs, if given, is a parallel list of env variables. -# Returns a list of (node, success, output) tuples. -# 'output' is None (vs. []) if we couldn't connect to host. -def runHelperParallel(cmds, fullcmds = None, envs = None): - - util.disableSignals() - - try: - results = [] - running = [] - - for (node, cmd, args) in cmds: - - if fullcmds: - fullcmd = fullcmds[0] - fullcmds = fullcmds[1:] - else: - fullcmd = "" - - if envs: - env = envs[0] - envs = envs[1:] - else: - env = "" - - status = _runHelperInit(node, cmd, args, fullcmd, env) - if status: - running += [node] - else: - results += [(node, False, None)] - - for node in running: - status = _runHelperWait(node) - if status: - (success, output) = status - results += [(node, success, output)] - else: - results += [(node, False, None)] - - return results - - finally: - util.enableSignals() - -# Helpers for running helpers. -# -# We keep the SSH sessions open across calls to runHelper. -Connections = {} -WhoAmI = None - -# FIXME: This is an ugly hack. The __del__ method produces -# strange unhandled exceptions in the child at termination -# of the main process. Not sure if disabling the cleanup -# altogether is a good thing but right now that's the -# only fix I can come up with. -def _emptyDel(self): - pass -subprocess.Popen.__del__ = _emptyDel - -def _getConnection(host): - - global WhoAmI - if not WhoAmI: - (success, output) = captureCmd("whoami") - if not success: - util.error("can't get 'whoami'") - WhoAmI = output[0] - - if not host: - host = config.Config.manager() - - if host.tag in Connections: - p = Connections[host.tag] - if p.poll() != None: - # Terminated. - global _deadHosts - _deadHosts[host.host] = True - util.warn("connection to %s broke" % host.host) - return None - - return (p.stdin, p.stdout) - - if isLocal(host): - cmdline = "sh" - else: - # Check whether host is alive. - if not isAlive(host.host): - return None - - cmdline = "ssh -o ConnectTimeout=30 -l %s %s sh" % (WhoAmI, host.host) - - util.debug(1, "%-10s %s" % ("[local]", cmdline)) - - try: - p = popen(cmdline) - except OSError, e: - util.warn("cannot login into %s [IOError: %s]" % (host.host, e)) - return None - - Connections[host.tag] = p - return (p.stdin, p.stdout) - -def _runHelperInit(host, cmd, args, fullcmd, env): - - c = _getConnection(host) - if not c: - return None - - (stdin, stdout) = c - - if not fullcmd: - cmdline = "%s %s %s" % (env, os.path.join(config.Config.helperdir, cmd), " ".join(args)) - else: - cmdline = fullcmd - - util.debug(1, "%-10s %s" % (("[%s]" % host.host), cmdline)) - print >>stdin, cmdline - stdin.flush() - - return host - -def _runHelperWait(host): - output = [] - while True: - - c = _getConnection(host) - if not c: - return None - - (stdin, stdout) = c - - line = stdout.readline().strip() - if line == "~~~": - break - output += [line] - - try: - rc = int(output[0]) - except ValueError: - util.warn("cannot parse exit code from helper on %s: %s" % (host.host, output[0])) - rc = 1 - - util.debug(1, "%-10s exit code %d" % (("[%s]" % host.host), rc)) - - for line in output: - util.debug(2, " > %s" % line) - - return (rc == 0, output[1:]) - -# Broccoli communication with running nodes. - -# Sends event to a set of nodes in parallel. -# -# events is a list of tuples of the form (node, event, args, result_event). -# node: the destination node. -# event: the name of the event to send (node that receiver must subscribe to it as well). -# args: a list of event args; each arg must be a data type understood by the Broccoli module. -# result_event: name of a event the node sends back. None if no event is sent back. -# -# Returns a list of tuples (node, success, results_args). -# If success is True, result_args is a list of arguments as shipped with the result event, -# or [] if no result_event was specified. -# If success is False, results_args is a string with an error message. - -def sendEventsParallel(events): - - results = [] - sent = [] - - for (node, event, args, result_event) in events: - - if not haveBroccoli: - results += [(node, False, "no Python bindings for Broccoli installed")] - continue - - (success, bc) = _sendEventInit(node, event, args, result_event) - if success and result_event: - sent += [(node, result_event, bc)] - else: - results += [(node, success, bc)] - - for (node, result_event, bc) in sent: - (success, result_args) = _sendEventWait(node, result_event, bc) - results += [(node, success, result_args)] - - return results - -def _sendEventInit(node, event, args, result_event): - - try: - bc = broccoli.Connection("%s:%d" % (node.addr, node.getPort()), broclass="update", - flags=broccoli.BRO_CFLAG_ALWAYS_QUEUE, connect=False) - bc.subscribe(result_event, _event_callback(bc)) - bc.got_result = False - bc.connect() - except IOError, e: - util.debug(1, "%-10s broccoli: cannot connect" % (("[%s]" % node.tag))) - return (False, str(e)) - - util.debug(1, "%-10s broccoli: %s(%s)" % (("[%s]" % node.tag), event, ", ".join(args))) - bc.send(event, *args) - return (True, bc) - -def _sendEventWait(node, result_event, bc): - # Wait until we have sent the event out. - cnt = 0 - while bc.processInput(): - time.sleep(1) - - cnt += 1 - if cnt > 10: - util.debug(1, "%-10s broccoli: timeout during send" % (("[%s]" % node.tag))) - return (False, "time-out") - - if not result_event: - return (True, []) - - # Wait for reply event. - cnt = 0 - bc.processInput(); - while not bc.got_result: - time.sleep(1) - bc.processInput(); - - cnt += 1 - if cnt > 10: - util.debug(1, "%-10s broccoli: timeout during receive" % (("[%s]" % node.tag))) - return (False, "time-out") - - util.debug(1, "%-10s broccoli: %s(%s)" % (("[%s]" % node.tag), result_event, ", ".join(bc.result_args))) - return (True, bc.result_args) - -def _event_callback(bc): - def save_results(*args): - bc.got_result = True - bc.result_args = args - return save_results - diff --git a/aux/broctl/BroControl/install.py b/aux/broctl/BroControl/install.py deleted file mode 100644 index 77bf36603d..0000000000 --- a/aux/broctl/BroControl/install.py +++ /dev/null @@ -1,556 +0,0 @@ -#! /usr/bin/env python -# -# $Id: install.py 6948 2009-12-03 20:59:41Z robin $ -# -# Functions to install files on all nodes. - -import os -import sys -import glob -import fileinput - -import util -import execute -import config - -# In all paths given in this file, ${