logo The Libebox Intrusion Detection Library Get libebox Intrusion Detection Library at SourceForge.net. Fast, secure and Free Open Source software downloads

» Libebox Can be downloaded @ sourceforge.net

» Page last updated: Mon May 11 15:07:44 EDT 2009

Libebox library (toolkit) allows the application programmer to easily capture, classify and detect anomalies in network traffic.
It allows a programmer to capture all protocols and pass that information into user designed functions,
for easy proc essing and detection of errors and attempts to evade, interrupt and or intrude into netwok systems.
Most complex network programs can be rewritten with libebox with ease and simplicity.
There are a myriad of functions for detection and for parsing and displaying captured information.
And gives the programmer the functionality to override/replace/add to any protocol decoder

Libebox-Traffic Phases:

START_UP PKT_PHASE ALL_PHASE ETHER_PHASE IPV4_PHASE
TCP_PHASE UDP_PHASE PPPOE_PHASE IPV4_FRAG_PHASE IPV6_PHASE
ARP_PHASE IPX_PHASE MPLS_PHASE Q8021Q_PHASE JUMBO_PHASE
ISOCLNS_PHASE EAP_PHASE PPP_PHASE SLOW_PHASE CDP_PHASE
LOOP_PHASE PPP_ENCAP_PHASE IEEE802_PHASE CHDLC_PHASE FDDI_PHASE
TOKEN_PHASE SLL_PHASE ARCNET_PHASE ARCNET_LNX_PHASE LANE_PHASE
CIP_PHASE SL_PHASE SL_B_PHASE FR_PHASE SUNATM_PHASE
PRISIM_PHASE IEE802_11_RADIO_PHASE ENCAP_PHASE ATM_PHASE AP1394_PHASE
IPFC_PHASE SCTP_PHASE IGRP_PHASE EGP_PHASE OSPF4_PHASE
OSPF6_PHASE IGMP_PHASE RSVP_PHASE GRE_PHASE MOBILE_PHASE
VRRP_PHASE VLAN_PHASE RAWPKT_PHASE
RAWIP_PHASE I4L_PHASE
ICMP4_PHASE STP_PHASE PIM_PHASE AH_PHASE IPCOMP_PHASE
ESP_PHASE DCCP_PHASE UDP6_PHASE MOBL_PHASE IP6_ROUTE_PHASE
IP6_FRAG_PHASE ICMP6_PHASE TCP6_PHASE
STREAM_PHASE EBOX_S5_PHASE
SNORT_S5_PHASE




» Libebox is distrubuted under the GNU license.


» An Incomplete (and slighlty out of date) Man-Page. Updated Documentaion to follow soon.

» Writing code with libebox.

» Example Of Writing engine module for libebox.

» Example Of Writing parser module for libebox.



» Libebox was designed and is maintained by Garrick Hermitt-Barrett.

 I can be reached here contact me here




Libebox supports modules {engines and parsers} that can be written and later loaded by an application.
» Currently distributed modules:
Engines:

  engines/libpkttimer.so packet timer engine
  engines/libsnipcopy.so load snort ip copy util
  engines/libstats.so simple stats engine
  engines/libfr.so frame relay engine
  engines/libap1394.so apple ap1394 engine
  engines/libarcnet.so arcnet engine
  engines/libatm.so atm engine
  engines/libcip.so cip engine
  engines/libenc.so enc engine
  engines/libipfc.so ipfc engine
  engines/libsunatm.so sunatm engine
  engines/libsl.so sl engine
  engines/libdccp.so dccp engine
  engines/libipv4frag.so ipv4 frag engine
  engines/libfingeros.so finger os engine -- tcp only
  engines/libscan.so simple scan engine
  engines/libaltbuffer.so altbuffer storage
  engines/libstream5e.so snort stream5e engine uses ParserPkt
  engines/libipv6frag.so ipv6 frag engine
  engines/libconficker.so load conficker detection utility
  engines/snort/libsn_stream5.so snort stream5 engine uses a cropped SnortPacket
  engines/snort/libsn_ftptelnet.so snort ftptelnet engine
  engines/snort/libsn_searchapi.so snort search api
  engines/snort/libsn_arpspoof.so snort arpspoof engine
  engines/snort/libsn_frag3.so snort frag3 engine
  engines/snort/libsn_sfpscan.so snort sf portscan engine
  engines/snort/libsn_bo.so snort bo engine
  engines/snort/libsn_rpc.so snort rpc engine
  engines/snort/libsn_http1.so snort simple http engine
  engines/snort/libsn_ssh.so snort ssh engine
  engines/snort/libsn_smtp.so snort smtp engine
  engines/snort/libsn_dns.so snort dns engine
  engines/snort/libsn_dcerpc.so snort dcerpc engine

Parsers: ** These are only distributed to test the api ** they provide no other relevant functionality

  parsers/libether_psr.so ethernet parser
  parsers/libipv4_psr.so ipv4 parser
  parsers/libsearchtest_psr.so snort search api test





Current 2.0.1 Tree

» Latest Stable Version: 2.0.1-rc3

» Libebox 2.0.1 supported protocols/detectioin modes

Basic warn types: {Class}

IDS_WARN_ETH IDS_WARN_IP IDS_WARN_IP6 IDS_WARN_IP6_OPT IDS_WARN_IP6_FRAG IDS_WARN_ICMP6
IDS_WARN_TCP IDS_WARN_UDP IDS_WARN_SCAN IDS_WARN_OSPF IDS_WARN_OSPF6 IDS_WARN_RT6
IDS_WARN_IPCOMP IDS_WARN_AH IDS_WARN_ESP IDS_WARN_IGRP IDS_WARN_IGMP IDS_WARN_EGP
IDS_WARN_GRE IDS_WARN_MOBILE IDS_WARN_VRRP IDS_WARN_SCTP IDS_WARN_PIM IDS_WARN_IPX
IDS_WARN_VLAN IDS_WARN_PPPoE IDS_WARN_ARP IDS_WARN_ATMARP IDS_WARN_IEEE_802 IDS_WARN_MOBILITY
IDS_WARN_RSVP IDS_WARN_MPLS IDS_WARN_TCPen6 IDS_WARN_UDPen6 IDS_WARN_ICMP IDS_WARN_TOKEN
IDS_WARN_FDDI IDS_WARN_TCPSTREAM IDS_WARN_CDP IDS_WARN_STP IDS_WARN_ISOCLNS IDS_WARN_CHDLC
IDS_WARN_ARCNET IDS_WARN_ARCNET_LINUX IDS_WARN_80211_RADIO IDS_WARN_PRISM IDS_WARN_FIREWIRE IDS_WARN_CIP
IDS_WARN_FR IDS_WARN_LANE IDS_WARN_IPFC IDS_WARN_SLIP IDS_WARN_SUNATM IDS_WARN_ENC
IDS_WARN_LLC IDS_WARN_ATM IDS_WARN_SLOW IDS_WARN_SNAP IDS_WARN_SMB IDS_WARN_DCCP
IDS_WARN_RPC IDS_WARN_SSH IDS_WARN_DVMRP

