aboutsummaryrefslogtreecommitdiffstats
path: root/config/snort-dev/patches
diff options
context:
space:
mode:
Diffstat (limited to 'config/snort-dev/patches')
-rw-r--r--config/snort-dev/patches/SnortSam/TODAO.txt1
-rw-r--r--config/snort-dev/patches/SnortSam/snortsam-2.8.6.1.diff3021
-rw-r--r--config/snort-dev/patches/inlinemode_options_flags.txt0
-rw-r--r--config/snort-dev/patches/spoink_patch/2.8.6/Makefile.am17
-rw-r--r--config/snort-dev/patches/spoink_patch/2.8.6/Makefile.in445
-rw-r--r--config/snort-dev/patches/spoink_patch/2.8.6/plugbase.c1544
-rw-r--r--config/snort-dev/patches/spoink_patch/2.8.6/util.c3233
-rw-r--r--config/snort-dev/patches/spoink_patch/spo_pf.c462
-rw-r--r--config/snort-dev/patches/spoink_patch/spo_pf.h60
9 files changed, 0 insertions, 8783 deletions
diff --git a/config/snort-dev/patches/SnortSam/TODAO.txt b/config/snort-dev/patches/SnortSam/TODAO.txt
deleted file mode 100644
index 3abf0303..00000000
--- a/config/snort-dev/patches/SnortSam/TODAO.txt
+++ /dev/null
@@ -1 +0,0 @@
-Patch current snort 2.9 \ No newline at end of file
diff --git a/config/snort-dev/patches/SnortSam/snortsam-2.8.6.1.diff b/config/snort-dev/patches/SnortSam/snortsam-2.8.6.1.diff
deleted file mode 100644
index 983165e1..00000000
--- a/config/snort-dev/patches/SnortSam/snortsam-2.8.6.1.diff
+++ /dev/null
@@ -1,3021 +0,0 @@
-Index: snort-2.8.6.1/src/twofish.c
-===================================================================
---- snort-2.8.6.1/src/twofish.c (Revision 0)
-+++ snort-2.8.6.1/src/twofish.c (Revision 3)
-@@ -0,0 +1,971 @@
-+/* $Id: twofish.c,v 2.1 2008/12/15 20:36:05 fknobbe Exp $
-+ *
-+ *
-+ * Copyright (C) 1997-2000 The Cryptix Foundation Limited.
-+ * Copyright (C) 2000 Farm9.
-+ * Copyright (C) 2001 Frank Knobbe.
-+ * All rights reserved.
-+ *
-+ * For Cryptix code:
-+ * Use, modification, copying and distribution of this software is subject
-+ * the terms and conditions of the Cryptix General Licence. You should have
-+ * received a copy of the Cryptix General Licence along with this library;
-+ * if not, you can download a copy from http://www.cryptix.org/ .
-+ *
-+ * For Farm9:
-+ * --- jojo@farm9.com, August 2000, converted from Java to C++, added CBC mode and
-+ * ciphertext stealing technique, added AsciiTwofish class for easy encryption
-+ * decryption of text strings
-+ *
-+ * Frank Knobbe <frank@knobbe.us>:
-+ * --- April 2001, converted from C++ to C, prefixed global variables
-+ * with TwoFish, substituted some defines, changed functions to make use of
-+ * variables supplied in a struct, modified and added routines for modular calls.
-+ * Cleaned up the code so that defines are used instead of fixed 16's and 32's.
-+ * Created two general purpose crypt routines for one block and multiple block
-+ * encryption using Joh's CBC code.
-+ * Added crypt routines that use a header (with a magic and data length).
-+ * (Basically a major rewrite).
-+ *
-+ * Note: Routines labeled _TwoFish are private and should not be used
-+ * (or with extreme caution).
-+ *
-+ */
-+
-+#ifndef __TWOFISH_LIBRARY_SOURCE__
-+#define __TWOFISH_LIBRARY_SOURCE__
-+
-+#include <string.h>
-+#include <stdlib.h>
-+#include <time.h>
-+#include <ctype.h>
-+#include <sys/types.h>
-+
-+#ifdef WIN32
-+
-+#ifndef u_long
-+typedef unsigned long u_long;
-+#endif
-+#ifndef u_int32_t
-+typedef unsigned long u_int32_t;
-+#endif
-+#ifndef u_word
-+typedef unsigned short u_word;
-+#endif
-+#ifndef u_int16_t
-+typedef unsigned short u_int16_t;
-+#endif
-+#ifndef u_char
-+typedef unsigned char u_char;
-+#endif
-+#ifndef u_int8_t
-+typedef unsigned char u_int8_t;
-+#endif
-+
-+#endif /* WIN32 */
-+
-+#include "twofish.h"
-+
-+
-+bool TwoFish_srand=TRUE; /* if TRUE, first call of TwoFishInit will seed rand(); */
-+ /* of TwoFishInit */
-+
-+/* Fixed 8x8 permutation S-boxes */
-+static const u_int8_t TwoFish_P[2][256] =
-+{
-+ { /* p0 */
-+ 0xA9, 0x67, 0xB3, 0xE8, 0x04, 0xFD, 0xA3, 0x76, 0x9A, 0x92, 0x80, 0x78,
-+ 0xE4, 0xDD, 0xD1, 0x38, 0x0D, 0xC6, 0x35, 0x98, 0x18, 0xF7, 0xEC, 0x6C,
-+ 0x43, 0x75, 0x37, 0x26, 0xFA, 0x13, 0x94, 0x48, 0xF2, 0xD0, 0x8B, 0x30,
-+ 0x84, 0x54, 0xDF, 0x23, 0x19, 0x5B, 0x3D, 0x59, 0xF3, 0xAE, 0xA2, 0x82,
-+ 0x63, 0x01, 0x83, 0x2E, 0xD9, 0x51, 0x9B, 0x7C, 0xA6, 0xEB, 0xA5, 0xBE,
-+ 0x16, 0x0C, 0xE3, 0x61, 0xC0, 0x8C, 0x3A, 0xF5, 0x73, 0x2C, 0x25, 0x0B,
-+ 0xBB, 0x4E, 0x89, 0x6B, 0x53, 0x6A, 0xB4, 0xF1, 0xE1, 0xE6, 0xBD, 0x45,
-+ 0xE2, 0xF4, 0xB6, 0x66, 0xCC, 0x95, 0x03, 0x56, 0xD4, 0x1C, 0x1E, 0xD7,
-+ 0xFB, 0xC3, 0x8E, 0xB5, 0xE9, 0xCF, 0xBF, 0xBA, 0xEA, 0x77, 0x39, 0xAF,
-+ 0x33, 0xC9, 0x62, 0x71, 0x81, 0x79, 0x09, 0xAD, 0x24, 0xCD, 0xF9, 0xD8,
-+ 0xE5, 0xC5, 0xB9, 0x4D, 0x44, 0x08, 0x86, 0xE7, 0xA1, 0x1D, 0xAA, 0xED,
-+ 0x06, 0x70, 0xB2, 0xD2, 0x41, 0x7B, 0xA0, 0x11, 0x31, 0xC2, 0x27, 0x90,
-+ 0x20, 0xF6, 0x60, 0xFF, 0x96, 0x5C, 0xB1, 0xAB, 0x9E, 0x9C, 0x52, 0x1B,
-+ 0x5F, 0x93, 0x0A, 0xEF, 0x91, 0x85, 0x49, 0xEE, 0x2D, 0x4F, 0x8F, 0x3B,
-+ 0x47, 0x87, 0x6D, 0x46, 0xD6, 0x3E, 0x69, 0x64, 0x2A, 0xCE, 0xCB, 0x2F,
-+ 0xFC, 0x97, 0x05, 0x7A, 0xAC, 0x7F, 0xD5, 0x1A, 0x4B, 0x0E, 0xA7, 0x5A,
-+ 0x28, 0x14, 0x3F, 0x29, 0x88, 0x3C, 0x4C, 0x02, 0xB8, 0xDA, 0xB0, 0x17,
-+ 0x55, 0x1F, 0x8A, 0x7D, 0x57, 0xC7, 0x8D, 0x74, 0xB7, 0xC4, 0x9F, 0x72,
-+ 0x7E, 0x15, 0x22, 0x12, 0x58, 0x07, 0x99, 0x34, 0x6E, 0x50, 0xDE, 0x68,
-+ 0x65, 0xBC, 0xDB, 0xF8, 0xC8, 0xA8, 0x2B, 0x40, 0xDC, 0xFE, 0x32, 0xA4,
-+ 0xCA, 0x10, 0x21, 0xF0, 0xD3, 0x5D, 0x0F, 0x00, 0x6F, 0x9D, 0x36, 0x42,
-+ 0x4A, 0x5E, 0xC1, 0xE0
-+ },
-+ { /* p1 */
-+ 0x75, 0xF3, 0xC6, 0xF4, 0xDB, 0x7B, 0xFB, 0xC8, 0x4A, 0xD3, 0xE6, 0x6B,
-+ 0x45, 0x7D, 0xE8, 0x4B, 0xD6, 0x32, 0xD8, 0xFD, 0x37, 0x71, 0xF1, 0xE1,
-+ 0x30, 0x0F, 0xF8, 0x1B, 0x87, 0xFA, 0x06, 0x3F, 0x5E, 0xBA, 0xAE, 0x5B,
-+ 0x8A, 0x00, 0xBC, 0x9D, 0x6D, 0xC1, 0xB1, 0x0E, 0x80, 0x5D, 0xD2, 0xD5,
-+ 0xA0, 0x84, 0x07, 0x14, 0xB5, 0x90, 0x2C, 0xA3, 0xB2, 0x73, 0x4C, 0x54,
-+ 0x92, 0x74, 0x36, 0x51, 0x38, 0xB0, 0xBD, 0x5A, 0xFC, 0x60, 0x62, 0x96,
-+ 0x6C, 0x42, 0xF7, 0x10, 0x7C, 0x28, 0x27, 0x8C, 0x13, 0x95, 0x9C, 0xC7,
-+ 0x24, 0x46, 0x3B, 0x70, 0xCA, 0xE3, 0x85, 0xCB, 0x11, 0xD0, 0x93, 0xB8,
-+ 0xA6, 0x83, 0x20, 0xFF, 0x9F, 0x77, 0xC3, 0xCC, 0x03, 0x6F, 0x08, 0xBF,
-+ 0x40, 0xE7, 0x2B, 0xE2, 0x79, 0x0C, 0xAA, 0x82, 0x41, 0x3A, 0xEA, 0xB9,
-+ 0xE4, 0x9A, 0xA4, 0x97, 0x7E, 0xDA, 0x7A, 0x17, 0x66, 0x94, 0xA1, 0x1D,
-+ 0x3D, 0xF0, 0xDE, 0xB3, 0x0B, 0x72, 0xA7, 0x1C, 0xEF, 0xD1, 0x53, 0x3E,
-+ 0x8F, 0x33, 0x26, 0x5F, 0xEC, 0x76, 0x2A, 0x49, 0x81, 0x88, 0xEE, 0x21,
-+ 0xC4, 0x1A, 0xEB, 0xD9, 0xC5, 0x39, 0x99, 0xCD, 0xAD, 0x31, 0x8B, 0x01,
-+ 0x18, 0x23, 0xDD, 0x1F, 0x4E, 0x2D, 0xF9, 0x48, 0x4F, 0xF2, 0x65, 0x8E,
-+ 0x78, 0x5C, 0x58, 0x19, 0x8D, 0xE5, 0x98, 0x57, 0x67, 0x7F, 0x05, 0x64,
-+ 0xAF, 0x63, 0xB6, 0xFE, 0xF5, 0xB7, 0x3C, 0xA5, 0xCE, 0xE9, 0x68, 0x44,
-+ 0xE0, 0x4D, 0x43, 0x69, 0x29, 0x2E, 0xAC, 0x15, 0x59, 0xA8, 0x0A, 0x9E,
-+ 0x6E, 0x47, 0xDF, 0x34, 0x35, 0x6A, 0xCF, 0xDC, 0x22, 0xC9, 0xC0, 0x9B,
-+ 0x89, 0xD4, 0xED, 0xAB, 0x12, 0xA2, 0x0D, 0x52, 0xBB, 0x02, 0x2F, 0xA9,
-+ 0xD7, 0x61, 0x1E, 0xB4, 0x50, 0x04, 0xF6, 0xC2, 0x16, 0x25, 0x86, 0x56,
-+ 0x55, 0x09, 0xBE, 0x91
-+ }
-+};
-+
-+static bool TwoFish_MDSready=FALSE;
-+static u_int32_t TwoFish_MDS[4][256]; /* TwoFish_MDS matrix */
-+
-+
-+#define TwoFish_LFSR1(x) (((x)>>1)^(((x)&0x01)?TwoFish_MDS_GF_FDBK/2:0))
-+#define TwoFish_LFSR2(x) (((x)>>2)^(((x)&0x02)?TwoFish_MDS_GF_FDBK/2:0)^(((x)&0x01)?TwoFish_MDS_GF_FDBK/4:0))
-+
-+#define TwoFish_Mx_1(x) ((u_int32_t)(x)) /* force result to dword so << will work */
-+#define TwoFish_Mx_X(x) ((u_int32_t)((x)^TwoFish_LFSR2(x))) /* 5B */
-+#define TwoFish_Mx_Y(x) ((u_int32_t)((x)^TwoFish_LFSR1(x)^TwoFish_LFSR2(x))) /* EF */
-+#define TwoFish_RS_rem(x) { u_int8_t b=(u_int8_t)(x>>24); u_int32_t g2=((b<<1)^((b&0x80)?TwoFish_RS_GF_FDBK:0))&0xFF; u_int32_t g3=((b>>1)&0x7F)^((b&1)?TwoFish_RS_GF_FDBK>>1:0)^g2; x=(x<<8)^(g3<<24)^(g2<<16)^(g3<<8)^b; }
-+
-+/*#define TwoFish__b(x,N) (((u_int8_t *)&x)[((N)&3)^TwoFish_ADDR_XOR])*/ /* pick bytes out of a dword */
-+
-+#define TwoFish_b0(x) TwoFish__b(x,0) /* extract LSB of u_int32_t */
-+#define TwoFish_b1(x) TwoFish__b(x,1)
-+#define TwoFish_b2(x) TwoFish__b(x,2)
-+#define TwoFish_b3(x) TwoFish__b(x,3) /* extract MSB of u_int32_t */
-+
-+u_int8_t TwoFish__b(u_int32_t x,int n)
-+{ n&=3;
-+ while(n-->0)
-+ x>>=8;
-+ return (u_int8_t)x;
-+}
-+
-+
-+/* TwoFish Initialization
-+ *
-+ * This routine generates a global data structure for use with TwoFish,
-+ * initializes important values (such as subkeys, sBoxes), generates subkeys
-+ * and precomputes the MDS matrix if not already done.
-+ *
-+ * Input: User supplied password (will be appended by default password of 'SnortHas2FishEncryptionRoutines!')
-+ *
-+ * Output: Pointer to TWOFISH structure. This data structure contains key dependent data.
-+ * This pointer is used with all other crypt functions.
-+ */
-+
-+TWOFISH *TwoFishInit(char *userkey)
-+{ TWOFISH *tfdata;
-+ int i,x,m;
-+ char tkey[TwoFish_KEY_LENGTH+40];
-+
-+ tfdata=malloc(sizeof(TWOFISH)); /* allocate the TwoFish structure */
-+ if(tfdata!=NULL)
-+ { if(*userkey)
-+ { strncpy(tkey,userkey,TwoFish_KEY_LENGTH); /* use first 32 chars of user supplied password */
-+ tkey[TwoFish_KEY_LENGTH]=0; /* make sure it wasn't more */
-+ }
-+ else
-+ strcpy(tkey,TwoFish_DEFAULT_PW); /* if no key defined, use default password */
-+ for(i=0,x=0,m=strlen(tkey);i<TwoFish_KEY_LENGTH;i++) /* copy into data structure */
-+ { tfdata->key[i]=tkey[x++]; /* fill the whole keyspace with repeating key. */
-+ if(x==m)
-+ x=0;
-+ }
-+
-+ if(!TwoFish_MDSready)
-+ _TwoFish_PrecomputeMDSmatrix(); /* "Wake Up, Neo" */
-+ _TwoFish_MakeSubKeys(tfdata); /* generate subkeys */
-+ _TwoFish_ResetCBC(tfdata); /* reset the CBC */
-+ tfdata->output=NULL; /* nothing to output yet */
-+ tfdata->dontflush=FALSE; /* reset decrypt skip block flag */
-+ if(TwoFish_srand)
-+ { TwoFish_srand=FALSE;
-+ srand(time(NULL));
-+ }
-+ }
-+ return tfdata; /* return the data pointer */
-+}
-+
-+
-+void TwoFishDestroy(TWOFISH *tfdata)
-+{ if(tfdata!=NULL)
-+ free(tfdata);
-+}
-+
-+
-+/* en/decryption with CBC mode */
-+unsigned long _TwoFish_CryptRawCBC(char *in,char *out,unsigned long len,bool decrypt,TWOFISH *tfdata)
-+{ unsigned long rl;
-+
-+ rl=len; /* remember how much data to crypt. */
-+ while(len>TwoFish_BLOCK_SIZE) /* and now we process block by block. */
-+ { _TwoFish_BlockCrypt(in,out,TwoFish_BLOCK_SIZE,decrypt,tfdata); /* de/encrypt it. */
-+ in+=TwoFish_BLOCK_SIZE; /* adjust pointers. */
-+ out+=TwoFish_BLOCK_SIZE;
-+ len-=TwoFish_BLOCK_SIZE;
-+ }
-+ if(len>0) /* if we have less than a block left... */
-+ _TwoFish_BlockCrypt(in,out,len,decrypt,tfdata); /* ...then we de/encrypt that too. */
-+ if(tfdata->qBlockDefined && !tfdata->dontflush) /* in case len was exactly one block... */
-+ _TwoFish_FlushOutput(tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE,tfdata); /* ...we need to write the... */
-+ /* ...remaining bytes of the buffer */
-+ return rl;
-+}
-+
-+/* en/decryption on one block only */
-+unsigned long _TwoFish_CryptRaw16(char *in,char *out,unsigned long len,bool decrypt,TWOFISH *tfdata)
-+{ /* qBlockPlain already zero'ed through ResetCBC */
-+ memcpy(tfdata->qBlockPlain,in,len); /* toss the data into it. */
-+ _TwoFish_BlockCrypt16(tfdata->qBlockPlain,tfdata->qBlockCrypt,decrypt,tfdata); /* encrypt just that block without CBC. */
-+ memcpy(out,tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE); /* and return what we got */
-+ return TwoFish_BLOCK_SIZE;
-+}
-+
-+/* en/decryption without reset of CBC and output assignment */
-+unsigned long _TwoFish_CryptRaw(char *in,char *out,unsigned long len,bool decrypt,TWOFISH *tfdata)
-+{
-+ if(in!=NULL && out!=NULL && len>0 && tfdata!=NULL) /* if we have valid data, then... */
-+ { if(len>TwoFish_BLOCK_SIZE) /* ...check if we have more than one block. */
-+ return _TwoFish_CryptRawCBC(in,out,len,decrypt,tfdata); /* if so, use the CBC routines... */
-+ else
-+ return _TwoFish_CryptRaw16(in,out,len,decrypt,tfdata); /* ...otherwise just do one block. */
-+ }
-+ return 0;
-+}
-+
-+
-+/* TwoFish Raw Encryption
-+ *
-+ * Does not use header, but does use CBC (if more than one block has to be encrypted).
-+ *
-+ * Input: Pointer to the buffer of the plaintext to be encrypted.
-+ * Pointer to the buffer receiving the ciphertext.
-+ * The length of the plaintext buffer.
-+ * The TwoFish structure.
-+ *
-+ * Output: The amount of bytes encrypted if successful, otherwise 0.
-+ */
-+
-+unsigned long TwoFishEncryptRaw(char *in,
-+ char *out,
-+ unsigned long len,
-+ TWOFISH *tfdata)
-+{ _TwoFish_ResetCBC(tfdata); /* reset CBC flag. */
-+ tfdata->output=out; /* output straight into output buffer. */
-+ return _TwoFish_CryptRaw(in,out,len,FALSE,tfdata); /* and go for it. */
-+}
-+
-+/* TwoFish Raw Decryption
-+ *
-+ * Does not use header, but does use CBC (if more than one block has to be decrypted).
-+ *
-+ * Input: Pointer to the buffer of the ciphertext to be decrypted.
-+ * Pointer to the buffer receiving the plaintext.
-+ * The length of the ciphertext buffer (at least one cipher block).
-+ * The TwoFish structure.
-+ *
-+ * Output: The amount of bytes decrypted if successful, otherwise 0.
-+ */
-+
-+unsigned long TwoFishDecryptRaw(char *in,
-+ char *out,
-+ unsigned long len,
-+ TWOFISH *tfdata)
-+{ _TwoFish_ResetCBC(tfdata); /* reset CBC flag. */
-+ tfdata->output=out; /* output straight into output buffer. */
-+ return _TwoFish_CryptRaw(in,out,len,TRUE,tfdata); /* and go for it. */
-+}
-+
-+/* TwoFish Free
-+ *
-+ * Free's the allocated buffer.
-+ *
-+ * Input: Pointer to the TwoFish structure
-+ *
-+ * Output: (none)
-+ */
-+
-+void TwoFishFree(TWOFISH *tfdata)
-+{ if(tfdata->output!=NULL) /* if a valid buffer is present... */
-+ { free(tfdata->output); /* ...then we free it for you... */
-+ tfdata->output=NULL; /* ...and mark as such. */
-+ }
-+}
-+
-+/* TwoFish Set Output
-+ *
-+ * If you want to allocate the output buffer yourself,
-+ * then you can set it with this function.
-+ *
-+ * Input: Pointer to your output buffer
-+ * Pointer to the TwoFish structure
-+ *
-+ * Output: (none)
-+ */
-+
-+void TwoFishSetOutput(char *outp,TWOFISH *tfdata)
-+{ tfdata->output=outp; /* (do we really need a function for this?) */
-+}
-+
-+/* TwoFish Alloc
-+ *
-+ * Allocates enough memory for the output buffer that would be required
-+ *
-+ * Input: Length of the plaintext.
-+ * Boolean flag for BinHex Output.
-+ * Pointer to the TwoFish structure.
-+ *
-+ * Output: Returns a pointer to the memory allocated.
-+ */
-+
-+void *TwoFishAlloc(unsigned long len,bool binhex,bool decrypt,TWOFISH *tfdata)
-+{
-+/* TwoFishFree(tfdata); */ /* (don't for now) discard whatever was allocated earlier. */
-+ if(decrypt) /* if decrypting... */
-+ { if(binhex) /* ...and input is binhex encoded... */
-+ len/=2; /* ...use half as much for output. */
-+ len-=TwoFish_BLOCK_SIZE; /* Also, subtract the size of the header. */
-+ }
-+ else
-+ { len+=TwoFish_BLOCK_SIZE; /* the size is just increased by the header... */
-+ if(binhex)
-+ len*=2; /* ...and doubled if output is to be binhexed. */
-+ }
-+ tfdata->output=malloc(len+TwoFish_BLOCK_SIZE);/* grab some memory...plus some extra (it's running over somewhere, crashes without extra padding) */
-+
-+ return tfdata->output; /* ...and return to caller. */
-+}
-+
-+/* bin2hex and hex2bin conversion */
-+void _TwoFish_BinHex(u_int8_t *buf,unsigned long len,bool bintohex)
-+{ u_int8_t *pi,*po,c;
-+
-+ if(bintohex)
-+ { for(pi=buf+len-1,po=buf+(2*len)-1;len>0;pi--,po--,len--) /* let's start from the end of the bin block. */
-+ { c=*pi; /* grab value. */
-+ c&=15; /* use lower 4 bits. */
-+ if(c>9) /* convert to ascii. */
-+ c+=('a'-10);
-+ else
-+ c+='0';
-+ *po--=c; /* set the lower nibble. */
-+ c=*pi; /* grab value again. */
-+ c>>=4; /* right shift 4 bits. */
-+ c&=15; /* make sure we only have 4 bits. */
-+ if(c>9) /* convert to ascii. */
-+ c+=('a'-10);
-+ else
-+ c+='0';
-+ *po=c; /* set the higher nibble. */
-+ } /* and keep going. */
-+ }
-+ else
-+ { for(pi=buf,po=buf;len>0;pi++,po++,len-=2) /* let's start from the beginning of the hex block. */
-+ { c=tolower(*pi++)-'0'; /* grab higher nibble. */
-+ if(c>9) /* convert to value. */
-+ c-=('0'-9);
-+ *po=c<<4; /* left shit 4 bits. */
-+ c=tolower(*pi)-'0'; /* grab lower nibble. */
-+ if(c>9) /* convert to value. */
-+ c-=('0'-9);
-+ *po|=c; /* and add to value. */
-+ }
-+ }
-+}
-+
-+
-+/* TwoFish Encryption
-+ *
-+ * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc,
-+ * this routine will alloc the memory. In addition, it will include a small 'header'
-+ * containing the magic and some salt. That way the decrypt routine can check if the
-+ * packet got decrypted successfully, and return 0 instead of garbage.
-+ *
-+ * Input: Pointer to the buffer of the plaintext to be encrypted.
-+ * Pointer to the pointer to the buffer receiving the ciphertext.
-+ * The pointer either points to user allocated output buffer space, or to NULL, in which case
-+ * this routine will set the pointer to the buffer allocated through the struct.
-+ * The length of the plaintext buffer.
-+ * Can be -1 if the input is a null terminated string, in which case we'll count for you.
-+ * Boolean flag for BinHex Output (if used, output will be twice as large as input).
-+ * Note: BinHex conversion overwrites (converts) input buffer!
-+ * The TwoFish structure.
-+ *
-+ * Output: The amount of bytes encrypted if successful, otherwise 0.
-+ */
-+
-+unsigned long TwoFishEncrypt(char *in,
-+ char **out,
-+ signed long len,
-+ bool binhex,
-+ TWOFISH *tfdata)
-+{ unsigned long ilen,olen;
-+
-+
-+ if(len== -1) /* if we got -1 for len, we'll assume IN is a... */
-+ ilen=strlen(in); /* ...\0 terminated string and figure len out ourselves... */
-+ else
-+ ilen=len; /* ...otherwise we trust you supply a correct length. */
-+
-+ if(in!=NULL && out!=NULL && ilen>0 && tfdata!=NULL) /* if we got usable stuff, we'll do it. */
-+ { if(*out==NULL) /* if OUT points to a NULL pointer... */
-+ *out=TwoFishAlloc(ilen,binhex,FALSE,tfdata); /* ...we'll (re-)allocate buffer space. */
-+ if(*out!=NULL)
-+ { tfdata->output=*out; /* set output buffer. */
-+ tfdata->header.salt=rand()*65536+rand(); /* toss in some salt. */
-+ tfdata->header.length[0]= (u_int8_t)(ilen);
-+ tfdata->header.length[1]= (u_int8_t)(ilen>>8);
-+ tfdata->header.length[2]= (u_int8_t)(ilen>>16);
-+ tfdata->header.length[3]= (u_int8_t)(ilen>>24);
-+ memcpy(tfdata->header.magic,TwoFish_MAGIC,TwoFish_MAGIC_LEN); /* set the magic. */
-+ olen=TwoFish_BLOCK_SIZE; /* set output counter. */
-+ _TwoFish_ResetCBC(tfdata); /* reset the CBC flag */
-+ _TwoFish_BlockCrypt((u_int8_t *)&(tfdata->header),*out,olen,FALSE,tfdata); /* encrypt first block (without flush on 16 byte boundary). */
-+ olen+=_TwoFish_CryptRawCBC(in,*out+TwoFish_BLOCK_SIZE,ilen,FALSE,tfdata); /* and encrypt the rest (we do not reset the CBC flag). */
-+ if(binhex) /* if binhex... */
-+ { _TwoFish_BinHex(*out,olen,TRUE); /* ...convert output to binhex... */
-+ olen*=2; /* ...and size twice as large. */
-+ }
-+ tfdata->output=*out;
-+ return olen;
-+ }
-+ }
-+ return 0;
-+}
-+
-+/* TwoFish Decryption
-+ *
-+ * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc,
-+ * this routine will alloc the memory. In addition, it will check the small 'header'
-+ * containing the magic. If magic does not match we return 0. Otherwise we return the
-+ * amount of bytes decrypted (should be the same as the length in the header).
-+ *
-+ * Input: Pointer to the buffer of the ciphertext to be decrypted.
-+ * Pointer to the pointer to the buffer receiving the plaintext.
-+ * The pointer either points to user allocated output buffer space, or to NULL, in which case
-+ * this routine will set the pointer to the buffer allocated through the struct.
-+ * The length of the ciphertext buffer.
-+ * Can be -1 if the input is a null terminated binhex string, in which case we'll count for you.
-+ * Boolean flag for BinHex Input (if used, plaintext will be half as large as input).
-+ * Note: BinHex conversion overwrites (converts) input buffer!
-+ * The TwoFish structure.
-+ *
-+ * Output: The amount of bytes decrypted if successful, otherwise 0.
-+ */
-+
-+unsigned long TwoFishDecrypt(char *in,
-+ char **out,
-+ signed long len,
-+ bool binhex,
-+ TWOFISH *tfdata)
-+{ unsigned long ilen,elen,olen;
-+ const u_int8_t cmagic[TwoFish_MAGIC_LEN]=TwoFish_MAGIC;
-+ u_int8_t *tbuf;
-+
-+
-+
-+ if(len== -1) /* if we got -1 for len, we'll assume IN is... */
-+ ilen=strlen(in); /* ...\0 terminated binhex and figure len out ourselves... */
-+ else
-+ ilen=len; /* ...otherwise we trust you supply a correct length. */
-+
-+ if(in!=NULL && out!=NULL && ilen>0 && tfdata!=NULL) /* if we got usable stuff, we'll do it. */
-+ { if(*out==NULL) /* if OUT points to a NULL pointer... */
-+ *out=TwoFishAlloc(ilen,binhex,TRUE,tfdata); /* ...we'll (re-)allocate buffer space. */
-+ if(*out!=NULL)
-+ { if(binhex) /* if binhex... */
-+ { _TwoFish_BinHex(in,ilen,FALSE); /* ...convert input to values... */
-+ ilen/=2; /* ...and size half as much. */
-+ }
-+ _TwoFish_ResetCBC(tfdata); /* reset the CBC flag. */
-+
-+ tbuf=(u_int8_t *)malloc(ilen+TwoFish_BLOCK_SIZE); /* get memory for data and header. */
-+ if(tbuf==NULL)
-+ return 0;
-+ tfdata->output=tbuf; /* set output to temp buffer. */
-+
-+ olen=_TwoFish_CryptRawCBC(in,tbuf,ilen,TRUE,tfdata)-TwoFish_BLOCK_SIZE; /* decrypt the whole thing. */
-+ memcpy(&(tfdata->header),tbuf,TwoFish_BLOCK_SIZE); /* copy first block into header. */
-+ tfdata->output=*out;
-+ for(elen=0;elen<TwoFish_MAGIC_LEN;elen++) /* compare magic. */
-+ if(tfdata->header.magic[elen]!=cmagic[elen])
-+ break;
-+ if(elen==TwoFish_MAGIC_LEN) /* if magic matches then... */
-+ { elen=(tfdata->header.length[0]) |
-+ (tfdata->header.length[1])<<8 |
-+ (tfdata->header.length[2])<<16 |
-+ (tfdata->header.length[3])<<24; /* .. we know how much to expect. */
-+ if(elen>olen) /* adjust if necessary. */
-+ elen=olen;
-+ memcpy(*out,tbuf+TwoFish_BLOCK_SIZE,elen); /* copy data into intended output. */
-+ free(tbuf);
-+ return elen;
-+ }
-+ free(tbuf);
-+ }
-+ }
-+ return 0;
-+}
-+
-+void _TwoFish_PrecomputeMDSmatrix(void) /* precompute the TwoFish_MDS matrix */
-+{ u_int32_t m1[2];
-+ u_int32_t mX[2];
-+ u_int32_t mY[2];
-+ u_int32_t i, j;
-+
-+ for (i = 0; i < 256; i++)
-+ { j = TwoFish_P[0][i] & 0xFF; /* compute all the matrix elements */
-+ m1[0] = j;
-+ mX[0] = TwoFish_Mx_X( j ) & 0xFF;
-+ mY[0] = TwoFish_Mx_Y( j ) & 0xFF;
-+
-+ j = TwoFish_P[1][i] & 0xFF;
-+ m1[1] = j;
-+ mX[1] = TwoFish_Mx_X( j ) & 0xFF;
-+ mY[1] = TwoFish_Mx_Y( j ) & 0xFF;
-+
-+ TwoFish_MDS[0][i] = m1[TwoFish_P_00] | /* fill matrix w/ above elements */
-+ mX[TwoFish_P_00] << 8 |
-+ mY[TwoFish_P_00] << 16 |
-+ mY[TwoFish_P_00] << 24;
-+ TwoFish_MDS[1][i] = mY[TwoFish_P_10] |
-+ mY[TwoFish_P_10] << 8 |
-+ mX[TwoFish_P_10] << 16 |
-+ m1[TwoFish_P_10] << 24;
-+ TwoFish_MDS[2][i] = mX[TwoFish_P_20] |
-+ mY[TwoFish_P_20] << 8 |
-+ m1[TwoFish_P_20] << 16 |
-+ mY[TwoFish_P_20] << 24;
-+ TwoFish_MDS[3][i] = mX[TwoFish_P_30] |
-+ m1[TwoFish_P_30] << 8 |
-+ mY[TwoFish_P_30] << 16 |
-+ mX[TwoFish_P_30] << 24;
-+ }
-+ TwoFish_MDSready=TRUE;
-+}
-+
-+
-+void _TwoFish_MakeSubKeys(TWOFISH *tfdata) /* Expand a user-supplied key material into a session key. */
-+{ u_int32_t k64Cnt = TwoFish_KEY_LENGTH / 8;
-+ u_int32_t k32e[4]; /* even 32-bit entities */
-+ u_int32_t k32o[4]; /* odd 32-bit entities */
-+ u_int32_t sBoxKey[4];
-+ u_int32_t offset,i,j;
-+ u_int32_t A, B, q=0;
-+ u_int32_t k0,k1,k2,k3;
-+ u_int32_t b0,b1,b2,b3;
-+
-+ /* split user key material into even and odd 32-bit entities and */
-+ /* compute S-box keys using (12, 8) Reed-Solomon code over GF(256) */
-+
-+
-+ for (offset=0,i=0,j=k64Cnt-1;i<4 && offset<TwoFish_KEY_LENGTH;i++,j--)
-+ { k32e[i] = tfdata->key[offset++];
-+ k32e[i]|= tfdata->key[offset++]<<8;
-+ k32e[i]|= tfdata->key[offset++]<<16;
-+ k32e[i]|= tfdata->key[offset++]<<24;
-+ k32o[i] = tfdata->key[offset++];
-+ k32o[i]|= tfdata->key[offset++]<<8;
-+ k32o[i]|= tfdata->key[offset++]<<16;
-+ k32o[i]|= tfdata->key[offset++]<<24;
-+ sBoxKey[j] = _TwoFish_RS_MDS_Encode( k32e[i], k32o[i] ); /* reverse order */
-+ }
-+
-+ /* compute the round decryption subkeys for PHT. these same subkeys */
-+ /* will be used in encryption but will be applied in reverse order. */
-+ i=0;
-+ while(i < TwoFish_TOTAL_SUBKEYS)
-+ { A = _TwoFish_F32( k64Cnt, q, k32e ); /* A uses even key entities */
-+ q += TwoFish_SK_BUMP;
-+
-+ B = _TwoFish_F32( k64Cnt, q, k32o ); /* B uses odd key entities */
-+ q += TwoFish_SK_BUMP;
-+
-+ B = B << 8 | B >> 24;
-+
-+ A += B;
-+ tfdata->subKeys[i++] = A; /* combine with a PHT */
-+
-+ A += B;
-+ tfdata->subKeys[i++] = A << TwoFish_SK_ROTL | A >> (32-TwoFish_SK_ROTL);
-+ }
-+
-+ /* fully expand the table for speed */
-+ k0 = sBoxKey[0];
-+ k1 = sBoxKey[1];
-+ k2 = sBoxKey[2];
-+ k3 = sBoxKey[3];
-+
-+ for (i = 0; i < 256; i++)
-+ { b0 = b1 = b2 = b3 = i;
-+ switch (k64Cnt & 3)
-+ { case 1: /* 64-bit keys */
-+ tfdata->sBox[ 2*i ] = TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][b0]) ^ TwoFish_b0(k0)];
-+ tfdata->sBox[ 2*i+1] = TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][b1]) ^ TwoFish_b1(k0)];
-+ tfdata->sBox[0x200+2*i ] = TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][b2]) ^ TwoFish_b2(k0)];
-+ tfdata->sBox[0x200+2*i+1] = TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][b3]) ^ TwoFish_b3(k0)];
-+ break;
-+ case 0: /* 256-bit keys (same as 4) */
-+ b0 = (TwoFish_P[TwoFish_P_04][b0]) ^ TwoFish_b0(k3);
-+ b1 = (TwoFish_P[TwoFish_P_14][b1]) ^ TwoFish_b1(k3);
-+ b2 = (TwoFish_P[TwoFish_P_24][b2]) ^ TwoFish_b2(k3);
-+ b3 = (TwoFish_P[TwoFish_P_34][b3]) ^ TwoFish_b3(k3);
-+ case 3: /* 192-bit keys */
-+ b0 = (TwoFish_P[TwoFish_P_03][b0]) ^ TwoFish_b0(k2);
-+ b1 = (TwoFish_P[TwoFish_P_13][b1]) ^ TwoFish_b1(k2);
-+ b2 = (TwoFish_P[TwoFish_P_23][b2]) ^ TwoFish_b2(k2);
-+ b3 = (TwoFish_P[TwoFish_P_33][b3]) ^ TwoFish_b3(k2);
-+ case 2: /* 128-bit keys */
-+ tfdata->sBox[ 2*i ]=
-+ TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][(TwoFish_P[TwoFish_P_02][b0]) ^
-+ TwoFish_b0(k1)]) ^ TwoFish_b0(k0)];
-+
-+ tfdata->sBox[ 2*i+1]=
-+ TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][(TwoFish_P[TwoFish_P_12][b1]) ^
-+ TwoFish_b1(k1)]) ^ TwoFish_b1(k0)];
-+
-+ tfdata->sBox[0x200+2*i ]=
-+ TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][(TwoFish_P[TwoFish_P_22][b2]) ^
-+ TwoFish_b2(k1)]) ^ TwoFish_b2(k0)];
-+
-+ tfdata->sBox[0x200+2*i+1]=
-+ TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][(TwoFish_P[TwoFish_P_32][b3]) ^
-+ TwoFish_b3(k1)]) ^ TwoFish_b3(k0)];
-+ }
-+ }
-+}
-+
-+
-+/**
-+ * Encrypt or decrypt exactly one block of plaintext in CBC mode.
-+ * Use "ciphertext stealing" technique described on pg. 196
-+ * of "Applied Cryptography" to encrypt the final partial
-+ * (i.e. <16 byte) block if necessary.
-+ *
-+ * jojo: the "ciphertext stealing" requires we read ahead and have
-+ * special handling for the last two blocks. Because of this, the
-+ * output from the TwoFish algorithm is handled internally here.
-+ * It would be better to have a higher level handle this as well as
-+ * CBC mode. Unfortunately, I've mixed the two together, which is
-+ * pretty crappy... The Java version separates these out correctly.
-+ *
-+ * fknobbe: I have reduced the CBC mode to work on memory buffer only.
-+ * Higher routines should use an intermediate buffer and handle
-+ * their output seperately (mainly so the data can be flushed
-+ * in one chunk, not seperate 16 byte blocks...)
-+ *
-+ * @param in The plaintext.
-+ * @param out The ciphertext
-+ * @param size how much to encrypt
-+ * @param tfdata: Pointer to the global data structure containing session keys.
-+ * @return none
-+ */
-+void _TwoFish_BlockCrypt(u_int8_t *in,u_int8_t *out,unsigned long size,int decrypt,TWOFISH *tfdata)
-+{ u_int8_t PnMinusOne[TwoFish_BLOCK_SIZE];
-+ u_int8_t CnMinusOne[TwoFish_BLOCK_SIZE];
-+ u_int8_t CBCplusCprime[TwoFish_BLOCK_SIZE];
-+ u_int8_t Pn[TwoFish_BLOCK_SIZE];
-+ u_int8_t *p,*pout;
-+ unsigned long i;
-+
-+ /* here is where we implement CBC mode and cipher block stealing */
-+ if(size==TwoFish_BLOCK_SIZE)
-+ { /* if we are encrypting, CBC means we XOR the plain text block with the */
-+ /* previous cipher text block before encrypting */
-+ if(!decrypt && tfdata->qBlockDefined)
-+ { for(p=in,i=0;i<TwoFish_BLOCK_SIZE;i++,p++)
-+ Pn[i]=*p ^ tfdata->qBlockCrypt[i]; /* FK: I'm copying the xor'ed input into Pn... */
-+ }
-+ else
-+ memcpy(Pn,in,TwoFish_BLOCK_SIZE); /* FK: same here. we work of Pn all the time. */
-+
-+ /* TwoFish block level encryption or decryption */
-+ _TwoFish_BlockCrypt16(Pn,out,decrypt,tfdata);
-+
-+ /* if we are decrypting, CBC means we XOR the result of the decryption */
-+ /* with the previous cipher text block to get the resulting plain text */
-+ if(decrypt && tfdata->qBlockDefined)
-+ { for (p=out,i=0;i<TwoFish_BLOCK_SIZE;i++,p++)
-+ *p^=tfdata->qBlockPlain[i];
-+ }
-+
-+ /* save the input and output blocks, since CBC needs these for XOR */
-+ /* operations */
-+ _TwoFish_qBlockPush(Pn,out,tfdata);
-+ }
-+ else
-+ { /* cipher block stealing, we are at Pn, */
-+ /* but since Cn-1 must now be replaced with CnC' */
-+ /* we pop it off, and recalculate Cn-1 */
-+
-+ if(decrypt)
-+ { /* We are on an odd block, and had to do cipher block stealing, */
-+ /* so the PnMinusOne has to be derived differently. */
-+
-+ /* First we decrypt it into CBC and C' */
-+ _TwoFish_qBlockPop(CnMinusOne,PnMinusOne,tfdata);
-+ _TwoFish_BlockCrypt16(CnMinusOne,CBCplusCprime,decrypt,tfdata);
-+
-+ /* we then xor the first few bytes with the "in" bytes (Cn) */
-+ /* to recover Pn, which we put in out */
-+ for(p=in,pout=out,i=0;i<size;i++,p++,pout++)
-+ *pout=*p ^ CBCplusCprime[i];
-+
-+ /* We now recover the original CnMinusOne, which consists of */
-+ /* the first "size" bytes of "in" data, followed by the */
-+ /* "Cprime" portion of CBCplusCprime */
-+ for(p=in,i=0;i<size;i++,p++)
-+ CnMinusOne[i]=*p;
-+ for(;i<TwoFish_BLOCK_SIZE;i++)
-+ CnMinusOne[i]=CBCplusCprime[i];
-+
-+ /* we now decrypt CnMinusOne to get PnMinusOne xored with Cn-2 */
-+ _TwoFish_BlockCrypt16(CnMinusOne,PnMinusOne,decrypt,tfdata);
-+
-+ for(i=0;i<TwoFish_BLOCK_SIZE;i++)
-+ PnMinusOne[i]=PnMinusOne[i] ^ tfdata->prevCipher[i];
-+
-+ /* So at this point, out has PnMinusOne */
-+ _TwoFish_qBlockPush(CnMinusOne,PnMinusOne,tfdata);
-+ _TwoFish_FlushOutput(tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE,tfdata);
-+ _TwoFish_FlushOutput(out,size,tfdata);
-+ }
-+ else
-+ { _TwoFish_qBlockPop(PnMinusOne,CnMinusOne,tfdata);
-+ memset(Pn,0,TwoFish_BLOCK_SIZE);
-+ memcpy(Pn,in,size);
-+ for(i=0;i<TwoFish_BLOCK_SIZE;i++)
-+ Pn[i]^=CnMinusOne[i];
-+ _TwoFish_BlockCrypt16(Pn,out,decrypt,tfdata);
-+ _TwoFish_qBlockPush(Pn,out,tfdata); /* now we officially have Cn-1 */
-+ _TwoFish_FlushOutput(tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE,tfdata);
-+ _TwoFish_FlushOutput(CnMinusOne,size,tfdata); /* old Cn-1 becomes new partial Cn */
-+ }
-+ tfdata->qBlockDefined=FALSE;
-+ }
-+}
-+
-+void _TwoFish_qBlockPush(u_int8_t *p,u_int8_t *c,TWOFISH *tfdata)
-+{ if(tfdata->qBlockDefined)
-+ _TwoFish_FlushOutput(tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE,tfdata);
-+ memcpy(tfdata->prevCipher,tfdata->qBlockPlain,TwoFish_BLOCK_SIZE);
-+ memcpy(tfdata->qBlockPlain,p,TwoFish_BLOCK_SIZE);
-+ memcpy(tfdata->qBlockCrypt,c,TwoFish_BLOCK_SIZE);
-+ tfdata->qBlockDefined=TRUE;
-+}
-+
-+void _TwoFish_qBlockPop(u_int8_t *p,u_int8_t *c,TWOFISH *tfdata)
-+{ memcpy(p,tfdata->qBlockPlain,TwoFish_BLOCK_SIZE );
-+ memcpy(c,tfdata->qBlockCrypt,TwoFish_BLOCK_SIZE );
-+ tfdata->qBlockDefined=FALSE;
-+}
-+
-+/* Reset's the CBC flag and zero's PrevCipher (through qBlockPlain) (important) */
-+void _TwoFish_ResetCBC(TWOFISH *tfdata)
-+{ tfdata->qBlockDefined=FALSE;
-+ memset(tfdata->qBlockPlain,0,TwoFish_BLOCK_SIZE);
-+}
-+
-+void _TwoFish_FlushOutput(u_int8_t *b,unsigned long len,TWOFISH *tfdata)
-+{ unsigned long i;
-+
-+ for(i=0;i<len && !tfdata->dontflush;i++)
-+ *tfdata->output++ = *b++;
-+ tfdata->dontflush=FALSE;
-+}
-+
-+void _TwoFish_BlockCrypt16(u_int8_t *in,u_int8_t *out,bool decrypt,TWOFISH *tfdata)
-+{ u_int32_t x0,x1,x2,x3;
-+ u_int32_t k,t0,t1,R;
-+
-+
-+ x0=*in++;
-+ x0|=(*in++ << 8 );
-+ x0|=(*in++ << 16);
-+ x0|=(*in++ << 24);
-+ x1=*in++;
-+ x1|=(*in++ << 8 );
-+ x1|=(*in++ << 16);
-+ x1|=(*in++ << 24);
-+ x2=*in++;
-+ x2|=(*in++ << 8 );
-+ x2|=(*in++ << 16);
-+ x2|=(*in++ << 24);
-+ x3=*in++;
-+ x3|=(*in++ << 8 );
-+ x3|=(*in++ << 16);
-+ x3|=(*in++ << 24);
-+
-+ if(decrypt)
-+ { x0 ^= tfdata->subKeys[4]; /* swap input and output whitening keys when decrypting */
-+ x1 ^= tfdata->subKeys[5];
-+ x2 ^= tfdata->subKeys[6];
-+ x3 ^= tfdata->subKeys[7];
-+
-+ k = 7+(TwoFish_ROUNDS*2);
-+ for (R = 0; R < TwoFish_ROUNDS; R += 2)
-+ { t0 = _TwoFish_Fe320( tfdata->sBox, x0);
-+ t1 = _TwoFish_Fe323( tfdata->sBox, x1);
-+ x3 ^= t0 + (t1<<1) + tfdata->subKeys[k--];
-+ x3 = x3 >> 1 | x3 << 31;
-+ x2 = x2 << 1 | x2 >> 31;
-+ x2 ^= t0 + t1 + tfdata->subKeys[k--];
-+
-+ t0 = _TwoFish_Fe320( tfdata->sBox, x2);
-+ t1 = _TwoFish_Fe323( tfdata->sBox, x3);
-+ x1 ^= t0 + (t1<<1) + tfdata->subKeys[k--];
-+ x1 = x1 >> 1 | x1 << 31;
-+ x0 = x0 << 1 | x0 >> 31;
-+ x0 ^= t0 + t1 + tfdata->subKeys[k--];
-+ }
-+
-+ x2 ^= tfdata->subKeys[0];
-+ x3 ^= tfdata->subKeys[1];
-+ x0 ^= tfdata->subKeys[2];
-+ x1 ^= tfdata->subKeys[3];
-+ }
-+ else
-+ { x0 ^= tfdata->subKeys[0];
-+ x1 ^= tfdata->subKeys[1];
-+ x2 ^= tfdata->subKeys[2];
-+ x3 ^= tfdata->subKeys[3];
-+
-+ k = 8;
-+ for (R = 0; R < TwoFish_ROUNDS; R += 2)
-+ { t0 = _TwoFish_Fe320( tfdata->sBox, x0);
-+ t1 = _TwoFish_Fe323( tfdata->sBox, x1);
-+ x2 ^= t0 + t1 + tfdata->subKeys[k++];
-+ x2 = x2 >> 1 | x2 << 31;
-+ x3 = x3 << 1 | x3 >> 31;
-+ x3 ^= t0 + (t1<<1) + tfdata->subKeys[k++];
-+
-+ t0 = _TwoFish_Fe320( tfdata->sBox, x2);
-+ t1 = _TwoFish_Fe323( tfdata->sBox, x3);
-+ x0 ^= t0 + t1 + tfdata->subKeys[k++];
-+ x0 = x0 >> 1 | x0 << 31;
-+ x1 = x1 << 1 | x1 >> 31;
-+ x1 ^= t0 + (t1<<1) + tfdata->subKeys[k++];
-+ }
-+
-+ x2 ^= tfdata->subKeys[4];
-+ x3 ^= tfdata->subKeys[5];
-+ x0 ^= tfdata->subKeys[6];
-+ x1 ^= tfdata->subKeys[7];
-+ }
-+
-+ *out++ = (u_int8_t)(x2 );
-+ *out++ = (u_int8_t)(x2 >> 8);
-+ *out++ = (u_int8_t)(x2 >> 16);
-+ *out++ = (u_int8_t)(x2 >> 24);
-+
-+ *out++ = (u_int8_t)(x3 );
-+ *out++ = (u_int8_t)(x3 >> 8);
-+ *out++ = (u_int8_t)(x3 >> 16);
-+ *out++ = (u_int8_t)(x3 >> 24);
-+
-+ *out++ = (u_int8_t)(x0 );
-+ *out++ = (u_int8_t)(x0 >> 8);
-+ *out++ = (u_int8_t)(x0 >> 16);
-+ *out++ = (u_int8_t)(x0 >> 24);
-+
-+ *out++ = (u_int8_t)(x1 );
-+ *out++ = (u_int8_t)(x1 >> 8);
-+ *out++ = (u_int8_t)(x1 >> 16);
-+ *out++ = (u_int8_t)(x1 >> 24);
-+}
-+
-+/**
-+ * Use (12, 8) Reed-Solomon code over GF(256) to produce a key S-box
-+ * 32-bit entity from two key material 32-bit entities.
-+ *
-+ * @param k0 1st 32-bit entity.
-+ * @param k1 2nd 32-bit entity.
-+ * @return Remainder polynomial generated using RS code
-+ */
-+u_int32_t _TwoFish_RS_MDS_Encode(u_int32_t k0,u_int32_t k1)
-+{ u_int32_t i,r;
-+
-+ for(r=k1,i=0;i<4;i++) /* shift 1 byte at a time */
-+ TwoFish_RS_rem(r);
-+ r ^= k0;
-+ for(i=0;i<4;i++)
-+ TwoFish_RS_rem(r);
-+
-+ return r;
-+}
-+
-+u_int32_t _TwoFish_F32(u_int32_t k64Cnt,u_int32_t x,u_int32_t *k32)
-+{ u_int8_t b0,b1,b2,b3;
-+ u_int32_t k0,k1,k2,k3,result = 0;
-+
-+ b0=TwoFish_b0(x);
-+ b1=TwoFish_b1(x);
-+ b2=TwoFish_b2(x);
-+ b3=TwoFish_b3(x);
-+ k0=k32[0];
-+ k1=k32[1];
-+ k2=k32[2];
-+ k3=k32[3];
-+
-+ switch (k64Cnt & 3)
-+ { case 1: /* 64-bit keys */
-+ result =
-+ TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][b0] & 0xFF) ^ TwoFish_b0(k0)] ^
-+ TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][b1] & 0xFF) ^ TwoFish_b1(k0)] ^
-+ TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][b2] & 0xFF) ^ TwoFish_b2(k0)] ^
-+ TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][b3] & 0xFF) ^ TwoFish_b3(k0)];
-+ break;
-+ case 0: /* 256-bit keys (same as 4) */
-+ b0 = (TwoFish_P[TwoFish_P_04][b0] & 0xFF) ^ TwoFish_b0(k3);
-+ b1 = (TwoFish_P[TwoFish_P_14][b1] & 0xFF) ^ TwoFish_b1(k3);
-+ b2 = (TwoFish_P[TwoFish_P_24][b2] & 0xFF) ^ TwoFish_b2(k3);
-+ b3 = (TwoFish_P[TwoFish_P_34][b3] & 0xFF) ^ TwoFish_b3(k3);
-+
-+ case 3: /* 192-bit keys */
-+ b0 = (TwoFish_P[TwoFish_P_03][b0] & 0xFF) ^ TwoFish_b0(k2);
-+ b1 = (TwoFish_P[TwoFish_P_13][b1] & 0xFF) ^ TwoFish_b1(k2);
-+ b2 = (TwoFish_P[TwoFish_P_23][b2] & 0xFF) ^ TwoFish_b2(k2);
-+ b3 = (TwoFish_P[TwoFish_P_33][b3] & 0xFF) ^ TwoFish_b3(k2);
-+ case 2: /* 128-bit keys (optimize for this case) */
-+ result =
-+ TwoFish_MDS[0][(TwoFish_P[TwoFish_P_01][(TwoFish_P[TwoFish_P_02][b0] & 0xFF) ^ TwoFish_b0(k1)] & 0xFF) ^ TwoFish_b0(k0)] ^
-+ TwoFish_MDS[1][(TwoFish_P[TwoFish_P_11][(TwoFish_P[TwoFish_P_12][b1] & 0xFF) ^ TwoFish_b1(k1)] & 0xFF) ^ TwoFish_b1(k0)] ^
-+ TwoFish_MDS[2][(TwoFish_P[TwoFish_P_21][(TwoFish_P[TwoFish_P_22][b2] & 0xFF) ^ TwoFish_b2(k1)] & 0xFF) ^ TwoFish_b2(k0)] ^
-+ TwoFish_MDS[3][(TwoFish_P[TwoFish_P_31][(TwoFish_P[TwoFish_P_32][b3] & 0xFF) ^ TwoFish_b3(k1)] & 0xFF) ^ TwoFish_b3(k0)];
-+ break;
-+ }
-+ return result;
-+}
-+
-+u_int32_t _TwoFish_Fe320(u_int32_t *lsBox,u_int32_t x)
-+{ return lsBox[ TwoFish_b0(x)<<1 ]^
-+ lsBox[ ((TwoFish_b1(x)<<1)|1)]^
-+ lsBox[0x200+ (TwoFish_b2(x)<<1) ]^
-+ lsBox[0x200+((TwoFish_b3(x)<<1)|1)];
-+}
-+
-+u_int32_t _TwoFish_Fe323(u_int32_t *lsBox,u_int32_t x)
-+{ return lsBox[ (TwoFish_b3(x)<<1) ]^
-+ lsBox[ ((TwoFish_b0(x)<<1)|1)]^
-+ lsBox[0x200+ (TwoFish_b1(x)<<1) ]^
-+ lsBox[0x200+((TwoFish_b2(x)<<1)|1)];
-+}
-+
-+u_int32_t _TwoFish_Fe32(u_int32_t *lsBox,u_int32_t x,u_int32_t R)
-+{ return lsBox[ 2*TwoFish__b(x,R ) ]^
-+ lsBox[ 2*TwoFish__b(x,R+1)+1]^
-+ lsBox[0x200+2*TwoFish__b(x,R+2) ]^
-+ lsBox[0x200+2*TwoFish__b(x,R+3)+1];
-+}
-+
-+
-+#endif
-
-Index: snort-2.8.6.1/src/twofish.h
-===================================================================
---- snort-2.8.6.1/src/twofish.h (Revision 0)
-+++ snort-2.8.6.1/src/twofish.h (Revision 3)
-@@ -0,0 +1,276 @@
-+/* $Id: twofish.h,v 2.1 2008/12/15 20:36:05 fknobbe Exp $
-+ *
-+ *
-+ * Copyright (C) 1997-2000 The Cryptix Foundation Limited.
-+ * Copyright (C) 2000 Farm9.
-+ * Copyright (C) 2001 Frank Knobbe.
-+ * All rights reserved.
-+ *
-+ * For Cryptix code:
-+ * Use, modification, copying and distribution of this software is subject
-+ * the terms and conditions of the Cryptix General Licence. You should have
-+ * received a copy of the Cryptix General Licence along with this library;
-+ * if not, you can download a copy from http://www.cryptix.org/ .
-+ *
-+ * For Farm9:
-+ * --- jojo@farm9.com, August 2000, converted from Java to C++, added CBC mode and
-+ * ciphertext stealing technique, added AsciiTwofish class for easy encryption
-+ * decryption of text strings
-+ *
-+ * Frank Knobbe <frank@knobbe.us>:
-+ * --- April 2001, converted from C++ to C, prefixed global variables
-+ * with TwoFish, substituted some defines, changed functions to make use of
-+ * variables supplied in a struct, modified and added routines for modular calls.
-+ * Cleaned up the code so that defines are used instead of fixed 16's and 32's.
-+ * Created two general purpose crypt routines for one block and multiple block
-+ * encryption using Joh's CBC code.
-+ * Added crypt routines that use a header (with a magic and data length).
-+ * (Basically a major rewrite).
-+ *
-+ * Note: Routines labeled _TwoFish are private and should not be used
-+ * (or with extreme caution).
-+ *
-+ */
-+
-+#ifndef __TWOFISH_LIBRARY_HEADER__
-+#define __TWOFISH_LIBRARY_HEADER__
-+
-+#ifndef FALSE
-+#define FALSE 0
-+#endif
-+#ifndef TRUE
-+#define TRUE !FALSE
-+#endif
-+#ifndef bool
-+#define bool int
-+#endif
-+
-+
-+/* Constants */
-+
-+#define TwoFish_DEFAULT_PW "SnortHas2FishEncryptionRoutines!" /* default password (not more than 32 chars) */
-+#define TwoFish_MAGIC "TwoFish" /* to indentify a successful decryption */
-+
-+enum
-+{ TwoFish_KEY_SIZE = 256, /* Valid values: 64, 128, 192, 256 */
-+ /* User 256, other key sizes have not been tested. */
-+ /* (But should work. I substituted as much as */
-+ /* I could with this define.) */
-+ TwoFish_ROUNDS = 16,
-+ TwoFish_BLOCK_SIZE = 16, /* bytes in a data-block */
-+ TwoFish_KEY_LENGTH = TwoFish_KEY_SIZE/8, /* 32= 256-bit key */
-+ TwoFish_TOTAL_SUBKEYS = 4+4+2*TwoFish_ROUNDS,
-+ TwoFish_MAGIC_LEN = TwoFish_BLOCK_SIZE-8,
-+ TwoFish_SK_BUMP = 0x01010101,
-+ TwoFish_SK_ROTL = 9,
-+ TwoFish_P_00 = 1,
-+ TwoFish_P_01 = 0,
-+ TwoFish_P_02 = 0,
-+ TwoFish_P_03 = TwoFish_P_01 ^ 1,
-+ TwoFish_P_04 = 1,
-+ TwoFish_P_10 = 0,
-+ TwoFish_P_11 = 0,
-+ TwoFish_P_12 = 1,
-+ TwoFish_P_13 = TwoFish_P_11 ^ 1,
-+ TwoFish_P_14 = 0,
-+ TwoFish_P_20 = 1,
-+ TwoFish_P_21 = 1,
-+ TwoFish_P_22 = 0,
-+ TwoFish_P_23 = TwoFish_P_21 ^ 1,
-+ TwoFish_P_24 = 0,
-+ TwoFish_P_30 = 0,
-+ TwoFish_P_31 = 1,
-+ TwoFish_P_32 = 1,
-+ TwoFish_P_33 = TwoFish_P_31 ^ 1,
-+ TwoFish_P_34 = 1,
-+ TwoFish_GF256_FDBK = 0x169,
-+ TwoFish_GF256_FDBK_2 = 0x169 / 2,
-+ TwoFish_GF256_FDBK_4 = 0x169 / 4,
-+ TwoFish_RS_GF_FDBK = 0x14D, /* field generator */
-+ TwoFish_MDS_GF_FDBK = 0x169 /* primitive polynomial for GF(256) */
-+};
-+
-+
-+/* Global data structure for callers */
-+
-+typedef struct
-+{ u_int32_t sBox[4 * 256]; /* Key dependent S-box */
-+ u_int32_t subKeys[TwoFish_TOTAL_SUBKEYS]; /* Subkeys */
-+ u_int8_t key[TwoFish_KEY_LENGTH]; /* Encryption Key */
-+ u_int8_t *output; /* Pointer to output buffer */
-+ u_int8_t qBlockPlain[TwoFish_BLOCK_SIZE]; /* Used by CBC */
-+ u_int8_t qBlockCrypt[TwoFish_BLOCK_SIZE];
-+ u_int8_t prevCipher[TwoFish_BLOCK_SIZE];
-+ struct /* Header for crypt functions. Has to be at least one block long. */
-+ { u_int32_t salt; /* Random salt in first block (will salt the rest through CBC) */
-+ u_int8_t length[4]; /* The amount of data following the header */
-+ u_int8_t magic[TwoFish_MAGIC_LEN]; /* Magic to identify successful decryption */
-+ } header;
-+ bool qBlockDefined;
-+ bool dontflush;
-+} TWOFISH;
-+
-+#ifndef __TWOFISH_LIBRARY_SOURCE__
-+
-+extern bool TwoFish_srand; /* if set to TRUE (default), first call of TwoFishInit will seed rand(); */
-+ /* call of TwoFishInit */
-+#endif
-+
-+
-+/**** Public Functions ****/
-+
-+/* TwoFish Initialization
-+ *
-+ * This routine generates a global data structure for use with TwoFish,
-+ * initializes important values (such as subkeys, sBoxes), generates subkeys
-+ * and precomputes the MDS matrix if not already done.
-+ *
-+ * Input: User supplied password (will be appended by default password of 'SnortHas2FishEncryptionRoutines!')
-+ *
-+ * Output: Pointer to TWOFISH structure. This data structure contains key dependent data.
-+ * This pointer is used with all other crypt functions.
-+ */
-+TWOFISH *TwoFishInit(char *userkey);
-+
-+
-+/* TwoFish Destroy
-+ *
-+ * Nothing else but a free...
-+ *
-+ * Input: Pointer to the TwoFish structure.
-+ *
-+ */
-+void TwoFishDestroy(TWOFISH *tfdata);
-+
-+
-+/* TwoFish Alloc
-+ *
-+ * Allocates enough memory for the output buffer as required.
-+ *
-+ * Input: Length of the plaintext.
-+ * Boolean flag for BinHex Output.
-+ * Pointer to the TwoFish structure.
-+ *
-+ * Output: Returns a pointer to the memory allocated.
-+ */
-+void *TwoFishAlloc(unsigned long len,bool binhex,bool decrypt,TWOFISH *tfdata);
-+
-+
-+/* TwoFish Free
-+ *
-+ * Free's the allocated buffer.
-+ *
-+ * Input: Pointer to the TwoFish structure
-+ *
-+ * Output: (none)
-+ */
-+void TwoFishFree(TWOFISH *tfdata);
-+
-+
-+/* TwoFish Set Output
-+ *
-+ * If you want to allocate the output buffer yourself,
-+ * then you can set it with this function.
-+ *
-+ * Input: Pointer to your output buffer
-+ * Pointer to the TwoFish structure
-+ *
-+ * Output: (none)
-+ */
-+void TwoFishSetOutput(char *outp,TWOFISH *tfdata);
-+
-+
-+/* TwoFish Raw Encryption
-+ *
-+ * Does not use header, but does use CBC (if more than one block has to be encrypted).
-+ *
-+ * Input: Pointer to the buffer of the plaintext to be encrypted.
-+ * Pointer to the buffer receiving the ciphertext.
-+ * The length of the plaintext buffer.
-+ * The TwoFish structure.
-+ *
-+ * Output: The amount of bytes encrypted if successful, otherwise 0.
-+ */
-+unsigned long TwoFishEncryptRaw(char *in,char *out,unsigned long len,TWOFISH *tfdata);
-+
-+/* TwoFish Raw Decryption
-+ *
-+ * Does not use header, but does use CBC (if more than one block has to be decrypted).
-+ *
-+ * Input: Pointer to the buffer of the ciphertext to be decrypted.
-+ * Pointer to the buffer receiving the plaintext.
-+ * The length of the ciphertext buffer (at least one cipher block).
-+ * The TwoFish structure.
-+ *
-+ * Output: The amount of bytes decrypted if successful, otherwise 0.
-+ */
-+unsigned long TwoFishDecryptRaw(char *in,char *out,unsigned long len,TWOFISH *tfdata);
-+
-+
-+/* TwoFish Encryption
-+ *
-+ * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc,
-+ * this routine will alloc the memory. In addition, it will include a small 'header'
-+ * containing the magic and some salt. That way the decrypt routine can check if the
-+ * packet got decrypted successfully, and return 0 instead of garbage.
-+ *
-+ * Input: Pointer to the buffer of the plaintext to be encrypted.
-+ * Pointer to the pointer to the buffer receiving the ciphertext.
-+ * The pointer either points to user allocated output buffer space, or to NULL, in which case
-+ * this routine will set the pointer to the buffer allocated through the struct.
-+ * The length of the plaintext buffer.
-+ * Can be -1 if the input is a null terminated string, in which case we'll count for you.
-+ * Boolean flag for BinHex Output (if used, output will be twice as large as input).
-+ * Note: BinHex conversion overwrites (converts) input buffer!
-+ * The TwoFish structure.
-+ *
-+ * Output: The amount of bytes encrypted if successful, otherwise 0.
-+ */
-+unsigned long TwoFishEncrypt(char *in,char **out,signed long len,bool binhex,TWOFISH *tfdata);
-+
-+
-+/* TwoFish Decryption
-+ *
-+ * Uses header and CBC. If the output area has not been intialized with TwoFishAlloc,
-+ * this routine will alloc the memory. In addition, it will check the small 'header'
-+ * containing the magic. If magic does not match we return 0. Otherwise we return the
-+ * amount of bytes decrypted (should be the same as the length in the header).
-+ *
-+ * Input: Pointer to the buffer of the ciphertext to be decrypted.
-+ * Pointer to the pointer to the buffer receiving the plaintext.
-+ * The pointer either points to user allocated output buffer space, or to NULL, in which case
-+ * this routine will set the pointer to the buffer allocated through the struct.
-+ * The length of the ciphertext buffer.
-+ * Can be -1 if the input is a null terminated binhex string, in which case we'll count for you.
-+ * Boolean flag for BinHex Input (if used, plaintext will be half as large as input).
-+ * Note: BinHex conversion overwrites (converts) input buffer!
-+ * The TwoFish structure.
-+ *
-+ * Output: The amount of bytes decrypted if successful, otherwise 0.
-+ */
-+unsigned long TwoFishDecrypt(char *in,char **out,signed long len,bool binhex,TWOFISH *tfdata);
-+
-+
-+/**** Private Functions ****/
-+
-+u_int8_t TwoFish__b(u_int32_t x,int n);
-+void _TwoFish_BinHex(u_int8_t *buf,unsigned long len,bool bintohex);
-+unsigned long _TwoFish_CryptRawCBC(char *in,char *out,unsigned long len,bool decrypt,TWOFISH *tfdata);
-+unsigned long _TwoFish_CryptRaw16(char *in,char *out,unsigned long len,bool decrypt,TWOFISH *tfdata);
-+unsigned long _TwoFish_CryptRaw(char *in,char *out,unsigned long len,bool decrypt,TWOFISH *tfdata);
-+void _TwoFish_PrecomputeMDSmatrix(void);
-+void _TwoFish_MakeSubKeys(TWOFISH *tfdata);
-+void _TwoFish_qBlockPush(u_int8_t *p,u_int8_t *c,TWOFISH *tfdata);
-+void _TwoFish_qBlockPop(u_int8_t *p,u_int8_t *c,TWOFISH *tfdata);
-+void _TwoFish_ResetCBC(TWOFISH *tfdata);
-+void _TwoFish_FlushOutput(u_int8_t *b,unsigned long len,TWOFISH *tfdata);
-+void _TwoFish_BlockCrypt(u_int8_t *in,u_int8_t *out,unsigned long size,int decrypt,TWOFISH *tfdata);
-+void _TwoFish_BlockCrypt16(u_int8_t *in,u_int8_t *out,bool decrypt,TWOFISH *tfdata);
-+u_int32_t _TwoFish_RS_MDS_Encode(u_int32_t k0,u_int32_t k1);
-+u_int32_t _TwoFish_F32(u_int32_t k64Cnt,u_int32_t x,u_int32_t *k32);
-+u_int32_t _TwoFish_Fe320(u_int32_t *lsBox,u_int32_t x);
-+u_int32_t _TwoFish_Fe323(u_int32_t *lsBox,u_int32_t x);
-+u_int32_t _TwoFish_Fe32(u_int32_t *lsBox,u_int32_t x,u_int32_t R);
-+
-+
-+#endif
-
-Index: snort-2.8.6.1/src/plugin_enum.h
-===================================================================
---- snort-2.8.6.1/src/plugin_enum.h (Revision 1)
-+++ snort-2.8.6.1/src/plugin_enum.h (Revision 3)
-@@ -60,6 +60,7 @@
- PLUGIN_URILEN_CHECK,
- PLUGIN_DYNAMIC,
- PLUGIN_FLOWBIT,
-+ PLUGIN_FWSAM,
- PLUGIN_MAX /* sentinel value */
- };
-
-Index: snort-2.8.6.1/src/fatal.h
-===================================================================
---- snort-2.8.6.1/src/fatal.h (Revision 0)
-+++ snort-2.8.6.1/src/fatal.h (Revision 3)
-@@ -0,0 +1,40 @@
-+/* $Id$ */
-+/*
-+** Copyright (C) 2002-2008 Sourcefire, Inc.
-+** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
-+**
-+** This program is free software; you can redistribute it and/or modify
-+** it under the terms of the GNU General Public License Version 2 as
-+** published by the Free Software Foundation. You may not use, modify or
-+** distribute this program under any other version of the GNU General
-+** Public License.
-+**
-+** 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.
-+*/
-+
-+#ifndef __FATAL_H__
-+#define __FATAL_H__
-+
-+
-+/*
-+ * in debugging mode print out the filename and the line number where the
-+ * failure have occured
-+ */
-+
-+
-+#ifdef DEBUG
-+ #define FATAL(msg) { printf("%s:%d: ", __FILE__, __LINE__); FatalError( (char *) msg); }
-+#else
-+ #define FATAL(msg) FatalError( (char *) msg)
-+#endif
-+
-+
-+
-+#endif /* __FATAL_H__ */
-
-Index: snort-2.8.6.1/src/output-plugins/spo_alert_fwsam.c
-===================================================================
---- snort-2.8.6.1/src/output-plugins/spo_alert_fwsam.c (Revision 0)
-+++ snort-2.8.6.1/src/output-plugins/spo_alert_fwsam.c (Revision 3)
-@@ -0,0 +1,1380 @@
-+/* $id: snortpatchb,v 1.2 2002/10/26 03:32:35 fknobbe Exp $
-+**
-+** spo_alert_fwsam.c
-+**
-+** Copyright (c) 2001-2004 Frank Knobbe <frank@knobbe.us>
-+**
-+** 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.
-+*/
-+
-+/*
-+ * Purpose:
-+ *
-+ * This module sends alerts to a remote service on a host running SnortSam
-+ * (the agent) which will block the intruding IP address on a variety of
-+ * host and network firewalls.
-+ *
-+ * SnortSam also performs checks against a white-list of never-to-be-blocked IP addresses,
-+ * can override block durations (for example for known proxies), and can detect attack conditions
-+ * where too many blocks are received within a defined interval. If an attack is detected
-+ * it will unblock the last x blocks and wait for the attack to end.
-+ *
-+ * See the SnortSam documentation for more information.
-+ *
-+ *
-+ * Output Plugin Parameters:
-+ ***************************
-+ *
-+ * output alert_fwsam: <SnortSam Station>:<port>/<key>
-+ *
-+ * <FW Mgmt Station>: The IP address or host name of the host running SnortSam.
-+ * <port>: The port the remote SnortSam service listens on (default 898).
-+ * <key>: The key used for authentication (encryption really)
-+ * of the communication to the remote service.
-+ *
-+ * Examples:
-+ *
-+ * output alert_fwsam: snortsambox/idspassword
-+ * output alert_fwsam: fw1.domain.tld:898/mykey
-+ * output alert_fwsam: 192.168.0.1/borderfw 192.168.1.254/wanfw
-+ *
-+ *
-+ * Rule Options:
-+ ***************
-+ *
-+ * fwsam: who[how],time;
-+ *
-+ * who: src, source, dst, dest, destination
-+ * IP address to be blocked according to snort rule (some rules
-+ * are reversed, i.e. homenet -> any [and you want to block any]).
-+ * src denotes IP to the left of -> and dst denotes IP to the right
-+ *
-+ * how: Optional. In, out, src, dest, either, both, this, conn, connection
-+ * Tells FW-1 to block packets INcoming from host, OUTgoing to host,
-+ * EITHERway, or only THIS connection (IP/Service pair).
-+ * See 'fw sam' for more information. May be ignored by other plugins.
-+ *
-+ * time: Duration of block in seconds. (Accepts 'days', 'months', 'weeks',
-+ * 'years', 'minutes', 'seconds', 'hours'. Alternatively, a value of
-+ * 0, or the keyword PERManent, INFinite, or ALWAYS, will block the
-+ * host permanently. Be careful with this!
-+ * Tells FW-1 (and others) how long to inhibit packets from the host.
-+ *
-+ * Examples:
-+ *
-+ * fwsam: src[either],15min;
-+ * or dst[in], 2 days 4 hours
-+ * or src, 1 hour
-+ *
-+ * (default: src[either],5min)
-+ *
-+ *
-+ * Effect:
-+ *
-+ * Alerts are sent to the remote SnortSam services on Firewall-1 Management Stations
-+ * or other hosts running SnortSam (as required for Cisco Routers and PIX).
-+ * The remote services will invoke the SAM configuration via the fw sam
-+ * command line, or by sending a packet to the SAM port 18183, or by using the official
-+ * OPSEC API calls, or by telnetting into Cisco routers or PIX firewalls.
-+ * The communication over the network is encrypted using two-fish.
-+ * (Implementation ripped from CryptCat by Farm9 with permission.)
-+ *
-+ * Future Plans:
-+ *
-+ * - Custom alert trigger per rule (x alerts in y secs) --> Seems to exist in Snort 1.9 now.
-+ * - Enable/Allow tagged fwsam: arguments to provide different values to
-+ * different stations. --> Seems to be accomplished with custom rule-types
-+ *
-+ *
-+ * Comments:
-+ *
-+ * It seem that above wishes can be implemented with todays setup. Feedback concerning
-+ * these is greatly appreciated.
-+ *
-+*/
-+
-+
-+#include "spo_alert_fwsam.h"
-+#include "twofish.h"
-+/* external globals from rules.c */
-+extern char *file_name;
-+extern int file_line;
-+extern OptTreeNode *otn_tmp;
-+extern char *snort_conf_dir; /* extern PV pv; */
-+
-+
-+/* my globals */
-+
-+FWsamList *FWsamStationList=NULL; /* Global (for all alert-types) list of snortsam stations */
-+FWsamOptions *FWsamOptionField=NULL;
-+unsigned long FWsamMaxOptions=0;
-+
-+
-+/*
-+ * Function: AlertFWsamSetup()
-+ *
-+ * Purpose: Registers the output plugin keyword and initialization
-+ * function into the output plugin list. This is the function that
-+ * gets called from InitOutputPlugins() in plugbase.c.
-+ * It also registers itself as a plugin in order to parse every rule
-+ * and to set the appropiate flags from fwsam: option.
-+ *
-+ * Arguments: None.
-+ *
-+ * Returns: void function
-+ *
-+*/
-+void AlertFWsamSetup(void)
-+{
-+ /* link the preprocessor keyword to the init function in
-+ the preproc list */
-+ RegisterOutputPlugin("alert_fwsam", OUTPUT_TYPE_FLAG__ALERT, AlertFWsamInit);
-+ RegisterRuleOption("fwsam", AlertFWsamOptionInit, NULL, OPT_TYPE_ACTION, NULL);
-+
-+#ifdef FWSAMDEBUG /* This allows debugging of fwsam only */
-+ LogMessage("DEBUG => [Alert_FWsam](AlertFWsamSetup) Output plugin is plugged in...\n");
-+#endif
-+}
-+
-+
-+/* This function checks if a given snortsam station is already in
-+ * a given list.
-+*/
-+int FWsamStationExists(FWsamStation *who,FWsamList *list)
-+{
-+ while(list)
-+ {
-+ if(list->station) {
-+// if( who->stationip.s_addr==list->station->stationip.s_addr &&
-+ if(IP_EQUALITY(&who->stationip, &list->station->stationip) &&
-+ who->stationport==list->station->stationport)
-+ return TRUE;
-+ }
-+ list=list->next;
-+ }
-+ return FALSE;
-+}
-+
-+/*
-+ * Function: AlertFWsamInit(char *args)
-+ *
-+ * Purpose: Calls the argument parsing function, performs final setup on data
-+ * structs, links the preproc function into the function list.
-+ *
-+ * Arguments: args => ptr to argument string
-+ *
-+ * Returns: void function
-+ *
-+*/
-+void AlertFWsamInit(char *args)
-+{ char *ap;
-+ unsigned long statip,cnt,again,i;
-+ char *stathost,*statport,*statpass;
-+ FWsamStation *station;
-+ FWsamList *fwsamlist=NULL; /* alert-type dependent list of snortsam stations */
-+ FWsamList *listp,*newlistp;
-+ struct hostent *hoste;
-+ char buf[1024]="";
-+ FILE *fp;
-+ FWsamOptions tempopt;
-+
-+#ifdef FWSAMDEBUG
-+ unsigned long hostcnt=0;
-+
-+
-+
-+ LogMessage("DEBUG => [Alert_FWsam](AlertFWsamInit) Output plugin initializing...\n");
-+#endif
-+
-+ /* pv.alert_plugin_active = 1; */
-+
-+ /* parse the argument list from the rules file */
-+
-+ if(args == NULL)
-+ FatalError("ERROR %s (%d) => [Alert_FWsam](AlertFWsamInit) No arguments to alert_fwsam preprocessor!\n", file_name, file_line);
-+
-+ if(!FWsamOptionField && !FWsamMaxOptions)
-+ { strncpy(buf,snort_conf_dir,sizeof(buf)-1);
-+ strncpy(buf+strlen(buf),SID_MAPFILE,sizeof(buf)-strlen(buf)-1);
-+#ifdef FWSAMDEBUG
-+ LogMessage("DEBUG => [Alert_FWsam](AlertFWsamSetup) Using file: %s\n",buf);
-+#endif
-+ fp=fopen(buf,"rt");
-+ if(!fp)
-+ { strncpy(buf,snort_conf_dir,sizeof(buf)-1);
-+ strncpy(buf+strlen(buf),SID_ALT_MAPFILE,sizeof(buf)-strlen(buf)-1);
-+ fp=fopen(buf,"rt");
-+ }
-+ if(fp) /* Check for presence of map file and read those in, sorted. */
-+ { LogMessage("INFO => [Alert_FWsam](AlertFWsamSetup) Using sid-map file: %s\n",buf);
-+
-+ while(FWsamReadLine(buf,sizeof(buf),fp))
-+ if(*buf)
-+ FWsamMaxOptions++;
-+ if(FWsamMaxOptions)
-+ { if((FWsamOptionField=(FWsamOptions *)malloc(sizeof(FWsamOptions)*FWsamMaxOptions))==NULL)
-+ FatalError("ERROR => [Alert_FWsam](AlertFWsamSetup) malloc failed for OptionField!\n");
-+ fseek(fp,0,SEEK_SET);
-+ for(cnt=0;cnt<FWsamMaxOptions;)
-+ { FWsamReadLine(buf,sizeof(buf),fp);
-+ if(*buf)
-+ FWsamParseLine(&(FWsamOptionField[cnt++]),buf);
-+ }
-+ if(FWsamMaxOptions>1)
-+ { for(again=TRUE,cnt=FWsamMaxOptions-1;cnt>=1 && again;cnt--)
-+ { for(again=FALSE,i=0;i<cnt;i++)
-+ { if(FWsamOptionField[i].sid>FWsamOptionField[i+1].sid)
-+ { memcpy(&tempopt,&(FWsamOptionField[i]),sizeof(FWsamOptions));
-+ memcpy(&(FWsamOptionField[i]),&(FWsamOptionField[i+1]),sizeof(FWsamOptions));
-+ memcpy(&(FWsamOptionField[i+1]),&tempopt,sizeof(FWsamOptions));
-+ again=TRUE;
-+ }
-+ }
-+ }
-+ }
-+ }
-+ else
-+ FWsamMaxOptions=1;
-+ fclose(fp);
-+ }
-+ else
-+ FWsamMaxOptions=1;
-+ }
-+
-+
-+ ap=args; /* start at the beginning of the argument */
-+ while(*ap && isspace(*ap)) ap++;
-+ while(*ap)
-+ { stathost=ap; /* first argument should be host */
-+ statport=NULL;
-+ statpass=NULL;
-+ while(*ap && *ap!=':' && *ap!='/' && !isspace(*ap)) ap++; /* find token */
-+ switch(*ap)
-+ { case ':': *ap++=0; /* grab the port */
-+ statport=ap;
-+ while(*ap && *ap!='/' && !isspace(*ap)) ap++;
-+ if(*ap!='/')
-+ break;
-+ case '/': *ap++=0; /* grab the key */
-+ statpass=ap;
-+ while(*ap && !isspace(*ap)) ap++;
-+ default: break;
-+ }
-+ if(*ap)
-+ { *ap++=0;
-+ while(isspace(*ap)) ap++;
-+ }
-+ /* now we have the first host with port and password (key) */
-+ /* next we check for valid/blank password/port */
-+ if(statpass!=NULL)
-+ if(!*statpass)
-+ statpass=NULL;
-+ if(statport!=NULL)
-+ if(!*statport)
-+ statport=NULL;
-+ statip=0;
-+ /* now we check if a valid host was specified */
-+ if(inet_addr(stathost)==INADDR_NONE)
-+ { hoste=gethostbyname(stathost);
-+ if (!hoste)
-+ LogMessage("WARNING %s (%d) => [Alert_FWsam](AlertFWsamInit) Unable to resolve host '%s'!\n",file_name,file_line,stathost);
-+ else
-+ statip=*(unsigned long *)hoste->h_addr;
-+ }
-+ else
-+ { statip=inet_addr(stathost);
-+ if(!statip)
-+ LogMessage("WARNING %s (%d) => [Alert_FWsam](AlertFWsamInit) Invalid host address '%s'!\n",file_name,file_line,stathost);
-+ }
-+ if(statip)
-+ { /* groovie, a valid host. Let's alloc and assemble the structure for it. */
-+ if((station=(FWsamStation *)malloc(sizeof(FWsamStation)))==NULL)
-+ FatalError("ERROR => [Alert_FWsam](AlertFWsamInit) malloc failed for station!\n");
-+
-+// station->stationip.s_addr=statip; /* the IP address */
-+ station->stationip.ip32[0] = statip; /* the IP address */
-+ if(statport!=NULL && atoi(statport)>0) /* if the user specified one */
-+ station->stationport=atoi(statport); /* use users setting */
-+ else
-+ station->stationport=FWSAM_DEFAULTPORT; /* set the default port */
-+
-+ if(statpass!=NULL) /* if specified by user */
-+ strncpy(station->stationkey,statpass,TwoFish_KEY_LENGTH); /* use defined key */
-+ else
-+ station->stationkey[0]=0;
-+ station->stationkey[TwoFish_KEY_LENGTH]=0; /* make sure it's terminated. (damn strncpy...) */
-+
-+ strcpy(station->initialkey,station->stationkey);
-+ station->stationfish=TwoFishInit(station->stationkey);
-+
-+ station->localsocketaddr.sin_port=htons(0); /* let's use dynamic ports for now */
-+ station->localsocketaddr.sin_addr.s_addr=0;
-+ station->localsocketaddr.sin_family=AF_INET;
-+ station->stationsocketaddr.sin_port=htons(station->stationport);
-+ //station->stationsocketaddr.sin_addr=station->stationip;
-+ station->stationsocketaddr.sin_addr.s_addr=station->stationip.ip32[0];
-+ station->stationsocketaddr.sin_family=AF_INET; /* load all socket crap and keep for later */
-+
-+ do
-+ station->myseqno=rand(); /* the seqno this host will use */
-+ while(station->myseqno<20 || station->myseqno>65500);
-+ station->mykeymod[0]=rand();
-+ station->mykeymod[1]=rand();
-+ station->mykeymod[2]=rand();
-+ station->mykeymod[3]=rand();
-+ station->stationseqno=0; /* peer hasn't answered yet. */
-+
-+
-+ if(!FWsamStationExists(station,FWsamStationList)) /* If we don't have the station already in global list....*/
-+ { if(FWsamCheckIn(station)) /* ...and we can talk to the agent... */
-+ { if((newlistp=(FWsamList *)malloc(sizeof(FWsamList)))==NULL)
-+ FatalError("ERROR => [Alert_FWsam](AlertFWsamInit) malloc failed for global newlistp!\n");
-+ newlistp->station=station;
-+ newlistp->next=NULL;
-+
-+ if(!FWsamStationList) /* ... add it to the global list/ */
-+ FWsamStationList=newlistp;
-+ else
-+ { listp=FWsamStationList;
-+ while(listp->next)
-+ listp=listp->next;
-+ listp->next=newlistp;
-+ }
-+ }
-+ else
-+ { TwoFishDestroy(station->stationfish); /* if not, we trash it. */
-+ free(station);
-+ station=NULL;
-+ }
-+ }
-+#ifdef FWSAMDEBUG
-+ else
-+ LogMessage("DEBUG => [Alert_FWsam](AlertFWsamInit) Host %s:%i already in global list, skipping CheckIn.\n", sfip_ntoa(&station->stationip),station->stationport);
-+#endif
-+
-+ if(station)
-+ { if(!FWsamStationExists(station,fwsamlist)) /* If we don't have the station already in local list....*/
-+ { if((newlistp=(FWsamList *)malloc(sizeof(FWsamList)))==NULL)
-+ FatalError("ERROR => [Alert_FWsam](AlertFWsamInit) malloc failed for local newlistp!\n");
-+ newlistp->station=station;
-+ newlistp->next=NULL;
-+
-+ if(!fwsamlist) /* ... add it to the local list/ */
-+ fwsamlist=newlistp;
-+ else
-+ { listp=fwsamlist;
-+ while(listp->next)
-+ listp=listp->next;
-+ listp->next=newlistp;
-+ }
-+ }
-+
-+#ifdef FWSAMDEBUG
-+ else
-+ LogMessage("DEBUG => [Alert_FWsam](AlertFWsamInit) Host %s:%i already in local list, skipping.\n",sfip_ntoa(&station->stationip),station->stationport);
-+ LogMessage("DEBUG => [Alert_FWsam](AlertFWsamInit) #%i: Host %s [%s] port %i password %s\n",++hostcnt,stathost,sfip_ntoa(&station->stationip),station->stationport,station->stationkey);
-+#endif
-+ }
-+
-+ }
-+ } /* next one */
-+
-+#ifdef FWSAMDEBUG
-+ LogMessage("DEBUG => [Alert_FWsam](AlertFWsamInit) Linking fwsam alert function to call list...\n");
-+#endif
-+
-+ /* Set the preprocessor function into the function list */
-+ AddFuncToOutputList(AlertFWsam, OUTPUT_TYPE_FLAG__ALERT, fwsamlist);
-+ AddFuncToCleanExitList(AlertFWsamCleanExitFunc, fwsamlist);
-+ AddFuncToRestartList(AlertFWsamRestartFunc, fwsamlist);
-+}
-+
-+
-+/* This routine reads in a str from a file, snips white-spaces
-+ * off the front and back, removes comments, and pretties the
-+ * string. Returns true or false if a line was read or not.
-+*/
-+int FWsamReadLine(char *buf,unsigned long bufsize,FILE *fp)
-+{ char *p;
-+
-+ if(fgets(buf,bufsize-1,fp))
-+ { buf[bufsize-1]=0;
-+
-+#ifdef FWSAMDEBUG_off
-+ LogMessage("DEBUG => [Alert_FWsam](AlertFWsamReadLine) Line: %s\n",buf);
-+#endif
-+
-+ p=buf;
-+ while(isspace(*p))
-+ p++;
-+ if(p>buf);
-+ strcpy(buf,p);
-+ if(*buf)
-+ { p=buf+strlen(buf)-1; /* remove leading and trailing spaces */
-+ while(isspace(*p))
-+ *p-- =0;
-+ }
-+ p=buf;
-+ if(*p=='#' || *p==';')
-+ *p=0;
-+ else
-+ p++;
-+ while(*p) /* remove inline comments (except escaped #'s and ;'s) */
-+ { if(*p=='#' || *p==';')
-+ { if(*(p-1)=='\\')
-+ strcpy(p-1,p);
-+ else
-+ *p=0;
-+ }
-+ else
-+ p++;
-+ }
-+ return TRUE;
-+ }
-+ return FALSE;
-+}
-+
-+
-+/* Parses the duration of the argument, recognizing minutes, hours, etc..
-+*/
-+unsigned long FWsamParseDuration(char *p)
-+{ unsigned long dur=0,tdu;
-+ char *tok,c1,c2;
-+
-+ while(*p)
-+ { tok=p;
-+ while(*p && isdigit(*p))
-+ p++;
-+ if(*p)
-+ { c1=tolower(*p);
-+ *p=0;
-+ p++;
-+ if(*p && !isdigit(*p))
-+ { c2=tolower(*p++);
-+ while(*p && !isdigit(*p))
-+ p++;
-+ }
-+ else
-+ c2=0;
-+ tdu=atol(tok);
-+ switch(c1)
-+ { case 'm': if(c2=='o') /* month */
-+ tdu*=(60*60*24*30); /* use 30 days */
-+ else
-+ tdu*=60; /* minutes */
-+ case 's': break; /* seconds */
-+ case 'h': tdu*=(60*60); /* hours */
-+ break;
-+ case 'd': tdu*=(60*60*24); /* days */
-+ break;
-+ case 'w': tdu*=(60*60*24*7); /* week */
-+ break;
-+ case 'y': tdu*=(60*60*24*365); /* year */
-+ break;
-+ }
-+ dur+=tdu;
-+ }
-+ else
-+ dur+=atol(tok);
-+ }
-+
-+ return dur;
-+}
-+
-+
-+/* This routine parses an option line. It is called by FWsamParseLine,
-+ * which parses the sid-block.map file, and also by AlertFWsamOptionInit,
-+ * which is called by Snort when processing fwsam: options in rules.
-+ * It returns TRUE it there is a possible option problem, otherwise FALSE.
-+*/
-+int FWsamParseOption(FWsamOptions *optp,char *ap)
-+{ int possprob=FALSE;
-+
-+ /* set defaults */
-+
-+ optp->duration=300; /* default of 5 minute block */
-+ optp->how=FWSAM_HOW_INOUT; /* inbound and outbound block */
-+ optp->who=FWSAM_WHO_SRC; /* the source */
-+ optp->loglevel=FWSAM_LOG_LONGALERT; /* the log level default */
-+ /* parse the fwsam keywords */
-+
-+#ifdef FWSAMDEBUG
-+ LogMessage("DEBUG => [Alert_FWsam](AlertFWamOptionInit) Parse Options Args: %s\n",ap);
-+#endif
-+
-+ if(*ap) /* should be dst/src (the WHO) or duration */
-+ { if(isdigit(*ap))
-+ optp->duration=FWsamParseDuration(ap);
-+ else
-+ { switch(*ap) /* yeah, we're lazy and check only the first character */
-+ { case 'p': ; /* permanent, perm */
-+ case 'f': ; /* forever */
-+ case 'i': optp->duration=0; /* infinite, inf */
-+ break;
-+ case 'd': optp->who=FWSAM_WHO_DST; /* destination, dest, dst */
-+ break;
-+ case 's': optp->who=FWSAM_WHO_SRC; /* source, src */
-+ break;
-+ default: possprob=TRUE;
-+ }
-+ while(*ap && *ap!=',' && *ap!='[')
-+ ap++;
-+ if(*ap=='[')
-+ { ap++; /* now we have the HOW */
-+ switch(*ap)
-+ { case 'i': ; /* in */
-+ case 's': optp->how=FWSAM_HOW_IN; /* source, src */
-+ break;
-+ case 'o': ; /* out */
-+ case 'd': optp->how=FWSAM_HOW_OUT; /* destination, dest, dst */
-+ break;
-+ case 'b': ; /* both */
-+ case 'e': optp->how=FWSAM_HOW_INOUT; /* either */
-+ break;
-+ case 't': ; /* this */
-+ case 'c': optp->how=FWSAM_HOW_THIS; /* connection, conn */
-+ break;
-+ default: possprob=TRUE;
-+ }
-+ while(*ap && *ap!=',')
-+ ap++;
-+ }
-+ if(*ap==',')
-+ { ap++;
-+ if(isdigit(*ap)) /* and figure out how long to block */
-+ optp->duration=FWsamParseDuration(ap);
-+ else if(*ap=='p' || *ap=='f' || *ap=='i')
-+ optp->duration=0;
-+ else
-+ possprob=TRUE;
-+ }
-+ else if(!*ap)
-+ possprob=TRUE;
-+ }
-+ }
-+ else
-+ possprob=TRUE;
-+
-+ return possprob;
-+}
-+
-+
-+/* This goes through the lines of sid-block.map and sets the
-+ * options for fwsam if the file is being used.
-+*/
-+void FWsamParseLine(FWsamOptions *optp,char *buf)
-+{ char *ap;
-+
-+ ap=buf; /* start at the beginning of the argument */
-+
-+ while(*ap)
-+ { if(isspace(*ap)) /* normalize spaces (tabs into space, etc) */
-+ *ap=' ';
-+ if(isupper(*ap)) /* and set to lower case */
-+ *ap=tolower(*ap);
-+ ap++;
-+ }
-+ while((ap=strrchr(buf,' '))!=NULL) /* remove spaces */
-+ strcpy(ap,ap+1);
-+
-+ ap=buf;
-+ if(*ap)
-+ { while(*ap && *ap!=':' && *ap!='|')
-+ ap++;
-+ *ap++ =0;
-+ while(*ap && (*ap==':' || *ap=='|'))
-+ ap++;
-+
-+ optp->sid=(unsigned long)atol(buf);
-+
-+ if(FWsamParseOption(optp,ap))
-+ LogMessage("WARNING %s (%d) => [Alert_FWsam](AlertFWamOptionInit) Possible option problem. Using %s[%s],%lu.\n",file_name,file_line,(optp->who==FWSAM_WHO_SRC)?"src":"dst",(optp->how==FWSAM_HOW_IN)?"in":((optp->how==FWSAM_HOW_OUT)?"out":"either"),optp->duration);
-+ }
-+ else
-+ optp->sid=0;
-+}
-+
-+
-+
-+/*
-+ * Function: AlertFWsamOptionInit(char *data, OptTreeNode *otn, int protocol)
-+ *
-+ * Purpose: Parses each rule and sets the option flags in the tree.
-+ *
-+ * Arguments: args => ptr to argument string
-+ *
-+ * Returns: void function
-+ *
-+*/
-+void AlertFWsamOptionInit(char *args,OptTreeNode *otn,int protocol)
-+{
-+ FWsamOptions *optp;
-+ char *ap;
-+
-+
-+#ifdef FWSAMDEBUG
-+ LogMessage("DEBUG => [Alert_FWsam](AlertFWamOptionInit) FWsamOptionInit is parsing...\n");
-+#endif
-+
-+ if((optp=(FWsamOptions *)malloc(sizeof(FWsamOptions)))==NULL)
-+ FatalError("ERROR => [Alert_FWsam](AlertFWamOptionInit) malloc failed for opt!\n");
-+
-+
-+ ap=args; /* start at the beginning of the argument */
-+
-+ while(*ap)
-+ { if(isspace(*ap)) /* normalize spaces (tabs into space, etc) */
-+ *ap=' ';
-+ if(isupper(*ap)) /* and set to lower case */
-+ *ap=tolower(*ap);
-+ ap++;
-+ }
-+ while((ap=strrchr(args,' '))!=NULL) /* remove spaces */
-+ strcpy(ap,ap+1);
-+
-+
-+ if(FWsamParseOption(optp,args))
-+ LogMessage("WARNING %s (%d) => [Alert_FWsam](AlertFWamOptionInit) Possible option problem. Using %s[%s],%lu.\n",file_name,file_line,(optp->who==FWSAM_WHO_SRC)?"src":"dst",(optp->how==FWSAM_HOW_IN)?"in":((optp->how==FWSAM_HOW_OUT)?"out":"either"),optp->duration);
-+
-+ otn->ds_list[PLUGIN_FWSAM]=(FWsamOptions *)optp;
-+}
-+
-+
-+/* Generates a new encryption key for TwoFish based on seq numbers and a random that
-+ * the SnortSam agents send on checkin (in protocol)
-+*/
-+void FWsamNewStationKey(FWsamStation *station,FWsamPacket *packet)
-+{
-+ //unsigned char newkey[TwoFish_KEY_LENGTH+2];
-+ char newkey[TwoFish_KEY_LENGTH+2];
-+ int i;
-+
-+ newkey[0]=packet->snortseqno[0]; /* current snort seq # (which both know) */
-+ newkey[1]=packet->snortseqno[1];
-+ newkey[2]=packet->fwseqno[0]; /* current SnortSam seq # (which both know) */
-+ newkey[3]=packet->fwseqno[1];
-+ newkey[4]=packet->protocol[0]; /* the random SnortSam chose */
-+ newkey[5]=packet->protocol[1];
-+
-+ strncpy(newkey+6,station->stationkey,TwoFish_KEY_LENGTH-6); /* append old key */
-+ newkey[TwoFish_KEY_LENGTH]=0;
-+
-+ newkey[0]^=station->mykeymod[0]; /* modify key with key modifiers which were */
-+ newkey[1]^=station->mykeymod[1]; /* exchanged during the check-in handshake. */
-+ newkey[2]^=station->mykeymod[2];
-+ newkey[3]^=station->mykeymod[3];
-+ newkey[4]^=station->fwkeymod[0];
-+ newkey[5]^=station->fwkeymod[1];
-+ newkey[6]^=station->fwkeymod[2];
-+ newkey[7]^=station->fwkeymod[3];
-+
-+ for(i=0;i<=7;i++)
-+ if(newkey[i]==0)
-+ newkey[i]++;
-+
-+ strcpy(station->stationkey,newkey);
-+ TwoFishDestroy(station->stationfish);
-+ station->stationfish=TwoFishInit(newkey);
-+}
-+
-+
-+/* This routine will search the option list as defined
-+ * by the sid-block.map file and return a pointer
-+ * to the matching record.
-+*/
-+FWsamOptions *FWsamGetOption(unsigned long sid)
-+{ signed long i,step,diff,o,o2;
-+
-+#ifdef FWSAM_FANCYFETCH /* Fancy-fetch jumps in decreasing n/2 steps and takes much less lookups */
-+ o=o2= -1;
-+ i=step=FWsamMaxOptions>>1;
-+ while(i>=0 && i<FWsamMaxOptions && i!=o2)
-+ { diff=sid-FWsamOptionField[i].sid;
-+ if(!diff)
-+ return &(FWsamOptionField[i]);
-+ if(step>1)
-+ step=step>>1;
-+ o2=o;
-+ o=i;
-+ if(diff>0)
-+ i+=step;
-+ else
-+ i-=step;
-+ }
-+#else /* This is just a sequential list lookup */
-+ for(i=0;i<FWsamMaxOptions;i++)
-+ if(FWsamOptionField[i].sid==sid)
-+ return &(FWsamOptionField[i]);
-+#endif
-+ return NULL;
-+}
-+
-+
-+/****************************************************************************
-+ *
-+ * Function: AlertFWsam(Packet *, char *)
-+ *
-+ * Purpose: Send the current alert to a remote module on a FW-1 mgmt station
-+ *
-+ * Arguments: p => pointer to the packet data struct
-+ * msg => the message to print in the alert
-+ *
-+ * Returns: void function
-+ *
-+ ***************************************************************************/
-+void AlertFWsam(Packet *p, char *msg, void *arg, Event *event)
-+{ FWsamOptions *optp;
-+ FWsamPacket sampacket;
-+ FWsamStation *station=NULL;
-+ FWsamList *fwsamlist;
-+ SOCKET stationsocket;
-+ int i,len,deletestation,stationtry=0;
-+ //unsigned char *encbuf,*decbuf;
-+ char *encbuf,*decbuf;
-+ static unsigned long lastbsip[FWSAM_REPET_BLOCKS],lastbdip[FWSAM_REPET_BLOCKS],
-+ lastbduration[FWSAM_REPET_BLOCKS],lastbtime[FWSAM_REPET_BLOCKS];
-+ static unsigned short lastbsp[FWSAM_REPET_BLOCKS],lastbdp[FWSAM_REPET_BLOCKS],
-+ lastbproto[FWSAM_REPET_BLOCKS],lastbpointer;
-+ static unsigned char lastbmode[FWSAM_REPET_BLOCKS];
-+ static unsigned long btime=0;
-+
-+
-+ if(otn_tmp==NULL)
-+ {
-+#ifdef FWSAMDEBUG
-+ LogMessage("DEBUG => [Alert_FWsam] NULL otn_tmp!\n");
-+#endif
-+ return;
-+ }
-+ if(p == NULL)
-+ {
-+#ifdef FWSAMDEBUG
-+ LogMessage("DEBUG => [Alert_FWsam] NULL packet!\n");
-+#endif
-+ return;
-+ }
-+ if(arg == NULL)
-+ {
-+#ifdef FWSAMDEBUG
-+ LogMessage("DEBUG => [Alert_FWsam] NULL arg!\n");
-+#endif
-+ return;
-+ }
-+
-+ /* SnortSam does no IPv6 */
-+ if (!IS_IP4(p)) {
-+#ifdef FWSAMDEBUG
-+ LogMessage("DEBUG => [Alert_FWsam] not acting on non-IP4 packet!\n");
-+#endif
-+ return;
-+ }
-+
-+ optp=NULL;
-+
-+ if(FWsamOptionField) /* If using the file (field present), let's use that */
-+ optp=FWsamGetOption(event->sig_id);
-+
-+ if(!optp) /* If file not present, check if an fwsam option was defined on the triggering rule */
-+ optp=otn_tmp->ds_list[PLUGIN_FWSAM];
-+
-+ if(optp) /* if options specified for this rule */
-+ { if(!btime) /* if this is the first time this function is */
-+ { for(i=0;i<FWSAM_REPET_BLOCKS;i++) /* called, reset the time and protocol to 0. */
-+ { lastbproto[i]=0;
-+ lastbtime[i]=0;
-+ }
-+ }
-+
-+ fwsamlist=(FWsamList *)arg;
-+
-+#ifdef FWSAMDEBUG
-+ LogMessage("DEBUG => [Alert_FWsam] Alert -> Msg=\"%s\"\n",msg);
-+
-+ LogMessage("DEBUG => [Alert_FWsam] Alert -> Option: %s[%s],%lu.\n",(optp->who==FWSAM_WHO_SRC)?"src":"dst",(optp->how==FWSAM_HOW_IN)?"in":((optp->how==FWSAM_HOW_OUT)?"out":"either"),optp->duration);
-+#endif
-+
-+ len=TRUE;
-+ btime=(unsigned long)time(NULL); /* get current time */
-+ /* This is a cheap check to see if the blocking request matches any of the previous requests. */
-+ for(i=0;i<FWSAM_REPET_BLOCKS && len;i++)
-+ { if( ((optp->how==FWSAM_HOW_THIS)? /* if blocking mode SERVICE, check for src and dst */
-+ ( lastbsip[i]==p->iph->ip_src.s_addr && lastbdip[i]==p->iph->ip_dst.s_addr &&lastbproto[i]==p->iph->ip_proto &&
-+ ((p->iph->ip_proto==IPPROTO_TCP || p->iph->ip_proto==IPPROTO_UDP)? /* check port only of TCP or UDP */
-+/* ((optp->who==FWSAM_WHO_SRC)?(lastbsp[i]==p->sp):(lastbdp[i]==p->dp)):TRUE) ): */
-+ lastbdp[i]==p->dp:TRUE) ):
-+ ((optp->who==FWSAM_WHO_SRC)?(lastbsip[i]==p->iph->ip_src.s_addr):(lastbdip[i]==p->iph->ip_dst.s_addr))) && /* otherwise if we block source, only compare source. Same for dest. */
-+ lastbduration[i]==optp->duration &&
-+ (lastbmode[i]&(FWSAM_HOW|FWSAM_WHO))==(optp->how|optp->who) &&
-+ (btime-lastbtime[i]<((optp->duration>FWSAM_REPET_TIME)?FWSAM_REPET_TIME:optp->duration)))
-+ { len=FALSE; /* If so, we don't need to block again. */
-+ }
-+ }
-+ if(len)
-+ { if(++lastbpointer>=FWSAM_REPET_BLOCKS) /* increase repetitive check pointer */
-+ lastbpointer=0;
-+ lastbsip[lastbpointer]=p->iph->ip_src.s_addr; /* and note packet details */
-+ lastbdip[lastbpointer]=p->iph->ip_dst.s_addr;
-+ lastbduration[lastbpointer]=optp->duration;
-+ lastbmode[lastbpointer]=optp->how|optp->who|optp->loglevel;
-+ lastbproto[lastbpointer]=p->iph->ip_proto;
-+ if(p->iph->ip_proto==IPPROTO_TCP || p->iph->ip_proto==IPPROTO_UDP)
-+ { lastbsp[lastbpointer]=p->sp; /* set ports if TCP or UDP */
-+ lastbdp[lastbpointer]=p->dp;
-+ }
-+ lastbtime[lastbpointer]=btime;
-+
-+
-+ while(fwsamlist!=NULL)
-+ { station=fwsamlist->station;
-+ //if(station->stationip.s_addr)
-+ if(station->stationip.ip32[0])
-+ { deletestation=FALSE;
-+ stationtry++; /* first try */
-+ /* create a socket for the station */
-+ stationsocket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
-+ if(stationsocket==INVALID_SOCKET)
-+ FatalError("ERROR => [Alert_FWsam] Funky socket error (socket)!\n");
-+ if(bind(stationsocket,(struct sockaddr *)&(station->localsocketaddr),sizeof(struct sockaddr)))
-+ FatalError("ERROR => [Alert_FWsam] Could not bind socket!\n");
-+
-+ /* let's connect to the agent */
-+ if(connect(stationsocket,(struct sockaddr *)&station->stationsocketaddr,sizeof(struct sockaddr)))
-+ {
-+ LogMessage("WARNING => [Alert_FWsam] Could not send block to host %s. Will try later.\n",sfip_ntoa(&station->stationip));
-+#ifdef WIN32
-+ closesocket(stationsocket);
-+#else
-+ close(stationsocket);
-+#endif
-+ stationtry=0;
-+ }
-+ else
-+ {
-+#ifdef FWSAMDEBUG
-+ LogMessage("DEBUG => [Alert_FWsam] Connected to host %s.\n",sfip_ntoa(&station->stationip));
-+#endif
-+ /* now build the packet */
-+ station->myseqno+=station->stationseqno; /* increase my seqno by adding agent seq no */
-+ sampacket.endiancheck=1; /* This is an endian indicator for Snortsam */
-+ sampacket.snortseqno[0]=(char)station->myseqno;
-+ sampacket.snortseqno[1]=(char)(station->myseqno>>8);
-+ sampacket.fwseqno[0]=(char)station->stationseqno;/* fill station seqno */
-+ sampacket.fwseqno[1]=(char)(station->stationseqno>>8);
-+ sampacket.status=FWSAM_STATUS_BLOCK; /* set block mode */
-+ sampacket.version=FWSAM_PACKETVERSION; /* set packet version */
-+ sampacket.duration[0]=(char)optp->duration; /* set duration */
-+ sampacket.duration[1]=(char)(optp->duration>>8);
-+ sampacket.duration[2]=(char)(optp->duration>>16);
-+ sampacket.duration[3]=(char)(optp->duration>>24);
-+ sampacket.fwmode=optp->how|optp->who|optp->loglevel; /* set the mode */
-+ sampacket.dstip[0]=(char)p->iph->ip_dst.s_addr; /* destination IP */
-+ sampacket.dstip[1]=(char)(p->iph->ip_dst.s_addr>>8);
-+ sampacket.dstip[2]=(char)(p->iph->ip_dst.s_addr>>16);
-+ sampacket.dstip[3]=(char)(p->iph->ip_dst.s_addr>>24);
-+ sampacket.srcip[0]=(char)p->iph->ip_src.s_addr; /* source IP */
-+ sampacket.srcip[1]=(char)(p->iph->ip_src.s_addr>>8);
-+ sampacket.srcip[2]=(char)(p->iph->ip_src.s_addr>>16);
-+ sampacket.srcip[3]=(char)(p->iph->ip_src.s_addr>>24);
-+ sampacket.protocol[0]=(char)p->iph->ip_proto; /* protocol */
-+ sampacket.protocol[1]=(char)(p->iph->ip_proto>>8);/* protocol */
-+
-+ if(p->iph->ip_proto==IPPROTO_TCP || p->iph->ip_proto==IPPROTO_UDP)
-+ { sampacket.srcport[0]=(char)p->sp; /* set ports */
-+ sampacket.srcport[1]=(char)(p->sp>>8);
-+ sampacket.dstport[0]=(char)p->dp;
-+ sampacket.dstport[1]=(char)(p->dp>>8);
-+ }
-+ else
-+ sampacket.srcport[0]=sampacket.srcport[1]=sampacket.dstport[0]=sampacket.dstport[1]=0;
-+
-+ sampacket.sig_id[0]=(char)event->sig_id; /* set signature ID */
-+ sampacket.sig_id[1]=(char)(event->sig_id>>8);
-+ sampacket.sig_id[2]=(char)(event->sig_id>>16);
-+ sampacket.sig_id[3]=(char)(event->sig_id>>24);
-+
-+#ifdef FWSAMDEBUG
-+ LogMessage("DEBUG => [Alert_FWsam] Sending BLOCK\n");
-+ LogMessage("DEBUG => [Alert_FWsam] Snort SeqNo: %x\n",station->myseqno);
-+ LogMessage("DEBUG => [Alert_FWsam] Mgmt SeqNo : %x\n",station->stationseqno);
-+ LogMessage("DEBUG => [Alert_FWsam] Status : %i\n",FWSAM_STATUS_BLOCK);
-+ LogMessage("DEBUG => [Alert_FWsam] Mode : %i\n",optp->how|optp->who|optp->loglevel);
-+ LogMessage("DEBUG => [Alert_FWsam] Duration : %li\n",optp->duration);
-+ LogMessage("DEBUG => [Alert_FWsam] Protocol : %i\n",GET_IPH_PROTO(p));
-+#ifdef SUP_IP6
-+ LogMessage("DEBUG => [Alert_FWsam] Src IP : %s\n",sfip_ntoa(GET_SRC_IP(p)));
-+ LogMessage("DEBUG => [Alert_FWsam] Dest IP : %s\n",sfip_ntoa(GET_DST_IP(p)));
-+#else
-+ LogMessage("DEBUG => [Alert_FWsam] Src IP : %s\n",inet_ntoa(p->iph->ip_src));
-+ LogMessage("DEBUG => [Alert_FWsam] Dest IP : %s\n",inet_ntoa(p->iph->ip_dst));
-+#endif
-+ LogMessage("DEBUG => [Alert_FWsam] Src Port : %i\n",p->sp);
-+ LogMessage("DEBUG => [Alert_FWsam] Dest Port : %i\n",p->dp);
-+ LogMessage("DEBUG => [Alert_FWsam] Sig_ID : %lu\n",event->sig_id);
-+
-+#endif
-+
-+ encbuf=TwoFishAlloc(sizeof(FWsamPacket),FALSE,FALSE,station->stationfish); /* get the encryption buffer */
-+ len=TwoFishEncrypt((char *)&sampacket,&encbuf,sizeof(FWsamPacket),FALSE,station->stationfish); /* encrypt the packet with current key */
-+
-+ if(send(stationsocket,encbuf,len,0)!=len) /* weird...could not send */
-+ { LogMessage("WARNING => [Alert_FWsam] Could not send to host %s. Will try again later.\n",sfip_ntoa(&station->stationip));
-+#ifdef WIN32
-+ closesocket(stationsocket);
-+#else
-+ close(stationsocket);
-+#endif
-+ stationtry=0;
-+ }
-+ else
-+ { i=FWSAM_NETWAIT;
-+#ifdef WIN32
-+ ioctlsocket(stationsocket,FIONBIO,&i); /* set non blocking and wait for */
-+#else
-+ ioctl(stationsocket,FIONBIO,&i); /* set non blocking and wait for */
-+#endif
-+ while(i-- >1) /* the response packet */
-+ { waitms(10); /* wait for response (default maximum 3 secs */
-+ if(recv(stationsocket,encbuf,len,0)==len)
-+ i=0; /* if we received packet we set the counter to 0. */
-+ /* by the time we check with if, it's already dec'ed to -1 */
-+ }
-+ if(!i) /* id we timed out (i was one, then dec'ed)... */
-+ { LogMessage("WARNING => [Alert_FWsam] Did not receive response from host %s. Will try again later.\n",sfip_ntoa(&station->stationip));
-+#ifdef WIN32
-+ closesocket(stationsocket);
-+#else
-+ close(stationsocket);
-+#endif
-+ stationtry=0;
-+ }
-+ else /* got a packet */
-+ { decbuf=(char *)&sampacket; /* get the pointer to the packet struct */
-+ len=TwoFishDecrypt(encbuf,&decbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,FALSE,station->stationfish); /* try to decrypt the packet with current key */
-+
-+ if(len!=sizeof(FWsamPacket)) /* invalid decryption */
-+ { strcpy(station->stationkey,station->initialkey); /* try the intial key */
-+ TwoFishDestroy(station->stationfish);
-+ station->stationfish=TwoFishInit(station->stationkey); /* re-initialize the TwoFish with the intial key */
-+ len=TwoFishDecrypt(encbuf,&decbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,FALSE,station->stationfish); /* try again to decrypt */
-+ LogMessage("INFO => [Alert_FWsam] Had to use initial key!\n");
-+ }
-+ if(len==sizeof(FWsamPacket)) /* valid decryption */
-+ { if(sampacket.version==FWSAM_PACKETVERSION)/* master speaks my language */
-+ { if(sampacket.status==FWSAM_STATUS_OK || sampacket.status==FWSAM_STATUS_NEWKEY
-+ || sampacket.status==FWSAM_STATUS_RESYNC || sampacket.status==FWSAM_STATUS_HOLD)
-+ { station->stationseqno=sampacket.fwseqno[0] | (sampacket.fwseqno[1]<<8); /* get stations seqno */
-+ station->lastcontact=(unsigned long)time(NULL); /* set the last contact time (not used yet) */
-+#ifdef FWSAMDEBUG
-+ LogMessage("DEBUG => [Alert_FWsam] Received %s\n",sampacket.status==FWSAM_STATUS_OK?"OK":
-+ sampacket.status==FWSAM_STATUS_NEWKEY?"NEWKEY":
-+ sampacket.status==FWSAM_STATUS_RESYNC?"RESYNC":
-+ sampacket.status==FWSAM_STATUS_HOLD?"HOLD":"ERROR");
-+ LogMessage("DEBUG => [Alert_FWsam] Snort SeqNo: %x\n",sampacket.snortseqno[0]|(sampacket.snortseqno[1]<<8));
-+ LogMessage("DEBUG => [Alert_FWsam] Mgmt SeqNo : %x\n",station->stationseqno);
-+ LogMessage("DEBUG => [Alert_FWsam] Status : %i\n",sampacket.status);
-+ LogMessage("DEBUG => [Alert_FWsam] Version : %i\n",sampacket.version);
-+#endif
-+ if(sampacket.status==FWSAM_STATUS_HOLD)
-+ { i=FWSAM_NETHOLD; /* Stay on hold for a maximum of 60 secs (default) */
-+ while(i-- >1) /* the response packet */
-+ { waitms(10); /* wait for response */
-+ if(recv(stationsocket,encbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,0)==sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE)
-+ i=0; /* if we received packet we set the counter to 0. */
-+ }
-+ if(!i) /* id we timed out (i was one, then dec'ed)... */
-+ { LogMessage("WARNING => [Alert_FWsam] Did not receive response from host %s. Will try again later.\n",sfip_ntoa(&station->stationip));
-+ stationtry=0;
-+ sampacket.status=FWSAM_STATUS_ERROR;
-+ }
-+ else /* got a packet */
-+ { decbuf=(char *)&sampacket; /* get the pointer to the packet struct */
-+ len=TwoFishDecrypt(encbuf,&decbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,FALSE,station->stationfish); /* try to decrypt the packet with current key */
-+
-+ if(len!=sizeof(FWsamPacket)) /* invalid decryption */
-+ { strcpy(station->stationkey,station->initialkey); /* try the intial key */
-+ TwoFishDestroy(station->stationfish);
-+ station->stationfish=TwoFishInit(station->stationkey); /* re-initialize the TwoFish with the intial key */
-+ len=TwoFishDecrypt(encbuf,&decbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,FALSE,station->stationfish); /* try again to decrypt */
-+ LogMessage("INFO => [Alert_FWsam] Had to use initial key again!\n");
-+ }
-+#ifdef FWSAMDEBUG
-+ LogMessage("DEBUG => [Alert_FWsam] Received %s\n",sampacket.status==FWSAM_STATUS_OK?"OK":
-+ sampacket.status==FWSAM_STATUS_NEWKEY?"NEWKEY":
-+ sampacket.status==FWSAM_STATUS_RESYNC?"RESYNC":
-+ sampacket.status==FWSAM_STATUS_HOLD?"HOLD":"ERROR");
-+ LogMessage("DEBUG => [Alert_FWsam] Snort SeqNo: %x\n",sampacket.snortseqno[0]|(sampacket.snortseqno[1]<<8));
-+ LogMessage("DEBUG => [Alert_FWsam] Mgmt SeqNo : %x\n",station->stationseqno);
-+ LogMessage("DEBUG => [Alert_FWsam] Status : %i\n",sampacket.status);
-+ LogMessage("DEBUG => [Alert_FWsam] Version : %i\n",sampacket.version);
-+#endif
-+ if(len!=sizeof(FWsamPacket)) /* invalid decryption */
-+ { ErrorMessage("ERROR => [Alert_FWsam] Password mismatch! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
-+ deletestation=TRUE;
-+ sampacket.status=FWSAM_STATUS_ERROR;
-+ }
-+ else if(sampacket.version!=FWSAM_PACKETVERSION) /* invalid protocol version */
-+ { ErrorMessage("ERROR => [Alert_FWsam] Protocol version error! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
-+ deletestation=TRUE;
-+ sampacket.status=FWSAM_STATUS_ERROR;
-+ }
-+ else if(sampacket.status!=FWSAM_STATUS_OK && sampacket.status!=FWSAM_STATUS_NEWKEY && sampacket.status!=FWSAM_STATUS_RESYNC)
-+ { ErrorMessage("ERROR => [Alert_FWsam] Funky handshake error! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
-+ deletestation=TRUE;
-+ sampacket.status=FWSAM_STATUS_ERROR;
-+ }
-+ }
-+ }
-+ if(sampacket.status==FWSAM_STATUS_RESYNC) /* if station want's to resync... */
-+ { strcpy(station->stationkey,station->initialkey); /* ...we use the intial key... */
-+ memcpy(station->fwkeymod,sampacket.duration,4); /* and note the random key modifier */
-+ }
-+ if(sampacket.status==FWSAM_STATUS_NEWKEY || sampacket.status==FWSAM_STATUS_RESYNC)
-+ {
-+ FWsamNewStationKey(station,&sampacket); /* generate new TwoFish keys */
-+#ifdef FWSAMDEBUG
-+ LogMessage("DEBUG => [Alert_FWsam] Generated new encryption key...\n");
-+#endif
-+ }
-+#ifdef WIN32
-+ closesocket(stationsocket);
-+#else
-+ close(stationsocket);
-+#endif
-+ stationtry=0;
-+ }
-+ else if(sampacket.status==FWSAM_STATUS_ERROR) /* if SnortSam reports an error on second try, */
-+ {
-+#ifdef WIN32
-+ closesocket(stationsocket); /* something is messed up and ... */
-+#else
-+ close(stationsocket);
-+#endif
-+ if(stationtry>1) /* we ignore that station. */
-+ { deletestation=TRUE; /* flag for deletion */
-+ ErrorMessage("ERROR => [Alert_FWsam] Could not renegotiate key! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
-+ }
-+ else /* if we get an error on the first try, */
-+ { if(!FWsamCheckIn(station)) /* we first try to check in again. */
-+ { deletestation=TRUE;
-+ ErrorMessage("ERROR => [Alert_FWsam] Password mismatch! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
-+ }
-+ }
-+ }
-+ else /* an unknown status means trouble... */
-+ { ErrorMessage("ERROR => [Alert_FWsam] Funky handshake error! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
-+#ifdef WIN32
-+ closesocket(stationsocket);
-+#else
-+ close(stationsocket);
-+#endif
-+ deletestation=TRUE;
-+ }
-+ }
-+ else /* if the SnortSam agent uses a different packet version, we have no choice but to ignore it. */
-+ { ErrorMessage("ERROR => [Alert_FWsam] Protocol version error! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
-+#ifdef WIN32
-+ closesocket(stationsocket);
-+#else
-+ close(stationsocket);
-+#endif
-+ deletestation=TRUE;
-+ }
-+ }
-+ else /* if the intial key failed to decrypt as well, the keys are not configured the same, and we ignore that SnortSam station. */
-+ { ErrorMessage("ERROR => [Alert_FWsam] Password mismatch! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
-+#ifdef WIN32
-+ closesocket(stationsocket);
-+#else
-+ close(stationsocket);
-+#endif
-+ deletestation=TRUE;
-+ }
-+ }
-+ }
-+ free(encbuf); /* release of the TwoFishAlloc'ed encryption buffer */
-+ }
-+ if(stationtry==0 || deletestation) /* if everything went real well, or real bad... */
-+ { if(deletestation){ /* If it went bad, we remove the station from the list by marking the IP */
-+// station->stationip.s_addr=0;
-+ station->stationip.ip32[0]=0;
-+ }
-+ fwsamlist=fwsamlist->next;
-+ }
-+ }
-+ else
-+ fwsamlist=fwsamlist->next;
-+ }
-+ }
-+ else
-+ {
-+#ifdef FWSAMDEBUG
-+ LogMessage("DEBUG => [Alert_FWsam] Skipping repetitive block.\n");
-+#endif
-+ }
-+ }
-+}
-+
-+/* FWsamCheckOut will be called when Snort exists. It de-registeres this snort sensor
-+ * from the list of sensor that the SnortSam agent keeps.
-+ */
-+void FWsamCheckOut(FWsamStation *station)
-+{ FWsamPacket sampacket;
-+ SOCKET stationsocket;
-+ int i,len;
-+ char *encbuf,*decbuf;
-+ //unsigned char *encbuf,*decbuf;
-+
-+
-+ stationsocket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
-+ if(stationsocket==INVALID_SOCKET)
-+ FatalError("ERROR => [Alert_FWsam](FWsamCheckOut) Funky socket error (socket)!\n");
-+ if(bind(stationsocket,(struct sockaddr *)&(station->localsocketaddr),sizeof(struct sockaddr)))
-+ FatalError("ERROR => [Alert_FWsam](FWsamCheckOut) Could not bind socket!\n");
-+
-+ /* let's connect to the agent */
-+ if(!connect(stationsocket,(struct sockaddr *)&station->stationsocketaddr,sizeof(struct sockaddr)))
-+ { LogMessage("INFO => [Alert_FWsam](FWsamCheckOut) Disconnecting from host %s.\n",sfip_ntoa(&station->stationip));
-+ /* now build the packet */
-+ station->myseqno+=station->stationseqno; /* increase my seqno */
-+ sampacket.endiancheck=1;
-+ sampacket.snortseqno[0]=(char)station->myseqno;
-+ sampacket.snortseqno[1]=(char)(station->myseqno>>8);
-+ sampacket.fwseqno[0]=(char)station->stationseqno; /* fill station seqno */
-+ sampacket.fwseqno[1]=(char)(station->stationseqno>>8);
-+ sampacket.status=FWSAM_STATUS_CHECKOUT; /* checking out... */
-+ sampacket.version=FWSAM_PACKETVERSION;
-+
-+#ifdef FWSAMDEBUG
-+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckOut) Sending CHECKOUT\n");
-+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckOut) Snort SeqNo: %x\n",station->myseqno);
-+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckOut) Mgmt SeqNo : %x\n",station->stationseqno);
-+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckOut) Status : %i\n",sampacket.status);
-+
-+#endif
-+
-+ encbuf=TwoFishAlloc(sizeof(FWsamPacket),FALSE,FALSE,station->stationfish); /* get encryption buffer */
-+ len=TwoFishEncrypt((char *)&sampacket,&encbuf,sizeof(FWsamPacket),FALSE,station->stationfish); /* encrypt packet with current key */
-+
-+ if(send(stationsocket,encbuf,len,0)==len)
-+ { i=FWSAM_NETWAIT;
-+#ifdef WIN32
-+ ioctlsocket(stationsocket,FIONBIO,&i); /* set non blocking and wait for */
-+#else
-+ ioctl(stationsocket,FIONBIO,&i); /* set non blocking and wait for */
-+#endif
-+ while(i-- >1)
-+ { waitms(10); /* ...wait a maximum of 3 secs for response... */
-+ if(recv(stationsocket,encbuf,len,0)==len) /* ... for the status packet */
-+ i=0;
-+ }
-+ if(i) /* if we got the packet */
-+ { decbuf=(char *)&sampacket;
-+ len=TwoFishDecrypt(encbuf,&decbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,FALSE,station->stationfish);
-+
-+ if(len!=sizeof(FWsamPacket)) /* invalid decryption */
-+ { strcpy(station->stationkey,station->initialkey); /* try initial key */
-+ TwoFishDestroy(station->stationfish); /* toss this fish */
-+ station->stationfish=TwoFishInit(station->stationkey); /* re-initialze TwoFish with initial key */
-+ len=TwoFishDecrypt(encbuf,&decbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,FALSE,station->stationfish); /* and try to decrypt again */
-+ LogMessage("INFO => [Alert_FWsam](FWsamCheckOut) Had to use initial key!\n");
-+ }
-+ if(len==sizeof(FWsamPacket)) /* valid decryption */
-+ { if(sampacket.version!=FWSAM_PACKETVERSION) /* but don't really care since we are on the way out */
-+ ErrorMessage("WARNING => [Alert_FWsam](FWsamCheckOut) Protocol version error! What the hell, we're quitting anyway! :)\n");
-+ }
-+ else
-+ ErrorMessage("WARNING => [Alert_FWsam](FWsamCheckOut) Password mismatch! What the hell, we're quitting anyway! :)\n");
-+ }
-+ }
-+ free(encbuf); /* release TwoFishAlloc'ed buffer */
-+ }
-+ else
-+ LogMessage("WARNING => [Alert_FWsam] Could not connect to host %s for CheckOut. What the hell, we're quitting anyway! :)\n",sfip_ntoa(&station->stationip));
-+#ifdef WIN32
-+ closesocket(stationsocket);
-+#else
-+ close(stationsocket);
-+#endif
-+}
-+
-+
-+/* FWSamFree: Disconnects all FW-1 management stations,
-+ * closes sockets, and frees the structures.
-+ */
-+void FWsamFree(FWsamList *list)
-+{
-+ FWsamList *next;
-+
-+ while(list) /* Free pointer list for rule type */
-+ {
-+ next=list->next;
-+ free(list);
-+ list=next;
-+ }
-+ list=FWsamStationList;
-+
-+ while(list) /* Free global pointer list and stations */
-+ {
-+ next=list->next;
-+ if (list->station)
-+ {
-+ if(list->station->stationip.ip32[0])
-+ //if(list->station->stationip.s_addr)
-+ FWsamCheckOut(list->station); /* Send a Check-Out to SnortSam, */
-+
-+ TwoFishDestroy(list->station->stationfish); /* toss the fish, */
-+ free(list->station); /* free station, */
-+ }
-+ free(list); /* free pointer, */
-+ list=next; /* and move to next. */
-+ }
-+ FWsamStationList=NULL;
-+ if(FWsamOptionField)
-+ free(FWsamOptionField);
-+}
-+
-+void AlertFWsamCleanExitFunc(int signal, void *arg)
-+{ FWsamList *fwsamlist;
-+
-+#ifdef FWSAMDEBUG
-+ LogMessage("DEBUG => [Alert_FWsam](AlertFWsamCleanExitFunc) Exiting...\n");
-+#endif
-+
-+ fwsamlist=(FWsamList *)arg;
-+ FWsamFree(fwsamlist); /* Free all elements */
-+}
-+
-+void AlertFWsamRestartFunc(int signal, void *arg)
-+{ FWsamList *fwsamlist;
-+
-+#ifdef FWSAMDEBUG
-+ LogMessage("DEBUG => [Alert_FWsam](AlertFWsamRestartFunc) Restarting...\n");
-+#endif
-+
-+ fwsamlist=(FWsamList *)arg;
-+ FWsamFree(fwsamlist); /* Free all elements */
-+}
-+
-+/* This routine registers this Snort sensor with SnortSam.
-+ * It will also change the encryption key based on some variables.
-+ */
-+int FWsamCheckIn(FWsamStation *station)
-+{ int i,len,stationok=TRUE;
-+ FWsamPacket sampacket;
-+ char *encbuf,*decbuf;
-+ //unsigned char *encbuf,*decbuf;
-+ SOCKET stationsocket;
-+
-+
-+ /* create a socket for the station */
-+ stationsocket=socket(PF_INET,SOCK_STREAM,IPPROTO_TCP);
-+ if(stationsocket==INVALID_SOCKET)
-+ FatalError("ERROR => [Alert_FWsam](FWsamCheckIn) Funky socket error (socket)!\n");
-+ if(bind(stationsocket,(struct sockaddr *)&(station->localsocketaddr),sizeof(struct sockaddr)))
-+ FatalError("ERROR => [Alert_FWsam](FWsamCheckIn) Could not bind socket!\n");
-+
-+ i=TRUE;
-+ /* let's connect to the agent */
-+ if(connect(stationsocket,(struct sockaddr *)&station->stationsocketaddr,sizeof(struct sockaddr)))
-+ LogMessage("WARNING => [Alert_FWsam](FWsamCheckIn) Could not connect to host %s. Will try later.\n",sfip_ntoa(&station->stationip));
-+ else
-+ { LogMessage("INFO => [Alert_FWsam](FWsamCheckIn) Connected to host %s.\n",sfip_ntoa(&station->stationip));
-+ /* now build the packet */
-+ sampacket.endiancheck=1;
-+ sampacket.snortseqno[0]=(char)station->myseqno; /* fill my sequence number number */
-+ sampacket.snortseqno[1]=(char)(station->myseqno>>8); /* fill my sequence number number */
-+ sampacket.status=FWSAM_STATUS_CHECKIN; /* let's check in */
-+ sampacket.version=FWSAM_PACKETVERSION; /* set the packet version */
-+ memcpy(sampacket.duration,station->mykeymod,4); /* we'll send SnortSam our key modifier in the duration slot */
-+ /* (the checkin packet is just the plain initial key) */
-+#ifdef FWSAMDEBUG
-+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Sending CheckIn\n");
-+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Snort SeqNo: %x\n",station->myseqno);
-+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Mode : %i\n",sampacket.status);
-+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Version : %i\n",sampacket.version);
-+#endif
-+ encbuf=TwoFishAlloc(sizeof(FWsamPacket),FALSE,FALSE,station->stationfish); /* get buffer for encryption */
-+ len=TwoFishEncrypt((char *)&sampacket,&encbuf,sizeof(FWsamPacket),FALSE,station->stationfish); /* encrypt with initial key */
-+ if(send(stationsocket,encbuf,len,0)!=len) /* weird...could not send */
-+ LogMessage("WARNING => [Alert_FWsam](FWsamCheckIn) Could not send to host %s. Will try again later.\n",sfip_ntoa(&station->stationip));
-+ else
-+ { i=FWSAM_NETWAIT;
-+#ifdef WIN32
-+ ioctlsocket(stationsocket,FIONBIO,&i); /* set non blocking and wait for */
-+#else
-+ ioctl(stationsocket,FIONBIO,&i); /* set non blocking and wait for */
-+#endif
-+ while(i-- >1)
-+ { waitms(10); /* wait a maximum of 3 secs for response */
-+ if(recv(stationsocket,encbuf,len,0)==len)
-+ i=0;
-+ }
-+ if(!i) /* time up? */
-+ LogMessage("WARNING => [Alert_FWsam](FWsamCheckIn) Did not receive response from host %s. Will try again later.\n",sfip_ntoa(&station->stationip));
-+ else
-+ { decbuf=(char *)&sampacket; /* got status packet */
-+ len=TwoFishDecrypt(encbuf,&decbuf,sizeof(FWsamPacket)+TwoFish_BLOCK_SIZE,FALSE,station->stationfish); /* try to decrypt with initial key */
-+ if(len==sizeof(FWsamPacket)) /* valid decryption */
-+ {
-+#ifdef FWSAMDEBUG
-+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Received %s\n",sampacket.status==FWSAM_STATUS_OK?"OK":
-+ sampacket.status==FWSAM_STATUS_NEWKEY?"NEWKEY":
-+ sampacket.status==FWSAM_STATUS_RESYNC?"RESYNC":
-+ sampacket.status==FWSAM_STATUS_HOLD?"HOLD":"ERROR");
-+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Snort SeqNo: %x\n",sampacket.snortseqno[0]|(sampacket.snortseqno[1]<<8));
-+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Mgmt SeqNo : %x\n",sampacket.fwseqno[0]|(sampacket.fwseqno[1]<<8));
-+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Status : %i\n",sampacket.status);
-+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Version : %i\n",sampacket.version);
-+#endif
-+ if(sampacket.version==FWSAM_PACKETVERSION) /* master speaks my language */
-+ { if(sampacket.status==FWSAM_STATUS_OK || sampacket.status==FWSAM_STATUS_NEWKEY || sampacket.status==FWSAM_STATUS_RESYNC)
-+ { station->stationseqno=sampacket.fwseqno[0]|(sampacket.fwseqno[1]<<8); /* get stations seqno */
-+ station->lastcontact=(unsigned long)time(NULL);
-+
-+ if(sampacket.status==FWSAM_STATUS_NEWKEY || sampacket.status==FWSAM_STATUS_RESYNC) /* generate new keys */
-+ { memcpy(station->fwkeymod,sampacket.duration,4); /* note the key modifier */
-+ FWsamNewStationKey(station,&sampacket); /* and generate new TwoFish keys (with key modifiers) */
-+#ifdef FWSAMDEBUG
-+ LogMessage("DEBUG => [Alert_FWsam](FWsamCheckIn) Generated new encryption key...\n");
-+#endif
-+ }
-+ }
-+ else /* weird, got a strange status back */
-+ { ErrorMessage("ERROR => [Alert_FWsam](FWsamCheckIn) Funky handshake error! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
-+ stationok=FALSE;
-+ }
-+ }
-+ else /* packet version does not match */
-+ { ErrorMessage("ERROR =>[Alert_FWsam](FWsamCheckIn) Protocol version error! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
-+ stationok=FALSE;
-+ }
-+ }
-+ else /* key does not match */
-+ { ErrorMessage("ERROR => [Alert_FWsam](FWsamCheckIn) Password mismatch! Ignoring host %s.\n",sfip_ntoa(&station->stationip));
-+ stationok=FALSE;
-+ }
-+ }
-+ }
-+ free(encbuf); /* release TwoFishAlloc'ed buffer */
-+ }
-+#ifdef WIN32
-+ closesocket(stationsocket);
-+#else
-+ close(stationsocket);
-+#endif
-+ return stationok;
-+}
-+#undef FWSAMDEBUG
-+
-
-Index: snort-2.8.6.1/src/output-plugins/spo_alert_fwsam.h
-===================================================================
---- snort-2.8.6.1/src/output-plugins/spo_alert_fwsam.h (Revision 0)
-+++ snort-2.8.6.1/src/output-plugins/spo_alert_fwsam.h (Revision 3)
-@@ -0,0 +1,216 @@
-+/* $Id: snortpatchb,v 1.5 2005/10/06 08:50:39 fknobbe Exp $
-+**
-+** spo_alert_fwsam.h
-+**
-+** Copyright (c) 2001-2004 Frank Knobbe <frank@knobbe.us>
-+**
-+** 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.
-+*/
-+
-+/* This file gets included in plugbase.c when it is integrated into the rest
-+ * of the program.
-+ *
-+ * For more info, see the beginning of spo_alert_fwsam.c
-+ *
-+ */
-+
-+#ifndef __SPO_FWSAM_H__
-+#define __SPO_FWSAM_H__
-+
-+#include "snort.h"
-+#include "rules.h"
-+#include "plugbase.h"
-+#include "plugin_enum.h"
-+#include "fatal.h"
-+#include "util.h"
-+#include "twofish.h"
-+
-+#include <stdlib.h>
-+#include <stdio.h>
-+#include <time.h>
-+#include <string.h>
-+#include <ctype.h>
-+#include <unistd.h>
-+
-+
-+/* just some compatibility stuff */
-+#ifdef WIN32
-+#if !defined(_WINSOCKAPI_) && !defined(_WINSOCK2API_)
-+#include <winsock.h>
-+#endif
-+#define waitms(x) Sleep(x)
-+
-+#else
-+
-+#include <sys/socket.h>
-+#include <netinet/in.h>
-+#include <arpa/inet.h>
-+#include <sys/ioctl.h>
-+#include <netdb.h>
-+
-+#ifdef SOLARIS
-+#include <sys/filio.h>
-+#endif
-+
-+typedef int SOCKET;
-+
-+#ifndef INVALID_SOCKET
-+#define INVALID_SOCKET -1
-+#endif
-+
-+#define waitms(x) usleep((x)*1000)
-+
-+#endif
-+
-+#ifndef FALSE
-+#define FALSE 0
-+#endif
-+#ifndef TRUE
-+#define TRUE !FALSE
-+#endif
-+#ifndef bool
-+#define bool int
-+#endif
-+
-+
-+#if defined(_DEBUG) || defined(DEBUG)
-+#ifndef FWSAMDEBUG
-+#define FWSAMDEBUG
-+#endif
-+#else
-+#endif
-+
-+
-+/* Official Snort PlugIn Number has been moved into plugin_enum.h */
-+
-+
-+/* fixed defines */
-+
-+#define FWSAM_DEFAULTPORT 898 /* Default port if user does not specify one in snort.conf */
-+ /* (Was unused last time I checked...) */
-+#define FWSAM_PACKETVERSION 14 /* version of the packet. Will increase with enhancements. */
-+
-+#define FWSAM_STATUS_CHECKIN 1 /* snort to fw */
-+#define FWSAM_STATUS_CHECKOUT 2
-+#define FWSAM_STATUS_BLOCK 3
-+#define FWSAM_STATUS_UNBLOCK 9
-+
-+#define FWSAM_STATUS_OK 4 /* fw to snort */
-+#define FWSAM_STATUS_ERROR 5
-+#define FWSAM_STATUS_NEWKEY 6
-+#define FWSAM_STATUS_RESYNC 7
-+#define FWSAM_STATUS_HOLD 8
-+
-+#define FWSAM_LOG_NONE 0
-+#define FWSAM_LOG_SHORTLOG 1
-+#define FWSAM_LOG_SHORTALERT 2
-+#define FWSAM_LOG_LONGLOG 3
-+#define FWSAM_LOG_LONGALERT 4
-+#define FWSAM_LOG (FWSAM_LOG_SHORTLOG|FWSAM_LOG_SHORTALERT|FWSAM_LOG_LONGLOG|FWSAM_LOG_LONGALERT)
-+#define FWSAM_WHO_DST 8
-+#define FWSAM_WHO_SRC 16
-+#define FWSAM_WHO (FWSAM_WHO_DST|FWSAM_WHO_SRC)
-+#define FWSAM_HOW_IN 32
-+#define FWSAM_HOW_OUT 64
-+#define FWSAM_HOW_INOUT (FWSAM_HOW_IN|FWSAM_HOW_OUT)
-+#define FWSAM_HOW_THIS 128
-+#define FWSAM_HOW (FWSAM_HOW_IN|FWSAM_HOW_OUT|FWSAM_HOW_THIS)
-+
-+
-+/* user adjustable defines */
-+
-+#define FWSAM_REPET_BLOCKS 10 /* Snort remembers this amount of last blocks and... */
-+#define FWSAM_REPET_TIME 20 /* ...checks if they fall within this time. If so,... */
-+ /* ...the blocking request is not send. */
-+
-+#define FWSAM_NETWAIT 300 /* 100th of a second. 3 sec timeout for network connections */
-+#define FWSAM_NETHOLD 6000 /* 100th of a second. 60 sec timeout for holding */
-+
-+#define SID_MAPFILE "sid-block.map"
-+#define SID_ALT_MAPFILE "sid-fwsam.map"
-+
-+#define FWSAM_FANCYFETCH /* This will invoke a fast sid lookup routine */
-+
-+
-+/* vars */
-+
-+typedef struct _FWsamstation /* structure of a mgmt station */
-+{ unsigned short myseqno;
-+ unsigned short stationseqno;
-+ unsigned char mykeymod[4];
-+ unsigned char fwkeymod[4];
-+ unsigned short stationport;
-+ //struct in_addr stationip;
-+ sfip_t stationip;
-+ struct sockaddr_in localsocketaddr;
-+ struct sockaddr_in stationsocketaddr;
-+ TWOFISH *stationfish;
-+ char initialkey[TwoFish_KEY_LENGTH+2];
-+ char stationkey[TwoFish_KEY_LENGTH+2];
-+ time_t lastcontact;
-+/* time_t sleepstart; */
-+} FWsamStation;
-+
-+typedef struct _FWsampacket /* 2 blocks (3rd block is header from TwoFish) */
-+{ unsigned short endiancheck; /* 0 */
-+ unsigned char srcip[4]; /* 2 */
-+ unsigned char dstip[4]; /* 6 */
-+ unsigned char duration[4]; /* 10 */
-+ unsigned char snortseqno[2]; /* 14 */
-+ unsigned char fwseqno[2]; /* 16 */
-+ unsigned char srcport[2]; /* 18 */
-+ unsigned char dstport[2]; /* 20 */
-+ unsigned char protocol[2]; /* 22 */
-+ unsigned char fwmode; /* 24 */
-+ unsigned char version; /* 25 */
-+ unsigned char status; /* 26 */
-+ unsigned char sig_id[4]; /* 27 */
-+ unsigned char fluff; /* 31 */
-+} FWsamPacket; /* 32 bytes in size */
-+
-+typedef struct _FWsamoptions /* snort rule options */
-+{ unsigned long sid;
-+ unsigned long duration;
-+ unsigned char who;
-+ unsigned char how;
-+ unsigned char loglevel;
-+} FWsamOptions;
-+
-+typedef struct _FWsamlistpointer
-+{ FWsamStation *station;
-+ struct _FWsamlistpointer *next;
-+} FWsamList;
-+
-+
-+/* functions */
-+void AlertFWsamSetup(void);
-+void AlertFWsamInit(char *args);
-+void AlertFWsamOptionInit(char *args,OptTreeNode *otn,int protocol);
-+void AlertFWsamCleanExitFunc(int signal, void *arg);
-+void AlertFWsamRestartFunc(int signal, void *arg);
-+void AlertFWsam(Packet *p, char *msg, void *arg, Event *event);
-+int FWsamCheckIn(FWsamStation *station);
-+void FWsamCheckOut(FWsamStation *station);
-+void FWsamNewStationKey(FWsamStation *station,FWsamPacket *packet);
-+void FWsamFixPacketEndian(FWsamPacket *p);
-+unsigned long FWsamParseDuration(char *p);
-+void FWsamFree(FWsamList *fwsamlist);
-+int FWsamStationExists(FWsamStation *who,FWsamList *list);
-+int FWsamReadLine(char *,unsigned long,FILE *);
-+void FWsamParseLine(FWsamOptions *,char *);
-+FWsamOptions *FWsamGetOption(unsigned long);
-+int FWsamParseOption(FWsamOptions *,char *);
-+
-+#endif /* __SPO_FWSAM_H__ */
-
-Index: snort-2.8.6.1/src/output-plugins/Makefile.am
-===================================================================
---- snort-2.8.6.1/src/output-plugins/Makefile.am (Revision 1)
-+++ snort-2.8.6.1/src/output-plugins/Makefile.am (Revision 3)
-@@ -11,6 +11,7 @@
- spo_log_tcpdump.h spo_unified.c spo_unified2.c spo_unified.h spo_unified2.h \
- spo_log_ascii.c spo_log_ascii.h spo_alert_sf_socket.h spo_alert_sf_socket.c \
- spo_alert_prelude.c spo_alert_prelude.h spo_alert_arubaaction.c spo_alert_arubaaction.h \
-+spo_alert_fwsam.c spo_alert_fwsam.h \
- spo_alert_test.c spo_alert_test.h
-
- INCLUDES = @INCLUDES@
-Index: snort-2.8.6.1/src/plugbase.c
-===================================================================
---- snort-2.8.6.1/src/plugbase.c (Revision 1)
-+++ snort-2.8.6.1/src/plugbase.c (Revision 3)
-@@ -125,6 +125,7 @@
- #endif
-
- #include "output-plugins/spo_alert_test.h"
-+#include "output-plugins/spo_alert_fwsam.h"
-
- extern ListHead *head_tmp;
- extern PreprocConfigFuncNode *preproc_config_funcs;
-@@ -1240,6 +1241,7 @@
- #endif
-
- AlertTestSetup();
-+ AlertFWsamSetup();
- }
-
- /****************************************************************************
-Index: snort-2.8.6.1/src/Makefile.am
-===================================================================
---- snort-2.8.6.1/src/Makefile.am (Revision 1)
-+++ snort-2.8.6.1/src/Makefile.am (Revision 3)
-@@ -52,7 +52,8 @@
- detection_filter.c detection_filter.h \
- rate_filter.c rate_filter.h \
- obfuscation.c obfuscation.h \
--rule_option_types.h
-+rule_option_types.h \
-+twofish.c twofish.h
-
- snort_LDADD = output-plugins/libspo.a \
- detection-plugins/libspd.a \
-Index: snort-2.8.6.1/autojunk.sh
-===================================================================
---- snort-2.8.6.1/autojunk.sh (Revision 0)
-+++ snort-2.8.6.1/autojunk.sh (Revision 3)
-@@ -0,0 +1,7 @@
-+#!/bin/sh
-+# the list of commands that need to run before we do a compile
-+libtoolize --automake --copy
-+aclocal -I m4
-+autoheader
-+automake --add-missing --copy
-+autoconf
-
-Index: snort-2.8.6.1/etc/snort.conf
-===================================================================
---- snort-2.8.6.1/etc/snort.conf (Revision 1)
-+++ snort-2.8.6.1/etc/snort.conf (Revision 3)
-@@ -277,6 +277,32 @@
- # prelude
- # output alert_prelude
-
-+# snortsam
-+# In order to cause Snort to send a blocking request to the SnortSam agent,
-+# that agent has to be listed, including the port it listens on,
-+# and the encryption key it is using. The statement for that is:
-+#
-+# output alert_fwsam: {SnortSam Station}:{port}/{password}
-+#
-+# {SnortSam Station}: IP address or host name of the host where SnortSam is running.
-+# {port}: The port the remote SnortSam agent listens on.
-+# {password}: The password, or key, used for encryption of the
-+# communication to the remote agent.
-+#
-+# At the very least, the IP address or host name of the host running SnortSam
-+# needs to be specified. If the port is omitted, it defaults to TCP port 898.
-+# If the password is omitted, it defaults to a preset password.
-+# (In which case it needs to be omitted on the SnortSam agent as well)
-+#
-+# More than one host can be specified, but has to be done on the same line.
-+# Just separate them with one or more spaces.
-+#
-+# Examples:
-+#
-+# output alert_fwsam: firewall/idspassword
-+# output alert_fwsam: fw1.domain.tld:898/mykey
-+# output alert_fwsam: 192.168.0.1/borderfw 192.168.1.254/wanfw
-+
- # metadata reference data. do not modify these lines
- include classification.config
- include reference.config
diff --git a/config/snort-dev/patches/inlinemode_options_flags.txt b/config/snort-dev/patches/inlinemode_options_flags.txt
deleted file mode 100644
index e69de29b..00000000
--- a/config/snort-dev/patches/inlinemode_options_flags.txt
+++ /dev/null
diff --git a/config/snort-dev/patches/spoink_patch/2.8.6/Makefile.am b/config/snort-dev/patches/spoink_patch/2.8.6/Makefile.am
deleted file mode 100644
index 0879c6e3..00000000
--- a/config/snort-dev/patches/spoink_patch/2.8.6/Makefile.am
+++ /dev/null
@@ -1,17 +0,0 @@
-## $Id
-AUTOMAKE_OPTIONS=foreign no-dependencies
-
-noinst_LIBRARIES = libspo.a
-
-libspo_a_SOURCES = spo_alert_fast.c spo_alert_fast.h \
-spo_alert_full.c spo_alert_full.h \
-spo_alert_syslog.c spo_alert_syslog.h spo_alert_unixsock.c \
-spo_alert_unixsock.h spo_csv.c spo_csv.h spo_database.c spo_database.h \
-spo_log_null.c spo_log_null.h spo_log_tcpdump.c \
-spo_log_tcpdump.h spo_unified.c spo_unified2.c spo_unified.h spo_unified2.h \
-spo_log_ascii.c spo_log_ascii.h spo_alert_sf_socket.h spo_alert_sf_socket.c \
-spo_alert_prelude.c spo_alert_prelude.h spo_alert_arubaaction.c spo_alert_arubaaction.h \
-spo_alert_test.c spo_alert_test.h \
-spo_pf.h spo_pf.c
-
-INCLUDES = @INCLUDES@
diff --git a/config/snort-dev/patches/spoink_patch/2.8.6/Makefile.in b/config/snort-dev/patches/spoink_patch/2.8.6/Makefile.in
deleted file mode 100644
index 3f06cc31..00000000
--- a/config/snort-dev/patches/spoink_patch/2.8.6/Makefile.in
+++ /dev/null
@@ -1,445 +0,0 @@
-# Makefile.in generated by automake 1.9.6 from Makefile.am.
-# @configure_input@
-
-# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004, 2005 Free Software Foundation, Inc.
-# This Makefile.in is free software; the Free Software Foundation
-# gives unlimited permission to copy and/or distribute it,
-# with or without modifications, as long as this notice is preserved.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
-# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
-# PARTICULAR PURPOSE.
-
-@SET_MAKE@
-
-srcdir = @srcdir@
-top_srcdir = @top_srcdir@
-VPATH = @srcdir@
-pkgdatadir = $(datadir)/@PACKAGE@
-pkglibdir = $(libdir)/@PACKAGE@
-pkgincludedir = $(includedir)/@PACKAGE@
-top_builddir = ../..
-am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
-INSTALL = @INSTALL@
-install_sh_DATA = $(install_sh) -c -m 644
-install_sh_PROGRAM = $(install_sh) -c
-install_sh_SCRIPT = $(install_sh) -c
-INSTALL_HEADER = $(INSTALL_DATA)
-transform = $(program_transform_name)
-NORMAL_INSTALL = :
-PRE_INSTALL = :
-POST_INSTALL = :
-NORMAL_UNINSTALL = :
-PRE_UNINSTALL = :
-POST_UNINSTALL = :
-build_triplet = @build@
-host_triplet = @host@
-subdir = src/output-plugins
-DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in
-ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
-am__aclocal_m4_deps = $(top_srcdir)/m4/libprelude.m4 \
- $(top_srcdir)/configure.in
-am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
- $(ACLOCAL_M4)
-mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
-CONFIG_HEADER = $(top_builddir)/config.h
-CONFIG_CLEAN_FILES =
-LIBRARIES = $(noinst_LIBRARIES)
-ARFLAGS = cru
-libspo_a_AR = $(AR) $(ARFLAGS)
-libspo_a_LIBADD =
-am_libspo_a_OBJECTS = spo_alert_fast.$(OBJEXT) \
- spo_alert_full.$(OBJEXT) spo_alert_syslog.$(OBJEXT) \
- spo_alert_unixsock.$(OBJEXT) spo_csv.$(OBJEXT) \
- spo_database.$(OBJEXT) spo_log_null.$(OBJEXT) \
- spo_log_tcpdump.$(OBJEXT) spo_unified.$(OBJEXT) \
- spo_unified2.$(OBJEXT) spo_log_ascii.$(OBJEXT) \
- spo_alert_sf_socket.$(OBJEXT) spo_alert_prelude.$(OBJEXT) \
- spo_alert_arubaaction.$(OBJEXT) spo_alert_test.$(OBJEXT) \
- spo_pf.$(OBJEXT)
-libspo_a_OBJECTS = $(am_libspo_a_OBJECTS)
-DEFAULT_INCLUDES = -I. -I$(srcdir) -I$(top_builddir)
-depcomp =
-am__depfiles_maybe =
-COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
- $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
-LTCOMPILE = $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) \
- $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
- $(AM_CFLAGS) $(CFLAGS)
-CCLD = $(CC)
-LINK = $(LIBTOOL) --tag=CC --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
- $(AM_LDFLAGS) $(LDFLAGS) -o $@
-SOURCES = $(libspo_a_SOURCES)
-DIST_SOURCES = $(libspo_a_SOURCES)
-ETAGS = etags
-CTAGS = ctags
-DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
-ACLOCAL = @ACLOCAL@
-AMDEP_FALSE = @AMDEP_FALSE@
-AMDEP_TRUE = @AMDEP_TRUE@
-AMTAR = @AMTAR@
-AR = @AR@
-AUTOCONF = @AUTOCONF@
-AUTOHEADER = @AUTOHEADER@
-AUTOMAKE = @AUTOMAKE@
-AWK = @AWK@
-BUILD_DYNAMIC_EXAMPLES_FALSE = @BUILD_DYNAMIC_EXAMPLES_FALSE@
-BUILD_DYNAMIC_EXAMPLES_TRUE = @BUILD_DYNAMIC_EXAMPLES_TRUE@
-CC = @CC@
-CCDEPMODE = @CCDEPMODE@
-CFLAGS = @CFLAGS@
-CPP = @CPP@
-CPPFLAGS = @CPPFLAGS@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
-CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
-CYGPATH_W = @CYGPATH_W@
-DEFS = @DEFS@
-DEPDIR = @DEPDIR@
-ECHO = @ECHO@
-ECHO_C = @ECHO_C@
-ECHO_N = @ECHO_N@
-ECHO_T = @ECHO_T@
-EGREP = @EGREP@
-EXEEXT = @EXEEXT@
-F77 = @F77@
-FFLAGS = @FFLAGS@
-HAVE_DYNAMIC_PLUGINS_FALSE = @HAVE_DYNAMIC_PLUGINS_FALSE@
-HAVE_DYNAMIC_PLUGINS_TRUE = @HAVE_DYNAMIC_PLUGINS_TRUE@
-HAVE_SUP_IP6_FALSE = @HAVE_SUP_IP6_FALSE@
-HAVE_SUP_IP6_TRUE = @HAVE_SUP_IP6_TRUE@
-HAVE_TARGET_BASED_FALSE = @HAVE_TARGET_BASED_FALSE@
-HAVE_TARGET_BASED_TRUE = @HAVE_TARGET_BASED_TRUE@
-HAVE_ZLIB_FALSE = @HAVE_ZLIB_FALSE@
-HAVE_ZLIB_TRUE = @HAVE_ZLIB_TRUE@
-INCLUDES = @INCLUDES@
-INSTALL_DATA = @INSTALL_DATA@
-INSTALL_PROGRAM = @INSTALL_PROGRAM@
-INSTALL_SCRIPT = @INSTALL_SCRIPT@
-INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
-LDFLAGS = @LDFLAGS@
-LEX = @LEX@
-LIBOBJS = @LIBOBJS@
-LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
-LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
-LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
-LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
-LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
-LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
-LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
-LIBS = @LIBS@
-LIBTOOL = @LIBTOOL@
-LN_S = @LN_S@
-LTLIBOBJS = @LTLIBOBJS@
-MAINT = @MAINT@
-MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
-MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
-MAKEINFO = @MAKEINFO@
-OBJEXT = @OBJEXT@
-PACKAGE = @PACKAGE@
-PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
-PACKAGE_NAME = @PACKAGE_NAME@
-PACKAGE_STRING = @PACKAGE_STRING@
-PACKAGE_TARNAME = @PACKAGE_TARNAME@
-PACKAGE_VERSION = @PACKAGE_VERSION@
-PATH_SEPARATOR = @PATH_SEPARATOR@
-RANLIB = @RANLIB@
-SED = @SED@
-SET_MAKE = @SET_MAKE@
-SHELL = @SHELL@
-STRIP = @STRIP@
-VERSION = @VERSION@
-YACC = @YACC@
-ac_ct_AR = @ac_ct_AR@
-ac_ct_CC = @ac_ct_CC@
-ac_ct_CXX = @ac_ct_CXX@
-ac_ct_F77 = @ac_ct_F77@
-ac_ct_RANLIB = @ac_ct_RANLIB@
-ac_ct_STRIP = @ac_ct_STRIP@
-am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
-am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
-am__fastdepCXX_FALSE = @am__fastdepCXX_FALSE@
-am__fastdepCXX_TRUE = @am__fastdepCXX_TRUE@
-am__include = @am__include@
-am__leading_dot = @am__leading_dot@
-am__quote = @am__quote@
-am__tar = @am__tar@
-am__untar = @am__untar@
-bindir = @bindir@
-build = @build@
-build_alias = @build_alias@
-build_cpu = @build_cpu@
-build_os = @build_os@
-build_vendor = @build_vendor@
-datadir = @datadir@
-exec_prefix = @exec_prefix@
-extra_incl = @extra_incl@
-host = @host@
-host_alias = @host_alias@
-host_cpu = @host_cpu@
-host_os = @host_os@
-host_vendor = @host_vendor@
-includedir = @includedir@
-infodir = @infodir@
-install_sh = @install_sh@
-libdir = @libdir@
-libexecdir = @libexecdir@
-localstatedir = @localstatedir@
-mandir = @mandir@
-mkdir_p = @mkdir_p@
-oldincludedir = @oldincludedir@
-prefix = @prefix@
-program_transform_name = @program_transform_name@
-sbindir = @sbindir@
-sharedstatedir = @sharedstatedir@
-sysconfdir = @sysconfdir@
-target_alias = @target_alias@
-AUTOMAKE_OPTIONS = foreign no-dependencies
-noinst_LIBRARIES = libspo.a
-libspo_a_SOURCES = spo_alert_fast.c spo_alert_fast.h \
-spo_alert_full.c spo_alert_full.h \
-spo_alert_syslog.c spo_alert_syslog.h spo_alert_unixsock.c \
-spo_alert_unixsock.h spo_csv.c spo_csv.h spo_database.c spo_database.h \
-spo_log_null.c spo_log_null.h spo_log_tcpdump.c \
-spo_log_tcpdump.h spo_unified.c spo_unified2.c spo_unified.h spo_unified2.h \
-spo_log_ascii.c spo_log_ascii.h spo_alert_sf_socket.h spo_alert_sf_socket.c \
-spo_alert_prelude.c spo_alert_prelude.h spo_alert_arubaaction.c spo_alert_arubaaction.h \
-spo_alert_test.c spo_alert_test.h \
-spo_pf.h spo_pf.c
-
-all: all-am
-
-.SUFFIXES:
-.SUFFIXES: .c .lo .o .obj
-$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
- @for dep in $?; do \
- case '$(am__configure_deps)' in \
- *$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
- exit 1;; \
- esac; \
- done; \
- echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign src/output-plugins/Makefile'; \
- cd $(top_srcdir) && \
- $(AUTOMAKE) --foreign src/output-plugins/Makefile
-.PRECIOUS: Makefile
-Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
- @case '$?' in \
- *config.status*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
- *) \
- echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
- cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
- esac;
-
-$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-
-clean-noinstLIBRARIES:
- -test -z "$(noinst_LIBRARIES)" || rm -f $(noinst_LIBRARIES)
-libspo.a: $(libspo_a_OBJECTS) $(libspo_a_DEPENDENCIES)
- -rm -f libspo.a
- $(libspo_a_AR) libspo.a $(libspo_a_OBJECTS) $(libspo_a_LIBADD)
- $(RANLIB) libspo.a
-
-mostlyclean-compile:
- -rm -f *.$(OBJEXT)
-
-distclean-compile:
- -rm -f *.tab.c
-
-.c.o:
- $(COMPILE) -c $<
-
-.c.obj:
- $(COMPILE) -c `$(CYGPATH_W) '$<'`
-
-.c.lo:
- $(LTCOMPILE) -c -o $@ $<
-
-mostlyclean-libtool:
- -rm -f *.lo
-
-clean-libtool:
- -rm -rf .libs _libs
-
-distclean-libtool:
- -rm -f libtool
-uninstall-info-am:
-
-ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
- mkid -fID $$unique
-tags: TAGS
-
-TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- tags=; \
- here=`pwd`; \
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
- if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
- test -n "$$unique" || unique=$$empty_fix; \
- $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
- $$tags $$unique; \
- fi
-ctags: CTAGS
-CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
- $(TAGS_FILES) $(LISP)
- tags=; \
- here=`pwd`; \
- list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
- unique=`for i in $$list; do \
- if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
- done | \
- $(AWK) ' { files[$$0] = 1; } \
- END { for (i in files) print i; }'`; \
- test -z "$(CTAGS_ARGS)$$tags$$unique" \
- || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
- $$tags $$unique
-
-GTAGS:
- here=`$(am__cd) $(top_builddir) && pwd` \
- && cd $(top_srcdir) \
- && gtags -i $(GTAGS_ARGS) $$here
-
-distclean-tags:
- -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
-
-distdir: $(DISTFILES)
- @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
- topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
- list='$(DISTFILES)'; for file in $$list; do \
- case $$file in \
- $(srcdir)/*) file=`echo "$$file" | sed "s|^$$srcdirstrip/||"`;; \
- $(top_srcdir)/*) file=`echo "$$file" | sed "s|^$$topsrcdirstrip/|$(top_builddir)/|"`;; \
- esac; \
- if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
- dir=`echo "$$file" | sed -e 's,/[^/]*$$,,'`; \
- if test "$$dir" != "$$file" && test "$$dir" != "."; then \
- dir="/$$dir"; \
- $(mkdir_p) "$(distdir)$$dir"; \
- else \
- dir=''; \
- fi; \
- if test -d $$d/$$file; then \
- if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
- cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
- fi; \
- cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
- else \
- test -f $(distdir)/$$file \
- || cp -p $$d/$$file $(distdir)/$$file \
- || exit 1; \
- fi; \
- done
-check-am: all-am
-check: check-am
-all-am: Makefile $(LIBRARIES)
-installdirs:
-install: install-am
-install-exec: install-exec-am
-install-data: install-data-am
-uninstall: uninstall-am
-
-install-am: all-am
- @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
-
-installcheck: installcheck-am
-install-strip:
- $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
- install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
- `test -z '$(STRIP)' || \
- echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
-mostlyclean-generic:
-
-clean-generic:
-
-distclean-generic:
- -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-
-maintainer-clean-generic:
- @echo "This command is intended for maintainers to use"
- @echo "it deletes files that may require special tools to rebuild."
-clean: clean-am
-
-clean-am: clean-generic clean-libtool clean-noinstLIBRARIES \
- mostlyclean-am
-
-distclean: distclean-am
- -rm -f Makefile
-distclean-am: clean-am distclean-compile distclean-generic \
- distclean-libtool distclean-tags
-
-dvi: dvi-am
-
-dvi-am:
-
-html: html-am
-
-info: info-am
-
-info-am:
-
-install-data-am:
-
-install-exec-am:
-
-install-info: install-info-am
-
-install-man:
-
-installcheck-am:
-
-maintainer-clean: maintainer-clean-am
- -rm -f Makefile
-maintainer-clean-am: distclean-am maintainer-clean-generic
-
-mostlyclean: mostlyclean-am
-
-mostlyclean-am: mostlyclean-compile mostlyclean-generic \
- mostlyclean-libtool
-
-pdf: pdf-am
-
-pdf-am:
-
-ps: ps-am
-
-ps-am:
-
-uninstall-am: uninstall-info-am
-
-.PHONY: CTAGS GTAGS all all-am check check-am clean clean-generic \
- clean-libtool clean-noinstLIBRARIES ctags distclean \
- distclean-compile distclean-generic distclean-libtool \
- distclean-tags distdir dvi dvi-am html html-am info info-am \
- install install-am install-data install-data-am install-exec \
- install-exec-am install-info install-info-am install-man \
- install-strip installcheck installcheck-am installdirs \
- maintainer-clean maintainer-clean-generic mostlyclean \
- mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
- pdf pdf-am ps ps-am tags uninstall uninstall-am \
- uninstall-info-am
-
-# Tell versions [3.59,3.63) of GNU make to not export all variables.
-# Otherwise a system limit (for SysV at least) may be exceeded.
-.NOEXPORT:
diff --git a/config/snort-dev/patches/spoink_patch/2.8.6/plugbase.c b/config/snort-dev/patches/spoink_patch/2.8.6/plugbase.c
deleted file mode 100644
index 31f381a8..00000000
--- a/config/snort-dev/patches/spoink_patch/2.8.6/plugbase.c
+++ /dev/null
@@ -1,1544 +0,0 @@
-/* $Id$ */
-/*
-** Copyright (C) 2002-2010 Sourcefire, Inc.
-** Copyright (C) 1998-2002 Martin Roesch <roesch@sourcefire.com>
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License Version 2 as
-** published by the Free Software Foundation. You may not use, modify or
-** distribute this program under any other version of the GNU General
-** Public License.
-**
-** 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.
-*/
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <assert.h>
-
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-
-#ifndef WIN32
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#endif /* !WIN32 */
-#include <time.h>
-#include <errno.h>
-
-#include "sf_types.h"
-#include "plugbase.h"
-#include "spo_plugbase.h"
-#include "snort.h"
-#include "debug.h"
-#include "util.h"
-#include "log.h"
-#include "detect.h"
-
-/* built-in preprocessors */
-#include "preprocessors/spp_rpc_decode.h"
-#include "preprocessors/spp_bo.h"
-#include "preprocessors/spp_stream5.h"
-#include "preprocessors/spp_arpspoof.h"
-#include "preprocessors/spp_perfmonitor.h"
-#include "preprocessors/spp_httpinspect.h"
-#include "preprocessors/spp_sfportscan.h"
-#include "preprocessors/spp_frag3.h"
-
-/* built-in detection plugins */
-#include "detection-plugins/sp_pattern_match.h"
-#include "detection-plugins/sp_tcp_flag_check.h"
-#include "detection-plugins/sp_icmp_type_check.h"
-#include "detection-plugins/sp_icmp_code_check.h"
-#include "detection-plugins/sp_ttl_check.h"
-#include "detection-plugins/sp_ip_id_check.h"
-#include "detection-plugins/sp_tcp_ack_check.h"
-#include "detection-plugins/sp_tcp_seq_check.h"
-#include "detection-plugins/sp_dsize_check.h"
-#include "detection-plugins/sp_ipoption_check.h"
-#include "detection-plugins/sp_rpc_check.h"
-#include "detection-plugins/sp_icmp_id_check.h"
-#include "detection-plugins/sp_icmp_seq_check.h"
-#include "detection-plugins/sp_session.h"
-#include "detection-plugins/sp_ip_tos_check.h"
-#include "detection-plugins/sp_ip_fragbits.h"
-#include "detection-plugins/sp_tcp_win_check.h"
-#include "detection-plugins/sp_ip_same_check.h"
-#include "detection-plugins/sp_ip_proto.h"
-#include "detection-plugins/sp_ip_same_check.h"
-#include "detection-plugins/sp_clientserver.h"
-#include "detection-plugins/sp_byte_check.h"
-#include "detection-plugins/sp_byte_jump.h"
-#include "detection-plugins/sp_isdataat.h"
-#include "detection-plugins/sp_pcre.h"
-#include "detection-plugins/sp_flowbits.h"
-#include "detection-plugins/sp_file_data.h"
-#include "detection-plugins/sp_asn1.h"
-#ifdef ENABLE_REACT
-#include "detection-plugins/sp_react.h"
-#endif
-#ifdef ENABLE_RESPOND
-#include "detection-plugins/sp_respond.h"
-#endif
-#include "detection-plugins/sp_ftpbounce.h"
-#include "detection-plugins/sp_urilen_check.h"
-#include "detection-plugins/sp_cvs.h"
-
-/* built-in output plugins */
-#include "output-plugins/spo_alert_syslog.h"
-#include "output-plugins/spo_log_tcpdump.h"
-#include "output-plugins/spo_database.h"
-#include "output-plugins/spo_alert_fast.h"
-#include "output-plugins/spo_alert_full.h"
-#include "output-plugins/spo_alert_unixsock.h"
-#include "output-plugins/spo_csv.h"
-#include "output-plugins/spo_unified.h"
-#include "output-plugins/spo_log_null.h"
-#include "output-plugins/spo_log_ascii.h"
-#include "output-plugins/spo_unified2.h"
-#include "output-plugins/spo_pf.h"
-
-#ifdef ARUBA
-#include "output-plugins/spo_alert_arubaaction.h"
-#endif
-
-#ifdef HAVE_LIBPRELUDE
-#include "output-plugins/spo_alert_prelude.h"
-#endif
-
-#ifdef LINUX
-#include "output-plugins/spo_alert_sf_socket.h"
-#endif
-
-#include "output-plugins/spo_alert_test.h"
-
-extern ListHead *head_tmp;
-extern PreprocConfigFuncNode *preproc_config_funcs;
-extern OutputConfigFuncNode *output_config_funcs;
-extern RuleOptConfigFuncNode *rule_opt_config_funcs;
-extern RuleOptOverrideInitFuncNode *rule_opt_override_init_funcs;
-extern RuleOptParseCleanupNode *rule_opt_parse_cleanup_list;
-extern PreprocSignalFuncNode *preproc_restart_funcs;
-extern PreprocSignalFuncNode *preproc_clean_exit_funcs;
-extern PreprocSignalFuncNode *preproc_shutdown_funcs;
-extern PreprocSignalFuncNode *preproc_reset_funcs;
-extern PreprocSignalFuncNode *preproc_reset_stats_funcs;
-extern PreprocStatsFuncNode *preproc_stats_funcs;
-extern PluginSignalFuncNode *plugin_shutdown_funcs;
-extern PluginSignalFuncNode *plugin_clean_exit_funcs;
-extern PluginSignalFuncNode *plugin_restart_funcs;
-extern OutputFuncNode *AlertList;
-extern OutputFuncNode *LogList;
-
-
-/**************************** Detection Plugin API ****************************/
-/* For translation from enum to char* */
-#ifdef DEBUG
-static const char *optTypeMap[OPT_TYPE_MAX] =
-{
- "action",
- "logging",
- "detection"
-};
-
-#define ENUM2STR(num, map) \
- ((num < sizeof(map)/sizeof(map[0])) ? map[num] : "undefined")
-#endif
-
-
-void RegisterRuleOptions(void)
-{
- LogMessage("Initializing Plug-ins!\n");
-
- SetupPatternMatch();
- SetupTCPFlagCheck();
- SetupIcmpTypeCheck();
- SetupIcmpCodeCheck();
- SetupTtlCheck();
- SetupIpIdCheck();
- SetupTcpAckCheck();
- SetupTcpSeqCheck();
- SetupDsizeCheck();
- SetupIpOptionCheck();
- SetupRpcCheck();
- SetupIcmpIdCheck();
- SetupIcmpSeqCheck();
- SetupSession();
- SetupIpTosCheck();
- SetupFragBits();
- SetupFragOffset();
- SetupTcpWinCheck();
- SetupIpProto();
- SetupIpSameCheck();
- SetupClientServer();
- SetupByteTest();
- SetupByteJump();
- SetupIsDataAt();
- SetupFileData();
- SetupPcre();
- SetupFlowBits();
- SetupAsn1();
-#ifdef ENABLE_REACT
- SetupReact();
-#endif
-#ifdef ENABLE_RESPOND
- SetupRespond();
-#endif
- SetupFTPBounce();
- SetupUriLenCheck();
- SetupCvs();
-}
-
-/****************************************************************************
- *
- * Function: RegisterRuleOption(char *, void (*func)(), enum OptionType)
- *
- * Purpose: Associates a rule option keyword with an option setup/linking
- * function.
- *
- * Arguments: keyword => The option keyword to associate with the option
- * handler
- * *func => function pointer to the handler
- * type => used to determine where keyword is allowed
- *
- * Returns: void function
- *
- ***************************************************************************/
-void RegisterRuleOption(char *opt_name, RuleOptConfigFunc config_func,
- RuleOptOverrideInitFunc override_init_func,
- RuleOptType opt_type,
- RuleOptOtnHandler otn_handler)
-{
- RuleOptConfigFuncNode *node;
-
- DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN, "Registering keyword:func => %s/%s:%p\n",
- ENUM2STR(opt_type, optTypeMap), opt_name, config_func););
-
- node = (RuleOptConfigFuncNode *)SnortAlloc(sizeof(RuleOptConfigFuncNode));
-
- if (rule_opt_config_funcs == NULL)
- {
- rule_opt_config_funcs = node;
- }
- else
- {
- RuleOptConfigFuncNode *tmp = rule_opt_config_funcs;
- RuleOptConfigFuncNode *last;
-
- do
- {
- if (strcasecmp(tmp->keyword, opt_name) == 0)
- {
- free(node);
- FatalError("Duplicate detection plugin keyword: %s.\n",
- file_line, opt_name);
- }
-
- last = tmp;
- tmp = tmp->next;
-
- } while (tmp != NULL);
-
- last->next = node;
- }
-
- node->keyword = SnortStrdup(opt_name);
- node->type = opt_type;
- node->func = config_func;
- node->otn_handler = otn_handler;
-
- if (override_init_func != NULL)
- {
- RuleOptOverrideInitFuncNode *node_override =
- (RuleOptOverrideInitFuncNode *)SnortAlloc(sizeof(RuleOptOverrideInitFuncNode));
-
- if (rule_opt_override_init_funcs == NULL)
- {
- rule_opt_override_init_funcs = node_override;
- }
- else
- {
- RuleOptOverrideInitFuncNode *tmp = rule_opt_override_init_funcs;
- RuleOptOverrideInitFuncNode *last;
-
- do
- {
- if (strcasecmp(tmp->keyword, opt_name) == 0)
- {
- free(node_override);
- FatalError("RegisterRuleOption: Duplicate detection plugin keyword:"
- " (%s) (%s)!\n", tmp->keyword, opt_name);
- }
-
- last = tmp;
- tmp = tmp->next;
-
- } while (tmp != NULL);
-
- last->next = node_override;
- }
-
- node_override->keyword = SnortStrdup(opt_name);
- node_override->type = opt_type;
- node_override->func = override_init_func;
- node_override->otn_handler = otn_handler;
- }
-}
-
-void RegisterOverrideKeyword(char *keyword, char *option, RuleOptOverrideFunc func)
-{
- RuleOptOverrideInitFuncNode *node = rule_opt_override_init_funcs;
-
- while (node != NULL)
- {
- if (strcasecmp(node->keyword, keyword) == 0)
- {
- node->func(keyword, option, func);
- break;
- }
-
- node = node->next;
- }
-}
-
-/****************************************************************************
- *
- * Function: DumpPlugIns()
- *
- * Purpose: Prints the keyword->function list
- *
- * Arguments: None.
- *
- * Returns: void function
- *
- ***************************************************************************/
-void DumpRuleOptions(void)
-{
- RuleOptConfigFuncNode *node;
-
- node = rule_opt_config_funcs;
-
- LogMessage("-------------------------------------------------\n");
- LogMessage(" Keyword | Plugin Registered @\n");
- LogMessage("-------------------------------------------------\n");
-
- while (node != NULL)
- {
- LogMessage("%-13s: %p\n", node->keyword, node->func);
- node = node->next;
- }
-
- LogMessage("-------------------------------------------------\n");
- LogMessage("\n");
-}
-
-
-/****************************************************************************
- *
- * Function: AddOptFuncToList(int (*func)(), OptTreeNode *)
- *
- * Purpose: Links the option detection module to the OTN
- *
- * Arguments: (*func)() => function pointer to the detection module
- * otn => pointer to the current OptTreeNode
- *
- * Returns: void function
- *
- ***************************************************************************/
-OptFpList * AddOptFuncToList(RuleOptEvalFunc func, OptTreeNode *otn)
-{
- OptFpList *ofp = (OptFpList *)SnortAlloc(sizeof(OptFpList));
-
- DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Adding new rule to list\n"););
-
- /* if there are no nodes on the function list... */
- if (otn->opt_func == NULL)
- {
- otn->opt_func = ofp;
- }
- else
- {
- OptFpList *tmp = otn->opt_func;
-
- /* walk to the end of the list */
- while (tmp->next != NULL)
- tmp = tmp->next;
-
- tmp->next = ofp;
- }
-
- DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Set OptTestFunc to %p\n", func););
-
- ofp->OptTestFunc = func;
-
- return ofp;
-}
-
-/****************************************************************************
- *
- * Function: AddRspFuncToList(int (*func)(), OptTreeNode *)
- *
- * Purpose: Adds Response function to OTN
- *
- * Arguments: (*func)() => function pointer to the response module
- * otn => pointer to the current OptTreeNode
- *
- * Returns: void function
- *
- ***************************************************************************/
-void AddRspFuncToList(ResponseFunc func, OptTreeNode *otn, void *params)
-{
- RspFpList *rsp = (RspFpList *)SnortAlloc(sizeof(RspFpList));
-
- DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Adding response to list\n"););
-
- /* if there are no nodes on the function list... */
- if (otn->rsp_func == NULL)
- {
- otn->rsp_func = rsp;
- }
- else
- {
- RspFpList *tmp = otn->rsp_func;
-
- /* walk to the end of the list */
- while (tmp->next != NULL)
- tmp = tmp->next;
-
- tmp->next = rsp;
- }
-
- DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,"Set ResponseFunc to %p\n", func););
-
- rsp->func = func;
- rsp->params = params;
-}
-
-void PostConfigInitPlugins(PluginSignalFuncNode *post_config_funcs)
-{
- while (post_config_funcs != NULL)
- {
- post_config_funcs->func(0, post_config_funcs->arg);
- post_config_funcs = post_config_funcs->next;
- }
-}
-
-void FreeRuleOptConfigFuncs(RuleOptConfigFuncNode *head)
-{
-
- while (head != NULL)
- {
- RuleOptConfigFuncNode *tmp = head;
-
- head = head->next;
-
- if (tmp->keyword != NULL)
- free(tmp->keyword);
-
- free(tmp);
- }
-}
-
-void FreeRuleOptOverrideInitFuncs(RuleOptOverrideInitFuncNode *head)
-{
-
- while (head != NULL)
- {
- RuleOptOverrideInitFuncNode *tmp = head;
-
- head = head->next;
-
- if (tmp->keyword != NULL)
- free(tmp->keyword);
-
- free(tmp);
- }
-}
-
-void FreePluginSigFuncs(PluginSignalFuncNode *head)
-{
- while (head != NULL)
- {
- PluginSignalFuncNode *tmp = head;
-
- head = head->next;
-
- /* don't free sig->arg, that's free'd by the CleanExit/Restart func */
- free(tmp);
- }
-}
-
-
-/************************** Preprocessor Plugin API ***************************/
-static void AddFuncToPreprocSignalList(PreprocSignalFunc, void *,
- PreprocSignalFuncNode **, uint16_t, uint32_t);
-
-
-void RegisterPreprocessors(void)
-{
- LogMessage("Initializing Preprocessors!\n");
-
- SetupARPspoof();
- SetupFrag3();
- SetupStream5();
- SetupRpcDecode();
- SetupBo();
- SetupHttpInspect();
- SetupPerfMonitor();
- SetupSfPortscan();
-}
-
-/****************************************************************************
- *
- * Function: RegisterPreprocessor(char *, void (*)(char *))
- *
- * Purpose: Associates a preprocessor statement with its function.
- *
- * Arguments: keyword => The option keyword to associate with the
- * preprocessor
- * *func => function pointer to the handler
- *
- * Returns: void function
- *
- ***************************************************************************/
-#ifndef SNORT_RELOAD
-void RegisterPreprocessor(char *keyword, PreprocConfigFunc func)
-#else
-void RegisterPreprocessor(char *keyword, PreprocConfigFunc func,
- PreprocReloadFunc rfunc, PreprocReloadSwapFunc sfunc,
- PreprocReloadSwapFreeFunc ffunc)
-#endif
-{
- PreprocConfigFuncNode *node =
- (PreprocConfigFuncNode *)SnortAlloc(sizeof(PreprocConfigFuncNode));
-
- DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Registering keyword:preproc => %s:%p\n", keyword, func););
-
- if (preproc_config_funcs == NULL)
- {
- preproc_config_funcs = node;
- }
- else
- {
- PreprocConfigFuncNode *tmp = preproc_config_funcs;
- PreprocConfigFuncNode *last;
-
- do
- {
- if (strcasecmp(tmp->keyword, keyword) == 0)
- {
- free(node);
- FatalError("Duplicate preprocessor keyword: %s.\n", keyword);
- }
-
- last = tmp;
- tmp = tmp->next;
-
- } while (tmp != NULL);
-
- last->next = node;
- }
-
- node->keyword = SnortStrdup(keyword);
- node->config_func = func;
-
-#ifdef SNORT_RELOAD
- node->reload_func = rfunc;
- node->reload_swap_func = sfunc;
- node->reload_swap_free_func = ffunc;
-#endif
-}
-
-PreprocConfigFuncNode * GetPreprocConfig(char *keyword)
-{
- PreprocConfigFuncNode *head = preproc_config_funcs;
-
- if (keyword == NULL)
- return NULL;
-
- while (head != NULL)
- {
- if (strcasecmp(head->keyword, keyword) == 0)
- return head;
-
- head = head->next;
- }
-
- return NULL;
-}
-
-PreprocConfigFunc GetPreprocConfigFunc(char *keyword)
-{
- PreprocConfigFuncNode *head = preproc_config_funcs;
-
- if (keyword == NULL)
- return NULL;
-
- while (head != NULL)
- {
- if (strcasecmp(head->keyword, keyword) == 0)
- return head->config_func;
-
- head = head->next;
- }
-
- return NULL;
-}
-
-/****************************************************************************
- *
- * Function: RegisterPreprocStats(char *keyword, void (*func)(int))
- *
- * Purpose: Registers a function for printing preprocessor final stats
- * (or other if it has a use for printing final stats)
- *
- * Arguments: keyword => keyword (preprocessor) whose stats will print
- * func => function pointer to the handler
- *
- * Returns: void function
- *
- ***************************************************************************/
-void RegisterPreprocStats(char *keyword, PreprocStatsFunc func)
-{
- PreprocStatsFuncNode *node;
-
- DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Registering final stats function: "
- "preproc => %s:%p\n", keyword, func););
-
- node = (PreprocStatsFuncNode *)SnortAlloc(sizeof(PreprocStatsFuncNode));
-
- if (preproc_stats_funcs == NULL)
- {
- preproc_stats_funcs = node;
- }
- else
- {
- PreprocStatsFuncNode *tmp = preproc_stats_funcs;
- PreprocStatsFuncNode *last;
-
- do
- {
- if (strcasecmp(tmp->keyword, keyword) == 0)
- {
- free(node);
- FatalError("Duplicate preprocessor keyword: %s.\n", keyword);
- }
-
- last = tmp;
- tmp = tmp->next;
-
- } while (tmp != NULL);
-
- last->next = node;
- }
-
- node->keyword = SnortStrdup(keyword);
- node->func = func;
-}
-
-/****************************************************************************
- *
- * Function: DumpPreprocessors()
- *
- * Purpose: Prints the keyword->preprocess list
- *
- * Arguments: None.
- *
- * Returns: void function
- *
- ***************************************************************************/
-void DumpPreprocessors(void)
-{
- PreprocConfigFuncNode *node = preproc_config_funcs;
-
- LogMessage("-------------------------------------------------\n");
- LogMessage(" Keyword | Preprocessor @ \n");
- LogMessage("-------------------------------------------------\n");
-
- while (node != NULL)
- {
- LogMessage("%-13s: %p\n", node->keyword, node->config_func);
- node = node->next;
- }
-
- LogMessage("-------------------------------------------------\n\n");
-}
-
-int IsPreprocEnabled(uint32_t preproc_id)
-{
- PreprocEvalFuncNode *node;
- SnortConfig *sc = snort_conf_for_parsing;
- tSfPolicyId policy_id = getParserPolicy();
- SnortPolicy *p;
-
- if (sc == NULL)
- {
- FatalError("%s(%d) Snort config for parsing is NULL.\n",
- __FILE__, __LINE__);
- }
-
- p = sc->targeted_policies[policy_id];
- if (p == NULL)
- return 0;
-
- for (node = p->preproc_eval_funcs; node != NULL; node = node->next)
- {
- if (node->preproc_id == preproc_id)
- return 1;
- }
-
- return 0;
-}
-
-PreprocEvalFuncNode * AddFuncToPreprocList(PreprocEvalFunc func, uint16_t priority,
- uint32_t preproc_id, uint32_t proto_mask)
-{
- PreprocEvalFuncNode *node;
- SnortConfig *sc = snort_conf_for_parsing;
- tSfPolicyId policy_id = getParserPolicy();
- SnortPolicy *p;
-
- if (sc == NULL)
- {
- FatalError("%s(%d) Snort config for parsing is NULL.\n",
- __FILE__, __LINE__);
- }
-
- p = sc->targeted_policies[policy_id];
- if (p == NULL)
- return NULL;
-
- DEBUG_WRAP(DebugMessage(DEBUG_CONFIGRULES,
- "Adding preprocessor function ID %d/bit %d/pri %d to list\n",
- preproc_id, p->num_preprocs, priority););
-
- node = (PreprocEvalFuncNode *)SnortAlloc(sizeof(PreprocEvalFuncNode));
-
- if (p->preproc_eval_funcs == NULL)
- {
- p->preproc_eval_funcs = node;
- }
- else
- {
- PreprocEvalFuncNode *tmp = p->preproc_eval_funcs;
- PreprocEvalFuncNode *last = NULL;
-
- do
- {
- if (tmp->preproc_id == preproc_id)
- {
- free(node);
- FatalError("Preprocessor already registered with ID %d\n",
- preproc_id);
- }
-
- /* Insert higher priority preprocessors first. Lower priority
- * number means higher priority */
- if (priority < tmp->priority)
- break;
-
- last = tmp;
- tmp = tmp->next;
-
- } while (tmp != NULL);
-
- /* Priority higher than first item in list */
- if (last == NULL)
- {
- node->next = tmp;
- p->preproc_eval_funcs = node;
- }
- else
- {
- node->next = tmp;
- last->next = node;
- }
- }
-
- node->func = func;
- node->priority = priority;
- node->preproc_id = preproc_id;
- node->preproc_bit = (1 << preproc_id);
- node->proto_mask = proto_mask;
-
- p->num_preprocs++;
- p->preproc_proto_mask |= proto_mask;
- p->preproc_bit_mask |= node->preproc_bit;
-
- return node;
-}
-
-void AddFuncToPreprocPostConfigList(PreprocPostConfigFunc func, void *data)
-{
- PreprocPostConfigFuncNode *node;
- SnortConfig *sc = snort_conf_for_parsing;
-
- if (sc == NULL)
- {
- FatalError("%s(%d) Snort config for parsing is NULL.\n",
- __FILE__, __LINE__);
- }
-
- node = (PreprocPostConfigFuncNode *)SnortAlloc(sizeof(PreprocPostConfigFuncNode));
-
- if (sc->preproc_post_config_funcs == NULL)
- {
- sc->preproc_post_config_funcs = node;
- }
- else
- {
- PreprocPostConfigFuncNode *tmp = sc->preproc_post_config_funcs;
-
- while (tmp->next != NULL)
- tmp = tmp->next;
-
- tmp->next = node;
- }
-
- node->data = data;
- node->func = func;
-}
-
-void PostConfigPreprocessors(SnortConfig *sc)
-{
- PreprocPostConfigFuncNode *list;
-
- if (sc == NULL)
- {
- FatalError("%s(%d) Snort config is NULL.\n",
- __FILE__, __LINE__);
- }
-
- snort_conf_for_parsing = sc;
-
- list = sc->preproc_post_config_funcs;
-
- for (; list != NULL; list = list->next)
- {
- if (list->func != NULL)
- list->func(list->data);
- }
-
- snort_conf_for_parsing = NULL;
-}
-
-#ifdef SNORT_RELOAD
-void SwapPreprocConfigurations(void)
-{
- PreprocConfigFuncNode *node = preproc_config_funcs;
-
- for (; node != NULL; node = node->next)
- {
- if (node->reload_swap_func != NULL)
- node->swap_free_data = node->reload_swap_func();
- }
-}
-
-void FreeSwappedPreprocConfigurations(void)
-{
- PreprocConfigFuncNode *node = preproc_config_funcs;
-
- for (; node != NULL; node = node->next)
- {
- if ((node->reload_swap_free_func != NULL) &&
- (node->swap_free_data != NULL))
- {
- node->reload_swap_free_func(node->swap_free_data);
- node->swap_free_data = NULL;
- }
- }
-}
-
-void AddFuncToPreprocReloadVerifyList(PreprocReloadVerifyFunc func)
-{
- PreprocReloadVerifyFuncNode *node;
- SnortConfig *sc = snort_conf_for_parsing;
-
- if (sc == NULL)
- {
- FatalError("%s(%d) Snort config for parsing is NULL.\n",
- __FILE__, __LINE__);
- }
-
- node = (PreprocReloadVerifyFuncNode *)SnortAlloc(sizeof(PreprocReloadVerifyFuncNode));
-
- if (sc->preproc_reload_verify_funcs == NULL)
- {
- sc->preproc_reload_verify_funcs = node;
- }
- else
- {
- PreprocReloadVerifyFuncNode *tmp = sc->preproc_reload_verify_funcs;
-
- while (tmp->next != NULL)
- tmp = tmp->next;
-
- tmp->next = node;
- }
-
- node->func = func;
-}
-
-void FreePreprocReloadVerifyFuncList(PreprocReloadVerifyFuncNode *head)
-{
- while (head != NULL)
- {
- PreprocReloadVerifyFuncNode *tmp = head;
-
- head = head->next;
- free(tmp);
- }
-}
-#endif
-
-void AddFuncToConfigCheckList(PreprocCheckConfigFunc func)
-{
- PreprocCheckConfigFuncNode *node;
- SnortConfig *sc = snort_conf_for_parsing;
-
- if (sc == NULL)
- {
- FatalError("%s(%d) Snort config for parsing is NULL.\n",
- __FILE__, __LINE__);
- }
-
- node = (PreprocCheckConfigFuncNode *)SnortAlloc(sizeof(PreprocCheckConfigFuncNode));
-
- if (sc->preproc_config_check_funcs == NULL)
- {
- sc->preproc_config_check_funcs = node;
- }
- else
- {
- PreprocCheckConfigFuncNode *tmp = sc->preproc_config_check_funcs;
-
- while (tmp->next != NULL)
- tmp = tmp->next;
-
- tmp->next = node;
- }
-
- node->func = func;
-}
-
-/* functions to aid in cleaning up after plugins */
-void AddFuncToPreprocRestartList(PreprocSignalFunc func, void *arg,
- uint16_t priority, uint32_t preproc_id)
-{
- AddFuncToPreprocSignalList(func, arg, &preproc_restart_funcs, priority, preproc_id);
-}
-
-void AddFuncToPreprocCleanExitList(PreprocSignalFunc func, void *arg,
- uint16_t priority, uint32_t preproc_id)
-{
- AddFuncToPreprocSignalList(func, arg, &preproc_clean_exit_funcs, priority, preproc_id);
-}
-
-void AddFuncToPreprocShutdownList(PreprocSignalFunc func, void *arg,
- uint16_t priority, uint32_t preproc_id)
-{
- AddFuncToPreprocSignalList(func, arg, &preproc_shutdown_funcs, priority, preproc_id);
-}
-
-void AddFuncToPreprocResetList(PreprocSignalFunc func, void *arg,
- uint16_t priority, uint32_t preproc_id)
-{
- AddFuncToPreprocSignalList(func, arg, &preproc_reset_funcs, priority, preproc_id);
-}
-
-void AddFuncToPreprocResetStatsList(PreprocSignalFunc func, void *arg,
- uint16_t priority, uint32_t preproc_id)
-{
- AddFuncToPreprocSignalList(func, arg, &preproc_reset_stats_funcs, priority, preproc_id);
-}
-
-static void AddFuncToPreprocSignalList(PreprocSignalFunc func, void *arg,
- PreprocSignalFuncNode **list,
- uint16_t priority, uint32_t preproc_id)
-{
- PreprocSignalFuncNode *node;
-
- if (list == NULL)
- return;
-
- node = (PreprocSignalFuncNode *)SnortAlloc(sizeof(PreprocSignalFuncNode));
-
- if (*list == NULL)
- {
- *list = node;
- }
- else
- {
- PreprocSignalFuncNode *tmp = *list;
- PreprocSignalFuncNode *last = NULL;
-
- do
- {
- /* Insert higher priority stuff first. Lower priority
- * number means higher priority */
- if (priority < tmp->priority)
- break;
-
- last = tmp;
- tmp = tmp->next;
-
- } while (tmp != NULL);
-
- /* Priority higher than first item in list */
- if (last == NULL)
- {
- node->next = tmp;
- *list = node;
- }
- else
- {
- node->next = tmp;
- last->next = node;
- }
- }
-
- node->func = func;
- node->arg = arg;
- node->preproc_id = preproc_id;
- node->priority = priority;
-}
-
-void AddFuncToPreprocReassemblyPktList(PreprocReassemblyPktFunc func, uint32_t preproc_id)
-{
- PreprocReassemblyPktFuncNode *node;
- SnortConfig *sc = snort_conf_for_parsing;
- tSfPolicyId policy_id = getParserPolicy();
- SnortPolicy *p;
-
- if (sc == NULL)
- {
- FatalError("%s(%d) Snort config for parsing is NULL.\n",
- __FILE__, __LINE__);
- }
-
- p = sc->targeted_policies[policy_id];
- if (p == NULL)
- return;
-
- node = (PreprocReassemblyPktFuncNode *)SnortAlloc(sizeof(PreprocReassemblyPktFuncNode));
-
- if (p->preproc_reassembly_pkt_funcs == NULL)
- {
- p->preproc_reassembly_pkt_funcs = node;
- }
- else
- {
- PreprocReassemblyPktFuncNode *tmp = p->preproc_reassembly_pkt_funcs;
-
- /* just insert at front of list */
- p->preproc_reassembly_pkt_funcs = node;
- node->next = tmp;
- }
-
- node->func = func;
- node->preproc_id = preproc_id;
-}
-
-void FreePreprocConfigFuncs(void)
-{
- PreprocConfigFuncNode *head = preproc_config_funcs;
- PreprocConfigFuncNode *tmp;
-
- while (head != NULL)
- {
- tmp = head->next;
- if (head->keyword != NULL)
- free(head->keyword);
- free(head);
- head = tmp;
- }
-}
-
-void FreePreprocCheckConfigFuncs(PreprocCheckConfigFuncNode *head)
-{
- PreprocCheckConfigFuncNode *tmp;
-
- while (head != NULL)
- {
- tmp = head->next;
- free(head);
- head = tmp;
- }
-}
-
-void FreePreprocPostConfigFuncs(PreprocPostConfigFuncNode *head)
-{
- PreprocPostConfigFuncNode *tmp;
-
- while (head != NULL)
- {
- tmp = head->next;
- free(head);
- head = tmp;
- }
-}
-
-void FreePreprocStatsFuncs(PreprocStatsFuncNode *head)
-{
- PreprocStatsFuncNode *tmp;
-
- while (head != NULL)
- {
- tmp = head->next;
- if (head->keyword != NULL)
- free(head->keyword);
- free(head);
- head = tmp;
- }
-}
-
-void FreePreprocEvalFuncs(PreprocEvalFuncNode *head)
-{
- PreprocEvalFuncNode *tmp;
-
- while (head != NULL)
- {
- tmp = head->next;
- //if (head->context)
- // free(head->context);
- free(head);
- head = tmp;
- }
-}
-
-void FreePreprocReassemblyPktFuncs(PreprocReassemblyPktFuncNode *head)
-{
- PreprocReassemblyPktFuncNode *tmp;
-
- while (head != NULL)
- {
- tmp = head->next;
- free(head);
- head = tmp;
- }
-}
-
-void FreePreprocSigFuncs(PreprocSignalFuncNode *head)
-{
- PreprocSignalFuncNode *tmp;
-
- while (head != NULL)
- {
- tmp = head->next;
- /* don't free sig->arg, that's free'd by the CleanExit/Restart func */
- free(head);
- head = tmp;
- }
-}
-
-void CheckPreprocessorsConfig(SnortConfig *sc)
-{
- PreprocCheckConfigFuncNode *idx;
-
- if (sc == NULL)
- {
- FatalError("%s(%d) Snort config is NULL.\n",
- __FILE__, __LINE__);
- }
-
- snort_conf_for_parsing = sc;
-
- idx = sc->preproc_config_check_funcs;
-
- LogMessage("Verifying Preprocessor Configurations!\n");
-
- while(idx != NULL)
- {
- idx->func();
- idx = idx->next;
- }
-
- snort_conf_for_parsing = NULL;
-}
-
-#ifdef SNORT_RELOAD
-int VerifyReloadedPreprocessors(SnortConfig *sc)
-{
- PreprocReloadVerifyFuncNode *node;
-
- if (sc == NULL)
- {
- FatalError("%s(%d) Snort config is NULL.\n",
- __FILE__, __LINE__);
- }
-
- snort_conf_for_parsing = sc;
-
- node = sc->preproc_reload_verify_funcs;
- while (node != NULL)
- {
- if (node->func != NULL)
- {
- if (node->func() == -1)
- return -1;
- }
-
- node = node->next;
- }
-
- snort_conf_for_parsing = NULL;
-
- return 0;
-}
-#endif
-
-
-/***************************** Output Plugin API *****************************/
-extern OutputConfigFuncNode *output_config_funcs;
-
-static void AppendOutputFuncList(OutputFunc, void *, OutputFuncNode **);
-
-void RegisterOutputPlugins(void)
-{
- LogMessage("Initializing Output Plugins!\n");
-
- AlertSyslogSetup();
- LogTcpdumpSetup();
- DatabaseSetup();
- AlertFastSetup();
- AlertFullSetup();
- AlertPfSetup();
-#ifndef WIN32
- /* Win32 doesn't support AF_UNIX sockets */
- AlertUnixSockSetup();
-#endif /* !WIN32 */
- AlertCSVSetup();
- LogNullSetup();
- UnifiedSetup();
- Unified2Setup();
- LogAsciiSetup();
-
-#ifdef ARUBA
- AlertArubaActionSetup();
-#endif
-
-#ifdef LINUX
- /* This uses linux only capabilities */
- AlertSFSocket_Setup();
-#endif
-
-#ifdef HAVE_LIBPRELUDE
- AlertPreludeSetup();
-#endif
-
- AlertTestSetup();
-}
-
-/****************************************************************************
- *
- * Function: RegisterOutputPlugin(char *, void (*func)(Packet *, u_char *))
- *
- * Purpose: Associates an output statement with its function.
- *
- * Arguments: keyword => The output keyword to associate with the
- * output processor
- * type => alert or log types
- * *func => function pointer to the handler
- *
- * Returns: void function
- *
- ***************************************************************************/
-void RegisterOutputPlugin(char *keyword, int type_flags, OutputConfigFunc func)
-{
- OutputConfigFuncNode *node = (OutputConfigFuncNode *)SnortAlloc(sizeof(OutputConfigFuncNode));
-
- DEBUG_WRAP(DebugMessage(DEBUG_PLUGIN,"Registering keyword:output => %s:%p\n",
- keyword, func););
-
- if (output_config_funcs == NULL)
- {
- output_config_funcs = node;
- }
- else
- {
- OutputConfigFuncNode *tmp = output_config_funcs;
- OutputConfigFuncNode *last;
-
- do
- {
- if (strcasecmp(tmp->keyword, keyword) == 0)
- {
- free(node);
- FatalError("Duplicate output keyword: %s\n", keyword);
- }
-
- last = tmp;
- tmp = tmp->next;
-
- } while (tmp != NULL);
-
- last->next = node;
- }
-
- node->keyword = SnortStrdup(keyword);
- node->func = func;
- node->output_type_flags = type_flags;
-}
-
-OutputConfigFunc GetOutputConfigFunc(char *keyword)
-{
- OutputConfigFuncNode *head = output_config_funcs;
-
- if (keyword == NULL)
- return NULL;
-
- while (head != NULL)
- {
- if (strcasecmp(head->keyword, keyword) == 0)
- return head->func;
-
- head = head->next;
- }
-
- return NULL;
-}
-
-int GetOutputTypeFlags(char *keyword)
-{
- OutputConfigFuncNode *head = output_config_funcs;
-
- if (keyword == NULL)
- return 0;
-
- while (head != NULL)
- {
- if (strcasecmp(head->keyword, keyword) == 0)
- return head->output_type_flags;
-
- head = head->next;
- }
-
- return 0;
-}
-
-void FreeOutputConfigFuncs(void)
-{
- OutputConfigFuncNode *head = output_config_funcs;
- OutputConfigFuncNode *tmp;
-
- while (head != NULL)
- {
- tmp = head->next;
- if (head->keyword != NULL)
- free(head->keyword);
- free(head);
- head = tmp;
- }
-}
-
-void FreeOutputList(OutputFuncNode *list)
-{
- while (list != NULL)
- {
- OutputFuncNode *tmp = list;
-
- list = list->next;
- free(tmp);
- }
-}
-
-/****************************************************************************
- *
- * Function: DumpOutputPlugins()
- *
- * Purpose: Prints the keyword->preprocess list
- *
- * Arguments: None.
- *
- * Returns: void function
- *
- ***************************************************************************/
-void DumpOutputPlugins(void)
-{
- OutputConfigFuncNode *idx = output_config_funcs;
-
- LogMessage("-------------------------------------------------\n");
- LogMessage(" Keyword | Output @ \n");
- LogMessage("-------------------------------------------------\n");
- while(idx != NULL)
- {
- LogMessage("%-13s: %p\n", idx->keyword, idx->func);
- idx = idx->next;
- }
- LogMessage("-------------------------------------------------\n\n");
-}
-
-void AddFuncToOutputList(OutputFunc func, OutputType type, void *arg)
-{
- switch (type)
- {
- case OUTPUT_TYPE__ALERT:
- if (head_tmp != NULL)
- AppendOutputFuncList(func, arg, &head_tmp->AlertList);
- else
- AppendOutputFuncList(func, arg, &AlertList);
-
- break;
-
- case OUTPUT_TYPE__LOG:
- if (head_tmp != NULL)
- AppendOutputFuncList(func, arg, &head_tmp->LogList);
- else
- AppendOutputFuncList(func, arg, &LogList);
-
- break;
-
- default:
- /* just to be error-prone */
- FatalError("Unknown output type: %i. Possible bug, please "
- "report.\n", type);
- }
-}
-
-void AppendOutputFuncList(OutputFunc func, void *arg, OutputFuncNode **list)
-{
- OutputFuncNode *node;
-
- if (list == NULL)
- return;
-
- node = (OutputFuncNode *)SnortAlloc(sizeof(OutputFuncNode));
-
- if (*list == NULL)
- {
- *list = node;
- }
- else
- {
- OutputFuncNode *tmp = *list;
-
- while (tmp->next != NULL)
- tmp = tmp->next;
-
- tmp->next = node;
- }
-
- node->func = func;
- node->arg = arg;
-}
-
-
-/************************** Miscellaneous Functions **************************/
-
-/* functions to aid in cleaning up after plugins
- * Used for both rule options and output. Preprocessors have their own */
-void AddFuncToRestartList(PluginSignalFunc func, void *arg)
-{
- AddFuncToSignalList(func, arg, &plugin_restart_funcs);
-}
-
-void AddFuncToCleanExitList(PluginSignalFunc func, void *arg)
-{
- AddFuncToSignalList(func, arg, &plugin_clean_exit_funcs);
-}
-
-void AddFuncToShutdownList(PluginSignalFunc func, void *arg)
-{
- AddFuncToSignalList(func, arg, &plugin_shutdown_funcs);
-}
-
-void AddFuncToPostConfigList(PluginSignalFunc func, void *arg)
-{
- SnortConfig *sc = snort_conf_for_parsing;
-
- if (sc == NULL)
- {
- FatalError("%s(%d) Snort config for parsing is NULL.\n",
- __FILE__, __LINE__);
- }
-
- AddFuncToSignalList(func, arg, &sc->plugin_post_config_funcs);
-}
-
-void AddFuncToSignalList(PluginSignalFunc func, void *arg, PluginSignalFuncNode **list)
-{
- PluginSignalFuncNode *node;
-
- if (list == NULL)
- return;
-
- node = (PluginSignalFuncNode *)SnortAlloc(sizeof(PluginSignalFuncNode));
-
- if (*list == NULL)
- {
- *list = node;
- }
- else
- {
- PluginSignalFuncNode *tmp = *list;
-
- while (tmp->next != NULL)
- tmp = tmp->next;
-
- tmp->next = node;
- }
-
- node->func = func;
- node->arg = arg;
-}
-
-void AddFuncToRuleOptParseCleanupList(RuleOptParseCleanupFunc func)
-{
- RuleOptParseCleanupNode *node =
- (RuleOptParseCleanupNode *)SnortAlloc(sizeof(RuleOptParseCleanupNode));
-
- if (rule_opt_parse_cleanup_list == NULL)
- {
- rule_opt_parse_cleanup_list = node;
- }
- else
- {
- RuleOptParseCleanupNode *tmp = rule_opt_parse_cleanup_list;
-
- while (tmp->next != NULL)
- tmp = tmp->next;
-
- tmp->next = node;
- }
-
- node->func = func;
-}
-
-void RuleOptParseCleanup(void)
-{
- RuleOptParseCleanupNode *list = rule_opt_parse_cleanup_list;
-
- for (; list != NULL; list = list->next)
- {
- if (list->func != NULL)
- list->func();
- }
-}
-
-void FreeRuleOptParseCleanupList(RuleOptParseCleanupNode *head)
-{
- while (head != NULL)
- {
- RuleOptParseCleanupNode *tmp = head;
-
- head = head->next;
- free(tmp);
- }
-}
-
-
diff --git a/config/snort-dev/patches/spoink_patch/2.8.6/util.c b/config/snort-dev/patches/spoink_patch/2.8.6/util.c
deleted file mode 100644
index b2d3b38b..00000000
--- a/config/snort-dev/patches/spoink_patch/2.8.6/util.c
+++ /dev/null
@@ -1,3233 +0,0 @@
-/* $Id$ */
-/*
-** Copyright (C) 2002-2010 Sourcefire, Inc.
-** Copyright (C) 2002 Martin Roesch <roesch@sourcefire.com>
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License Version 2 as
-** published by the Free Software Foundation. You may not use, modify or
-** distribute this program under any other version of the GNU General
-** Public License.
-**
-** 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.
-*/
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include <sys/types.h>
-
-#ifndef WIN32
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <sys/wait.h>
-#include <dirent.h>
-#include <fnmatch.h>
-#endif /* !WIN32 */
-
-#include <stdarg.h>
-#include <syslog.h>
-#include <errno.h>
-#include <sys/stat.h>
-#include <time.h>
-#include <signal.h>
-#include <unistd.h>
-
-#ifndef WIN32
-#include <grp.h>
-#include <pwd.h>
-#include <netdb.h>
-#include <limits.h>
-#endif /* !WIN32 */
-
-#include <fcntl.h>
-
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-
-#ifdef ZLIB
-#include <zlib.h>
-#endif
-
-#include "snort.h"
-#include "mstring.h"
-#include "debug.h"
-#include "util.h"
-#include "parser.h"
-#include "inline.h"
-#include "build.h"
-#include "plugbase.h"
-#include "sf_types.h"
-#include "sflsq.h"
-#include "ipv6_port.h"
-
-#include "pcre.h"
-
-#include "mpse.h"
-
-#include "ppm.h"
-
-#ifdef TARGET_BASED
-#include "sftarget_reader.h"
-#endif
-
-#ifdef WIN32
-#include "win32/WIN32-Code/name.h"
-#endif
-
-#include "stream5_common.h"
-
-#ifdef PATH_MAX
-#define PATH_MAX_UTIL PATH_MAX
-#else
-#define PATH_MAX_UTIL 1024
-#endif /* PATH_MAX */
-
-extern Stream5Stats s5stats;
-extern int datalink;
-extern pcap_t *pcap_handle;
-extern PreprocStatsFuncNode *preproc_stats_funcs;
-
-static PcapPktStats pkt_stats;
-
-/*
- * you may need to adjust this on the systems which don't have standard
- * paths defined
- */
-#ifndef _PATH_VARRUN
-static char _PATH_VARRUN[STD_BUF];
-#endif
-
-
-#ifdef NAME_MAX
-#define NAME_MAX_UTIL NAME_MAX
-#else
-#define NAME_MAX_UTIL 256
-#endif /* NAME_MAX */
-
-#define FILE_MAX_UTIL (PATH_MAX_UTIL + NAME_MAX_UTIL)
-
-/****************************************************************************
- *
- * Function: CalcPct(uint64_t, uint64_t)
- *
- * Purpose: Calculate the percentage of a value compared to a total
- *
- * Arguments: cnt => the numerator in the equation
- * total => the denominator in the calculation
- *
- * Returns: pct -> the percentage of cnt to value
- *
- ****************************************************************************/
-double CalcPct(uint64_t cnt, uint64_t total)
-{
- double pct = 0.0;
-
- if (total == 0.0)
- {
- pct = (double)cnt;
- }
- else
- {
- pct = (double)cnt / (double)total;
- }
-
- pct *= 100.0;
-
- return pct;
-}
-
-
-/****************************************************************************
- *
- * Function: DisplayBanner()
- *
- * Purpose: Show valuable proggie info
- *
- * Arguments: None.
- *
- * Returns: 0 all the time
- *
- ****************************************************************************/
-int DisplayBanner(void)
-{
- const char * info;
- const char * pcre_ver;
-#ifdef ZLIB
- const char * zlib_ver;
-#endif
-
- info = getenv("HOSTTYPE");
- if( !info )
- {
- info="";
- }
-
- pcre_ver = pcre_version();
-#ifdef ZLIB
- zlib_ver = zlib_version;
-#endif
-
- LogMessage("\n");
- LogMessage(" ,,_ -*> Snort! <*-\n");
- LogMessage(" o\" )~ Version %s%s%s (Build %s) %s %s\n",
- VERSION,
-#ifdef SUP_IP6
- " IPv6",
-#else
- "",
-#endif
-#ifdef GRE
- " GRE",
-#else
- "",
-#endif
- BUILD,
-#ifdef GIDS
- "inline",
-#else
- "",
-#endif
- info);
- LogMessage(" '''' By Martin Roesch & The Snort Team: http://www.snort.org/snort/snort-team\n");
- LogMessage(" Copyright (C) 1998-2010 Sourcefire, Inc., et al.\n");
- LogMessage(" Using PCRE version: %s\n", pcre_ver);
-#ifdef ZLIB
- LogMessage(" Using ZLIB version: %s\n", zlib_ver);
-#endif
- LogMessage("\n");
- LogMessage(" ___ Built Date for Snort on Pfsense 2.0 is May 25 2010.\n");
- LogMessage(" ___/ f \\ Orion IPS Output Code Copyright (C) 2009-2010 Robert Zelaya.\n");
- LogMessage("/ p \\___/Sense\n");
- LogMessage("\\___/ \\\n");
- LogMessage(" \\___/ Using Snort.org dynamic plugins and Orion IPS source.\n");
- LogMessage("\n");
-
- return 0;
-}
-
-
-
-/****************************************************************************
- *
- * Function: ts_print(register const struct, char *)
- *
- * Purpose: Generate a time stamp and stuff it in a buffer. This one has
- * millisecond precision. Oh yeah, I ripped this code off from
- * TCPdump, props to those guys.
- *
- * Arguments: timeval => clock struct coming out of libpcap
- * timebuf => buffer to stuff timestamp into
- *
- * Returns: void function
- *
- ****************************************************************************/
-void ts_print(register const struct timeval *tvp, char *timebuf)
-{
- register int s;
- int localzone;
- time_t Time;
- struct timeval tv;
- struct timezone tz;
- struct tm *lt; /* place to stick the adjusted clock data */
-
- /* if null was passed, we use current time */
- if(!tvp)
- {
- /* manual page (for linux) says tz is never used, so.. */
- bzero((char *) &tz, sizeof(tz));
- gettimeofday(&tv, &tz);
- tvp = &tv;
- }
-
- localzone = snort_conf->thiszone;
-
- /*
- ** If we're doing UTC, then make sure that the timezone is correct.
- */
- if (ScOutputUseUtc())
- localzone = 0;
-
- s = (tvp->tv_sec + localzone) % 86400;
- Time = (tvp->tv_sec + localzone) - s;
-
- lt = gmtime(&Time);
-
- if (ScOutputIncludeYear())
- {
- (void) SnortSnprintf(timebuf, TIMEBUF_SIZE,
- "%02d/%02d/%02d-%02d:%02d:%02d.%06u ",
- lt->tm_mon + 1, lt->tm_mday, lt->tm_year - 100,
- s / 3600, (s % 3600) / 60, s % 60,
- (u_int) tvp->tv_usec);
- }
- else
- {
- (void) SnortSnprintf(timebuf, TIMEBUF_SIZE,
- "%02d/%02d-%02d:%02d:%02d.%06u ", lt->tm_mon + 1,
- lt->tm_mday, s / 3600, (s % 3600) / 60, s % 60,
- (u_int) tvp->tv_usec);
- }
-}
-
-
-
-/****************************************************************************
- *
- * Function: gmt2local(time_t)
- *
- * Purpose: Figures out how to adjust the current clock reading based on the
- * timezone you're in. Ripped off from TCPdump.
- *
- * Arguments: time_t => offset from GMT
- *
- * Returns: offset seconds from GMT
- *
- ****************************************************************************/
-int gmt2local(time_t t)
-{
- register int dt, dir;
- register struct tm *gmt, *loc;
- struct tm sgmt;
-
- if(t == 0)
- t = time(NULL);
-
- gmt = &sgmt;
- *gmt = *gmtime(&t);
- loc = localtime(&t);
-
- dt = (loc->tm_hour - gmt->tm_hour) * 60 * 60 +
- (loc->tm_min - gmt->tm_min) * 60;
-
- dir = loc->tm_year - gmt->tm_year;
-
- if(dir == 0)
- dir = loc->tm_yday - gmt->tm_yday;
-
- dt += dir * 24 * 60 * 60;
-
- return(dt);
-}
-
-
-
-
-/****************************************************************************
- *
- * Function: copy_argv(u_char **)
- *
- * Purpose: Copies a 2D array (like argv) into a flat string. Stolen from
- * TCPDump.
- *
- * Arguments: argv => 2D array to flatten
- *
- * Returns: Pointer to the flat string
- *
- ****************************************************************************/
-char *copy_argv(char **argv)
-{
- char **p;
- u_int len = 0;
- char *buf;
- char *src, *dst;
- //void ftlerr(char *,...);
-
- p = argv;
- if(*p == 0)
- return 0;
-
- while(*p)
- len += strlen(*p++) + 1;
-
- buf = (char *) calloc(1,len);
-
- if(buf == NULL)
- {
- FatalError("calloc() failed: %s\n", strerror(errno));
- }
- p = argv;
- dst = buf;
-
- while((src = *p++) != NULL)
- {
- while((*dst++ = *src++) != '\0');
- dst[-1] = ' ';
- }
-
- dst[-1] = '\0';
-
- /* Check for an empty string */
- dst = buf;
- while (isspace((int)*dst))
- dst++;
-
- if (strlen(dst) == 0)
- {
- free(buf);
- buf = NULL;
- }
-
- return buf;
-}
-
-
-/****************************************************************************
- *
- * Function: strip(char *)
- *
- * Purpose: Strips a data buffer of CR/LF/TABs. Replaces CR/LF's with
- * NULL and TABs with spaces.
- *
- * Arguments: data => ptr to the data buf to be stripped
- *
- * Returns: void
- *
- * 3/7/07 - changed to return void - use strlen to get size of string
- *
- * Note that this function will turn all '\n' and '\r' into null chars
- * so, e.g. 'Hello\nWorld\n' => 'Hello\x00World\x00'
- * note that the string is now just 'Hello' and the length is shortened
- * by more than just an ending '\n' or '\r'
- ****************************************************************************/
-void strip(char *data)
-{
- int size;
- char *end;
- char *idx;
-
- idx = data;
- end = data + strlen(data);
- size = end - idx;
-
- while(idx != end)
- {
- if((*idx == '\n') ||
- (*idx == '\r'))
- {
- *idx = 0;
- size--;
- }
- if(*idx == '\t')
- {
- *idx = ' ';
- }
- idx++;
- }
-}
-
-/*
- * Function: ErrorMessage(const char *, ...)
- *
- * Purpose: Print a message to stderr.
- *
- * Arguments: format => the formatted error string to print out
- * ... => format commands/fillers
- *
- * Returns: void function
- */
-void ErrorMessage(const char *format,...)
-{
- char buf[STD_BUF+1];
- va_list ap;
-
- if (snort_conf == NULL)
- return;
-
- va_start(ap, format);
-
- if (ScDaemonMode() || ScLogSyslog())
- {
- vsnprintf(buf, STD_BUF, format, ap);
- buf[STD_BUF] = '\0';
- syslog(LOG_CONS | LOG_DAEMON | LOG_ERR, "%s", buf);
- }
- else
- {
- vfprintf(stderr, format, ap);
- }
- va_end(ap);
-}
-
-/*
- * Function: LogMessage(const char *, ...)
- *
- * Purpose: Print a message to stderr or with logfacility.
- *
- * Arguments: format => the formatted error string to print out
- * ... => format commands/fillers
- *
- * Returns: void function
- */
-void LogMessage(const char *format,...)
-{
- char buf[STD_BUF+1];
- va_list ap;
-
- if (snort_conf == NULL)
- return;
-
- if (ScLogQuiet() && !ScDaemonMode() && !ScLogSyslog())
- return;
-
- va_start(ap, format);
-
- if (ScDaemonMode() || ScLogSyslog())
- {
- vsnprintf(buf, STD_BUF, format, ap);
- buf[STD_BUF] = '\0';
- syslog(LOG_DAEMON | LOG_NOTICE, "%s", buf);
- }
- else
- {
- vfprintf(stderr, format, ap);
- }
-
- va_end(ap);
-}
-
-/*
- * Function: CreateApplicationEventLogEntry(const char *)
- *
- * Purpose: Add an entry to the Win32 "Application" EventLog
- *
- * Arguments: szMessage => the formatted error string to print out
- *
- * Returns: void function
- */
-#if defined(WIN32) && defined(ENABLE_WIN32_SERVICE)
-void CreateApplicationEventLogEntry(const char *msg)
-{
- HANDLE hEventLog;
- char* pEventSourceName = "SnortService";
-
- /* prepare to write to Application log on local host
- * with Event Source of SnortService
- */
- AddEventSource(pEventSourceName);
- hEventLog = RegisterEventSource(NULL, pEventSourceName);
- if (hEventLog == NULL)
- {
- /* Could not register the event source. */
- return;
- }
-
- if (!ReportEvent(hEventLog, /* event log handle */
- EVENTLOG_ERROR_TYPE, /* event type */
- 0, /* category zero */
- EVMSG_SIMPLE, /* event identifier */
- NULL, /* no user security identifier */
- 1, /* one substitution string */
- 0, /* no data */
- &msg, /* pointer to array of strings */
- NULL)) /* pointer to data */
- {
- /* Could not report the event. */
- }
-
- DeregisterEventSource(hEventLog);
-}
-#endif /* WIN32 && ENABLE_WIN32_SERVICE */
-
-
-/*
- * Function: FatalError(const char *, ...)
- *
- * Purpose: When a fatal error occurs, this function prints the error message
- * and cleanly shuts down the program
- *
- * Arguments: format => the formatted error string to print out
- * ... => format commands/fillers
- *
- * Returns: void function
- */
-NORETURN void FatalError(const char *format,...)
-{
- char buf[STD_BUF+1];
- va_list ap;
-
- va_start(ap, format);
- vsnprintf(buf, STD_BUF, format, ap);
- va_end(ap);
-
- buf[STD_BUF] = '\0';
-
- if ((snort_conf != NULL) && (ScDaemonMode() || ScLogSyslog()))
- {
- syslog(LOG_CONS | LOG_DAEMON | LOG_ERR, "FATAL ERROR: %s", buf);
- }
- else
- {
- fprintf(stderr, "ERROR: %s", buf);
- fprintf(stderr,"Fatal Error, Quitting..\n");
-#if defined(WIN32) && defined(ENABLE_WIN32_SERVICE)
- CreateApplicationEventLogEntry(buf);
-#endif
- }
-
- exit(1);
-}
-
-
-/****************************************************************************
- *
- * Function: CreatePidFile(char *)
- *
- * Purpose: Creates a PID file
- *
- * Arguments: Interface opened.
- *
- * Returns: void function
- *
- ****************************************************************************/
-static FILE *pid_lockfile = NULL;
-static FILE *pid_file = NULL;
-void CreatePidFile(char *intf)
-{
- struct stat pt;
- int pid = (int) getpid();
-#ifdef WIN32
- char dir[STD_BUF + 1];
-#endif
-
- if (!ScReadMode())
- {
- LogMessage("Checking PID path...\n");
-
- if (strlen(snort_conf->pid_path) != 0)
- {
- if((stat(snort_conf->pid_path, &pt) == -1) ||
- !S_ISDIR(pt.st_mode) || access(snort_conf->pid_path, W_OK) == -1)
- {
-#ifndef WIN32
- /* Save this just in case it's reset with LogMessage call */
- int err = errno;
-
- LogMessage("WARNING: %s is invalid, trying "
- "/var/run...\n", snort_conf->pid_path);
- if (err)
- {
- LogMessage("Previous Error, errno=%d, (%s)\n",
- err, strerror(err) == NULL ? "Unknown error" : strerror(err));
- }
-#endif
- memset(snort_conf->pid_path, 0, sizeof(snort_conf->pid_path));
- }
- else
- {
- LogMessage("PID path stat checked out ok, "
- "PID path set to %s\n", snort_conf->pid_path);
- }
- }
-
- if (strlen(snort_conf->pid_path) == 0)
- {
-#ifndef _PATH_VARRUN
-# ifndef WIN32
- SnortStrncpy(_PATH_VARRUN, "/var/run/", sizeof(_PATH_VARRUN));
-# else
- if (GetCurrentDirectory(sizeof(dir) - 1, dir))
- SnortStrncpy(_PATH_VARRUN, dir, sizeof(_PATH_VARRUN));
-# endif /* WIN32 */
-#else
- LogMessage("PATH_VARRUN is set to %s on this operating "
- "system\n", _PATH_VARRUN);
-#endif /* _PATH_VARRUN */
-
- stat(_PATH_VARRUN, &pt);
-
- if(!S_ISDIR(pt.st_mode) || access(_PATH_VARRUN, W_OK) == -1)
- {
- LogMessage("WARNING: _PATH_VARRUN is invalid, trying "
- "/var/log...\n");
- SnortStrncpy(snort_conf->pid_path, "/var/log/", sizeof(snort_conf->pid_path));
- stat(snort_conf->pid_path, &pt);
-
- if(!S_ISDIR(pt.st_mode) || access(snort_conf->pid_path, W_OK) == -1)
- {
- LogMessage("WARNING: %s is invalid, logging Snort "
- "PID path to log directory (%s)\n", snort_conf->pid_path,
- snort_conf->log_dir);
- CheckLogDir();
- SnortSnprintf(snort_conf->pid_path, sizeof(snort_conf->pid_path),
- "%s/", snort_conf->log_dir);
- }
- }
- else
- {
- LogMessage("PID path stat checked out ok, "
- "PID path set to %s\n", _PATH_VARRUN);
- SnortStrncpy(snort_conf->pid_path, _PATH_VARRUN, sizeof(snort_conf->pid_path));
- }
- }
- }
-
- if(intf == NULL || strlen(snort_conf->pid_path) == 0)
- {
- /* snort_conf->pid_path should have some value by now
- * so let us just be sane. */
- FatalError("CreatePidFile() failed to lookup interface or pid_path is unknown!\n");
- }
-
- SnortSnprintf(snort_conf->pid_filename, sizeof(snort_conf->pid_filename),
- "%s/snort_%s%s.pid", snort_conf->pid_path, intf, snort_conf->pidfile_suffix);
-
-#ifndef WIN32
- if (!ScNoLockPidFile())
- {
- char pid_lockfilename[STD_BUF+1];
- int lock_fd;
-
- /* First, lock the PID file */
- SnortSnprintf(pid_lockfilename, STD_BUF, "%s.lck", snort_conf->pid_filename);
- pid_lockfile = fopen(pid_lockfilename, "w");
-
- if (pid_lockfile)
- {
- struct flock lock;
- lock_fd = fileno(pid_lockfile);
-
- lock.l_type = F_WRLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = 0;
- lock.l_len = 0;
-
- if (fcntl(lock_fd, F_SETLK, &lock) == -1)
- {
- ClosePidFile();
- FatalError("Failed to Lock PID File \"%s\" for PID \"%d\"\n", snort_conf->pid_filename, pid);
- }
- }
- }
-#endif
-
- /* Okay, were able to lock PID file, now open and write PID */
- pid_file = fopen(snort_conf->pid_filename, "w");
- if(pid_file)
- {
- LogMessage("Writing PID \"%d\" to file \"%s\"\n", pid, snort_conf->pid_filename);
- fprintf(pid_file, "%d\n", pid);
- fflush(pid_file);
- }
- else
- {
- ErrorMessage("Failed to create pid file %s", snort_conf->pid_filename);
- snort_conf->pid_filename[0] = 0;
- }
-}
-
-/****************************************************************************
- *
- * Function: ClosePidFile(char *)
- *
- * Purpose: Releases lock on a PID file
- *
- * Arguments: None
- *
- * Returns: void function
- *
- ****************************************************************************/
-void ClosePidFile(void)
-{
- if (pid_file)
- {
- fclose(pid_file);
- pid_file = NULL;
- }
- if (pid_lockfile)
- {
- fclose(pid_lockfile);
- pid_lockfile = NULL;
- }
-}
-
-/****************************************************************************
- *
- * Function: SetUidGid()
- *
- * Purpose: Sets safe UserID and GroupID if needed
- *
- * Arguments: none
- *
- * Returns: void function
- *
- ****************************************************************************/
-void SetUidGid(int user_id, int group_id)
-{
-#ifndef WIN32
-
- if ((group_id != -1) && (getgid() != (gid_t)group_id))
- {
- if (!InlineModeSetPrivsAllowed())
- {
- ErrorMessage("Cannot set uid and gid when running Snort in "
- "inline mode.\n");
- return;
- }
-
- if (setgid(group_id) < 0)
- FatalError("Cannot set gid: %d\n", group_id);
-
- DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Set gid to %d\n", group_id););
- }
-
- if ((user_id != -1) && (getuid() != (uid_t)user_id))
- {
- struct passwd *pw = getpwuid(user_id);
-
- if (!InlineModeSetPrivsAllowed())
- {
- ErrorMessage("Cannot set uid and gid when running Snort in "
- "inline mode.\n");
- return;
- }
-
- if (pw != NULL)
- {
- /* getpwuid and initgroups may use the same static buffers */
- char *username = SnortStrdup(pw->pw_name);
-
- if ((getuid() == 0) && (initgroups(username, group_id) < 0))
- {
- free(username);
- FatalError("Can not initgroups(%s,%d)",
- username, group_id);
- }
-
- free(username);
- }
-
- /** just to be on a safe side... **/
- endgrent();
- endpwent();
-
- if (setuid(user_id) < 0)
- FatalError("Can not set uid: %d\n", user_id);
-
- DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Set uid to %d\n", user_id););
- }
-#endif /* WIN32 */
-}
-
-#ifdef TIMESTATS
-
-static IntervalStats istats = {0};
-time_t start_time;
-
-void InitTimeStats(void)
-{
- start_time = time(NULL);
-}
-
-void ResetTimeStats(void)
-{
- memset(&istats, 0, sizeof(istats));
-}
-
-/* This function prints out stats based on a configurable time
- * interval. It is an indication on how well snort is */
-/* processing packets, including types, drops, etc */
-void DropStatsPerTimeInterval(void)
-{
- double per_sec, per_minute, per_hour;
- uint64_t recv, drop;
- uint64_t total = 0;
- uint32_t timestats_interval = ScTimestatsInterval();
-
-#ifdef PCAP_CLOSE
- if (UpdatePcapPktStats(0) != -1)
-#else
- if (UpdatePcapPktStats() != -1)
-#endif
- {
- recv = GetPcapPktStatsRecv();
- drop = GetPcapPktStatsDrop();
-
- istats.recv = recv - istats.recv_total;
- istats.recv_total = recv;
-
- istats.drop = drop - istats.drop_total;
- istats.drop_total = drop;
-
- /* calculate received packets by type */
- istats.tcp = pc.tcp - istats.tcp_total;
- istats.tcp_total = pc.tcp;
-
- istats.udp = pc.udp - istats.udp_total;
- istats.udp_total = pc.udp;
-
- istats.icmp = pc.icmp - istats.icmp_total;
- istats.icmp_total = pc.icmp;
-
- istats.arp = pc.arp - istats.arp_total;
- istats.arp_total = pc.arp;
-
-#ifdef GRE
- istats.ip4ip4 = pc.ip4ip4 - istats.ip4ip4_total;
- istats.ip4ip4_total = pc.ip4ip4;
-
- istats.ip4ip6 = pc.ip4ip6 - istats.ip4ip6_total;
- istats.ip4ip6_total = pc.ip4ip6;
-
- istats.ip6ip4 = pc.ip6ip4 - istats.ip6ip4_total;
- istats.ip6ip4_total = pc.ip6ip4;
-
- istats.ip6ip6 = pc.ip6ip6 - istats.ip6ip6_total;
- istats.ip6ip6_total = pc.ip6ip6;
-
- istats.gre = pc.gre - istats.gre_total;
- istats.gre_total = pc.gre;
-
- istats.gre_ip = pc.gre_ip - istats.gre_ip_total;
- istats.gre_ip_total = pc.gre_ip;
-
- istats.gre_eth = pc.gre_eth - istats.gre_eth_total;
- istats.gre_eth_total = pc.gre_eth;
-
- istats.gre_arp = pc.gre_arp - istats.gre_arp_total;
- istats.gre_arp_total = pc.gre_arp;
-
- istats.gre_ipv6 = pc.gre_ipv6 - istats.gre_ipv6_total;
- istats.gre_ipv6_total = pc.gre_ipv6;
-
- istats.gre_ipx = pc.gre_ipx - istats.gre_ipx_total;
- istats.gre_ipx_total = pc.gre_ipx;
-
- istats.gre_loopback = pc.gre_loopback - istats.gre_loopback_total;
- istats.gre_loopback_total = pc.gre_loopback;
-
- istats.gre_vlan = pc.gre_vlan - istats.gre_vlan_total;
- istats.gre_vlan_total = pc.gre_vlan;
-
- istats.gre_ppp = pc.gre_ppp - istats.gre_ppp_total;
- istats.gre_ppp_total = pc.gre_ppp;
-#endif
-
-#ifdef DLT_IEEE802_11 /* if we are tracking wireless, add this to output */
- istats.wifi_mgmt = pc.wifi_mgmt - istats.wifi_mgmt_total;
- istats.wifi_mgmt_total = pc.wifi_mgmt;
-
- istats.wifi_control = pc.wifi_control - istats.wifi_control_total;
- istats.wifi_control_total = pc.wifi_control;
-
- istats.wifi_data = pc.wifi_data - istats.wifi_data_total;
- istats.wifi_data_total = pc.wifi_data;
-#endif
-
- istats.ipx = pc.ipx - istats.ipx_total;
- istats.ipx_total = pc.ipx;
-
- istats.eapol = pc.eapol - istats.eapol_total;
- istats.eapol_total = pc.eapol;
-
- istats.ipv6 = pc.ipv6 - istats.ipv6_total;
- istats.ipv6_total = pc.ipv6;
-
- istats.ethloopback = pc.ethloopback - istats.ethloopback_total;
- istats.ethloopback_total = pc.ethloopback;
-
- istats.other = pc.other - istats.other_total;
- istats.other_total = pc.other;
-
- istats.discards = pc.discards - istats.discards_total;
- istats.discards_total = pc.discards;
-
- if (pc.frags > 0) /* do we have any fragmented packets being seen? */
- {
- istats.frags = pc.frags - istats.frags_total;
- istats.frags_total = pc.frags;
-
- istats.frag_trackers = pc.frag_trackers - istats.frag_trackers_total;
- istats.frag_trackers_total = pc.frag_trackers;
-
- istats.frag_rebuilt = pc.rebuilt_frags - istats.frag_rebuilt_total;
- istats.frag_rebuilt_total = pc.rebuilt_frags;
-
- istats.frag_element = pc.rebuild_element - istats.frag_element_total;
- istats.frag_element_total = pc.rebuild_element;
-
- istats.frag_incomp = pc.frag_incomp - istats.frag_incomp_total;
- istats.frag_incomp_total = pc.frag_incomp;
-
- istats.frag_timeout = pc.frag_timeout - istats.frag_timeout_total;
- istats.frag_timeout_total = pc.frag_timeout;
-
- istats.frag_mem_faults = pc.frag_mem_faults - istats.frag_mem_faults_total;
- istats.frag_mem_faults_total = pc.frag_mem_faults;
- }
-
- if (pc.tcp_stream_pkts > 0) /* do we have TCP stream re-assembly going on? */
- {
- istats.tcp_str_packets = pc.tcp_stream_pkts - istats.tcp_str_packets_total;
- istats.tcp_str_packets_total = pc.tcp_stream_pkts;
-
- istats.tcp_str_trackers = pc.tcp_streams - istats.tcp_str_trackers_total;
- istats.tcp_str_trackers_total = pc.tcp_streams;
-
- istats.tcp_str_flushes = pc.rebuilt_tcp - istats.tcp_str_flushes_total;
- istats.tcp_str_flushes_total = pc.rebuilt_tcp;
-
- istats.tcp_str_segs_used = pc.rebuilt_segs - istats.tcp_str_segs_used_total;
- istats.tcp_str_segs_used_total = pc.rebuilt_segs;
-
- istats.tcp_str_segs_queued = pc.queued_segs - istats.tcp_str_segs_queued_total;
- istats.tcp_str_segs_queued_total = pc.queued_segs;
-
- istats.tcp_str_mem_faults = pc.str_mem_faults - istats.tcp_str_mem_faults_total;
- istats.tcp_str_mem_faults_total = pc.str_mem_faults;
- }
-
- istats.processed = pc.total_processed - istats.processed_total;
- istats.processed_total = pc.total_processed;
- total = istats.processed;
-
- /* prepare packet type per time interval routine */
- LogMessage("================================================"
- "===============================\n");
-
- LogMessage("\n");
- LogMessage("Statistics Report (last %d seconds)\n", timestats_interval);
- LogMessage("\n");
-
- per_sec = (double)istats.recv / (double)timestats_interval;
-
- LogMessage("Packet Wire Totals:\n");
- LogMessage("Packets received: " FMTu64("13") "\n", istats.recv);
-
- if (timestats_interval >= SECONDS_PER_HOUR)
- {
- per_hour = (double)(istats.recv * SECONDS_PER_HOUR) / (double)timestats_interval;
- LogMessage(" per hour: %13.2f\n", per_hour);
- }
- if (timestats_interval >= SECONDS_PER_MIN)
- {
- per_minute = (double)(istats.recv * SECONDS_PER_MIN) / (double)timestats_interval;
- LogMessage(" per minute: %13.2f\n", per_minute);
- }
- LogMessage(" per second: %13.2f\n", per_sec);
- LogMessage(" Packets dropped: " FMTu64("13") "\n", istats.drop);
- LogMessage("\n");
- LogMessage("Packet Breakdown by Protocol (includes rebuilt packets):\n");
-
- LogMessage(" TCP: " FMTu64("10") " (%.3f%%)\n",
- istats.tcp, CalcPct(istats.tcp, total));
- LogMessage(" UDP: " FMTu64("10") " (%.3f%%)\n",
- istats.udp, CalcPct(istats.udp, total));
- LogMessage(" ICMP: " FMTu64("10") " (%.3f%%)\n",
- istats.icmp, CalcPct(istats.icmp, total));
- LogMessage(" ARP: " FMTu64("10") " (%.3f%%)\n",
- istats.arp, CalcPct(istats.arp, total));
-#ifndef NO_NON_ETHER_DECODER
- LogMessage(" EAPOL: " FMTu64("10") " (%.3f%%)\n",
- istats.eapol, CalcPct(istats.eapol, total));
-#endif
- LogMessage(" IPv6: " FMTu64("10") " (%.3f%%)\n",
- istats.ipv6, CalcPct(istats.ipv6, total));
- LogMessage(" ETHLOOP: " FMTu64("10") " (%.3f%%)\n",
- istats.ethloopback, CalcPct(istats.ethloopback, total));
- LogMessage(" IPX: " FMTu64("10") " (%.3f%%)\n",
- istats.ipx, CalcPct(istats.ipx, total));
-
-#ifdef GRE
- LogMessage(" IP4/IP4: " FMTu64("-10") " (%.3f%%)\n",
- istats.ip4ip4, CalcPct(istats.ip4ip4, total));
- LogMessage(" IP4/IP6: " FMTu64("-10") " (%.3f%%)\n",
- istats.ip4ip6, CalcPct(istats.ip4ip6, total));
- LogMessage(" IP6/IP4: " FMTu64("-10") " (%.3f%%)\n",
- istats.ip6ip4, CalcPct(istats.ip6ip4, total));
- LogMessage(" IP6/IP6: " FMTu64("-10") " (%.3f%%)\n",
- istats.ip6ip6, CalcPct(istats.ip6ip6, total));
- LogMessage(" GRE: " FMTu64("10") " (%.3f%%)\n",
- istats.gre, CalcPct(istats.gre, total));
- LogMessage(" GRE ETH: " FMTu64("-10") " (%.3f%%)\n",
- istats.gre_eth, CalcPct(istats.gre_eth, total));
- LogMessage("GRE VLAN: " FMTu64("-10") " (%.3f%%)\n",
- istats.gre_vlan, CalcPct(istats.gre_vlan, total));
- LogMessage(" GRE IP: " FMTu64("-10") " (%.3f%%)\n",
- istats.gre_ip, CalcPct(istats.gre_ip, total));
- LogMessage("GRE IPv6: " FMTu64("-10") " (%.3f%%)\n",
- istats.gre_ipv6, CalcPct(istats.gre_ipv6, total));
- LogMessage("GRE PPTP: " FMTu64("-10") " (%.3f%%)\n",
- istats.gre_ppp, CalcPct(istats.gre_ppp, total));
- LogMessage(" GRE ARP: " FMTu64("-10") " (%.3f%%)\n",
- istats.gre_arp, CalcPct(istats.gre_arp, total));
- LogMessage(" GRE IPX: " FMTu64("-10") " (%.3f%%)\n",
- istats.gre_ipx, CalcPct(istats.gre_ipx, total));
- LogMessage("GRE LOOP: " FMTu64("-10") " (%.3f%%)\n",
- istats.gre_loopback, CalcPct(istats.gre_loopback, total));
-#endif
-
- LogMessage(" FRAG: " FMTu64("10") " (%.3f%%)\n",
- istats.frags, CalcPct(istats.frags, total));
- LogMessage(" OTHER: " FMTu64("10") " (%.3f%%)\n",
- istats.other, CalcPct(istats.other, total));
- LogMessage(" DISCARD: " FMTu64("10") " (%.3f%%)\n",
- istats.discards, CalcPct(istats.discards, total));
- LogMessage(" Total: " FMTu64("10") "\n", total);
-
- LogMessage("\n");
-
-
- /* handle case where wireless is enabled... */
-
-#ifndef NO_NON_ETHER_DECODER
-#ifdef DLT_IEEE802_11
- if (datalink == DLT_IEEE802_11)
- {
- LogMessage("\n");
- LogMessage("Wireless Stats:\n\n");
- LogMessage("Management Packets: " FMTu64("10") " (%.3f%%)\n",
- istats.wifi_mgmt, CalcPct(istats.wifi_mgmt, total));
- LogMessage(" Control Packets: " FMTu64("10") " (%.3f%%)\n",
- istats.wifi_control, CalcPct(istats.wifi_control, total));
- LogMessage(" Data Packets: " FMTu64("10") " (%.3f%%)\n",
- istats.wifi_data, CalcPct(istats.wifi_data, total));
- LogMessage("\n");
- }
-
-#endif /* if wireless is enabled... */
-#endif // NO_NON_ETHER_DECODER
-
- /* handle case where we have snort seeing fragmented packets */
-
- if (pc.frags > 0) /* begin if (pc.frags > 0) */
- {
- LogMessage("\n");
- LogMessage("Fragmentation Stats:\n\n");
- LogMessage("Fragmented IP Packets: " FMTu64("10") "\n", istats.frags);
- LogMessage(" Fragment Trackers: " FMTu64("10") "\n", istats.frag_trackers);
- LogMessage(" Rebuilt IP Packets: " FMTu64("10") "\n", istats.frag_rebuilt);
- LogMessage(" Frag Elements Used: " FMTu64("10") "\n", istats.frag_element);
- LogMessage("Discarded(incomplete): " FMTu64("10") "\n", istats.frag_incomp);
- LogMessage(" Discarded(timeout): " FMTu64("10") "\n", istats.frag_timeout);
- LogMessage(" Frag2 memory faults: " FMTu64("10") "\n", istats.frag_mem_faults);
- LogMessage("\n");
- } /* end if (pc.frags > 0) */
-
- /* handle TCP stream re-assy stuff here */
-
- if (pc.tcp_stream_pkts > 0)
- {
- LogMessage("\n");
- LogMessage("TCP Stream Reassembly Stats:\n\n");
- LogMessage(" TCP Packets Used: " FMTu64("10") "\n", istats.tcp_str_packets);
- LogMessage(" Stream Trackers: " FMTu64("10") "\n", istats.tcp_str_trackers);
- LogMessage(" Stream Flushes: " FMTu64("10") "\n", istats.tcp_str_flushes);
- LogMessage(" Stream Segments Used: " FMTu64("10") "\n", istats.tcp_str_segs_used);
- LogMessage("Stream Segments Queued: " FMTu64("10") "\n", istats.tcp_str_segs_queued);
- LogMessage(" Stream4 Memory Faults: " FMTu64("10") "\n", istats.tcp_str_mem_faults);
- LogMessage("\n");
- }
-
- //mpse_print_qinfo();
-
- } /* end if pcap_stats(ps, &ps) */
-
- alarm(timestats_interval); /* reset the alarm to go off again */
-}
-
-/* print out stats on how long snort ran */
-void TimeStats(void)
-{
-
-/*
- * variable definitions for improved statistics handling
- *
- * end_time = time which snort finished running (unix epoch)
- * total_secs = total amount of time snort ran
- * int_total_secs = used to eliminate casts from this function (temp. var)
- * days = number of days snort ran
- * hrs = number of hrs snort ran
- * mins = number of minutes snort ran
- * secs = number of seconds snort ran
- *
- * ival = temp. variable for integer/modulus math
- * ppd = packets per day processed
- * pph = packets per hour processed
- * ppm = packets per minute processed
- * pps = packets per second processed
- *
- * hflag = used to flag when hrs = zero, but days > 0
- * mflag = used to flag when min = zero, but hrs > 0
- *
- */
-
- time_t end_time, total_secs;
- uint32_t days = 0, hrs = 0, mins = 0, secs = 0, tmp = 0;
- uint64_t pps = 0, ppm = 0, pph = 0, ppd = 0;
- uint32_t int_total_secs = 0;
- char hflag = 0, mflag = 0;
-
-
- end_time = time(NULL); /* grab epoch for end time value (in seconds) */
- total_secs = end_time - start_time; /* total_secs is how many seconds snort ran for */
-
- tmp = (uint32_t)total_secs;
- int_total_secs = tmp; /* used for cast elimination */
-
- days = tmp / SECONDS_PER_DAY; /* 86400 is number of seconds in a day */
- tmp = tmp % SECONDS_PER_DAY; /* grab remainder to process hours */
- hrs = tmp / SECONDS_PER_HOUR; /* 3600 is number of seconds in a(n) hour */
- tmp = tmp % SECONDS_PER_HOUR; /* grab remainder to process minutes */
- mins = tmp / SECONDS_PER_MIN; /* 60 is number of seconds in a minute */
- secs = tmp % SECONDS_PER_MIN; /* grab remainder to process seconds */
-
- if (total_secs)
- pps = (pc.total_from_pcap / int_total_secs);
- else
- pps = pc.total_from_pcap; /* guard against division by zero */
-
- /* Use ErrorMessage because this is logged whether
- * or not logging quietly */
- ErrorMessage("Snort ran for %u Days %u Hours %u Minutes %u Seconds\n",
- days, hrs, mins, secs);
-
- if (days > 0)
- {
- ppd = (pc.total_from_pcap / (int_total_secs / SECONDS_PER_DAY));
- ErrorMessage("Snort Analyzed " STDu64 " Packets Per Day\n", ppd);
- hflag = 1;
- }
-
- if (hrs > 0 || hflag == 1)
- {
- pph = (pc.total_from_pcap / (int_total_secs / SECONDS_PER_HOUR));
- ErrorMessage("Snort Analyzed " STDu64 " Packets Per Hour\n", pph);
- mflag = 1;
- }
-
- if (mins > 0 || mflag == 1)
- {
- ppm = (pc.total_from_pcap / (int_total_secs / SECONDS_PER_MIN));
- ErrorMessage("Snort Analyzed " STDu64 " Packets Per Minute\n", ppm);
- }
-
- ErrorMessage("Snort Analyzed " STDu64 " Packets Per Second\n", pps);
- ErrorMessage("\n");
-}
-#endif /* TIMESTATS */
-
-
-#ifdef PCAP_CLOSE
-int UpdatePcapPktStats(int cacheReturn)
-#else
-int UpdatePcapPktStats(void)
-#endif
-{
- struct pcap_stat ps;
- uint32_t recv, drop;
- static char not_initialized = 1;
-
-#ifdef PCAP_CLOSE
- static int priorReturn = 0;
- static int returnWasCached = 0;
-
- if ( !cacheReturn && returnWasCached )
- {
- returnWasCached = 0;
- return priorReturn;
- }
- priorReturn = -1;
- returnWasCached = cacheReturn;
-#endif
-
- if (not_initialized)
- {
- memset(&pkt_stats, 0, sizeof(PcapPktStats));
- not_initialized = 0;
- }
-
- if ((pcap_handle == NULL) || ScReadMode())
- return -1;
-
- if (pcap_stats(pcap_handle, &ps) == -1)
- {
- pcap_perror(pcap_handle, "pcap_stats");
- return -1;
- }
-
- recv = (uint32_t)ps.ps_recv;
- drop = (uint32_t)ps.ps_drop;
-
-#ifdef LINUX_LIBPCAP_DOUBLES_STATS
- recv /= 2;
- drop /= 2;
-#endif
-
-#ifdef LIBPCAP_ACCUMULATES
- /* pcap recv wrapped */
- if (recv < pkt_stats.wrap_recv)
- pkt_stats.recv += (uint64_t)UINT32_MAX;
-
- /* pcap drop wrapped */
- if (drop < pkt_stats.wrap_drop)
- pkt_stats.drop += (uint64_t)UINT32_MAX;
-
- pkt_stats.wrap_recv = recv;
- pkt_stats.wrap_drop = drop;
-#else
- pkt_stats.recv += (uint64_t)recv;
- pkt_stats.drop += (uint64_t)drop;
-#endif /* LIBPCAP_ACCUMULATES */
-
-#ifdef PCAP_CLOSE
- priorReturn = 0;
-#endif
- return 0;
-}
-
-uint64_t GetPcapPktStatsRecv(void)
-{
- return pkt_stats.recv + (uint64_t)pkt_stats.wrap_recv;
-}
-
-uint64_t GetPcapPktStatsDrop(void)
-{
- return pkt_stats.drop + (uint64_t)pkt_stats.wrap_drop;
-}
-
-
-#ifdef PCAP_CLOSE
-/* exiting should be 0 for if not exiting, 1 if restarting, and 2 if exiting */
-#else
-/* exiting should be 0 for if not exiting and 1 if exiting */
-#endif
-void DropStats(int exiting)
-{
- PreprocStatsFuncNode *idx;
- uint64_t total = 0;
- uint64_t pkts_recv;
- uint64_t pkts_drop;
-
- total = pc.total_processed;
-
-#ifdef PPM_MGR
- PPM_PRINT_SUMMARY(&snort_conf->ppm_cfg);
-#endif
-
- LogMessage("================================================"
- "===============================\n");
-
-#ifdef TIMESTATS
- TimeStats(); /* how long did snort run? */
-#endif
-
- if (ScReadMode()
-#ifdef GIDS
- || ScAdapterInlineMode()
-#endif
- )
- {
- LogMessage("Snort processed " STDu64 " packets.\n", total);
- }
- else
- {
-#ifdef PCAP_CLOSE
- if (exiting < 2 && (pcap_handle == NULL))
-#else
- if (pcap_handle == NULL)
-#endif
- {
- LogMessage("Snort received 0 packets\n");
- }
- else
- {
-#ifdef PCAP_CLOSE
- if (UpdatePcapPktStats(0) != -1)
-#else
- if (UpdatePcapPktStats() != -1)
-#endif
- {
- pkts_recv = GetPcapPktStatsRecv();
- pkts_drop = GetPcapPktStatsDrop();
-
- LogMessage("Packet Wire Totals:\n");
- LogMessage(" Received: " FMTu64("12") "\n", pkts_recv);
- LogMessage(" Analyzed: " FMTu64("12") " (%.3f%%)\n", pc.total_from_pcap,
- CalcPct(pc.total_from_pcap, pkts_recv));
- LogMessage(" Dropped: " FMTu64("12") " (%.3f%%)\n", pkts_drop,
- CalcPct(pkts_drop, pkts_recv));
- LogMessage("Outstanding: " FMTu64("12") " (%.3f%%)\n",
- pkts_recv - pkts_drop - pc.total_from_pcap,
- CalcPct((pkts_recv - pkts_drop - pc.total_from_pcap), pkts_recv));
- }
- else
- {
- LogMessage("Unable to calculate percentages for stats\n");
- LogMessage("Total number of packets Analyzed: " FMTu64("12") "\n", pc.total_from_pcap);
- }
- }
- }
-
- LogMessage("================================================"
- "===============================\n");
-
- LogMessage("Breakdown by protocol (includes rebuilt packets):\n");
-
- LogMessage(" ETH: " FMTu64("-10") " (%.3f%%)\n",
- pc.eth, CalcPct(pc.eth, total));
- LogMessage(" ETHdisc: " FMTu64("-10") " (%.3f%%)\n",
- pc.ethdisc, CalcPct(pc.ethdisc, total));
-#ifdef GIDS
-#ifndef IPFW
- LogMessage(" IPTables: " FMTu64("-10") " (%.3f%%)\n",
- pc.iptables, CalcPct(pc.iptables, total));
-#else
- LogMessage(" IPFW: " FMTu64("-10") " (%.3f%%)\n",
- pc.ipfw, CalcPct(pc.ipfw, total));
-#endif /* IPFW */
-#endif /* GIDS */
- LogMessage(" VLAN: " FMTu64("-10") " (%.3f%%)\n",
- pc.vlan, CalcPct(pc.vlan, total));
-
- if (pc.nested_vlan != 0)
- LogMessage("Nested VLAN: " FMTu64("-10") " (%.3f%%)\n",
- pc.nested_vlan, CalcPct(pc.nested_vlan, total));
-
- LogMessage(" IPV6: " FMTu64("-10") " (%.3f%%)\n",
- pc.ipv6, CalcPct(pc.ipv6, total));
- LogMessage(" IP6 EXT: " FMTu64("-10") " (%.3f%%)\n",
- pc.ip6ext, CalcPct(pc.ip6ext, total));
- LogMessage(" IP6opts: " FMTu64("-10") " (%.3f%%)\n",
- pc.ipv6opts, CalcPct(pc.ipv6opts, total));
- LogMessage(" IP6disc: " FMTu64("-10") " (%.3f%%)\n",
- pc.ipv6disc, CalcPct(pc.ipv6disc, total));
-
- LogMessage(" IP4: " FMTu64("-10") " (%.3f%%)\n",
- pc.ip, CalcPct(pc.ip, total));
- LogMessage(" IP4disc: " FMTu64("-10") " (%.3f%%)\n",
- pc.ipdisc, CalcPct(pc.ipdisc, total));
-
- LogMessage(" TCP 6: " FMTu64("-10") " (%.3f%%)\n",
- pc.tcp6, CalcPct(pc.tcp6, total));
- LogMessage(" UDP 6: " FMTu64("-10") " (%.3f%%)\n",
- pc.udp6, CalcPct(pc.udp6, total));
- LogMessage(" ICMP6: " FMTu64("-10") " (%.3f%%)\n",
- pc.icmp6, CalcPct(pc.icmp6, total));
- LogMessage(" ICMP-IP: " FMTu64("-10") " (%.3f%%)\n",
- pc.embdip, CalcPct(pc.embdip, total));
-
- LogMessage(" TCP: " FMTu64("-10") " (%.3f%%)\n",
- pc.tcp, CalcPct(pc.tcp, total));
- LogMessage(" UDP: " FMTu64("-10") " (%.3f%%)\n",
- pc.udp, CalcPct(pc.udp, total));
- LogMessage(" ICMP: " FMTu64("-10") " (%.3f%%)\n",
- pc.icmp, CalcPct(pc.icmp, total));
-
- LogMessage(" TCPdisc: " FMTu64("-10") " (%.3f%%)\n",
- pc.tdisc, CalcPct(pc.tdisc, total));
- LogMessage(" UDPdisc: " FMTu64("-10") " (%.3f%%)\n",
- pc.udisc, CalcPct(pc.udisc, total));
- LogMessage(" ICMPdis: " FMTu64("-10") " (%.3f%%)\n",
- pc.icmpdisc, CalcPct(pc.icmpdisc, total));
-
- LogMessage(" FRAG: " FMTu64("-10") " (%.3f%%)\n",
- pc.frags, CalcPct(pc.frags, total));
- LogMessage(" FRAG 6: " FMTu64("-10") " (%.3f%%)\n",
- pc.frag6, CalcPct(pc.frag6, total));
-
- LogMessage(" ARP: " FMTu64("-10") " (%.3f%%)\n",
- pc.arp, CalcPct(pc.arp, total));
-#ifndef NO_NON_ETHER_DECODER
- LogMessage(" EAPOL: " FMTu64("-10") " (%.3f%%)\n",
- pc.eapol, CalcPct(pc.eapol, total));
-#endif
- LogMessage(" ETHLOOP: " FMTu64("-10") " (%.3f%%)\n",
- pc.ethloopback, CalcPct(pc.ethloopback, total));
- LogMessage(" IPX: " FMTu64("-10") " (%.3f%%)\n",
- pc.ipx, CalcPct(pc.ipx, total));
-#ifdef GRE
- LogMessage("IPv4/IPv4: " FMTu64("-10") " (%.3f%%)\n",
- pc.ip4ip4, CalcPct(pc.ip4ip4, total));
- LogMessage("IPv4/IPv6: " FMTu64("-10") " (%.3f%%)\n",
- pc.ip4ip6, CalcPct(pc.ip4ip6, total));
- LogMessage("IPv6/IPv4: " FMTu64("-10") " (%.3f%%)\n",
- pc.ip6ip4, CalcPct(pc.ip6ip4, total));
- LogMessage("IPv6/IPv6: " FMTu64("-10") " (%.3f%%)\n",
- pc.ip6ip6, CalcPct(pc.ip6ip6, total));
- LogMessage(" GRE: " FMTu64("-10") " (%.3f%%)\n",
- pc.gre, CalcPct(pc.gre, total));
- LogMessage(" GRE ETH: " FMTu64("-10") " (%.3f%%)\n",
- pc.gre_eth, CalcPct(pc.gre_eth, total));
- LogMessage(" GRE VLAN: " FMTu64("-10") " (%.3f%%)\n",
- pc.gre_vlan, CalcPct(pc.gre_vlan, total));
- LogMessage(" GRE IPv4: " FMTu64("-10") " (%.3f%%)\n",
- pc.gre_ip, CalcPct(pc.gre_ip, total));
- LogMessage(" GRE IPv6: " FMTu64("-10") " (%.3f%%)\n",
- pc.gre_ipv6, CalcPct(pc.gre_ipv6, total));
- LogMessage("GRE IP6 E: " FMTu64("-10") " (%.3f%%)\n",
- pc.gre_ipv6ext, CalcPct(pc.gre_ipv6ext, total));
- LogMessage(" GRE PPTP: " FMTu64("-10") " (%.3f%%)\n",
- pc.gre_ppp, CalcPct(pc.gre_ppp, total));
- LogMessage(" GRE ARP: " FMTu64("-10") " (%.3f%%)\n",
- pc.gre_arp, CalcPct(pc.gre_arp, total));
- LogMessage(" GRE IPX: " FMTu64("-10") " (%.3f%%)\n",
- pc.gre_ipx, CalcPct(pc.gre_ipx, total));
- LogMessage(" GRE LOOP: " FMTu64("-10") " (%.3f%%)\n",
- pc.gre_loopback, CalcPct(pc.gre_loopback, total));
-#endif /* GRE */
-#ifdef MPLS
- LogMessage(" MPLS: " FMTu64("-10") " (%.3f%%)\n",
- pc.mpls, CalcPct(pc.mpls, total));
-#endif
- LogMessage(" OTHER: " FMTu64("-10") " (%.3f%%)\n",
- pc.other, CalcPct(pc.other, total));
- LogMessage(" DISCARD: " FMTu64("-10") " (%.3f%%)\n",
- pc.discards, CalcPct(pc.discards, total));
- LogMessage("InvChkSum: " FMTu64("-10") " (%.3f%%)\n",
- pc.invalid_checksums, CalcPct(pc.invalid_checksums, total));
-
- LogMessage(" S5 G 1: " FMTu64("-10") " (%.3f%%)\n",
- pc.s5tcp1, CalcPct(pc.s5tcp1, total));
- LogMessage(" S5 G 2: " FMTu64("-10") " (%.3f%%)\n",
- pc.s5tcp2, CalcPct(pc.s5tcp2, total));
-
- LogMessage(" Total: " FMTu64("-10") "\n", total);
-
- LogMessage("================================================"
- "===============================\n");
-
- LogMessage("Action Stats:\n");
- LogMessage("ALERTS: " STDu64 "\n", pc.alert_pkts);
- LogMessage("LOGGED: " STDu64 "\n", pc.log_pkts);
- LogMessage("PASSED: " STDu64 "\n", pc.pass_pkts);
-
-#ifdef TARGET_BASED
- if (ScIdsMode() && IsAdaptiveConfigured(getDefaultPolicy(), 0))
- {
- LogMessage("================================================"
- "===============================\n");
- LogMessage("Attribute Table Stats:\n");
- LogMessage(" Number Entries: %u\n", SFAT_NumberOfHosts());
- LogMessage(" Table Reloaded: " STDu64 "\n", pc.attribute_table_reloads);
- }
-#endif /* TARGET_BASED */
-
- //mpse_print_qinfo();
-
-#ifndef NO_NON_ETHER_DECODER
-#ifdef DLT_IEEE802_11
- if(datalink == DLT_IEEE802_11)
- {
- LogMessage("================================================"
- "===============================\n");
- LogMessage("Wireless Stats:\n");
- LogMessage("Breakdown by type:\n");
- LogMessage(" Management Packets: " FMTu64("-10") " (%.3f%%)\n",
- pc.wifi_mgmt, CalcPct(pc.wifi_mgmt, total));
- LogMessage(" Control Packets: " FMTu64("-10") " (%.3f%%)\n",
- pc.wifi_control, CalcPct(pc.wifi_control, total));
- LogMessage(" Data Packets: " FMTu64("-10") " (%.3f%%)\n",
- pc.wifi_data, CalcPct(pc.wifi_data, total));
- }
-#endif /* DLT_IEEE802_11 */
-#endif // NO_NON_ETHER_DECODER
-
- for (idx = preproc_stats_funcs; idx != NULL; idx = idx->next)
- {
- LogMessage("=============================================="
- "=================================\n");
-
-#ifdef PCAP_CLOSE
- idx->func(exiting ? 1 : 0);
-#else
- idx->func(exiting);
-#endif
- }
-
- LogMessage("=============================================="
- "=================================\n");
-
- return;
-}
-
-/****************************************************************************
- *
- * Function: CleanupProtoNames()
- *
- * Purpose: Frees the protocol names
- *
- * Arguments: None.
- *
- * Returns: void function
- *
- ****************************************************************************/
-void CleanupProtoNames(void)
-{
- int i;
-
- for(i = 0; i < 256; i++)
- {
- if( protocol_names[i] != NULL )
- {
- free( protocol_names[i] );
- protocol_names[i] = NULL;
- }
- }
-}
-
-/****************************************************************************
- *
- * Function: read_infile(char *)
- *
- * Purpose: Reads the BPF filters in from a file. Ripped from tcpdump.
- *
- * Arguments: fname => the name of the file containing the BPF filters
- *
- * Returns: the processed BPF string
- *
- ****************************************************************************/
-char *read_infile(char *fname)
-{
- register int fd, cc;
- register char *cp, *cmt;
- struct stat buf;
-
- fd = open(fname, O_RDONLY);
-
- if(fd < 0)
- FatalError("can't open %s: %s\n", fname, pcap_strerror(errno));
-
- if(fstat(fd, &buf) < 0)
- FatalError("can't stat %s: %s\n", fname, pcap_strerror(errno));
-
- cp = (char *)SnortAlloc(((u_int)buf.st_size + 1) * sizeof(char));
-
- cc = read(fd, cp, (int) buf.st_size);
-
- if(cc < 0)
- FatalError("read %s: %s\n", fname, pcap_strerror(errno));
-
- if(cc != buf.st_size)
- FatalError("short read %s (%d != %d)\n", fname, cc, (int) buf.st_size);
-
- cp[(int) buf.st_size] = '\0';
-
- close(fd);
-
- /* Treat everything upto the end of the line as a space
- * so that we can put comments in our BPF filters
- */
-
- while((cmt = strchr(cp, '#')) != NULL)
- {
- while (*cmt != '\r' && *cmt != '\n' && *cmt != '\0')
- {
- *cmt++ = ' ';
- }
- }
-
- /** LogMessage("BPF filter file: %s\n", fname); **/
-
- return(cp);
-}
-
-
- /****************************************************************************
- *
- * Function: CheckLogDir()
- *
- * Purpose: CyberPsychotic sez: basically we only check if logdir exist and
- * writable, since it might screw the whole thing in the middle. Any
- * other checks could be performed here as well.
- *
- * Arguments: None.
- *
- * Returns: void function
- *
- ****************************************************************************/
-void CheckLogDir(void)
-{
- struct stat st;
-
- if (snort_conf->log_dir == NULL)
- return;
-
- if (stat(snort_conf->log_dir, &st) == -1)
- FatalError("Stat check on log dir failed: %s.\n", strerror(errno));
-
- if (!S_ISDIR(st.st_mode) || (access(snort_conf->log_dir, W_OK) == -1))
- {
- FatalError("Can not get write access to logging directory \"%s\". "
- "(directory doesn't exist or permissions are set incorrectly "
- "or it is not a directory at all)\n",
- snort_conf->log_dir);
- }
-}
-
-/* Signal handler for child process signaling the parent
- * that is is ready */
-static int parent_wait = 1;
-static void SigChildReadyHandler(int signal)
-{
-#ifdef DEBUG
- LogMessage("Received Signal from Child\n");
-#endif
- parent_wait = 0;
-}
-
-/****************************************************************************
- *
- * Function: GoDaemon()
- *
- * Purpose: Puts the program into daemon mode, nice and quiet like....
- *
- * Arguments: None.
- *
- * Returns: void function
- *
- ****************************************************************************/
-void GoDaemon(void)
-{
-#ifndef WIN32
- int exit_val = 0;
- pid_t fs;
-
- LogMessage("Initializing daemon mode\n");
-
- if (ScDaemonRestart())
- return;
-
- /* Don't daemonize if we've already daemonized and
- * received a SIGHUP. */
- if(getppid() != 1)
- {
- /* Register signal handler that parent can trap signal */
- signal(SIGNAL_SNORT_CHILD_READY, SigChildReadyHandler);
- if (errno != 0) errno=0;
-
- /* now fork the child */
- fs = fork();
-
- if(fs > 0)
- {
- /* Parent */
-
- /* Don't exit quite yet. Wait for the child
- * to signal that is there and created the PID
- * file.
- */
- while (parent_wait)
- {
- /* Continue waiting until receiving signal from child */
- int status;
- if (waitpid(fs, &status, WNOHANG) == fs)
- {
- /* If the child is gone, parent should go away, too */
- if (WIFEXITED(status))
- {
- LogMessage("Child exited unexpectedly\n");
- exit_val = -1;
- break;
- }
-
- if (WIFSIGNALED(status))
- {
- LogMessage("Child terminated unexpectedly\n");
- exit_val = -2;
- break;
- }
- }
-#ifdef DEBUG
- LogMessage("Parent waiting for child...\n");
-#endif
-
- sleep(1);
- }
-
- LogMessage("Daemon parent exiting\n");
-
- exit(exit_val); /* parent */
- }
-
- if(fs < 0)
- {
- /* Daemonizing failed... */
- perror("fork");
- exit(1);
- }
-
- /* Child */
- setsid();
- }
-
- close(0);
- close(1);
- close(2);
-
-#ifdef DEBUG
- /* redirect stdin/stdout/stderr to a file */
- open("/tmp/snort.debug", O_CREAT | O_RDWR); /* stdin, fd 0 */
-
- /* Change ownership to that which we will drop privileges to */
- if ((snort_conf->user_id != -1) || (snort_conf->group_id != -1))
- {
- uid_t user_id = getuid();
- gid_t group_id = getgid();
-
- if (snort_conf->user_id != -1)
- user_id = snort_conf->user_id;
- if (snort_conf->group_id != -1)
- group_id = snort_conf->group_id;
-
- chown("/tmp/snort.debug", user_id, group_id);
- }
-#else
- /* redirect stdin/stdout/stderr to /dev/null */
- (void)open("/dev/null", O_RDWR); /* stdin, fd 0 */
-#endif
-
- dup(0); /* stdout, fd 0 => fd 1 */
- dup(0); /* stderr, fd 0 => fd 2 */
-
- SignalWaitingParent();
-
-#endif /* ! WIN32 */
-}
-
-/* Signal the parent that child is ready */
-void SignalWaitingParent(void)
-{
-#ifndef WIN32
- pid_t parentpid = getppid();
-#ifdef DEBUG
- LogMessage("Signaling parent %d from child %d\n", parentpid, getpid());
-#endif
-
- if (kill(parentpid, SIGNAL_SNORT_CHILD_READY))
- {
- LogMessage("Daemon initialized, failed to signal parent pid: %d, failure: %d, %s\n", parentpid, errno, strerror(errno));
- }
- else
- {
- LogMessage("Daemon initialized, signaled parent pid: %d\n", parentpid);
- }
-#endif
-}
-
-/* This function has been moved into mstring.c, since that
-* is where the allocation actually occurs. It has been
-* renamed to mSplitFree().
-*
-void FreeToks(char **toks, int num_toks)
-{
- if (toks)
- {
- if (num_toks > 0)
- {
- do
- {
- num_toks--;
- free(toks[num_toks]);
- } while(num_toks);
- }
- free(toks);
- }
-}
-*/
-
-
-/* Self preserving memory allocator */
-void *SPAlloc(unsigned long size, struct _SPMemControl *spmc)
-{
- void *tmp;
-
- spmc->mem_usage += size;
-
- if(spmc->mem_usage > spmc->memcap)
- {
- spmc->sp_func(spmc);
- }
-
- tmp = (void *) calloc(size, sizeof(char));
-
- if(tmp == NULL)
- {
- FatalError("Unable to allocate memory! (%lu requested, %lu in use)\n",
- size, spmc->mem_usage);
- }
-
- return tmp;
-}
-
-/* Guaranteed to be '\0' terminated even if truncation occurs.
- *
- * returns SNORT_SNPRINTF_SUCCESS if successful
- * returns SNORT_SNPRINTF_TRUNCATION on truncation
- * returns SNORT_SNPRINTF_ERROR on error
- */
-int SnortSnprintf(char *buf, size_t buf_size, const char *format, ...)
-{
- va_list ap;
- int ret;
-
- if (buf == NULL || buf_size <= 0 || format == NULL)
- return SNORT_SNPRINTF_ERROR;
-
- /* zero first byte in case an error occurs with
- * vsnprintf, so buffer is null terminated with
- * zero length */
- buf[0] = '\0';
- buf[buf_size - 1] = '\0';
-
- va_start(ap, format);
-
- ret = vsnprintf(buf, buf_size, format, ap);
-
- va_end(ap);
-
- if (ret < 0)
- return SNORT_SNPRINTF_ERROR;
-
- if (buf[buf_size - 1] != '\0' || (size_t)ret >= buf_size)
- {
- /* result was truncated */
- buf[buf_size - 1] = '\0';
- return SNORT_SNPRINTF_TRUNCATION;
- }
-
- return SNORT_SNPRINTF_SUCCESS;
-}
-
-/* Appends to a given string
- * Guaranteed to be '\0' terminated even if truncation occurs.
- *
- * returns SNORT_SNPRINTF_SUCCESS if successful
- * returns SNORT_SNPRINTF_TRUNCATION on truncation
- * returns SNORT_SNPRINTF_ERROR on error
- */
-int SnortSnprintfAppend(char *buf, size_t buf_size, const char *format, ...)
-{
- int str_len;
- int ret;
- va_list ap;
-
- if (buf == NULL || buf_size <= 0 || format == NULL)
- return SNORT_SNPRINTF_ERROR;
-
- str_len = SnortStrnlen(buf, buf_size);
-
- /* since we've already checked buf and buf_size an error
- * indicates no null termination, so just start at
- * beginning of buffer */
- if (str_len == SNORT_STRNLEN_ERROR)
- {
- buf[0] = '\0';
- str_len = 0;
- }
-
- buf[buf_size - 1] = '\0';
-
- va_start(ap, format);
-
- ret = vsnprintf(buf + str_len, buf_size - (size_t)str_len, format, ap);
-
- va_end(ap);
-
- if (ret < 0)
- return SNORT_SNPRINTF_ERROR;
-
- if (buf[buf_size - 1] != '\0' || (size_t)ret >= buf_size)
- {
- /* truncation occured */
- buf[buf_size - 1] = '\0';
- return SNORT_SNPRINTF_TRUNCATION;
- }
-
- return SNORT_SNPRINTF_SUCCESS;
-}
-
-/* Guaranteed to be '\0' terminated even if truncation occurs.
- *
- * Arguments: dst - the string to contain the copy
- * src - the string to copy from
- * dst_size - the size of the destination buffer
- * including the null byte.
- *
- * returns SNORT_STRNCPY_SUCCESS if successful
- * returns SNORT_STRNCPY_TRUNCATION on truncation
- * returns SNORT_STRNCPY_ERROR on error
- *
- * Note: Do not set dst[0] = '\0' on error since it's possible that
- * dst and src are the same pointer - it will at least be null
- * terminated in any case
- */
-int SnortStrncpy(char *dst, const char *src, size_t dst_size)
-{
- char *ret = NULL;
-
- if (dst == NULL || src == NULL || dst_size <= 0)
- return SNORT_STRNCPY_ERROR;
-
- dst[dst_size - 1] = '\0';
-
- ret = strncpy(dst, src, dst_size);
-
- /* Not sure if this ever happens but might as
- * well be on the safe side */
- if (ret == NULL)
- return SNORT_STRNCPY_ERROR;
-
- if (dst[dst_size - 1] != '\0')
- {
- /* result was truncated */
- dst[dst_size - 1] = '\0';
- return SNORT_STRNCPY_TRUNCATION;
- }
-
- return SNORT_STRNCPY_SUCCESS;
-}
-
-char *SnortStrndup(const char *src, size_t dst_size)
-{
- char *ret = SnortAlloc(dst_size + 1);
- int ret_val;
-
- ret_val = SnortStrncpy(ret, src, dst_size + 1);
-
- if(ret_val == SNORT_STRNCPY_ERROR)
- {
- free(ret);
- return NULL;
- }
-
- return ret;
-}
-
-/* Determines whether a buffer is '\0' terminated and returns the
- * string length if so
- *
- * returns the string length if '\0' terminated
- * returns SNORT_STRNLEN_ERROR if not '\0' terminated
- */
-int SnortStrnlen(const char *buf, int buf_size)
-{
- int i = 0;
-
- if (buf == NULL || buf_size <= 0)
- return SNORT_STRNLEN_ERROR;
-
- for (i = 0; i < buf_size; i++)
- {
- if (buf[i] == '\0')
- break;
- }
-
- if (i == buf_size)
- return SNORT_STRNLEN_ERROR;
-
- return i;
-}
-
-char * SnortStrdup(const char *str)
-{
- char *copy = NULL;
-
- if (!str)
- {
- FatalError("Unable to duplicate string: NULL!\n");
- }
-
- copy = strdup(str);
-
- if (copy == NULL)
- {
- FatalError("Unable to duplicate string: %s!\n", str);
- }
-
- return copy;
-}
-
-/*
- * Find first occurrence of char of accept in s, limited by slen.
- * A 'safe' version of strpbrk that won't read past end of buffer s
- * in cases that s is not NULL terminated.
- *
- * This code assumes 'accept' is a static string.
- */
-const char *SnortStrnPbrk(const char *s, int slen, const char *accept)
-{
- char ch;
- const char *s_end;
- if (!s || !*s || !accept || slen == 0)
- return NULL;
-
- s_end = s + slen;
- while (s < s_end)
- {
- ch = *s;
- if (strchr(accept, ch))
- return s;
- s++;
- }
- return NULL;
-}
-
-/*
- * Find first occurrence of searchstr in s, limited by slen.
- * A 'safe' version of strstr that won't read past end of buffer s
- * in cases that s is not NULL terminated.
- */
-const char *SnortStrnStr(const char *s, int slen, const char *searchstr)
-{
- char ch, nc;
- int len;
- if (!s || !*s || !searchstr || slen == 0)
- return NULL;
-
- if ((ch = *searchstr++) != 0)
- {
- len = strlen(searchstr);
- do
- {
- do
- {
- if ((nc = *s++) == 0)
- {
- return NULL;
- }
- slen--;
- if (slen == 0)
- return NULL;
- } while (nc != ch);
- if (slen - len < 0)
- return NULL;
- } while (memcmp(s, searchstr, len) != 0);
- s--;
- slen++;
- }
- return s;
-}
-
-/*
- * Find first occurrence of substring in s, ignore case.
-*/
-const char *SnortStrcasestr(const char *s, const char *substr)
-{
- char ch, nc;
- int len;
-
- if (!s || !*s || !substr)
- return NULL;
-
- if ((ch = *substr++) != 0)
- {
- ch = tolower((char)ch);
- len = strlen(substr);
- do
- {
- do
- {
- if ((nc = *s++) == 0)
- {
- return NULL;
- }
- } while ((char)tolower((uint8_t)nc) != ch);
- } while (strncasecmp(s, substr, len) != 0);
- s--;
- }
- return s;
-}
-
-void *SnortAlloc(unsigned long size)
-{
- void *tmp;
-
- tmp = (void *) calloc(size, sizeof(char));
-
- if(tmp == NULL)
- {
- FatalError("Unable to allocate memory! (%lu requested)\n", size);
- }
-
- return tmp;
-}
-
-void * SnortAlloc2(size_t size, const char *format, ...)
-{
- void *tmp;
-
- tmp = (void *)calloc(size, sizeof(char));
-
- if(tmp == NULL)
- {
- va_list ap;
- char buf[STD_BUF];
-
- buf[STD_BUF - 1] = '\0';
-
- va_start(ap, format);
-
- vsnprintf(buf, STD_BUF - 1, format, ap);
-
- va_end(ap);
-
- FatalError("%s", buf);
- }
-
- return tmp;
-}
-
-/**
- * Chroot and adjust the snort_conf->log_dir reference
- *
- * @param directory directory to chroot to
- * @param logstore ptr to snort_conf->log_dir which must be dynamically allocated
- */
-void SetChroot(char *directory, char **logstore)
-{
-#ifdef WIN32
- FatalError("SetChroot() should not be called under Win32!\n");
-#else
- char *absdir;
- size_t abslen;
- char *logdir;
-
- if(!directory || !logstore)
- {
- FatalError("Null parameter passed\n");
- }
-
- logdir = *logstore;
-
- if(logdir == NULL || *logdir == '\0')
- {
- FatalError("Null log directory\n");
- }
-
- DEBUG_WRAP(DebugMessage(DEBUG_INIT,"SetChroot: %s\n",
- CurrentWorkingDir()););
-
- logdir = GetAbsolutePath(logdir);
-
- DEBUG_WRAP(DebugMessage(DEBUG_INIT, "SetChroot: %s\n",
- CurrentWorkingDir()));
-
- logdir = SnortStrdup(logdir);
-
- /* We're going to reset logstore, so free it now */
- free(*logstore);
- *logstore = NULL;
-
- /* change to the directory */
- if(chdir(directory) != 0)
- {
- FatalError("SetChroot: Can not chdir to \"%s\": %s\n", directory,
- strerror(errno));
- }
-
- /* always returns an absolute pathname */
- absdir = CurrentWorkingDir();
-
- if(absdir == NULL)
- {
- FatalError("NULL Chroot found\n");
- }
-
- abslen = strlen(absdir);
-
- DEBUG_WRAP(DebugMessage(DEBUG_INIT, "ABS: %s %d\n", absdir, abslen););
-
- /* make the chroot call */
- if(chroot(absdir) < 0)
- {
- FatalError("Can not chroot to \"%s\": absolute: %s: %s\n",
- directory, absdir, strerror(errno));
- }
-
- DEBUG_WRAP(DebugMessage(DEBUG_INIT,"chroot success (%s ->", absdir););
- DEBUG_WRAP(DebugMessage(DEBUG_INIT,"%s)\n ", CurrentWorkingDir()););
-
- /* change to "/" in the new directory */
- if(chdir("/") < 0)
- {
- FatalError("Can not chdir to \"/\" after chroot: %s\n",
- strerror(errno));
- }
-
- DEBUG_WRAP(DebugMessage(DEBUG_INIT,"chdir success (%s)\n",
- CurrentWorkingDir()););
-
-
- if(strncmp(absdir, logdir, strlen(absdir)))
- {
- FatalError("Absdir is not a subset of the logdir");
- }
-
- if(abslen >= strlen(logdir))
- {
- *logstore = SnortStrdup("/");
- }
- else
- {
- *logstore = SnortStrdup(logdir + abslen);
- }
-
- DEBUG_WRAP(DebugMessage(DEBUG_INIT,"new logdir from %s to %s\n",
- logdir, *logstore));
-
- LogMessage("Chroot directory = %s\n", directory);
-
-#if 0
- /* XXX XXX */
- /* install the I can't do this signal handler */
- signal(SIGHUP, SigCantHupHandler);
-#endif
-#endif /* !WIN32 */
-}
-
-
-/**
- * Return a ptr to the absolute pathname of snort. This memory must
- * be copied to another region if you wish to save it for later use.
- */
-char *CurrentWorkingDir(void)
-{
- static char buf[PATH_MAX_UTIL + 1];
-
- if(getcwd((char *) buf, PATH_MAX_UTIL) == NULL)
- {
- return NULL;
- }
-
- buf[PATH_MAX_UTIL] = '\0';
-
- return (char *) buf;
-}
-
-/**
- * Given a directory name, return a ptr to a static
- */
-char *GetAbsolutePath(char *dir)
-{
- char *savedir, *dirp;
- static char buf[PATH_MAX_UTIL + 1];
-
- if(dir == NULL)
- {
- return NULL;
- }
-
- savedir = strdup(CurrentWorkingDir());
-
- if(savedir == NULL)
- {
- return NULL;
- }
-
- if(chdir(dir) < 0)
- {
- LogMessage("Can't change to directory: %s\n", dir);
- free(savedir);
- return NULL;
- }
-
- dirp = CurrentWorkingDir();
-
- if(dirp == NULL)
- {
- LogMessage("Unable to access current directory\n");
- free(savedir);
- return NULL;
- }
- else
- {
- strncpy(buf, dirp, PATH_MAX_UTIL);
- buf[PATH_MAX_UTIL] = '\0';
- }
-
- if(chdir(savedir) < 0)
- {
- LogMessage("Can't change back to directory: %s\n", dir);
- free(savedir);
- return NULL;
- }
-
- free(savedir);
- return (char *) buf;
-}
-
-
-#ifndef WIN32
-/* very slow sort - do not use at runtime! */
-SF_LIST * SortDirectory(const char *path)
-{
- SF_LIST *dir_entries;
- DIR *dir;
- struct dirent *direntry;
- int ret = 0;
-
- if (path == NULL)
- return NULL;
-
- dir_entries = sflist_new();
- if (dir_entries == NULL)
- {
- ErrorMessage("Could not allocate new list for directory entries\n");
- return NULL;
- }
-
- dir = opendir(path);
- if (dir == NULL)
- {
- ErrorMessage("Error opening directory: %s: %s\n",
- path, strerror(errno));
- sflist_free_all(dir_entries, free);
- return NULL;
- }
-
- /* Reset errno since we'll be checking it unconditionally */
- errno = 0;
-
- while ((direntry = readdir(dir)) != NULL)
- {
- char *node_entry_name, *dir_entry_name;
- SF_LNODE *node;
-
- dir_entry_name = SnortStrdup(direntry->d_name);
-
- for (node = sflist_first_node(dir_entries);
- node != NULL;
- node = sflist_next_node(dir_entries))
- {
- node_entry_name = (char *)node->ndata;
- if (strcmp(dir_entry_name, node_entry_name) < 0)
- break;
- }
-
- if (node == NULL)
- ret = sflist_add_tail(dir_entries, (NODE_DATA)dir_entry_name);
- else
- ret = sflist_add_before(dir_entries, node, (NODE_DATA)dir_entry_name);
-
- if (ret == -1)
- {
- ErrorMessage("Error adding directory entry to list\n");
- sflist_free_all(dir_entries, free);
- closedir(dir);
- return NULL;
- }
- }
-
- if (errno != 0)
- {
- ErrorMessage("Error reading directory: %s: %s\n",
- path, strerror(errno));
- errno = 0;
- sflist_free_all(dir_entries, free);
- closedir(dir);
- return NULL;
- }
-
- closedir(dir);
-
- return dir_entries;
-}
-
-int GetFilesUnderDir(const char *path, SF_QUEUE *dir_queue, const char *filter)
-{
- SF_LIST *dir_entries;
- char *direntry;
- int ret = 0;
- int num_files = 0;
-
- if ((path == NULL) || (dir_queue == NULL))
- return -1;
-
- dir_entries = SortDirectory(path);
- if (dir_entries == NULL)
- {
- ErrorMessage("Error sorting entries in directory: %s\n", path);
- return -1;
- }
-
- for (direntry = (char *)sflist_first(dir_entries);
- direntry != NULL;
- direntry = (char *)sflist_next(dir_entries))
- {
- char path_buf[PATH_MAX];
- struct stat file_stat;
-
- /* Don't look at dot files */
- if (strncmp(".", direntry, 1) == 0)
- continue;
-
- ret = SnortSnprintf(path_buf, PATH_MAX, "%s%s%s",
- path, path[strlen(path) - 1] == '/' ? "" : "/", direntry);
- if (ret == SNORT_SNPRINTF_TRUNCATION)
- {
- ErrorMessage("Error copying file to buffer: Path too long\n");
- sflist_free_all(dir_entries, free);
- return -1;
- }
- else if (ret != SNORT_SNPRINTF_SUCCESS)
- {
- ErrorMessage("Error copying file to buffer\n");
- sflist_free_all(dir_entries, free);
- return -1;
- }
-
- ret = stat(path_buf, &file_stat);
- if (ret == -1)
- {
- ErrorMessage("Could not stat file: %s: %s\n",
- path_buf, strerror(errno));
- sflist_free_all(dir_entries, free);
- return -1;
- }
-
- if (file_stat.st_mode & S_IFDIR)
- {
- ret = GetFilesUnderDir(path_buf, dir_queue, filter);
- if (ret == -1)
- {
- sflist_free_all(dir_entries, free);
- return -1;
- }
-
- num_files += ret;
- }
- else if (file_stat.st_mode & S_IFREG)
- {
- if ((filter == NULL) || (fnmatch(filter, direntry, 0) == 0))
- {
- char *file = SnortStrdup(path_buf);
-
- ret = sfqueue_add(dir_queue, (NODE_DATA)file);
- if (ret == -1)
- {
- ErrorMessage("Could not append item to list: %s\n", file);
- free(file);
- sflist_free_all(dir_entries, free);
- return -1;
- }
-
- num_files++;
- }
- }
- }
-
- sflist_free_all(dir_entries, free);
-
- return num_files;
-}
-#endif
-
-/****************************************************************************
- *
- * Function: GetUniqueName(char * iface)
- *
- * Purpose: To return a string that has a high probability of being unique
- * for a given sensor.
- *
- * Arguments: char * iface - The network interface you are sniffing
- *
- * Returns: A char * -- its a static char * so you should not free it
- *
- ***************************************************************************/
-char *GetUniqueName(char * iface)
-{
- char * rptr;
- static char uniq_name[256];
-
- if (iface == NULL) LogMessage("Interface is NULL. Name may not be unique for the host\n");
-#ifndef WIN32
- rptr = GetIP(iface);
- if(rptr == NULL || !strcmp(rptr, "unknown"))
-#endif
- {
- SnortSnprintf(uniq_name, 255, "%s:%s\n",GetHostname(),iface);
- rptr = uniq_name;
- }
- if (ScLogVerbose()) LogMessage("Node unique name is: %s\n", rptr);
- return rptr;
-}
-
-/****************************************************************************
- *
- * Function: GetIP(char * iface)
- *
- * Purpose: To return a string representing the IP address for an interface
- *
- * Arguments: char * iface - The network interface you want to find an IP
- * address for.
- *
- * Returns: A char * -- make sure you call free on this when you are done
- * with it.
- *
- ***************************************************************************/
-char *GetIP(char * iface)
-{
- struct ifreq ifr;
- struct sockaddr_in *addr;
- int s;
-#ifdef SUP_IP6
- sfip_t ret;
-#endif
-
- if(iface)
- {
- /* Set up a dummy socket just so we can use ioctl to find the
- ip address of the interface */
- s = socket(PF_INET, SOCK_DGRAM, 0);
- if(s == -1)
- {
- FatalError("Problem establishing socket to find IP address for interface: %s\n", iface);
- }
-
- SnortStrncpy(ifr.ifr_name, iface, strlen(iface) + 1);
-
-#ifndef WIN32
- if(ioctl(s, SIOCGIFADDR, &ifr) < 0) return NULL;
- else
-#endif
- {
- addr = (struct sockaddr_in *) &ifr.ifr_broadaddr;
- }
- close(s);
-
-#ifdef SUP_IP6
-// XXX-IPv6 uses ioctl to populate a sockaddr_in structure ... but what if the interface only has an IPv6 address?
- sfip_set_raw(&ret, addr, AF_INET);
- return SnortStrdup(sfip_ntoa(&ret));
-#else
- return SnortStrdup(inet_ntoa(addr->sin_addr));
-#endif
- }
- else
- {
- return "unknown";
- }
-}
-
-/****************************************************************************
- *
- * Function: GetHostname()
- *
- * Purpose: To return a string representing the hostname
- *
- * Arguments: None
- *
- * Returns: A static char * representing the hostname.
- *
- ***************************************************************************/
-char *GetHostname(void)
-{
-#ifdef WIN32
- DWORD bufflen = 256;
- static char buff[256];
- GetComputerName(buff, &bufflen);
- return buff;
-#else
- char * error = "unknown";
- if(getenv("HOSTNAME")) return getenv("HOSTNAME");
- else if(getenv("HOST")) return getenv("HOST");
- else return error;
-#endif
-}
-
-/****************************************************************************
- *
- * Function: GetTimestamp(register const struct timeval *tvp, int tz)
- *
- * Purpose: Get an ISO-8601 formatted timestamp for tvp within the tz
- * timezone.
- *
- * Arguments: tvp is a timeval pointer. tz is a timezone.
- *
- * Returns: char * -- You must free this char * when you are done with it.
- *
- ***************************************************************************/
-char *GetTimestamp(register const struct timeval *tvp, int tz)
-{
- struct tm *lt; /* localtime */
- char * buf;
- int msec;
-
- buf = (char *)SnortAlloc(SMALLBUFFER * sizeof(char));
-
- msec = tvp->tv_usec / 1000;
-
- if (ScOutputUseUtc())
- {
- lt = gmtime((time_t *)&tvp->tv_sec);
- SnortSnprintf(buf, SMALLBUFFER, "%04i-%02i-%02i %02i:%02i:%02i.%03i",
- 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
- lt->tm_hour, lt->tm_min, lt->tm_sec, msec);
- }
- else
- {
- lt = localtime((time_t *)&tvp->tv_sec);
- SnortSnprintf(buf, SMALLBUFFER,
- "%04i-%02i-%02i %02i:%02i:%02i.%03i+%03i",
- 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
- lt->tm_hour, lt->tm_min, lt->tm_sec, msec, tz);
- }
-
- return buf;
-}
-
-/****************************************************************************
- *
- * Function: GetLocalTimezone()
- *
- * Purpose: Find the offset from GMT for current host
- *
- * Arguments: none
- *
- * Returns: int representing the offset from GMT
- *
- ***************************************************************************/
-int GetLocalTimezone(void)
-{
- time_t ut;
- struct tm * ltm;
- long seconds_away_from_utc;
-
- time(&ut);
- ltm = localtime(&ut);
-
-#if defined(WIN32) || defined(SOLARIS) || defined(AIX) || defined(HPUX)
- /* localtime() sets the global timezone variable,
- which is defined in <time.h> */
- seconds_away_from_utc = timezone;
-#else
- seconds_away_from_utc = ltm->tm_gmtoff;
-#endif
-
- return seconds_away_from_utc/3600;
-}
-
-/****************************************************************************
- *
- * Function: GetCurrentTimestamp()
- *
- * Purpose: Generate an ISO-8601 formatted timestamp for the current time.
- *
- * Arguments: none
- *
- * Returns: char * -- You must free this char * when you are done with it.
- *
- ***************************************************************************/
-char *GetCurrentTimestamp(void)
-{
- struct tm *lt;
- struct timezone tz;
- struct timeval tv;
- struct timeval *tvp;
- char * buf;
- int tzone;
- int msec;
-
- buf = (char *)SnortAlloc(SMALLBUFFER * sizeof(char));
-
- bzero((char *)&tz,sizeof(tz));
- gettimeofday(&tv,&tz);
- tvp = &tv;
-
- msec = tvp->tv_usec/1000;
-
- if (ScOutputUseUtc())
- {
- lt = gmtime((time_t *)&tvp->tv_sec);
- SnortSnprintf(buf, SMALLBUFFER, "%04i-%02i-%02i %02i:%02i:%02i.%03i",
- 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
- lt->tm_hour, lt->tm_min, lt->tm_sec, msec);
- }
- else
- {
- lt = localtime((time_t *)&tvp->tv_sec);
-
- tzone = GetLocalTimezone();
-
- SnortSnprintf(buf, SMALLBUFFER,
- "%04i-%02i-%02i %02i:%02i:%02i.%03i+%03i",
- 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday,
- lt->tm_hour, lt->tm_min, lt->tm_sec, msec, tzone);
- }
-
- return buf;
-}
-
-/****************************************************************************
- * Function: base64(char * xdata, int length)
- *
- * Purpose: Insert data into the database
- *
- * Arguments: xdata => pointer to data to base64 encode
- * length => how much data to encode
- *
- * Make sure you allocate memory for the output before you pass
- * the output pointer into this function. You should allocate
- * (1.5 * length) bytes to be safe.
- *
- * Returns: data base64 encoded as a char *
- *
- ***************************************************************************/
-char * base64(const u_char * xdata, int length)
-{
- int count, cols, bits, c, char_count;
- unsigned char alpha[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /* 64 bytes */
- char * payloadptr;
- char * output;
- char_count = 0;
- bits = 0;
- cols = 0;
-
- output = (char *)SnortAlloc( ((unsigned int) (length * 1.5 + 4)) * sizeof(char) );
-
- payloadptr = output;
-
- for(count = 0; count < length; count++)
- {
- c = xdata[count];
-
- if(c > 255)
- {
- ErrorMessage("plugbase.c->base64(): encountered char > 255 (decimal %d)\n If you see this error message a char is more than one byte on your machine\n This means your base64 results can not be trusted", c);
- }
-
- bits += c;
- char_count++;
-
- if(char_count == 3)
- {
- *output = alpha[bits >> 18]; output++;
- *output = alpha[(bits >> 12) & 0x3f]; output++;
- *output = alpha[(bits >> 6) & 0x3f]; output++;
- *output = alpha[bits & 0x3f]; output++;
- cols += 4;
- if(cols == 72)
- {
- *output = '\n'; output++;
- cols = 0;
- }
- bits = 0;
- char_count = 0;
- }
- else
- {
- bits <<= 8;
- }
- }
-
- if(char_count != 0)
- {
- bits <<= 16 - (8 * char_count);
- *output = alpha[bits >> 18]; output++;
- *output = alpha[(bits >> 12) & 0x3f]; output++;
- if(char_count == 1)
- {
- *output = '='; output++;
- *output = '='; output++;
- }
- else
- {
- *output = alpha[(bits >> 6) & 0x3f];
- output++; *output = '=';
- output++;
- }
- }
- *output = '\0';
- return payloadptr;
-}
-
-/****************************************************************************
- *
- * Function: ascii(u_char *xdata, int length)
- *
- * Purpose: This function takes takes a buffer "xdata" and its length then
- * returns a string of only the printable ASCII characters.
- *
- * Arguments: xdata is the buffer, length is the length of the buffer in
- * bytes
- *
- * Returns: char * -- You must free this char * when you are done with it.
- *
- ***************************************************************************/
-char *ascii(const u_char *xdata, int length)
-{
- char *d_ptr, *ret_val;
- int i,count = 0;
- int size;
-
- if(xdata == NULL)
- {
- return NULL;
- }
-
- for(i=0;i<length;i++)
- {
- if(xdata[i] == '<')
- count+=4; /* &lt; */
- else if(xdata[i] == '&')
- count+=5; /* &amp; */
- else if(xdata[i] == '>') /* &gt; */
- count += 4;
- }
-
- size = length + count + 1;
- ret_val = (char *) calloc(1,size);
-
- if(ret_val == NULL)
- {
- LogMessage("plugbase.c: ascii(): Out of memory, can't log anything!\n");
- return NULL;
- }
-
- d_ptr = ret_val;
-
- for(i=0;i<length;i++)
- {
- if((xdata[i] > 0x1F) && (xdata[i] < 0x7F))
- {
- if(xdata[i] == '<')
- {
- SnortStrncpy(d_ptr, "&lt;", size - (d_ptr - ret_val));
- d_ptr+=4;
- }
- else if(xdata[i] == '&')
- {
- SnortStrncpy(d_ptr, "&amp;", size - (d_ptr - ret_val));
- d_ptr += 5;
- }
- else if(xdata[i] == '>')
- {
- SnortStrncpy(d_ptr, "&gt;", size - (d_ptr - ret_val));
- d_ptr += 4;
- }
- else
- {
- *d_ptr++ = xdata[i];
- }
- }
- else
- {
- *d_ptr++ = '.';
- }
- }
-
- *d_ptr++ = '\0';
-
- return ret_val;
-}
-
-/****************************************************************************
- *
- * Function: hex(u_char *xdata, int length)
- *
- * Purpose: This function takes takes a buffer "xdata" and its length then
- * returns a string of hex with no spaces
- *
- * Arguments: xdata is the buffer, length is the length of the buffer in
- * bytes
- *
- * Returns: char * -- You must free this char * when you are done with it.
- *
- ***************************************************************************/
-char *hex(const u_char *xdata, int length)
-{
- int x;
- char *rval = NULL;
- char *buf = NULL;
-
- if (xdata == NULL)
- return NULL;
-
- buf = (char *)calloc((length * 2) + 1, sizeof(char));
-
- if (buf != NULL)
- {
- rval = buf;
-
- for (x = 0; x < length; x++)
- {
- SnortSnprintf(buf, 3, "%02X", xdata[x]);
- buf += 2;
- }
-
- rval[length * 2] = '\0';
- }
-
- return rval;
-}
-
-
-
-char *fasthex(const u_char *xdata, int length)
-{
- char conv[] = "0123456789ABCDEF";
- char *retbuf = NULL;
- const u_char *index;
- const u_char *end;
- char *ridx;
-
- index = xdata;
- end = xdata + length;
- retbuf = (char *)SnortAlloc(((length * 2) + 1) * sizeof(char));
- ridx = retbuf;
-
- while(index < end)
- {
- *ridx++ = conv[((*index & 0xFF)>>4)];
- *ridx++ = conv[((*index & 0xFF)&0x0F)];
- index++;
- }
-
- return retbuf;
-}
-
-/*
- * Fatal Integer Parser
- * Ascii to Integer conversion with fatal error support
- */
-long int xatol(const char *s , const char *etext)
-{
- long int val;
- char *endptr;
- char *default_error = "xatol() error\n";
-
- if (etext == NULL)
- etext = default_error;
-
- if (s == NULL)
- FatalError("%s: String is NULL\n", etext);
-
- while (isspace((int)*s))
- s++;
-
- if (strlen(s) == 0)
- FatalError("%s: String is empty\n", etext);
-
-
- /*
- * strtoul - errors on win32 : ERANGE (VS 6.0)
- * errors on linux : ERANGE, EINVAL
- * (for EINVAL, unsupported base which won't happen here)
- */
- val = SnortStrtol(s, &endptr, 0);
-
- if ((errno == ERANGE) || (*endptr != '\0'))
- FatalError("%s: Invalid integer input: %s\n", etext, s);
-
- return val;
-}
-
-/*
- * Fatal Integer Parser
- * Ascii to Integer conversion with fatal error support
- */
-unsigned long int xatou(const char *s , const char *etext)
-{
- unsigned long int val;
- char *endptr;
- char *default_error = "xatou() error\n";
-
- if (etext == NULL)
- etext = default_error;
-
- if (s == NULL)
- FatalError("%s: String is NULL\n", etext);
-
- while (isspace((int)*s))
- s++;
-
- if (strlen(s) == 0)
- FatalError("%s: String is empty\n", etext);
-
- if (*s == '-')
- {
- FatalError("%s: Invalid unsigned integer - negative sign found, "
- "input: %s\n", etext, s);
- }
-
-
- /*
- * strtoul - errors on win32 : ERANGE (VS 6.0)
- * errors on linux : ERANGE, EINVAL
- */
- val = SnortStrtoul(s, &endptr, 0);
-
- if ((errno == ERANGE) || (*endptr != '\0'))
- FatalError("%s: Invalid integer input: %s\n", etext, s);
-
- return val;
-}
-
-unsigned long int xatoup(const char *s , const char *etext)
-{
- unsigned long int val = xatou(s, etext);
- if ( !val )
- FatalError("%s: must be > 0\n", etext);
- return val;
-}
-
-#ifndef SUP_IP6
-char * ObfuscateIpToText(const struct in_addr ip_addr)
-#else
-char * ObfuscateIpToText(sfip_t *ip)
-#endif
-{
- static char ip_buf1[INET6_ADDRSTRLEN];
- static char ip_buf2[INET6_ADDRSTRLEN];
- static int buf_num = 0;
- int buf_size = INET6_ADDRSTRLEN;
- char *ip_buf;
-#ifndef SUP_IP6
- uint32_t ip = ip_addr.s_addr;
-#endif
-
- if (buf_num)
- ip_buf = ip_buf2;
- else
- ip_buf = ip_buf1;
-
- buf_num ^= 1;
- ip_buf[0] = 0;
-
-#ifndef SUP_IP6
- if (ip == 0)
- return ip_buf;
-
- if (snort_conf->obfuscation_net == 0)
- {
- /* Fully obfuscate - just use 'x' */
- SnortSnprintf(ip_buf, buf_size, "xxx.xxx.xxx.xxx");
- }
- else
- {
- if (snort_conf->homenet != 0)
- {
- if ((ip & snort_conf->netmask) == snort_conf->homenet)
- ip = snort_conf->obfuscation_net | (ip & snort_conf->obfuscation_mask);
- }
- else
- {
- ip = snort_conf->obfuscation_net | (ip & snort_conf->obfuscation_mask);
- }
-
- SnortSnprintf(ip_buf, buf_size, "%s", inet_ntoa(*((struct in_addr *)&ip)));
- }
-
-#else
- if (ip == NULL)
- return ip_buf;
-
- if (!IS_SET(snort_conf->obfuscation_net))
- {
- if (IS_IP6(ip))
- SnortSnprintf(ip_buf, buf_size, "x:x:x:x::x:x:x:x");
- else
- SnortSnprintf(ip_buf, buf_size, "xxx.xxx.xxx.xxx");
- }
- else
- {
- sfip_t tmp;
- char *tmp_buf;
-
- IP_COPY_VALUE(tmp, ip);
-
- if (IS_SET(snort_conf->homenet))
- {
- if (sfip_contains(&snort_conf->homenet, &tmp) == SFIP_CONTAINS)
- sfip_obfuscate(&snort_conf->obfuscation_net, &tmp);
- }
- else
- {
- sfip_obfuscate(&snort_conf->obfuscation_net, &tmp);
- }
-
- tmp_buf = sfip_to_str(&tmp);
- SnortSnprintf(ip_buf, buf_size, "%s", tmp_buf);
- }
-#endif
-
- return ip_buf;
-}
-
-void PrintPacketData(const uint8_t *data, const uint32_t len)
-{
- uint32_t i, j;
- uint32_t total_len = 0;
- uint8_t hex_buf[16];
- uint8_t char_buf[16];
- char *length_chars = " 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15\n"
- "------------------------------------------------------\n";
-
- LogMessage("%s", length_chars);
-
- for (i = 0; i <= len; i++)
- {
- if ((i%16 == 0) && (i != 0))
- {
- LogMessage("%04x ", total_len);
- total_len += 16;
-
- for (j = 0; j < 16; j++)
- {
- LogMessage("%02x ", hex_buf[j]);
- if (j == 7)
- LogMessage(" ");
- }
-
- LogMessage(" ");
-
- for (j = 0; j < 16; j++)
- {
- LogMessage("%c", char_buf[j]);
- if (j == 7)
- LogMessage(" ");
- }
-
- LogMessage("\n");
- }
-
- if (i == len)
- break;
-
- hex_buf[i%16] = data[i];
-
- if (isprint((int)data[i]))
- char_buf[i%16] = data[i];
- else
- char_buf[i%16] = '.';
- }
-
- if ((i-total_len) > 0)
- {
- LogMessage("%04x ", total_len);
-
- for (j = 0; j < i-total_len; j++)
- {
- LogMessage("%02x ", hex_buf[j]);
- if (j == 7)
- LogMessage(" ");
- }
-
- if (j < 8)
- LogMessage(" ");
- LogMessage("%*s", (16-j)*3, "");
- LogMessage(" ");
-
- for (j = 0; j < i-total_len; j++)
- {
- LogMessage("%c", char_buf[j]);
- if (j == 7)
- LogMessage(" ");
- }
- }
-
- LogMessage("\n");
-}
-
diff --git a/config/snort-dev/patches/spoink_patch/spo_pf.c b/config/snort-dev/patches/spoink_patch/spo_pf.c
deleted file mode 100644
index 121920fc..00000000
--- a/config/snort-dev/patches/spoink_patch/spo_pf.c
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
-*
-* Copyright (c) 2006 Antonio Benojar <zz.stalker@gmail.com>
-* Copyright (c) 2005 Antonio Benojar <zz.stalker@gmail.com>
-*
-* Copyright (c) 2003, 2004 Armin Wolfermann:
-*
-* s2c_pf_block and s2c_pf_unblock functions are based
-* in Armin's Wolfermann pftabled-1.03 functions.
-*
-* All rights reserved.
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions
-* are met:
-*
-* 1. Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-*
-* 2. Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the distribution.
-*
-* THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
-* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-* IN NO EVENT SHALL THE AUTHOR 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.
-*/
-
-
-/*
- TODO
-
- - num. max ips.
- - ipwhitelisting structure
- - best ip regex expr
-*/
-
-
-#ifndef LIST_END
-#define LIST_END(head) NULL
-#endif
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "event.h"
-#include "decode.h"
-#include "plugbase.h"
-#include "spo_plugbase.h"
-#include "debug.h"
-#include "parser.h"
-#include "util.h"
-#include "log.h"
-#include "mstring.h"
-
-#include "snort.h"
-
-#include "spo_pf.h"
-
-#ifdef HAVE_STRINGS_H
-#include <strings.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <arpa/inet.h>
-#include <errno.h>
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/queue.h>
-#include <ctype.h>
-#include <fcntl.h>
-#include <net/if.h>
-#include <net/pfvar.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <err.h>
-#include <unistd.h>
-#include <regex.h>
-
-#define PFDEVICE "/dev/pf"
-
-typedef struct _SpoAlertPfData {
- FILE *wlfile;
- char *pftable;
- int fd;
- struct wlist_head head;
-} SpoAlertPfData;
-
-void AlertPfInit(u_char *);
-SpoAlertPfData *ParseAlertPfArgs(char *);
-void AlertPf(Packet *, char *, void *, Event *);
-void AlertPfCleanExit(int, void *);
-void AlertPfRestart(int, void *);
-
-int s2c_pf_init(void);
-int s2c_pf_block(int, char *, char *, int);
-int s2c_pf_intbl(int, char *, int);
-
-int s2c_parse_line(char *, FILE*);
-int s2c_parse_load_wl(FILE*, struct wlist_head*, int);
-int s2c_parse_search_wl(char *, struct wlist_head);
-int s2c_parse_free_wl(struct wlist_head*);
-int s2c_parse_ip(char *, char *, int);
-
-
-void AlertPfSetup(void)
-{
- RegisterOutputPlugin("alert_pf", OUTPUT_TYPE_FLAG__ALERT, AlertPfInit);
-
- DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Output plugin: AlertPf is setup...\n"););
-}
-
-void AlertPfInit(u_char *args)
-{
- SpoAlertPfData *data;
- DEBUG_WRAP(DebugMessage(DEBUG_INIT, "Output: AlertPf Initialized\n"););
-
- data = ParseAlertPfArgs(args);
-
- DEBUG_WRAP(DebugMessage(DEBUG_INIT,"Linking AlertPf functions to call lists...\n"););
-
- AddFuncToOutputList(AlertPf, OUTPUT_TYPE_FLAG__ALERT, data);
- AddFuncToCleanExitList(AlertPfCleanExit, data);
- AddFuncToRestartList(AlertPfRestart, data);
-}
-
-
-void AlertPf(Packet *p, char *msg, void *arg, Event *event)
-{
- SpoAlertPfData *data = (SpoAlertPfData *)arg;
- char *ip;
- int ret;
-
- DEBUG_WRAP(DebugMessage(DEBUG_LOG, "spoink block'n!!\n"););
-
- ip = inet_ntoa(p->iph->ip_src);
-
- if (ip == NULL)
- FatalError("AlertPf() => inet_ntoa() = NULL\n", strerror(errno));
-
- ret = s2c_parse_search_wl(ip, data->head);
-
- if (ret == 0)
- s2c_pf_block(data->fd, data->pftable, inet_ntoa(p->iph->ip_src), 0);
-
- return;
-}
-
-SpoAlertPfData *ParseAlertPfArgs(char *args)
-{
- char **toks;
- int num_toks;
- SpoAlertPfData *data;
-
- int res = 0;
-
- data = (SpoAlertPfData *)SnortAlloc(sizeof(SpoAlertPfData));
-
- if(args == NULL)
- FatalError("Unable to load pf args\n", strerror(errno));
-
- data->fd = s2c_pf_init();
-
- if (data->fd == -1)
- FatalError("s2c_pf_init() => no pf device\n");
-
- DEBUG_WRAP(DebugMessage(DEBUG_LOG,"ParseAlertPfArgs: %s\n", args););
-
- toks = mSplit(args, ",", 2, &num_toks, 0);
-
- if(num_toks <= 1)
- FatalError("snort.conf => You must supply TWO arguments for the pf plugin...\n", strerror(errno));
-
- if(strstr(toks[0], "..") != NULL)
- FatalError("snort.conf => File definition contains \"..\". Do not do that!\n");
-
- data->wlfile = fopen(toks[0], "r");
-
- if (data->wlfile == NULL)
- FatalError("snort.conf => Unable to open whitelist file\n", strerror(errno));
-
- if (toks[1] == NULL)
- FatalError("snort.conf => No pf table defined\n", strerror(errno));
- else
- data->pftable = toks[1];
-
- if (s2c_pf_intbl(data->fd, data->pftable, 0) == 0)
- FatalError("pf.conf => Table %s don't exists in packet filter\n", data->pftable, strerror(errno));
-
- res = s2c_parse_load_wl(data->wlfile, &data->head, 0);
- if (res == -1)
- FatalError("snort.conf => Unable to load whitelist\n", strerror(errno));
-
- return data;
-}
-
-void AlertPfCleanExit(int signal, void *arg)
-{
- SpoAlertPfData *data = (SpoAlertPfData *)arg;
- DEBUG_WRAP(DebugMessage(DEBUG_LOG,"AlertPfCleanExit\n"););
-
- s2c_parse_free_wl(&data->head);
- fclose(data->wlfile);
- close(data->fd);
-
- free(data);
-}
-
-void AlertPfRestart(int signal, void *arg)
-{
- SpoAlertPfData *data = (SpoAlertPfData *)arg;
- DEBUG_WRAP(DebugMessage(DEBUG_LOG,"AlertPfRestart\n"););
-
- s2c_parse_free_wl(&data->head);
- fclose(data->wlfile);
- close(data->fd);
-
- free(data);
-}
-
-
-int s2c_pf_init(void)
-{
- return(open(PFDEVICE, O_RDWR));
-}
-
-int s2c_pf_block(int dev, char *tablename, char *ip, int debug)
-{
-
- struct pfioc_table io;
- struct pfr_table table;
- struct pfr_addr addr;
- struct in_addr *net_addr=NULL;
-
- memset(&io, 0x00, sizeof(struct pfioc_table));
- memset(&table, 0x00, sizeof(struct pfr_table));
- memset(&addr, 0x00, sizeof(struct pfr_addr));
-
- strlcpy(table.pfrt_name, tablename, PF_TABLE_NAME_SIZE);
- net_addr=(struct in_addr*)malloc(sizeof(struct in_addr));
-
- if (net_addr == NULL )
- FatalError("s2c_pf_block() => malloc()\n", strerror(errno));
-
- inet_aton(ip, (struct in_addr *)&net_addr);
- memcpy(&addr.pfra_ip4addr.s_addr, &net_addr, sizeof(struct in_addr));
-
- addr.pfra_af = AF_INET;
- addr.pfra_net = 32;
-
- io.pfrio_table = table;
- io.pfrio_buffer = &addr;
- io.pfrio_esize = sizeof(struct pfr_addr);
- io.pfrio_size = 1;
-
- if (ioctl(dev, DIOCRADDADDRS, &io))
- FatalError("s2c_pf_block() => ioctl() DIOCRADDADDRS\n", strerror(errno));
-
- return(0);
-}
-
-int s2c_pf_intbl(int dev, char * tablename, int debug)
-{
- int i;
- struct pfioc_table io;
- struct pfr_table *table_aux = NULL;
-
- memset(&io, 0x00, sizeof(struct pfioc_table));
-
- io.pfrio_buffer = table_aux;
- io.pfrio_esize = sizeof(struct pfr_table);
- io.pfrio_size = 0;
-
- if(ioctl(dev, DIOCRGETTABLES, &io))
- FatalError("s2c_pf_intbl() => ioctl() DIOCRGETTABLES\n", strerror(errno));
-
- table_aux = (struct pfr_table*)malloc(sizeof(struct pfr_table)*io.pfrio_size);
-
- if (table_aux == NULL)
- FatalError("s2c_pf_intbl() => malloc()\n", strerror(errno));
-
- io.pfrio_buffer = table_aux;
- io.pfrio_esize = sizeof(struct pfr_table);
-
- if(ioctl(dev, DIOCRGETTABLES, &io))
- FatalError("s2c_pf_intbl() => ioctl() DIOCRGETTABLES\n", strerror(errno));
-
- for(i=0; i< io.pfrio_size; i++) {
- if (!strcmp(table_aux[i].pfrt_name, tablename))
- return 1;
- }
-
- return 0;
-
-}
-
-
-int s2c_parse_line(char buf[WLMAX] , FILE* wfile)
-{
- static char next_ch = ' ';
- int i = 0;
-
- if (feof(wfile)) {
- return (0);
- }
- do {
- next_ch = fgetc(wfile);
- if (i < WLMAX)
- buf[i++] = next_ch;
- } while (!feof(wfile) && !isspace(next_ch));
- if (i >= WLMAX) {
- return (-1);
- }
-
- buf[i] = '\0';
- return (1);
-}
-
-
-int s2c_parse_load_wl(FILE *wfile, struct wlist_head *head, int debug)
-{
-
- char cad[WLMAX];
- char ret[WLMAX];
- struct ipwlist *ipw2, *ipw1 = NULL;
- struct flock lock;
-
- if (wfile == NULL)
- FatalError("s2c_parse_load_wl() => Unable to open whitelist file\n", strerror(errno));
-
- memset(&lock, 0x00, sizeof(struct flock));
- lock.l_type = F_RDLCK;
- fcntl(fileno(wfile), F_SETLKW, &lock);
-
- LIST_INIT(head);
-
- if (s2c_parse_line(cad, wfile) == 1) {
- if (s2c_parse_ip(cad, ret, debug) == 1) {
- ipw1 = (struct ipwlist*)malloc(sizeof(struct ipwlist));
- if (ipw1 == NULL)
- FatalError("s2c_parse_load_wl() => malloc()\n", strerror(errno));
- inet_aton(ret, &ipw1->waddr);
- LIST_INSERT_HEAD(head, ipw1, elem);
-
- } else {
- FatalError("s2c_parse_load_wl() => Invalid data in whitelist file\n", strerror(errno));
- }
- }
-
- while(s2c_parse_line(cad, wfile) == 1) {
- if (s2c_parse_ip(cad, ret, debug) == 1) {
- ipw2 = (struct ipwlist*)malloc(sizeof(struct ipwlist));
- if (ipw2 == NULL)
- FatalError("s2c_parse_load_wl() => malloc()\n", strerror(errno));
- inet_aton(ret, &ipw2->waddr);
- LIST_INSERT_AFTER(ipw1, ipw2, elem);
- ipw1 = ipw2;
- } else {
- break;
- }
-
- }
-
- lock.l_type = F_UNLCK;
- fcntl(fileno(wfile), F_SETLKW, &lock);
-
- return (0);
-}
-
-/* XXX: optimize */
-
-int
-s2c_parse_search_wl(char *ip, struct wlist_head wl)
-{
- struct ipwlist *aux2;
- char *ip_aux, ip1[IPMAX], ip2[IPMAX];
- int ret;
-
- strlcpy(ip1, ip, sizeof(ip1));
-
- for(aux2=wl.lh_first; aux2 !=NULL; aux2=aux2->elem.le_next) {
- ip_aux = inet_ntoa(aux2->waddr);
- strlcpy(ip2, ip_aux, sizeof(ip2));
- ret = strcmp(ip1, ip2);
-
- if (ret == 0)
- return 1;
- }
- return (0);
-}
-
-
-int s2c_parse_free_wl(struct wlist_head *wl)
-{
- struct ipwlist *aux, *aux2;
- for(aux = LIST_FIRST(wl); aux != LIST_END(wl); aux = aux2) {
- aux2 = LIST_NEXT(aux, elem);
- LIST_REMOVE(aux, elem);
- free(aux);
- }
- if (LIST_EMPTY(wl)) {
- return (1);
- } else {
- FatalError("s2c_parse_free_wl() => Unable to free whitelist\n", strerror(errno));
- return (0);
- }
-}
-
-/* XXX: too much complex ? */
-
-int s2c_parse_ip(char *cad, char ret[WLMAX], int debug)
-{
- int len;
- unsigned int enc=1;
- regex_t *expr;
- regmatch_t *resultado;
- expr = (regex_t*)malloc(sizeof(regex_t));
-
- bzero(ret, WLMAX);
-
- if (expr == NULL)
- FatalError("s2c_parse_ip() => malloc()\n", strerror(errno));
-
- resultado = (regmatch_t*)malloc(sizeof(regmatch_t));
-
- if (resultado == NULL)
- FatalError("s2c_parse_ip() => malloc()\n", strerror(errno));
-
- if (regcomp(expr, REG_ADDR, REG_EXTENDED) !=0)
- FatalError("s2c_parse_ip() => regcomp()\n", strerror(errno));
-
- if (regexec(expr, cad, 1, resultado, 0) !=0)
- enc=0;
-
- if (enc !=0) {
- len = resultado->rm_eo - resultado->rm_so;
- memcpy(ret, cad + resultado->rm_so, len);
- ret[len]='\0';
- }
-
- free(resultado);
- regfree(expr);
-
- if(enc)
- return (1);
- else {
- errno = EINVAL;
- return (0);
- }
-}
diff --git a/config/snort-dev/patches/spoink_patch/spo_pf.h b/config/snort-dev/patches/spoink_patch/spo_pf.h
deleted file mode 100644
index af07dacd..00000000
--- a/config/snort-dev/patches/spoink_patch/spo_pf.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
-*
-* Copyright (c) 2006 Antonio Benojar <zz.stalker@gmail.com>
-* Copyright (c) 2005 Antonio Benojar <zz.stalker@gmail.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:
-*
-* 1. Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-*
-* 2. Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the distribution.
-*
-* THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS OR
-* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-* IN NO EVENT SHALL THE AUTHOR 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.
-*/
-
-#ifndef __SPO_PF_H__
-#define __SPO_PF_H__
-
-#include <sys/queue.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include <sys/socket.h>
-#include <fcntl.h>
-#include <net/if.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <stdio.h>
-
-#define WLMAX 1024
-#define IPMAX 20
-#define REG_ADDR "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}"
-
-
-struct ipwlist {
- struct in_addr waddr;
- LIST_ENTRY(ipwlist) elem;
-};
-
-LIST_HEAD(wlist_head, ipwlist);
-
-void AlertPfSetup(void);
-
-#endif
-
-