pcap_freealldevs(alldevs);
}
-char* GetFirstInterface(void)
-{
- char* iface = NULL;
- char errorbuf[PCAP_ERRBUF_SIZE];
-
- DebugMessage(
- DEBUG_INIT, "interface is NULL, looking up interface....");
-
- /* look up the device and get the handle */
- iface = pcap_lookupdev(errorbuf);
-
- if ( !iface )
- {
- FatalError("Failed to lookup interface: %s. "
- "Please specify one with -i switch\n", errorbuf);
- }
-
- DebugFormat(DEBUG_INIT, "found interface %s\n", PRINT_INTERFACE(iface));
-
- iface = SnortStrdup(iface);
- return iface;
-}
-
*pbuf = NULL;
}
-/****************************************************************
- *
- * Function: mContainsSubstr(char *, int, char *, int)
- *
- * Purpose: Determines if a string contains a (non-regex)
- * substring.
- *
- * Parameters:
- * buf => data buffer we want to find the data in
- * b_len => data buffer length
- * pat => pattern to find
- * p_len => length of the data in the pattern buffer
- *
- * Returns:
- * Integer value, 1 on success (str constains substr), 0 on
- * failure (substr not in str)
- *
- ****************************************************************/
-int mContainsSubstr(const char* buf, int b_len, const char* pat, int p_len)
-{
- const char* b_idx; /* index ptr into the data buffer */
- const char* p_idx; /* index ptr into the pattern buffer */
- const char* b_end; /* ptr to the end of the data buffer */
- int m_cnt = 0; /* number of pattern matches so far... */
-#ifdef DEBUG_MSGS
- unsigned long loopcnt = 0;
-#endif
-
- /* mark the end of the strs */
- b_end = (char*)(buf + b_len);
-
- /* init the index ptrs */
- b_idx = buf;
- p_idx = pat;
-
- do
- {
-#ifdef DEBUG_MSGS
- loopcnt++;
-#endif
-
- if (*p_idx == *b_idx)
- {
- if (m_cnt == (p_len - 1))
- {
- DebugFormat(DEBUG_PATTERN_MATCH,
- "\n%ld compares for match\n", loopcnt);
- return 1;
- }
- m_cnt++;
- b_idx++;
- p_idx++;
- }
- else
- {
- if (m_cnt == 0)
- {
- b_idx++;
- }
- else
- {
- b_idx = b_idx - (m_cnt - 1);
- }
-
- p_idx = pat;
-
- m_cnt = 0;
- }
- }
- while (b_idx < b_end);
-
- /* if we make it here we didn't find what we were looking for */
- return 0;
-}
-
SO_PUBLIC char** mSplit(const char*, const char*, const int, int*, const char);
SO_PUBLIC void mSplitFree(char*** toks, int numtoks);
-SO_PUBLIC int mContainsSubstr(const char*, int, const char*, int);
#endif
return 0;
}
-/*
-* Add a Key to the list of key+data pairs
-*/
-int acsmAddKey2(
- ACSM_STRUCT2* p, unsigned char* key, int klen, int nocase, void*)
-{
- ACSM_PATTERN2* plist;
-
- plist = (ACSM_PATTERN2*)
- AC_MALLOC(sizeof(ACSM_PATTERN2), ACSM2_MEMORY_TYPE__PATTERN);
- MEMASSERT (plist, "acsmAddPattern");
-
- plist->patrn =
- (unsigned char*)AC_MALLOC(klen, ACSM2_MEMORY_TYPE__PATTERN);
- MEMASSERT (plist->patrn, "acsmAddPattern");
- memcpy (plist->patrn, key, klen);
-
- plist->casepatrn =
- (unsigned char*)AC_MALLOC(klen, ACSM2_MEMORY_TYPE__PATTERN);
- MEMASSERT (plist->casepatrn, "acsmAddPattern");
- memcpy (plist->casepatrn, key, klen);
-
- plist->n = klen;
- plist->nocase = nocase;
- plist->iid = 0;
- plist->udata = 0;
-
- plist->next = p->acsmPatterns;
- p->acsmPatterns = plist;
-
- return 0;
-}
-
/*
* Copy a boolean match flag int NextState table, for caching purposes.
*/
return FTPP_SUCCESS;
}
-/*
- * Function: ParseBounceTo(char *token, FTP_BOUNCE_TO*)
- *
- * Purpose: Extract the IP address, masking bits (CIDR format), and
- * port information from an FTP Bounce To configuration.
- *
- * Arguments: token => string pointer to the FTP bounce configuration
- * required format: IP/CIDR,port[,portHi]\0
- * FTP_BOUNCE_TO => populated with parsed data
- *
- * Returns: int => an error code integer (0 = success,
- * >0 = non-fatal error, <0 = fatal error)
- *
- */
-int ParseBounceTo(char* token, FTP_BOUNCE_TO* bounce)
-{
- char** toks;
- int num_toks;
- long int port_lo;
- char* endptr = NULL;
- sfip_t tmp_ip;
-
- toks = mSplit(token, ",", 3, &num_toks, 0);
- if (num_toks < 2)
- return FTPP_INVALID_ARG;
-
- if (sfip_pton(toks[0], &tmp_ip) != SFIP_SUCCESS)
- {
- mSplitFree(&toks, num_toks);
- return FTPP_INVALID_ARG;
- }
-
- memcpy(&bounce->ip, &tmp_ip, sizeof(sfip_t));
-
- port_lo = SnortStrtol(toks[1], &endptr, 10);
- if ((errno == ERANGE) || (*endptr != '\0') ||
- (port_lo < 0) || (port_lo >= MAXPORTS))
- {
- mSplitFree(&toks, num_toks);
- return FTPP_INVALID_ARG;
- }
-
- bounce->portlo = (unsigned short)port_lo;
-
- if (num_toks == 3)
- {
- long int port_hi = SnortStrtol(toks[2], &endptr, 10);
-
- if ((errno == ERANGE) || (*endptr != '\0') ||
- (port_hi < 0) || (port_hi >= MAXPORTS))
- {
- mSplitFree(&toks, num_toks);
- return FTPP_INVALID_ARG;
- }
-
- if (bounce->portlo != (unsigned short)port_hi)
- {
- bounce->porthi = (unsigned short)port_hi;
- if (bounce->porthi < bounce->portlo)
- {
- unsigned short tmp = bounce->porthi;
- bounce->porthi = bounce->portlo;
- bounce->portlo = tmp;
- }
- }
- }
-
- mSplitFree(&toks, num_toks);
- return FTPP_SUCCESS;
-}
-
/* FIXIT: Maybe want to redo this with high-speed searcher for ip/port.
* Would be great if we could handle both full addresses and
* subnets quickly -- using CIDR format. Need something that would
* Date: Author: Notes:
* ---------- ------- ----------------------------------------------
* 08/19/98 MFR Initial coding begun
- * 03/06/99 MFR Added Boyer-Moore pattern match routine, don't use
- * mContainsSubstr() any more if you don't have to
+ * 03/06/99 MFR Added Boyer-Moore pattern match routine
* 12/31/99 JGW Added a full Boyer-Moore implementation to increase
* performance. Added a case insensitive version of mSearch
* 07/24/01 MFR Fixed Regex pattern matcher introduced by Fyodor
return -1;
}
-/****************************************************************
- *
- * Function: mSearchREG(char *, int, char *, int)
- *
- * Purpose: Determines if a string contains a (regex)
- * substring.
- *
- * Parameters:
- * buf => data buffer we want to find the data in
- * blen => data buffer length
- * ptrn => pattern to find
- * plen => length of the data in the pattern buffer
- * skip => the B-M skip array
- * shift => the B-M shift array
- *
- * Returns:
- * 1 = found, 0 = not found
- *
- ****************************************************************/
-int mSearchREG(
- const char* buf, int blen, const char* ptrn, int plen, int* skip, int* shift)
-{
- int b_idx = plen;
- int literal = 0;
- int regexcomp = 0;
-#ifdef DEBUG_MSGS
- int cmpcnt = 0;
-#endif /* DEBUG_MSGS */
-
- DebugFormat(DEBUG_PATTERN_MATCH, "buf: %p blen: %d ptrn: %p "
- " plen: %d b_idx: %d\n", buf, blen, ptrn, plen, b_idx);
- DebugFormat(DEBUG_PATTERN_MATCH, "packet data: \"%s\"\n", buf);
- DebugFormat(DEBUG_PATTERN_MATCH, "matching for \"%s\"\n", ptrn);
-
- if (plen == 0)
- return 1;
-
- while (b_idx <= blen)
- {
- int p_idx = plen, skip_stride, shift_stride;
-
- DebugFormat(DEBUG_PATTERN_MATCH, "Looping... "
- "([%d]0x%X (%c) -> [%d]0x%X(%c))\n",
- b_idx, buf[b_idx-1],
- buf[b_idx-1],
- p_idx, ptrn[p_idx-1], ptrn[p_idx-1]);
-
- while (buf[--b_idx] == ptrn[--p_idx]
- || (ptrn[p_idx] == '?' && !literal)
- || (ptrn[p_idx] == '*' && !literal)
- || (ptrn[p_idx] == '\\' && !literal))
- {
- DebugFormat(DEBUG_PATTERN_MATCH, "comparing: b:%c -> p:%c\n",
- buf[b_idx], ptrn[p_idx]);
-#ifdef DEBUG_MSGS
- cmpcnt++;
-#endif
-
- if (literal)
- literal = 0;
- if (!literal && ptrn[p_idx] == '\\')
- literal = 1;
- if (ptrn[p_idx] == '*')
- {
- DebugMessage(DEBUG_PATTERN_MATCH,"Checking wildcard matching...\n");
- while (p_idx != 0 && ptrn[--p_idx] == '*')
- ; /* fool-proof */
-
- while (buf[--b_idx] != ptrn[p_idx])
- {
- DebugFormat(DEBUG_PATTERN_MATCH,
- "comparing: b[%d]:%c -> p[%d]:%c\n",
- b_idx, buf[b_idx], p_idx, ptrn[p_idx]);
-
- regexcomp++;
- if (b_idx == 0)
- {
- DebugMessage(DEBUG_PATTERN_MATCH,
- "b_idx went to 0, returning 0\n");
- return 0;
- }
- }
-
- DebugFormat(DEBUG_PATTERN_MATCH,
- "got wildcard final char match! (b[%d]: %c -> p[%d]: %c\n",
- b_idx, buf[b_idx], p_idx, ptrn[p_idx]);
- }
-
- if (p_idx == 0)
- {
- DebugFormat(DEBUG_PATTERN_MATCH, "match: compares = %d.\n",
- cmpcnt);
- return 1;
- }
-
- if (b_idx == 0)
- break;
- }
-
- DebugMessage(DEBUG_PATTERN_MATCH, "skip-shifting...\n");
- skip_stride = skip[(unsigned char)buf[b_idx]];
- shift_stride = shift[p_idx];
-
- b_idx += (skip_stride > shift_stride) ? skip_stride : shift_stride;
- DebugFormat(DEBUG_PATTERN_MATCH, "b_idx skip-shifted to %d\n", b_idx);
- b_idx += regexcomp;
- DebugFormat(DEBUG_PATTERN_MATCH,
- "b_idx regex compensated %d steps, to %d\n", regexcomp, b_idx);
- regexcomp = 0;
- }
-
- DebugFormat(DEBUG_PATTERN_MATCH, "no match: compares = %d, b_idx = %d, "
- "blen = %d\n", cmpcnt, b_idx, blen);
-
- return 0;
-}
-
int* make_shift(char*, int);
int mSearch(const char*, int, const char*, int, int*, int*);
int mSearchCI(const char*, int, const char*, int, int*, int*);
-int mSearchREG(const char*, int, const char*, int, int*, int*);
#endif
/*
* sflsq.c
*
-* Simple list, stack, queue, and dictionary implementations
+* Simple list, queue, and dictionary implementations
* ( most of these implementations are list based - not performance monsters,
* and they all use alloc via s_alloc/s_free )
-* Stack based Ineteger and Pointer Stacks, these are for performance.(inline would be better)
*
* 11/05/2005 - man - Added sflist_firstx() and sflist_nextx() with user
* provided SF_NODE inputs for tracking the list position. This allows
return s;
}
-SF_STACK* sfstack_new(void)
-{
- return (SF_STACK*)sflist_new();
-}
-
SF_QUEUE* sfqueue_new(void)
{
return (SF_QUEUE*)sflist_new();
}
/*
-* ADD to List/Stack/Queue/Dictionary
+* ADD to List/Queue/Dictionary
*/
/*
* Add-Head Item
return sflist_add_tail (s, ndata);
}
-int sfstack_add(SF_STACK* s, NODE_DATA ndata)
-{
- return sflist_add_tail (s, ndata);
-}
-
/*
* List walk - First/Next - return the node data or NULL
*/
return (NODE_DATA)sflist_remove_head(s);
}
-/*
-* Remove Tail Item from stack
-*/
-NODE_DATA sfstack_remove(SF_QUEUE* s)
-{
- return (NODE_DATA)sflist_remove_tail(s);
-}
-
/*
* COUNT
*/
return s->count;
}
-int sfstack_count(SF_STACK* s)
-{
- if (!s)
- return 0;
- return s->count;
-}
-
/*
* Free List + Free it's data nodes using 'nfree'
*/
sflist_free_all(s, nfree);
}
-void sfstack_free_all(SF_STACK* s,void (* nfree)(void*) )
-{
- sflist_free_all(s, nfree);
-}
-
void sflist_static_free_all(SF_LIST* s, void (* nfree)(void*) )
{
void* p;
}
}
-void sfqueue_static_free_all(SF_QUEUE* s,void (* nfree)(void*) )
-{
- sflist_static_free_all(s, nfree);
-}
-
-void sfstack_static_free_all(SF_STACK* s,void (* nfree)(void*) )
-{
- sflist_static_free_all(s, nfree);
-}
-
/*
-* FREE List/Queue/Stack/Dictionary
+* FREE List/Queue/Dictionary
*
* This does not free a nodes data
*/
sflist_free (s);
}
-void sfstack_free(SF_STACK* s)
-{
- sflist_free (s);
-}
-
-/* Use these if the SF_LIST was not dynamically allocated via
- * sflist_new() */
-void sflist_static_free(SF_LIST* s)
-{
- while (sflist_count(s))
- sflist_remove_head(s);
-}
-
-void sfqueue_static_free(SF_QUEUE* s)
-{
- sflist_static_free(s);
-}
-
-void sfstack_static_free(SF_STACK* s)
-{
- sflist_static_free(s);
-}
-
-/*
-* Integer stack functions - for performance scenarios
-*/
-int sfistack_init(SF_ISTACK* s, unsigned* a, unsigned n)
-{
- if ( a )
- s->stack = a;
- else
- {
- s->stack = (unsigned*)calloc(n, sizeof(unsigned) );
- }
- if ( !s->stack )
- return -1;
- s->nstack= n;
- s->n =0;
- return 0;
-}
-
-int sfistack_push(SF_ISTACK* s, unsigned value)
-{
- if ( s->n < s->nstack )
- {
- s->stack[s->n++] = value;
- return 0;
- }
- return -1;
-}
-
-int sfistack_pop(SF_ISTACK* s, unsigned* value)
-{
- if ( s->n > 0 )
- {
- s->n--;
- *value = s->stack[s->n];
- return 0;
- }
- return -1;
-}
-
-/*
-* Pointer Stack Functions - for performance scenarios
-*/
-int sfpstack_init(SF_PSTACK* s, void** a, unsigned n)
-{
- if ( a )
- s->stack = a;
- else
- {
- s->stack = (void**)calloc(n, sizeof(void*) );
- }
-
- if ( !s->stack )
- return -1;
- s->nstack= n;
- s->n =0;
- return 0;
-}
-
-int sfpstack_push(SF_PSTACK* s, void* value)
-{
- if ( s->n < s->nstack )
- {
- s->stack[s->n++] = value;
- return 0;
- }
- return -1;
-}
-
-int sfpstack_pop(SF_PSTACK* s, void** value)
-{
- if ( s->n > 0 )
- {
- s->n--;
- *value = s->stack[s->n];
- return 0;
- }
- return -1;
-}
-
};
typedef sf_list SF_QUEUE;
-typedef sf_list SF_STACK;
typedef sf_list SF_LIST;
// -----------------------------------------------------------------------------
void sflist_free(SF_LIST*);
void sflist_free_all(SF_LIST*, void (* free)(void*) );
void sflist_static_free_all(SF_LIST*, void (* nfree)(void*));
-void sflist_static_free(SF_LIST*);
-
-// -----------------------------------------------------------------------------
-// Stack Interface ( LIFO - Last in, First out )
-// -----------------------------------------------------------------------------
-SF_STACK* sfstack_new(void);
-int sfstack_add(SF_STACK*, NODE_DATA);
-NODE_DATA sfstack_remove(SF_STACK*);
-int sfstack_count(SF_STACK*);
-void sfstack_free(SF_STACK*);
-void sfstack_free_all(SF_STACK*, void (* free)(void*) );
-void sfstack_static_free_all(SF_STACK*, void (* nfree)(void*));
-void sfstack_static_free(SF_STACK*);
// -----------------------------------------------------------------------------
// Queue Interface ( FIFO - First in, First out )
int sfqueue_count(SF_QUEUE*);
void sfqueue_free(SF_QUEUE*);
void sfqueue_free_all(SF_QUEUE*, void (* free)(void*) );
-void sfqueue_static_free_all(SF_QUEUE*,void (* nfree)(void*));
-void sfqueue_static_free(SF_QUEUE*);
-
-// Performance Stack functions for Integer/Unsigned and Pointers, uses
-// user provided array storage, perhaps from the program stack or a global.
-// These are efficient, and use no memory functions.
-int sfistack_init(SF_ISTACK*, unsigned* a, unsigned n);
-int sfistack_push(SF_ISTACK*, unsigned value);
-int sfistack_pop(SF_ISTACK*, unsigned* value);
-
-int sfpstack_init(SF_PSTACK*, void** a, unsigned n);
-int sfpstack_push(SF_PSTACK*, void* value);
-int sfpstack_pop(SF_PSTACK*, void** value);
#endif
return (char*)buf;
}
-int CheckValueInRange(const char* value_str, const char* option,
- unsigned long lo, unsigned long hi, unsigned long* value)
-{
- char* endptr;
- uint32_t val;
-
- if ( value_str == NULL )
- {
- ParseError("invalid format for %s.", option);
- return -1;
- }
-
- if (SnortStrToU32(value_str, &endptr, &val, 10))
- {
- ParseError("invalid format for %s.", option);
- return -1;
- }
-
- if (*endptr)
- {
- ParseError("invalid format for %s.", option);
- return -1;
- }
-
- *value = val;
-
- if ( (errno == ERANGE) || (*value) < lo || (*value) > hi)
- {
- ParseError("invalid value for %s."
- "It should range between %u and %u.", option,
- lo, hi);
- return -1;
- }
-
- return 0;
-}
-
void SetNoCores(void)
{
struct rlimit rlim;
return buf;
}
-char* get_tok(char* s, const char* delim)
-{
- static THREAD_LOCAL char* lasts = nullptr;
- return strtok_r(s, delim, &lasts);
-}
-
SO_PUBLIC int SnortStrncpy(char*, const char*, size_t);
SO_PUBLIC int SnortStrnlen(const char*, int);
-int CheckValueInRange(const char* value_str, const char* option,
- unsigned long lo, unsigned long hi, unsigned long* value);
-
char* CurrentWorkingDir(void);
char* GetAbsolutePath(const char* dir);
char* StripPrefixDir(char* prefix, char* dir);
return 0;
}
-static inline long SnortStrtolRange(const char* nptr, char** endptr, int base, long lo, long hi)
-{
- long iRet = SnortStrtol(nptr, endptr, base);
- if ((iRet > hi) || (iRet < lo))
- *endptr = (char*)nptr;
-
- return iRet;
-}
-
-static inline unsigned long SnortStrtoulRange(const char* nptr, char** endptr, int base, unsigned
- long lo, unsigned long hi)
-{
- unsigned long iRet = SnortStrtoul(nptr, endptr, base);
- if ((iRet > hi) || (iRet < lo))
- *endptr = (char*)nptr;
-
- return iRet;
-}
-
-static inline int IsEmptyStr(const char* str)
-{
- const char* end;
-
- if (str == NULL)
- return 1;
-
- end = str + strlen(str);
-
- while ((str < end) && isspace((int)*str))
- str++;
-
- if (str == end)
- return 1;
-
- return 0;
-}
-
static inline pid_t gettid(void)
{
#if defined(LINUX) && defined(SYS_gettid)
SO_PUBLIC const char* get_error(int errnum);
-// get_tok() provided to retrofit distributed calls to
-// strtok() to use strtok_r(). use strtok_r() directly
-// for new code. get_tok() is thread safe but not
-// reentrant.
-char* get_tok(char* s, const char* delim);
-
#endif
#include "main/thread.h"
#include "util.h"
-/**
- * give a textual representation of tcp flags
- *
- * @param flags tcph->flags
- *
- * @return ptr to a static buffer w/ the string represented
- */
-char* mktcpflag_str(int flags)
-{
- static THREAD_LOCAL char buf[9];
- const int fin = 0x01;
- const int syn = 0x02;
- const int rst = 0x04;
- const int psh = 0x08;
- const int ack = 0x10;
- const int urg = 0x20;
- const int cwr = 0x40;
- const int ecn_echo = 0x80;
-
- memset(buf, '-', 9);
-
- if (flags & fin)
- buf[0] = 'F';
-
- if (flags & syn)
- buf[1] = 'S';
-
- if (flags & rst)
- buf[2] = 'R';
-
- if (flags & psh)
- buf[3] = 'P';
-
- if (flags & ack)
- buf[4] = 'A';
-
- if (flags & urg)
- buf[5] = 'U';
-
- if (flags & cwr)
- buf[6] = 'C';
-
- if (flags & ecn_echo)
- buf[7] = 'E';
-
- buf[8] = '\0';
-
- return buf;
-}
-
/**
* A inet_ntoa that has 2 static buffers that are changed between
* subsequent calls
#include "sfip/sfip_t.h"
SO_PUBLIC char* inet_ntoax(const sfip_t*);
-SO_PUBLIC char* mktcpflag_str(int flags);
#endif