Basic warn types: {Errors}:
IDS_WARN_UNDEFINED IDS_WARN_ETH_HDR_LEN IDS_WARN_IP_OVERSIZED
IDS_WARN_IP_TSERROR IDS_WARN_TRUNCATED_IP IDS_WARN_IP_OPTS
IDS_WARN_IP_OPTS_TRUNC IDS_WARN_IP_INVLIST IDS_WARN_IP_OVERLAP
IDS_WARN_IP_HDR IDS_WARN_IP_SRR IDS_WARN_IP_MAX_PORTS
IDS_WARN_IP6_HDRLEN IDS_WARN_IP6_LEN IDS_WARN_IP6_SAMEIP
IDS_WARN_IP6_HBHOPT IDS_WARN_IP6_DSTOPT IDS_WARN_IP6_SOPT_DECODE
IDS_WARN_IP6_OPTS_DECODE IDS_WARN_IP6_OVERSIZED_PKT IDS_WARN_IP6_FRAG_OFF
IDS_WARN_IP6_FRAG_HDRERROR IDS_WARN_IP6_FRAG_ROUNDED_ERROR IDS_WARN_IP6_FRAG_NOTFRAG
IDS_WARN_ICMP6_HDRLEN IDS_WARN_ICMP6_HDR IDS_WARN_ICMP6_OPTS
IDS_WARN_ICMP6_CSUM IDS_WARN_ICMP6_RRENUM IDS_WARN_ICMP6_V2MEMB
IDS_WARN_ICMP6_NIINFO IDS_WARN_TCP_TOOMUCH IDS_WARN_TCP_HDR
IDS_WARN_TCP_BIGQUEUE IDS_WARN_TCP_BADFLAGS IDS_WARN_TCP_EXPR_TCPOPTS
IDS_WARN_TCP_OBSL_TCPOPTS IDS_WARN_TCP_BAD_OPTS_TTCP IDS_WARN_TCP_BAD_TCPOPTS
IDS_WARN_TCP_BAD_SACK_OPTS IDS_WARN_OSPF_LEN IDS_WARN_OSPF_HDR
IDS_WARN_OSPF6_LEN IDS_WARN_OSPF6_HDR IDS_WARN_RT6_HDR
IDS_WARN_IPCOMP_HDR IDS_WARN_AH_HDR IDS_WARN_ESP_HDR
IDS_WARN_IGRP_HDR IDS_WARN_EGP_VER IDS_WARN_EGP_HDR
IDS_WARN_IGMP_HDR IDS_WARN_IGMP_SUM IDS_WARN_GRE_HDR
IDS_WARN_GRE_UNKNOW_VER IDS_WARN_GRE_VER0_ERROR IDS_WARN_GRE_VER1_ERROR
IDS_WARN_MOBILE_CSUM IDS_WARN_MOBILE_SIZE IDS_WARN_VRRP_CSUM
IDS_WARN_VRRP_HDR IDS_WARN_SCTP_LEN IDS_WARN_SCTP_HDR
IDS_WARN_PIM_HDR IDS_WARN_PIM_LEN IDS_WARN_IPX_HDR
IDS_WARN_VLAN_HDR IDS_WARN_VLAN_LEN IDS_WARN_PPPoE_HDR
IDS_WARN_ARP_HDR IDS_WARN_ARP_HDR_LEN IDS_WARN_ARP_REQUEST
IDS_WARN_ARP_MISMATCH_S IDS_WARN_ARP_MISMATCH_D IDS_WARN_ARP_OVERWRITE
IDS_WARN_ATMARP_HDR IDS_WARN_ATMARP_LEN IDS_WARN_IEEE_802_LEN
IDS_WARN_IEEE_802_HDR IDS_WARN_IEEE_802_DATA_LEN IDS_WARN_MOBILITY_HDR
IDS_WARN_MOBILITY_OPTS IDS_WARN_RSVP_VER IDS_WARN_RSVP_COM_HDR
IDS_WARN_RSVP_HDR IDS_WARN_SCAN_DETECT IDS_WARN_SCAN_DETECTV6
IDS_WARN_UDP_HDR_LEN IDS_WARN_UDP_HDR_TOO_SMALL IDS_WARN_UDP_SMALL_ULEN
IDS_WARN_UDP_HDR_LEN_ULEN IDS_WARN_UDP_HDR_CHKSUM IDS_WARN_BO_TRAFFIC
IDS_WARN_MPLS_HDR IDS_WARN_TCPen6_HDR IDS_WARN_UDPen6_HDR
IDS_WARN_UDPen6_SUM IDS_WARN_ICMP_HDR IDS_WARN_TOKEN_HDR
IDS_WARN_TOKEN_SNAP IDS_WARN_FDDI_HDR IDS_WARN_STREAM_EVASIVE_RETRANS
IDS_WARN_STREAM_WINDOW_VIOLATION IDS_WARN_STREAM_DATA_ON_SYNPKT IDS_WARN_STREAM_EVASION_ATTEMPT
IDS_WARN_STREAM_STEALTHNMAP_FINGERPRINT IDS_WARN_STREAM_STEALTHACTIVITY IDS_WARN_STREAM_STEALTH_FULL_XMAS
IDS_WARN_STREAM_STEALTH_SAPU IDS_WARN_STREAM_STEALTH_FINS IDS_WARN_STREAM_SYN_FIN_SCAN
IDS_WARN_STREAM_NULL_SCAN IDS_WARN_NMAP_XMAS_SCAN IDS_WARN_STEALTH_VECNA_SCAN
IDS_WARN_EVASIVE_RESET IDS_WARN_STREAM_TTL_EVASION IDS_WARN_STREAM_PAWS_ID
IDS_WARN_STREAM_HIJACKING IDS_WARN_STREAM_INVALID_OFFSET IDS_WARN_STREAM_LARGE_OFFSET
IDS_WARN_STREAM_IP4_SAMEIP IDS_WARN_STREAM_INVALID_DATA_LENGTH IDS_WARN_STREAM_INVALID_CKSUM
IDS_WARN_STREAM_WINDOW_SCALE_ERR_RFC1323 IDS_WARN_STREAM_POSSIBLE_TROJAN IDS_WARN_STREAM_OVERLAP_LIMIT
IDS_WARN_STREAM_FORWARD_OVERLAP IDS_WARN_HTTP_LARGE_METH IDS_WARN_HTTP_MISS_URI
IDS_WARN_HTTP_DOUBLE_ENC IDS_WARN_HTTP_ILLEGAL_HEX IDS_WARN_HTTP_OVERLONG_CHAR
IDS_WARN_TCP_NO_ACK IDS_WARN_STREAM_ZERO_TIMESTAMP IDS_WARN_STREAM_EVASIVE_RETRANS_DATAFAST
IDS_WARN_SMTP_PKT IDS_WARN_SMTP_XLINK2 IDS_WARN_CDP_HEADER
IDS_WARN_STP_HEADER_LEN IDS_WARN_STP_VERSION_ERROR IDS_WARN_STP_UNK_VERSION
IDS_WARN_STP_PKT_LENGTH IDS_WARN_ISOCLNS_LENGTH_ERROR IDS_WARN_CHDLC_SLARP_HEADER
IDS_WARN_FRAG3_IPOPTIONS IDS_WARN_FRAG3_ANOMALY_BADSIZE IDS_WARN_FRAG3_TEARDROP
IDS_WARN_FRAG3_SHORTFRAG IDS_WARN_ANOMALY_OVERSIZE IDS_WARN_ANOMALY_ZERO
IDS_WARN_ANOMALY_BADSIZE_LG IDS_WARN_FRAG3_ANOMALY_OVERLAP IDS_WARN_ARCNET_HEADER_LEN
IDS_WARN_ARCNET_NEWHEADER_LEN IDS_WARN_ARCNET_LINUX_HEADER_LEN IDS_WARN_ARCNET_LINUX_NEWHEADER_LEN
IDS_WARN_80211_RADIO_HDRLEN IDS_WARN_80211_RADIO_CAPLEN IDS_WARN_80211_RADIO_TRUNC
IDS_WARN_PRISM_CAPLEN IDS_WARN_PRISM_HDRLEN IDS_WARN_FIREWIRE_HDRLEN
IDS_WARN_CIP_TRUNC IDS_WARN_FR_HEADER IDS_WARN_FR_Q933
IDS_WARN_LANE_HEADER IDS_WARN_IPFC_HEADERLEN IDS_WARN_SLIP_HEADER
IDS_WARN_SUNATM_HDR IDS_WARN_ENC_HEADER IDS_WARN_LLC_HEADER
IDS_WARN_ATM_HEADER IDS_WARN_ATM_TRUNC IDS_WARN_ATM_TRUNC_MSG
IDS_WARN_ATM_TRUNC_CALLREF IDS_WARN_SLOW_LENGTH IDS_WARN_SNAP_LENGTH
IDS_WARN_SMB_LENGTH IDS_WARN_DCCP_HEADER_LENGTH IDS_WARN_DCCP_TRUNCATED_LENGTH
IDS_WARN_DCCP_IP_CHKSUM IDS_WARN_DCCP_IP6_CHKSUM IDS_WARN_DCCP_ZERO_TIMESTAMP
IDS_WARN_DCCP_TRUNC_OPTS IDS_WARN_RPC_TRAFFIC IDS_WARN_RPC_MUL_RECORD
IDS_WARN_RPC_LFRAGSIZE IDS_WARN_RPC_INCSEG IDS_WARN_SSH_EVENT_CRC32
IDS_WARN_SSH_EVENT_GOBBLES IDS_WARN_SSH_EVENT_SECURECRT IDS_WARN_SSH_EVENT_PROTOMISMATCH
IDS_WARN_SSH_EVENT_PAYLOAD_SIZE IDS_WARN_SSH_EVENT_WRONG_DIR IDS_WARN_SSH_EVENT_VERSION
IDS_WARN_USER_CALL_BADNET IDS_WARN_USER_CALLUP IDS_WARN_DVMRP_HDR
IDS_WARN_DVMRP_PROBE IDS_WARN_DVMRP_REPORT IDS_WARN_GRE_TRUNC_LENGTH



Writing code with libebox
Example Simple Snoop Code
Make sure that you use the output of libebox-config --defines --cflags --libs in your compile process
snoop.c
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <fcntl.h>

#ifdef WIN32
 #include "..\src\win-config.h"
#endif

#ifndef WIN32
 #include <strings.h>
 #include <sys/socket.h>
#endif

#ifndef WIN32
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
 #include <netinet/tcp.h>
 #include <netinet/udp.h>
 #include <netinet/ip_icmp.h>
 #include <arpa/inet.h>
#endif

#include "ids_ebox.h"
#include "ebox_scan.h" 
#include "ebox_var.h" 
#include "snort/sfsnprintfappend.h"

#ifndef u_int8_t 
 # define u_int8_t unsigned char 
#endif 
#ifndef u_int32_t
 # define u_int32_t u_int 
#endif 

#define IP6 1 

#ifdef IP6
#include "../src/ip6.h"
#include "../src/icmp6.h" 
#endif 

#define int_ntoa(x)     inet_ntoa(*((struct in_addr *)&x))

extern void PrintEboxModules(short); 


char *ids_state_names[] = { "CLOSED",
                            "LISTEN",
                            "SYN_RCVD",
                            "SYN_SENT",
                            "ESTABLISHED",
                            "CLOSE_WAIT",
                            "LAST_ACK",
                            "FIN_WAIT_1",
                            "CLOSING",
                            "FIN_WAIT_2",
                            "TIME_WAIT"};



#define MAX_ETHER 20
#define SN_IPLEN  46

void my_syslog( ParserPkt *pkt )
{
 char esrc[MAX_ETHER];
 char edst[MAX_ETHER];
 char epro[8];
 char sIP[SN_IPLEN], dIP[SN_IPLEN];
 char scanaddr[SN_IPLEN]; 
 char buffer[1024]; 
 ulScanHost *sdata = NULL; 
 char *scan_proto = NULL;
 int i; 

 if(!pkt) return;
 if(!pkt->ehdr) return; 

 memset(esrc, 0, MAX_ETHER);
 memset(edst, 0, MAX_ETHER);
 memset(epro, 0, 8);
 memset(sIP, 0, SN_IPLEN); 
 memset(dIP, 0, SN_IPLEN); 
 memset(buffer, 0, 1024); 


 LogInfo("my_syslog:\n");
 /* Get the ethernet src and destination address and eth proto type strings*/
 EthAddrString((u_int8_t *)pkt->ehdr->ether_shost,esrc);
 EthAddrString((u_int8_t *)pkt->ehdr->ether_dhost,edst);
 EthProtoString(pkt->ehdr->ether_type,epro); 

 if( pkt->cap.ned->estring )
 {
     LogInfo("[t.%d,c.%d] Alert: %s\n",
             pkt->cap.ned->type,pkt->cap.ned->code,pkt->cap.ned->estring);
 }
 else
 {
     LogInfo("[t.%d,c.%d] Alert: Undefined Alert, no alert string\n",
             pkt->cap.ned->type,pkt->cap.ned->code);
 }

 if( pkt->L1->isv4 ) 
 {
     ebox_ntop(AF_INET,&(pkt->cap.v4_addr).saddr, sIP, SN_IPLEN);
     ebox_ntop(AF_INET,&(pkt->cap.v4_addr).daddr, dIP, SN_IPLEN);
     LogInfo("logv4. epro(%s) %s_%s.%d -> %s_%s.%d\n",
             epro,esrc,sIP,pkt->cap.sp,edst,dIP,pkt->cap.dp);
 } 
 else if( pkt->L1->isv6 ) 
 { 
     ebox_ntop(AF_INET6, &(pkt->cap.v6_addr).saddr, sIP, SN_IPLEN);
     ebox_ntop(AF_INET6, &(pkt->cap.v6_addr).daddr, dIP, SN_IPLEN);
     LogInfo("logv6. epro(%s) %s_%s.%d -> %s_%s.%d\n",
             epro,esrc,sIP,pkt->cap.sp,edst,dIP,pkt->cap.dp);
 }
 else 
 { 
    LogInfo("log(udef): type.%p\n",pkt);
 } 


 if( pkt->cap.ned->code  == IDS_WARN_SCAN ) 
 {
     memset(scanaddr, 0, SN_IPLEN);

     LogInfo("Scan alert sent \n");

     sdata = (ulScanHost *)pkt->cap.ned->mdata;

     if(sdata) 
     {
        if(pkt->cap.ned->wbtype == -2 ) 
        {
           scan_proto = GetProtoName(pkt->ip4h->ip_p); 
           sprintf( buffer + strlen(buffer), "%s scan from %s Scanned ports: ",
                    scan_proto, int_ntoa(sdata->addr.saddr));
           for( i = 0; i < sdata->n_packets; i++) 
                sprintf(buffer + strlen(buffer),":%hu,",sdata->PORTLIST[i]);
           sprintf(buffer + strlen(buffer), " [SType:(%d) %s] ",sdata->oc_flag,sdata->scan_type);

           LogInfo("%s\n",buffer);
       }
       else if(pkt->cap.ned->wbtype == -6 ) 
       { 
           scan_proto = GetProtoName(pkt->ip6h->ip6_nxt); 
           sprintf( buffer + strlen(buffer),"%s Scan from %s Scanned ports: ",
                    scan_proto, ebox_ntop( AF_INET6,&sdata->addr6.saddr,scanaddr,SN_IPLEN));

           for( i = 0; i < sdata->n_packets; i++) 
                sprintf(buffer+strlen(buffer),":%hu,",sdata->PORTLIST[i]);
                   
           sprintf(buffer + strlen(buffer), " [SType:(%d) %s] ",sdata->oc_flag,sdata->scan_type);

           LogInfo("%s\n",buffer);
       }
    }
 }

}



void udp_callback(ParserPkt *bp) 
{
 LogInfo("udp packet ");
}

#define STD_BUF 1024
void ip_callback(ParserPkt *ep)
{
 char buffer[8192];
 char sIP[IDS_IPLEN];
 char dIP[IDS_IPLEN];
 char *flow[2],*proto;
 int i,sp,dp;

 memset(buffer, 0, 8192);
 flow[0] = CLIENT_ID;
 flow[1] = SERVER_ID;

 ebox_ntop(AF_INET,&(a_packet)->ip_src, sIP, IDS_IPLEN);
 ebox_ntop(AF_INET,&(a_packet)->ip_dst, dIP, IDS_IPLEN);

 sp = GetSrcPort((u_int8_t*)a_packet);
 dp = GetDstPort((u_int8_t*)a_packet);

 switch( a_packet->ip_p )
 {
         case IPPROTO_ICMP:
              proto = "icmp.";
            break;
         case IPPROTO_UDP:
              proto = "udp.";
            break;
         case IPPROTO_TCP:
              proto = "tcp.";
            break;
         case IPPROTO_IGMP:
              proto = "igmp.";
            break;

         case IPPROTO_IGRP:
              proto = "igrp.";
            break;
         default:
              proto = "undef.";
            break;
 }

 LogInfo("v4IP [%s]\n",proto);
 LogInfo("[Sender:%s] %s.%d => %s.%d\n",
         flow[ll->flow_data.direction],sIP,sp,dIP,dp);

 if( ll->ip_opts_count )
 {
     LogInfo("Ip opts: ");
     for(i=0; i < ll->ip_opts_count; i++ )
     {
        LogInfo("%s",ll->ip_opts[i].data);
     }
 }

 sp = GetSrcPort((u_int8_t*)a_packet);
 dp = GetDstPort((u_int8_t*)a_packet);

 DumpPacket_Hex_Ascii_Buffer("\n",(u_char *)a_packet,(u_int)len,buffer);

 LogInfo("%s\n",buffer);
}

void sniff_callback3(ParserPkt *bp) 
{ 

 LogInfo("snoop_stream5_hook \n");
} 

void sniff_callback2(ParserPkt *bp) 
{ 
 struct ip     *iph;
 u_int8_t      *payload;
 struct tcphdr *tcph;
 STREAM        *hs;
 char          *state;
 
 LogInfo("tcpstream callback\n");

 if( bp->conn->v4orv6 == 1 )
          LogInfo(" .v4 ");
 else if( bp->conn->v4orv6 == 2)
          LogInfo(" .v6 ");
 else
      LogInfo(" (what).2T ");

 if(bp->conn->v4orv6 == 1 ) {
    if( bp->conn->flow == 0 ) // packet for server
    {
        LogInfo("[S@]%s -->\n\t\t%s %s-%s\n",
          GetTupleConDataV4(bp->conn->addr,1),bp->conn->snd_machine_string,
          TCP_STATES[bp->conn->server.state],ids_state_names[(int)bp->conn->ids_state]);
    }
    else
    {
        LogInfo("[C@]%s -->\n\t\t%s %s-%s\n",  //packet for client
          GetTupleConDataV4(bp->conn->addr,0),bp->conn->rcv_machine_string,
          TCP_STATES[bp->conn->client.state],ids_state_names[(int)bp->conn->ids_state]);
    }
 }

 if( bp->conn->flow == 0 )
     hs = &bp->conn->server; // packet for server
 else
     hs = &bp->conn->client; // packet for client


 state   = ids_state_names[(int)bp->conn->ids_state];
 iph     = (struct ip *)hs->opkt;
 payload = hs->data;
 tcph    = (struct tcphdr *)payload;


 if(bp->L1 != NULL){
    LogInfo("Have L1 data ");
       /* write our ip opts string if any */
       if( bp->L1->isv4 )
           LogInfo(" v4 L1 data\n");
       else if ( bp->L1->isv6 )
           LogInfo(" v6 L1 data\n");
 }
 else
 {  
    LogInfo("Do Not Have L1 data\n");
 }

 if( bp->L1->flow_data.direction == 0 )   /* server packet */
 {
     LogInfo("From server");
 } 
 else  // bp->L1->flow_data.direction >= 1/* client packet */
 {
     LogInfo("From client");
 }

#ifdef  HARD_WAY
 if( bp->conn->flow == 0){  /* from server */
     if( bp->conn->v4orv6 == 1 )
         LogInfo("src(%u.%d) dst(%u.%d) ",bp->conn->addr.saddr,bp->conn->addr.source,
                 bp->conn->addr.daddr,bp->conn->addr.dest);
 }
 else
 {
    if( bp->conn->v4orv6 == 1 )
         LogInfo("src(%u.%d) dst(%u.%d) ",bp->conn->addr.daddr,bp->conn->addr.dest,
                 bp->conn->addr.saddr,bp->conn->addr.source);
 }
#endif
}

void icmp6_callback(ParserPkt *pp)
{
 LogInfo("6icmp\n");
}

void route6_callback(ParserPkt *pp)
{

 if( (pp->cap.flags & 0x00006000) != 0x00006000 ) 
 {
     LogInfo("route6 raw\n");
 } 
 else 
 { 
     LogInfo("route6 reassembled\n");
 }

}


int main(int argc, char *argv[])
{

 /* dont use memory api */
 ids_params.MemoryApiInitialize = NULL;
#if 0
 //ids_params.MemoryApiInitialize(); 
 //ids_params.use_bget_mem_functions = 0;
 //ids_params.HaveMemHandler = 0;
#endif 


#ifdef  WIN32
 /*
 On win32 
 Gianluca Varenni  states: 
 it's not only a matter of (un)supported network cards (being them wireless 
 or wired). It's also a matter of network card drivers. Some cards are 
 supported (and by supported I mean that they work in promiscuous mode) 
 with any version of their drivers, 
 some others work only with some particular versions of their drivers (and 
 maybe on some Windows flavors, only).
 try to capture in non-promiscuous mode
  */
 ids_params.promisc = 0;
#else 
 ids_params.promisc = 1;
#endif 


 ids_params.n_tcp_streams        = 1;  /* collect tcp streams */
 ids_params.tcp_useBothCollectionMethods = 0;
 stream_params.tcp_collect_state = 0;  /* syn_rcvd, 4established */
 stream_params.alert_replies_to_trojan_sweep = 1;
 stream_params.random_data_flush_points      = 0;

 stream_params.alert_tcp_state   = 1;
 stream_params.flush_base        = 256;
 stream_params.flush_style       = "default"; //"random";//"large_window";

 /* turn off secondary scan detection */
 stream_params.use_ebox_scan = 0;

 /* turn off secondary syslog scan alerts */
 stream_params.stream_scan_alerts = 0;

 stream_params.watch_ports = (u_char *)strdup("all");
 /* stream_params.watch_ports = strdup("21 22 80 53 100"); */


 /* do no assemble server pkts */
 stream_params.assemble_server = 1; 
 stream_params.assemble_client = 1; 

 /* change prune method for stream cap */
 stream_params.prune_type   = 1; 


 ids_params.process_data_flow    = 1;

 ids_params.debug_ebox           = 0;  /* debug ebox code */
 ids_params.debug_Level         |= 0x00000000;  /* debug ebox code */
 //ids_params.debug_Level       |= (0x00004000|0x00000100);  /* debug ebox code */


 /* read from dump file */
 /* ids_params.filename = "/path/to/some/tcpdump_file";

 /**
  * ids_params.os_match_modes = 0x00000000;  //no os match 
  * ids_params.os_match_modes |=  FP_MODE_RST;  //only reset 
  * ids_params.os_match_modes |=  (FP_MODE_ACK|FP_MODE_RST|FP_MODE_SYNACK);
  */
 ids_params.os_match_modes =(FP_MODE_SYN|FP_MODE_SYNACK|FP_MODE_RST|FP_MODE_ACK);
 ids_params.do_os_match             = 1;
 ids_params.display_os_match_params = 0;


 /* suppress sylog logging */
 ids_params.suppress_syslog  = 1;

 /* override ebox sylog code with your own */
 ids_params.syslog = (void *)my_syslog; 

 /*
   On win32 you can specify the device by a digit or a proper device name
   where "1" is the  "\Device\NPF_GenericDialupAdapter" and all other adapters
   adapter "++1" upwards to adapter limit.
   so to point to the second device you can use
     ids_params.device = "2";
   or
     ids_params.device  = "\\Device\\NPF_{4095CE7F-305D-49C2-ADBA-1D85C082F7EF}";
   and so on
      ids_params.device = "3";  if you have two adapters on you system
 */
 ids_params.device  = "hme0";   /* fxp0,qfe0, etc.. check your system */

 /* change prune method for flow cap */
 ids_params.flow_prune_type = 1;


 ids_params.module_list   = strdup("snoop_modules.conf"); 
 ids_params.module_logdir = strdup("/tmp/"); 

 ids_params.passdata_before_processing = 0;
 ids_params.passdata_after_processing  = 1;

 /* initialize ebox component */
 if(!ebox_init() ) 
 {
    LogInfo("%s\n", EBOX_ERROR_BUFF);
    exit (1);
 }
 

 /* register user defined functions */
 EBOX_REG_USERCODE( IPR_PROC_TYPE, ip_callback);
 EBOX_REG_USERCODE( UDP_PROC_TYPE, udp_callback);
 EBOX_REG_USERCODE( TCP_STREAM_PROC_TYPE, sniff_callback2); 
 EBOX_REG_USERCODE( SNORT_S5_STREAM_PROC_TYPE, sniff_callback3); 
 EBOX_REG_USERCODE( ICMP6_PROC_TYPE, icmp6_callback); 
 EBOX_REG_USERCODE( IP6_RT_PROC_TYPE, route6_callback); 


 /*
  * EBOX_REG_USERCODE( IPF_PROC_TYPE, ipf_callback);
  * EBOX_REG_USERCODE( ICMP_PROC_TYPE, icmp_callback);
  * EBOX_REG_USERCODE( IGMP_PROC_TYPE, igmp_callback); 
  */

 EBOX_VIEW_USERCODE( IPR_PROC_TYPE ); 
 EBOX_VIEW_USERCODE( UDP_PROC_TYPE ); 

 /* list modules we are using */
 PrintEboxModules(0); 
 PrintEboxModules(1); 

 /* start pkt collection */
 ebox_run();

 /* should never get here, unless reading from dump log  */ 
 return 0;
}
 


Writing libebox engine module

At this time we do not have a utility to automatically make your engine project 'like apache apxs'.
So the way to do it is by hand or by adding your project under the src/modules/engines/ directory
modify Makfile.am and either re-run buildconf-generic or do
autoconf;
automake;
./configure --whatever-opts

Example Engine Module

 #ifdef HAVE_CONFIG_H
 #include "config.h"
#endif 

#include "ebox_internal.h"

#include "eboxmodule.h"
#include "phase.h"
#include "stats.h" 

/* module meta information */
#define MAJOR_VERSION   1
#define MINOR_VERSION   4
#define BUILD_VERSION   3
#define DETECT_NAME     "PKT_ENGINE_SOMETHING"
#define TYPE_ENGINE     0

ModuleEngineData *_dpd;


ENGINE_LINKAGE int InitializeEngine(ModuleEngineData *ded, char *eargs)
{

 if( !ded)
 {
     fprintf(stderr,"ModuleEngine Data not supplied\n"); 
     return -1;
 }

 /* set to module engine data */
 _dpd = ded; 

 if( ded->version < MODULE_DATA_VERSION)
 {
     fprintf(stderr,"Module DataVersion dose not match engine DataVersion\n"); 
     return -1; 
 }

 return 0;
}

ENGINE_LINKAGE int LibVersion(ModulePluginData *dpm)
{
 dpm->type  = MOD_ENGINE;
 dpm->major = MAJOR_VERSION;
 dpm->minor = MINOR_VERSION;
 dpm->build = BUILD_VERSION;

 /* where we want to be calld */
 dpm->anchor[0]  = IPV4_PHASE;

 /* reflect the number of times though the ebox we want to be called */
 dpm->num_anchor = 1;

 /* specify engine dependaincies */
 dpm->amt_eng_deps = 0;

 /* specify parser dependaincies */
 dpm->amt_psr_deps = 0;

 /* module name */
 dpm->modName    = DETECT_NAME;

 return 0;
}

ENGINE_LINKAGE int EboxEngineRun(ModuleEngineData *ed, ParserPkt *p )
{ 
 if(!p  || !ed) return 0; 

 //do something 
 return 0;
} 

ENGINE_LINKAGE int EboxEngineStop(ModuleEngineData *ed )
{ 
 

 return 0;
}


#ifdef  WIN32
/** 
 *  do nothing during dll init/end  just here to stop win32 from
 *  complaining 
 */
BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,  // handle to DLL module
    DWORD fdwReason,     // reason for calling function
    LPVOID lpReserved )  // reserved
{
    // Perform actions based on the reason for calling.
    switch( fdwReason )
    {
        case DLL_PROCESS_ATTACH:
         // Initialize once for each new process.
         // Return FALSE to fail DLL load.
            break;

        case DLL_THREAD_ATTACH:
         // Do thread-specific initialization.
            break;

        case DLL_THREAD_DETACH:
         // Do thread-specific cleanup.
            break;

        case DLL_PROCESS_DETACH:
         // Perform any necessary cleanup.
            break;
    }
    return TRUE;  // Successful DLL_PROCESS_ATTACH.
}
#endif

/* Variables to check type of InitializeEngine and LibVersion */
ENGINE_LINKAGE InitEngineLibFunc initEngineFunc = &InitializeEngine;
ENGINE_LINKAGE ModuleVersionFunc libVersionFunc = &LibVersion;


Writing libebox parser module

At this time we do not have a utility to automatically make your engine project 'like apache apxs'.
So the way to do it is by hand or by adding your project under the src/modules/parsers/ directory
modify Makfile.am and either re-run buildconf-generic or do
autoconf;
automake;
./configure --whatever-opts

Example Parser Module



#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "ebox_internal.h"

#include "listutils.h"
#include "eboxmodule.h"
#include "phase.h"
#include "export.h" 

#define MAJOR_VERSION   1
#define MINOR_VERSION   4
#define BUILD_VERSION   3
#define DETECT_NAME     "GNRC_PARSER"
#define TYPE_PARSER     1



ENGINE_LINKAGE int InitializeParser(ModuleParserData *mpd, char *pargs)
{

 return 0;
}

ENGINE_LINKAGE int LibVersion(ModulePluginData *dpm)
{

 dpm->type  = MOD_PARSER;
 dpm->major = MAJOR_VERSION;
 dpm->minor = MINOR_VERSION;
 dpm->build = BUILD_VERSION;

 /* where we want to be calld */
 dpm->anchor[0]  = IPV4_PHASE; 

 /* reflect the number of time though the ebox we want to be called */
 dpm->num_anchor = 1;
 dpm->modName    = DETECT_NAME; 

 /* specify engine dependaincies */
 dpm->amt_eng_deps = 0;  

 /* specify parser dependaincies */
 dpm->amt_psr_deps = 0;  

 return 0;
}

ENGINE_LINKAGE int EboxParserRun(ModuleParserData *mpd, ParserPkt *ebd )
{ 
 if(!mpd  || !ebd) return 0; 

 //do something 

 return 0;
} 

ENGINE_LINKAGE int EboxParserStop(ModuleParserData *mpd )
{

 return 0;
}


#ifdef  WIN32
/** 
 *  do nothing during dll init/end  just here to stop win32 from
 *  complaining 
 */
BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,  // handle to DLL module
    DWORD fdwReason,     // reason for calling function
    LPVOID lpReserved )  // reserved
{
    // Perform actions based on the reason for calling.
    switch( fdwReason )
    {
        case DLL_PROCESS_ATTACH:
         // Initialize once for each new process.
         // Return FALSE to fail DLL load.
            break;

        case DLL_THREAD_ATTACH:
         // Do thread-specific initialization.
            break;

        case DLL_THREAD_DETACH:
         // Do thread-specific cleanup.
            break;

        case DLL_PROCESS_DETACH:
         // Perform any necessary cleanup.
            break;
    }
    return TRUE;  // Successful DLL_PROCESS_ATTACH.
}
#endif

/* Variables to check type of InitializeParser and LibVersion */
ENGINE_LINKAGE InitParserLibFunc initParserFunc = &InitializeParser;
ENGINE_LINKAGE ModuleVersionFunc libVersionFunc = &LibVersion;




An Incomplete Man-Page.

Introduction to Library Functions                      LIBEBOX(3)



NAME
     libebox - network intrusion detection system E-box library

SYNOPSIS
     #include <ebox_core_vars.h>
     #include <ids_ebox.h>
     #include <ids_misc.h>
     #include <ebox_var.h>

     extern struct ebox_prm ids_params;
     extern struct snort_prm snort_params;
     extern char ebox_warn[];
     extern char EBOX_ERROR_BUFF[];
     extern char TCP_STATES[];
     extern char EboxCurrScanType;

     #define SBOX_VER_MAJOR 2
     #define SBOX_VER_MINOR 0

     /*
       amount of mem allocated by EboxAlloc et al
      */
     u_int32_t ebox_memory_usage;


     int ebox_init( void);

     int EBOX_REG_USERCODE( int , void (*));

     void EBOX_UNREGISTER_CODE( int , void (*));

     void EBOX_VIEW_USERCODE( int PROC_TYPE);

     void EBOX_PKT_BASEHANDLER( u_char *, struct pcap_pkthdr *, u_char *);

     void ebox_run( void);

     void ebox_discard( TCPSTREAM *, int);

     int ebox_getfd(void);

     int ebox_dispatch(int);

     int ebox_next(void);

     void ebox_exit(void);

     char * GetTupleConDataV4(struct tuple4 addr, int dir);

     char * GetTupleConDataV6(struct tuple6 addr, int dir);

     void SetAddressByFlowId( TCPSTREAM *, int *, int *, char *, char *);

     inline int GetSrcPort( u_int8_t *);

     inline int GetDstPort( u_int8_t *);

     inline int GetSrcPortV6(u_int8_t *);

     inline int GetDstPortV6(u_int8_t *);

     TCPSTREAM * Getv4Session(struct ip *, u_int16_t , u_int16_t);

     TCPSTREAM * Getv6Session(struct ip6_hdr *, u_int16_t, u_int16_t);

     inline void StopCollectStream( TCPSTREAM *);

     inline void StopCollectHalfStream(TCPSTREAM *, int);

     char * lookup_link(u_int16_t mss, u_int8_t txt);

     void EthProtoString( u_short, char *);

     void EthAddrString( u_char *, char *);

     const char * ebox_ntop(int , const void *, char *, int);

     int ebox_pton(int , const char *, void *);

     u_short ip_fast_csum(u_char *, int);

     u_short ip_compute_csum(u_char *, int);

     u_short ids_tcp_check(struct tcphdr *, int, u_int, u_int);

     u_short ids_udp_check(void *, int, u_int, u_int);

     u_short in_cksum(const u_short *, register u_int , int);

     u_short ip_check_ext(register u_short *, register int , int);

     unsigned short in_chksum_icmp( unsigned short * w, int blen);

     int osi_cksum(const u_int8_t *tptr, u_int len);

     void * EboxAlloc(unsigned long);

     void EboxFree(void *, int);

     int EboxRespondInit(char *);

     void EboxRespondShutDown(void);

     void ebox_killtcp(TCPSTREAM *);

     void ebox_sendicmpv4_unreach(u_int, u_int, u_int32_t, u_int32_t, struct ip *, u_char *, int);

     int EboxContinuationCheck(char *);

     void  FreeStringToks(char **, int);

     char ** SplitString(char *, char *, int , int *, char);

     void DumpPacket_Hex_Ascii(char *, u_char *, u_int);
     void DumpPacket_Hex_Ascii_Offset(char *, u_char *, u_int , u_int );

     void DumpPacket_Hex_Offset(char *, u_char *, u_int,u_int);
     void DumpPacket_Hex(char *, u_char *, u_int);

     void DumpPacket_Hex_Buffer(char *,u_char *,u_int,char *);
     void DumpPacket_Hex_Offset_Buffer(char *,u_char *,u_int,u_int,char *);

     void DumpPacket_Hex_Ascii_Buffer(char *,u_char *,u_int, char *);
     void DumpPacket_Hex_Ascii_Offset_Buffer(char *,u_char *,u_int,u_int,char *);

DESCRIPTION
     libebox provides the functionality of  a  network  intrusion
     detection  system  (NIDS)  E-box  component.  This  ebox was
     inspired by  libnids(3),  snort,  tcpdump(1),  pcap(3).   It
     currently performs:

     1. IP defragmentation      (ipfrags.c,snortfrag3.c)
     2. TCP stream reassembly   (v4 and v6 tcp )
     3. TCP port scan detection (
                                 ebox_v4/v6 scan detect,
                                 snort portscan
                                 snort portscan2
                                 snort sfportscan
                                )
     4. Data Flow Processing    (eboxflow.c)
     5. Provides processing and warnings for the following:

     WARN_ETH_HDR_LEN, WARN_IP_OVERSIZED,
     WARN_IP_TSERROR, WARN_TRUNCATED_IP, WARN_IP_OPTS,
     WARN_IP_OPTS_TRUNC, WARN_IP_INVLIST, WARN_IP_OVERLAP,
     WARN_IP_HDR, WARN_IP_SRR, WARN_IP6_HDRLE,
     WARN_IP6_LEN, WARN_IP6_SAMEIP, WARN_IP6_HBHOPT,
     WARN_IP6_DSTOPT, WARN_IP6_SOPT_DECODE, WARN_IP6_OPTS_DECODE,
     WARN_IP6_FRAG_OFF, WARN_ICMP6_HDRLEN, WARN_ICMP6_HDR,
     WARN_ICMP6_LEN, WARN_ICMP6_CSUM, WARN_ICMP6_TOOBIG,
     WARN_ICMP6_PRAMERR, WARN_ICMP6_TEXCEED, WARN_ICMP6_UNRCH,
     WARN_TCP_TOOMUCH, WARN_TCP_HDR, WARN_TCP_BIGQUEUE,
     WARN_TCP_BADFLAGS, WARN_TCP_EXPR_TCPOPTS,
     WARN_TCP_OBSL_TCPOPTS,
     WARN_TCP_BAD_OPTS_TTCP, WARN_TCP_BAD_TCPOPTS,
     WARN_TCP_BAD_SACK_OPTS,
     WARN_OSPF_LEN, WARN_OSPF_HDR, WARN_OSPF6_LEN,
     WARN_OSPF6_HDR, WARN_RT6_HDR, WARN_IPCOMP_HDR,
     WARN_AH_HDR, WARN_ESP_HDR, WARN_IGRP_HDR,
     WARN_EGP_VER, WARN_EGP_HDR, WARN_IGMP_HDR,
     WARN_IGMP_SUM, WARN_GRE_HDR, WARN_GRE_TRUNC_LENGTH,
     WARN_GRE_UNKNOW_VER, WARN_GRE_VER0_ERROR, WARN_GRE_VER1_ERROR,
     WARN_MO BILE_CSUM, WARN_MOBILE_SIZE, WARN_VRRP_CSUM,
     WARN_VRRP_HDR, WARN_SCTP_LEN, WARN_SCTP_HDR,
     WARN_PIM_HDR, WARN_PIM_LEN, WARN_IPX_HDR,
     WARN_VLAN_HDR, WARN_VLAN_LEN, WARN_PPPoE_HDR,
     WARN_ARP_HDR, WARN_ARP_HDR_LEN, WARN_ATMARP_HDR,
     WARN_ATMARP_LEN, WARN_IEEE_802_LEN, WARN_IEEE_802_HDR,
     WARN_IEEE_802_DATA_LEN, WARN_MOBILITY_HDR, WARN_MOBILITY_OPTS,
     WARN_RSVP_VER, WARN_RSVP_COM_HDR, WARN_RSVP_HDR,
     WARN_SCAN_DETECT, WARN_SCAN_DETECTV6,WARN_UDP_HDR,
     WARN_MPLS_HDR, WARN_TCPen6_HDR, WARN_UDPen6_HDR,
     WARN_ICMP_HDR, WARN_TOKEN_HDR, WARN_TOKEN_SNAP,
     WARN_FDDI_HDR, WARN_STREAM_EVASIVE_RETRANS,
     WARN_STREAM_WINDOW_VIOLATION,
     WARN_STREAM_DATA_ON_SYNPKT, WARN_STREAM_EVASION_ATTEMPT ,
     WARN_STREAM_STEALTHNMAP_FINGERPRINT,
     WARN_STREAM_STEALTHACTIVITY, WARN_STREAM_STEALTH_FULL_XMAS,
     WARN_STREAM_STEALTH_SAPU,
     WARN_STREAM_STEALTH_FINS, WARN_STREAM_SYN_FIN_SCAN,
     WARN_STREAM_NULL_SCAN, WARN_NMAP_XMAS_SCAN,
     WARN_STEALTH_VECNA_SCAN, WARN_EVASIVE_RESET,
     WARN_STREAM_TTL_EVASION, WARN_STREAM_PAWS_ID,
     WARN_STREAM_HIJACKING, WARN_STREAM_INVALID_OFFSET,
     WARN_STREAM_LARGE_OFFSET, WARN_STREAM_IP4_SAMEIP,
     WARN_STREAM_INVALID_DATA_LENGTH, WARN_STREAM_INVALID_CKSUM,
     WARN_STREAM_WINDOW_SCALE_ERR_RFC1323,
     WARN_STREAM_POSSIBLE_TROJAN,
     WARN_STREAM_OVERLAP_LIMIT, WARN_STREAM_FOWARD_OVERLAP,
     WARN_TCP_NO_ACK, WARN_CDP_HEADER,
     WARN_STP_HEADER_LEN, WARN_STP_VERSION_ERROR,
     WARN_ISOCLNS_LENGTH_ERROR, WARN_CHDLC_SLARP_HEADER,
     WARN_FRAG3_IPOPTIONS, WARN_FRAG3_ANOMALY_BADSIZE,
     WARN_FRAG3_TEARDROP, WARN_FRAG3_SHORTFRAG,
     WARN_ANOMALY_OVERSIZE, WARN_ANOMALY_ZERO,
     WARN_ANOMALY_BADSIZE_LG, WARN_FRAG3_ANOMALY_OVERLAP,
     WARN_USER_CALL_BADNET, WARN_USER_CALLUP

ROUTINES

     void ebox_init () initializes the application for  sniffing,
     based  on  the values set in the global variable ids_params,
     declared as follows:

     struct ebox_prm {
      u_int32_t  n_tcp_streams;
      u_int32_t  n_hosts;

      char *device;
      char *filename;

      void (*syslog)( ParserPkt *);
      int  syslog_level;

      u_int32_t  scan_num_hosts;
      u_int32_t  scan_delay;
      u_int32_t  scan_num_ports;

      void * (*MemGet)(unsigned long  );
      void   (*MemDel)(void * );
      u_int8_t  HaveMemHandler;

      void (*no_mem)(char *);

      int  (*ip_filter)(void *,...);

      int  default_snaplen;

      char *pcap_filter;

      u_int8_t  promisc;
      u_int8_t  tcpopt_experiment;
      u_int8_t  tcpopt_obsolete;
      u_int8_t  tcpopt_decode;
      u_int8_t  tcpopt_ttcp;
      u_int8_t  ospf_check_all_data;
      u_int8_t  check_ip6_opts;
      u_int8_t  warnSCAN;
      u_int8_t  initResponse;
      u_int8_t  suppress_syslog;
      u_int8_t  suppress_bad_packets;
      u_int8_t  tcp_useBothCollectionMethods;
      u_int8_t  do_os_match;
      u_int8_t  display_os_match_params;
      u_int32_t os_match_modes;
      u_int8_t  process_data_flow;
      u_int8_t  use_utc;
      pcap_t    *pcap_hand;
      u_int8_t  passdata_before_processing;
      u_int8_t  passdata_after_processing;
      u_int8_t  debug_ebox;
      u_int8_t  debug_Level;
     };

     The members of this structure are:

     n_tcp_streams
          If non-zero then we do v4/v6  stream  assembly  Default
          value: 1024

     n_hosts
          Size of the hash table used for storing IP defragmenta-
          tion information. Default value: 256

     filename
          It  this   variable   is   set,   libebox   will   call
          pcap_open_offline  with  this  variable as the argument
          (instead of pcap_open_live()). Default value: NULL

     device
          Interface to monitor. Default  value:  NULL  (in  which
          case  an  appropriate  device  is  determined automati-
          cally). If this variable is assigned value all, libebox
          will  attempt  to  capture  packets  on  all interfaces
          (which works on Linux only)

     sk_buff_size
          Size of struct  sk_buff  (used  for  queuing  packets),
          which  should  be  set  to match the value on the hosts
          being monitored. Default value: 168

     dev_addon
          Number of bytes in struct sk_buff  reserved  for  link-
          layer  information. Default value: -1 (in which case an
          appropriate offset if determined automatically based on
          link-layer type)

     syslog
          Syslog callback function, used to report unusual condi-
          tions,  such  as port scan attempts, invalid TCP header
          flags, etc. Default value:  syslog (which logs messages
          via  syslog(3)  without  regard  for  message  rate per
          second or free disk space)

     syslog_level
          Log level used by ebox syslog for reporting events  via
          syslog(3). Default value: LOG_ALERT

     scan_num_hosts
          Size of hash table used for storing  portscan  informa-
          tion   (the  maximum  number  portscans  that  will  be
          detected simultaneously). If set to 0, portscan  detec-
          tion will be disabled. Default value: 256

     scan_num_ports
          Minimum number of ports that must be scanned  from  the
          same  source host before it is identifed as a portscan.
          Default value: 10

     scan_delay
          Maximum delay (in milliseconds) between connections  to
          different  ports for them to be identified as part of a
          portscan. Default value:  3000

     void * (*MemGet)(unsigned long);
            memory handler get  sub (your mem handler get routine
          must only take one arg)

     void   (*MemDel)(void *);
           memory handler free sub (your mem handler free routine
           must only take one arg)

      int    HaveMemHandler;
            are we useing memory handler subs

     no_mem
          Out-of-memory callback function, used to terminate  the
          calling process gracefully.

     ip_filter
          IP filtering callback  function,  used  to  selectively
          discard  IP packets, inspected after reassembly. If the
          function returns a non-zero value, the packet  is  pro-
          cessed;  otherwise,  it  is  discarded.  Default value:
          ebox_ip_filter (which always returns 1)

     default_snaplen;
            just in case, you need to set it default(16384)

     pcap_filter
          pcap(3) filter string applied to the  link-layer  (raw,
          unassembled) packets. Note: filters like ``tcp dst port
          23'' will NOT correctly handle appropriately fragmented
          traffic,  e.g.  8-byte IP fragments; one should add "or
          (ip[6:2] & 0x1fff != 0)" at the end of  the  filter  to
          process reassembled packets. Default value: NULL

     promisc
          If non-zero,  libebox  will  set  the  interface(s)  it
          listens on to promiscuous mode. Default value: 1

     tcpopt_experiment
          alert on experimental opts

     tcpopt_obsolete
           alert on obsolete opts

     tcpopt_decode
          alert on crummy  opts

     tcpopt_ttcp

     ospf_check_all_data

     check_ip6_opts

     warnSCAN
          1 when a scan is in progress

     initResponse
          init response code

     suppress_syslog
          default (0)  suppress any alerts

     suppress_bad_packets
          default (1)  suprress alerted packets from futher  pro-
          cessing

     tcp_useBothCollectionMethods
          default 1

     do_os_match
          default 1, should we try to guess at os'es

     display_os_match_params
          default 0, could use info to  build  new  finger  print
          signatures

     os_match_modes
          def SYN possible SYN+ACK,RST,RST+ACK,ACK

     process_data_flow
          if we want flow stats per conn

     use_utc
          use UTC

     passdata_before_processing : passdata to user code

     passdata_after_processing : passdata to user code

     debug_ebox [0|1]
          display debug default(0). output only if compiled  with
          --enable-debug

     debug_Level
          what code to debug default(0x00000000).  only  if  com-
          piled with --enable-debug

     pcap_hand
          It this variable is  set,  libebox  will  call  neither
          pcap_open_live  nor  pcap_open_offline,  but will use a
          pre-opened   PCAP    descriptor;    use    this    with
          EBOX_PKT_BASEHANDLER()  in  order to interactively feed
          packets to libebox. Default value: NULL

     Stream code intializer arguments

     struct stream_prm
     {
      u_int32_t stream_cap_memory_limit; /*default(8M)*/
      u_int8_t  tcp_collect_state;       /* SYN_RCVD,SYN_SENT,ESTABILSHED etc*/
      u_int8_t  assemble_client;         /* default (1) */
      u_int8_t  assemble_server;         /* default (1) */
      u_int8_t  stream_scan_alerts;      /* default (0) */
      u_int8_t  alert_tcp_state;         /* default (1) */
      u_int8_t  alert_tcp_evade;         /* default (1) */
      u_int8_t  alert_ttl_evade;         /* default (1) */
      u_int8_t  alert_ttl_max;           /* default (1) */
      u_int8_t  alert_stream_evasion;    /* default (1) */
      u_int8_t  stream_cap_def_mode;     /* default (1)  normal ops mode */
      u_int8_t  use_ebox_scan;           /*override def scan mode default(0)*/
      u_int     stream_time_out_value;   /* def(30), when to cull stream data */
      u_int8_t  inspect_mac_addrs;       /* default (1) */
      u_int8_t  inspect_server_side_mac; /* default (1) */
      u_int8_t  inspect_client_side_mac; /* default (1) */
      u_int     null_flushed_packets;    /* default (0) */
      u_int     flush_data_diff_size;    /* default (500) */
      u_int8_t  random_data_flush_points; /* default (0) */
      u_int8_t  alert_replies_to_trojan_sweep; /* default 0 */
      u_int8_t  server_inspect_limit;          /* default 4 */
      u_char    *watch_ports;    /* ports we want to get data on */
      u_int     overlap_limit;   /* limit of packet overlaps we permit */
      char      *flush_style;
      u_int     flush_seed;
      u_int     flush_base;
      u_int     flush_range;
      u_int8_t  assemble_method; /* 0, favor old , 1 favor new*/
     };

     stream_cap_memory_limit
          additional  Tcp  Stream  Cap  Vars  default(8M),(if   < 16000K, lol, then set2MB))

     tcp_collect_state
          SYN_RCVD,SYN_SENT,ESTABILSHED etc

     assemble_client
           default (1)

     assemble_server
          default (1)

     stream_scan_alerts
          default (0)

     alert_tcp_state
          default (1)

     alert_tcp_evade
          default (1)

     alert_ttl_evade
          default (1)

     alert_ttl_max
          default (1)

     alert_stream_evasion
          default (1)

     stream_cap_def_mode
          default (1)  normal ops mode

     use_ebox_scan
          override def scan mode default(0)

     stream_time_out_value
          def(30), when to cull stream data

     inspect_mac_addrs
          default (1)

     inspect_server_side_mac
          default (1)

     inspect_client_side_mac
          default (1)

     null_flushed_packets
          default (0)

     flush_data_diff_size
          default (500)

     random_data_flush_points
          default (0)

     alert_replies_to_trojan_sweep
          default 0

     server_inspect_limit
          default -1 unlimited

     watch_ports
          ports we want to get data on

     overlap_limit
          limit of packet overlaps we permit

     flush_style

     flush_seed

     flush_base

     flush_range

     assemble_method 0, forward stream search, 1 reverse search



     ebox_init() Returns 1 on success, 0  on  failure  (in  which
     case EBOX_ERROR_BUFF contains an appropriate error message).

     int EBOX_REG_USERCODE( int code_type, void *mycode);

     Register your code with the ebox code_type as define by  one of the following int types.

     ETH_PROC_TYPE,IPF_PROC_TYPE,IPR_PROC_TYPE,UDP_PROC_TYPE

     ARP_PROC_TYPE,PPPoe_PROC_TYPE,VLAN_PROC_TYPE,IPX_PROC_TYPE

     IP6_PROC_TYPE,IP6F_PROC_TYPE,ICMP6_PROC_TYPE,IP6_RT_PROC_TYPE

     ICMP_PROC_TYPE,TCP_PROC_TYPE,TCP_STREAM_PROC_TYPE,OSPF_PROC_TYPE

     OSPF6_PROC_TYPE,ESP_PROC_TYPE,SCTP_PROC_TYPE,AH_PROC_TYPE

     IPCOMP_PROC_TYPE,IGRP_PROC_TYPE,EGP_PROC_TYPE,IGMP_PROC_TYPE

     GRE_PROC_TYPE,MOBILE_PROC_TYPE,VRRP_PROC_TYPE,PIM_PROC_TYPE

     IEEE_80211_PROC_TYPE,MOBILITY_PROC_TYPE,RSVP_PROC_TYPE,MPLS_PROC_TYPE

     TCP6_PROC_TYPE,UDP6_PROC_TYPE,TOKEN_PROC_TYPE,FDDI_PROC_TYPE

     STP_PROC_TYPE,SLL_PROC_TYPE,RAWPKT_PROC_TYPE,RAWIPP_PROC_TYPE

     I4L_Cisco_PROC_TYPE,NULL_PROC_TYPE,ISOCLNS_PROC_TYPE,CDP_PROC_TYPE

     CHDLC_PROC_TYPE

     And mycode pointing to your  code  to  run. Registering a user-defined callback function to process 
     TCP streams vali-dated and reassembled by libebox. The TCPSTREAM structure is defined as follows:

     typedef struct _TCPSTREAM
     {

      struct tuple4 addr;         /* v4 addr if */
      struct tuple6 addr6;        /* v6 addr if */

      char       ids_state;       /* RESET,DATA,EST,CLOSED,etc */
      u_int8_t   v4orv6;          /* is this v4 or v6 */
      u_int32_t  hash_index;      /* index into hash table */
      u_int32_t  read;            /* data size avail for reading now */
      u_int32_t  s_time;          /* when caught */
      u_int32_t  l_time;          /* when last updated */

      u_int32_t  sflags;          /* session state flags */
      u_int32_t  isn_s;           /* initial seq no for server */
      u_int32_t  isn_c;           /* initial seq no for client */
      u_int8_t   flow;            /* direction that data  is being sent from */
      u_int8_t   preserve_stream;  /*keep stream up to(programmer) to delete*/
      u_int32_t  data_flush_point; /*random flush point value for stream data */
      u_int8_t   stop_collect_srv;
      u_int8_t   stop_queue_srv;
      u_int8_t   stop_collect_cli;
      u_int8_t   stop_queue_cli;
      u_int8_t   syn_s_flags;      /* what options sent with syn, if we caught
                                      the session from begining,
                                      not applicable on midstream,
                                      unless conn dose another TWH
                                    */
      u_int16_t  o_window_scale;   /* changes during TWH, after that point it is
                                      the orig server win scale factor if
                                      any syn opt sent
                                    */

      u_int8_t  *snd_machine_string; /* identify os,else use default string*/
      u_int8_t  *rcv_machine_string; /* identify os,else use default string*/

      EthHeader   imac_c;     /* original mac for server */
      EthHeader   imac_s;     /* original mac for client */


      u_int8_t  *ipPkt;  /* ip4orip6 raw pkt,represents the current sender pkt*/
      u_int8_t  *tcpPkt; /* tcp raw pkt,represents the current sender pkt*/

      /* client and server halves of the stream */
      STREAM  client;
      STREAM  server;

     } TCPSTREAM;

     /* VALID IDS STATES (for stream processing) */
     #define IDS_INVALID_STATE 0  /* should never see */
     #define IDS_SYN_DATA      1  /* a syn pkt just came in */
     #define IDS_JUST_EST      2  /* just established connection*/
     #define IDS_DATA          3  /* n/a unused*/
     #define IDS_CLOSE         4  /* n/a unused*/
     #define IDS_RESET         5  /* n/a unused*/
     #define IDS_TIMED_OUT     6  /* n/a unused*/
     #define IDS_PKT_REBUILT   7  /* stream rebuilt pkt data  */
     #define IDS_DATA_ON_UNEST 8  /* n/a unused*/
     #define IDS_EXITING       9  /* n/a unused*/

     The members of the tuple4 ||  tuple6  structure identify a unique TCP connection:

     void EBOX_UNREGISTER_CODE( int code_type, void *mycode);

     where code_type is one of codes supplied in  above  section.
     And mycode pointing to your code that was registered.

     void EBOX_VIEW_USERCODE( int PROC_TYPE); 

     used  to  view  the code(s)  attached to a SBOX_NODE by EBOX_REG_USERCODE(), i.e
     the amount of usercode registered to a certain processor

     void EBOX_PKT_BASEHANDLER( u_char *, struct pcap_pkthdr u_char *);

     may be used by an application already running a capture with
     libpcap,  in  order  to pass frames to libebox interactively
     (frame per frame) instead of having libebox  itself  do  the
     capture.

     void ebox_run( void);

     starts the packet-driven application, reading packets in  an
     endless  loop, and invoking registered callback functions to
     handle new data  as  it  arrives.  This  function  does  not
     return.

     void ebox_discard( TCPSTREAM *, int); (deprecated)

     int ebox_getfd(void);

     may be used by an application sleeping in select(2) to snoop
     for  a  socket  file  descriptor present in the read fd_set.
     Returns the file descriptor on success, -1  on  failure  (in
     which  case  nids_errbuf  contains an appropriate error mes-
     sage).

     int ebox_dispatch(int);

     attempts to process cnt packets before returning, with a cnt
     of  -1  understood  as  all  packets  available  in one pcap
     buffer, or all packets in a file when reading  offline.   On
     success,  returns  the count of packets processed, which may
     be zero upon EOF (offline read) or upon hitting pcap_timeout
     (if  supported  by  your platform).  On failure, returns -1,
     putting an appropriate error message in nids_errbuf.

     int ebox_next(void);

     process the next available packet before returning.  Returns
     1  on  success,  0  if  no  packet  was  processed,  setting
     nids_effbuf appropriately if an error prevented packet  pro-
     cessing.

     void ebox_exit(void);

     close ebox processors


     GetTupleConDataV4(struct tuple4 addr, int dir);

      string representaion of connection src.port/dst.port params

     GetTupleConDataV6(struct tuple6 addr, int dir);
      string representaion of connection src.port/dst.port params

     void SetAddressByFlowId( TCPSTREAM *, int *,
                           int *, char *, char  *);  for  streams
      set the address by the current flow  of data

     int GetSrcPort( u_int8_t *);

      get the src port from an ip v4  packet

     int GetDstPort( u_int8_t *);

      get the dst port from an ip v4  packet

     int GetSrcPortV6(u_int8_t *);

      get the src port from an ip v6  packet

     int GetDstPortV6(u_int8_t *);

      get the dst port from an ip v6  packet

     TCPSTREAM * Getv4Session(struct ip *, u_int16_t , u_int16_t);

      so top level code can pull up a session copy  if  it  exsits
      user must free TCPSTREAM object when finished using it

     TCPSTREAM * Getv6Session(struct ip6_hdr *, u_int16_t, u_int16_t);

      so top level code can pull up a session copy  if  it  exsits
      user must free TCPSTREAM object when finished using it

     StopCollectStream( TCPSTREAM *);

      stop collection on a desired stream

     StopCollectHalfStream(TCPSTREAM *, int);

      stop collection on a desired  half stream

     lookup_link(u_int16_t mss, u_int8_t txt);

      look up a link information based on mss  of the connection

     EthProtoString( u_short, char *);

      Get the ethernet proto in string form

     EthAddrString( u_char *, char *);

      Get the ethernet addr in string form

     ebox_ntop(int , const void *, char

      our ntop/pton functions, thanks Paul Vixie, 1996.

     ebox_pton(int , const char *, void

      our ntop/pton functions, thanks Paul Vixie, 1996.

     ip_fast_csum(u_char *, int);

      ip checksums

     ip_compute_csum(u_char *, int);

      ip checksums

     ids_tcp_check(struct tcphdr *, int, u_int, u_int);

      tcp checksums

     ids_udp_check(void *, int, u_int, u_int);

      udp checksums

     in_cksum(const u_short *, register u_int ,

      checksums

     ip_check_ext(register u_short *, register int ,

      checksums

     in_chksum_icmp( unsigned short * w, int

      icmp checksums

     osi_cksum(const u_int8_t *tptr, u_int len);

      osi checksums

     EboxAlloc(unsigned long);

      our memory alloc funtion  returns (void *)

     EboxFree(void *, int);

      our free memory funtion

     EboxRespondInit(char *);

      for terminating tcp connections, sending icmp responses

     EboxRespondShutDown(void);

      for shutting down term socket

     ebox_killtcp(TCPSTREAM *);

      tears down the specified TCP connection with  symmetric  RST
      packets between client and server.

     ebox_sendicmpv4_unreach(u_int,u_int,u_int32_t,u_int32_t, struct ip *,u_char  *,int);  send

      icmp  unreach

Common string utilities

     EboxContinuationCheck(char *);


     FreeStringToks(char **, int);

     Common string utilities

     char **SplitString(char *, char *, int

Packet Dump Utilities

     void DumpPacket_Hex_Ascii(char *,  u_char  *,  u_int); 

      dump packet in hex and ascii


     void DumpPacket_Hex_Ascii_Offset(char  *,  u_char  *,  u_int, u_int);

      dump packet in hex and ascii


     void DumpPacket_Hex(char *, u_char *, u_int); 
       dumpacket in hex (default offset=0)

     void DumpPacket_Hex_Offset(char *, u_char  *,  u_int,u_int);

       dumpacket in hex with an offset

     void DumpPacket_Hex_Buffer(char  *,u_char  *,u_int,char  *);

       dumpacket      in      hex      to      a      user     void

     DumpPacket_Hex_Offset_Buffer(char   *,u_char *,u_int,u_int,char *);

       dumpacket in hex to a user

     void DumpPacket_Hex_Ascii_Buffer(char *,u_char *,u_int, char *);

      dumpacket    in    hex    and    ascii    to    void

     DumpPacket_Hex_Ascii_Offset_Buffer(char             *,u_char *,u_int,u_int,char *);

      dumpacket in hex and ascii to


CODE_PROC CALLBACK ARGS
     This details the arguments that will be passed to  the  code
     registered  with the ebox If your function dose not have the
     right arg mathching the correct code  box  the  errors  will
     occour. (more likley a core dump)

     ETH_PROC_NODE => (user_code)( ParserPkt * );

     CDP_PROC_NODE => (user_code)(  ParserPkt * );

     SLL_PROC_NODE => (user_code)( ParserPkt * );

     STP_PROC_NODE => (user_code)( ParserPkt * );

     IEEE_80211_PROC_NOD => (user_code)( ParserPkt * );

     IPX_PROC_NODE => (user_code)( ParserPkt * );

     VLAN_PROC_NODE => (user_code)( ParserPkt * );

     PPPoe_PROC_NODE => (user_code)(  ParserPkt * );

     CHDLC_PROC_NODE => (user_code)( ParserPkt * );

     ARP_PROC_NODE   => (user_code)( ParserPkt * );

     IPF_PROC_NODE   => (user_code)( ParserPkt * );

     IPR_PROC_NODE   => (user_code)( ParserPkt * );

     RSVP_PROC_NODE  => (user_code)( ParserPkt * );

     PIM_PROC_NODE => (user_code)( ParserPkt * );

     VRRP_PROC_NODE => (user_code)( ParserPkt * );

     MOBILE_PROC_NODE => (user_code)( ParserPkt * );

     GRE_PROC_NODE => (user_code)( ParserPkt * );

     IGMP_PROC_NODE => (user_code)( ParserPkt * );

     EGP_PROC_NODE => (user_code)( ParserPkt * );

     IGRP_PROC_NODE => (user_code)( ParserPkt * );

     UDP_PROC_NODE => (user_code)( ParserPkt * );

     AH_PROC_NODE => (user_code)( ParserPkt * );

     IPCOMP_PROC_NODE => (user_code)( ParserPkt * );

     ESP_PROC_NODE => (user_code)( ParserPkt * );

     MPLS_PROC_NODE => (user_code)(  ParserPkt * );

     NULL_PROC_NODE => (user_code)( ParserPkt * );

     RAWPKT_PROC_NODE => (user_code)( ParserPkt * );

     RAWIPP_PROC_NODE => (user_code)( ParserPkt * );

     I4L_Cisco_PROC_NODE => (user_code)( ParserPkt * );

     ISOCLNS_PROC_NODE => (user_code)( ParserPkt * );

     IP6_PROC_NODE => (user_code)( ParserPkt * );

     TCP6_PROC_NODE => (user_code)( ParserPkt * );

     UDP6_PROC_NODE => (user_code)( ParserPkt * );

     MOBILITY_PROC_NODE => (user_code)( ParserPkt * );

     ICMP6_PROC_NODE => (user_code)( ParserPkt * );

     IP6_RT_PROC_NODE => (user_code)( ParserPkt * );

     IP6F_PROC_NODE  => (user_code)( ParserPkt * );

     TOKEN_PROC_NODE => (user_code)( ParserPkt * );

     FDDI_PROC_NODE => (user_code)( ParserPkt * );

     OSPF_PROC_NODE => (user_code)( ParserPkt * );

     OSPF6_PROC_NODE => (user_code)( ParserPkt * );

     DCCP_PROC_NODE => (user_code)( ParserPkt * );


SEE ALSO
     pcap(3), libnids(3), snort(3), libnet(3) pcre(3)

AUTHOR
     Garrick Hermitt-Barrett
     http://www.enssoft.org